0
\$\begingroup\$

I am trying to do a snake game in XNA but I have some little problems...

I explain :

The Snake has a direction (Enum Type : Haut(=up), Bas(=down), Droite(=right), Gauche(=left)) When the player press a direction key this funcion is used :

public void SetDirection(Direction newDirection) // Teste les directions impossibles => impossible de faire un demi tour
{
    if (_direction == Direction.Haut && newDirection == Direction.Bas)
    {
        return;
    }
    else if (_direction == Direction.Bas && newDirection == Direction.Haut)
    {
        return;
    }
    else if (_direction == Direction.Gauche && newDirection == Direction.Droite)
    {
        return;
    }
    else if (_direction == Direction.Droite && newDirection == Direction.Gauche)
    {
        return;
    }
    _direction = newDirection;
}

In theory, the snake can't make a U-turn. But it does not work properly (I will try to explain why) :

The snake moves each 100ms. while these 100ms, the snake is waiting for a direction. BUT if the snake goes up for example, and if the user presses {Droite(=right), Bas(=down)} or {Gauche(=left), Bas(=down)} while these 100ms, the snake makes a U-turn, and die because he cuts himself.

As a consequence, the user loose the game...

I can't see how to solve this problem.

If I am not clear or if you need any other information, please let me know.

Thanks in advance for your help

PS : I am sorry for the grammar faults but I don't speak perfectly english... :)

PPS : Here is the call to setDirection :

case GameState.Infini:
    if (newKeyboardState.IsKeyDown(Keys.Escape))
    {
        CurrentGameState = GameState.Pause;
    }
    else if (newKeyboardState.IsKeyDown(Keys.Up))
    {
        _snake.SetDirection(Direction.Haut);
    }
    else if (newKeyboardState.IsKeyDown(Keys.Down))
    {
        _snake.SetDirection(Direction.Bas);
    }
    else if (newKeyboardState.IsKeyDown(Keys.Left))
    {
        _snake.SetDirection(Direction.Gauche);
    }
    else if (newKeyboardState.IsKeyDown(Keys.Right))
    {
        _snake.SetDirection(Direction.Droite);
    }
\$\endgroup\$
  • 1
    \$\begingroup\$ Don't let the snake change its direction if it heads backward from its current heading. \$\endgroup\$ – jgallant May 25 '16 at 11:56
  • \$\begingroup\$ Use mathematical directions and check if the direction is the additive inverse of the current direction and the 100ms movement should be irrelevant to the problem. \$\endgroup\$ – user5665 May 25 '16 at 11:58
  • \$\begingroup\$ Could you edit the question and add the code that calls SetDirection? The issue could be coming from there. \$\endgroup\$ – Alexandre Vaillancourt May 25 '16 at 13:10
  • \$\begingroup\$ Where does the 100ms come from? In Monogame/XNA the gameloop is created for you- what made you deviate from this behavior? \$\endgroup\$ – Felsir May 25 '16 at 16:14
  • \$\begingroup\$ @Jon : it could work ! I will think about why I can implement this in my game \$\endgroup\$ – Bénédicte Ruelle May 26 '16 at 6:19
1
\$\begingroup\$

I finally succeeded to get rid of this behaviour. (Thanks @Jon !)

"Don't let the snake change its direction if it heads backward from its current heading. " It actually works :)

Example with 'Up' Direction :

int X = _snake._parts.Last().X;
int Y = _snake._parts.Last().Y;
if (newDirection == Direction.Haut)
{
    Rectangle test = new Rectangle(X, Y - _blocCorps.Height, _blocCorps.Width, _blocCorps.Height);
    if (test.Intersects(_snake._parts.ElementAt(_snake._parts.Count - 2)))
    {
        return; 
    }
}

Thank to everyone who took some time to help me !

\$\endgroup\$
0
\$\begingroup\$

Not sure if this will work but I did a few tests and it seems to be fine. Define your enum like this :

enum Directions
    {
        Up = 1,
        Down = ~Up,
        Right = 2,
        Left = ~Right
    };

Now you can a check about the current direction and next direction like this

    if(currDit == ~nextDir)
    {
    //the snake will go into itself
    }else
    {
    //change the direction
    }

Again I'm not 100% sure that this will work. Someone correct me if I'm wrong.

\$\endgroup\$
  • \$\begingroup\$ Thank you for your answer ! The problem still occurs, but I'm under the impression that it occurs less often... It is more complicated to provoke the problem but it still appears \$\endgroup\$ – Bénédicte Ruelle May 25 '16 at 12:45
  • \$\begingroup\$ @BénédicteRuelle I think you might have to share more code from your game for us to continue helping you. Like where is the SetDirection method being called. Also the timer for the 100 ms would be nice to have a look at that. \$\endgroup\$ – Uri Popov May 25 '16 at 13:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.