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

P5.js平台游戏添加碰撞检测后角色无法跳跃求助

P5.js平台游戏碰撞检测导致角色无法跳跃问题求助

我是P5.js新手,跟着YouTube教程做平台游戏,添加碰撞检测代码后角色没法跳跃,移除碰撞代码就恢复正常,我的代码和教程一致,附上代码求帮忙解决。

原代码:

//game control ***(not used rn)***
let level = 0;
//gravity
let minHeight = 375
let direction = 1;
let vel = 2;
let jumpPower = 10;
let fallingSpeed = 1;

//player setup and whatnot
let playerX = 400;
let playerY = 370

let playerWidth = 30;
let playerHeight = 70;

//platform
let platX = 200;
let platY = 300;
let platWidth = 200;
let platHeight = 40;

function setup() {
  createCanvas(800, 500);
  rectMode(CENTER);
  textAlign(CENTER);
}
function gravityControl(){
if (keyIsDown(32)){
  jump = true
}else{
  jump = false
}
}
function draw() {
  background(220);
  movement();
  gravityControl()
  gravity()

  if (level == 0) {
    game();
  }
}

function game() {
  background(150, 230, 240);

  //floor
  noStroke();
  fill("green");
  rect(width / 2, 450, width, 100);

  //platform
  stroke(0);
  strokeWeight(4);
  fill("rgb(218,218,138)");
  rect(platX, platY, platWidth, platHeight);

  //player
  noStroke();
  fill("red");
  rect(playerX, playerY, playerWidth, playerHeight);
  
  
  
  //collisions
  if (playerX >= platX -platWidth/2 && playerX <= playerX+platWidth/2 && playerY >= platY-platHeight/2 &&playerY<=platY+platHeight/2)
    playerY = playerY
    vel = 0
}

function movement() {
  if (keyIsDown(LEFT_ARROW)) {
    playerX -= 3;
  }
  if(keyIsDown(RIGHT_ARROW) )
    playerX += 3
}
function mousePressed() {
  fullscreen(true);
}

function gravity(){
  if (playerY >= minHeight && jump == false){
    if(playerY >= minHeight){
      playerY = minHeight
    }else{
      vel = fallingSpeed
    }
    playerY = playerY +0
    
  }
  else{
    playerY = playerY + (direction * vel)
  }
  if (jump == true){
    vel = -jumpPower
  }else{
    vel = fallingSpeed
  }
  
}
function gravityControl(){
if (keyIsDown(32)){
  jump = true
}
  else{
  jump = false
  }
}

问题分析及修复方案:

  1. 碰撞检测语句缺少花括号:原代码中碰撞检测的if没有加{},导致不管碰撞条件是否满足,vel = 0都会执行,直接锁死角色速度,自然跳不起来。
  2. 碰撞检测X轴条件错误:playerX <= playerX+platWidth/2逻辑完全错误,应该是playerX <= platX + platWidth/2,否则X轴碰撞判断永远成立。
  3. 未声明jump变量:jump属于隐式全局变量,容易引发意外问题。
  4. 重复定义gravityControl函数:代码重复写了两次该函数,会覆盖前一个。
  5. 碰撞逻辑不完善:未判断角色是从上方落到平台,导致角色从下方碰平台也被卡住,且碰撞后无法触发跳跃。

修正后的代码:

//game control ***(not used rn)***
let level = 0;
//gravity
let minHeight = 375;
let direction = 1;
let vel = 2;
let jumpPower = 10;
let fallingSpeed = 1;
let jump = false; // 声明jump变量

//player setup and whatnot
let playerX = 400;
let playerY = 370;

let playerWidth = 30;
let playerHeight = 70;

//platform
let platX = 200;
let platY = 300;
let platWidth = 200;
let platHeight = 40;

function setup() {
  createCanvas(800, 500);
  rectMode(CENTER);
  textAlign(CENTER);
}

function gravityControl(){
  jump = keyIsDown(32); // 简化逻辑
}

function draw() {
  background(220);
  movement();
  gravityControl();
  gravity();

  if (level == 0) {
    game();
  }
}

function game() {
  background(150, 230, 240);

  //floor
  noStroke();
  fill("green");
  rect(width / 2, 450, width, 100);

  //platform
  stroke(0);
  strokeWeight(4);
  fill("rgb(218,218,138)");
  rect(platX, platY, platWidth, platHeight);

  //player
  noStroke();
  fill("red");
  rect(playerX, playerY, playerWidth, playerHeight);
  
  //collisions - 修正逻辑,添加花括号,判断从上方下落碰撞
  let playerBottom = playerY + playerHeight/2;
  let platTop = platY - platHeight/2;
  if (playerX >= platX - platWidth/2 && playerX <= platX + platWidth/2 && 
      playerBottom >= platTop && playerBottom <= platTop + 5 && vel > 0) {
    playerY = platTop - playerHeight/2; // 把角色放到平台顶部
    vel = 0; // 停止下落
    jump = false; // 重置跳跃状态,允许再次跳跃
  }
}

function movement() {
  if (keyIsDown(LEFT_ARROW)) {
    playerX -= 3;
  }
  if(keyIsDown(RIGHT_ARROW)) {
    playerX += 3;
  }
}

function mousePressed() {
  fullscreen(true);
}

function gravity(){
  // 地面碰撞处理
  if (playerY >= minHeight) {
    playerY = minHeight;
    vel = 0;
    jump = false;
  } else {
    playerY += direction * vel;
  }

  // 跳跃逻辑:只有当vel为0(站在地面/平台)时才能触发跳跃
  if (jump && vel === 0) {
    vel = -jumpPower;
  } 
  // 下落速度递增,模拟重力加速度
  else if (vel < fallingSpeed && !jump) {
    vel += 0.2;
  }
}

修复说明:

  • 给碰撞检测if语句添加花括号,确保仅满足条件时执行速度重置和位置修正
  • 修正X轴碰撞判断条件,现在能正确检测角色是否在平台X范围内
  • 声明jump变量,避免隐式全局变量问题
  • 移除重复的gravityControl函数,简化按键判断逻辑
  • 优化碰撞检测:仅判断角色从上方落到平台的情况(通过vel>0判断正在下落),同时将角色精准定位到平台顶部
  • 调整重力和跳跃逻辑:只有角色站在地面或平台上(vel=0)时才能触发跳跃,下落时速度递增模拟真实重力

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 08:36:00