比较画布上两个位置的 x/y

Comparing x/y of two positions on a canvas

本文关键字:位置 两个 比较      更新时间:2023-09-26

im 使用画布来可视化我的一个小游戏。基本上,我有两个代表宇宙飞船的对象,每个对象都有一个"位置"数组,用于保存飞船当前的 x/y。根据这些数组,我在画布上绘制图像(总 w/h 是 300/300 fyi(。

现在,对于困难的部分。我想在画布上绘制动画(枪声(。基本上从 Ship1 X/Y 到 Ship2 X/Y。

对于动画函数本身,im 传递一个包含 3 个数组的效果对象,shooter.location[x, y]、target.location[x, y] 和第三个数组,该数组保存 EFFECT 当前位于 [x, y] 的位置。

this.animateEffects = function(effects){
    var shooter = effects.shooter;
    var target = effects.target;
    var current = effects.current;
    var canvas = document.getElementById("effects");
    var context = canvas.getContext("2d");
        context.clearRect(0, 0, canvas.width, canvas.height);
        context.beginPath();
        context.fillStyle = "red";
        context.arc(current[0], current[1], 5, 0, 2*Math.PI);
        effects.current[0]++
        effects.current[1]++
        context.fill();
        if (current == target){
            console.log("ding");
            this.end()
        }
}

我的"问题"是,如果可能的话,我正在寻找一种聪明的方法来确定(对于每一帧(效果[x,y]是否应该去++或 - 或两者的组合,这取决于"移动"的船位于何处(当时,拍摄开始(。

任何建议或提示不胜感激。

您可以使用线性插值将子弹从射手发射到目标。

  1. 计算射手和目标的原始X和Y位置的差异。

    // save the starting position of the bullet (== shooter's original position)
    // (these original X & Y are needed in the linear interpolation formula)
    bulletOriginalX=shooter.x;
    bulletOriginalY=shooter.y;
    // calc the delta-X & delta-Y of the shooter & target positions
    // (these deltas are needed in the linear interpolation formula)
    dx=target.x-shooter.x;
    dy=target.y-shooter.y;
    
  2. 使用插值公式将项目符号移向目标

    // where percent == the percent you want the bullet to be between 
    // it's starting & ending positions
    // (between starting shooter & starting target positions)
    currentBulletX=bulletOriginalX+dx*percent;
    currentBulletY=bulletOriginalY+dy*percent;
    

下面是一个示例:

var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
shooter={x:50,y:50};
target={x:100,y:100};
effect={x:50,y:50,dx:0,dy:0,pct:0,speedPct:0.25};
draw();
fire();
$('#test').click(function(){
  moveEffect();
  draw();
});
function fire(){
  effect.x=shooter.x;
  effect.y=shooter.y;
  effect.dx=target.x-shooter.x;
  effect.dy=target.y-shooter.y;
  effect.pct=0;
}
function moveEffect(){
  effect.pct+=effect.speedPct;
}
function draw(){
  ctx.clearRect(0,0,cw,ch);
  ctx.beginPath();
  ctx.arc(shooter.x,shooter.y,15,0,Math.PI*2);
  ctx.closePath();
  ctx.strokeStyle='green';
  ctx.stroke();
  ctx.beginPath();
  ctx.arc(target.x,target.y,15,0,Math.PI*2);
  ctx.closePath();
  ctx.strokeStyle='red';
  ctx.stroke();
  if(effect.pct>1){return;}
  var x=effect.x+effect.dx*effect.pct;
  var y=effect.y+effect.dy*effect.pct;
  ctx.beginPath();
  ctx.arc(x,y,3,0,Math.PI*2);
  ctx.closePath();
  ctx.fillStyle='black';
  ctx.fill();
}
body{ background-color: ivory; padding:10px; }
#canvas{border:1px solid red;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<button id=test>Animate 1 frame</button>
<br><canvas id="canvas" width=300 height=300></canvas>