写在开头
利用canvas写的弹球碰撞小游戏,体验地址,练习canvas!
实现过程
1.设置画布
先生成一个黑色背景充满当前窗口,便于后续实现小球移动
const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');
const width = canvas.width = window.innerWidth;
const height = canvas.height = window.innerHeight;
ctx.fillRect (0,0, width, height);
2.生成随机小球
先画出小球,比较简单,就是只画出一个圆
ctx.beginPath();
ctx.fillStyle = 'red';
ctx.arc(95,50,40,0,2*Math.PI);
ctx.fill()
ctx.closePath()
一个小球肯定不够,所以我们要实现多个随机位置、随机颜色、随机大小的小球
增加随机方法
function random(min, max) {
const num = Math.floor(Math.random() * (max - min)) + min;
return num;
}
获取全随机值
function Ball(width, height, ctx) {
this.width = width;
this.height = height;
this.ctx = ctx;
this.r = random(10, 20);
this.x = random(this.r, this.width - this.r);
this.y = random(this.r, this.height - this.r)
this.color = `rgb(${random(0, 255)},${random(0, 255)},${random(0, 255)})`;
}
加入循环多次调用,生成小球实例,即可实现多个随机小球了
3.小球实现移动、碰撞变色
小球移动
实现移动,就是改变小球的坐标值,所以需要给小球加一个速度值
ctx.arc(x,y,r,0,2*Math.PI);
即改变x、y值。这个速度值也可以随机生成,加入正负,即可实现上下左右移动。
this.speedX = random(-4, 4);
this.speedY = random(-4, 4);
move: function () {
this.x += this.speedX;
this.y += this.speedY;
},
这个时候会出现一些问题,随机速度为零,球就不移动了,这个这个加入判断即可
另一种情况,球到边界了,此时再移动就出去了,这个时候就把速度取反
//解决生成球不动情况
if (this.speedX == 0) {
this.speedX = 1;
}
if (this.speedY == 0) {
this.speedY = 1;
}
//判断边界值,让圆球始终保证在画面内
if (this.x > this.width - this.r || this.x < this.r) {
this.speedX = -this.speedX;
}
if (this.y > this.height - this.r || this.y < this.r) {
this.speedY = -this.speedY;
}
碰撞变色
实现碰撞其实也很简单,两个小球之间只需要判断他们的位置距离是否超过它们半径和即可,
然后再赋予他们随机变色
if (Math.sqrt(Math.pow(balls[j].x - balls[k].x, 2) + Math.pow(balls[j].y - balls[k].y, 2)) <= balls[k].r + balls[j].r) {
balls[j].color = balls[k].color = `rgb(${random(0, 255)},${random(0, 255)},${random(0, 255)})`;
}
4.控制球吃球
控制球移动,就需要绑定键盘的事件,用键盘控制移动速度,这里设置ctrl加速
document.onkeydown = function (event) {
//定义一个变量,来表示移动的速度
var speed = 30;
//当用户按了ctrl以后,速度加快
if (event.ctrlKey) {
speed = 100;
}
switch (event.code) {
case "ArrowLeft":
//alert("向左");
that.x = that.x - speed;
break;
case "ArrowRight":
//alert("向右");
that.x = that.x + speed;
break;
case "ArrowUp":
//alert("向上");
that.y = that.y - speed;
break;
case "ArrowDown":
//alert("向下");
that.y = that.y + speed;
break;
}
};
然后判断相撞,依然是用距离和半径比较,撞后小球消失,玩家小球增大
//判断玩家球和其他球相撞
if (Math.sqrt(Math.pow(balls[j].x - playerBall.x, 2) + Math.pow(balls[j].y - playerBall.y, 2)) <= playerBall.r + balls[j].r) {
balls.splice(j, 1);
playerBall.r = playerBall.r + 5;
}
5.增加尾迹
为了让小球更加美观,加入尾迹,每次重新画布时增加透明度即可
ctx.fillStyle = "rgba(0,0,0,0.2)"
ctx.fillRect(0, 0, width, height);
这就实现了完整效果
写在结尾
这就是对canvas的一个小练习,欢迎进一步拓展!