The SDL forums have moved to discourse.libsdl.org.
This is just a read-only archive of the previous forums, to keep old links working.


SDL Forum Index
SDL
Simple Directmedia Layer Forums
I'm having a problem manipulating a variable
LAURENT*


Joined: 06 Jan 2013
Posts: 32
Modifying code from the SDL legacy tutorial I have tried to render tiles are new way. This is a link to the tutorial. http://lazyfoo.net/SDL_tutorials/lesson29/index.php

No matter what I've tried and how logical it seems I cannot control where I render my tile to. In order to render I must change the value of my variables. I got the idea to read from a map file and check for conditions to render my level. At the bottom of my post you can view all of my code but I suspect my problem remains exclusively with the set tiles fucntion




My problem in my code

Code:

bool set_tiles( Tile *tiles[], Tile *walls[] )
{
    //The tile offsets
    int x = 0, y = 0;
   int a = 0, b = 0;
   int p = 0, q = 0;
   

    //Open the map
    std::ifstream map( "lazy.map" );
   std::ifstream map2( "Zrender.map" );
   std::ifstream coords ("Coords.map");
    //If the map couldn't be loaded
    if( map == NULL )
    {
        return false;
    }
   if( map2 == NULL )
    {
        return false;
    }
    //Initialize the tiles
    for( int t = 0; t < TOTAL_TILES; t++ )
    {
      //Determines what kind of tile will be made
        int tileType = -1;

        //Read tile from map file
        map >> tileType;

        //If the was a problem in reading the map
        if( map.fail() == true )
        {
            //Stop loading map
            map.close();
            return false;
        }

         //If the number is a valid tile number
         if( ( tileType >= 0 ) && ( tileType <  TILE_SPRITES ) )
         {
            tiles[ t ] = new Tile(NULL, NULL, NULL , NULL, x, y, tileType );
            //Move to next tile spot
            x += TILE_WIDTH;

         }
       
         //If we don't recognize the tile type
         else
         {
            //Stop loading map
            map.close();
            return false;
         }

         

         //If we've gone too far
         if( x >= LEVEL_WIDTH )
         {
            //Move back
            x = 0;

            //Move to the next row
            y += TILE_HEIGHT;
         }
      }
//Ending of for loop.

    for( int tz = 0; tz < TOTAL_TILES_WALL; tz++ )
    {
      
      //Determines what kind of tile will be made
        int tileTypeWall = -1;
      int Position = -1;

        //Read tile from map file
        map2 >> tileTypeWall;
      coords >> Position;
        //If the was a problem in reading the map
        if( map2.fail() == true )
        {
            //Stop loading map
            map2.close();
            return false;
        }

         if (Position == 0)
         {
            p += TILE_WIDTH;
         }
         //If the number is a valid tile number
         if ( tileTypeWall == TILE_RED_WALLf  )
         {
            walls[ tz ] = new Tile( NULL, NULL, p , q, NULL, NULL, tileTypeWall );
         }
       
      

      
      }

    //Close the file
    map.close();

    //If the map was loaded fine
    return true;
}




ALL OF MY CODE
Quote:
//The headers
#include "SDL.h"
#include "SDL_image.h"
#include <string>
#include <fstream>


//The gravity of the game
const float ACCELARATION = 300;
const int YS_VEL_WALK = 100;

//Screen attributes
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
const int SCREEN_BPP = 32;


/*Frames rate
This concept was removed due to needs of performance, and independed movement.
Investigate uses in prototype before deleteion of concept.
*/
//const int FRAMES_PER_SECOND = 20;

//The Ys dimensions
const int YS_WIDTH = 25;
const int YS_HEIGHT = 19;
const int LANDPAD_WIDTH = 19;
const int LANDPAD_HEIGHT = 7;

//The dimensions of the level
const int LEVEL_WIDTH = 1280;
const int LEVEL_HEIGHT = 960;

//Tile constants
const int TILE_WIDTH = 80;
const int TILE_HEIGHT = 80;
const int TILE_WALLf_HEIGHT = 20;
const int TILE_WALLf_WIDTH = 20;
const int TILE_WALLs_HEIGHT = 20;
const int TILE_WALLs_WIDTH = 3;
const int TOTAL_TILES = 192;
const int TOTAL_TILES_WALL = 1;
const int TILE_SPRITESWALL = 11;
const int TILE_SPRITES = 23;


