我试着帮你改进你的代码。

function scr_player_knockback(){

    var knockback_speed = 3;

    ///检测是否碰撞到敌人
    if (!place_meeting(x, y, obj_enemy)){
        move_x = 0;
        return;
    }

    ///如果没有在上方向移去的空隙,就不进行击退动画
    if ((obj_enemy.hspeed == 2 && !place_free(x - 32, y)) || (obj_enemy.hspeed == -2 && !place_free(x + 32, y))){
        return;
    }

    ///获取击退方向并移去
    if (obj_enemy.hspeed == 2){
        move_x -= knockback_speed;
        while knockback_speed > 0{
            if (place_free(x - 32, y)){
                move_x -= 0.1;
                knockback_speed -= 1;
            }else{
                break;
            }
        }
    }

    ///等于上面的 else
    if (obj_enemy.hspeed == -2){
        move_x += knockback_speed;
        while knockback_speed > 0{
            if (place_free(x + 32, y)){
                move_x += 0.1;
                knockback_speed -= 1;
            }else{
                break;
            }
        }
    }

    ///重置速度
    kb_speed = 0;

    //同样需要处理垂直方向的击退
    //检测是否碰撞到敌人
    if (!place_meeting(x, y + 10, obj_enemy)){
        move_y = 0;
        return;
    }

    ///如果没有在上方向移去的空隙,就不进行击退动画
    if ((obj_enemy.vspeed == 2 && !place_free(x, y - 10)) || (obj_enemy.vspeed == -2 && !place_free(x, y + 30)))){
        return;
    }

    ///获取击退方向并移去
    if (obj_enemy.vspeed == 2){
        move_y -= knockback_speed;
        while knockback_speed > 0{
            if (place_free(x, y - 10)){
                move_y -= 0.1;
                knockback_speed -= 1;
            }else{
                break;
            }
        }
    }

    ///等于上面的 else
    if (obj_enemy.vspeed == -2){
        move_y += knockback_speed;
        while knockback_speed > 0{
            if (place_free(x, y + 30)){
                move_y += 0.1;
                knockback_speed -= 1;
            }else{
                break;
            }
        }
    }

    ///重置速度
    kb_speed = 0;
}

需要注意的几点:

  1. 你的 knockback_speed 速度设定为3,每次只减少 0.1 个单位。 这意味着每次玩家受到击退,移动距离将会减少 3 个单位。
  2. 检测是否上方有空隙的位置设置为 x - 32。 如果对应的 h_speed 值为正(即向右移动),则击退动画就会发生,因为在向右移动时玩家身后的位置是 x - 32,而不是 x + 32。如果是向左移动(即 h_speed 为负),那么玩家身后的位置是 x + 32
  3. 对于垂直方向的击退,检查是否可以在上方位置移动出检查了y + 10``y + 30两种情况。
  4. 如果玩家受到击退动画(意味着 place_meeting(x, y, obj_enemy) 返回 true ),就会在对应的 h_speedv_speed 基础上执行击退动画,所以对于给定的案例(只有 h_speed2-2 ),玩家将向后退或者向前进的移动。

希望我的修改能有所帮助。