From b722577a98f5b502c50364055c989ecf0a2edccc Mon Sep 17 00:00:00 2001 From: SGOrava Date: Fri, 7 Nov 2014 20:47:50 +0100 Subject: [PATCH] First commit --- .gitignore | 46 ++++++ .kdev4/Tetris.kdev4 | 53 +++++++ .kdev4/_custom.kdev4 | 20 +++ .kdev4/tetris.kdev4 | 57 +++++++ CMakeLists.txt | 27 ++++ Tetris.kdev4 | 4 + build/data-latin.ttf | Bin 0 -> 21116 bytes build/handelgotd.ttf | Bin 0 -> 28372 bytes game.cpp | 228 +++++++++++++++++++++++++++ game.hpp | 73 +++++++++ gamestate.hpp | 32 ++++ global.cpp | 29 ++++ global.hpp | 19 +++ main.cpp | 44 ++++++ map.cpp | 140 +++++++++++++++++ map.hpp | 29 ++++ menu.cpp | 68 ++++++++ menu.hpp | 34 ++++ menuitem.cpp | 39 +++++ menuitem.hpp | 34 ++++ menustate.cpp | 127 +++++++++++++++ menustate.hpp | 52 +++++++ part.cpp | 132 ++++++++++++++++ part.hpp | 45 ++++++ pausestate.cpp | 110 +++++++++++++ pausestate.hpp | 48 ++++++ playstate.cpp | 359 +++++++++++++++++++++++++++++++++++++++++++ playstate.hpp | 68 ++++++++ resource.cpp | 21 +++ resource.hpp | 203 ++++++++++++++++++++++++ scoreitem.cpp | 35 +++++ scoreitem.hpp | 32 ++++ scorestate.cpp | 108 +++++++++++++ scorestate.hpp | 46 ++++++ states.hpp | 4 + stringinput.cpp | 99 ++++++++++++ stringinput.hpp | 35 +++++ 37 files changed, 2500 insertions(+) create mode 100644 .gitignore create mode 100644 .kdev4/Tetris.kdev4 create mode 100644 .kdev4/_custom.kdev4 create mode 100644 .kdev4/tetris.kdev4 create mode 100644 CMakeLists.txt create mode 100644 Tetris.kdev4 create mode 100644 build/data-latin.ttf create mode 100644 build/handelgotd.ttf create mode 100644 game.cpp create mode 100644 game.hpp create mode 100644 gamestate.hpp create mode 100644 global.cpp create mode 100644 global.hpp create mode 100644 main.cpp create mode 100644 map.cpp create mode 100644 map.hpp create mode 100644 menu.cpp create mode 100644 menu.hpp create mode 100644 menuitem.cpp create mode 100644 menuitem.hpp create mode 100644 menustate.cpp create mode 100644 menustate.hpp create mode 100644 part.cpp create mode 100644 part.hpp create mode 100644 pausestate.cpp create mode 100644 pausestate.hpp create mode 100644 playstate.cpp create mode 100644 playstate.hpp create mode 100644 resource.cpp create mode 100644 resource.hpp create mode 100644 scoreitem.cpp create mode 100644 scoreitem.hpp create mode 100644 scorestate.cpp create mode 100644 scorestate.hpp create mode 100644 states.hpp create mode 100644 stringinput.cpp create mode 100644 stringinput.hpp diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..47772a3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,46 @@ +# CMake ignore... +CMakeCache.txt +CMakeFiles +Makefile +cmake_install.cmake +install_manifest.txt + +# Compiled Object files +*.slo +*.lo +*.o +*.obj + +# Precompiled Headers +*.gch +*.pch + +# Compiled Dynamic libraries +*.so +*.dylib +*.dll + +# Fortran module files +*.mod + +# Compiled Static libraries +*.lai +*.la +*.a +*.lib + +# Executables +*.exe +*.out +*.app + +# backup +*~ + +# score +.score + +# unsuported build +windows* + +build/tetris diff --git a/.kdev4/Tetris.kdev4 b/.kdev4/Tetris.kdev4 new file mode 100644 index 0000000..89e105a --- /dev/null +++ b/.kdev4/Tetris.kdev4 @@ -0,0 +1,53 @@ +[Buildset] +BuildItems=@Variant(\x00\x00\x00\t\x00\x00\x00\x00\x01\x00\x00\x00\x0b\x00\x00\x00\x00\x01\x00\x00\x00\x0c\x00T\x00e\x00t\x00r\x00i\x00s) + +[CMake] +Build Directory Count=1 +CMakeDir=/usr/share/cmake-3.0/Modules +Current Build Directory Index=0 +ProjectRootRelative=./ + +[CMake][CMake Build Directory 0] +Build Directory Path=file:///home/juraj/projects/Tetris/build +Build Type=Debug +CMake Binary=file:///usr/bin/cmake +Environment Profile= +Extra Arguments= +Install Directory=file:///usr/local + +[Defines And Includes][Compiler] +Name=GCC +Path=gcc +Type=GCC + +[Launch] +Launch Configurations=Launch Configuration 0 + +[Launch][Launch Configuration 0] +Configured Launch Modes=execute +Configured Launchers=nativeAppLauncher +Name=Tetris +Type=Native Application + +[Launch][Launch Configuration 0][Data] +Arguments= +Debugger Shell= +Dependencies=@Variant(\x00\x00\x00\t\x00\x00\x00\x00\x00) +Dependency Action=Nothing +Display Demangle Names=true +Display Static Members=true +EnvironmentGroup=default +Executable= +External Terminal=xterm -hold -e %exe +GDB Path= +Project Target=Tetris,tetris +Remote GDB Config Script= +Remote GDB Run Script= +Remote GDB Shell Script= +Start With=ApplicationOutput +Use External Terminal=true +Working Directory= +isExecutable=false + +[SourceFileTemplates] +LastUsedTemplate=/home/juraj/.kde/share/apps/kdevfiletemplates/template_descriptions/cpp_basic.desktop diff --git a/.kdev4/_custom.kdev4 b/.kdev4/_custom.kdev4 new file mode 100644 index 0000000..e128f9a --- /dev/null +++ b/.kdev4/_custom.kdev4 @@ -0,0 +1,20 @@ +[Containments][1] +ActionPluginsSource=Global +activity=tetris +activityId= +desktop=-1 +formfactor=0 +geometry=0,0,1098,581 +immutability=1 +lastDesktop=-1 +lastScreen=0 +location=0 +orientation=2 +plugin=newspaper +screen=0 +zvalue=0 + +[Project] +Manager=KDevCMakeManager +Name=tetris +VersionControl= diff --git a/.kdev4/tetris.kdev4 b/.kdev4/tetris.kdev4 new file mode 100644 index 0000000..4632700 --- /dev/null +++ b/.kdev4/tetris.kdev4 @@ -0,0 +1,57 @@ +[Buildset] +BuildItems=@Variant(\x00\x00\x00\t\x00\x00\x00\x00\x00) + +[CMake] +Build Directory Count=2 +CMakeDir=/usr/share/cmake-2.8/Modules +Current Build Directory Index=0 +ProjectRootRelative=./ + +[CMake][CMake Build Directory 0] +Build Directory Path=file:///home/juraj/projects/tetris/build +Build Type= +CMake Binary=file:///usr/bin/cmake +Environment Profile=default +Extra Arguments= +Install Directory=file:///usr/local + +[CMake][CMake Build Directory 1] +Build Directory Path=file:///home/juraj/projects/tetris/releare +Build Type=Release +CMake Binary=file:///usr/bin/cmake +Environment Profile=Release +Extra Arguments= +Install Directory=file:///usr/local + +[Launch] +Launch Configurations=Launch Configuration 0 + +[Launch][Launch Configuration 0] +Configured Launch Modes=execute +Configured Launchers=nativeAppLauncher +Name=Tetris +Type=Native Application + +[Launch][Launch Configuration 0][Data] +Arguments= +Debugger Shell= +Dependencies=@Variant(\x00\x00\x00\t\x00\x00\x00\x00\x00) +Dependency Action=Nothing +Display Demangle Names=true +Display Static Members=true +EnvironmentGroup=default +Executable= +External Terminal=xterm -hold -e %exe +GDB Path= +Project Target=tetris,tetris +Remote GDB Config Script= +Remote GDB Run Script= +Remote GDB Shell Script= +Start With=GdbConsole +Use External Terminal=true +Working Directory= +isExecutable=false + +[MakeBuilder] +Number Of Jobs=3 +Su Command=2 diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..b45e7bd --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,27 @@ +cmake_minimum_required(VERSION 2.8) + +project(tetris) + +add_executable( + tetris + scoreitem.cpp + scorestate.cpp + stringinput.cpp + part.cpp + main.cpp + global.cpp + map.cpp + resource.cpp + game.cpp + pausestate.cpp + playstate.cpp + menustate.cpp + menuitem.cpp + menu.cpp +) + +target_link_libraries(tetris SDL SDL_ttf) + +set(CMAKE_CXX_FLAGS "-Wextra -ftabstop=4 -march=native -std=gnu++11 -fshow-column -ftabstop=4 -frounding-math -pipe") + +install(TARGETS tetris RUNTIME DESTINATION bin) diff --git a/Tetris.kdev4 b/Tetris.kdev4 new file mode 100644 index 0000000..0421764 --- /dev/null +++ b/Tetris.kdev4 @@ -0,0 +1,4 @@ +[Project] +Name=Tetris +Manager=KDevCMakeManager +VersionControl= diff --git a/build/data-latin.ttf b/build/data-latin.ttf new file mode 100644 index 0000000000000000000000000000000000000000..46f6425b8beee7a3a19184eaf1d1a4e23902806c GIT binary patch literal 21116 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 Us{U-5>@MYbcuZyC|L8>j7suf6yZ`_I literal 0 HcmV?d00001 diff --git a/build/handelgotd.ttf b/build/handelgotd.ttf new file mode 100644 index 0000000000000000000000000000000000000000..96619e75129112c9789d69de28e9ee6e7eeaf94c GIT binary patch literal 28372 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

