简单模拟打飞机的游戏,核心技术用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人参与
发表评论: