Jump Buffering功能异常及高台跳下缓冲问题排查求助
问题修复方案
一、跳跃缓冲不稳定的修复
问题根源
- 缓冲计数器递减逻辑先于落地判断,可能导致计数器归零瞬间错过跳跃触发
- 代码中存在未定义变量
jump_buffered(仅声明了jump_buffered_flag) - 落地时的跳跃触发未同步更新
j_limit,可能导致后续跳跃被限制
修改后的缓冲逻辑
//// Jump Buffering if keyboard_check_pressed(vk_up) { if (on_ground and j_limit == 1) { vspd = -jspd; j_limit = 0; jump_buffered_flag = false; // 重置缓冲标记 } else if (!on_ground) { jump_buffer_active = true; jump_buffer_counter = 30; jump_buffered_flag = true; } } if jump_buffer_active == true { // 先判断是否落地,再递减计数器 if on_ground and j_limit == 1 { jump_buffer_active = false; jump_buffered_flag = false; vspd = -jspd; // 直接设置跳跃速度,避免叠加错误 j_limit = 0; // 消耗一次跳跃次数 } else { jump_buffer_counter--; if (jump_buffer_counter <= 0) { jump_buffer_active = false; jump_buffered_flag = false; } } }
二、下落冻结/抬升问题修复
问题根源
- 碰撞检测时直接将
vspd设为0,但未将角色位置对齐到地面,导致角色悬浮在地面上方,后续帧反复触发地面检测和速度重置 - 垂直速度的钳制逻辑错误,按住上方向键时会强制限制
vspd范围,干扰下落过程
修改后的碰撞与重力逻辑
//// Gravity // 先施加重力,再处理碰撞 vspd += grav; vspd = clamp(vspd, -max_jspd, max_vspd); // 统一钳制垂直速度,移除原按住上方向键的错误限制 //// Collisions // 水平碰撞 if place_meeting(x + hspd, y, obj_wall) { hspd = 0; } x += hspd; // 垂直碰撞(修正位置对齐) if place_meeting(x, y + vspd, obj_wall) { // 将角色移动到地面接触位置,而非直接重置速度 while (!place_meeting(x, y + sign(vspd), obj_wall)) { y += sign(vspd); } vspd = 0; } y += vspd;
三、其他细节优化
- 地面检测逻辑简化:确保
on_ground的检测更可靠,避免因角色位置偏移导致误判
//// Checking if character on ground on_ground = place_meeting(x, y + 1, obj_wall); j_limit = on_ground ? 1 : 0; // 简化赋值逻辑,保持可读性
- 摩擦逻辑简化:原摩擦代码冗余,可简化为:
//// Friction if (!keyboard_check(vk_right) && !keyboard_check(vk_left)) { hspd *= 0.75; // 用乘法替代逐帧加减,更直观 if (abs(hspd) < 0.1) hspd = 0; // 避免微小速度残留 }
完整修改后的Step代码
//// debug show_debug_message("Step started"); //// Checking if character on ground on_ground = place_meeting(x, y + 1, obj_wall); j_limit = on_ground ? 1 : 0; //// Movements if keyboard_check(vk_right) { hspd += movespeed; } if keyboard_check(vk_left) { hspd -= movespeed; } //// Jump Buffering if keyboard_check_pressed(vk_up) { if (on_ground and j_limit == 1) { vspd = -jspd; j_limit = 0; jump_buffered_flag = false; } else if (!on_ground) { jump_buffer_active = true; jump_buffer_counter = 30; jump_buffered_flag = true; } } if jump_buffer_active == true { if on_ground and j_limit == 1 { jump_buffer_active = false; jump_buffered_flag = false; vspd = -jspd; j_limit = 0; } else { jump_buffer_counter--; if (jump_buffer_counter <= 0) { jump_buffer_active = false; jump_buffered_flag = false; } } } show_debug_message("Jump Buffer Flag: " + string(jump_buffered_flag)); show_debug_message("Jump Buffer Timer: " + string(jump_buffer_counter)); //// Gravity vspd += grav; vspd = clamp(vspd, -max_jspd, max_vspd); //// Clamp Move Speed hspd = clamp(hspd, -max_movespeed, max_movespeed); //// Friction if (!keyboard_check(vk_right) && !keyboard_check(vk_left)) { hspd *= 0.75; if (abs(hspd) < 0.1) hspd = 0; } //// Collisions // 水平碰撞 if place_meeting(x + hspd, y, obj_wall) { hspd = 0; } x += hspd; // 垂直碰撞 if place_meeting(x, y + vspd, obj_wall) { while (!place_meeting(x, y + sign(vspd), obj_wall)) { y += sign(vspd); } vspd = 0; } y += vspd; //// debug show_debug_message("After position update: x=" + string(x) + ", y=" + string(y)); show_debug_message("After position update: hspd=" + string(hspd) + ", vspd=" + string(vspd)); if keyboard_check_pressed(vk_escape) { show_debug_message("Exiting game..."); game_end(); }
修复说明
- 跳跃缓冲:调整了计数器递减和落地判断的顺序,确保落地时优先触发跳跃,同时修正了变量名错误,同步更新跳跃次数限制
- 下落问题:通过
while循环将角色精准对齐到地面,避免悬浮;移除了按住上方向键时错误的速度钳制,确保下落过程正常 - 代码简化:保留了你的
if语句风格,同时优化了冗余逻辑,保持可读性
内容的提问来源于stack exchange,提问作者sokunn S
相关产品推荐
相关产品推荐