//The different tile sprites
const int TILE_RED = 0;
const int TILE_GREEN = 1;
const int TILE_BLUE = 2;
const int TILE_CENTER = 3;
const int TILE_TOP = 4;
const int TILE_TOPRIGHT = 5;
const int TILE_RIGHT = 6;
const int TILE_BOTTOMRIGHT = 7;
const int TILE_BOTTOM = 8;
const int TILE_BOTTOMLEFT = 9;
const int TILE_LEFT = 10;
const int TILE_TOPLEFT = 11;
const int TILE_RED_WALLf = 12;
const int TILE_GREEN_WALLf= 13;
const int TILE_BLUE_WALLf= 14;
const int TILE_RED_WALLs= 15;
const int TILE_GREEN_WALLs= 16;
const int TILE_BLUE_WALLs= 17;
const int Move_Over_Right = 18;
const int TilePlacement2 = 19;
const int TilePlacement3 = 20;
const int TilePlacement4 = 21;
const int TilePlacement5 = 22;

//The surfaces
SDL_Surface *dot = NULL;
SDL_Surface *screen = NULL;
SDL_Surface *tileSheet = NULL;
SDL_Surface *walltilesheet = NULL;
SDL_Surface *LandPad = NULL;
SDL_Surface *Ysguy1 = NULL;
//Sprite from the tile sheet
SDL_Rect clips[ TILE_SPRITES ];

//The event structure
SDL_Event event;

//The camera
SDL_Rect camera = { 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT };
//////
//The tile
class Tile
{
private:
//The attributes of the tile
SDL_Rect floorpad;
SDL_Rect wallside;
SDL_Rect wallfront;

//The tile type
int type;

public:
//Initializes the variables
Tile(int a, int b, int p, int q, int x, int y, int tileType );

//Shows the tile
void show();


//Get the tile type
int get_type();

//Get the collision box
SDL_Rect get_box();
};


//The dot
class Dot
{
private:
//Land pad's collision box
SDL_Rect box;

//The velocity of the dot
float xVel, yVel, zVel;
float x, y, z;

bool grounded;
public:
//Initializes the variables
Dot();

//Takes key presses and adjusts the dot's velocity
void handle_input();

//Moves the dot
void move( Tile *tiles[], Uint32 deltaTicks);

//Shows on the screen
void show();

//Sets the camera over the dot
void set_camera();
};

//The timer
class Timer
{
private:
//The clock time when the timer started
int startTicks;

//The ticks stored when the timer was paused
int pausedTicks;

//The timer status
bool paused;
bool started;

public:
//Initializes variables
Timer();

//The various clock actions
void start();
void stop();
void pause();
void unpause();

//Gets the timer's time
int get_ticks();

//Checks the status of the timer
bool is_started();
bool is_paused();
};

SDL_Surface *load_image( std::string filename )
{
//The image that's loaded
SDL_Surface* loadedImage = NULL;

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

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

//If the image loaded
if( loadedImage != NULL )
{
//Create an optimized surface
optimizedImage = SDL_DisplayFormat( loadedImage );

//Free the old surface
SDL_FreeSurface( loadedImage );

//If the surface was optimized
if( optimizedImage != NULL )
{
//Color key surface
SDL_SetColorKey( optimizedImage, SDL_SRCCOLORKEY, SDL_MapRGB( optimizedImage->format, 0, 0xFF, 0xFF ) );
}
}

//Return the optimized surface
return optimizedImage;
}

void apply_surface( int x, int y, SDL_Surface* source, SDL_Surface* destination, SDL_Rect* clip = NULL )
{
//Holds offsets
SDL_Rect offset;

//Get offsets
offset.x = x;
offset.y = y;

//Blit
SDL_BlitSurface( source, clip, destination, &offset );
}

void showCharacterMovement(int x, int z, SDL_Surface* source, SDL_Surface* destination, SDL_Rect* clip = NULL)
{
//Holds offsets
SDL_Rect offset;

//Get offsets
offset.x = x;
offset.y = z;

//Blit
SDL_BlitSurface( source, clip, screen, &offset);
}

bool check_collision( SDL_Rect A, SDL_Rect B )
{
//The sides of the rectangles
int leftA, leftB;
int rightA, rightB;
int topA, topB;
int bottomA, bottomB;

//Calculate the sides of rect A
leftA = A.x;
rightA = A.x + A.w;
topA = A.y;
bottomA = A.y + A.h;

//Calculate the sides of rect B
leftB = B.x;
rightB = B.x + B.w;
topB = B.y;
bottomB = B.y + B.h;

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

if( topA >= bottomB )
{
return false;
}

if( rightA <= leftB )
{
return false;
}

if( leftA >= rightB )
{
return false;
}

//If none of the sides from A are outside B
return true;
}

bool init()
{
//Initialize all SDL subsystems
if( SDL_Init( SDL_INIT_EVERYTHING ) == -1 )
{
return false;
}

//Set up the screen
screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE );

//If there was an error in setting up the screen
if( screen == NULL )
{
return false;
}

