GameMaker Studio 2角色停止移动后行走动画持续播放问题求助
解决角色静止时仍播放行走动画的问题
嘿,我看到你遇到的问题了——角色松开按键停下后,走路动画还在继续播放,这确实挺影响游戏体验的。咱们来快速搞定它!
问题根源
你的代码只在按下左右方向键时,把角色的 sprite 设置成了行走动画(spr_denpman_Loop),但完全没处理「松开按键、角色静止」的情况——所以角色停下后,sprite 还停留在行走动画上,自然会一直播下去。
修复方案
- 首先确认你有一个角色静止状态的 sprite(比如叫
spr_denpman_Idle,如果还没有就赶紧创建一个)。 - 在现有移动代码的最后,加一个判断分支:当既没按左键也没按右键时,把 sprite 切换回静止状态,还可以重置动画帧(避免从走路动画的中间帧开始显示)。
修改后的完整代码
///////////////////// // MOVING // ///////////////////// var is_moving = false; // 新增变量,标记角色是否处于移动状态 if(keyboard_check(vk_left)){ // moving left collisions dir=-1; // set the correct direction image_xscale = dir; // make the sprite face the correct direction // if we are not jumping or falling sprite_index = spr_denpman_Loop; // set the sprite to walking image_speed = anim_speed; // 确保行走动画速度正确 x=x-xspeed // move the player left c2 = -1; c3 = -1; // check the points at the bottom of the sprite c1 = tilemap_get_at_pixel(obj_Spel.map,x-(sprite_get_width(sprite_index)/2),y-1); // left c3 = tilemap_get_at_pixel(obj_Spel.map,x,y-1); // center if( y&$3f>0 ) c2=tilemap_get_at_pixel(obj_Spel.map,x-(sprite_get_width(sprite_index)/2),y+1); // left below (only check if there is a tile below) if(c1 == 3 || c2 == 3){ // 修正原代码的语法错误:括号位置不对 x = real(x&$ffffffc0)+(sprite_get_width(sprite_index)/2); // stop the player from moving } if(x < 0){ // the the player has moved off the edge of the screen x = room_width; // wrap around to the other side of the screen } is_moving = true; }else if(keyboard_check(vk_right)){ // moving right collisions (check with else so that both directions cant be triggered at the same time) dir=1; // set the correct direction image_xscale = dir; // make the sprite face the correct direction // if we are not jumping or falling sprite_index = spr_denpman_Loop; // set the sprite to walking image_speed = anim_speed; x=x+xspeed; // move the player right c2 = -1; c3 = -1; // check the points at the bottom of the sprite c1 = tilemap_get_at_pixel(obj_Spel.map,x+(sprite_get_width(sprite_index)/2),y-1); // right c3 = tilemap_get_at_pixel(obj_Spel.map,x,y-1); // center if( y&$3f>0 ) c2=tilemap_get_at_pixel(obj_Spel.map,x+(sprite_get_width(sprite_index)/2),y+1); // right below (only check if there is a tile below) if(c1 == 3 || c2 == 3){ // 修正原代码的语法错误:括号位置不对 x = real(x&$ffffffc0)+obj_Spel.tilesize-(sprite_get_width(sprite_index)/2); // stop the player from moving } if(x > room_width){ // the the player has moved off the edge of the screen x = 0; // wrap around to the other side of the screen } is_moving = true; } // 新增:当没有移动输入时,切换到静止状态 if(!is_moving){ sprite_index = spr_denpman_Idle; // 替换成你实际的静止sprite名称 image_index = 0; // 可选:重置动画帧到第一帧,避免从行走动画中间开始显示 // 如果你的静止sprite不需要动画,可以加上这行:image_speed = 0; }
额外细节提醒
- 我顺便修正了原代码里的一个语法错误:
if(c1 == 3) || (c2 == 3)这种写法是错的,应该把条件都放在if()括号里,改成if(c1 == 3 || c2 == 3),不然会触发语法报错。 - 如果你的静止 sprite 是静态单帧的,记得把
image_speed设置为 0,防止它意外播放动画。 - 用
is_moving变量来标记移动状态,比直接写!keyboard_check(vk_left) && !keyboard_check(vk_right)更清晰,后续扩展功能也更方便。
内容的提问来源于stack exchange,提问作者markm
相关产品推荐
相关产品推荐

