Player对象在简单物理模拟GMS中移动不正确

时间:2017-06-19 23:26:42

标签: game-physics game-maker

我创造了一个非常简单的游戏来模拟在球迷宫中滚动球#34; Gamemaker Studio中的风格游戏。它只包含一个玩家对象和无法穿过的墙壁。

当您按下移动键时,玩家对象具有增加/减少的垂直速度和水平速度,然后它的位置每步移动一次这些速度(直到它撞到墙壁) )。当没有按下任何按钮时,我还添加了基本的减速度。

它主要有效,但我有一个非常具体的错误。在 WASD方面非常快速地+正向移动(正确向下; S D )沿x或y轴,如果我提供相反方向的输入(当持有 S 等时交换到 W )当非常靠近墙壁时播放器物体瞬间闪回,尽可能向相反方向移动。

应该发生的事情是,物体应该开始减速,然后不可避免地撞到它所照顾的墙壁上,这就是反向做同样事情时会发生的事情;也就是说,通过按住 W 沿着y轴快速移动,然后在它撞到墙壁之前切换到 S

我不确定,但我很确定当物体以+正方向快速向墙壁移动时它会发生,它没有通过向相反方向增加力量,在撞到墙壁之前有足够的时间减速到停止。

以下是错误行为的short clip

这是另一个方向的正确行为的short clip

这是简单的步骤脚本:

// determine which input keys are being pressed and 
// increment/decrement vspd and hspd respectively
if (vspd < 0 || keyboard_check(ord('W'))){
    if place_meeting(x, y+vspd, block_obj)
    {
        // pixel-perfect collision resolution
        while(!place_meeting(x, y-1, block_obj))
        {
            y -= 1;
        }
        vspd = 0;
    }
    else if keyboard_check(ord('W'))
    {
        if(!place_meeting(x, y-1, block_obj))
            vspd -= 2;
    }
    else
    {
        if(vspd < -2) 
        {
            vspd += 1;
        }
        else
        { 
            vspd = 0;
        }
    }
} 
if (vspd > 0 || keyboard_check(ord('S'))){
    if place_meeting(x, y+vspd, block_obj)
    {
        // pixel-perfect collision resolution
        while(!place_meeting(x, y+1, block_obj))
        {
            y += 1;
        }
        vspd = 0;
    }
    else if keyboard_check(ord('S'))
    {
        if(!place_meeting(x, y+1, block_obj))
            vspd += 2;
    }
    else
    {
        if(vspd > 2)
        {
            vspd -= 1;
        }
        else
        {
            vspd = 0;
        }
    }
}

if (hspd < 0 || keyboard_check(ord('A'))){
    if place_meeting(x+hspd, y, block_obj)
    {
        // pixel-perfect collision resolution
        while(!place_meeting(x-1, y, block_obj))
        {
            x -= 1;
        }
        hspd = 0;
    }
    else if keyboard_check(ord('A'))
    {
        if(!place_meeting(x-1, y, block_obj))
            hspd -= 2;
    }
    else
    {
        if(hspd < -2) 
        {
            hspd += 1;
        }
        else
        {
            hspd = 0;
        }
    }
}
if (hspd > 0 || keyboard_check(ord('D'))){
    if place_meeting(x+hspd, y, block_obj)
    {
        // pixel-perfect collision resolution
        while(!place_meeting(x+1, y, block_obj))
        {
            x += 1;
        }
        hspd = 0;
    }
    else if keyboard_check(ord('D'))
    {
        if(!place_meeting(x+1, y, block_obj))
            hspd += 2;
    }
    else
    {
        if(hspd > 2)
        {
            hspd -= 1;
        }
        else
        {
            hspd = 0;
        }
    }
}

x += hspd;
y += vspd;

我似乎无法找到导致问题的步骤代码部分。

1 个答案:

答案 0 :(得分:1)

如果我这样做,我会通过使用else if语句使每个控件彼此分开。伪代码,例如:

if (w) {
//code
} else if (a) {
//code
} else if (s) {
//code
} else if (d) {
//code
}

这可以防止/帮助您解决问题,因为您无法再一次在多个方向上提供加速度,如果这不能完全发挥作用,可能是因为您正在将轴移动增加到墙上并且当您改变方向时你正朝着那个方向加速,因为碰撞检查不再是一个问题,因为你在按键内部进行了碰撞检查,当你碰到一堵墙时,你不应该因为这个原因而加速,只能让玩家反弹。 我有一个多年前的项目,它会做你想要做的事情,不好的尝试,发现它不起作用,让我知道。