2017-03-11 3 views
-2

Ich mache ein Spiel in HTML5 Canvas. Im Moment versuche ich es so zu machen, dass der Feind (ein Boden zum Luftgewehr) in Richtung des Spielers (eines Flugzeugs) schießen kann.HTML5 Canvas - Enemy Shooting

Mein Spiel verwendet 2 Arrays, um eine Karte entsprechend den darin enthaltenen Werten zu erstellen. Da das Spiel nicht weiß, wie viele Gegner auf den Bildschirm gesetzt werden, bis es die Karte durchläuft, erstelle ich einen neuen Feind mit einer zufälligen ID und lasse es zu einem Objekt hinzufügen, das jedes Mal die Feinde verfolgt Es trifft auf einen Feind in der Karte.

Das Problem kommt, wenn die Feinde auf das Flugzeug schießen, schießen sie alle im gleichen Winkel, und nicht in dem Winkel für diese besondere Situation notwendig.

Hier ist die Frage: Wie kann ich jeden Gegner dazu bringen, im richtigen Winkel auf den Spieler zu schießen?

Ich realisiere, dass diese Frage/Erklärung ein wenig verwirrend sein kann, aber bitte geben Sie es eine Chance. Es wäre gut, mit den Zeilen 222-257 zu beginnen (Die updateEntity-Funktion). (Bitte beachten Sie, dass dies ein separater Code Beispiel aus meinem realen Spielcode, es ist nicht die beste.)

-Code auf Google Drive: https://drive.google.com/open?id=0By026U5OT4C7OUZSNG5GM19kV1U

JS Fiddle: https://jsfiddle.net/k2xwypkp/

Ganzer Code:

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

Ich schätze Ihre Zeit verbrachte versuchen (und hoffentlich) helfen mir. Vielen Dank.

+2

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

+1

Das Problem mit Ihrer Frage ist, dass es eine Menge verschiedener Stücke und Das passt nicht zum Format dieser Q & A-Sitzung. Wenn Sie gefragt haben, wie man einen Winkel programmatisch berechnet und uns zeigt, was Sie versucht haben, ist das eine Sache, aber Ihre Frage ist viel mehr als das. – Rob

Antwort

1

Dieser Code in 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); 
    } 

Sollte ohne die for-Schleife geschrieben werden. Sie sollten sich nur auf den Feind beziehen, der die Kugel geschossen hat.

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

Anstatt jedoch all diese Informationen zu speichern, wenn eine Kugel geschossen wird, sollten Sie nur den Winkel der Kugel berechnen, wenn es gedreht wird (es nicht notwendig ist, dass die Kugel die Spielerposition zu erkennen, und die ' dir‘Wert scheint nicht notwendig)

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

Ihr updateEntity Code wird dann nur:

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

Bevor Sie weiter gehen würde ich vorschlagen, dass Sie aussehen an Ihrem Code und überprüfen, wie Sie es vereinfachen können, gibt es eine Menge, die entfernt werden könnte. Du erschaffst gegnerische Kugeln an 2 Stellen und jeder Ort hat 4 Aufrufe an createEnemyBullet auch überlegen, wie feindliche Kugeln und Spieler Kugeln sind die gleichen. Auch Math.random() ist keine gute Möglichkeit, eine eindeutige ID zu generieren. Verwenden Sie einfach eine steigende Zahl jedes Mal (obwohl es keinen wirklichen Grund für die ID in diesem Code gibt)