该例子用于对象的理解非常有效(建议看完上面网站的内容在开始练习)
弹球
body {
margin: 0;
overflow: hidden;
font-family: "PingFangSC-Regular", "微软雅黑", sans-serif;
height: 100%;
}
h1 {
font-size: 2rem;
letter-spacing: -1px;
position: absolute;
margin: 0;
top: -4px;
right: 5px;
color: transparent;
text-shadow: 0 0 4px white;
}
p {
position: absolute;
margin: 0;
top: 35px;
right: 5px;
color: #aaa;
}
弹球
//弹球的个数
const BALLS\_COUNT = 25;
//弹球的半径范围
const BALL\_SIZE\_MIN = 10;
const BALL\_SIZE\_MAX = 20;
// 弹球的速度
const BALL\_SPEED\_MAX = 7;
// 设定画布
var canvas = document.querySelector("canvas");
var pcount = document.querySelector("p");
var ctx = canvas.getContext("2d");
//获取屏幕的宽高 并设置为画布的宽高
var width = (canvas.width = window.innerWidth);
var height = (canvas.height = window.innerHeight);
// 生成随机数的函数
function random(min, max) {
return Math.floor(Math.random() * (max - min)) + min;
}
// 生成随机颜色的函数
function randomColor() {
return (
"rgb(" + random(0, 255) + ", " + random(0, 255) + ", " +random(0, 255) + ")");
}
//定义形状
function Shape(x, y, velX, velY, exists) {
this.x = x;
this.y = y;
this.velX = velX;
this.velY = velY;
this.exists = exists;
}
// 创建弹球对象
function Ball(x, y, velX, velY, color, size, exists) {
Shape.call(this, x, y, velX, velY, exists);
this.color = color;
this.size = size;
}
Ball.prototype = Object.create(Shape.prototype);
Ball.prototype.constructor = Ball;
// 定义绘制球的函数
Ball.prototype.draw = function() {
ctx.beginPath();
ctx.fillStyle = this.color;
ctx.arc(this.x, this.y, this.size, 0, 2 * Math.PI);
ctx.fill();
};
//更新跳球的位置
Ball.prototype.update = function() {
//到达右边,反弹
if (this.x + this.size >= width) {
this.velX = -this.velX;
}
//到达左边,反弹
if (this.x - this.size <= 0) {
this.velX = -this.velX;
}
//到达底部,反弹
if (this.y + this.size >= height) {
this.velY = -this.velY;
}
//到达顶部 反弹
if (this.y - this.size <= 0) {
this.velY = -this.velY;
}
this.x += this.velX;
this.y += this.velY;
};
//弹球的碰撞处理
Ball.prototype.collisionDetect = function() {
for (var j = 0; j < balls.length; j++) {
//是不是弹球本身
if (balls[j] === this) continue;
var dx = this.x - balls[j].x;
var dy = this.y - balls[j].y;
var distance = Math.sqrt(dx * dx + dy * dy);
//碰撞改变两个球的颜色
if (distance < this.size + balls[j].size) {
this.color = balls[j].color = randomColor();
}
}
};
//定义一个小吃货
function EvilCircle(x, y, exists) {
Shape.call(this, x, y, 20, 20, exists);
this.color = "white";
this.size = 10;
}
EvilCircle.prototype = Object.create(Shape.prototype);
EvilCircle.prototype.constructor = EvilCircle;
// 定义绘制小吃货的函数
EvilCircle.prototype.draw = function() {
ctx.beginPath();
ctx.strokeStyle = this.color;
ctx.arc(this.x, this.y, this.size, 0, 2 * Math.PI);
ctx.stroke();
};
// 检查小吃货是否碰壁
EvilCircle.prototype.checkBounds = function() {
if (this.x + this.size >= width) {
this.velX = -this.velX;
}
if (this.x - this.size <= 0) {
this.x = this.size;
}
if (this.y + this.size >= height) {
this.y = height - this.size;
}
if (this.y - this.size <= 0) {
this.y = this.size;
}
};
// 定义小吃货移动函数
EvilCircle.prototype.setControls = function() {
window.onkeydown = e => {
if (e.key === "a") {
this.x -= this.velX;
} else if (e.key === "d") {
this.x += this.velX;
} else if (e.key === "w") {
this.y -= this.velY;
} else if (e.key === "s") {
this.y += this.velY;
}
//上下左右移动
if (e.key === "ArrowLeft") {
this.x -= this.velX;
} else if (e.key === "ArrowRight") {
this.x += this.velX;
} else if (e.key === "ArrowUp") {
this.y -= this.velY;
} else if (e.key === "ArrowDown") {
this.y += this.velY;
}
};
};
//小吃货碰撞到了弹球
EvilCircle.prototype.collisionDetect = function() {
for (var j = 0; j < balls.length; j++) {
//弹球没被吃
if (balls[j].exists) {
var dx = this.x - balls[j].x;
var dy = this.y - balls[j].y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < this.size + balls[j].size) {
//标记弹球被吃
balls[j].exists = false;
}
}
}
};
//激活小吃货
EvilCircle.prototype.run = function() {
this.draw();
this.checkBounds();
this.collisionDetect();
};
//创建吃货
var evilCircle = new EvilCircle(20, 20, true);
evilCircle.setControls();
// 定义一个数组来保存所有的球
var balls = [];
pcount.textContent = "还剩" + BALLS\_COUNT + "个球";
for (let i = 0; i < BALLS\_COUNT; i++) {
var size = random(BALL\_SIZE\_MIN, BALL\_SIZE\_MAX);
var ball = new Ball(
// 为避免绘制错误,球至少离画布边缘球本身一倍宽度的距离
random(0 + size, width - size),
random(0 + size, height - size),
random(-BALL\_SPEED\_MAX, BALL\_SPEED\_MAX),
random(-BALL\_SPEED\_MAX, BALL\_SPEED\_MAX),
randomColor(),
size,
true
);
balls.push(ball);
}
// 定义一个循环来不停地播放
function loop() {
background("rgb(0, 0, 0)");
for (var i = 0; i < balls.length; i++) {
if (!balls[i].exists) {
continue;
}
balls[i].draw();
balls[i].update();
balls[i].collisionDetect();
}
evilCircle.run();
var newballs = balls.filter(balls => balls.exists);
pcount.textContent = "还剩" + newballs.length + "个球";
requestAnimationFrame(loop);
}
function background(color) {
ctx.fillStyle = color;
ctx.fillRect(0, 0, width, height);
ctx.beginPath();
}
loop();