//Set the window caption
SDL_WM_SetCaption( "Sega forum testing shit and ect", NULL );

//If everything initialized fine
return true;
}

bool load_files()
{
//Load the dot image
dot = load_image( "dot.png" );

//If there was a problem in loading the dot
if( dot == NULL )
{
return false;
}

//Load the tile sheet
tileSheet = load_image( "tiles.png" );

//If there was a problem in loading the tiles
if( tileSheet == NULL )
{
return false;
}

//Load the tile sheet
LandPad = load_image( "LandPad.png" );

//If there was a problem in loading the tiles
if( LandPad == NULL )
{
return false;
}

//Load the tile sheet
Ysguy1 = load_image( "Ysguy1.png" );

//If there was a problem in loading the tiles
if( Ysguy1 == NULL )
{
return false;
}

//If everything loaded fine
return true;
}

void clean_up( Tile *tiles[], Tile *walls[] )
{
//Free the surfaces
SDL_FreeSurface( dot );
SDL_FreeSurface( tileSheet );
SDL_FreeSurface( LandPad );
SDL_FreeSurface( Ysguy1 );
//Free the tiles
for( int t = 0; t < TOTAL_TILES; t++ )
{
delete tiles[ t ];
}
for( int tz = 0; tz < TOTAL_TILES_WALL; tz++ )
{
delete walls[ tz ];
}
//Quit SDL
SDL_Quit();
}

void clip_tiles()
{
//Clip the sprite sheet
clips[ TILE_RED ].x = 0;
clips[ TILE_RED ].y = 0;
clips[ TILE_RED ].w = TILE_WIDTH;
clips[ TILE_RED ].h = TILE_HEIGHT;

clips[ TILE_GREEN ].x = 0;
clips[ TILE_GREEN ].y = 80;
clips[ TILE_GREEN ].w = TILE_WIDTH;
clips[ TILE_GREEN ].h = TILE_HEIGHT;

clips[ TILE_BLUE ].x = 0;
clips[ TILE_BLUE ].y = 160;
clips[ TILE_BLUE ].w = TILE_WIDTH;
clips[ TILE_BLUE ].h = TILE_HEIGHT;

clips[ TILE_TOPLEFT ].x = 80;
clips[ TILE_TOPLEFT ].y = 0;
clips[ TILE_TOPLEFT ].w = TILE_WIDTH;
clips[ TILE_TOPLEFT ].h = TILE_HEIGHT;

clips[ TILE_LEFT ].x = 80;
clips[ TILE_LEFT ].y = 80;
clips[ TILE_LEFT ].w = TILE_WIDTH;
clips[ TILE_LEFT ].h = TILE_HEIGHT;

clips[ TILE_BOTTOMLEFT ].x = 80;
clips[ TILE_BOTTOMLEFT ].y = 160;
clips[ TILE_BOTTOMLEFT ].w = TILE_WIDTH;
clips[ TILE_BOTTOMLEFT ].h = TILE_HEIGHT;

clips[ TILE_TOP ].x = 160;
clips[ TILE_TOP ].y = 0;
clips[ TILE_TOP ].w = TILE_WIDTH;
clips[ TILE_TOP ].h = TILE_HEIGHT;

clips[ TILE_CENTER ].x = 160;
clips[ TILE_CENTER ].y = 80;
clips[ TILE_CENTER ].w = TILE_WIDTH;
clips[ TILE_CENTER ].h = TILE_HEIGHT;

clips[ TILE_BOTTOM ].x = 160;
clips[ TILE_BOTTOM ].y = 160;
clips[ TILE_BOTTOM ].w = TILE_WIDTH;
clips[ TILE_BOTTOM ].h = TILE_HEIGHT;

clips[ TILE_TOPRIGHT ].x = 240;
clips[ TILE_TOPRIGHT ].y = 0;
clips[ TILE_TOPRIGHT ].w = TILE_WIDTH;
clips[ TILE_TOPRIGHT ].h = TILE_HEIGHT;

clips[ TILE_RIGHT ].x = 240;
clips[ TILE_RIGHT ].y = 80;
clips[ TILE_RIGHT ].w = TILE_WIDTH;
clips[ TILE_RIGHT ].h = TILE_HEIGHT;

clips[ TILE_BOTTOMRIGHT ].x = 240;
clips[ TILE_BOTTOMRIGHT ].y = 160;
clips[ TILE_BOTTOMRIGHT ].w = TILE_WIDTH;
clips[ TILE_BOTTOMRIGHT ].h = TILE_HEIGHT;

clips[ TILE_RED_WALLf ].x = 0;
clips[ TILE_RED_WALLf ].y = 240;
clips[ TILE_RED_WALLf ].w = TILE_WALLf_WIDTH;
clips[ TILE_RED_WALLf ].h = TILE_WALLf_HEIGHT;

clips[ TILE_GREEN_WALLf ].x = 21;
clips[ TILE_GREEN_WALLf ].y = 240;
clips[ TILE_GREEN_WALLf ].w = TILE_WALLf_WIDTH;
clips[ TILE_GREEN_WALLf ].h = TILE_WALLf_HEIGHT;

clips[ TILE_BLUE_WALLf ].x = 41;
clips[ TILE_BLUE_WALLf ].y = 240;
clips[ TILE_BLUE_WALLf ].w = TILE_WALLf_WIDTH;
clips[ TILE_BLUE_WALLf ].h = TILE_WALLf_HEIGHT;
//
clips[ TILE_RED_WALLs ].x = 61;
clips[ TILE_RED_WALLs ].y = 240;
clips[ TILE_RED_WALLs ].w = TILE_WALLs_WIDTH;
clips[ TILE_RED_WALLs ].h = TILE_WALLs_HEIGHT;

clips[ TILE_BLUE_WALLs ].x = 64;
clips[ TILE_BLUE_WALLs ].y = 240;
clips[ TILE_BLUE_WALLs ].w = TILE_WALLs_WIDTH;
clips[ TILE_BLUE_WALLs ].h = TILE_WALLs_HEIGHT;

clips[ TILE_GREEN_WALLs ].x = 67;
clips[ TILE_GREEN_WALLs ].y = 240;
clips[ TILE_GREEN_WALLs ].w = TILE_WALLs_WIDTH;
clips[ TILE_GREEN_WALLs ].h = TILE_WALLs_HEIGHT;
}

