First commit

This commit is contained in:
SGOrava 2014-11-07 20:47:50 +01:00
commit b722577a98
37 changed files with 2500 additions and 0 deletions

46
.gitignore vendored Normal file
View File

@ -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

53
.kdev4/Tetris.kdev4 Normal file
View File

@ -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

20
.kdev4/_custom.kdev4 Normal file
View File

@ -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=

57
.kdev4/tetris.kdev4 Normal file
View File

@ -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

27
CMakeLists.txt Normal file
View File

@ -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)

4
Tetris.kdev4 Normal file
View File

@ -0,0 +1,4 @@
[Project]
Name=Tetris
Manager=KDevCMakeManager
VersionControl=

BIN
build/data-latin.ttf Normal file

Binary file not shown.

BIN
build/handelgotd.ttf Normal file

Binary file not shown.

228
game.cpp Normal file
View File

@ -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;
}

73
game.hpp Normal file
View File

@ -0,0 +1,73 @@
#ifndef GAME_HPP_INCLUDED
#define GAME_HPP_INCLUDED
#include <iostream>
#include <vector>
#include <SDL/SDL.h>
#include <SDL/SDL_ttf.h>
#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 <GameState *> states;
bool m_bRunning;
bool m_bGameOver;
TTF_Font * fontMenu;
TTF_Font * fontGame;
Uint32 start;
int tick;
};
#endif

32
gamestate.hpp Normal file
View File

@ -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

29
global.cpp Normal file
View File

@ -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;
}

19
global.hpp Normal file
View File

@ -0,0 +1,19 @@
#ifndef GLOBAL_HPP_INCLUDED
#define GLOBAL_HPP_INCLUDED
#include <SDL/SDL.h>
#include <SDL/SDL_ttf.h>
#include <sstream>
#include <cstdio>
#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

44
main.cpp Normal file
View File

@ -0,0 +1,44 @@
#include <iostream>
#include <ctime>
#include <cstdlib>
#include <SDL/SDL.h>
#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;
}

140
map.cpp Normal file
View File

@ -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]);
}
}
}
}

29
map.hpp Normal file
View File

@ -0,0 +1,29 @@
#ifndef MAP_HPP_INCLUDED
#define MAP_HPP_INCLUDED
#include <iostream>
#include <SDL/SDL.h>
#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

68
menu.cpp Normal file
View File

@ -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<MenuItem>::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--;
}
}

34
menu.hpp Normal file
View File

@ -0,0 +1,34 @@
#ifndef MENU_HPP_INCLUDED
#define MENU_HPP_INCLUDED
#include <iostream>
#include <vector>
#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 <MenuItem> polozky;
int select;
};
#endif

39
menuitem.cpp Normal file
View File

@ -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);
}

34
menuitem.hpp Normal file
View File

@ -0,0 +1,34 @@
#ifndef MENUITEM_HPP_INCLUDED
#define MENUITEM_HPP_INCLUDED
#include <iostream>
#include <SDL/SDL.h>
#include <SDL/SDL_ttf.h>
#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

127
menustate.cpp Normal file
View File

@ -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

52
menustate.hpp Normal file
View File

@ -0,0 +1,52 @@
#ifndef MENU_STATE_HPP_INCLUDED
#define MENU_STATE_HPP_INCLUDED
#include <iostream>
#include <SDL/SDL.h>
#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

132
part.cpp Normal file
View File

@ -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;
}

45
part.hpp Normal file
View File

@ -0,0 +1,45 @@
#ifndef PART_HPP_INCLUDED
#define PART_HPP_INCLUDED
#include <iostream>
#include <SDL/SDL.h>
#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

110
pausestate.cpp Normal file
View File

@ -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();
}

48
pausestate.hpp Normal file
View File

@ -0,0 +1,48 @@
#ifndef PAUSE_STATE_HPP_INCLUDED
#define PAUSE_STATE_HPP_INCLUDED
#include <iostream>
#include <SDL/SDL.h>
#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

359
playstate.cpp Normal file
View File

@ -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);
}

68
playstate.hpp Normal file
View File

@ -0,0 +1,68 @@
# ifndef PLAY_STATE_HPP_INCLUDED
# define PLAY_STATE_HPP_INCLUDED
# include <SDL/SDL.h>
# include <iostream>
# include <string>
# include <fstream>
# 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

21
resource.cpp Normal file
View File

@ -0,0 +1,21 @@
#include "resource.hpp"
int colors[7] =
{
0xFF0000,
0x00FF00,
0x0000FF,
0xFF00FF,
0x00FFFF,
0xFFFF00,
0xFF8000
};
int points[4] =
{
40,
100,
300,
1200
};

203
resource.hpp Normal file
View File

@ -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

35
scoreitem.cpp Normal file
View File

@ -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;
}

32
scoreitem.hpp Normal file
View File

@ -0,0 +1,32 @@
#ifndef SCOREITEM_H
#define SCOREITEM_H
# include <iostream>
# include <SDL/SDL.h>
# include <SDL/SDL_ttf.h>
# 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

108
scorestate.cpp Normal file
View File

@ -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;
}

46
scorestate.hpp Normal file
View File

@ -0,0 +1,46 @@
#ifndef SCORESTATE_H
#define SCORESTATE_H
# include <iostream>
# include <vector>
# include <algorithm>
# include <fstream>
# 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<ScoreItem> Items;
};
#endif // SCORESTATE_H

4
states.hpp Normal file
View File

@ -0,0 +1,4 @@
# include "playstate.hpp"
# include "menustate.hpp"
# include "pausestate.hpp"
# include "scorestate.hpp"

99
stringinput.cpp Normal file
View File

@ -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;
}

35
stringinput.hpp Normal file
View File

@ -0,0 +1,35 @@
#ifndef STRINGINPUT_H
#define STRINGINPUT_H
# include <iostream>
# include <string>
# include <SDL/SDL.h>
# include <SDL/SDL_ttf.h>
# 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