Javascript:如何移动与其旋转相关的上下文对象

Javascript:如何移动与其旋转相关的上下文对象,javascript,canvas,vector,rotation,Javascript,Canvas,Vector,Rotation,我想使用html画布制作游戏。我的目标是上下移动一个矩形,当我按下左键和右键时它会旋转。就像汽车一样,汽车只向前和向后行驶,但不向左和向右行驶,而是旋转。 唯一的问题是我的矩形会旋转,但它不会随着旋转而移动,它只会上下移动,不管它面对的是什么 this.Draw = function() { //this goes inside constructor ctx.clearRect(0,0,ctx.canvas.width, ctx.canvas.height); ctx.s

我想使用html画布制作游戏。我的目标是上下移动一个矩形,当我按下左键和右键时它会旋转。就像汽车一样,汽车只向前和向后行驶,但不向左和向右行驶,而是旋转。 唯一的问题是我的矩形会旋转,但它不会随着旋转而移动,它只会上下移动,不管它面对的是什么

this.Draw = function() {    //this goes inside constructor
    ctx.clearRect(0,0,ctx.canvas.width, ctx.canvas.height);
    ctx.save();
    ctx.fillStyle = this.color;
    ctx.translate(this.x, this.y);
    ctx.rotate(this.angle * Math.PI / 180);
    ctx.fillRect( -1* this.width/2 , -1* this.height/2, this.width, this.height); //center context to get a center rotation
    ctx.restore();   };
我不知道如何向前移动矩形,所以它只是上下移动。 对于我的矩形移动,我使用了一个包含4个输入的列表,当它们为真时,它们将移动。在这里:

this.inputWASD = [false,false,false,false]; //this goes inside constructor
//input for ---->[ W  ,  A  ,   S  ,   D ]  <--------- 

switch(keyDown.key){
    case 87: //w
        rect1.inputWASD[0] = true;
        break;
    case 83:  //s
        rect1.inputWASD[2] = true;
        break;
    case 65:  //a
        rect1.inputWASD[1] = true;
        break;
    case 68:  //d
        rect1.inputWASD[3] = true;
        break;                     };

switch(keyUp.keyCode){
    case 87:
        rect1.inputWASD[0] = false;
        break;
    case 83:
        rect1.inputWASD[2] = false;
        break;
    case 65:
        rect1.inputWASD[1] = false;
        break;
    case 68:
        rect1.inputWASD[3] = false;
        break;     };


funtion Update() {
        if(this.inputWASD[0] == true){this.y-= velocity}    //UP and DOWN
        else if(this.inputWASD[2] == true){this.y+= velocity};

        if(this.inputWASD[1] == true){this.angle -= angleMovement}  //Rotate RIGHT and LEFT
        else if(this.inputWASD[3] == true) {this.angle += angleMovement};
this.inputWASD=[false,false,false,false]//这进入了构造函数内部

//-->[W,A,S,D]的输入需要用极坐标表示速度。这意味着你不用存储X和Y速度,而是存储一个角度和一个速度。然后在更新函数中,将其转换为X和Y速度,以更新位置。可以使用三角法将极坐标转换为笛卡尔坐标:


因此,在代码中,您可以执行以下操作:

// In the Constructor
this.angle = 0;
this.speed = 0;

// ... //

function Update()
{
    this.speed = 0; // Do this if you want the rectangle to have no momentum

    // Input handling
    if(this.inputWASD[0]) this.speed += acceleration;
    if(this.inputWASD[2]) this.speed -= acceleration;

    if(this.inputWASD[1]) this.angle -= angleMovement;
    if(this.inputWASD[3]) this.angle += angleMovement;

    // Position update
    this.x += this.speed * Math.cos(this.angle);
    this.y += this.speed * Math.sin(this.angle);
}

注:我将
velocity
重命名为
acceleration
,以更符合物理学术语。另外,我在每个刻度上将速度重置为0,这样矩形就没有动量。如果你想要更逼真,你可以删除那条线,而只是在每次更新时将速度降低一点(比如10%左右),以模拟摩擦。

你需要计算给定角度表示的向量,并沿该向量(而不是原始垂直向量)移动矩形。很好,矩形现在移动到一个特定的方向,但不是它面对的地方,当我按下“左”或“右”时,它会移动到一个随机的方向。当我把
this.speed=0在Update()中我的矩形不移动。三角函数的约定是角度0与正X轴(向右)对齐。您可能假设负Y轴(向上)是矩形所面对的方向。可能最简单的修复方法是绘制矩形,使其面向右侧,然后使用
this.angle=-90
对其进行初始化。当您按
a
d
时,是否确定它正在随机移动?这似乎不太可能。可能您留下了一些原始更新代码,这些代码根据键盘输入更改了
this.x
this.y
。至于
速度
的发布顺序很重要。您必须将速度设置为0,然后运行我的输入处理代码,该代码可以将速度设置为
+加速度
-加速度
,然后根据速度更新位置。如果您在输入处理后但在位置更新之前将
速度设置为0,则按键将无效。感谢所有帮助,它几乎就到了。我的矩形不会沿随机方向移动,但按
a
d
时,角度旋转不同步。当我按下
D
并旋转180度时,我本应该朝相反的方向移动,但相反,它会使移动旋转180度以上。我的位置更新如下
this.x+=this.speed*Math.cos(this.angle)
this.y+=this.speed*Math.sin(this.angle)
。我一直在玩这个,但我没弄清楚。请注意,
Math.sin()
Math.cos()
期望角度为弧度,就像
context.rotate()一样。因此,你要么用弧度表示所有角度,要么每次用
this.angle*Math.PI/180
将角度转换为弧度。