bool set_tiles( Tile *tiles[], Tile *walls[] )
{
//The tile offsets
int x = 0, y = 0;
int a = 0, b = 0;
int p = 0, q = 0;


//Open the map
std::ifstream map( "lazy.map" );
std::ifstream map2( "Zrender.map" );
std::ifstream coords ("Coords.map");
//If the map couldn't be loaded
if( map == NULL )
{
return false;
}
if( map2 == NULL )
{
return false;
}
//Initialize the tiles
for( int t = 0; t < TOTAL_TILES; t++ )
{
//Determines what kind of tile will be made
int tileType = -1;

//Read tile from map file
map >> tileType;

//If the was a problem in reading the map
if( map.fail() == true )
{
//Stop loading map
map.close();
return false;
}

//If the number is a valid tile number
if( ( tileType >= 0 ) && ( tileType < TILE_SPRITES ) )
{
tiles[ t ] = new Tile(NULL, NULL, NULL , NULL, x, y, tileType );
//Move to next tile spot
x += TILE_WIDTH;

}

//If we don't recognize the tile type
else
{
//Stop loading map
map.close();
return false;
}



//If we've gone too far
if( x >= LEVEL_WIDTH )
{
//Move back
x = 0;

//Move to the next row
y += TILE_HEIGHT;
}
}
//Ending of for loop.

for( int tz = 0; tz < TOTAL_TILES_WALL; tz++ )
{

//Determines what kind of tile will be made
int tileTypeWall = -1;
int Position = -1;

//Read tile from map file
map2 >> tileTypeWall;
coords >> Position;
//If the was a problem in reading the map
if( map2.fail() == true )
{
//Stop loading map
map2.close();
return false;
}

if (Position == 0)
{
p += TILE_WIDTH;
}
//If the number is a valid tile number
if ( tileTypeWall == TILE_RED_WALLf )
{
walls[ tz ] = new Tile( NULL, NULL, p , q, NULL, NULL, tileTypeWall );
}




}

//Close the file
map.close();

//If the map was loaded fine
return true;
}

bool touches_wall( SDL_Rect box, Tile *tiles[] )
{
//Go through the tiles
for( int t = 0; t < TOTAL_TILES; t++ )
{
//If the tile is a wall type tile
if( ( tiles[ t ]->get_type() >= TILE_CENTER ) && ( tiles[ t ]->get_type() <= TILE_TOPLEFT ) )
{
//If the collision box touches the wall tile
if( check_collision( box, tiles[ t ]->get_box() ) == true )
{
return true;
}
}
}

//If no wall tiles were touched
return false;
}

Tile::Tile( int a, int b, int p, int q, int x, int y, int tileType )
{
//Get the offsets
floorpad.x = x;
floorpad.y = y;

//Set the collision box
floorpad.w = TILE_WIDTH;
floorpad.h = TILE_HEIGHT;

wallside.x = a;
wallside.y = b;
wallside.w = TILE_WALLs_WIDTH;
wallside.h = TILE_WALLs_HEIGHT;



wallfront.x = p;
wallfront.y = q;
wallfront.w = TILE_WALLf_WIDTH;
wallfront.h = TILE_WALLf_HEIGHT;


//Get the tile type
type = tileType;
}

