Javascript:如何根据旋转移动上下文对象

Javascript: how to move a context object in relation with its rotation

我想使用 html canvas 制作游戏。我的objective是上下移动一个矩形,按左右键会旋转。像汽车一样思考,汽车只能向前和向后行驶,而不会向左和向右行驶,它们会旋转。 唯一的问题是我的矩形会旋转,但它不会随着旋转而移动,无论它面向哪里,它只会上下移动。

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

如果您不知道答案,但您知道我可以用来根据旋转移动上下文对象的库,请告诉我。

你需要的是用极坐标表示速度。这意味着不是存储 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% 左右)来模拟摩擦。