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

GameMaker单向平台实现问题:玩家无法站立求解

问题原因分析
  • 碰撞对象遗漏:你的move_and_collide只针对tilemap(tmWorld1)处理碰撞,但单向平台obj_oneway是实例对象,不在tile层里,所以玩家站在平台上时没有触发和平台的碰撞检测,自然会穿过去。
  • 位置判断逻辑不准确:当前用y <= oneway_id.y判断玩家是否在平台上方,这个条件太模糊——玩家的y坐标是锚点位置(通常是sprite中心),平台的y也是中心,所以当玩家站在平台上时,玩家的y可能已经大于平台的y,导致条件不满足,反而触发了禁用平台掩码的逻辑,让玩家穿过去。
  • 单向平台的碰撞处理逻辑颠倒:你当前的逻辑是“当玩家向下移动且在平台上方时,禁用平台掩码”,这完全搞反了——应该是当玩家从下方往上移动时,禁用平台掩码允许穿过;当玩家从上方下落时,保留掩码让玩家站在平台上。
解决方案与代码优化

修改后的玩家Create事件(无需改动)

// Create Event
move_speed = 4; jump_speed = 16;
move_x = 0; move_y = 0;

tmWorld1 = layer_tilemap_get_id("tiles");

修改后的玩家Step事件

// Step Event
move_x = move_speed * sign(image_xscale); // 按朝向移动

// 水平墙碰撞检测(tilemap)
if (place_meeting(x + move_x, y, tmWorld1)) {
    image_xscale *= -1;
    move_x = 0; // 碰到墙后直接停止水平移动,避免反复翻转
}

// 重力与跳跃处理(移到碰撞前,逻辑更清晰)
if (!place_meeting(x, y + 2, tmWorld1) && !place_meeting(x, y + 2, obj_oneway)) {
    if (move_y < 10) {
        move_y += 1;
    }
} else {
    move_y = 0;
    if (keyboard_check_pressed(vk_space)) {
        move_y = -jump_speed;
    }
}

// 单向平台碰撞判断
var oneway_collision = false;
var oneway_id = instance_place(x, y + move_y, obj_oneway); // 检测垂直移动后的碰撞

if (oneway_id != noone) {
    // 计算玩家底部和平台顶部的精确位置
    var player_bottom = y + sprite_height / 2;
    var platform_top = oneway_id.y - oneway_id.sprite_height / 2;
    
    // 玩家从下方往上移动时,允许穿过;从上方下落时,触发碰撞
    if (!(move_y < 0 && player_bottom <= platform_top + 1)) {
        oneway_collision = true;
    }
}

// 统一执行移动:同时处理tilemap和需要碰撞的单向平台
var collision_targets = tmWorld1;
if (oneway_collision) {
    collision_targets += obj_oneway;
}
move_and_collide(move_x, move_y, collision_targets);

关键改动说明

  1. 调整逻辑顺序:把重力和跳跃检测移到碰撞处理前,符合“先计算速度,再处理碰撞”的游戏逻辑,同时把obj_oneway加入地面检测,让玩家站在单向平台上也能触发跳跃。
  2. 精确碰撞判断:通过计算玩家底部与平台顶部的坐标,准确区分“从上方下落”和“从下方上升”两种状态,避免误判。
  3. 统一碰撞处理:将tilemap和需要碰撞的单向平台合并到move_and_collide的目标中,简化分支逻辑,减少出错概率。
  4. 修复水平碰撞小问题:碰到墙后直接重置move_x为0,避免玩家反复左右翻转。
额外优化建议
  • 给obj_oneway设置专属碰撞掩码:在Sprite编辑器里把平台的碰撞掩码改成仅顶部一条线(选“精确”模式后裁剪),能进一步简化碰撞判断,减少误触发。
  • 用变量存储阈值:比如定义collision_threshold = 1代替代码里的硬编码数字,后续调整更方便。
  • 封装单向平台逻辑:把碰撞判断写成独立脚本script_is_oneway_passable(oneway_id),后续新增同类平台时可直接复用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 12:22:34