简单模拟打飞机的游戏,核心技术用javascript和canvas开发的,一起来了解下:
鼠标右键移动,鼠标左键攻击,移动的时候不能攻击,飞机有效射程是 300 码,敌机会侦察周围 300 码的地方,如果你与敌机的距离低于 300 码,敌机会主动追踪你,但是敌机需要飞到距离你 200 码的时候才会射击,因为敌机的有效射程是 200 码,当前版本里你的飞机是无敌的,要死亡的话把底下 2 行注释改过来就行了。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>飞机大战</title>
<style>
html,body,canvas {
margin: 0;
width: 100vw;
height: 100vh;
background-color: #000;
overflow: hidden;
}
</style>
</head>
<body>
<canvas></canvas>
<script>
window.onload = function() {
var canvas = document.querySelector("canvas");
var width = window.innerWidth;
var height = window.innerHeight;
canvas.width = width;
canvas.height = height;
var ctx = canvas.getContext("2d");
var effects = [];
var count = 0;
function random(min, max) {
return Math.floor(Math.random() * (max - min) + min);
}
function collision(a, b) {
var ax1 = a.x - a.size / 2;
var ax2 = a.x + a.size / 2;
var ay1 = a.y - a.size / 2;
var ay2 = a.y + a.size / 2;
var bx1 = b.x - b.size / 2;
var bx2 = b.x + b.size / 2;
var by1 = b.y - b.size / 2;
var by2 = b.y + b.size / 2;
return !(ax1 > bx2 || ax2 < bx1 || ay1 > by2 || ay2 < by1);
}
function Airplane() {
var texture = new Image();
texture.src = "http://pic.yupoo.com/pines/fabd3716/342bfcb9.png";
this.x = width / 2;
this.y = height / 2;
this.orginX = this.x;
this.orginY = this.y;
this.size = 50;
this.anchorX = 0 - this.size / 2;
this.anchorY = 0 - this.size / 2;
this.texture = texture;
this.blood = 100;
this.angle = -45 * Math.PI / 180;
this.speed = 5;
this.isMove = false;
this.rockets = [];
this.count = 0;
this._dist = 0;
this.dist = 0;
}
Airplane.prototype = {
render: function() {
this.draw();
if (this.isMove) {
this.move();
}
},
draw: function() {
ctx.save();
ctx.translate(this.x, this.y);
ctx.rotate(this.angle);
ctx.drawImage(this.texture, this.anchorX, this.anchorY, this.size, this.size);
ctx.restore();
},
attack: function(angle) {
this.angle = angle;
var texture = new Image();
texture.src = "http://pic.yupoo.com/pines/fb85d82b/f6bd8b88.png";
var speed = 10;
for (var i = 0; i < 2; i++) {
var x = this.x + this.size / 3 * Math.cos(this.angle + (1 - 4 * i) * Math.PI / 4);
var y = this.y + this.size / 3 * Math.sin(this.angle + (1 - 4 * i) * Math.PI / 4);
var rocket = new Rocket(x, y, this.angle, speed, texture, 300);
this.rockets[this.count] = rocket;
this.count += 1;
}
},
move: function() {
this.x += this.speed * Math.cos(this.angle - Math.PI / 4);
this.y += this.speed * Math.sin(this.angle - Math.PI / 4);
this._dist = Math.pow(this.x - this.orginX, 2) + Math.pow(this.y - this.orginY, 2);
if (this._dist >= this.dist) {
this.isMove = false;
}
},
hit: function(n) {
this.blood -= n;
if (this.blood <= 0) {
this.die = true;
}
},
explosion: function() {
var x = this.x - this.size * Math.cos(Math.PI / 4);
var y = this.y - this.size * Math.sin(Math.PI / 4);
var effect = new Effect(x, y, this.size);
effects[count] = effect;
count += 1;
}
};
function Enemy() {
var texture = new Image();
texture.src = "http://pic.yupoo.com/pines/35de8b71/a1b87dde.png";
this.size = 40;
this.x = Math.random() * (width - this.size * 2) + this.size;
this.y = Math.random() * (height - this.size * 2) + this.size;
this.orginX = this.x;
this.orginY = this.y;
this.anchorX = 0 - this.size / 2;
this.anchorY = 0 - this.size / 2;
this.texture = texture;
this.blood = 10;
this.angle = Math.random() * Math.PI * 2;
this.speed = 1;
this.disX = 0;
this.disY = 0;
this.rockets = [];
this.count = 0;
this._dist1 = 0;
this._dist2 = 0;
this.dist1 = random(100, 300);
this.dist2 = 300;
this.dx = 0;
this.dy = 0;
this.die = false;
this.interval = 0;
}
Enemy.prototype = {
initState: function() {
this.orginX = this.x;
this.orginY = this.y;
this._dist1 = 0;
this.dist1 = random(100, 300);
},
render: function() {
this.move();
this.draw();
},
draw: function() {
ctx.save();
ctx.translate(this.x, this.y);
ctx.rotate(this.angle);
ctx.drawImage(this.texture, this.anchorX, this.anchorY, this.size, this.size);
ctx.restore();
},
move: function() {
this.disX = this.speed * Math.cos(this.angle - Math.PI / 4);
this.disY = this.speed * Math.sin(this.angle - Math.PI / 4);
this.x += this.disX;
this.y += this.disY;
this._dist1 = Math.pow(this.x - this.orginX, 2) + Math.pow(this.y - this.orginY, 2);
if (this._dist1 >= Math.pow(this.dist1, 2)) {
this.angle += random(-45, 45) * Math.PI / 180;
this.angle %= Math.PI * 2;
this.initState();
}
this.dx = airplane.x - this.x;
this.dy = airplane.y - this.y;
this._dist2 = Math.pow(this.dx, 2) + Math.pow(this.dy, 2);
if (this._dist2 <= Math.pow(this.dist2, 2)) {
this.angle = Math.atan2(this.dy, this.dx) + Math.PI / 4;
if (this._dist2 <= Math.pow(200, 2)) {
this.speed = 0;
if (this.interval % 50 === 0) {
this.interval = 0;
this.attack();
}
this.interval += 1;
} else {
this.speed = 1;
this.initState();
this.dist1 = 100;
}
}
if (this.x < -this.size && this.disX < 0 || this.x > width + this.size && this.disX > 0 || this.y < -this.size && this.disY < 0 || this.y > height + this.size && this.disY > 0) {
this.angle += Math.PI / 2;
this.angle %= Math.PI * 2;
this.initState();
}
},
attack: function() {
var texture = new Image();
texture.src = "http://pic.yupoo.com/pines/b3bf2b4a/5ebf09f8.png";
var speed = 3;
var x = this.x + this.size / 2 * Math.cos(this.angle - Math.PI / 4);
var y = this.y + this.size / 2 * Math.sin(this.angle - Math.PI / 4);
var rocket = new Rocket(x, y, this.angle, speed, texture, 200);
this.rockets[this.count] = rocket;
this.count += 1;
},
explosion: function() {
var x = this.x - this.size * Math.cos(Math.PI / 4);
var y = this.y - this.size * Math.sin(Math.PI / 4);
var effect = new Effect(x, y, this.size);
effects[count] = effect;
count += 1;
effects = effects.filter(function(effect) {
return !!effect;
});
},
hit: function() {
this.blood -= 1;
if (this.blood <= 0) {
this.die = true;
}
}
}
var airplane = new Airplane();
var enemys = [];
for (var i = 0; i < 20; i++) {
enemys.push(new Enemy());
}
function Rocket(x, y, angle, speed, texture, maxDist) {
this.x = x;
this.y = y;
this.orginX = this.x;
this.orginY = this.y;
this.size = 20;
this.anchorX = 0 - this.size / 2;
this.anchorY = 0 - this.size / 2;
this.texture = texture;
this.angle = angle;
this.speed = speed;
this._dist = 0;
this.maxDist = maxDist;
this.die = false;
}
Rocket.prototype = {
render: function() {
if (!this.die) {
this.x += this.speed * Math.cos(this.angle - Math.PI / 4);
this.y += this.speed * Math.sin(this.angle - Math.PI / 4);
this._dist = Math.pow(this.x - this.orginX, 2) + Math.pow(this.y - this.orginY, 2);
this.draw();
if (this._dist >= Math.pow(this.maxDist, 2)) {
this.die = true;
this.explosion();
}
}
},
draw: function() {
ctx.save();
ctx.translate(this.x, this.y);
ctx.rotate(this.angle);
ctx.drawImage(this.texture, this.anchorX, this.anchorY, this.size, this.size);
ctx.restore();
},
explosion: function() {
var x = this.x - this.size * Math.cos(Math.PI / 4);
var y = this.y - this.size * Math.sin(Math.PI / 4);
var effect = new Effect(x, y, this.size);
effects[count] = effect;
count += 1;
}
};
function Effect(x, y, size) {
var texture = new Image();
texture.src = "http://pic.yupoo.com/pines/eb59179b/4d5a9fac.png";
this.x = x;
this.y = y;
this.i = 0;
this.size = size * 1.5;
this.texture = texture;
this.die = false;
}
Effect.prototype = {
render: function() {
var x = (this.i % 8) * 256;
var y = Math.floor(this.i / 8) * 256;
ctx.drawImage(this.texture, x, y, 256, 256, this.x, this.y, this.size, this.size);
if (this.i >= 31) {
this.die = true;
}
this.i += 1;
}
}
canvas.addEventListener("click", function(ev) {
if (!airplane.isMove) {
var x = ev.offsetX;
var y = ev.offsetY;
var angle = Math.atan2(y - airplane.y, x - airplane.x) + Math.PI / 4;
airplane.attack(angle);
}
}, false);
canvas.addEventListener("contextmenu", function(ev) {
var targetX = ev.offsetX;
var targetY = ev.offsetY;
var dx = targetX - airplane.x;
var dy = targetY - airplane.y;
airplane.dist = Math.pow(dx, 2) + Math.pow(dy, 2);
if (airplane.dist >= 20) {
airplane.orginX = airplane.x;
airplane.orginY = airplane.y;
airplane.angle = Math.atan2(dy, dx) + Math.PI / 4;
airplane.isMove = true;
}
ev.preventDefault();
});
function animate() {
if (!airplane.die) {
ctx.clearRect(0, 0, width, height);
for (var i in airplane.rockets) {
var rocket = airplane.rockets[i];
if (rocket && !rocket.die) {
rocket.render();
for (var j in enemys) {
var enemy = enemys[j];
if (collision(rocket, enemy)) {
rocket.die = true;
rocket.explosion();
enemy.hit();
if (enemy.die) {
enemy.explosion();
delete enemys[m];
}
}
}
} else {
delete airplane.rockets[i];
}
}
airplane.render();
for (var m in enemys) {
var enemyAir = enemys[m];
if (enemyAir && !enemyAir.die) {
for (var n in enemyAir.rockets) {
var enemyRocket = enemyAir.rockets[n];
if (enemyRocket && !enemyRocket.die) {
enemyRocket.render();
if (collision(enemyRocket, airplane)) {
enemyRocket.die = true;
enemyRocket.explosion();
//airplane.hit(1);
if (airplane.die) {
airplane.explosion();
}
}
} else if (enemyRocket && enemyRocket.die) {
delete enemyAir.rockets[n];
}
}
enemyAir.render();
if (collision(enemyAir, airplane)) {
enemyAir.die = true;
enemyAir.explosion();
//airplane.hit(10);
if (airplane.die) {
airplane.explosion();
}
}
} else if (enemyAir && enemyAir.die) {
delete enemys[m];
enemys = enemys.filter(function(enemy) {
return !!enemy;
});
if (enemys.length < 20) {
setTimeout(function() {
enemys.push(new Enemy());
}, 2000)
}
}
}
for (var e in effects) {
var effect = effects[e];
if (effect && !effect.die) {
effect.render();
} else if (effect && effect.die) {
delete effects[e];
}
}
}
requestAnimationFrame(animate)
}
animate();
};
</script>
</body>
</html> 







网友评论文明上网理性发言 已有0人参与
发表评论: