tetris in sdl

Started by
8 comments, last by evillive2 15 years, 9 months ago
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?
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 screenconst int SCREEN_WIDTH = 800;const int SCREEN_HEIGHT = 600;const int SCREEN_BPP = 32;//The surfaces that will be usedSDL_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 imageSDL_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 imagesvoid 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 thatvoid 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 quitsvoid 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 gameBoardvoid 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 putPieceOnBoardvoid 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 collisionbool 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 shapevoid nextShape(){    shape = rand() % 7;    //return shape;} // end nextShape*/// gets the next piece, sets rotation and x and y cordinatesvoid 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 3void rotate(){    rotation = (rotation + 1) & 3;    if (checkCollision())        rotation = (rotation - 1) & 3;} // end rotate// try to move left, move back if you can'tvoid tryToMoveLeft(){    --xPos;    if (checkCollision())        ++xPos;} // end tryToMoveLeft// try to move right, move back if you can'tvoid tryToMoveRight(){    ++xPos;    if (checkCollision())        --xPos;} // end tryToMoveRight// try to move down, move back if you can'tvoid tryToMoveDown(){    ++yPos;    if (checkCollision())    {        --yPos;        collideDown = TRUE;    } // end if} // end tryToMoveDown// rotate if you can, if you can't go back to old rotationvoid 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 otherwisebool 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 rowvoid 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 bevoid increaseLevel(){   if (lines == 10)      level = level + 1;} // end increaseLevel/************************************************ *        end array that holds all the shapes ************************************************/// the main methodint 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;    }
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.
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.
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?
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?
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 acrossint iLevelDropTime = 1000; // 1 second = 1000 millisecondsint 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.


Evillive2
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
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?
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.
Evillive2

This topic is closed to new replies.

Advertisement