void Tile::show()
{
//If the tile is on screen
if( check_collision( camera, floorpad ) == true )
{
//Show the tile
apply_surface( floorpad.x - camera.x, floorpad.y - camera.y, tileSheet, screen, &clips[ type ] );
}

if( check_collision( camera, wallfront ) == true )
{
apply_surface( wallfront.x - camera.x, wallfront.y - camera.y, walltilesheet, screen, &clips[ type ] );
}
}



int Tile::get_type()
{
return type;
}

SDL_Rect Tile::get_box()
{
return floorpad;
}

Dot::Dot()
{
//Initialize the offsets
box.x = 0;
box.y = 0;
box.w = LANDPAD_WIDTH;
box.h = LANDPAD_HEIGHT;

x = 0;
y = 0;
z = y + YS_HEIGHT;
//Initialize the velocity
xVel = 0;
yVel = 0;
zVel = 0;
}

void Dot::handle_input()
{
//If a key was pressed
if( event.type == SDL_KEYDOWN )
{
//Adjust the velocity
switch( event.key.keysym.sym )
{
case SDLK_UP: yVel -= YS_VEL_WALK; zVel -= YS_VEL_WALK; break;
case SDLK_DOWN: yVel += YS_VEL_WALK; zVel += YS_VEL_WALK; break;
case SDLK_LEFT: xVel -= YS_VEL_WALK; break;
case SDLK_RIGHT: xVel += YS_VEL_WALK; break;
case SDLK_SPACE: if(grounded == true){z -= 4; zVel -= YS_VEL_WALK + 20;} break;
}
}
//If a key was released
else if( event.type == SDL_KEYUP )
{
//Adjust the velocity
switch( event.key.keysym.sym )
{
case SDLK_UP: yVel += YS_VEL_WALK; zVel += YS_VEL_WALK; break;
case SDLK_DOWN: yVel -= YS_VEL_WALK; zVel -= YS_VEL_WALK; break;
case SDLK_LEFT: xVel += YS_VEL_WALK; break;
case SDLK_RIGHT: xVel -= YS_VEL_WALK; break;
}
}
}

void Dot::move( Tile *tiles[], Uint32 deltaTicks )
{

//Move the dot left or right
x += xVel * ( deltaTicks / 1000.f );
box.x = x;
//If the dot went too far to the left or right or touched a wall
if( ( x < 0 ) || ( x + YS_WIDTH > LEVEL_WIDTH )|| touches_wall( box, tiles ) )
{
//move back
x -= xVel* ( deltaTicks / 1000.f );
}

//Move the dot up or down
y += yVel * ( deltaTicks / 1000.f );
box.y = y;
//If the dot went too far up or down or touched a wall
if( ( y < 0 ) || ( y + YS_HEIGHT > LEVEL_HEIGHT ) || touches_wall( box, tiles ) )
{
//move back
y -= yVel* ( deltaTicks / 1000.f );
}


if (z + YS_HEIGHT > y)
{
grounded = true;
}
else if (z + YS_HEIGHT < y)
{
grounded = false;
}


if (grounded == true)
{
zVel = yVel;
z = y - YS_HEIGHT + 2;
}
else if (grounded == false)
{
zVel += ACCELARATION * ( deltaTicks / 1000.f );
z += zVel * ( deltaTicks / 1000.f );
}
}

void Dot::show()
{
//Show the dot
apply_surface( (int)x - camera.x, (int)y - camera.y, LandPad, screen );
showCharacterMovement( (int)x - camera.x,(int)z - camera.y, Ysguy1, screen );

}

void Dot::set_camera()
{
//Center the camera over the dot
camera.x = ( box.x + YS_WIDTH / 2 ) - SCREEN_WIDTH / 2;
camera.y = ( box.y + YS_HEIGHT / 2 ) - SCREEN_HEIGHT / 2;

//Keep the camera in bounds.
if( camera.x < 0 )
{
camera.x = 0;
}
if( camera.y < 0 )
{
camera.y = 0;
}
if( camera.x > LEVEL_WIDTH - camera.w )
{
camera.x = LEVEL_WIDTH - camera.w;
}
if( camera.y > LEVEL_HEIGHT - camera.h )
{
camera.y = LEVEL_HEIGHT - camera.h;
}
}

Timer::Timer()
{
//Initialize the variables
startTicks = 0;
pausedTicks = 0;
paused = false;
started = false;
}

void Timer::start()
{
//Start the timer
started = true;

//Unpause the timer
paused = false;

//Get the current clock time
startTicks = SDL_GetTicks();
}

