2017-03-11 50 views
-2

我在HTML5画布中制作游戏。现在我正在努力做到这一点,因此敌人(地面对空气枪)可以朝着玩家(飞机)的方向射击。HTML5画布 - 敌人射击

我的游戏根据数值使用2个数组来制作地图。因为游戏不会知道屏幕上有多少敌人穿过地图,我会用随机ID创建一个新敌人,并将它添加到每次跟踪敌人的物体上它在地图上遇到敌方值。

问题出现在敌人在飞机上射击时,他们都以相同的角度射击,而不是以特定情况所需的角度射击。

下面是问题:如何让每个敌人以正确的角度向玩家射击?

我意识到,这个问题/解释可能有点混淆理解,但请给它一个镜头。开始查看第222-257行(updateEntity函数)会很好。 (请注意,这是我真正的游戏代码的单独代码示例,它不是最好的。)

代码在谷歌驱动器:https://drive.google.com/open?id=0By026U5OT4C7OUZSNG5GM19kV1U

JS小提琴:https://jsfiddle.net/k2xwypkp/

整个代码:

<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]; 
}); 

我很欣赏你花在尝试(并希望)帮助我的时间。谢谢。

+2

http://stackoverflow.com/help/mcve – ceejayoz

+1

你的问题的问题是它涉及很多不同的部分和这不符合本Q&A会议的格式。如果您询问如何以编程方式计算角度并向我们展示您所尝试的内容,那是一回事,但您的问题涉及的远多于此。 – Rob

回答

1

这段代码在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”价值似乎是不必要的),然后

if (enemy[e].canShoot) { 
    enemy[e].canShoot = false; 
    var angle = Math.atan2(enemy[e].y-player.y, enemy[e].x-player.x); 
    ...  
    createEnemyBullet(Math.random(), angle, enemy[e].x + enemy[e].w/2, enemy[e].y); 

updateEntity代码只是变成:

for (var enemyBullet in enemyClip) { 
    var angle = enemyClip[enemyBullet].angle; 

你走得更远之前,我建议你看看在你的代码和审查如何可以简化它有很多可以被删除。你在2个地方制造敌方子弹,每个地方有4个电话createEnemyBullet也考虑敌方子弹和子弹是如何相同的。另外Math.random()不是生成唯一ID的好方法。每次只使用一个递增的数字(虽然这个代码中的id没有真正的原因)