Jump to content
  • Advertisement
Sign in to follow this  
Keeperofsoulz

please Help with my tetris clone in SDL

This topic is 4493 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm having just a bit of trouble with this code the code generates a piece and is just supposed to make it fall like it would if you were playing a game (I'm not worried about collision or it stopping at the bottom yet) the problem is the piece doesn't fall unless I'm moving the mouse over the screen constantly, if I do this the piece does exactly what I want it to do I don't have any mouseover events in the code so I'm not sure if maybe it's having trouble processing loops or what it could be and I'm hoping someone can give me some advice here is the code
//headers
#include "SDL/SDL.h"
#include "SDL/SDL_image.h"
#include <string>
#include <vector>

//constants
const int SCREEN_HEIGHT = 480;
const int SCREEN_WIDTH = 640;
const int SCREEN_BPP = 32;
const int BLOCK_WIDTH = 20;
const int BLOCK_HEIGHT = 20;
const int FRAMES_PER_SECOND = 20;

//surfaces
SDL_Surface *screen;
SDL_Surface *BG;
SDL_Surface *block;
SDL_Event event;


//Piece Class
class Piece
{
    private:
    std::vector<SDL_Rect> piece;
    int type;
    int x, y;
    int x_vel, y_vel;
    public:
    Piece(int X, int Y);
    void piece_type();
    void piece_move(std::vector<SDL_Rect> &rects);
    void shift_boxes();
    void handle_input();
    void piece_show();
    void make_piece(int type);
    std::vector<SDL_Rect> &get_piece();

};
//Timer Class to keep the FPS in order
class Timer
{
    private:
    int startTicks;
    int pausedTicks;
    bool paused;
    bool started;
    
    public:
    Timer();
    void start();
    void stop();
    void pause();
    void unpause();
    int get_ticks();
    bool is_started();
    bool is_paused();    
};
//functions
//loading images function
SDL_Surface *load_image(std::string filename)
{
    SDL_Surface* loaded_image = NULL;
    SDL_Surface* optimized_image = NULL;
    
    loaded_image = IMG_Load(filename.c_str());
    
    if(loaded_image != NULL)
    {
        optimized_image = SDL_DisplayFormat(loaded_image);
        SDL_FreeSurface(loaded_image);
    }
    return optimized_image;
}

//applying surfaces function
void apply_surface(int x, int y, SDL_Surface* source, SDL_Surface *destination)
{
    SDL_Rect offset;
    
    offset.x = x;
    offset.y = y;
    
    SDL_BlitSurface(source, NULL, destination, &offset);
}

//makes the piece fall
void Piece::handle_input()
{
    y_vel += BLOCK_HEIGHT;
}    

void Piece::piece_show()
{
    int i;
    for(i = 0; i < piece.size(); i++)
        apply_surface(piece.x, piece.y, block, screen);
            
}
//constructor
Piece::Piece(int X, int Y)
{
    type = -1;
    x = X; 
    y = Y; 
    x_vel = 0;
    y_vel = 0;
    
    piece.resize(4);
}
//creates a piece depending on what type is sent 
void Piece::make_piece(int type)
{
    int i = 0;
    switch(type)
    {
        case 1:
            
            piece[0].x = 290;
            piece[0].y = 0;
            piece[1].x = 310;
            piece[1].y = 0;
            piece[2].x = 330;
            piece[2].y = 0;
            piece[3].x = 310;
            piece[3].y = 20;
            break;
        case 2:
            piece[0].x = 300;
            piece[0].y = 0;
            piece[1].x = 320;
            piece[1].y = 0;
            piece[2].x = 300;
            piece[2].y = 20;
            piece[3].x = 320;
            piece[3].y = 20;
            break;
        case 3:
            piece[0].x = 310;
            piece[0].y = 0;
            piece[1].x = 310;
            piece[1].y = 20;
            piece[2].x = 310;
            piece[2].y = 40;
            piece[3].x = 310;
            piece[3].y = 60;
            break;
        case 4:
            piece[0].x = 310;
            piece[0].y = 0;
            piece[1].x = 330;
            piece[1].y = 0;
            piece[2].x = 290;
            piece[2].y = 20;
            piece[3].x = 310;
            piece[3].y = 20;
            break;
        
        
            
            
    }
}
//will generate a random peice ****not used yet****
void Piece::piece_type()
{
    type = rand() % 7;
    make_piece(type);
}
//goes through the parts of the piece and moves the piece
void Piece::piece_move(std::vector<SDL_Rect> &rects)
{
    int i;
    for(i = 0; i < piece.size(); i++)
        piece.y += y_vel;
}
std::vector<SDL_Rect> &Piece::get_piece()
{
    return piece;    
}

//Timer Construtor
Timer::Timer()
{
    startTicks = 0;
    pausedTicks = 0;
    paused = false;
    started = false;    
}

void Timer::start()
{
    started = true;
    paused = false;
    startTicks = SDL_GetTicks();    
}

void Timer::stop()
{
    started = false;
    paused = false;    
}

void Timer::pause()
{
    if( ( started == true ) && ( paused == false ) )
    {
        paused = true;
        pausedTicks = SDL_GetTicks() - startTicks;
    }
}

void Timer::unpause()
{
    if( paused == true )
    {
        paused = false;
        startTicks = SDL_GetTicks() - pausedTicks;
        pausedTicks = 0;
    }
}

int Timer::get_ticks()
{
    if( started == true )
        if( paused == true )
            return pausedTicks;
        else
            return SDL_GetTicks() - startTicks;
    return 0;    
}

bool Timer::is_started()
{
    return started;    
}

bool Timer::is_paused()
{
    return paused;    
}
//MAIN
int main(int argc, char* args[])
{
    bool quit = false;
    int type = -1;
    
    Piece my_piece(310, 0);
    Timer fps;
    
    //inits everything
    if(SDL_Init(SDL_INIT_EVERYTHING == -1))
        return 1;
    
    
    screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE);
    
    if(screen == NULL)
        return 1;
        
    SDL_WM_SetCaption("Sir Tet", NULL);
    
    BG = load_image("bg.png");
    block = load_image("block.png");
    
    
     while( quit == false )
    {
        type =  1;
        fps.start();
        while( SDL_PollEvent( &event ) )
        {
            my_piece.handle_input();
            if( event.type == SDL_QUIT )
                quit = true;
        }
        apply_surface(0, 0, BG, screen);
                
        my_piece.make_piece(type);
        my_piece.piece_move(my_piece.get_piece());
        my_piece.piece_show();
                  
        
        
        
    
        if(SDL_Flip(screen) == -1)
            return 1;
        while( fps.get_ticks() < 10000 / FRAMES_PER_SECOND )
        {
            //wait    
        }
    }
    
    
    SDL_FreeSurface(BG);
    SDL_Quit();
    
    return 0;
}
    
    
    



