html+css+js实现打砖块小游戏
简介
游戏要求
打砖块的小游戏对于许多同学来说是熟悉的,这个小游戏的逻辑如下:
1、添加挡板、小球、砖块等角色;
2、设置挡板随鼠标移动;
3、设置小球不断运行,在遇到挡板时反弹;
4、设置砖块被小球击中时消失,并克隆下一个砖块;
5、设置计分;
6、判断游戏结束(以小球低于档板为游戏结束)。.
运行结果
这个的运行效果是这个样子的,一个打砖块的游戏,点击中间的start然后就可以玩了。
完整代码
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" href="style.css"> <title>Document</title> </head> <body> <canvas id="canvas"></canvas> <button id="start" onclick="start()">START</button> </body> </html> <script src="script.js"></script>
style.css
* { margin: 0; padding: 0; } body { background: #333; } #canvas { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); border: 1px solid white; /* cursor:none; */ filter: drop-shadow(0 0 2px white); } #start { width: 120px; height: 40px; position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); font-size: 28px; padding: 5px; border-radius: 4px; display: flex; background: rgba(255, 255, 255, 0.4); justify-content: center; }
JS
var canvas = document.getElementById("canvas") var ctx = canvas.getContext("2d") canvas.width = 800 canvas.height = 600 var blocks = [] //砖块数组 var board = { //反弹板 x: 350, y: 580, long: 100 } var cRect = canvas.getBoundingClientRect() //画布位置 var ball = { //定义弹球对象 color: "white" } var score = 0 //分数 var rungame = false //默认运行状态 var colors = [ //颜色数组 "#eccc68", "#ff7f50", "#ff6b81", "#7bed9f", "#5352ed", "#70a1ff" ] var speed = 0.3 //弹球移动速度 var run = document.getElementById("start") var fires = [] //烟火数组 function start() { newgame() rungame = true run.style.display = "none" canvas.style.cursor = "none" } window.addEventListener("mousemove", function(evt) { //移动鼠标变更反弹板位置 var x = evt.clientX - cRect.left if (x < 50) { board.x = 0 } else if (x > 750) { board.x = 700 } else { board.x = x - 50 } console.log(x) }) function newgame() { //初始化游戏 ball = { //默认的弹球位置,随机方向 sx: 400, sy: 300, } ball.vx = (0.5 - Math.random()) * speed ball.vy = Math.sqrt(speed * speed - ball.vx * ball.vx) score = 0 blocks = [] for (var i = 0; i < 10; i++) { //生成砖块 for (var j = 0; j < 6; j++) { blocks.push({ x: i, y: j, color: colors[parseInt(Math.random() * colors.length)] }) } } } function draw() { ctx.clearRect(0, 0, 800, 600) for (var i = 0; i < blocks.length; i++) { //绘制砖块 block = blocks[i] ctx.fillStyle = block.color ctx.fillRect(block.x * 80 + 1, block.y * 30 + 1, 79, 29) if (ball.sx + 10 > block.x * 80 + 1 && ball.sx - 10 < block.x * 80 + 80 && ball.sy + 10 > block.y * 30 + 1 && ball.sy - 10 < block.y * 30 + 30) { //砖块碰撞判断 if (ball.sx > block.x * 80 + 80 || ball.sx < block.x * 80) { //左右方向碰撞则改变x轴运行方向 ball.vx = -ball.vx } else if (ball.sy > block.y * 30 + 30 || ball.sy < block.y * 30) { //垂直方向碰撞则改变Y轴运行方向 ball.vy = -ball.vy } if (ball.color == block.color) { //同色碰撞则加10分 score += 10 } else { //非同色碰撞加1分 score++ } ball.color = block.color //撞击后球的颜色变成砖块颜色 blocks.splice(i, 1) //碰撞后砖块消失 for (var f = 0; f < 50; f++) { //生成火花 fires.push({ sx: block.x * 80 + 40, sy: block.y * 30 + 15, color: block.color, vx: 0.5 - Math.random(), vy: 0.5 - Math.random(), age: 100 }) } } } ctx.fillStyle = "white" //绘制分数 ctx.font = "20px sans-serif" ctx.fillText(score, 5, 25) ctx.fillRect(board.x, board.y, board.long, 20) //绘制反弹板 ctx.beginPath() //绘制小球 ctx.fillStyle = ball.color ctx.arc(ball.sx, ball.sy, 10, 0, 2 * Math.PI) ctx.fill() if (rungame) { //判断游戏运行状态,并刷新球的位置 ball.sx += ball.vx * 5 ball.sy += ball.vy * 5 if (ball.sy < 10) { //上边缘碰撞判断 ball.vy = -ball.vy } if (ball.sx < 10 || ball.sx > 795) { //左右碰撞判断 ball.vx = -ball.vx } if (ball.sy > 570 && ball.sx > board.x && ball.sx < board.x + board.long) { //反弹板碰撞判断 ball.vx = (ball.sx - (board.x + board.long / 2)) / board.long / 2 * speed * 3 ball.vy = -Math.sqrt(speed * speed - ball.vx * ball.vx) speed = speed * 1.001 for (var f = 0; f < 20; f++) { fires.push({ sx: ball.sx, sy: ball.sy + 10, color: colors[parseInt(Math.random() * colors.length)], vx: 0.5 - Math.random(), vy: Math.random() - 1, age: 60 }) } } if (ball.sy > 590 || blocks.length <= 0) { //碰撞到底部或所有砖块都消失则游戏停止运行 rungame = false run.style.display = "flex" canvas.style.cursor = "default" for (var f = 0; f < 150; f++) { fires.push({ sx: 400, sy: 300, color: colors[parseInt(Math.random() * colors.length)], vx: 0.5 - Math.random(), vy: 0.5 - Math.random(), age: 560 }) } } } for (var i = 0; i < fires.length; i++) { fire = fires[i] ctx.fillStyle = fire.color ctx.fillRect(fire.sx, fire.sy, 2, 2) fire.age-- if (fire.age < 0) { fires.splice(i, 1) } fire.sx += fire.vx * 2 fire.sy += fire.vy * 2 } } newgame() setInterval(draw, 1);
买不到的数目
小明开了一家糖果店。
他别出心裁:把水果糖包成4颗一包和7颗一包的两种。
糖果不能拆包卖。
小朋友来买糖的时候,他就用这两种包装来组合。
当然有些糖果数目是无法组合出来的,比如要买 10 颗糖。
你可以用计算机测试一下,在这种包装情况下,最大不能买到的数量是17。
大于17的任何数字都可以用4和7组合出来。
本题的要求就是在已知两个包装的数量时,求最大不能组合出的数字。
输入格式
两个正整数 n,m,表示每种包装中糖的颗数。
输出格式
一个正整数,表示最大不能买到的糖数。
数据范围
2≤n,m≤1000,
保证数据一定有解。
输入样例:
4 7
输出样例:
17
算法思路:
先开一个bool类型dp数组,dp[i]表示能否组成i。
两个数据分别是n,m,假定最小值是minn,最大值是maxx,那么就相当于从minn开始,不断往前走,每走到一个数,都要看看dp[i - n]或者dp[i - m]是否为true,如果是,则置true,反之我们需要更新ans,ans就是指最大不能买的数目,也就是我们最后的输出,循环结束,便可直接输出ans.
特解答案:
#include<iostream> using namespace std; int main() { int a, b; cin >> a >> b; cout << a * b - a - b; return 0; }
正常解C++
#include <iostream> #include <algorithm> using namespace std; int n, m, minn, maxx, ans; bool dp[1000000]; int main() { cin >> n >> m; dp[0] = true; minn = min(n, m); maxx = max(n, m); for (int i = minn; i < n * m; i++) { if (dp[i - minn]) { dp[i] = true; } else if (i >= maxx && dp[i - maxx]) { dp[i] = true; } else { ans = i; } } cout << ans; return 0; }
正常解Java
import java.util.*; public class Main { static int N = 1000010; static boolean [] f = new boolean [N]; public static void main(String[] args) { Scanner in = new Scanner (System.in); int n = in.nextInt(); int m = in.nextInt(); int mi = Math.min(n, m); int ma = Math.max(n, m); int res = 0; f[0] = true; for (int i = mi; i <= n * m; ++ i) { if (f[i - mi]) f[i] = true; else if (i >= ma && f[i - ma]) f[i] = true; else res = i; } System.out.println(res); } }