直接贴代码:
/**
* 游戏类
*/
class Game {
// 初始化
constructor(
name = 'canvas',
boll = new Boll,
bat = new Bat,
){
this.canvas = new Canvas(name);
this.boll = boll;
this.bat = bat;
this.bat.canvas = this.canvas;
// 将球和球拍注册给画布
this.canvas.add(this.boll);
this.canvas.add(this.bat);
// 将画布和球拍注册给球
this.boll.add(this.canvas);
this.boll.add(this.bat);
}
// 开始
start(){
console.log("游戏开始");
this.ifRun = 1;
this.run();
}
// 结束
stop(){
console.log("游戏停止");
this.ifRun = 0;
}
// 运行
run(){
// 重复调用自身,这里用箭头函数是因为 this 的作用域原因
window.requestAnimationFrame(
timestamp => {
// console.log(timestamp);
this.ifRun && this.run();
},
this.canvas.item
);
// 画布绘图
this.canvas.draw();
// 球运动
this.boll.run();
this.bat.run();
}
}
/**
* 画布
*/
class Canvas {
// 初始化
constructor(
name, // 画布id
width = document.documentElement.clientWidth, // 画布宽度
height = document.documentElement.clientHeight, // 画布高度
objs = [] // 画布内元素
){
this.item = document.getElementById(name);
this.width = this.item.width = width;
this.height = this.item.height = height;
this.ctx = this.item.getContext('2d');
this.objs = objs;
}
// 清空画布
clear(){
this.ctx.clearRect(0,0, this.width, this.height); // 清屏
}
// 添加要绘图元素
add(obj){
this.objs.push(obj)
}
// 绘图
draw(){
this.clear();
for (let i in this.objs) {
this.objs[i].draw(this.ctx);
}
}
// 碰撞检测
hitBoll(boll){
if(boll.x + boll.r >= this.width || boll.x - boll.r <= 0)
boll.vx = -boll.vx;
if(boll.y - boll.r <= 0)
boll.vy = -boll.vy;
if(boll.y >= this.height + boll.r)
boll.vy = -boll.vy;
}
}
/**
* 球
*/
class Boll {
// 初始化
constructor(
x = 50, // 水平位置
y = 500, // 垂直位置
vx = 5, // 水平速度
vy = -5, // 垂直速度
r = 10, // 直径
objs = [], // 碰撞元素
){
this.x = x;
this.y = y;
this.vx = vx;
this.vy = vy;
this.r = r;
this.objs = objs;
}
// 添加要碰撞检测的元素
add(obj){
this.objs.push(obj)
}
// 运行
run(){
this.x += this.vx;
this.y += this.vy;
// 碰壁检测
for(let i in this.objs){
this.objs[i].hitBoll(this);
}
}
// 绘图
draw(ctx) {
ctx.beginPath();
ctx.arc(this.x, this.y, this.r, 0, Math.PI * 2, true);
ctx.closePath();
ctx.fillStyle = this.color;
ctx.fill();
}
// 碰撞检测
hitBoll(boll){
}
}
class Rect {
}
/**
* 拍
*/
class Bat {
// 初始化
constructor(
x = 100,
y = 500,
width = 200,
height = 5,
speed = 10,
){
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.speed = speed;
this.vx = 0;
this.listen();
}
// 绘图
draw(ctx){
ctx.fillStyle = this.color;
ctx.fillRect(this.x, this.y, this.width, this.height);
}
listen(){
let t = this.speed;
document.onkeydown = e => {
t++;
if(e.keyCode == 39){
this.vx = t;
}
if(e.keyCode == 37){
this.vx = -t;
}
}
document.onkeyup = e => {
t = this.speed;
this.vx = 0;
}
}
run(){
this.x += this.vx;
if(this.x <= 0) this.x = 0;
if(this.x + this.width >= this.canvas.width) this.x = this.canvas.width - this.width;
}
// 检测碰撞
hitBoll(boll){
let x1 = this.x - boll.r;
let x2 = this.x;
let x3 = this.x + this.width;
let x4 = this.x + this.width + boll.r;
let y1 = this.y - boll.r;
let y2 = this.y;
let y3 = this.y + this.height;
let y4 = this.y + this.height + boll.r;
// 与上面碰撞
if(
(boll.x > x2 && boll.x < x3 && boll.y >= y1 && boll.y < y2) ||
(boll.x > x2 && boll.x < x3 && boll.y > y3 && boll.y <= y4)
){
boll.vy = -boll.vy;
}
// 与侧面碰撞
if(
(boll.x >= x1 && boll.x < x2 && boll.y > y2 && boll.y < y3) ||
(boll.x > x3 && boll.x <= x4 && boll.y > y2 && boll.y < y3)
){
boll.vx = -boll.vx;
}
// 与角对心碰撞
if(
(Math.pow((x2 - boll.x),2) + Math.pow((y2 - boll.y), 2) <= Math.pow(boll.r, 2))||
(Math.pow((x3 - boll.x),2) + Math.pow((y2 - boll.y), 2) <= Math.pow(boll.r, 2))
){
boll.vy = -boll.vy;
boll.vx = -boll.vx;
}
}
}