void Timer::stop()
{
//Stop the timer
started = false;

//Unpause the timer
paused = false;
}

void Timer::pause()
{
//If the timer is running and isn't already paused
if( ( started == true ) && ( paused == false ) )
{
//Pause the timer
paused = true;

//Calculate the paused ticks
pausedTicks = SDL_GetTicks() - startTicks;
}
}

void Timer::unpause()
{
//If the timer is paused
if( paused == true )
{
//Unpause the timer
paused = false;

//Reset the starting ticks
startTicks = SDL_GetTicks() - pausedTicks;

//Reset the paused ticks
pausedTicks = 0;
}
}

int Timer::get_ticks()
{
//If the timer is running
if( started == true )
{
//If the timer is paused
if( paused == true )
{
//Return the number of ticks when the timer was paused
return pausedTicks;
}
else
{
//Return the current time minus the start time
return SDL_GetTicks() - startTicks;
}
}

//If the timer isn't running
return 0;
}

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

bool Timer::is_paused()
{
return paused;
}

int main( int argc, char* args[] )
{
//Quit flag
bool quit = false;

//The dot
Dot myDot;

//The tiles that will be used
Tile *tiles[ TOTAL_TILES ];
Tile *walls[ TOTAL_TILES_WALL ];


//The frame rate regulator
Timer delta;

//Initialize
if( init() == false )
{
return 1;
}

//Load the files
if( load_files() == false )
{
return 1;
}

//Clip the tile sheet
clip_tiles();

//Set the tiles
if( set_tiles( tiles, walls) == false )
{
return 1;
}

//While the user hasn't quit
while( quit == false )
{
//While there's events to handle
while( SDL_PollEvent( &event ) )
{
//Handle events for the dot
myDot.handle_input();

//If the user has Xed out the window
if( event.type == SDL_QUIT )
{
//Quit the program
quit = true;
}
}

//Move the dot
myDot.move( tiles, delta.get_ticks() );

//Restart delta timer
delta.start();

//Set the camera
myDot.set_camera();



//Show the tiles
for( int t = 0; t < TOTAL_TILES; t++ )
{
tiles[ t ]->show();
}

for( int tz = 0; tz < TOTAL_TILES_WALL; tz++ )
{
walls[ tz ]->show();
}
//Show the dot on the screen
myDot.show();

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

}

//Clean up
clean_up( tiles, walls );

return 0;
}
Naith


Joined: 03 Jul 2014
Posts: 158
Sorry but I don't understand what you mean by "it seems I cannot control where I render my tile to. In order to render I must change the value of my variables.".

Try to explain a bit more regarding what you want to do, what you try to accomplish and what doesn't work as it should and I will try to help you with it.
LAURENT*


Joined: 06 Jan 2013
Posts: 32
I'm having problems with the set_tiles function from the Lazy foo legacy tutorial on SDL 1.0 specifically the tiling tutorials. In the tutorial the creator makes the x axis move over to the right after each tile coordinate has been set. I wanna be able to place tiles in a less patternized way but no matter what I tried on the screen the special tile I made always show at coordinate (0,0).
Naith


Joined: 03 Jul 2014
Posts: 158
I would like to test out the program by myself and see what's happening and such so do you mind sharing your maps and graphic files?
LAURENT*


Joined: 06 Jan 2013
Posts: 32
https://www.dropbox.com/s/quzsawrqm78z2yd/resource.zip

This is everything. I slightly modified one of the map files since then but it was very small and only used to testing.
Naith


Joined: 03 Jul 2014
Posts: 158
Thanks.

If I understand your code correctly, you want to render multiple layers of tiles. Correct?

Also, I don't understand your map files (except the 'Lazy.map' which is just a normal map file). You have one map file named 'Coords.map' containing zero's (which I guess later will be changed to represent a tile in the tileset) and then you have a map file named 'Zrender.map' which contains some values.

I need to hear / see / read your thoughts behind your game, the thoughts behind your code, the way you're handling things in the code and so on. So please enlighten me with some more information regarding what your plan is. And please don't just write that you want to make a game with tiles because that's not gonna help much.
And yes, I know that you've already written that you're having problems with the set_tiles function but I need more information before we're starting to change stuff in your code because, to be honest, some things in your code will probably need to get changed in order to make the game behave the way you want. And yes, the set_tiles function will be fixed / changed along with the rest of the code that need's to get fixed / changed.

And btw, in my opinion, you should migrate to SDL 2.0. Check this page to read about the new features and also about what needs to be changed in the code to do the migration from SDL 1.2 to SDL 2.0: https://wiki.libsdl.org/MigrationGuide
LAURENT*