I appreciate any comments/suggestions from anyone Thank you in advance KoS

Share this post


Link to post
Share on other sites
Advertisement
You move the piece during the call to Piece::handleInput, which is only called when SDL_PollEvent has an event in the queue. There will be no event in the queue unless you're moving the mouse around or something, which is causing the unwanted behavior.

Moving the Piece::handleInput call outside your event loop should fix the problem, and I'd also suggest changing the name of the function - its a bit misleading.

EDIT: Additionally, you're calling Piece::make_piece every pass, which appears to reset the position of the piece at the top of the screen.

Share this post


Link to post
Share on other sites
Ha....didn't notice that thank you very much my friend

after staring at the code for a couple hours straight things tend to get lost

:-) thank you again

KoS

Share this post


Link to post
Share on other sites
ok could someone give me a little more help on this
I've got the piece to fall properly but now I'm having trouble getting it to stop

I have a "wall" on the bottom of the screen and I think I have the collision detection correct but it's not working so I obviously have something wrong
it doesn't stop on the wall it goes through the wall and appears back up top

[source = "cpp"]
//headers
#include "SDL/SDL.h"
#include "SDL/SDL_image.h"
#include <string>
#include <vector>

//constants
const int SCREEN_HEIGHT = 480;
const int SCREEN_WIDTH = 640;
const int SCREEN_BPP = 32;
const int BLOCK_WIDTH = 20;
const int BLOCK_HEIGHT = 20;
const int FRAMES_PER_SECOND = 20;

//surfaces
SDL_Surface *screen;
SDL_Surface *BG;
SDL_Surface *block;
SDL_Rect wall;
SDL_Event event;


//Piece Class
class Piece
{
private:
std::vector<SDL_Rect> piece;
int type;
int x, y;
int x_vel, y_vel;
public:
Piece(int X, int Y);
void piece_type();
void piece_move(std::vector<SDL_Rect> &rects);
void shift_boxes();
void fall();
void piece_show();
void make_piece(int type);
std::vector<SDL_Rect> &get_piece();

};
//Timer Class to keep the FPS in order
class Timer
{
private:
int startTicks;
int pausedTicks;
bool paused;
bool started;

public:
Timer();
void start();
void stop();
void pause();
void unpause();
int get_ticks();
bool is_started();
bool is_paused();
};
//functions
//loading images function
SDL_Surface *load_image(std::string filename)
{
SDL_Surface* loaded_image = NULL;
SDL_Surface* optimized_image = NULL;

loaded_image = IMG_Load(filename.c_str());

if(loaded_image != NULL)
{
optimized_image = SDL_DisplayFormat(loaded_image);
SDL_FreeSurface(loaded_image);
}
return optimized_image;
}

//applying surfaces function
void apply_surface(int x, int y, SDL_Surface* source, SDL_Surface *destination)
{
SDL_Rect offset;

offset.x = x;
offset.y = y;

SDL_BlitSurface(source, NULL, destination, &offset);
}
//constructor
Piece::Piece(int X, int Y)
{
type = -1;
x = X;
y = Y;
x_vel = 0;
y_vel = 0;

piece.resize(4);
}

//makes the piece fall
void Piece::fall()
{
y_vel += BLOCK_HEIGHT;
}

void Piece::piece_show()
{
int i;
for(i = 0; i < piece.size(); i++)
apply_surface(piece.x, piece.y, block, screen);

}

//creates a piece depending on what type is sent
void Piece::make_piece(int type)
{
int i = 0;
switch(type)
{
case 1:

piece[0].x = 290;
piece[0].y = 0;
piece[1].x = 310;
piece[1].y = 0;
piece[2].x = 330;
piece[2].y = 0;
piece[3].x = 310;
piece[3].y = 20;
break;
case 2:
piece[0].x = 300;
piece[0].y = 0;
piece[1].x = 320;
piece[1].y = 0;
piece[2].x = 300;
piece[2].y = 20;
piece[3].x = 320;
piece[3].y = 20;
break;
case 3:
piece[0].x = 310;
piece[0].y = 0;
piece[1].x = 310;
piece[1].y = 20;
piece[2].x = 310;
piece[2].y = 40;
piece[3].x = 310;
piece[3].y = 60;
break;
case 4:
piece[0].x = 310;
piece[0].y = 0;
piece[1].x = 330;
piece[1].y = 0;
piece[2].x = 290;
piece[2].y = 20;
piece[3].x = 310;
piece[3].y = 20;
break;




}
}
//will generate a random peice ****not used yet****
void Piece::piece_type()
{
type = rand() % 7;
make_piece(type);
}
bool check_collision( SDL_Rect &A, SDL_Rect &B )
{

int topB;
int bottomA;



bottomA = A.y + BLOCK_HEIGHT;
topB = B.y;

//If any of the sides from A are outside of B
if(bottomA <= topB)
return false;

return true;
}



//goes through the parts of the piece and moves the piece
void Piece::piece_move(std::vector<SDL_Rect> &rects)
{
int i;
for(i = 3; i >= 0; i--)
{
piece.y += y_vel;
if((check_collision(piece, wall)))
piece.y -= y_vel;
}


}
std::vector<SDL_Rect> &Piece::get_piece()
{
return piece;
}

//Timer Construtor
Timer::Timer()
{
startTicks = 0;
pausedTicks = 0;
paused = false;
started = false;
}

void Timer::start()
{
started = true;
paused = false;
startTicks = SDL_GetTicks();
}

void Timer::stop()
{
started = false;
paused = false;
}

void Timer::pause()
{
if( ( started == true ) && ( paused == false ) )
{
paused = true;
pausedTicks = SDL_GetTicks() - startTicks;
}
}

void Timer::unpause()
{
if( paused == true )
{
paused = false;
startTicks = SDL_GetTicks() - pausedTicks;
pausedTicks = 0;
}
}

int Timer::get_ticks()
{
if( started == true )
if( paused == true )
return pausedTicks;
else
return SDL_GetTicks() - startTicks;
return 0;
}

bool Timer::is_started()
{
return started;
}

bool Timer::is_paused()
{
return paused;
}
//MAIN
int main(int argc, char* args[])
{
bool quit = false;
int type = -1;

Piece my_piece(310, 0);
Timer fps;

//inits everything
if(SDL_Init(SDL_INIT_EVERYTHING == -1))
return 1;


screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE);

if(screen == NULL)
return 1;

SDL_WM_SetCaption("Sir Tet", NULL);

BG = load_image("bg.png");
block = load_image("block.png");
wall.x = 0;
wall.y = 440;
wall.w = SCREEN_WIDTH;
wall.h = 40;

while( quit == false )
{
type = 1;
fps.start();
while( SDL_PollEvent( &event ) )
{

if( event.type == SDL_QUIT )
quit = true;
}
apply_surface(0, 0, BG, screen);
SDL_FillRect( screen, &wall, SDL_MapRGB( screen->format, 0x77, 0x77, 0x77 ) );


my_piece.make_piece(type);
my_piece.fall();
my_piece.piece_move(my_piece.get_piece());
my_piece.piece_show();





if(SDL_Flip(screen) == -1)
return 1;
while( fps.get_ticks() < 10000 / FRAMES_PER_SECOND )
{
//wait
}
}


SDL_FreeSurface(BG);
SDL_Quit();

return 0;
}






Once again any suggestions are appreciated...I think my problem is I've stared at this code for way too long
gonna take a break and watch the soccer game

Thanks in Advance
KoS

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!