2017-03-11 18 views
-2

私はHTML5キャンバスでゲームを作っています。今私はそれを作ろうとしているので、敵(地面に飛ぶ銃)はプレーヤー(飛行機)の方向に撃つことができます。HTML5キャンバス - 敵対

私のゲームでは、2つの配列を使用してその値に応じたマップを作成します。ゲームがマップを通過するまで画面に表示される敵の数はわからないので、ランダムなIDを持つ新しい敵を作成し、毎回敵を追跡するオブジェクトに追加するようにしますそれはマップの敵の価値を横切って来る。

この問題は、敵が飛行機で撃つときに起こります。彼らはすべて同じ角度で撮影し、その特定の状況に必要な角度ではありません。

ここに質問があります:どのようにすれば、各敵を正しい角度でプレーヤーに撃つことができますか?

私は、この質問/説明が少し分かりにくいかもしれないことを理解していますが、それを一撃してください。行222-257(updateEntity関数)を見るのがよいでしょう。 (それが最高ではないですが、これは私の本当のゲームコードとは別のコード例があることに注意してください。)Googleで

コードはドライブ: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つの場所で敵の弾丸を作成し、各場所はcreateEnemyBulletへの4コールを持っている方法も敵の弾丸とプレイヤーの弾丸が同じであると考えています。またMath.random()は一意のIDを生成する良い方法ではありません。毎回インクリメントする番号を使用してください(このコードでIDの本当の理由はありませんが)。