c++ SDL2 snake自身发生U形转弯,碰撞问题

b0zn9rqh  于 2023-01-15  发布在  其他
关注(0)|答案(1)|浏览(138)

让这个箭头是蛇走向正确的方向,而游戏正在运行:
-———〉

    • 问题是**如果我按下向上键,然后设法按下向左键很快,然后蛇采取这种掉头和击中自己:

-———〉—〈
游戏结束。
看起来蛇跳过了游戏的一个迭代,并且根本不动。
这意味着在游戏循环的一次迭代中,变量dir将其值设置为direction_up,但switch语句不执行。因此,存在"dir = direction_up"的点,但snake实际上是向右移动。

    • 我想**防止蛇掉头。蛇应该在每一帧(游戏循环的每一次迭代)中向一个方向移动。

我想回合按键被忽略,如果蛇没有移动至少1瓷砖,因为上一回合?
此枚举在主循环之外:

enum directions
{
    direction_default,
    direction_down,
    direction_left,
    direction_right,
    direction_up,
    direction_total
};

游戏循环内事件处理:

while(SDL_PollEvent(&e))
{
    //poll for currently pending events
    if(e.type == SDL_QUIT) {quit = 1;}
    if(e.type == SDL_KEYDOWN)
    {
        if(e.key.keysym.sym == SDLK_DOWN && dir != direction_up)
            dir = direction_down;
        if(e.key.keysym.sym == SDLK_UP && dir != direction_down)
            dir = direction_up;
        if(e.key.keysym.sym == SDLK_LEFT && dir != direction_right)
            dir = direction_left;
        if(e.key.keysym.sym == SDLK_RIGHT && dir != direction_left)
            dir = direction_right;
    }
}

此switch语句用于移动:

switch(dir)
{
    //check which direction snake is moving
    case direction_down:
        head.y += 10;
        break;
    case direction_up:
        head.y -= 10;
        break;
    case direction_left:
        head.x -= 10;
        break;
    case direction_right:
        head.x += 10;
        break;
}
8hhllhi2

8hhllhi21#

解决任何问题都要从清晰准确地描述所需行为开始。“我希望回合按键被忽略,如果蛇没有移动至少1瓷砖,因为上一回合”?当这样说,它应该是显而易见的如何实现它。
您可以累计蛇在不改变方向的情况下移动的距离,例如:

int moved_since_last_turn = 0;

// ...
while(SDL_PollEvent(&e))
{
    //poll for currently pending events
    if(e.type == SDL_QUIT) {quit = 1;}
    if(e.type == SDL_KEYDOWN)
    {
        if(moved_since_last_turn == 0) { continue; }
        // set new direction to ndir and compare it with old direction later
        int ndir = dir;
        if(e.key.keysym.sym == SDLK_DOWN && dir != direction_up)
            ndir = direction_down;
        if(e.key.keysym.sym == SDLK_UP && dir != direction_down)
            ndir = direction_up;
        if(e.key.keysym.sym == SDLK_LEFT && dir != direction_right)
            ndir = direction_left;
        if(e.key.keysym.sym == SDLK_RIGHT && dir != direction_left)
            ndir = direction_right;

        if(dir != ndir)
        {
            // direction changed, reset move counter
            dir = ndir;
            moved_since_last_turn = 0;
        }
    }
}

// ...

moved_since_last_turn += 1;
switch(dir)
{
    //check which direction snake is moving
    // ...
}

顺便提一下,我建议你把你的逻辑从帧速率中解放出来。通常你需要以比你的逻辑步长更高的速率重绘,例如当操作系统告诉你你之前的图像不再有效,你必须重绘,或者当你有一些动画和/或效果,你需要以正确的速率重绘,而snake的逻辑仍然是固定步长。取决于你画的频率。它也简化了很多事情。

相关问题