From 1d6a7bb467d28898da5eb1270a6e8dabf958fa42 Mon Sep 17 00:00:00 2001 From: Ekaitz Zarraga Date: Tue, 28 Dec 2021 12:39:47 +0100 Subject: Huge rewrite, this is not how I'm supposed to use git but whatever --- assets/block.png | Bin 0 -> 359 bytes src/command.cpp | 9 ++++- src/command.h | 8 +++++ src/game.cpp | 102 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- src/game.h | 42 ++++++++++++++++++++++- src/keyboard.cpp | 20 ++++++++--- src/keyboard.h | 2 ++ src/main.cpp | 72 +++------------------------------------ src/piece.cpp | 71 ++++++++++++++++++++++++++++++++++++++ src/piece.h | 32 +++++++++++++++++ src/point.h | 8 +++++ src/renderer.cpp | 2 +- src/renderer.h | 6 +++- src/texture.h | 3 ++ src/window.cpp | 2 ++ src/window.h | 5 +-- 16 files changed, 302 insertions(+), 82 deletions(-) create mode 100644 assets/block.png create mode 100644 src/piece.cpp create mode 100644 src/piece.h create mode 100644 src/point.h diff --git a/assets/block.png b/assets/block.png new file mode 100644 index 0000000..45bacec Binary files /dev/null and b/assets/block.png differ diff --git a/src/command.cpp b/src/command.cpp index ab134e9..d0ee45b 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -24,4 +24,11 @@ void WindowUnFocus::execute( GameState &game ){ } // Keyboard commands - +KeyboardDownReleased::~KeyboardDownReleased(){} +void KeyboardDownReleased::execute( GameState &game ){ + game.releaseDown(); +} +KeyboardDownPressed::~KeyboardDownPressed(){} +void KeyboardDownPressed::execute( GameState &game ){ + game.pressDown(); +} diff --git a/src/command.h b/src/command.h index 5af7517..a40e786 100644 --- a/src/command.h +++ b/src/command.h @@ -28,5 +28,13 @@ class WindowUnFocus: public Command { }; // Keyboard commands +class KeyboardDownReleased: public Command { + ~KeyboardDownReleased(); + void execute( GameState &state ) override; +}; +class KeyboardDownPressed: public Command { + ~KeyboardDownPressed(); + void execute( GameState &state ) override; +}; #endif diff --git a/src/game.cpp b/src/game.cpp index aae7e7f..1ed8cc0 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -1,8 +1,30 @@ #include "game.h" -GameState::GameState(): +GameState::GameState(Renderer* renderer, float scale_): closed_ {false}, - paused_ {false} { + paused_ {false}, + timeAdvance_ {1000}, + timeCounterAdvance_ {1000}, + timeLevelUp_ {20000}, + renderer_ {renderer}, + piece_ {Piece::PieceType::LINE, 4}, + blockTexture_ {renderer_->renderer()} { + + renderer->setScale(scale_, scale_); + blockTexture_.loadFromFile("assets/block.png"); + + for(int i=0; i < GRID_WIDTH; i++){ + for(int j=0; j < GRID_HEIGHT; j++){ + grid[j][i] = 0; + } + } + grid[1][1] = 1; + grid[0][1] = 1; + grid[0][2] = 1; + grid[9][9] = 1; + + xdirection_ = Direction::NONE; + yspeed_ = 1; } void GameState::close(){ @@ -21,3 +43,79 @@ bool GameState::isPaused(){ bool GameState::isClosed(){ return closed_; } + +void GameState::update( unsigned int dt ){ + timeCounterAdvance_ -= dt * yspeed_; + if ( timeCounterAdvance_ <= 0 ){ + timeCounterAdvance_ = timeAdvance_; + Piece tmp = piece_; + tmp.advance(); + Point* p; + tmp.initIterator(); + + // Check if there's space to move forward + bool canadvance; + while ( p = tmp.nextAbsBlockPos() ){ + if ( grid[p->y][p->x] == 0 ){ + canadvance = true; + } else { + canadvance = false; + } + } + if ( canadvance ){ + piece_ = tmp; + } + } + + // If timer finished, level up + timeCounterLevelUp_ -= dt; + if ( timeCounterLevelUp_ <= 0 ){ + // Make pieces go faster + timeAdvance_ *= 0.95; + timeCounterLevelUp_ = timeLevelUp_; + } + +} + +void GameState::render(){ + // TODO + renderer_->clear(); + + SDL_Rect rect; + rect.x = 0; + rect.y = 0; + rect.w = SQUARE_SIZE; + rect.h = SQUARE_SIZE; + + // Render piece + Point* b; + piece_.initIterator(); + while( b = piece_.nextAbsBlockPos() ){ + blockTexture_.render( b->x * SQUARE_SIZE, b->y * SQUARE_SIZE, &rect ); + } + + // Render grid + for(int i=0; i < GRID_WIDTH; i++){ + for(int j=0; j < GRID_HEIGHT; j++){ + if( grid[j][i] != 0){ + blockTexture_.render( i * SQUARE_SIZE, j * SQUARE_SIZE , &rect); + } + } + } + + renderer_->update(); +} + + +void GameState::pressRotate(){} +void GameState::pressDown(){ + yspeed_ = 4; +} +void GameState::releaseDown(){ + yspeed_ = 1; +} + +void GameState::pressLeft(){} +void GameState::releaseLeft(){} +void GameState::pressRight(){} +void GameState::releaseRight(){} diff --git a/src/game.h b/src/game.h index 118d642..8965010 100644 --- a/src/game.h +++ b/src/game.h @@ -1,19 +1,59 @@ #ifndef GAME_H #define GAME_H +#include "renderer.h" +#include "piece.h" +#include "point.h" +#include "texture.h" class GameState{ private: bool closed_; bool paused_; + int timeAdvance_; + int timeCounterAdvance_; + int timeLevelUp_; + int timeCounterLevelUp_; + + Renderer* renderer_; + + enum class Direction{ + NONE, + LEFT, + RIGHT + }; + Direction xdirection_; + int yspeed_; + + static const int SQUARE_SIZE = 16; + static const int GRID_WIDTH = 16; + static const int GRID_HEIGHT = 32; + + + int grid [GRID_HEIGHT][GRID_WIDTH]; + Piece piece_; + + float scale_; + + Texture blockTexture_; public: - GameState(); + GameState(Renderer* renderer, float scale); void close(); void resume(); void pause(); bool isClosed(); bool isPaused(); + void update(unsigned int dt); + void render(); + + void pressRotate(); + void pressDown(); + void releaseDown(); + void pressLeft(); + void releaseLeft(); + void pressRight(); + void releaseRight(); }; #endif diff --git a/src/keyboard.cpp b/src/keyboard.cpp index b3efada..1eff1d1 100644 --- a/src/keyboard.cpp +++ b/src/keyboard.cpp @@ -2,9 +2,13 @@ Keyboard::Keyboard(){ nop = new Nop; + pressedDown = new KeyboardDownPressed; + releasedDown = new KeyboardDownReleased; } Keyboard::~Keyboard(){ delete nop; + delete pressedDown; + delete releasedDown; } Command* Keyboard::handleEvent( SDL_Event e ){ @@ -19,11 +23,19 @@ Command* Keyboard::handleEvent( SDL_Event e ){ } Command* Keyboard::pressed( SDL_Keycode k, Uint16 mod ){ - // TODO - return nop; + switch(k){ + case SDLK_DOWN: + return pressedDown; + default: + return nop; + } } Command* Keyboard::released( SDL_Keycode k, Uint16 mod ){ - // TODO - return nop; + switch(k){ + case SDLK_DOWN: + return releasedDown; + default: + return nop; + } } diff --git a/src/keyboard.h b/src/keyboard.h index fd4680e..561fda2 100644 --- a/src/keyboard.h +++ b/src/keyboard.h @@ -16,6 +16,8 @@ class Keyboard{ // Keycodes: https://wiki.libsdl.org/SDL_Keycode private: Command* nop; + Command* pressedDown; + Command* releasedDown; }; #endif diff --git a/src/main.cpp b/src/main.cpp index fb4a6b5..1cc27d3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -18,44 +18,6 @@ const int SCREEN_WIDTH = 640; const int SCREEN_HEIGHT = 480; const int WALKING_ANIMATION_FRAMES = 7; -void loop( Renderer &renderer, Texture &gSpriteSheetTexture, SDL_Rect* gSpriteClips, Uint32 dt){ - static int frame; - - renderer.clear(); - SDL_Rect* currentClip = &gSpriteClips[ frame / WALKING_ANIMATION_FRAMES ]; - - - // Txanpona mugitu: - float vx = 100; // px/s - static float xpos0; - float xpos = xpos0 + dt/1000.f * vx; - xpos0 = xpos; - - float g = 75; // px/(s^2) - static float vy0 = 100; // px/s - static float ypos0; - float vy = vy0 -(dt/1000.f * g) ; - float ypos = ypos0 + dt/1000.f * vy; - ypos0 = ypos; - vy0 = vy; - if ( ypos0 < 0 ) { ypos0 = 0; } - if ( ypos < 0 ) { ypos = 0; } - - gSpriteSheetTexture.render(xpos, (SCREEN_HEIGHT/2 -20) - ypos, currentClip); - - //Update screen - renderer.update(); - ++frame; - - //Cycle animation - if( frame / WALKING_ANIMATION_FRAMES >= WALKING_ANIMATION_FRAMES ) - { - frame = 0; - } - return; - -} - int main( int argc, char* args[] ) { @@ -67,38 +29,12 @@ main( int argc, char* args[] ) { Window window {"This is the title", SCREEN_WIDTH, SCREEN_HEIGHT}; Renderer renderer; renderer.init(window.window()); - renderer.setScale(2,2); - - //The window we'll be rendering to - SDL_Rect gSpriteClips[ WALKING_ANIMATION_FRAMES ]; - Texture gSpriteSheetTexture {renderer.renderer()}; - - - //Load sprite sheet texture - if(-1 ==gSpriteSheetTexture.loadFromFile( "assets/money.png" ) ) - { - return -1; - } - else - { - for( int i =0; i < WALKING_ANIMATION_FRAMES; i++){ - //Set sprite clips - gSpriteClips[ i ].x = i*16; - gSpriteClips[ i ].y = 0; - gSpriteClips[ i ].w = 16; - gSpriteClips[ i ].h = 16; - } - } - - - // BODY - /////////////////////////////////////////////////////////////////////////// const Uint32 LOOP_TIME = 20L; // milliseconds Timer timer; timer.start(); - GameState game; + GameState game {&renderer, 2.0}; Keyboard keys; while( true ) @@ -107,7 +43,6 @@ main( int argc, char* args[] ) { SDL_Event e; while( SDL_PollEvent( &e ) != 0 ) { - // Maybe add commands in a queue or a better defined stream? window.handleEvent(e)->execute(game); keys.handleEvent(e)->execute(game); } @@ -117,10 +52,11 @@ main( int argc, char* args[] ) { // GAME LOOP: - loop(renderer, gSpriteSheetTexture, gSpriteClips, timer.elapsed()); + game.update( timer.elapsed() ); + game.render(); - // Loop time calculation: next: + // Loop time calculation: timer.restart(); timer.waitUntil( LOOP_TIME ); } diff --git a/src/piece.cpp b/src/piece.cpp new file mode 100644 index 0000000..51e8dc7 --- /dev/null +++ b/src/piece.cpp @@ -0,0 +1,71 @@ +#include "piece.h" + +Piece::Piece(Piece::PieceType type, int xpos){ + switch (type){ + case PieceType::LINE: + blocks[0] = { 1, 0 }; + blocks[1] = { 1, 1 }; + blocks[2] = { 1, 2 }; + blocks[3] = { 1, 3 }; + break; + case PieceType::BLOCK: + blocks[0] = { 1, 1 }; + blocks[1] = { 1, 2 }; + blocks[2] = { 2, 1 }; + blocks[3] = { 2, 2 }; + break; + case PieceType::S: + blocks[0] = { 1, 0 }; + blocks[1] = { 1, 1 }; + blocks[2] = { 1, 2 }; + blocks[3] = { 1, 3 }; + break; + case PieceType::T: + blocks[0] = { 1, 0 }; + blocks[1] = { 1, 1 }; + blocks[2] = { 1, 2 }; + blocks[3] = { 1, 3 }; + break; + case PieceType::L: + blocks[0] = { 1, 0 }; + blocks[1] = { 1, 1 }; + blocks[2] = { 1, 2 }; + blocks[3] = { 1, 3 }; + break; + } + position_ = {xpos, 0}; +} + +void Piece::initIterator(){ + iterator = 0; +} + +Point* Piece::nextAbsBlockPos(){ + current_block_ = blocks[iterator++]; + current_block_.x += position_.x; + current_block_.y += position_.y; + if( iterator > SIZE ){ + iterator = 0; + return nullptr; + } + return ¤t_block_; +} + +void Piece::rotate(){ + int tmp; + + // FLIP + for( int i = 0; i < SIZE; i++ ){ + tmp = blocks[i].y; + blocks[i].y = blocks[i].x; + blocks[i].x = tmp; + } + // MIRROR + for( int i = 0; i < SIZE; i++ ){ + blocks[i].x = blocks[i].x * (-1) + (SIZE-1); + } +} + +void Piece::advance(){ + position_.y++; +} diff --git a/src/piece.h b/src/piece.h new file mode 100644 index 0000000..53bd112 --- /dev/null +++ b/src/piece.h @@ -0,0 +1,32 @@ +#ifndef PIECES_H +#define PIECES_H + +#include "point.h" + +class Piece { + const static int SIZE = 4; + Point blocks [SIZE]; + Point current_block_; + Point position_; + int iterator; + + public: + enum class PieceType{ + LINE, + BLOCK, + S, + T, + L + }; + + Piece(PieceType type, int xpos); + + Point getPosition(); + void rotate(); + void advance(); + + void initIterator(); + Point* nextAbsBlockPos(); +}; + +#endif diff --git a/src/point.h b/src/point.h new file mode 100644 index 0000000..f67327b --- /dev/null +++ b/src/point.h @@ -0,0 +1,8 @@ +#ifndef POINT_H +#define POINT_H + +struct Point { + int x, y; +}; + +#endif diff --git a/src/renderer.cpp b/src/renderer.cpp index 2f90a8d..352b89b 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -29,7 +29,7 @@ SDL_Renderer * Renderer::renderer(){ return renderer_; } -void Renderer::setScale(int scaleX, int scaleY){ +void Renderer::setScale(float scaleX, float scaleY){ if( SDL_RenderSetScale(renderer_, scaleX, scaleY) < 0){ printf("Unable to set scale in renderer: %s", SDL_GetError()); } diff --git a/src/renderer.h b/src/renderer.h index b76b831..36f64bc 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -1,3 +1,5 @@ +#ifndef RENDERER_H +#define RENDERER_H #include class Renderer{ @@ -9,7 +11,9 @@ class Renderer{ void clear(); void update(); SDL_Renderer* renderer(); - void setScale(int scaleX, int scaleY); + void setScale(float scaleX, float scaleY); private: SDL_Renderer* renderer_; }; + +#endif diff --git a/src/texture.h b/src/texture.h index 311db4a..00779ff 100644 --- a/src/texture.h +++ b/src/texture.h @@ -1,3 +1,5 @@ +#ifndef TEXTURE_H +#define TEXTURE_H #include #include @@ -13,3 +15,4 @@ class Texture{ int h_; SDL_Renderer* renderer_; }; +#endif diff --git a/src/window.cpp b/src/window.cpp index cb25e94..a848de7 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -46,6 +46,8 @@ Command* Window::handleEvent(SDL_Event e){ return focus; case SDL_WINDOWEVENT_FOCUS_LOST: return unfocus; + // case SDL_WINDOWEVENT_SIZE_CHANGED: + // return resize; default: return nop; } diff --git a/src/window.h b/src/window.h index ee4c146..2bc917a 100644 --- a/src/window.h +++ b/src/window.h @@ -1,12 +1,9 @@ #ifndef WINDOW_H #define WINDOW_H #include "command.h" +#include "point.h" #include -struct Point{ - int x, y; -}; - class Window{ public: -- cgit v1.2.3