Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Using switch case to change states, but its not working  (Read 2506 times)

0 Members and 1 Guest are viewing this topic.

lukap295

  • Newbie
  • *
  • Posts: 3
    • View Profile
Using switch case to change states, but its not working
« on: January 12, 2024, 12:19:07 pm »
#include <SFML/Graphics.hpp>
#include <SFML/Graphics/Color.hpp>
#include "MainMenu.hpp"
#include "Game.hpp"
#include "Snake.hpp"
#include "Food.hpp"
#include "GameOver.hpp"
#include <ctime>

enum class GameState {
    MainMenu,
    Game,
    GameOver
};

int main() {
    srand(time(NULL));
    sf::RenderWindow window(sf::VideoMode(800, 600), "Zmija");
    sf::Texture texture;
    sf::Font font;
    sf::Text text;

    texture.loadFromFile("assets/grass.png");
    font.loadFromFile("assets/Salsa-Regular.ttf");
    MainMenu menu(font, "Zmija");
    GameOver over(font, "Game Over?");
    Game game;
    Snake snake;
    Food food;
    snake.drawSnake();
    game.textures();
    menu.startSetColor(sf::Color::Yellow);
    GameState state = GameState::MainMenu;
    texture.setRepeated(true);
    game.grass.setTexture(texture);
    game.grass.setTextureRect(sf::IntRect(0, 0, 800, 600));
    while (window.isOpen()) {
        sf::Event event;
        while (window.pollEvent(event)) {
            if (event.type == sf::Event::Closed)
                window.close();
        }
        switch (state) {
        case GameState::MainMenu:
        {
            if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up)) {
                menu.startSetColor(sf::Color::Yellow);
                menu.exitSetColor(sf::Color::White);
                if (sf::Keyboard::isKeyPressed(sf::Keyboard::Enter))
                    state = GameState::Game;
            }
            if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down)) {
                menu.startSetColor(sf::Color::White);
                menu.exitSetColor(sf::Color::Yellow);
                if (sf::Keyboard::isKeyPressed(sf::Keyboard::Enter))
                    window.close();
            }
        }
        case GameState::Game:
        {
           
            if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up)) {
                snake.pos = sf::Vector2f(0, -0.2);
            }
            else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down)) {
                snake.pos = sf::Vector2f(0, 0.2);
            }
            else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left)) {
                snake.pos = sf::Vector2f(-0.2, 0);
            }
            else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right)) {
                snake.pos = sf::Vector2f(0.2, 0);
            }
            //udaljenost izmedu zmije i hrane
            int dist2p = sqrt(pow((snake.head.getPosition().x - food.food.getPosition().x), 2) + pow((snake.head.getPosition().y - food.food.getPosition().y), 2));
            if (snake.head.getRadius() + food.food.getRadius() >= dist2p) {
                food.food.setPosition(rand() % 770, rand() % 570);
            }
            //Sudar sa zidom
            if (snake.head.getPosition().x < 20.f)
                state = GameState::GameOver;
            if (snake.head.getPosition().y < 20.f)
                state = GameState::GameOver;
            if (snake.head.getPosition().x > 755)
                state = GameState::GameOver;
            if (snake.head.getPosition().y > 555.f)
                state = GameState::GameOver;
        }
        case GameState::GameOver:
        {
            if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up)) {
                over.retrySetColor(sf::Color::Yellow);
                over.exitSetColor(sf::Color::White);
                snake.head.setPosition(400, 300);
                if (sf::Keyboard::isKeyPressed(sf::Keyboard::Enter))
                    state = GameState::Game;
            }
            if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down)) {
                over.retrySetColor(sf::Color::White);
                over.exitSetColor(sf::Color::Yellow);
                if (sf::Keyboard::isKeyPressed(sf::Keyboard::Enter))
                    window.close();
            }
            snake.move();
            window.clear();
        }
       
    }
        switch (state) {
        case GameState::MainMenu:
            window.draw(menu);
            break;
        case GameState::Game:
            window.draw(game);
            window.draw(food);
            window.draw(snake);
            break;
        case GameState::GameOver:
            window.draw(over);
            break;
        }
        window.display();
    }
    return 0;
}

So my problem is, every time I press Up it returns my snake to the original position, but I don't understand why because I am in a state of Game, and not in a state of GameOver. I am new to SFML.

kojack

  • Sr. Member
  • ****
  • Posts: 343
  • C++/C# game dev teacher.
    • View Profile
Re: Using switch case to change states, but its not working
« Reply #1 on: January 12, 2024, 01:12:00 pm »
Your case blocks don't have break at the end of each one.
Even with braces around the case's code, without a break the code will "fall through", the next case will also run (and so on).
So when you are in game state, it will run the game case then the game over case.
It should be like this:
switch (state)
{
   case GameState::MainMenu:
   {
      // your code
      break;
    }
    case GameState::Game:
    {
      // your code
      break;
    }
    case GameState::GameOver:
    {
      // your code
      break;
    }
}

lukap295

  • Newbie
  • *
  • Posts: 3
    • View Profile
Re: Using switch case to change states, but its not working
« Reply #2 on: January 12, 2024, 01:22:21 pm »
So i added the breaks, but now my snake wont move.

kojack

  • Sr. Member
  • ****
  • Posts: 343
  • C++/C# game dev teacher.
    • View Profile
Re: Using switch case to change states, but its not working
« Reply #3 on: January 12, 2024, 01:55:58 pm »
snake.move();
window.clear();
 
This is inside of the gameover case block, so the snake only moves during game over.
Try moving snake.move(); up into the game case and move window.clear(); outside of the switch (such as just above the second switch), because you want that to happen regardless of the state.