You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Processing角色平滑移动求助:移动卡顿且无法多键同时按下

解决Processing角色平滑移动与多按键同时触发问题

嘿,我来帮你搞定这个移动卡顿和不能同时按多个键的问题!先给你拆解下代码里的核心问题,再一步步修改让角色动起来更丝滑~

问题出在哪?

  1. 没法同时按多个按键:Processing的key变量一次只能存最后一个被按下的键,你原来在movePlayer1()里靠key判断的方式,只能响应单个按键,自然没法同时处理上下左右的组合操作。
  2. 移动卡顿:你把移动逻辑放在了keyPressed的判断里,而系统按住按键时,会有个初始延迟才会持续触发按键事件,而且只有keyPressed为true时才移动,导致移动不是每帧都执行,看起来就卡壳了。

修改后的完整代码

先给你改好的代码,后面再慢慢解释关键变化:

class Player1 {
  int x;
  int y;
  float speedX = 5;
  float speedY = 5;
  int size;
  boolean up, down, left, right;

  Player1(int newX, int newY, int newSize) {
    x = newX;
    y = newY;
    size = newSize;
  }

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

  void display() {
    ellipse(x, y, size, size);
  }

  void movePlayer1() {
    // 每帧根据按键状态移动,不再依赖keyPressed
    if (left) {
      x -= speedX;
    }
    if (right) {
      x += speedX;
    }
    if (up) {
      y -= speedY;
    }
    if (down) {
      y += speedY;
    }
  }
}

// 处理按键按下事件(Processing自带的内置函数)
void keyPressed() {
  if (key == 'a' || key == 'A') {
    player1.left = true;
  }
  if (key == 'd' || key == 'D') {
    player1.right = true;
  }
  if (key == 'w' || key == 'W') {
    player1.up = true;
  }
  if (key == 's' || key == 'S') {
    player1.down = true;
  }
}

// 处理按键松开事件
void keyReleased() {
  if (key == 'a' || key == 'A') {
    player1.left = false;
  }
  if (key == 'd' || key == 'D') {
    player1.right = false;
  }
  if (key == 'w' || key == 'W') {
    player1.up = false;
  }
  if (key == 's' || key == 'S') {
    player1.down = false;
  }
}

// 主代码页
Stars stars[] = new Stars[100];
Player1 player1;
Player2 player2;

void setup() {
  size(600, 800);
  player1 = new Player1(width/2, 100, 30);
  player2 = new Player2(width/2, 700, 30);
  for (int i = 0; i < stars.length; i++) {
    stars[i] = new Stars((int)random(width), (int)random(height));
  }
}

void draw() {
  background(0);
  stroke(255);
  strokeWeight(3);
  line(0, height/2, width, height/2);
  //绘制星星
  for (int i = 0; i < stars.length; i++) {
    stars[i].run();
  }
  // 绘制玩家
  player1.run();
  player2.run();
}

关键修改点说明

  • 拆分按键记录和移动逻辑:
    • 把记录按键按下/松开的操作,移到Processing自带的keyPressed()和keyReleased()函数里。这两个函数会在按键状态变化时自动触发,专门用来更新up/down/left/right这些开关变量的状态。
    • movePlayer1()里只负责根据这些开关变量移动角色,而且是在每一次draw()循环(每秒约60次)里执行,所以移动会非常平滑,不会再卡顿。
  • 支持多按键同时触发:每个按键的状态是单独用布尔变量记录的,比如同时按w和a,up和left都会变成true,移动逻辑里两个判断都会执行,角色就能斜着移动啦。

另外,我还悄悄修复了一个隐藏bug:原来Player1类里直接写int x = width/2;会报错,因为类定义时width还没被初始化(要等setup()里的size()执行后才有值),现在把初始化移到构造函数里就没问题了~

内容的提问来源于stack exchange,提问作者Lukaas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:53:02