Joined: 06 Jan 2013
Posts: 32
I rather just make a new game then immigrate, it not easy and there is a hard learning curve, please cooperate.

My idea was to render the floor first then render the wall tiles with another array. In order for my character to detect the wall tiles the Land pad rectangle must first detect specific floor tiles. Right now I'm having trouble just rendering the wall tiles to any other spot other than the upper left hand corner of the level. My goal is to print the wall tiles on the right location at the moment. I'm not at collision detection yet.
LAURENT*


Joined: 06 Jan 2013
Posts: 32
Zrender was intended to render the tile type and it's coordinate but I decided to save the latter feature to a new map file specifically the map file name coords. Zrender are the wall tiles rendered on the z axis and coords move the tiles to right location.

Try this for testing purposes, In the Zrender map file erase everything and then type the number "12" since their only suppose to be 1 tile render. Within the second for loop of

bool set_tiles(Tile *tiles[], Tile *walls[])

Try to modify the value of p before before tiltTypewall reads from the map file



//Only one wall tile is suppose to be rendered for testing purposes. Check the code
const int TOTAL_TILES_WALL = 1;
Naith


Joined: 03 Jul 2014
Posts: 158
Okey, I have a better understanding now.

Regarding the migration; I will help you whatever version of SDL you're using. It was just my opinion that you should migrate. As long as you're doing it sometime, it's good.

