处理中的平滑运动?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了处理中的平滑运动?相关的知识,希望对你有一定的参考价值。

我希望这段代码有效地提高方向之间的过渡的平滑度(一次只能使用一个键),以便可以使用多个键。问题是,每当我改变方向时,“ 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 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;

  



提前感谢!

答案

[如果您想要平滑的过渡,则必须放弃“添加固定的整数距离”,而是根据速度实现玩家的移动,以便将“增加速度”稍微提高一点,直到按下该键,直到达到最大速度(按所要按下的键的方向)。这也意味着您不仅可以记录keyPressed / keyReleased期间的值,还可以记录当前按下/未按下的键,然后在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 Box 
  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 -= 0.1;  
    else if (keys[40])  dy += 0.1; 
    else  dy *= 0.5; 

    if (keys[37])  dx -= 0.1;  
    else if (keys[39])  dx += 0.1; 
    else  dx *= 0.5; 

    dx = constrain(dx, -1, 1);
    dy = constrain(dy, -1, 1);
  

这里重要的部分是update代码,它更新框的x和y velocity,这样,如果当前按下方向键,我们会在其中增加速度(dx / dy)方向。重要的是,如果按下no键,我们也会降低速度使其返回0。

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

另一答案

将2个属性move_upmove_down添加到类Player,并在pressed分别released

class Player 
    // [...]

    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;
    

根据speedY中的属性更改move

class Player 
    // [...]

    void move() 
        speedY = speedY * 0.95;
        if (move_up)   speedY -= 0.2;
        if (move_down) speedY += 0.2;
        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() 
        speedY = speedY * 0.95;
        if (move_up)   speedY -= 0.2;
        if (move_down) speedY += 0.2;
        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;
    

以上是关于处理中的平滑运动?的主要内容,如果未能解决你的问题,请参考以下文章

OpenCV中的图像处理 —— 图像阈值+图像平滑+形态转换

Untiy中的数据平滑处理

youcans 的 OpenCV 例程200篇151. 边缘检测中的平滑处理

如何在pygame中进行平滑运动

在视频稳定中使用卡尔曼滤波器或粒子滤波器平滑运动

如何在 pixi.js 中实现黄油平滑运动(没有任何滞后/尖峰)