canvas画布实现飞机大战

标签: js  javascript  javascript

效果

下面是详细代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style type="text/css">
    	*{
    		margin: 0;
    		padding: 0;
    	}
    	#can1{
    		border: solid 1px red;
    		margin-left: 100px;
    		margin-top: 10px;
    	}
		.start,.score{
			width: 200px;
			margin: auto;
		}
		.start{
			margin-top: 20px;
		}
		.start button{
			width: 90px;
			height: 35px;
		}
		.score{
			color: red;
			margin-top: 20px;
			visibility: visible;
		}
    </style>
</head>
<body>
	<div class="start">
		<button>开始游戏</button>
		<button>停止游戏</button>
	</div>
	<div class="score">
		分数:
	</div>
   	<canvas id="can1" width="600" height="400"></canvas>
	<script src="./hero.js"></script>
	<script src="./bullet.js"></script>
	<script src="./game.js"></script>
</body>
</html>
function Hero(options) {
	this.x = options.x;
	this.y = options.y;
	this.speed = options.speed;
	this.moveDeley = options.moveDeley;
	this.bullet = [];
	this.life = 40;
	this.color = options.color;
	ctx.lineWidth = "1"
	ctx.fillRect(this.x, this.y, 40, 40);
}
Hero.prototype.draw = function() {
	ctx.fillStyle = this.color;
	ctx.fillRect(this.x, this.y, 40, 40);
	if (this.color == "blue") {
		ctx.fillRect(this.x - 15, this.y, 10, this.life);
	} else {
		ctx.fillRect(this.x + 45, this.y, 10, this.life);
	}
}

Hero.prototype.createBullet = function(options) {
	if (options.color == "blue") {
		let bu = new Bullet({
			x: options.x + 40,
			y: options.y + 20 - 5,
			Hurt: 10,
			color: options.color,
		})
		this.bullet.push(bu);
	} else {
		let bu = new Bullet({
			x: options.x,
			y: options.y + 20 - 5,
			Hurt: 10,
			color: options.color,
		})
		this.bullet.push(bu);
	}
}
function Bullet(options) {
	this.x = options.x;
	this.y = options.y;
	this.Hurt = options.Hurt;
	this.interval = null;
	this.color = options.color;
	ctx.lineWidth = "1"
	ctx.fillStyle = "blue"
	ctx.fillRect(this.x, this.y, 20, 10);
}

Bullet.prototype.draw = function() {
	ctx.fillStyle = this.color;
	ctx.fillRect(this.x, this.y, 20, 10);
}
let score = 0; //分数 
let scorediv = document.querySelector(".score"); //分数div
let canvas = document.querySelector("#can1"); //获取画布
let ctx = canvas.getContext("2d"); //获取画布对象
var enemyArr = []; //敌人数组
var timeouts = null; //子弹移动和界面刷新的定时器
let hero = null; //英雄
var timeouts2 = null; //随机产生敌人的定时器
let GameButton = document.querySelectorAll("button"); //两个游戏按钮 开始和暂停

/**
 * 游戏开始
 */
GameButton[0].addEventListener("click", () => {
	bindKeyEvent();
	hero = new Hero({
		x: 10,
		y: 10,
		speed: 10,
		color: "blue",
		moveDeley: 20
	})
	resetdraw();
	createEnemy();
	GameButton[0].style.visibility = "hidden"
	GameButton[1].style.visibility = "visible"
})

/**
 * 游戏停止
 */
GameButton[1].addEventListener("click", () => {
	document.onkeydown = null;
	document.onkeyup = null;
	clearTimeout(timeouts);
	clearTimeout(timeouts2);
	hero = null;
	enemyArr = [];
	GameButton[0].style.visibility = "visible"
	GameButton[1].style.visibility = "hidden"
})


/**
    刷新界面
    调用英雄的重绘 和子弹的重绘 以及子弹的移动
*/
function resetdraw() {
	if (timeouts != null)
		clearTimeout(timeouts);
	ctx.clearRect(0, 0, 600, 400); //刷新界面
	hero.draw(); //英雄重绘
	//英雄的子弹重绘和移动
	for (let i = 0; i < hero.bullet.length; i++) {
		hero.bullet[i].draw(); //子弹重绘
		hero.bullet[i].x += 5;
		if (bulletAcEnemy(hero.bullet[i])) {
			hero.bullet.splice(i, 1);
			continue;
		}
		if (hero.bullet[i].x > 600) {
			hero.bullet.splice(i, 1);
		}
	}
	//敌人的子弹重绘移动和对英雄的碰撞
	for (let i = 0; i < enemyArr.length; i++) {
		for (let j = 0; j < enemyArr[i].bullet.length; j++) {
			let enemyBullet = enemyArr[i].bullet[j];
			enemyBullet.draw();
			enemyBullet.x -= 5;
			if (enemyBullet.x < 50) {
				enemyArr[i].bullet.splice(j, 1);
			}
			if (bulletAcHero(enemyBullet)) {
				enemyArr[i].bullet.splice(j, 1);
				hero.life -= 2;
			}
		}
	}
	//敌人的重绘和移动
	for (let i = 0; i < enemyArr.length; i++) {
		enemyArr[i].draw(); //敌人重绘
		enemyArr[i].x -= 1;
		if (enemyArr[i].x < 50 || enemyArr[i].life == 0) {
			enemyArr.splice(i, 1);
		}
	}
	timeouts = setTimeout(resetdraw, 10);
}

