canvas 游戏 乒乓球

直接贴代码:

/**
 * 游戏类
 */
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;
		}
	}

}





  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值