%9@4vZ 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 literal 0 HcmV?d00001 diff --git a/game.cpp b/game.cpp new file mode 100644 index 0000000..8fcf29d --- /dev/null +++ b/game.cpp @@ -0,0 +1,228 @@ +#include "game.hpp" +#include "gamestate.hpp" + + +game::game() +{ } + +game::~game() +{ } + + + +bool game::Init() +{ + if ( SDL_Init ( SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_AUDIO ) == -1 ) + { + cerr << "[ERROR] Cannot init SDL" << endl; + + m_bRunning = false; + + return false; + } + + SDL_EnableUNICODE ( SDL_ENABLE ); + + + SDL_WM_SetCaption ( "[SG]Tetris", NULL ); + + m_pScreen = SDL_SetVideoMode ( WIDTH * SIZE + 130, HEIGHT * SIZE, 32, SDL_HWSURFACE | SDL_DOUBLEBUF ); + + if ( m_pScreen == NULL ) + { + cerr << "[ERROR] Cannot setup screen" << endl; + + m_bRunning = false; + + return false; + } + + + if ( TTF_Init() ) + { + cerr << "[ERROR] Cannot init SDL_ttf" << endl; + + m_bRunning = false; + + return false; + } + + + m_bRunning = Load(); + m_bGameOver = false; + tick = 0; + + return m_bRunning; +} + +bool game::Load() +{ + fontMenu = TTF_OpenFont ( "data-latin.ttf", 38 ); + + if ( fontMenu == NULL ) + { + cerr << "[ERROR] Cannot load font 'data-latin.ttf'" << endl; + + return false; + } + + + fontGame = TTF_OpenFont ( "handelgotd.ttf", 30 ); + + if ( fontGame == NULL ) + { + cerr << "[ERROR] Cannot load font 'handelgotd.ttf'" << endl; + + return false; + } + + + return true; +} + +void game::ChangeState ( GameState * state ) +{ + // cleanup the current state + if ( !states.empty() ) + { + states.back()->Clean(); + states.pop_back(); + } + + // store and init the new state + states.push_back ( state ); + states.back()->Init(); +} + +void game::PushState ( GameState * state ) +{ + // pause current state + if ( !states.empty() ) + { + states.back()->Pause(); + } + + // store and init the new state + states.push_back ( state ); + states.back()->Init(); +} + +void game::PopState() +{ + // cleanup the current state + if ( !states.empty() ) + { + states.back()->Clean(); + states.pop_back(); + } + + // resume previous state + if ( !states.empty() ) + { + states.back()->Resume(); + } +} + +void game::DelStateF() +{ + // cleanup the first state + if ( !states.empty() ) + { + states.front()->Clean(); + states.erase(states.begin()); + } +} + +# ifdef DEBUG + int game::CountStates() + { + return states.size(); + } +# endif + +void game::HandleEvents() +{ + states.back()->HandleEvents ( this ); +} + +void game::Update() +{ + states.back()->Update ( this ); +} + +void game::Draw() +{ + states.back()->Draw ( this ); +} + + +SDL_Surface * game::GetScreen() +{ + return m_pScreen; +} + +bool game::Running() +{ + return m_bRunning; +} + +void game::Clean() +{ + # ifdef DEBUG + cout << "Cleanning..." << endl; + # endif + + TTF_CloseFont ( fontMenu ); + + TTF_Quit(); + SDL_Quit(); +} + +void game::Quit() +{ + m_bRunning = false; + + # ifdef DEBUG + cout << "Shutting down..." << endl; + # endif +} + +void game::ReduceFPS() +{ + if ( 1000 / FPS > ( SDL_GetTicks() - start ) ) + { + SDL_Delay ( 1000 / FPS - ( SDL_GetTicks() - start ) ); + } +} + +void game::UpdateFPS() +{ + if ( tick <= FPS ) + { + tick += 1; + } + else + { + tick = 1; + } +} + +Uint32 game::GetStart() +{ + return start; +} + +void game::SetStart ( Uint32 start ) +{ + this->start = start; +} + +TTF_Font * game::GetfontGame() +{ + return fontGame; +} + +TTF_Font * game::GetfontMenu() +{ + return fontMenu; +} diff --git a/game.hpp b/game.hpp new file mode 100644 index 0000000..105b1ca --- /dev/null +++ b/game.hpp @@ -0,0 +1,73 @@ +#ifndef GAME_HPP_INCLUDED +#define GAME_HPP_INCLUDED + +#include +#include +#include +#include + +#include "map.hpp" +#include "part.hpp" + + +using namespace std; + + +class GameState; + +class game +{ + public: + game(); + ~game(); + + bool Init(); + bool Load(); + + void ChangeState ( GameState * state ); + void PushState ( GameState * state ); + void PopState(); + void DelStateF(); + + # ifdef DEBUG + int CountStates(); + # endif + + + void HandleEvents(); + void Update(); + void Draw(); + + SDL_Surface * GetScreen(); + Uint32 GetStart(); + + TTF_Font * GetfontMenu(); + TTF_Font * GetfontGame(); + + void SetStart ( Uint32 start ); + void SetRunning ( bool m_bRunning ); + + void Clean(); + + bool Running(); + void Quit(); + + void ReduceFPS(); + void UpdateFPS(); + + private: + SDL_Surface * m_pScreen; + vector states; + + bool m_bRunning; + bool m_bGameOver; + + TTF_Font * fontMenu; + TTF_Font * fontGame; + + Uint32 start; + int tick; +}; + + +#endif diff --git a/gamestate.hpp b/gamestate.hpp new file mode 100644 index 0000000..ef2e653 --- /dev/null +++ b/gamestate.hpp @@ -0,0 +1,32 @@ +#ifndef GAME_STATE_HPP_INCLUDED +#define GAME_STATE_HPP_INCLUDED + +#include "game.hpp" + + +class GameState +{ + public: + virtual void Init() = 0; + virtual void Clean() = 0; + + virtual void Pause() = 0; + virtual void Resume() = 0; + + virtual void HandleEvents ( game * Game ) = 0; + virtual void Update ( game * Game ) = 0; + virtual void Draw ( game * Game ) = 0; + + void ChangeState ( game * Game, GameState * state ) + { + Game->ChangeState ( state ); + } + + protected: + GameState() { } + + bool FirstRun; +}; + + +#endif diff --git a/global.cpp b/global.cpp new file mode 100644 index 0000000..be01a1c --- /dev/null +++ b/global.cpp @@ -0,0 +1,29 @@ +#include "global.hpp" + + +void drawQuad ( SDL_Surface * screen, short int x, short int y, int color ) +{ + SDL_Rect rect = {x, y, SIZE, SIZE}; + + SDL_FillRect ( screen, &rect, color ); +} + +void apply_surface ( int x, int y, SDL_Surface * source, SDL_Surface * destination, SDL_Rect * clip ) +{ + //Holds offsets + SDL_Rect offset; + + //Get offsets + offset.x = x; + offset.y = y; + + //Blit + SDL_BlitSurface ( source, clip, destination, &offset ); +} + +SDL_Color make_color ( Uint8 r, Uint8 g, Uint8 b ) +{ + SDL_Color color = {r, g, b}; + + return color; +} diff --git a/global.hpp b/global.hpp new file mode 100644 index 0000000..f94e847 --- /dev/null +++ b/global.hpp @@ -0,0 +1,19 @@ +#ifndef GLOBAL_HPP_INCLUDED +#define GLOBAL_HPP_INCLUDED + +#include +#include +#include +#include + +#include "resource.hpp" + + + + +void drawQuad ( SDL_Surface* screen, short int x, short int y, int color ); +void apply_surface ( int x, int y, SDL_Surface * source, SDL_Surface * destination, SDL_Rect * clip = NULL ); +SDL_Color make_color ( Uint8 r, Uint8 g, Uint8 b ); + + +#endif diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..6d9bcb3 --- /dev/null +++ b/main.cpp @@ -0,0 +1,44 @@ +#include +#include +#include +#include + +#include "resource.hpp" +#include "global.hpp" +#include "game.hpp" + +#include "states.hpp" + + +using namespace std; + + +int main ( int argc, char ** argv ) +{ + srand ( time ( NULL ) ); + + game Game; + + if ( !Game.Init() ) + { + return 0; + } + + + Game.ChangeState ( MenuState::Instance() ); + + while ( Game.Running() ) + { + Game.SetStart ( SDL_GetTicks() ); + + Game.HandleEvents(); + Game.Update(); + Game.Draw(); + + Game.ReduceFPS(); + } + + Game.Clean(); + + return 0; +} diff --git a/map.cpp b/map.cpp new file mode 100644 index 0000000..fb6693a --- /dev/null +++ b/map.cpp @@ -0,0 +1,140 @@ +#include "map.hpp" + + +map::map() +{ + reset(); +} + +void map::reset() +{ + for (int y = 0; y < HEIGHT; y++) + { + for (int x = 0; x < WIDTH; x++) + { + data[y][x] = 0; + } + } +} + +bool map::isCollision(part Part, bool strict) +{ + for (int y = 0; y < 4; y++) + { + for (int x = 0; x < 4; x++) + { + if (strict) + { + if ( (Part.getPosY() + y >= 0) && + ( ( data[Part.getPosY() + y][Part.getPosX() + x] && Part.getElement(x, y) ) || + ( Part.getElement(x, y) && Part.getPosX() + x >= WIDTH)) ) + { + return true; + } + } + else + { + if ( (Part.getPosY() + y >= 0) && + ( ( data[Part.getPosY() + y + 1][Part.getPosX() + x] && Part.getElement(x, y) ) || + ( Part.getElement(x, y) && Part.getPosY() + y >= HEIGHT - 1)) ) + { + return true; + } + } + } + } + + return false; +} + +void map::addPart(part Part) +{ + for (int y = 0; y < 4; y++) + { + for (int x = 0; x < 4; x++) + { + if (Part.getElement(x, y)) + data[Part.getPosY() + y][Part.getPosX() + x] = Part.getColor() + 1; + } + } +} + +void map::applyGravity(int h) +{ + int tmp = 0; + + for (int y = h; y > -1; y--) + { + for (int x = 0; x < WIDTH; x++) + { + if (y < (HEIGHT - 1) && data[y + 1][x] == 0 && data[y][x]) + { + tmp = data[y + 1][x]; + data[y + 1][x] = data[y][x]; + data[y][x] = 0; + } + } + } +} + +int map::destroyLines() +{ + int pocet = 0; + + for (int y = 0; y < HEIGHT; y++) + { + bool good = true; + + for (int x = 0; x < WIDTH; x++) + { + if (!data[y][x]) + { + good = false; + + break; + } + } + + if (good) + { + for (int x = 0; x < WIDTH; x++) + { + data[y][x] = 0; + } + + applyGravity(y); + pocet++; + + y = 0; + } + } + + return pocet; +} + +bool map::isFull() +{ + for (int x = 0; x < WIDTH; x++) + { + if (data[0][x]) + { + return true; + } + } + + return false; +} + +void map::draw(SDL_Surface *screen) +{ + for(int i = 0; i < HEIGHT; i++) + { + for(int m = 0; m < WIDTH; m++) + { + if(data[i][m]) + { + drawQuad(screen, m * SIZE, i * SIZE, colors[data[i][m] - 1]); + } + } + } +} diff --git a/map.hpp b/map.hpp new file mode 100644 index 0000000..b9b2b34 --- /dev/null +++ b/map.hpp @@ -0,0 +1,29 @@ +#ifndef MAP_HPP_INCLUDED +#define MAP_HPP_INCLUDED + +#include +#include + +#include "resource.hpp" +#include "part.hpp" +#include "global.hpp" + + +class map +{ + private: + int data[HEIGHT][WIDTH]; + + public: + map(); + + void reset(); + bool isCollision ( part Part, bool strict = false ); + void addPart ( part Part ); + void applyGravity ( int h ); + int destroyLines(); + bool isFull(); + void draw ( SDL_Surface * screen ); +}; + +#endif diff --git a/menu.cpp b/menu.cpp new file mode 100644 index 0000000..1e59fef --- /dev/null +++ b/menu.cpp @@ -0,0 +1,68 @@ +#include "menu.hpp" + + +Menu::Menu() +{ + select = 0; + + # ifdef DEBUG + cout << "First item selected" << endl; + # endif +} + +Menu::~Menu() +{ + +} + +void Menu::addItem(const char* nazov, void (* action)(game*)) +{ + MenuItem item = MenuItem(nazov, action); + + polozky.push_back(item); + + # ifdef DEBUG + cout << "Item was added" << endl; + # endif +} + +void Menu::Execute(game* Game) +{ + polozky[select].Execute(Game); +} + +void Menu::Draw(game* Game) +{ + int i = 0; + + for (vector::iterator it = polozky.begin(); it != polozky.end(); it++) + { + it->draw(Game, 100, (i * 50 + 50), (i == select)); + + i++; + } +} + +void Menu::Down(game* Game) +{ + if (polozky.size() > (select + 1)) + { + select++; + + # ifdef DEBUG + cout << "Next item" << endl; + # endif + } +} + +void Menu::Up(game* Game) +{ + if (select > 0) + { + # ifdef DEBUG + cout << "Previous item" << endl; + # endif + + select--; + } +} diff --git a/menu.hpp b/menu.hpp new file mode 100644 index 0000000..182445d --- /dev/null +++ b/menu.hpp @@ -0,0 +1,34 @@ +#ifndef MENU_HPP_INCLUDED +#define MENU_HPP_INCLUDED + + +#include +#include + +#include "game.hpp" +#include "menuitem.hpp" + + +using namespace std; + + +class Menu +{ + public: + Menu(); + ~Menu(); + + void addItem ( const char * nazov, void ( * action ) ( game * ) ); + void Execute ( game * Game ); + void Draw ( game * Game ); + + void Down ( game * Game ); + void Up ( game * Game ); + + private: + vector polozky; + int select; +}; + + +#endif diff --git a/menuitem.cpp b/menuitem.cpp new file mode 100644 index 0000000..4c0a82e --- /dev/null +++ b/menuitem.cpp @@ -0,0 +1,39 @@ +#include "menuitem.hpp" + + +MenuItem::MenuItem(const char* nazov, void (* action)(game*)) +{ + this->nazov = nazov; + this->action = action; +} + +void MenuItem::Execute(game* Game) +{ + # ifdef DEBUG + cout << "Executing..." << endl; + # endif + + action(Game); +} + +void MenuItem::draw(game* Game, int x, int y, bool active) +{ + SDL_Color textColor; + + if (active) + { + textColor = make_color(123, 123, 255); + } + else + { + textColor = make_color(255, 255, 255); + } + + message = TTF_RenderText_Solid( Game->GetfontMenu(), nazov, textColor); + + apply_surface(x, y, message, Game->GetScreen()); + + + SDL_FreeSurface(message); +} + diff --git a/menuitem.hpp b/menuitem.hpp new file mode 100644 index 0000000..a703514 --- /dev/null +++ b/menuitem.hpp @@ -0,0 +1,34 @@ +#ifndef MENUITEM_HPP_INCLUDED +#define MENUITEM_HPP_INCLUDED + + +#include +#include +#include + +#include "global.hpp" +#include "game.hpp" + + +using namespace std; + + +class MenuItem +{ + public: + MenuItem ( const char * nazov, void ( * action ) ( game * ) ); + + void Execute ( game * Game ); + void draw ( game * Game, int x, int y, bool active = false ); + + private: + void ( * action ) ( game * ); + + const char * nazov; + SDL_Surface * message; + + SDL_Color text_color; +}; + + +#endif diff --git a/menustate.cpp b/menustate.cpp new file mode 100644 index 0000000..6000851 --- /dev/null +++ b/menustate.cpp @@ -0,0 +1,127 @@ +#include "states.hpp" + + +MenuState MenuState::m_MenuState; + +void MenuState::Init() +{ + menu = new Menu(); + + menu->addItem("Play", play); + menu->addItem("High Score", score); + + # ifdef DEBUG + menu->addItem("Debug Info", Debug_Info); + # endif + + menu->addItem("Exit", quit); + + # ifdef DEBUG + std::cout << "MenuState Init Successful" << std::endl; + # endif +} + +void MenuState::Clean() +{ + delete menu; + + # ifdef DEBUG + std::cout << "MenuState Clean Successful" << std::endl; + # endif +} + +void MenuState::Pause() +{ + # ifdef DEBUG + std::cout << "MenuState Paused" << std::endl; + # endif +} + +void MenuState::Resume() +{ + # ifdef DEBUG + std::cout << "MenuState Resumed" << std::endl; + # endif +} + +void MenuState::HandleEvents(game* Game) +{ + SDL_Event event; + + while (SDL_PollEvent(&event)) + { + switch (event.type) + { + case SDL_QUIT: + Game->Quit(); + break; + + case SDL_KEYDOWN: + switch (event.key.keysym.sym) + { + case SDLK_ESCAPE: + { + Game->Quit(); + } + break; + + case SDLK_DOWN: + menu->Down(Game); + break; + + case SDLK_UP: + menu->Up(Game); + break; + + case SDLK_SPACE: + menu->Execute(Game); + break; + + case SDLK_RETURN: + menu->Execute(Game); + break; + } + break; + } + } +} + +void MenuState::Update(game* Game) +{ + SDL_FillRect(Game->GetScreen(), NULL, 0x000000); +} + +// We have to change the way we get the screen in this function +void MenuState::Draw(game* Game) +{ + menu->Draw(Game); + + SDL_Flip(Game->GetScreen()); +} + + +void MenuState::play(game* Game) +{ + Game->ChangeState(PlayState::Instance()); +} + +void MenuState::score(game* Game) +{ + Game->PushState(ScoreState::Instance()); +} + +void MenuState::quit(game* Game) +{ + Game->Quit(); +} + +# ifdef DEBUG + void MenuState::Debug_Info(game* Game) + { + std::cout << "\n\n=== DEBUG INFO ===\n" << std::endl; + + std::cout << "Number of States: " << Game->CountStates() << std::endl; + + std::cout << "\n=== Debug Info ===\n\n" << endl; + } +# endif diff --git a/menustate.hpp b/menustate.hpp new file mode 100644 index 0000000..a8d32df --- /dev/null +++ b/menustate.hpp @@ -0,0 +1,52 @@ +#ifndef MENU_STATE_HPP_INCLUDED +#define MENU_STATE_HPP_INCLUDED + + +#include +#include + +#include "game.hpp" +#include "gamestate.hpp" +#include "menuitem.hpp" +#include "menu.hpp" + + +class MenuState : public GameState +{ + public: + void Init(); + void Clean(); + + void Pause(); + void Resume(); + + void HandleEvents ( game * Game ); + void Update ( game * Game ); + void Draw ( game * Game ); + + // Implement Singleton Pattern + static MenuState * Instance() + { + return &m_MenuState; + } + + + static void play ( game * Game ); + static void score ( game * Game ); + static void quit ( game * Game ); + + # ifdef DEBUG + static void Debug_Info ( game * Game ); + # endif + + protected: + MenuState() {} + + private: + static MenuState m_MenuState; + + Menu * menu; +}; + + +#endif diff --git a/part.cpp b/part.cpp new file mode 100644 index 0000000..de5adf3 --- /dev/null +++ b/part.cpp @@ -0,0 +1,132 @@ +#include "part.hpp" + + +part::part() +{ + posX = WIDTH / 2 - 1; + posY = -4; + + generate(); +} + +void part::fillData() +{ + for (int i = 0; i < 4; i++) + { + for (int j = 0; j < 4; j++) + { + data[i][j] = Shapes[shapeIndex][i][j]; + } + } +} + +void part::generate() +{ + int g; + + g = (rand() % 7) * 4; + + shapeIndex = (ShapeIndexes)g; + color = g / 4; + + fillData(); +} + +void part::move(int x, int y) +{ + if (isValid(x, y)) + { + posX += x; + posY += y; + } +} + +void part::rotate() +{ + int coIndex; + + coIndex = shapeIndex; + + shapeIndex = ((shapeIndex + 1) % 4 == 0 ? shapeIndex - 3 : shapeIndex + 1); + + fillData(); + + if (!isValid()) + { + shapeIndex = coIndex; + + fillData(); + } +} + +bool part::isValid(int xOffset, int yOffset) +{ + for (int y = 0; y < 4; y++) + { + for (int x = 0; x < 4; x++) + { + if ( (data[y][x] && (posX + x + xOffset >= WIDTH || posX + xOffset < 0)) || (data[y][x] && (posY + y + yOffset > HEIGHT)) ) + { + # ifdef DEBUG + cout << "InValid" << endl; + # endif + + return false; + } + } + } + + # ifdef DEBUG + cout << "Valid" << endl; + # endif + + return true; +} + +void part::draw(SDL_Surface *screen) +{ + for (int i = 0; i < 4 ;i++) + { + for (int m = 0; m < 4; m++) + { + if (data[i][m]) + { + drawQuad(screen, (m + posX) * SIZE, (i + posY) * SIZE, colors[color]); + } + } + } +} + +void part::draw ( int startX, int startY, SDL_Surface * screen ) +{ + for (int i = 0; i < 4 ;i++) + { + for (int m = 0; m < 4; m++) + { + if (data[i][m]) + { + drawQuad(screen, (m + posX) * SIZE + startX, (i + posY) * SIZE + startY, colors[color]); + } + } + } +} + +int part::getPosX() +{ + return posX; +} + +int part::getPosY() +{ + return posY; +} + +int part::getElement(int x, int y) +{ + return data[y][x]; +} + +int part::getColor() +{ + return color; +} diff --git a/part.hpp b/part.hpp new file mode 100644 index 0000000..f22dd20 --- /dev/null +++ b/part.hpp @@ -0,0 +1,45 @@ +#ifndef PART_HPP_INCLUDED +#define PART_HPP_INCLUDED + +#include +#include + +#include "resource.hpp" +#include "global.hpp" + + +using namespace std; + + +class part +{ + private: + int shapeIndex; + int posX; + int posY; + + void fillData(); + + + protected: + int data[4][4]; + int color; + + + public: + part(); + + void generate(); + void move ( int x, int y ); + void rotate(); + bool isValid ( int xOffset = 0, int yOffset = 0 ); + void draw ( SDL_Surface * screen ); + void draw ( int startX, int startY, SDL_Surface * screen ); + + int getPosX(); + int getPosY(); + int getElement ( int x, int y ); + int getColor(); +}; + +#endif diff --git a/pausestate.cpp b/pausestate.cpp new file mode 100644 index 0000000..989a1c0 --- /dev/null +++ b/pausestate.cpp @@ -0,0 +1,110 @@ +#include "states.hpp" + + +PauseState PauseState::m_PauseState; + +void PauseState::Init() +{ + menu = new Menu(); + + menu->addItem("Resume", resume); + menu->addItem("To menu", go_to_menu); + menu->addItem("Exit", quit); + + # ifdef DEBUG + std::cout << "PauseState Init Successful" << std::endl; + # endif +} + +void PauseState::Clean() +{ + delete menu; + + # ifdef DEBUG + std::cout << "PauseState Clean Successful" << std::endl; + # endif +} + +void PauseState::Pause() +{ + # ifdef DEBUG + std::cout << "PauseState Paused" << std::endl; + # endif +} + +void PauseState::Resume() +{ + # ifdef DEBUG + std::cout << "PauseState Resumed" << std::endl; + # endif +} + +void PauseState::HandleEvents(game* Game) +{ + SDL_Event event; + + while (SDL_PollEvent(&event)) + { + switch (event.type) + { + case SDL_QUIT: + Game->Quit(); + break; + + case SDL_KEYDOWN: + switch (event.key.keysym.sym) + { + case SDLK_ESCAPE: + Game->PopState(); + break; + + case SDLK_DOWN: + menu->Down(Game); + break; + + case SDLK_UP: + menu->Up(Game); + break; + + case SDLK_SPACE: + menu->Execute(Game); + break; + + case SDLK_RETURN: + menu->Execute(Game); + break; + } + break; + } + } +} + +void PauseState::Update(game* Game) +{ + SDL_FillRect(Game->GetScreen(), NULL, 0x000000); +} + +// We have to change the way we get the screen in this function +void PauseState::Draw(game* Game) +{ + menu->Draw(Game); + + SDL_Flip(Game->GetScreen()); +} + + +void PauseState::resume(game* Game) +{ + Game->PopState(); +} + +void PauseState::go_to_menu(game* Game) +{ + Game->DelStateF(); + Game->ChangeState(MenuState::Instance()); +} + +void PauseState::quit(game* Game) +{ + Game->Quit(); +} diff --git a/pausestate.hpp b/pausestate.hpp new file mode 100644 index 0000000..d4baa03 --- /dev/null +++ b/pausestate.hpp @@ -0,0 +1,48 @@ +#ifndef PAUSE_STATE_HPP_INCLUDED +#define PAUSE_STATE_HPP_INCLUDED + + +#include +#include + +#include "game.hpp" +#include "gamestate.hpp" +#include "menuitem.hpp" +#include "menu.hpp" + + +class PauseState : public GameState +{ + public: + void Init(); + void Clean(); + + void Pause(); + void Resume(); + + void HandleEvents ( game * Game ); + void Update ( game * Game ); + void Draw ( game * Game ); + + // Implement Singleton Pattern + static PauseState * Instance() + { + return &m_PauseState; + } + + + static void resume ( game * Game ); + static void go_to_menu ( game * Game ); + static void quit ( game * Game ); + + protected: + PauseState() {} + + private: + static PauseState m_PauseState; + + Menu * menu; +}; + + +#endif diff --git a/playstate.cpp b/playstate.cpp new file mode 100644 index 0000000..148f137 --- /dev/null +++ b/playstate.cpp @@ -0,0 +1,359 @@ +# include "game.hpp" +# include "states.hpp" + +PlayState PlayState::m_PlayState; + +void PlayState::Init() +{ + Map = map(); + Part = part(); + Next = part(); + + level = 0; + lines = 0; + score = 0; + + tick = 1; + + nameEntered = false; + nameEntering = false; + message = NULL; + + textColor = make_color(255, 255, 255); + + SDL_EnableKeyRepeat ( REPAET_DELAY, SDL_DEFAULT_REPEAT_INTERVAL ); + + # ifdef DEBUG + std::cout << "PlayState Init Successful" << std::endl; + # endif +} + +void PlayState::Clean() +{ + SDL_EnableKeyRepeat ( 0, 0 ); + + # ifdef DEBUG + std::cout << "PlayState Clean Successful" << std::endl; + # endif +} + +void PlayState::Pause() +{ + SDL_EnableKeyRepeat ( 0, 0 ); + + # ifdef DEBUG + std::cout << "PlayState Paused" << std::endl; + # endif +} + +void PlayState::Resume() +{ + SDL_EnableKeyRepeat ( REPAET_DELAY, SDL_DEFAULT_REPEAT_INTERVAL ); + + # ifdef DEBUG + std::cout << "PlayState Resumed" << std::endl; + # endif +} + +void PlayState::HandleEvents ( game* Game ) +{ + SDL_Event event; + + while ( SDL_PollEvent ( &event ) ) + { + if ( event.type == SDL_QUIT) + Game->Quit(); + + if( nameEntering == true && nameEntered == false ) + { + //Get user input + name.handle_input(Game, &event); + + //If the enter key was pressed + if( ( event.type == SDL_KEYDOWN ) && ( event.key.keysym.sym == SDLK_RETURN ) ) + { + //Change the flag + nameEntered = true; + nameEntering = false; + + Save(name.GetStr(), lines); + + name.Clear(); + + //Free the old message surface + SDL_FreeSurface( message ); + + //Change the message + } + + name.show_centered(Game); + } + else + { + switch ( event.type ) + { + case SDL_KEYDOWN: + switch ( event.key.keysym.sym ) + { + case SDLK_ESCAPE: + { + //Game->SetRunning(false); + Game->PushState ( PauseState::Instance() ); + } + break; + + case SDLK_RIGHT: + { + part p = Part; + + # ifdef DEBUG + std::cout << "move to Right: "; + # endif + + Part.move ( 1, 0 ); + + if ( Map.isCollision ( Part, true ) ) + { + # ifdef DEBUG + std::cout << "Collision" << std::endl; + # endif + + Part = p; + } + } + break; + + case SDLK_LEFT: + { + part p = Part; + + # ifdef DEBUG + std::cout << "move to Left: "; + # endif + + Part.move ( -1, 0 ); + + if ( Map.isCollision ( Part, true ) ) + { + # ifdef DEBUG + std::cout << "Collision" << std::endl; + # endif + + Part = p; + } + } + break; + + case SDLK_DOWN: + # ifdef DEBUG + std::cout << "move to Down: "; + # endif + + if ( !Map.isCollision ( Part ) ) + { + Part.move ( 0, 1 ); + } + else + { + # ifdef DEBUG + std::cout << "Collision" << std::endl; + # endif + } + break; + + case SDLK_UP: + { + part p = Part; + + # ifdef DEBUG + std::cout << "Rotate: "; + # endif + + Part.rotate(); + + if ( Map.isCollision ( Part, true ) ) + { + # ifdef DEBUG + std::cout << "Map: Collission" << std::endl; + # endif + + Part = p; + } + } + break; + + case SDLK_SPACE: + # ifdef DEBUG + std::cout << "move to Bottom" << std::endl; + # endif + + while ( !Map.isCollision ( Part ) ) + { + Part.move ( 0, 1 ); + + tick = FPS - 1; + } + break; + + case SDLK_RETURN: + { + # ifdef DEBUG + std::cout << "continue" << std::endl; + # endif + + //Game->m_bGameOver = false; + } + break; + } + break; + } + } + } +} + +void PlayState::Update ( game* Game ) +{ + if ( Map.isFull() ) + { + nameEntering = true; + + if (nameEntered) + { + nameEntering = false; + nameEntered = false; + //text.setString("Score " + intToStr(Map.getScore()) + "\n" + "Press enter"); + Map.reset(); + + lines = 0; + level = 1; + } + } + + + if (!nameEntering) + { + if ( level == 0 ) + { + level = 1; + } + + if ( tick % ( FPS / ( ( level > 30 ) ? 30 : level ) ) == 0 && !Map.isCollision ( Part ) ) + { + # ifdef DEBUG + std::cout << "move to Down: "; + # endif + + Part.move ( 0, 1 ); + } + + + if ( Map.isCollision ( Part ) && tick + 1 == ( FPS / ( ( level > 30 ) ? 30 : level ) ) ) + { + int count; + + Map.addPart ( Part ); + + count = Map.destroyLines(); + + lines += count; + // level = (lines >= 5) ? (lines / 10) : 0; + level = lines / 10 + 1; + + # ifdef DEBUG + std::cout << "Lines: " << lines << std::endl; + std::cout << "Level: " << level << std::endl; + # endif + + Part = Next; + Next = part(); + } + + + if ( tick < FPS ) + { + tick++; + } + else + { + tick = 1; + } + } +} + + +void PlayState::Draw ( game* Game ) +{ + if (!nameEntering) + { + SDL_FillRect ( Game->GetScreen(), NULL, 0x000000 ); + + SDL_Rect rect = {WIDTH * SIZE, 0, 130, HEIGHT * SIZE}; + + SDL_FillRect ( Game->GetScreen(), &rect, 0x111111 ); + + Map.draw ( Game->GetScreen() ); + Part.draw ( Game->GetScreen() ); + Next.draw ( 165, 100, Game->GetScreen() ); + + PlayInfo(this, Game); + } + else + { + SDL_FillRect ( Game->GetScreen(), NULL, 0x000000 ); + + message = TTF_RenderText_Solid( Game->GetfontGame(), "Enter Name: ", textColor ); + apply_surface(10, 40, message, Game->GetScreen()); + + name.show_centered(Game); + } + + SDL_Flip ( Game->GetScreen() ); +} + + +void PlayState::Save ( string Name, int Lines ) +{ + ofstream file; + + file.open(".score", ios_base::app); + + if (file.is_open()) + { + file << Name << " " << Lines << endl; + + file.close(); + } + else + { + cerr << "Cannot open file '.score'" << endl; + } +} + + +void PlayInfo ( PlayState * Info, game * Game ) +{ + SDL_Color textColor; + SDL_Surface * message; + char temp[10]; + + textColor = make_color(255, 255, 255); + + + message = TTF_RenderText_Solid( Game->GetfontGame(), "Lines", textColor); + apply_surface(220, 150, message, Game->GetScreen()); + + std::sprintf ( temp, "%d", Info->lines); + message = TTF_RenderText_Solid( Game->GetfontGame(), temp, textColor); + apply_surface(220, 185, message, Game->GetScreen()); + + + message = TTF_RenderText_Solid( Game->GetfontGame(), "Level", textColor); + apply_surface(220, 230, message, Game->GetScreen()); + + std::sprintf ( temp, "%d", Info->level); + message = TTF_RenderText_Solid( Game->GetfontGame(), temp, textColor); + apply_surface(220, 265, message, Game->GetScreen()); + + + SDL_FreeSurface(message); +} diff --git a/playstate.hpp b/playstate.hpp new file mode 100644 index 0000000..f13616d --- /dev/null +++ b/playstate.hpp @@ -0,0 +1,68 @@ +# ifndef PLAY_STATE_HPP_INCLUDED +# define PLAY_STATE_HPP_INCLUDED + +# include +# include +# include +# include + +# include "game.hpp" +# include "gamestate.hpp" +# include "resource.hpp" +# include "part.hpp" +# include "map.hpp" +# include "stringinput.hpp" + + +class PlayState : public GameState +{ + public: + void Init(); + void Clean(); + + void Pause(); + void Resume(); + + void HandleEvents ( game * Game ); + void Update ( game * Game ); + void Draw ( game * Game ); + + // Implement Singleton Pattern + static PlayState * Instance() + { + return &m_PlayState; + } + + friend void PlayInfo ( PlayState * Info, game * Game ); + + protected: + PlayState() {} + + private: + void Save(string Name, int Lines); + + static PlayState m_PlayState; + + map Map; + part Part; + part Next; + + int score; + int level; + int lines; + + int tick; + + bool nameEntered; + bool nameEntering; + + SDL_Surface * message; + SDL_Color textColor; + + StringInput name; +}; + + +void PlayInfo ( PlayState * Info, game * Game ); + +# endif diff --git a/resource.cpp b/resource.cpp new file mode 100644 index 0000000..d66a55e --- /dev/null +++ b/resource.cpp @@ -0,0 +1,21 @@ +#include "resource.hpp" + + +int colors[7] = +{ + 0xFF0000, + 0x00FF00, + 0x0000FF, + 0xFF00FF, + 0x00FFFF, + 0xFFFF00, + 0xFF8000 +}; + +int points[4] = +{ + 40, + 100, + 300, + 1200 +}; diff --git a/resource.hpp b/resource.hpp new file mode 100644 index 0000000..41186a8 --- /dev/null +++ b/resource.hpp @@ -0,0 +1,203 @@ +# ifndef RESOURCE_HPP_INCLUDED +# define RESOURCE_HPP_INCLUDED + + +# define WIDTH 10 +# define HEIGHT 20 +# define SIZE 20 +# define FPS 60 + +# define REPAET_DELAY 170 + +extern int colors[7]; +extern int points[4]; + +enum ShapeIndexes { I = 0, O = 4, S = 8, Z = 12, T = 16, L = 20, J = 24 }; + +/* Šablóny hracích "kociak" */ +const bool Shapes[][4][4] = +{ + /* I */ + { + {1, 0, 0, 0}, + {1, 0, 0, 0}, + {1, 0, 0, 0}, + {1, 0, 0, 0} + }, + { + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {1, 1, 1, 1} + }, + { + {1, 0, 0, 0}, + {1, 0, 0, 0}, + {1, 0, 0, 0}, + {1, 0, 0, 0} + }, + { + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {1, 1, 1, 1} + }, + + /* O - kocka */ + { + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {1, 1, 0, 0}, + {1, 1, 0, 0} + }, + { + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {1, 1, 0, 0}, + {1, 1, 0, 0} + }, + { + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {1, 1, 0, 0}, + {1, 1, 0, 0} + }, + { + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {1, 1, 0, 0}, + {1, 1, 0, 0} + }, + + /* S */ + { + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 1, 1, 0}, + {1, 1, 0, 0} + }, + { + {0, 0, 0, 0}, + {1, 0, 0, 0}, + {1, 1, 0, 0}, + {0, 1, 0, 0} + }, + { + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 1, 1, 0}, + {1, 1, 0, 0} + }, + { + {0, 0, 0, 0}, + {1, 0, 0, 0}, + {1, 1, 0, 0}, + {0, 1, 0, 0} + }, + + /* Z */ + { + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {1, 1, 0, 0}, + {0, 1, 1, 0} + }, + { + {0, 0, 0, 0}, + {0, 1, 0, 0}, + {1, 1, 0, 0}, + {1, 0, 0, 0} + }, + { + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {1, 1, 0, 0}, + {0, 1, 1, 0} + }, + { + {0, 0, 0, 0}, + {0, 1, 0, 0}, + {1, 1, 0, 0}, + {1, 0, 0, 0} + }, + + /* T */ + { + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 1, 0, 0}, + {1, 1, 1, 0} + }, + { + {0, 0, 0, 0}, + {1, 0, 0, 0}, + {1, 1, 0, 0}, + {1, 0, 0, 0} + }, + { + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {1, 1, 1, 0}, + {0, 1, 0, 0} + }, + { + {0, 0, 0, 0}, + {0, 1, 0, 0}, + {1, 1, 0, 0}, + {0, 1, 0, 0} + }, + + /* L */ + { + {0, 0, 0, 0}, + {1, 0, 0, 0}, + {1, 0, 0, 0}, + {1, 1, 0, 0} + }, + { + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {1, 1, 1, 0}, + {1, 0, 0, 0} + }, + { + {0, 0, 0, 0}, + {1, 1, 0, 0}, + {0, 1, 0, 0}, + {0, 1, 0, 0} + }, + { + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 1, 0}, + {1, 1, 1, 0} + }, + + /* J */ + { + {0, 0, 0, 0}, + {0, 1, 0, 0}, + {0, 1, 0, 0}, + {1, 1, 0, 0} + }, + { + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {1, 0, 0, 0}, + {1, 1, 1, 0} + }, + { + {0, 0, 0, 0}, + {1, 1, 0, 0}, + {1, 0, 0, 0}, + {1, 0, 0, 0} + }, + { + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {1, 1, 1, 0}, + {0, 0, 1, 0} + }, +}; + +#endif diff --git a/scoreitem.cpp b/scoreitem.cpp new file mode 100644 index 0000000..cb719fc --- /dev/null +++ b/scoreitem.cpp @@ -0,0 +1,35 @@ +#include "scoreitem.hpp" + +ScoreItem::ScoreItem ( string Name, int Lines ) +{ + this->Name = Name; + this->Lines = Lines; + + message = NULL; + + textColor = make_color(255, 255, 255); +} + +ScoreItem::~ScoreItem() +{ + +} + +void ScoreItem::Draw ( game * Game, int y ) +{ + char temp[10]; + + message = TTF_RenderText_Solid( Game->GetfontMenu(), Name.c_str(), textColor); + apply_surface(105, y, message, Game->GetScreen()); + + std::sprintf ( temp, "%d", Lines); + message = TTF_RenderText_Solid( Game->GetfontMenu(), temp, textColor); + apply_surface(15, y, message, Game->GetScreen()); + + SDL_FreeSurface(message); +} + +int ScoreItem::GetLines() +{ + return Lines; +} diff --git a/scoreitem.hpp b/scoreitem.hpp new file mode 100644 index 0000000..62d136f --- /dev/null +++ b/scoreitem.hpp @@ -0,0 +1,32 @@ +#ifndef SCOREITEM_H +#define SCOREITEM_H + +# include +# include +# include + +# include "game.hpp" +# include "global.hpp" + +using namespace std; + + +class ScoreItem +{ + public: + ScoreItem ( string Name, int Lines ); + ~ScoreItem(); + + int GetLines(); + + void Draw( game * Game, int y ); + + private: + string Name; + int Lines; + + SDL_Surface * message; + SDL_Color textColor; +}; + +#endif // SCOREITEM_H diff --git a/scorestate.cpp b/scorestate.cpp new file mode 100644 index 0000000..1204343 --- /dev/null +++ b/scorestate.cpp @@ -0,0 +1,108 @@ +#include "scorestate.hpp" + + +bool operator< (ScoreItem First, ScoreItem Second ) +{ + return (First.GetLines() > Second.GetLines()); +} + + +ScoreState ScoreState::m_ScoreState; + +void ScoreState::Draw ( game * Game ) +{ + for (int i = 0; i < (Items.size() > 10 ? 10 : (int) Items.size()); i++) + { + Items[i].Draw(Game, i * 35); + } + + SDL_Flip(Game->GetScreen()); +} + +void ScoreState::Update ( game * Game ) +{ + SDL_FillRect(Game->GetScreen(), NULL, 0x000000); +} + +void ScoreState::HandleEvents ( game * Game ) +{ + SDL_Event event; + + while (SDL_PollEvent(&event)) + { + switch (event.type) + { + case SDL_QUIT: + Game->Quit(); + break; + + case SDL_KEYDOWN: + switch (event.key.keysym.sym) + { + case SDLK_ESCAPE: + Game->PopState(); + break; + } + break; + } + } +} + +void ScoreState::Resume() +{ + # ifdef DEBUG + std::cout << "ScoreState Resumed" << std::endl; + # endif +} + +void ScoreState::Pause() +{ + # ifdef DEBUG + std::cout << "ScoreState Paused" << std::endl; + # endif +} + +void ScoreState::Clean() +{ + Items.clear(); + + # ifdef DEBUG + std::cout << "ScoreState Clean Successful" << std::endl; + # endif +} + +void ScoreState::Init() +{ + Load(); + + sort(Items.begin(), Items.end()); + + # ifdef DEBUG + std::cout << "ScoreState Init Successful" << std::endl; + # endif +} + +void ScoreState::Load() +{ + ifstream file; + string Name; + int Lines; + + file.open(".score"); + + if (file.is_open()) + { + while (!file.eof()) + { + file >> Name; + file >> Lines; + + if (!file.eof()) + Items.push_back(ScoreItem(Name, Lines)); + } + + file.close(); + } + else + cerr << "Cannot open file '.score'" << endl; +} diff --git a/scorestate.hpp b/scorestate.hpp new file mode 100644 index 0000000..98bed17 --- /dev/null +++ b/scorestate.hpp @@ -0,0 +1,46 @@ +#ifndef SCORESTATE_H +#define SCORESTATE_H + +# include +# include +# include +# include + +# include "gamestate.hpp" +# include "scoreitem.hpp" + +using namespace std; + + +class ScoreState : public GameState +{ + public: + void Init(); + void Clean(); + + void Pause(); + void Resume(); + + void HandleEvents ( game * Game ); + void Update ( game * Game ); + void Draw ( game * Game ); + + // Implement Singleton Pattern + static ScoreState * Instance() + { + return &m_ScoreState; + } + + + protected: + ScoreState() {} + + private: + void Load(); + + static ScoreState m_ScoreState; + + vector Items; +}; + +#endif // SCORESTATE_H diff --git a/states.hpp b/states.hpp new file mode 100644 index 0000000..b2201ba --- /dev/null +++ b/states.hpp @@ -0,0 +1,4 @@ +# include "playstate.hpp" +# include "menustate.hpp" +# include "pausestate.hpp" +# include "scorestate.hpp" diff --git a/stringinput.cpp b/stringinput.cpp new file mode 100644 index 0000000..dd1db89 --- /dev/null +++ b/stringinput.cpp @@ -0,0 +1,99 @@ +#include "stringinput.hpp" + +StringInput::StringInput() +{ + str = ""; + text = NULL; + textColor = make_color ( 255, 255, 255 ); +} + +StringInput::~StringInput() +{ + SDL_FreeSurface ( text ); +} + + +void StringInput::handle_input ( game * Game, SDL_Event *event) +{ + //If a key was pressed + if ( event->type == SDL_KEYDOWN ) + { + //Keep a copy of the current version of the string + string temp = str; + + //If the string less than maximum size + if ( str.length() <= 11 ) + { + //If the key is a number + if ( ( event->key.keysym.unicode >= ( Uint16 ) '0' ) && ( event->key.keysym.unicode <= ( Uint16 ) '9' ) ) + { + //Append the character + str += ( char ) event->key.keysym.unicode; + } + else if ( ( event->key.keysym.unicode == ( Uint16 ) '-' ) ) + { + //Append the character + str += ( char ) event->key.keysym.unicode; + } + //If the key is a uppercase letter + else if ( ( event->key.keysym.unicode >= ( Uint16 ) 'A' ) && ( event->key.keysym.unicode <= ( Uint16 ) 'Z' ) ) + { + //Append the character + str += ( char ) event->key.keysym.unicode; + } + //If the key is a lowercase letter + else if ( ( event->key.keysym.unicode >= ( Uint16 ) 'a' ) && ( event->key.keysym.unicode <= ( Uint16 ) 'z' ) ) + { + //Append the character + str += ( char ) event->key.keysym.unicode; + } + } + + #ifdef DEBUG + cout << str << endl; + #endif + + //If backspace was pressed and the string isn't blank + if ( ( event->key.keysym.sym == SDLK_BACKSPACE ) && ( str.length() != 0 ) ) + { + //Remove a character from the end + str.erase ( str.length() - 1 ); + } + + //If the string was changed + if ( str != temp ) + { + //Free the old surface + SDL_FreeSurface ( text ); + + //Render a new text surface + text = TTF_RenderText_Solid ( Game->GetfontGame(), str.c_str(), textColor ); + } + } + +} + +void StringInput::show_centered ( game * Game ) +{ + //If the surface isn't blank + if ( text != NULL ) + { + //Show the name + apply_surface ( 50, 85, text, Game->GetScreen() ); + } +} + + +string StringInput::GetStr() +{ + return str; +} + + +void StringInput::Clear() +{ + str = ""; + + SDL_FreeSurface ( text ); + text = NULL; +} diff --git a/stringinput.hpp b/stringinput.hpp new file mode 100644 index 0000000..f02d0d9 --- /dev/null +++ b/stringinput.hpp @@ -0,0 +1,35 @@ +#ifndef STRINGINPUT_H +#define STRINGINPUT_H + +# include +# include +# include +# include + +# include "game.hpp" +# include "global.hpp" + +using namespace std; + + +class StringInput +{ + public: + StringInput(); + ~StringInput(); + + string GetStr(); + + void handle_input( game * Game, SDL_Event * event ); + void show_centered( game * Game ); + + void Clear(); + + private: + string str; + + SDL_Surface *text; + SDL_Color textColor; +}; + +#endif // STRINGINPUT_H