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

GameMaker兔子跳跃动画异常求助:落地无法切换至Idle Sprite

兔子跳跃动画问题排查与修复

需求说明

我需要用3个精灵实现兔子跳跃动画:

  • spr_conejo_idle:2帧
  • spr_conejo_airbourne_up:5帧(前4帧用于起跳,vsp < 0时冻结最后一帧)
  • spr_conejo_airbourne_down:4帧(vsp > 0时显示第1帧,落地时播放最后3帧)

预期逻辑:

角色跳跃时切换至spr_conejo_airbourne_up,冻结最后一帧直到开始下落(vsp <= 0);下落时切换至spr_conejo_airbourne_down,冻结第1帧直到垂直碰撞墙体,随后播放落地动画并最终切换至Idle精灵。

当前问题

  • 角色落地后无法切换至spr_conejo_idle,持续循环spr_conejo_airbourne_down
  • 偶尔在空中时,精灵会短暂切换至Idle帧

现有代码

CREATE事件

hp = 1;
hsp = 0;
vsp = 0;
grv = 0.3;
maxIdle = 360;
onFloor = true;
hitfrom = 0;
size = 1;

STEP事件

vsp += grv;
maxIdle--;
if (place_meeting(x,y+1,obj_wall)){onFloor = true;}else{onFloor = false;}
if (onFloor){if (maxIdle <= 0){maxIdle = random_range(60, 360);vsp = -6;onFloor = false;hsp = random_range(-3,3);}}
if(!onFloor){if (sign(vsp) < 0) {image_speed = 1;sprite_index = spr_conejo_airbourne_up;}else{image_speed = 0;sprite_index = spr_conejo_airbourne_down;}}
else{image_speed = 1;vsp = 0;hsp = 0;}
if (place_meeting(x+hsp,y,obj_wall)){while (!place_meeting(x+sign(hsp),y,obj_wall)){x += sign(hsp);}hsp = 0;}
x += hsp;
if (place_meeting(x,y+vsp,obj_wall)){while (!place_meeting(x,y+sign(vsp),obj_wall)){y += sign(vsp);}vsp = 0;}
y += vsp;
if (hsp != 0) image_xscale = sign(hsp)*-1;

ANIMATION END事件

if (sprite_index == spr_conejo_airbourne_up) image_speed = 0;
if (sprite_index == spr_conejo_airbourne_down) sprite_index = spr_conejo_idle;

问题分析与修复方案

核心问题点

  1. 落地精灵切换逻辑缺失:onFloor为true时仅重置速度,未明确设置Idle精灵,导致落地后停留在spr_conejo_airbourne_down,且无法触发Animation End事件完成切换。
  2. 下落动画控制错误:下落阶段直接将image_speed设为0,落地后无法播放最后3帧落地动画,自然触发不了切换Idle的逻辑。
  3. 状态判断时机偏差:先判断地面状态再处理移动,移动后实际落地但精灵切换逻辑已执行,导致空中误切Idle。

修复后的代码

修改后的STEP事件

vsp += grv;
maxIdle--;

// 先处理水平移动
if (place_meeting(x+hsp,y,obj_wall)){
    while (!place_meeting(x+sign(hsp),y,obj_wall)){
        x += sign(hsp);
    }
    hsp = 0;
}
x += hsp;

// 处理垂直移动并判断落地状态
var wasOnFloor = onFloor;
onFloor = place_meeting(x,y+1,obj_wall);

if (place_meeting(x,y+vsp,obj_wall)){
    while (!place_meeting(x,y+sign(vsp),obj_wall)){
        y += sign(vsp);
    }
    vsp = 0;
    // 从空中刚落地时,触发落地动画
    if (!wasOnFloor && onFloor){
        sprite_index = spr_conejo_airbourne_down;
        image_speed = 1;
        image_index = 1; // 直接跳至落地动画第2帧,播放最后3帧
    }
}
y += vsp;

// 状态与精灵切换逻辑
if (onFloor){
    vsp = 0;
    hsp = 0;
    // Idle状态下处理自动跳跃
    if (sprite_index == spr_conejo_idle){
        image_speed = 1;
        if (maxIdle <= 0){
            maxIdle = random_range(60, 360);
            vsp = -6;
            onFloor = false;
            hsp = random_range(-3,3);
        }
    }
}else{
    // 空中上升阶段
    if (vsp < 0){
        if (sprite_index != spr_conejo_airbourne_up){
            sprite_index = spr_conejo_airbourne_up;
            image_speed = 1;
        }
        // 播放完上升动画后冻结最后一帧
        if (image_index >= sprite_get_number(spr_conejo_airbourne_up)-1){
            image_speed = 0;
        }
    }
    // 空中下落阶段(未落地)
    else{
        if (sprite_index != spr_conejo_airbourne_down){
            sprite_index = spr_conejo_airbourne_down;
            image_speed = 0;
            image_index = 0; // 冻结第一帧
        }
    }
}

// 方向翻转
if (hsp != 0) image_xscale = sign(hsp)*-1;

修改后的ANIMATION END事件

if (sprite_index == spr_conejo_airbourne_down){
    sprite_index = spr_conejo_idle;
    image_speed = 1;
    image_index = 0;
}

修复说明

  1. 调整移动与状态判断顺序:先处理移动再判断地面状态,确保onFloor的判断基于最新位置,避免空中误判落地。
  2. 落地动画触发逻辑:角色从空中落地时,主动切换到落地精灵并设置从第2帧开始播放,开启动画速度确保落地动画完整播放。
  3. 上升动画冻结逻辑:上升阶段播放完所有帧后再冻结,替代原Animation End的冻结逻辑,避免冲突。
  4. Idle状态明确切换:仅当落地动画播放完成(触发Animation End)时,才切换到Idle精灵,保证落地动画播放完毕后再回到待机状态。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 19:18:31