Javascript HTML5画布-敌人射击
我正在用HTML5画布制作一个游戏。现在我正试图让敌人(地空炮)可以朝玩家(飞机)的方向射击 我的游戏使用2个数组根据其中的值制作地图。因为游戏在通过地图之前不知道要在屏幕上放置多少敌人,所以我让它创建一个带有随机id的新敌人,并让它将其添加到一个对象中,以便在每次遇到地图上的敌人值时跟踪敌人 问题是当敌人向飞机射击时,他们都是以相同的角度射击,而不是以特定情况所需的角度射击 问题是:如何让每个敌人以正确的角度向玩家射击 我意识到这个问题/解释可能有点令人困惑,但请试一试。最好先看看第222-257行(updateEntity函数)。(请注意,这是一个与我的真实游戏代码不同的代码示例,它不是最好的。) 谷歌硬盘上的代码: JS小提琴: 全部代码:Javascript HTML5画布-敌人射击,javascript,canvas,trigonometry,Javascript,Canvas,Trigonometry,我正在用HTML5画布制作一个游戏。现在我正试图让敌人(地空炮)可以朝玩家(飞机)的方向射击 我的游戏使用2个数组根据其中的值制作地图。因为游戏在通过地图之前不知道要在屏幕上放置多少敌人,所以我让它创建一个带有随机id的新敌人,并让它将其添加到一个对象中,以便在每次遇到地图上的敌人值时跟踪敌人 问题是当敌人向飞机射击时,他们都是以相同的角度射击,而不是以特定情况所需的角度射击 问题是:如何让每个敌人以正确的角度向玩家射击 我意识到这个问题/解释可能有点令人困惑,但请试一试。最好先看看第222-2
<center><canvas id = "gameCanvas" width = "500" height = "500" style = "border:1px solid navy;"></canvas></center>
var canvas, ctx;
var clip = {};
var arsenal = {};
var enemyClip = {};
var keyDown = {};
var enemy = {};
window.onload = function() {
canvas = document.getElementById("gameCanvas");
ctx = canvas.getContext("2d");
for (var i = 0; i < 3; i++) {
createEnemy(Math.random(), i * 100 + 140);
}
setInterval(function() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
update();
}, 1000 / 30);
}
var player = {
x: 240,
y: 240,
w: 20,
h: 20,
color: "navy",
alive: true,
canShoot: true,
canNuke: true,
facingRight: true,
draw: function() {
ctx.fillStyle = this.color;
ctx.fillRect(this.x, this.y, this.w, this.h);
},
shoot: function() {
if (player.canShoot) {
player.canShoot = false;
if (player.facingRight) {
createPlayerBullet(Math.random(), player.x + player.w, player.y + player.h / 2, true);
} else {
createPlayerBullet(Math.random(), player.x, player.y + player.h / 2, false);
}
setTimeout(function() {
player.canShoot = true;
}, 750);
}
},
nuke: function() {
if (player.canNuke) {
player.canNuke = false;
createNuke(Math.random(), player.x + player.w / 2, player.y + player.h);
setTimeout(function() {
player.canNuke = true;
}, 2000);
}
}
}
//var enemy = {
// x:240,
// y:480,
// w:20,
// h:20,
// color:"maroon",
// alive:true,
// canShoot:true,
//
// draw:function(){
// ctx.fillStyle = this.color;
// ctx.fillRect(this.x, this.y, this.w, this.h);
// },
//
// shoot:function(){
// if(enemy.canShoot){
// enemy.canShoot = false;
//
// if(player.x >= enemy.x && player.y <= enemy.y){// Top Right: TF, Bottom Right: TT, Bottom Left: FT, Top Left: FF
// createEnemyBullet(Math.random(), enemy.x + enemy.w/2, enemy.y, player.x, player.y, true, false); // True equals ___ is greater than
// }else if(player.x >= enemy.x && player.y >= enemy.y){
// createEnemyBullet(Math.random(), enemy.x + enemy.w/2, enemy.y, player.x, player.y, true, true);
// }else if(player.x <= enemy.x && player.y >= enemy.y){
// createEnemyBullet(Math.random(), enemy.x + enemy.w/2, enemy.y, player.x, player.y, false, true);
// }else if(player.x <= enemy.x && player.y <= enemy.y){
// createEnemyBullet(Math.random(), enemy.x + enemy.w/2, enemy.y, player.x, player.y, false, false);
// }
//
// setTimeout(function(){
// enemy.canShoot = true;
// }, 750);
// }
// }
//}
var createEnemy = function(ID, X) {
var e = {
x: X,
y: 480,
w: 20,
h: 20,
color: "maroon",
alive: true,
canShoot: true,
id: ID,
draw: function() {
ctx.fillStyle = this.color;
ctx.fillRect(this.x, this.y, this.w, this.h);
},
shoot: function() {
if (this.canShoot) {
this.canShoot = false;
if (player.x >= this.x && player.y <= this.y) { // Top Right: TF, Bottom Right: TT, Bottom Left: FT, Top Left: FF
createEnemyBullet(Math.random(), this.x + this.w / 2, this.y, player.x, player.y, true, false); // True means greater than
} else if (player.x >= this.x && player.y >= this.y) {
createEnemyBullet(Math.random(), this.x + this.w / 2, this.y, player.x, player.y, true, true);
} else if (player.x <= this.x && player.y >= this.y) {
createEnemyBullet(Math.random(), this.x + this.w / 2, this.y, player.x, player.y, false, true);
} else if (player.x <= this.x && player.y <= this.y) {
createEnemyBullet(Math.random(), this.x + this.w / 2, this.y, player.x, player.y, false, false);
}
setTimeout(function() {
enemy.canShoot = true;
}, 750);
}
}
};
enemy[e.id] = e;
}
var createPlayerBullet = function(ID, X, Y, dir) {
var playerBullet = {
x: X,
y: Y,
w: 5,
h: 5,
color: "navy",
id: ID,
facingRight: dir,
draw: function() {
ctx.fillStyle = this.color;
ctx.fillRect(this.x, this.y, this.w, this.h);
}
}
clip[playerBullet.id] = playerBullet;
}
var createEnemyBullet = function(ID, X, Y, playerx, playery, dirx, diry) {
var enemyBullet = {
x: X,
y: Y,
w: 5,
h: 5,
color: "maroon",
id: ID,
dirX: dirx,
dirY: diry,
playerX: playerx,
playerY: playery,
draw: function() {
ctx.fillStyle = this.color;
ctx.fillRect(this.x, this.y, this.w, this.h);
}
}
enemyClip[enemyBullet.id] = enemyBullet;
}
var createNuke = function(ID, X, Y) {
var nuke = {
x: X,
y: Y,
w: 5,
h: 5,
color: "green",
id: ID,
draw: function() {
ctx.fillStyle = this.color;
ctx.fillRect(this.x, this.y, this.w, this.h);
}
}
arsenal[nuke.id] = nuke;
}
var updateEntity = function() {
for (var playerBullet in clip) {
clip[playerBullet].draw();
if (clip[playerBullet].facingRight) {
clip[playerBullet].x += 8;
} else {
clip[playerBullet].x -= 8;
}
if (clip[playerBullet].x <= 0) {
delete clip[playerBullet];
} else if (clip[playerBullet].x >= canvas.width) {
delete clip[playerBullet];
}
}
for (var nuke in arsenal) {
arsenal[nuke].draw();
arsenal[nuke].y += 3;
if (arsenal[nuke].y >= canvas.height) {
delete arsenal[nuke];
}
}
for (var enemyBullet in enemyClip) {
for (var e in enemy) {
var dx = enemy[e].x - enemyClip[enemyBullet].playerX;
var dy = enemy[e].y - enemyClip[enemyBullet].playerY;
var angle = Math.atan2(dy, dx);
}
enemyClip[enemyBullet].draw();
if (enemyClip[enemyBullet].dirX && !enemyClip[enemyBullet].dirY) {
enemyClip[enemyBullet].x -= 10 * Math.cos(angle);
enemyClip[enemyBullet].y -= 10 * Math.sin(angle);
} else if (enemyClip[enemyBullet].dirX && enemyClip[enemyBullet].dirY) {
enemyClip[enemyBullet].x -= 10 * Math.cos(angle);
enemyClip[enemyBullet].y -= 10 * Math.sin(angle);
} else if (!enemyClip[enemyBullet].dirX && enemyClip[enemyBullet].dirY) {
enemyClip[enemyBullet].x -= 10 * Math.cos(angle);
enemyClip[enemyBullet].y -= 10 * Math.sin(angle);
} else if (!enemyClip[enemyBullet].dirX && !enemyClip[enemyBullet].dirY) {
enemyClip[enemyBullet].x -= 10 * Math.cos(angle);
enemyClip[enemyBullet].y -= 10 * Math.sin(angle);
}
if (enemyClip[enemyBullet].x <= 0) {
delete enemyClip[enemyBullet];
} else if (enemyClip[enemyBullet].x >= canvas.width) {
delete enemyClip[enemyBullet];
} else if (enemyClip[enemyBullet].y <= 0) {
delete enemyClip[enemyBullet];
} else if (enemyClip[enemyBullet].y >= canvas.height) {
delete enemyClip[enemyBullet];
} else if (enemyClip[enemyBullet].x >= player.x && enemyClip[enemyBullet].x <= player.x + player.w && enemyClip[enemyBullet].y >= player.y && enemyClip[enemyBullet].y <= player.y + player.h) {
delete enemyClip[enemyBullet];
}
}
}
var update = function() {
updateEntity();
if (player.alive) {
player.draw();
}
//if(enemy.alive){
// enemy.draw();
// enemy.shoot();
//}
for (var e in enemy) {
ctx.fillStyle = enemy[e].color;
ctx.fillRect(enemy[e].x, enemy[e].y, enemy[e].w, enemy[e].h);
if (enemy[e].canShoot) {
enemy[e].canShoot = false;
if (player.x >= enemy[e].x && player.y <= enemy[e].y) { // Top Right: TF, Bottom Right: TT, Bottom Left: FT, Top Left: FF
createEnemyBullet(Math.random(), enemy[e].x + enemy[e].w / 2, enemy[e].y, player.x, player.y, true, false); // True equals ___ is greater than
} else if (player.x >= enemy[e].x && player.y >= enemy[e].y) {
createEnemyBullet(Math.random(), enemy[e].x + enemy[e].w / 2, enemy[e].y, player.x, player.y, true, true);
} else if (player.x <= enemy[e].x && player.y >= enemy[e].y) {
createEnemyBullet(Math.random(), enemy[e].x + enemy[e].w / 2, enemy[e].y, player.x, player.y, false, true);
} else if (player.x <= enemy[e].x && player.y <= enemy[e].y) {
createEnemyBullet(Math.random(), enemy[e].x + enemy[e].w / 2, enemy[e].y, player.x, player.y, false, false);
}
setTimeout(function() {
for (var e in enemy) {
enemy[e].canShoot = true;
}
}, 750);
}
}
if (37 in keyDown) {
player.facingRight = false;
player.x -= 5;
}
if (38 in keyDown) {
player.y -= 5;
}
if (39 in keyDown) {
player.facingRight = true;
player.x += 5;
}
if (40 in keyDown) {
player.y += 5;
}
if (32 in keyDown) {
player.shoot();
}
if (90 in keyDown) {
player.nuke();
}
}
addEventListener("keydown", function(e) {
keyDown[e.keyCode] = true;
});
addEventListener("keyup", function(e) {
delete keyDown[e.keyCode];
});
var画布,ctx;
var clip={};
var={};
var enemyClip={};
var keyDown={};
var敌人={};
window.onload=函数(){
canvas=document.getElementById(“gameCanvas”);
ctx=canvas.getContext(“2d”);
对于(变量i=0;i<3;i++){
create敌军(Math.random(),i*100+140);
}
setInterval(函数(){
clearRect(0,0,canvas.width,canvas.height);
更新();
}, 1000 / 30);
}
变量播放器={
x:240,
y:240,
w:20,
h:20,
颜色:“海军”,
活着:是的,
真的,
坎努克:没错,
facingRight:没错,
绘图:函数(){
ctx.fillStyle=this.color;
ctx.fillRect(this.x,this.y,this.w,this.h);
},
shoot:function(){
if(player.canShoot){
player.canShoot=false;
if(球员右脸){
createPlayerBullet(Math.random(),player.x+player.w,player.y+player.h/2,true);
}否则{
createPlayerBullet(Math.random(),player.x,player.y+player.h/2,false);
}
setTimeout(函数(){
player.canShoot=true;
}, 750);
}
},
nuke:function(){
if(player.canNuke){
player.canNuke=false;
createNuke(Math.random(),player.x+player.w/2,player.y+player.h);
setTimeout(函数(){
player.canNuke=true;
}, 2000);
}
}
}
//var敌人={
//x:240,
//y:480,
//w:20,
//h:20,
//颜色:“栗色”,
//活着:是的,
//真的,
//
//绘图:函数(){
//ctx.fillStyle=this.color;
//ctx.fillRect(this.x,this.y,this.w,this.h);
// },
//
//shoot:function(){
//如果(敌人可以射击){
//敌人。可以射击=错误;
//
//如果(player.x>=敌方.x&&player.y=敌方.x&&player.y>=敌方.y){
//createneMyBullet(Math.random(),敌方.x+敌方.w/2,敌方.y,玩家.x,玩家.y,真,真);
//}else if(player.x=敌军.y){
//createneMyBullet(Math.random(),敌方.x+敌方.w/2,敌方.y,玩家.x,玩家.y,false,true);
//}else if(player.x=this.y){
createneMyBullet(Math.random(),this.x+this.w/2,this.y,player.x,player.y,true,true);
}else if(player.x=this.y){
createneMyBullet(Math.random(),this.x+this.w/2,this.y,player.x,player.y,false,true);
}否则如果(player.x=player.x&&enemyClip[enemyBullet].x=player.y&&enemyClip[enemyBullet].y=敌军[e]。x&&player.y=敌军[e]。x&&player.y>=敌军[e].y){
createneMyBullet(Math.random(),敌人[e].x+敌人[e].w/2,敌人[e].y,player.x,player.y,true,true);
}else if(player.x=敌人[e].y){
createneMyBullet(Math.random(),敌人[e].x+敌人[e].w/2,敌人[e].y,player.x,player.y,false,true);
}else if(player.x此代码位于updateEntity
for (var enemyBullet in enemyClip) {
for (var e in enemy) {
var dx = enemy[e].x - enemyClip[enemyBullet].playerX;
var dy = enemy[e].y - enemyClip[enemyBullet].playerY;
var angle = Math.atan2(dy, dx);
}
应该在没有for循环的情况下编写。您应该只引用开枪的敌人
for (var enemyBullet in enemyClip) {
var bullet = enemyClip[enemyBullet];
var dx = bullet.enemyX - bullet.playerX;
var dy = bullet.enemyY - bullet.playerY;
var angle = Math.atan2(dy, dx);
但是,不要在子弹被射出时存储所有这些信息,您应该只计算子弹被射出时的角度(子弹没有必要知道玩家的位置,而且“dir”值似乎没有必要)
您的updateEntity
代码将变成:
for (var enemyBullet in enemyClip) {
var angle = enemyClip[enemyBullet].angle;
在你进一步之前,我建议你看一下你的代码,看看如何简化它。有很多可以被删除的东西。你在2个地方创建了敌人的子弹,每个地方有4个调用<代码> createEnemyBullet < /代码>,同时也考虑敌人的子弹和玩家的子弹是什么样的。
不是生成唯一id的好方法。每次只需使用递增的数字(尽管此代码中没有id的真正原因)你的问题是,它涉及许多不同的部分,这不符合本问答环节的形式。如果你问如何以编程方式计算角度,并向我们展示了你的尝试,这是一回事,但你的问题远不止这些。
for (var enemyBullet in enemyClip) {
var angle = enemyClip[enemyBullet].angle;