phalange Temat założony przez niniejszego użytkownika |
gra snake - problem z przekazaniem informacji o zakończeniu gry » 2024-06-17 00:53:22 Cześć wszystkim, Mam napisany program do podstawowej wersji snake'a używając SFMLa. Cała logika działa, problem jest jedynie przy zakończeniu gry - okno z napisem game over i ilościa uzyskanych punktów wyświetla się już na początku gry, pomimo że getter statusu gry jest wszędzie ustawiony według mnie poprawnie. Wiąże się z tym również problem, że okno się nie zamyka po kolizji węża ze ścianą czy przeszkodą. Byłabym bardzo wdzięczna za wszelkie rady, gdzie mam źle ustawione. Poniżej pliki, które wpływają na stan gry, dziekuję za pomoc Controller: #include "controller.h" #include <cstdlib> #include <ctime>
GameManager::GameManager( Board & board, snake_figure & snakeFigure, unsigned obstacles, int speed, Ranking & ranking, Menu & menu, sfmlview & view ) : board( board ) , figura( snakeFigure ) , numObstacles( obstacles ) , snakeSpeed( speed ) , ranking( ranking ) , menu( menu ) , view( view ) , czy_trwa( true ) , scoreSaved( false ) { }
void GameManager::update_game() { for( int i = 0; i < figura.get_fig_size(); i++ ) { board.spawn_snake( figura.get_coords( i ).first, figura.get_coords( i ).second ); } std::pair < int, int > oldHeadCoords = figura.get_last_coords().koordy(); figura.move(); board.delete_snake( oldHeadCoords.first, oldHeadCoords.second ); if( figura.get_head().koordy().first == appleX && figura.get_head().koordy().second == appleY ) { figura.add_score(); snake_blocks end; end.x = figura.get_last_coords().koordy().first; end.y = figura.get_last_coords().koordy().second; figura.change_figure( end ); board.delete_apple( appleX, appleY ); unsigned newAppleX, newAppleY; do { newAppleX = rand() % board.get_size(); newAppleY = rand() % board.get_size(); } while( board.has_snake( newAppleX, newAppleY ) || board.has_obstacle( newAppleX, newAppleY ) ); appleX = newAppleX; appleY = newAppleY; board.spawn_apple( appleX, appleY ); } figura.kolizja(); int headX = figura.get_head().koordy().first; int headY = figura.get_head().koordy().second; if( headX >= board.get_size() || headY >= board.get_size() || headX < 0 || headY < 0 ) { czy_trwa = false; if( !scoreSaved ) { ranking.addScore( menu.getPlayerName(), figura.get_score() ); scoreSaved = true; } return; } if( figura.czy_kolizja() || board.has_obstacle( headX, headY ) ) { czy_trwa = false; if( !scoreSaved ) { ranking.addScore( menu.getPlayerName(), figura.get_score() ); scoreSaved = true; } return; } }
void GameManager::play( sf::RenderWindow & window ) { srand( time( 0 ) ); board.add_obstacles( numObstacles ); unsigned a = rand() % board.get_size(); unsigned b = rand() % board.get_size(); appleX = a; appleY = b; board.spawn_apple( a, b ); sf::Clock clock; snakeSpeed = menu.getSnakeSpeed(); if( menu.gameStarted ) { czy_trwa = true; } while( window.isOpen() ) { if( clock.getElapsedTime().asMilliseconds() > snakeSpeed && czy_trwa ) { update_game(); clock.restart(); } sf::Event event; while( window.pollEvent( event ) ) { if( event.type == sf::Event::Closed ) { window.close(); } if( event.type == sf::Event::KeyPressed ) { handle_input( event ); } } window.clear(); view.draw( window, board, figura ); if( !czy_trwa ) { window.draw( gameOverText ); scoreText.setString( "Score: " + std::to_string( figura.get_score() ) ); window.draw( scoreText ); } window.display(); } sf::Clock delayClock; while( delayClock.getElapsedTime().asSeconds() < 3 ) { sf::Event event; while( window.pollEvent( event ) ) { if( event.type == sf::Event::Closed ) { window.close(); } } } }
void GameManager::handle_input( sf::Event event ) { if( sf::Keyboard::isKeyPressed( sf::Keyboard::Left ) ) { figura.turn( A_CLOCKWISE ); } else if( sf::Keyboard::isKeyPressed( sf::Keyboard::Right ) ) { figura.turn( CLOCKWISE ); } }
Menu: #include "menu.h" #include <iostream>
Menu::Menu() : numObstacles( 0 ) , snakeSpeed( 0 ) , gameStarted( true ) { if( !font.loadFromFile( "/home/marta/git/snake/snake_ak_wt15_281312/Montserrat-Regular.ttf" ) ) { std::cout << "Failed to load font" << std::endl; } initializeText( title, "Snake Game", 40, 180, 50 ); initializeText( username, "Enter your name: ", 24, 180, 150 ); initializeText( game_level, "Select difficulty:", 24, 120, 250 ); initializeText( easy, "1. Easy (4 obstacles, 0,8 s)", 24, 150, 300 ); initializeText( medium, "2. Medium (6 obstacles, 0,25 s)", 24, 150, 350 ); initializeText( hard, "3. Hard (12 obstacles, 0,1 s)", 24, 150, 400 ); initializeText( playPrompt, "Press Enter to start", 24, 150, 500 ); initializeText( inputName, "", 24, 400, 150 ); }
void Menu::initializeText( sf::Text & text, const sf::String & str, int size, float x, float y ) { text.setFont( font ); text.setString( str ); text.setCharacterSize( size ); text.setPosition( x, y ); }
void Menu::show_menu( sf::RenderWindow & window ) { playerName = ""; sf::Event event; while( window.isOpen() ) { while( window.pollEvent( event ) ) { if( event.type == sf::Event::Closed ) { window.close(); } else if( event.type == sf::Event::TextEntered ) { if( event.text.unicode < 128 && event.text.unicode != 13 ) { char typedChar = static_cast < char >( event.text.unicode ); if( std::isalpha( typedChar ) ) { playerName += typedChar; inputName.setString( playerName ); } } } else if( event.type == sf::Event::KeyPressed ) { if( event.key.code == sf::Keyboard::Num1 ) { numObstacles = 4; snakeSpeed = 800; easy.setFillColor( sf::Color::Red ); medium.setFillColor( sf::Color::White ); hard.setFillColor( sf::Color::White ); } else if( event.key.code == sf::Keyboard::Num2 ) { numObstacles = 6; snakeSpeed = 250; easy.setFillColor( sf::Color::White ); medium.setFillColor( sf::Color::Red ); hard.setFillColor( sf::Color::White ); } else if( event.key.code == sf::Keyboard::Num3 ) { numObstacles = 12; snakeSpeed = 100; easy.setFillColor( sf::Color::White ); medium.setFillColor( sf::Color::White ); hard.setFillColor( sf::Color::Red ); } else if( event.key.code == sf::Keyboard::Enter ) { if( !playerName.empty() && numObstacles > 0 && snakeSpeed > 0 ) { gameStarted = true; return; } else { std::cout << "Please enter your name and select a difficulty level." << std::endl; } } } } window.clear(); window.draw( title ); window.draw( game_level ); window.draw( easy ); window.draw( medium ); window.draw( hard ); window.draw( username ); window.draw( inputName ); window.draw( playPrompt ); window.display(); } }
std::string Menu::getPlayerName() const { return playerName; }
unsigned Menu::getNumObstacles() const { return numObstacles; }
int Menu::getSnakeSpeed() const { return snakeSpeed; }
bool Menu::startGame() { return gameStarted; }
SnakeMove: #include "snake_move.h" #include "board.h"
void snake_figure::change_figure( snake_blocks & a ) { waz.push_back( a ); }
snake_figure::snake_figure() { for( int i = 0; i < 3; i++ ) { snake_blocks a; a.x = Board::get_size() / 2; a.y = Board::get_size() / 2 - i; change_figure( a ); } }
snake_figure::snake_figure( Board & board ) { for( int i = 0; i < 3; i++ ) { snake_blocks blocks; blocks.x = board.get_size() / 2; blocks.y = board.get_size() / 2 - i; change_figure( blocks ); } }
void snake_figure::change_direction( direction newDirection ) { switch( newDirection ) { case UP: if( kierunek != DOWN ) kierunek = UP; break; case DOWN: if( kierunek != UP ) kierunek = DOWN; break; case LEFT: if( kierunek != RIGHT ) kierunek = LEFT; break; case RIGHT: if( kierunek != LEFT ) kierunek = RIGHT; break; } }
void snake_figure::move() { std::vector < std::pair < int, int >> wspolrzedne; for( auto blocks: waz ) { std::pair < int, int > o = std::make_pair( blocks.x, blocks.y ); wspolrzedne.push_back( o ); } if( get_direction() == UP ) { waz[ 0 ].x -= 1; } else if( get_direction() == DOWN ) { waz[ 0 ].x += 1; } else if( get_direction() == LEFT ) { waz[ 0 ].y -= 1; } else if( get_direction() == RIGHT ) { waz[ 0 ].y += 1; } if( waz[ 0 ].x < 0 || waz[ 0 ].x >= Board::get_size() || waz[ 0 ].y < 0 || waz[ 0 ].y >= Board::get_size() ) { collision = true; } for( int i = 1; i < waz.size(); i++ ) { waz[ i ].x = wspolrzedne[ i - 1 ].first; waz[ i ].y = wspolrzedne[ i - 1 ].second; } }
void snake_figure::kolizja() { collision = false; for( int i = 1; i < get_fig_size(); i++ ) { if( get_head().koordy().first == get_coords( i ).first && get_head().koordy().second == get_coords( i ).second ) { collision = true; break; } } }
void snake_figure::turn( turn_direction turn ) { direction currentDirection = get_direction(); switch( currentDirection ) { case UP: if( turn == CLOCKWISE ) { change_direction( RIGHT ); } else { change_direction( LEFT ); } break; case RIGHT: if( turn == CLOCKWISE ) { change_direction( DOWN ); } else { change_direction( UP ); } break; case DOWN: if( turn == CLOCKWISE ) { change_direction( LEFT ); } else { change_direction( RIGHT ); } break; case LEFT: if( turn == CLOCKWISE ) { change_direction( UP ); } else { change_direction( DOWN ); } break; default: break; } }
bool snake_figure::czy_kolizja() { kolizja(); if( collision ) return true; int headX = get_head().koordy().first; int headY = get_head().koordy().second; if( headX < 0 || headX >= Board::get_size() || headY < 0 || headY >= Board::get_size() ) { return true; } return false; } bool snake_figure::get_gamestate() const { return czy_trwa; }
View: #include "view.h"
sfmlview::sfmlview( snake_figure & snakeFigure, Board & board ) : board( board ) , fig( snakeFigure ) { if( !appleTexture.loadFromFile( "/home/marta/git/snake/snake_ak_wt15_281312/apple.jpg" ) ) { std::cerr << "Failed to load apple.jpg" << std::endl; } else { appleSprite.setTexture( appleTexture ); appleSprite.setScale( static_cast < float >( TILE_SIZE ) / appleTexture.getSize().x, static_cast < float >( TILE_SIZE ) / appleTexture.getSize().y ); } if( !hammerTexture.loadFromFile( "/home/marta/git/snake/snake_ak_wt15_281312/hammer.png" ) ) { std::cerr << "Failed to load hammer.png" << std::endl; } else { hammerSprite.setTexture( hammerTexture ); hammerSprite.setScale( static_cast < float >( TILE_SIZE ) / hammerTexture.getSize().x, static_cast < float >( TILE_SIZE ) / hammerTexture.getSize().y ); } if( !font.loadFromFile( "/home/marta/git/snake/snake_ak_wt15_281312/Montserrat-Regular.ttf" ) ) { std::cerr << "Failed to load font" << std::endl; } else { gameOverText.setFont( font ); gameOverText.setString( "Game Over!" ); gameOverText.setCharacterSize( 50 ); gameOverText.setFillColor( sf::Color::Red ); gameOverText.setPosition( 150, 300 ); scoreText.setFont( font ); scoreText.setCharacterSize( 30 ); scoreText.setFillColor( sf::Color::Red ); scoreText.setPosition( 150, 250 ); } }
void sfmlview::draw( sf::RenderWindow & win, Board & board, snake_figure & figura ) { for( int i = 0; i < board.get_size(); i++ ) { for( int j = 0; j < board.get_size(); j++ ) { if( board.get_field( i, j ).has_snake ) { sf::RectangleShape s( sf::Vector2f( TILE_SIZE, TILE_SIZE ) ); s.setFillColor( sf::Color::Green ); s.setPosition( TILE_SIZE * j, TILE_SIZE * i ); win.draw( s ); } if( board.get_field( i, j ).has_apple ) { appleSprite.setPosition( TILE_SIZE * j, TILE_SIZE * i ); win.draw( appleSprite ); } if( board.get_field( i, j ).has_obstacle ) { hammerSprite.setPosition( TILE_SIZE * j, TILE_SIZE * i ); win.draw( hammerSprite ); } } } if( !figura.get_gamestate() ) { win.draw( gameOverText ); scoreText.setString( "Score: " + std::to_string( figura.get_score() ) ); win.draw( scoreText ); } }
|