I don't want to sound like a smartass now, and forgive me if I do, but since your game will be in 2D (as far as I understand), I don't see a reason to have any z variable(s) and specifying a specific tile to be rendered in a specific z value (since the z axis doesn't exist). Am I missing something here?
LAURENT*


Joined: 06 Jan 2013
Posts: 32
You're right the game is 2D but the view of the game is isometric and I declared a variable named float z to handle the movement of the characters. my idea to handle this special isometric collision detection was to check for the variables y and z at the same time. This is a summary of my logic

If (y < or > a certain value)
z can be interacted with.

Since the view is isometric similar to a legend of Zelda game just checking for one collision alone sound problematic. I wanted to be able to scale walls and other thing without distorting the view and keeping the graphic like this. http://www.brynmawr.edu/cities/Cities/imgb/071/071d.gif

Take a look at the Dot:: move (tile *tiles[], Uint32 deltaticks) function. This is where I use the z variable to implement the gravity on the characters. My plan is to pass both values z and y through parameter to do collision.
LAURENT*


Joined: 06 Jan 2013
Posts: 32
Its just an idea, it showed promise with gravity so I use it on tiles too.
LAURENT*


Joined: 06 Jan 2013
Posts: 32
BTW can you run it?
Naith


Joined: 03 Jul 2014
Posts: 158
Now the z variables and such makes more sense. I actually love games which has isometric view (like Zelda). It will be interesting to see the end result of your game!

Yes, I managed to execute the program and I found the reason to why the tile (wall tile) always end up at (0, 0).
The error is in the Tile::Show function.

Whenever a tile is rendered, the tile is positioned with the help of the floorpad rect / quad. When a wall tile is created, the x and y is not set (instead p and q is set). This means that the x and y is (0, 0) and since the floorpad.x is = x and floorpad.y is = y, the tile ends up at (0, 0) (since the wall tile is positioned with the help of the floorpad rect / quad aswell).

Code:

   //If the tile is on screen
   if( check_collision( camera, floorpad ) == true )
   {
      //Show the tile
      apply_surface( floorpad.x - camera.x, floorpad.y - camera.y, tileSheet, screen, &clips[ type ] );
   }



The code below (which is written directly under the above code) doesn't work since 'walltilesheet' is NULL (image surface is not being created at the start of the program).

Code:

   if( check_collision( camera, wallfront ) == true )
   {
      apply_surface( wallfront.x - camera.x, wallfront.y - camera.y, walltilesheet, screen, &clips[ type ] );
   }



Solution to the problem:

Write this in the Show function:

Code:

   if( type == TILE_RED_WALLf )
   {
      if( check_collision( camera, floorpad ) == true )
         apply_surface( wallfront.x - camera.x, wallfront.y - camera.y, tileSheet, screen, &clips[ type ] );
   }

   else
   {
      if( check_collision( camera, floorpad ) == true )
         apply_surface( floorpad.x - camera.x, floorpad.y - camera.y, tileSheet, screen, &clips[ type ] );
   }



Or if you want to specify a range of tile types, you can do it like this:

Code:

   // If the tile type is one of the floor tiles
   if( type >= TILE_RED && type <= TILE_TOPLEFT )
   {
      if( check_collision( camera, floorpad ) == true )
         apply_surface( floorpad.x - camera.x, floorpad.y - camera.y, tileSheet, screen, &clips[ type ] );
   }

   // If the tile type is one of the wall tiles
   else if( type >= TILE_RED_WALLf && type <= TILE_BLUE_WALLs )
   {
      if( check_collision( camera, floorpad ) == true )
         apply_surface( wallfront.x - camera.x, wallfront.y - camera.y, tileSheet, screen, &clips[ type ] );
   }



If the tile type ('type') is a red wall tile, us the wallfront rect / quad to position the tile. You should add some more tile types in the if statement if you want more tiles to rely on the wallfront rect / quad.
If the tile type ('type') is not a red wall tile, use the floorpad rect / quad to position the tile.

I hope you'll understand what causes the error and that you'll understand my solution to it.
LAURENT*


Joined: 06 Jan 2013
Posts: 32
Whoa. Slick bug fixing. This is just like they say in pixel art "Sometimes other people need to see your work".

I understand what you did. Now I see why when I was debugging the value of p did change but not the coordinates. Thank you for the aid.

BTW when you were debugging what did you do to notice this?
Naith


Joined: 03 Jul 2014
Posts: 158
No problem. Smile

I used some breakpoints to check the values of some of the variables at some points in the game loop. I first set out a breakpoint at where the show function of the tile map is first called.

Code:

      for( int t = 0; t < TOTAL_TILES; t++ )
      {
         tiles[ t ]->show();
      }

      for( int tz = 0; tz < TOTAL_TILES_WALL; tz++ )
      {
-- breakpoint here --  walls[ tz ]->show();
      }



And when I jumped into the show function I put a breakpoint there aswell, checked the value of the x, y, p and q variables and saw that x and y were in fact (0, 0) even though I tryed to change in the map files and such. At the same time I checked the variables in the function, I also realized that the floorpad rect / quad were used by both the floor tiles and the wall tiles when they were to be positioned.

So.. yeah. Breakpoints are always good. And like you said, sometimes someone else need to check the code, since that someone can spot errors and problems which the coder of the program has missed.

Some off-topic thoughts regarding Lazyfoo

To be perfectly honest, I don't like how Lazyfoo does- and solves some things, when it comes to coding.
But I do like the tutorials since I have really learned stuff by going through them, when I first learned SDL. They are good when it comes to learn SDL but when the coder has learned the stuff that Lazyfoo learns, the coder should find his / her own code style (which I've did).
I do know though that the reason why Lazyfoo solves things in a certain way, is to make the tutorials as simple and logic as possible, but again, the solutions that is made in the tutorials is not always the best solutions (again, in my opinion).

I would not, for example, have used a lot of 'const int MyFirstTileType = 0;' , 'const int MySecondTileType = 1;' and so on.
Instead I would've created a enum block containing all of my tile types.

Example:

Code:

enum ETileTypes
{
   TILE_RED = 0,
   TILE_GREEN,      <--- (automatically assigned to 1)
   TILE_BLUE,       <--- (automatically assigned to 2)
   NUM_TILETYPES    <--- (automatically assigned to 3)
};



By using an enum block, I can set the start value of the first tile type (TILE_RED = 0) and the rest of the tile types that I put into the enum block will automatically be assigned to the next numeric value (TILE_GREEN = 1, TILE_BLUE = 2 and so on). If I set TILE_RED to one (1), TILE_GREEN will be set to two (2) and so on.

As the last object in my enum block, I've added a NUM_TILETYPES which will always contain the total number of tile types that I have and it will update itself whenever I add- or remove a tile type from the enum block. That information might come in handy since I might sometimes need to know how much tile types I have without have to go up to the enum block and count all my tile types.
Me like enum's. Smile
LAURENT*


Joined: 06 Jan 2013
Posts: 32
I actually figured out the tutorials on this site use a lot of bad programming practices that have unfortunately embedded on me. It's for the sake of simplicity but still. I'm currently trying to break these bad habits to become a sharper programmer. Again thanks for the help

Off topic

Wanna see some clever? I like to draw up concept before I program. I've draw up the collision detection concept and it's looks really clever.
Naith


Joined: 03 Jul 2014
Posts: 158
No problem.

Yeah, please show. =]
LAURENT*


Joined: 06 Jan 2013
Posts: 32
There are only a few tile type in this game and almost each will require a special collision detection algorithm. Here is the collsion detection for sidewall tile. The purpose of the land pad bare extreme importance. It not only detriment where the character land but also detriment how he get on top of platforms. By running a loop to figure out where the land pad is if it get close enough to a wall I can make the character go along with special rules to get on top of each platform.

Eventually I plan to add alpha blending logic, and a few other details that will make this the first 2D isometric game where you can accurately judge height and make precise jump.


Naith


Joined: 03 Jul 2014
Posts: 158
Nice solution there! Keep up the good work. Smile