加工过程中运动平稳吗?

Smooth movement in processing?

我希望这段代码能够有效地增加方向之间过渡的平滑度(一次只能使用一个键),以便我可以使用多个键。问题是,每当我改变方向时,"Player" 就会停止,然后继续朝新的方向前进。我希望 "Player" 在不同方向之间平稳过渡,而不必在按下新键之前完全释放活动键。

主要代码:

Ball ball;
Player player1;
Player player2;

void setup() {

  size(1368,768);
  frameRate(60);
  noStroke();

  ball = new Ball(width/2, height/2, 30);
  player1 = new Player(0, height/2, 30, 150);
  player2 = new Player(width-30, height/2, 30, 150);

  ball.speedX = -10;
  ball.speedY = random(-5,5);

}

void draw() {

  background(0);

  ball.display();
  ball.move();
  player1.run();
  player2.run();

  //Collision
  if (ball.top() < 0) {
    ball.speedY = -ball.speedY;
  }

  if (ball.bottom() > height) {
    ball.speedY = -ball.speedY;
  }

  if (ball.left() < 0) {
    ball.speedX = 0;
    ball.speedY = 0;
  }

  if (ball.right() > width) {
    ball.speedX = 0;
    ball.speedY = 0;
  }

}

void keyPressed() {

  player1.pressed((key == 'w' || key == 'W'), (key == 's' || key == 'S'));
  player2.pressed((keyCode == UP), (keyCode == DOWN));

}

void keyReleased() {

  player1.released((key == 'w' || key == 'W'), (key == 's' || key == 'S'));
  player2.released((keyCode == UP), (keyCode == DOWN));

}

玩家class代码:

class Player {

  float x, y;
  int dy = 0;
  float w, h;
  float speedY = 5;
  color c;

  //Constructor
  Player(float tempX, float tempY, float tempW, float tempH){

    x = tempX;
    y = tempY;
    w = tempW;
    h = tempH;
    speedY = 0;
    c = (255);

  }

  void run() {

    display();
    move();

  }

  void display() {

    fill(c);
    rect(x, y-h/2, w, h);

  }

  void move() {

    y += dy * speedY;

  }

  void pressed(boolean up, boolean down) {

    if (up) {dy = -1;}
    if (down) {dy = 1;}

  }

  void released(boolean up, boolean down) {

    if (up) {dy = 0;}
    if (down) {dy = 0;}

  }


}

提前致谢!

如果你想要平滑的过渡,你将不得不放弃 "adding a fixed integer distance" 按键处理程序,而是跟踪哪些按键按下或未按下,然后 accelerating/decelerating 你的播放器每时间 draw() 运行。举个简单的例子:

Box box;
boolean[] active = new boolean[256];

void setup() {
  size(500,500);
  box = new Box(width/2, height/2);
}

void draw() {
  pushStyle();
  background(0);
  box.update(active);  // First, make the box update its velocity,
  box.draw();          // then, tell the box to draw itself.
  popStyle();
}

void keyPressed() { active[keyCode] = true; }
void keyReleased() { active[keyCode] = false; }

用简单的盒子class:

class Box {
  final float MAX_SPEED = 1, ACCELERATION = 0.1, DECELERATION = 0.5;
  float x, y;
  float dx=0, dy=0;

  Box(float _x, float _y) { x=_x; y=_y; }

  void draw() {
    // We first update our position, based on current speed,
    x += dx;
    y += dy;
    // and then we draw ourselves.
    noStroke();
    fill(255);
    rect(x,y,30,30);
  }

  void update(boolean[] keys) {
    if (keys[38]) { dy -= ACCELERATION ; } 
    else if (keys[40]) { dy += ACCELERATION ; }
    else { dy *= DECELERATION; }

    if (keys[37]) { dx -= ACCELERATION ; } 
    else if (keys[39]) { dx += ACCELERATION ; }
    else { dx *= DECELERATION; }

    dx = constrain(dx, -MAX_SPEED, MAX_SPEED);
    dy = constrain(dy, -MAX_SPEED, MAX_SPEED);
  }
}

这里的重要部分是 update 代码,它更新盒子的 x 和 y velocity 这样如果当前按下方向键,我们会增加速度(dx/dy) 在那个方向。重要的是,如果按下 no 键,我们也会将速度降低到 returns 到 0。

最后,为了确保我们不会以无限速度结束,我们限制了最大允许速度。

向 class Player 添加 2 个属性 move_upmove_down 并在中设置属性 pressed分别是released:

class Player {

    // [...]
    boolean move_up = false, move_down = false;

    void pressed(boolean up, boolean down) {
        if (up)   {move_up   = true;}
        if (down) {move_down = true;}
    }

    void released(boolean up, boolean down) {
        if (up)   {move_up   = false;}
        if (down) {move_down = false;}
    }
}

根据 move 中的属性更改 speedY。如果 move_upmove_down 均未设置(speedY = speedY * 0.95;),则继续降低速度。如果没有按下任何键,这会导致播放器平稳地减速。如果按下 move_upmove_down,则根据所需方向稍微改变速度。将速度限制在一定区间内(speedY = max(-5.0, min(5.0, speedY));):

class Player {
    // [...]

    void move() {
        if (!move_up && !move_down) {speedY *= 0.95;}
        if (move_up)                {speedY -= 0.1;}
        if (move_down)              {speedY += 0.1;}
        speedY = max(-5.0, min(5.0, speedY));
        y += speedY;
    }

    // [...]
}

Class Player:

class Player {

    float x, y;
    float w, h;
    float speedY = 0.0;
    color c;
    boolean move_up = false, move_down = false;

    //Constructor
    Player(float tempX, float tempY, float tempW, float tempH){

        x = tempX;
        y = tempY;
        w = tempW;
        h = tempH;
        c = (255);
    }

    void run() {
        display();
        move();
    }

    void display() {

        fill(c);
        rect(x, y-h/2, w, h);
        println(y);
    }

    void move() {
        if (!move_up && !move_down) {speedY *= 0.95;}
        if (move_up)                {speedY -= 0.1;}
        if (move_down)              {speedY += 0.1;}
        speedY = max(-5.0, min(5.0, speedY));
        y += speedY;
    }

    void pressed(boolean up, boolean down) {
        if (up)   {move_up   = true;}
        if (down) {move_down = true;}
    }

    void released(boolean up, boolean down) {
        if (up)   {move_up   = false;}
        if (down) {move_down = false;}
    }
}