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\$
9
  • 1
    \$\begingroup\$ Don't let the snake change its direction if it heads backward from its current heading. \$\endgroup\$
    – jgallant
    Commented May 25, 2016 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
    Commented May 25, 2016 at 11:58
  • \$\begingroup\$ Could you edit the question and add the code that calls SetDirection? The issue could be coming from there. \$\endgroup\$
    – Vaillancourt
    Commented May 25, 2016 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
    Commented May 25, 2016 at 16:14
  • \$\begingroup\$ @Jon : it could work ! I will think about why I can implement this in my game \$\endgroup\$ Commented May 26, 2016 at 6:19

2 Answers 2

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\$
2
  • \$\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\$ Commented May 25, 2016 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
    Commented May 25, 2016 at 13:42

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .