Jump to content
  • Advertisement
Sign in to follow this  
cwl157

tetris in sdl

This topic is 3761 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 have decided to use sdl to display graphics for my tetris game. In text it all works perfect. I display each shape with a different number and then have a display function that goes through the game playing area and says if that spot has a 1 draw red block, if its a 2 draw green block and so on. I need help figuring out how to handle events. I need it to move left when the left arrow is pushed, right when the right arrow is pushed down when the down arrow is pushed and change the shape when the up arrow is pushed. I already did this in test using the w, a, s, d keys so i just need to create functions using sdl that will return true when the button is pushed. So i need a function that returns true when the up arrow is pushed, a function that returns true when the down arrow is pushed a function that returns true when the left arrow is pushed and a function that returns true when the right arrow is pushed. The SDL tutorials on the website use a case switch to detect which one has been pushed. I guess i could do that instead of if statements but i have it set up with if statements. Also another big problem i am having is when a shape is moved down the shape before it is not removed. I have the 2d int array that is my gameBoard change them back to 0 and then i loop through the entire gameBoard everytime something is moved and re-draw the shapes so why is it that when i move a piece from one spot to another even though the place in the array where the piece was is now 0 it does not clear those old blocks? This is my first time making anything graphical so any advice would be appreciated. I have everything figured out in the console using a 2d int array but i can't figure out the graphics part. Thanks. EDIT: Also this sdl statement that updates the screen:
    //Update the screen
    if( SDL_Flip( screen ) == -1 )
    {
        return 1;    
    } // end if

I am not sure where to put that. Should it go at the end of the function that draws the game board to the screen?

Share this post


Link to post
Share on other sites
Advertisement
ok so i might have spoken too soon. I us a case switch to detect when an arrow is pushed and it works fine. I still have 2 problems. 1 is the artifacts left on the screen when the piece moves and the other is with collision detection. It detects when it hits the edge fine but it does not detect when it hits a piece that is down. These 2 lead me to beleive that maybe the gameBoard is not being updated with 0 and non 0 correctly when i added the sdl parts for some reason. Here is all the code what do you think? Sorry its pretty long. The sdl parts are the parts im really having trouble with


#include "SDL/SDL.h"
#include <string>
#include <iostream>

using namespace std;

#define MIDDLE_X 6
#define MIDDLE_Y 6
#define TRUE 1
#define FALSE 0
#define WIDTH 17
#define HEIGHT 17
#define BLOCK_SIZE 30

/************************************************
* function prototypes
************************************************/


void moveRowsDown(void);
void increaseLevel(void);


/************************************************
* SDL Stuff
* Initialize all SDL subsystems and window
* function that loads the images
* function that displays images to screen
************************************************/


//The attributes of the screen
const int SCREEN_WIDTH = 800;
const int SCREEN_HEIGHT = 600;
const int SCREEN_BPP = 32;

//The surfaces that will be used
SDL_Surface *backwardL_block = NULL;
SDL_Surface *longShank_block = NULL;
SDL_Surface *lShape_block = NULL;
SDL_Surface *square_block = NULL;
SDL_Surface *tShape_block = NULL;
SDL_Surface *zigZagRight_block = NULL;
SDL_Surface *zigZagLeft_block = NULL;
//SDL_Surface *background = NULL;
SDL_Surface *screen = NULL;
SDL_Surface *boarder_block = NULL;
SDL_Event event;

// load and optomize an image. Return the optomized image
SDL_Surface *loadImage( std::string filename )
{
//Temporary storage for the image that's loaded
SDL_Surface* loadedImage = NULL;

//The optimized image that will be used
SDL_Surface* optimizedImage = NULL;

//Load the image
loadedImage = SDL_LoadBMP( filename.c_str() );

//If nothing went wrong in loading the image
if( loadedImage != NULL )
{
//Create an optimized image
optimizedImage = SDL_DisplayFormat( loadedImage );

//Free the old image
SDL_FreeSurface( loadedImage );
}

//Return the optimized image
return optimizedImage;
} // end loadImage

// apply the surface to the screen at the x and y positions.
void applySurface( int x, int y, SDL_Surface* source, SDL_Surface* destination )
{
//Make a temporary rectangle to hold the offsets
SDL_Rect offset;

//Give the offsets to the rectangle
offset.x = x;
offset.y = y;

//Blit the surface
SDL_BlitSurface( source, NULL, destination, &offset );
} // end applySurface

// load the images
void loadAllImages()
{
backwardL_block = loadImage("bmp_blocks\\backwardL_block.bmp");
longShank_block = loadImage("bmp_blocks\\longShank_block.bmp");
lShape_block = loadImage("bmp_blocks\\lShape_block.bmp");
square_block = loadImage("bmp_blocks\\square_block.bmp");
tShape_block = loadImage("bmp_blocks\\tShape_block.bmp");
zigZagLeft_block = loadImage("bmp_blocks\\zigZagLeft_block.bmp");
zigZagRight_block = loadImage("bmp_blocks\\zigZagRight_block.bmp");
boarder_block = loadImage("bmp_blocks\\boarder_block.bmp");
//background = load_image( "background.bmp" );
} // end loadAllImages

// this initializes the SDL window and subsystem and all that
void initializeSDL()
{
//Initialize all SDL subsystems
if( SDL_Init( SDL_INIT_EVERYTHING ) == -1 )
{
exit(1);
} // end if
//Set up the screen
screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE );
//If there was in error in setting up the screen
if( screen == NULL )
{
exit(1);
} // end if
//Set the window caption
SDL_WM_SetCaption( "My Tetris Game", NULL );
} // end initializeSDL

// this is called at the end, it frees up all the surfaces and quits
void cleanUp()
{
//Free the surfaces
SDL_FreeSurface(longShank_block);
SDL_FreeSurface(backwardL_block);
SDL_FreeSurface(square_block);
SDL_FreeSurface(tShape_block);
SDL_FreeSurface(lShape_block);
SDL_FreeSurface(boarder_block);
SDL_FreeSurface(zigZagLeft_block);
SDL_FreeSurface(zigZagRight_block);
//Quit SDL
SDL_Quit();
} // end cleanUp

/************************************************
* End SDL Stuff
************************************************/


int shape;
int rotation;
int xPos;
int yPos;
int collideDown = FALSE;
int score;
int level;
int lines;
bool gameOver = false;

/************************************************
* main game board
************************************************/


int gameBoard[HEIGHT][WIDTH] = {{8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8},
{8, 0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8},
{8, 0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8},
{8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8},
{8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8},
{8, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8},
{8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8},
{8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8},
{8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8},
{8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8},
{8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8},
{8, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8},
{8, 0, 0, 0, 2, 2, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0, 8},
{8, 0, 0, 0, 0, 2, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0, 8},
{8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8},
{8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8},
{8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8},
};

// 0 out gameBoard()
void resetGameBoard()
{
for (int row = 1; row < HEIGHT-1; row++)
{
for (int col = 1; col < WIDTH-1; col++)
gameBoard[row][col] = 0;
} // end for
} // end resetGameBoard

/*
void displayGameBoard()
{
for (int row = 0; row < HEIGHT; row++)
{
for (int col = 0; col < WIDTH; col++)
cout << gameBoard[row][col];
cout << endl;
} // end for
} // end displayGameBoard
*/


void displayGameBoard()
{
for (int row = 0; row < HEIGHT; row++)
{
for (int col = 0; col < WIDTH; col++)
{
if (gameBoard[row][col] == 1)
applySurface(col*BLOCK_SIZE, row*BLOCK_SIZE, longShank_block, screen);
else if (gameBoard[row][col] == 2)
applySurface(col*BLOCK_SIZE, row*BLOCK_SIZE, tShape_block, screen);
else if (gameBoard[row][col] == 3)
applySurface(col*BLOCK_SIZE, row*BLOCK_SIZE, square_block, screen);
else if (gameBoard[row][col] == 4)
applySurface(col*BLOCK_SIZE, row*BLOCK_SIZE, backwardL_block, screen);
else if (gameBoard[row][col] == 5)
applySurface(col*BLOCK_SIZE, row*BLOCK_SIZE, zigZagLeft_block, screen);
else if (gameBoard[row][col] == 6)
applySurface(col*BLOCK_SIZE, row*BLOCK_SIZE, zigZagRight_block, screen);
else if (gameBoard[row][col] == 7)
applySurface(col*BLOCK_SIZE, row*BLOCK_SIZE, lShape_block, screen);
else if (gameBoard[row][col] == 8)
applySurface(col*BLOCK_SIZE, row*BLOCK_SIZE, boarder_block, screen);
} // end for
} // end for
} // end displayGameBoard

/************************************************
* end main game board
************************************************/



/************************************************
* array that holds all the shapes
************************************************/


int shapeArray[7][4][4][4] =
{
{
{
{0, 0, 1, 0},
{0, 0, 1, 0},
{0, 0, 1, 0},
{0, 0, 1, 0}
},
{
{0, 0, 0, 0},
{0, 0, 0, 0},
{1, 1, 1, 1},
{0, 0, 0, 0}
},
{
{0, 1, 0, 0},
{0, 1, 0, 0},
{0, 1, 0, 0},
{0, 1, 0, 0}
},
{
{0, 0, 0, 0},
{1, 1, 1, 1},
{0, 0, 0, 0},
{0, 0, 0, 0}
}
}
,
{
{
{0, 0, 0, 0},
{0, 2, 2, 2},
{0, 0, 2, 0},
{0, 0, 0, 0}
},
{
{0, 0, 0, 0},
{0, 0, 2, 0},
{0, 2, 2, 0},
{0, 0, 2, 0}
},
{
{0, 0, 0, 0},
{0, 2, 0, 0},
{2, 2, 2, 0},
{0, 0, 0, 0}
},
{
{0, 2, 0, 0},
{0, 2, 2, 0},
{0, 2, 0, 0},
{0, 0, 0, 0}
}
}
,
{
{
{0, 0, 0, 0},
{0, 3, 3, 0},
{0, 3, 3, 0},
{0, 0, 0, 0}
},
{
{0, 0, 0, 0},
{0, 3, 3, 0},
{0, 3, 3, 0},
{0, 0, 0, 0}
},
{
{0, 0, 0, 0},
{0, 3, 3, 0},
{0, 3, 3, 0},
{0, 0, 0, 0}
},
{
{0, 0, 0, 0},
{0, 3, 3, 0},
{0, 3, 3, 0},
{0, 0, 0, 0}
}
}
,
{
{
{0, 0, 0, 0},
{0, 4, 4, 4},
{0, 0, 0, 4},
{0, 0, 0, 0}
},
{
{0, 0, 0, 0},
{0, 0, 4, 0},
{0, 0, 4, 0},
{0, 4, 4, 0}
},
{
{0, 0, 0, 0},
{4, 0, 0, 0},
{4, 4, 4, 0},
{0, 0, 0, 0}
},
{
{0, 4, 4, 0},
{0, 4, 0, 0},
{0, 4, 0, 0},
{0, 0, 0, 0}
}
}
,
{
{
{0, 0, 0, 0},
{0, 5, 5, 0},
{0, 0, 5, 5},
{0, 0, 0, 0}
},
{
{0, 0, 0, 0},
{0, 0, 5, 0},
{0, 5, 5, 0},
{0, 5, 0, 0}
},
{
{0, 0, 0, 0},
{5, 5, 0, 0},
{0, 5, 5, 0},
{0, 0, 0, 0}
},
{
{0, 0, 5, 0},
{0, 5, 5, 0},
{0, 5, 0, 0},
{0, 0, 0, 0}
}
}
,
{
{
{0, 0, 0, 0},
{0, 0, 6, 6},
{0, 6, 6, 0},
{0, 0, 0, 0}
},
{
{0, 0, 0, 0},
{0, 6, 0, 0},
{0, 6, 6, 0},
{0, 0, 6, 0}
},
{
{0, 0, 0, 0},
{0, 6, 6, 0},
{6, 6, 0, 0},
{0, 0, 0, 0}
},
{
{0, 6, 0, 0},
{0, 6, 6, 0},
{0, 0, 6, 0},
{0, 0, 0, 0}
}
}
,
{
{
{0, 0, 0, 0},
{0, 7, 7, 7},
{0, 7, 0, 0},
{0, 0, 0, 0}
},
{
{0, 0, 0, 0},
{0, 7, 7, 0},
{0, 0, 7, 0},
{0, 0, 7, 0}
},
{
{0, 0, 0, 0},
{0, 0, 7, 0},
{7, 7, 7, 0},
{0, 0, 0, 0}
},
{
{0, 7, 0, 0},
{0, 7, 0, 0},
{0, 7, 7, 0},
{0, 0, 0, 0}
}
}
};

/************************************************
* end array that holds all the shapes
************************************************/


/************************************************
* Tetris game logic functions
* These functions have all the logic of
* playing Tetris
************************************************/


// put the piece on the gameBoard
void putPieceOnBoard()
{
for (int r = 0; r < 4; ++r)
for (int c = 0; c < 4; ++c)
if (shapeArray[shape][rotation][r][c] != 0)
gameBoard[yPos+r][xPos+c] = shape+1;
} // end putPieceOnBoard

void removePieceFromBoard()
{
for (int r = 0; r < 4; ++r)
for (int c = 0; c < 4; ++c)
if (shapeArray[shape][rotation][r][c] != 0)
gameBoard[yPos+r][xPos+c] = 0;
} // end removePieceFromBoard

// check if there is a collision
bool checkCollision()
{
for (int r = 0; r < 4; ++r)
for (int c = 0; c < 4; ++c)
{
if ( (gameBoard[r+yPos][c+xPos] != 0) && (shapeArray[shape][rotation][r][c] != 0) )
// There's overlap
return true;
} // end for

return false;
} // end checkCollision

/*
// this returns the next random shape
void nextShape()
{
shape = rand() % 7;
//return shape;
} // end nextShape
*/


// gets the next piece, sets rotation and x and y cordinates
void nextShape()
{
shape = rand() % 7;
rotation = 0;
xPos = MIDDLE_X; //or wherever the middle of your board is
yPos = 0;
if (checkCollision())
{
gameOver = true;
cout << "The game is over!\n";
} // end if
} // end nextPiece


// this returns the next rotation
// it sets the rotation to either a 0, 1, 2, or 3
void rotate()
{
rotation = (rotation + 1) & 3;
if (checkCollision())
rotation = (rotation - 1) & 3;
} // end rotate

// try to move left, move back if you can't
void tryToMoveLeft()
{
--xPos;
if (checkCollision())
++xPos;
} // end tryToMoveLeft

// try to move right, move back if you can't
void tryToMoveRight()
{
++xPos;
if (checkCollision())
--xPos;
} // end tryToMoveRight

// try to move down, move back if you can't
void tryToMoveDown()
{
++yPos;
if (checkCollision())
{
--yPos;
collideDown = TRUE;
} // end if
} // end tryToMoveDown

// rotate if you can, if you can't go back to old rotation
void tryToRotate()
{
int oldRotation = rotation;
rotation = (rotation + 1) & 3;
if (checkCollision())
{
rotation = oldRotation;
cout << "inside this if statement\n";
} // end if
cout << "the rotation inside the function is " << rotation << endl;
} // tryToRotate

// return true if the row is full and needs to be deleted, false otherwise
bool isRowFull(int row)
{
int rowFull = 0;
for (int col = 0; col < WIDTH; col++)
{
if (gameBoard[row][col] != 0)
{
rowFull++;
cout << "Row full is " << rowFull << endl;
cout << "row is : " << row << endl;
} // end if
} // end for
if (rowFull == 17)
{
cout << "row is full\n";
return true;
} // end if
else
{
cout << "row is not full\n";
return false;
} // end else
} // end isRowFull

// test the row full function fill up a row with 1's and see if it returns true;
void fillRow(int row)
{
for (int col = 1; col < WIDTH-1; col++)
{
gameBoard[row][col] = 1;
} // end for
} // end fillRow

// unfill 1 row
void unFillOneRow(int row)
{
for (int col = 1; col < WIDTH-1; col++)
gameBoard[row][col] = 0;
} // end unFillOneRow

void moveRowsDown(int n)
{
int row;
for (row = n; row > 1; row--)
{
for (int col = 1; col < WIDTH-1; col++)
{
//cout << "the row is : " << row << endl;
//cout << "the col is : " << col << endl;
gameBoard[row][col] = gameBoard[row-1][col];
} // end for
} // end for
cout << "the row is " << row << endl;
// this sets the first row to 0's
unFillOneRow(1);
} // end moveRowsDown


/*
void arrangeRows(int y)
{
for (int i = 0; i < 4; i++)
{
cout << "Y = " << y << endl;
if (isRowFull(y))
{
cout << "Y = " << y << endl;
moveRowsDown(y);
lines++;
cout << "line count is " << lines << endl;
increaseLevel();
cout << "level is " << level << endl;
} // end if
else
y = y - 1;
} // end for
} // end arrangeRows
*/


void arrangeRows()
{
for (int row = 1; row < WIDTH-1; row++)
{
if (isRowFull(row))
{
moveRowsDown(row);
lines = lines + 1;
cout << "line count is " << lines << endl;
increaseLevel();
cout << "level is " << level << endl;
score = score + 100;
cout << "score is " << score << endl;
} // end if
} // end for
} // end arrangeRows

// increment level if it needs to be
void increaseLevel()
{
if (lines == 10)
level = level + 1;
} // end increaseLevel

/************************************************
* end array that holds all the shapes
************************************************/


// the main method
int main( int argc, char* args[] )
{
bool quit = false;
initializeSDL();
loadAllImages();
resetGameBoard();
displayGameBoard();


// main game loop
while(quit == false)
{
putPieceOnBoard();

//If there's an event to handle
if( SDL_PollEvent( &event ) )
{
//If a key was pressed
if( event.type == SDL_KEYDOWN )
{
//Set the proper message surface
switch( event.key.keysym.sym )
{
case SDLK_UP:
removePieceFromBoard();
tryToRotate();
putPieceOnBoard();
displayGameBoard();
//Update the screen
if( SDL_Flip( screen ) == -1 )
{
return 1;
} // end if
break;

case SDLK_DOWN:
removePieceFromBoard();
tryToMoveDown();
if (collideDown == TRUE)
{
// do all the level and line checks in here
arrangeRows();
nextShape();
rotation = 0;
xPos = MIDDLE_X;
yPos = 0;
collideDown = FALSE;
continue;
} // end if
putPieceOnBoard();
displayGameBoard();
if( SDL_Flip( screen ) == -1 )
{
return 1;
} // end if
break;
case SDLK_LEFT:
removePieceFromBoard();
tryToMoveLeft();
putPieceOnBoard();
displayGameBoard();
if( SDL_Flip( screen ) == -1 )
{
return 1;
} // end if
break;
case SDLK_RIGHT:
removePieceFromBoard();
tryToMoveRight();
putPieceOnBoard();
displayGameBoard();
//Update the screen
if( SDL_Flip( screen ) == -1 )
{
return 1;
} // end if
break;
} // end switch
} // end if

//If the user has Xed out the window
else if( event.type == SDL_QUIT )
{
//Quit the program
quit = true;
} // end else if
} // end if
} // end while
/*
displayGameBoard();
nextShape();
putPieceOnBoard();
SDL_Delay(200);
displayGameBoard();
//Update the screen
if( SDL_Flip( screen ) == -1 )
{
return 1;
} // end if
removePieceFromBoard();
SDL_Delay(200);
while (collideDown == FALSE)
{
removePieceFromBoard();
displayGameBoard();
tryToMoveDown();
putPieceOnBoard();
displayGameBoard();
} //end while
*/



//Update the screen
if( SDL_Flip( screen ) == -1 )
{
return 1;
} // end if

//Wait 2 seconds
// SDL_Delay(20000);

cleanUp();
return 0;
}

Share this post


Link to post
Share on other sites
It doesn't really sound like you have a game loop at all. The common SDL game loop is along these lines:


while(game_is_running == 1)
{
SDL_Event event;
while(SDL_PollEvent(&event))
{
switch(event.type)
{
case SDL_QUIT:
game_is_running = 0;
break;
case SDL_KEYDOWN:
switch(event.key.keysym.sym)
{
case SDLK_ESCAPE:
game_is_running = 0;
break;
case SDLK_UP:
//handle up
break;
//handle other keys also
}
break;
}
}

//update logic


//draw scene

SDL_Flip(screen);
}




Your other option I suppose is to do something like this:


Uint8 * key_state = SDL_GetKeyState();

while(game_is_running == 1)
{
SDL_PumpEvents();

if(key_state[SDLK_UP])
{
//handle up key
}

//update logic

//draw scene

SDL_Flip(screen);
}




This code:


if( SDL_Flip( screen ) == -1 )
{
return 1;
}




does one of two things, on a double buffered window it will swap the front and back buffers, and on a single buffered window it will update the screen. Double buffering means that everything is drawn to a hidden buffer, then all drawn to the screen at one time, to prevent tearing and such.

EDIT: Answered too soon, sorry I am at work I do not have time to go through all of that code. You may want to learn SDL before you attempt a game though.

Share this post


Link to post
Share on other sites
O ok thanks, i've never written a "game loop" before so i'll switch it to that. Would that take care of the collision problems and the artifact problems though? I have heard of double buffering but don't know how i would do it or if i have to do it. Well i know some SDL. How to set up a window, how to draw things. I thought if i used an int array for the game board and pieces on the game board that i would not need to use the graphics for any of the logic really. All the graphics would be is a way to display it to the screen. All the logic would be using the 2d int array and it kinda works.

Share this post


Link to post
Share on other sites
I think the problem is that the gameBoard for some reason does not update correctly because the only collisions that get detected are when it hits bottom. But just using text it gets updated and really the only thing im using sdl for is to display the blocks so what in sdl could stop it from updating the gameBoard correctly? I changed 1 function from the text version to the graphics version and that is the display method and that does not modify the game board array at all. So why does it not work now?

Share this post


Link to post
Share on other sites
I was just reading about capping frame rate in sdl. Is it because right now i update the screen every time a piece is moved when i should be updating the screen every frame? If i need to update the screen every frame how do i even know when a frame has passed?

Share this post


Link to post
Share on other sites
Quote:
If i need to update the screen every frame how do i even know when a frame has passed?
As Portmanteau related, the game loop does it's thing in, well, a loop. That means that it goes though everything in the loop in order from top to bottom. Your "frame" ends when you reach the end of the code segment since this is the point right before it goes back to the top to start all over again.

As for frame rates, some people consider capping the frame rate poor practice. I just consider it unnecessary. In a game like tetris, everything is time based so just measure the time between frames (SDL_GetTicks() should do the trick) and update the game based on how much time has passed. For instance, a piece falls 1 level every second - after 1 second has passed change the level of the block.

Just an idea but consider the following:

// globals or whatever to get the point across
int iLevelDropTime = 1000; // 1 second = 1000 milliseconds
int iDropCounter = 0;
int iNowTime, iLastTime = SDL_GetTicks();

while( game_is_running )
{
// store the start time of the frame
iNowTime = SDL_GetTicks();

// get your input
HandleInput();

// Update the drop timer
iDropCounter += iNowTime - iLastTime;

// see if we need to drop the piece
// using while in case for some reason the frame took an extra long
// amount of time
while ( iDropCounter >= iLevelDropTime )
{
DropPieceLevel();
iDropCounter -= iLevelDropTime;
}

// update the screen
DrawStuff();
SDL_Flip( SDL_GetVideoSurface() );

// update the iLastTime variable with when this frame started
// when the loop starts again iNowTime - iLastTime will be the
// time it took to complete this frame
iLastTime = iNowTime;
}
That should work for you without having to cap the frame rate. Optionally, I have found that for games like tetris, throwing in an SDL_Delay(1) at the end of the game loop keeps the game from eating up 99% of the CPU time and is nicer to the OS when running in windowed mode.


Share this post


Link to post
Share on other sites
i think that will work but my program flow is a bit different. I update the board more i think. You have it as get input, update drop timer update screen. My loop is more check for all input and when an input is gotten, so moving a piece, the screen is updated. Here is my "game loop" when would i update to have the timer and whatnot cause i really don't know what im doing with this kind of stuff at all.


//While the user hasn't quit
while( quit == false )
{
displayGameBoard();
putPieceOnBoard();
iNowTime = SDL_GetTicks();
//While there's events to handle
while( SDL_PollEvent( &event ) )
{
//If the user has Xed out the window
if( event.type == SDL_QUIT )
{
//Quit the program
quit = true;
} // end if
} // end while

//Get the keystates
Uint8 *keystates = SDL_GetKeyState( NULL );

//If up is pressed
if( keystates[ SDLK_UP ] )
{
removePieceFromBoard();
tryToRotate();
putPieceOnBoard();
displayGameBoard();
} // end if

//If down is pressed
if( keystates[ SDLK_DOWN ] )
{
removePieceFromBoard();
tryToMoveDown();
if (collideDown == TRUE)
{
// do all the level and line checks in here
putPieceOnBoard();
arrangeRows();
nextShape();
collideDown = FALSE;
continue;
} // end if
putPieceOnBoard();
displayGameBoard();
displayGameBoardCons();
} // end if

//If left is pressed
if( keystates[ SDLK_LEFT ] )
{
removePieceFromBoard();
tryToMoveLeft();
putPieceOnBoard();
displayGameBoard();
displayGameBoardCons();
} // end if

//If right is pressed
if( keystates[ SDLK_RIGHT ] )
{
removePieceFromBoard();
tryToMoveRight();
putPieceOnBoard();
displayGameBoard();
displayGameBoardCons();
} // end if
// Update the drop timer
iDropCounter += iNowTime - iLastTime;

// see if we need to drop the piece
// using while in case for some reason the frame took an extra long
// amount of time
while ( iDropCounter >= iLevelDropTime )
{
tryToMoveDown();
iDropCounter -= iLevelDropTime;
}
iLastTime = iNowTime;
} // end while

Share this post


Link to post
Share on other sites
ok i got it to go down by itself. But now my question is which variable would i increment when the level increases to make it fall faster?

Share this post


Link to post
Share on other sites
You would decrease the iLevelDropTime variable making the time before the piece drops shorter.

You should make sure you understand what is going on in the game loop before going much further as it won't get any simpler than it already is. Try walking through each line of code in the game loop and figuring out why that line is there as opposed to somewhere else and what does it actually accomplish.

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!