GameMaker碰撞系统异常求助:角色穿墙、平台下陷等问题排查
问题分析与修复方案
核心问题点
- 水平移动碰撞检测漏洞:仅检测移动方向1像素处的tile,而移动速度是4,会直接跳过中间碰撞tile,导致穿墙。
- 脚部位置计算错误:
spriteleftfoot和spriterightfoot的公式错误,无法正确检测角色脚部与平台的碰撞。 - 垂直移动逻辑重复+冗余位移:两次判断左右脚时都执行
y = nextY,最后又额外执行y += vspd,导致角色在平台上重复下落出现下陷。 - 地面检测函数误用:
place_meeting用于检测实例碰撞,tilemap应使用tilemap_get_at_pixel类函数判断是否接地。
修复后的代码
创建事件
movespd = 4; grv = 0.3; jumpheight = 7; vspd = 0; // 预存地面tilemap ID,避免每步重复获取(优化性能) ground_tilemap = layer_tilemap_get_id(layer_get_id("Ground"));
步事件
// 1. 水平移动与碰撞检测 var _hspd = 0; if keyboard_check(ord("A")) _hspd -= movespd; if keyboard_check(ord("D")) _hspd += movespd; // 水平碰撞:逐像素移动(避免穿墙) if _hspd != 0 { var _dir = sign(_hspd); for(var i=0; i<abs(_hspd); i++){ // 检测角色左右边缘及中心的tile if tilemap_get_at_pixel(ground_tilemap, x + _dir + sprite_width/2, y) == 0 && tilemap_get_at_pixel(ground_tilemap, x + _dir - sprite_width/2, y) == 0 && tilemap_get_at_pixel(ground_tilemap, x + _dir, y + sprite_height/2) == 0 { x += _dir; } else { break; // 碰到障碍物停止移动 } } } // 2. 垂直移动与碰撞检测 vspd += grv; var _nextY = y + vspd; var _left_foot = x - sprite_width/2; var _right_foot = x + sprite_width/2; var _foot_y = _nextY + sprite_height; var _on_ground = false; // 检测左右脚是否碰到地面tile if tilemap_get_at_pixel(ground_tilemap, _left_foot, _foot_y) != 0 || tilemap_get_at_pixel(ground_tilemap, _right_foot, _foot_y) != 0 { // 校准位置到地面上方 while tilemap_get_at_pixel(ground_tilemap, _left_foot, y + 1) == 0 && tilemap_get_at_pixel(ground_tilemap, _right_foot, y + 1) == 0 { y += 1; } vspd = 0; _on_ground = true; } else { y = _nextY; } // 3. 跳跃逻辑 if _on_ground && keyboard_check_pressed(ord("W")) { vspd -= jumpheight; }
修复说明
- 水平碰撞:改为逐像素移动并检测角色多位置tile,彻底解决穿墙问题。
- 脚部位置:修正为角色左右边缘的正确坐标,确保平台碰撞检测准确。
- 垂直移动:合并左右脚检测逻辑,移除冗余位移代码,添加位置校准避免下陷。
- 接地检测:用tilemap专属检测替代实例碰撞函数,改用
keyboard_check_pressed防止连续跳跃。
内容的提问来源于stack exchange,提问作者user18124621
相关产品推荐
相关产品推荐

