当前位置: 首页 > 知识库问答 >
问题:

加工过程中的平稳运动?

糜帅
2023-03-14

我希望这段代码能有效地提高方向间转换的平滑度(一次只能使用一个键),这样我就可以使用多个键。问题是,每当我改变方向,“玩家”就会停下来,然后继续朝新的方向前进。我想让“玩家”在两个方向之间平稳过渡,而不必在按下新键之前完全释放活动键。

主要代码:

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

  }


}

提前谢谢!

共有2个答案

夹谷沛
2023-03-14

如果你想要平滑的过渡,你必须放弃在键处理程序中“添加固定的整数距离”,而是跟踪哪些键关闭了或者没有关闭,然后在每次绘制()运行时加速/减速你的播放器。正如简单的例子:

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

使用一个简单的box类:

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

这里的重要部分是更新代码,它会更新盒子的x和y速度,这样,如果当前按下方向键,我们就会增加该方向的速度(dx/dy)。重要的是,如果没有按下任何键,我们也会降低速度,使其返回0。

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

裴嘉良
2023-03-14

添加2个属性move_upmove_down到类Player中,并分别在按下释放中设置属性:

java prettyprint-override">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中的属性进行快速更改。如果未设置move_upnotmove_downspeedY=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 {

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

 类似资料:
  • 我试着在处理过程中创建平滑的运动,但它现在不起作用,我不知道为什么它不起作用。我是一名编程初学者,所以在解释时不要让我觉得太复杂:)。这个角色现在移动非常缓慢,我不能同时按下多个按钮,如果有人能帮助我,那就太好了。提前谢谢你。 这是主代码页

  • 我正在写一个程序,让小“鸟”四处移动并跟随你的光标。这些实例不旋转或任何花哨的东西,我有一个非常不寻常的问题。 如果实例位于同一个X级或Y级,它会振荡。我以前遇到过边界和运动的问题,所以我尝试采取类似的方法。 只有当两个版本同时运行时,移动才会平滑。我尝试过重新排列' 这个代码中有没有我可以删除的部分来阻止它重复出现? 谢谢:)

  • 有人有这方面的经验吗?我正在研究迁移,但是由于我们已经用GCM发布了应用程序,每天有成千上万的用户和成千上万的通知,我不愿意这样做,因为担心会破坏现有的服务。有人顺利过渡了吗? 具体来说,在教程中(https://developers.google.com/cloud-messaging/android/android-migrate-fcm)第一步是“导入谷歌项目”。这是单向操作吗?现有的GCM

  • 运动跟踪概述和资源 通过运动跟踪,您可以跟踪对象的运动,然后将该运动的跟踪数据应用于另一个对象(例如另一个图层或效果控制点)来创建图像和效果在其中跟随运动的合成。您还可以稳定运动,在这种情况下,跟踪数据用来使被跟踪的图层动态化以针对该图层中对象的运动进行补偿。您可以使用表达式将属性链接到跟踪数据,这开拓了广泛的用途。 After Effects 通过将来自某个帧中的选定区域的图像数据与每个后续帧中

  • 我使用ActiveMQ使用mvn构建运行集成测试。这是我的pom。xml首先触发activemq,然后触发集成测试,以便它们可以使用上面的activemq实例传输消息。 它工作正常,但不能顺利关闭..当mvn构建结束并且所有测试都成功时,构建看起来很好。但是activemq在关闭时会显示以下错误:- 有没有一种方法可以让Maven在maven构建完成时顺利关闭activeMQ而没有上述例外?以下是

  • 使用处理程序 我怎么让它从绿色变成黄色?我知道怎么把它变成深绿色到亮绿色,蓝色到黄色,但那不是我想要的。请救命!