/**
 * 随机产生敌人
 */
function createEnemy() {
	if (timeouts2 != null) {
		clearTimeout(timeouts2);
	}
	let point = [0, 60, 120, 180, 240, 300, 360]
	let y = parseInt(Math.random() * point.length)
	enemyArr.push(
		new Hero({
			x: 600,
			y: point[y],
			speed: 10,
			color: "red",
			moveDeley: 20
		})
	)
	EnemyCreatBullet();
	timeouts2 = setTimeout(createEnemy, 2000)
}

/**
 * 创建敌机子弹
 */
function EnemyCreatBullet() {
	for (let i = 0; i < enemyArr.length; i++) {
		enemyArr[i].createBullet({
			color: "red",
			x: enemyArr[i].x,
			y: enemyArr[i].y
		})
	}
}


/**
 * 子弹碰撞敌人检测
 * @param {*} bullet 
 */
function bulletAcEnemy(bullet) {
	for (let i = 0; i < enemyArr.length; i++) {
		let enemy = enemyArr[i];
		if ((bullet.x + 20 >= enemy.x) && (bullet.x + 20 < enemy.x + 50) &&
			(bullet.y + 10 >= enemy.y) && (bullet.y + 10 <= enemy.y + 50)) {
			enemyArr[i].life -= 10;
			if (enemyArr[i].life == 0) score += 10;
			scorediv.innerHTML = "分数:" + score;
			return true;
		}
	}
}

/**
 * 子弹碰撞英雄检测
 */
function bulletAcHero(bullet) {
	if ((bullet.x >= hero.x) && (bullet.x <= hero.x + 40) &&
		(bullet.y + 10 >= hero.y) && (bullet.y + 10 <= hero.y + 40)) {
		return true;
	}
}

/**
 * 英雄的移动方法
 */
let move = {
	lefts: null,
	ups: null,
	downs: null,
	rights: null,
	left() {
		this.lefts = setInterval(() => {
			if (hero.x > 0) {
				hero.x -= hero.speed;
				hero.draw();
			}
		}, hero.moveDeley)
	},
	up() {
		this.ups = setInterval(() => {
			if (hero.y > 0) {
				hero.y -= hero.speed;
				hero.draw();
			}
		}, hero.moveDeley)
	},
	down() {
		this.downs = setInterval(() => {
			if (hero.y < 360) { //计算时 还要减去自己宽高
				hero.y += hero.speed;
				hero.draw();
			}
		}, hero.moveDeley)
	},
	right() {
		this.rights = setInterval(() => {
			if (hero.x < 560) { //计算时 还要减去自己宽高
				hero.x += hero.speed;
				hero.draw();
			}
		}, hero.moveDeley)
	}
}




/**
 * 绑定键盘监听事件
 */
let up = false,
	left = false,
	right = false,
	down = false;

function bindKeyEvent() {
	document.onkeydown = function(e) {
		switch (e.keyCode) {
			case 32:
				hero.createBullet({
					color: "blue",
					x: hero.x,
					y: hero.y
				});
				break;
			case 38: //up
				if (!up) {
					up = true;
					move.up();
				}
				break;
			case 39: //right
				if (!right) {
					right = true;
					move.right();
				}
				break;
			case 40: //down
				if (!down) {
					down = true;
					move.down();
				}
				break;
			case 37: //left
				if (!left) {
					left = true;
					move.left();
				}
				break;
		}
	}

	document.onkeyup = function(e) {
		switch (e.keyCode) {
			case 38: //up
				up = false;
				clearInterval(move.ups);
				break;
			case 39: //right
				right = false;
				clearInterval(move.rights);
				break;
			case 40: //down
				down = false;
				clearInterval(move.downs);
				break;
			case 37: //left
				left = false;
				clearInterval(move.lefts);
				break;
		}
	}
}

 

原文链接:加载失败,请重新获取