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

Processing登月游戏控件失效求助:新手代码问题排查

嘿,我帮你梳理了代码里的几个关键问题,咱们一步步修复,让你的登月游戏正常运行起来!

1. 重力没真正生效(你以为的重力其实是初始速度)

你的代码里定义了gravity变量,但从来没在每一帧更新vy!飞船下落只是因为初始vy=1,不是真的重力作用。要在draw()函数里添加:

vy += gravity; // 每一帧给y方向速度加上重力加速度

2. 移动控制逻辑错误

  • 误用translate():moveKeys()里的translate()是移动整个画布坐标系,不是飞船位置,这会导致后续绘制混乱。应该直接控制飞船的速度或位置。
  • 未处理按键松开事件:只写了keyPressed没写keyReleased,导致按住方向键后状态一直是true,松开也停不下来。
  • 推力逻辑搞反:Processing的y轴向下,vy越大下落越快,向上推力应该减小vy(甚至让它变负实现向上飞),而不是增加。

修复后的按键相关函数:

void keyPressed() {
  if (key == CODED) {
    switch (keyCode) {
      case UP: moveUp = true; break;
      case LEFT: moveLeft = true; break;
      case RIGHT: moveRight = true; break;
    }
  }
}

void keyReleased() {
  if (key == CODED) {
    switch (keyCode) {
      case UP: moveUp = false; break;
      case LEFT: moveLeft = false; break;
      case RIGHT: moveRight = false; break;
    }
  }
}

void moveKeys() {
  // 控制左右移动速度
  if (moveLeft) {
    vx = -1;
  } else if (moveRight) {
    vx = 1;
  } else {
    vx = 0; // 松开按键后停止左右移动
  }
  
  if (moveUp) {
    thrust();
  }
}

void thrust() {
  vy -= 0.2; // 向上推力,抵消重力实现上升
}

3. 碰撞检测与着陆重启逻辑缺失

原代码的碰撞判断边界错误,而且没有检测是否落在红色着陆区,也没有重启游戏的逻辑。我们修复碰撞检测,并添加resetGame()函数实现重启:

void moveShip() {
  // 左右边界碰撞
  if (posx < 0) {
    posx = 0;
    vx = 0;
  } else if (posx + 50 > width) {
    posx = width - 50;
    vx = 0;
  }
  
  // 顶部边界碰撞
  if (posy - 10 < 0) {
    posy = 10;
    vy = 0;
  }
  
  // 底部着陆检测
  if (posy + 25 >= 470) {
    posy = 470 - 25; // 让飞船刚好落在地面上
    // 判断是否在红色着陆区(飞船中心x在200-300之间)
    if (posx + 25 >= 200 && posx + 25 <= 300) {
      resetGame(); // 成功着陆,重启游戏
    } else {
      vx = 0;
      vy = 0; // 着陆失败,停止移动
    }
  }
  
  // 更新位置
  posx += vx;
  posy += vy;
}

void resetGame() {
  // 重置飞船位置、速度和移动状态
  posx = int(random(width - 50)); // 避免飞船超出右边界
  posy = 20;
  vx = 0;
  vy = 0;
  moveLeft = moveRight = moveUp = false;
}

完整修复后的代码

把所有修改整合起来,最终代码如下:

int posx, posy;
float vx, vy;
float gravity = 0.05;
boolean moveLeft, moveRight, moveUp;

void setup() {
  size(500, 500);
  background(0);
  // 初始位置
  posx = int(random(width - 50)); // 防止初始位置超出右边界
  posy = 20;
  moveLeft = moveRight = moveUp = false;
  // 初始速度
  vx = vy = 0; // 初始速度设为0,让重力慢慢拉下来
}

void draw() {
  noStroke();
  background(0);
  // 绘制地面和红色着陆区
  fill(255, 255, 255);
  rect(0, 470, width, 30);
  fill(255, 0, 0);
  rect(200, 470, 100, 30);
  
  // 应用重力
  vy += gravity;
  
  // 处理按键控制
  moveKeys();
  // 更新飞船位置和碰撞
  moveShip();
  // 绘制飞船
  drawShip();
}

void drawShip() {
  fill(169, 169, 169);
  rect(posx, posy, 50, 25);
  fill(255, 255, 255);
  rect(posx + 20, posy - 10, 10, 10);
  fill(105, 105, 105);
  rect(posx + 20, posy + 25, 10, 5);
  stroke(255, 255, 255);
  strokeWeight(2);
  line(posx + 2, posy + 25, posx + 2, posy + 40);
  stroke(255, 255, 255);
  strokeWeight(2);
  line(posx + 48, posy + 25, posx + 48, posy + 40);
}

void moveShip() {
  // 左右边界碰撞
  if (posx < 0) {
    posx = 0;
    vx = 0;
  } else if (posx + 50 > width) {
    posx = width - 50;
    vx = 0;
  }
  
  // 顶部边界碰撞
  if (posy - 10 < 0) {
    posy = 10;
    vy = 0;
  }
  
  // 底部着陆检测
  if (posy + 25 >= 470) {
    posy = 470 - 25;
    // 判断是否在红色着陆区(飞船中心x在200-300之间)
    if (posx + 25 >= 200 && posx + 25 <= 300) {
      resetGame();
    } else {
      vx = 0;
      vy = 0;
    }
  }
  
  // 更新位置
  posx += vx;
  posy += vy;
}

void keyPressed() {
  if (key == CODED) {
    switch (keyCode) {
      case UP: moveUp = true; break;
      case LEFT: moveLeft = true; break;
      case RIGHT: moveRight = true; break;
    }
  }
}

void keyReleased() {
  if (key == CODED) {
    switch (keyCode) {
      case UP: moveUp = false; break;
      case LEFT: moveLeft = false; break;
      case RIGHT: moveRight = false; break;
    }
  }
}

void moveKeys() {
  if (moveLeft) {
    vx = -1;
  } else if (moveRight) {
    vx = 1;
  } else {
    vx = 0;
  }
  
  if (moveUp) {
    thrust();
  }
}

void thrust() {
  vy -= 0.2;
}

void resetGame() {
  posx = int(random(width - 50));
  posy = 20;
  vx = 0;
  vy = 0;
  moveLeft = moveRight = moveUp = false;
}

现在你可以运行这段代码,飞船应该能正常左右移动、向上推力抵消重力,并且落在红色区域后自动重启游戏啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 04:58:29