Sorry for the delay, it took me some time to re-write thw code in a readable fashion.
I'm not familiar with SourceForge yet, though, so I'll upload it here if it's not a problem. :-)
globals.h
Code:
#ifndef GLOBALS_H_INCLUDED
#define GLOBALS_H_INCLUDED
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
const int BITS_PER_PIXEL = 32;
const int FPS = 12;
const int TILE_WIDTH = 50;
const int TILE_HEIGHT = 50;
const int TILES_ROW = 16;
const int TILES_COLUMN = 12;
int TOTAL_TILES = TILES_ROW * TILES_COLUMN;
int LEVEL_WIDTH = TILES_ROW * TILE_WIDTH;
int LEVEL_HEIGHT = TILES_COLUMN * TILE_HEIGHT;
const int TILE_SPRITES = 3;
const int ENEMY_SPRITES = 2;
const int PLAYER_WIDTH = 50;
const int PLAYER_HEIGHT = 100;
const int gravity = 10;
enum
{
FACING_RIGHT,
FACING_LEFT
};
SDL_Surface * screen = NULL;
SDL_Surface * background = NULL;
SDL_Surface * playersprite = NULL;
SDL_Surface * tilesheet = NULL;
SDL_Rect camera = { 0 , 0 , SCREEN_WIDTH , SCREEN_HEIGHT };
SDL_Event event;
#endif // GLOBALS_H_INCLUDED
startup.h
Code:
#ifndef STARTUP_H_INCLUDED
#define STARTUP_H_INCLUDED
#include <fstream>
#include "globals.h"
int backgroundx = 0;
int backgroundy = 0;
SDL_Surface * enemysheet = NULL;
bool init()
{
if( SDL_Init( SDL_INIT_EVERYTHING ) == -1 ) return false;
screen = SDL_SetVideoMode( SCREEN_WIDTH , SCREEN_HEIGHT , BITS_PER_PIXEL , SDL_HWSURFACE | SDL_DOUBLEBUF );
if( screen == NULL ) return false;
SDL_WM_SetCaption( "Game" , NULL );
return true;
}
SDL_Surface * load( std::string file )
{
SDL_Surface * loaded = NULL;
SDL_Surface * optimized = NULL;
loaded = IMG_Load( file.c_str() );
if( loaded != NULL )
{
optimized = SDL_DisplayFormatAlpha( loaded );
SDL_FreeSurface( loaded );
}
return optimized;
}
bool load_files()
{
enemysheet = load( "enemies.png" );
if( enemysheet == NULL ) return false;
background = load( "clouds.png" );
playersprite = load( "sprite.png" );
tilesheet = load( "tiles.png" );
enemysheet = load( "enemy.png" );
if( background == NULL || playersprite == NULL || tilesheet == NULL || enemysheet == NULL ) return false;
return true;
}
void cleanup()
{
SDL_FreeSurface( enemysheet );
SDL_FreeSurface( background );
SDL_FreeSurface( playersprite );
SDL_FreeSurface( tilesheet );
SDL_FreeSurface( enemysheet );
SDL_Quit();
}
void apply_surface( int x , int y , SDL_Surface * get = NULL , SDL_Surface * returned = NULL , SDL_Rect * clips = NULL )
{
SDL_Rect offsets;
offsets.x = x;
offsets.y = y;
SDL_BlitSurface( get , clips , returned , &offsets );
}
void apply_surface( int x , int y , SDL_Surface * get , SDL_Surface * returned , int clipsx , int clipsy , int w , int h )
{
SDL_Rect offsets;
offsets.x = x;
offsets.y = y;
SDL_Rect clips;
clips.x = clipsx;
clips.y = clipsy;
clips.w = w;
clips.h = h;
SDL_BlitSurface( get , &clips , returned , &offsets );
}
bool collision( SDL_Rect a , SDL_Rect b )
{
int lefta , leftb;
int righta , rightb;
int topa , topb;
int bottoma , bottomb;
lefta = a.x;
righta = a.x + a.w;
topa = a.y;
bottoma = a.y + a.h;
leftb = b.x;
rightb = b.x + b.w;
topb = b.y;
bottomb = b.y + b.h;
if( righta <= leftb || lefta >= rightb || bottoma <= topb || topa >= bottomb ) return false;
return true;
}
void scrolling_background()
{
backgroundx -= 1;
if( backgroundx <= -background->w ) backgroundx = 0;
apply_surface( backgroundx , backgroundy , background , screen );
apply_surface( backgroundx + background->w , backgroundy , background , screen );
}
#endif // STARTUP_H_INCLUDED
timer.h
Code:
#ifndef TIMER_H_INCLUDED
#define TIMER_H_INCLUDED
class timer
{
private:
int start_ticks;
bool started;
public:
timer();
void start();
int get_ticks();
};
timer::timer()
{
start_ticks = 0;
started = false;
}
void timer::start()
{
started = true;
start_ticks = SDL_GetTicks();
}
int timer::get_ticks()
{
if( started )
{
return SDL_GetTicks() - start_ticks;
}
return 0;
}
#endif // TIMER_H_INCLUDED
player.h
Code:
#ifndef PLAYER_H_INCLUDED
#define PLAYER_H_INCLUDED
#include "SDL/SDL.h"
#include "SDL/SDL_image.h"
#include "tiles.h"
#include "timer.h"
class player
{
private:
SDL_Rect box;
int x;
int y;
int xvel;
int yvel;
bool jumping;
int frame;
int status;
public:
player( int X , int Y );
void control();
void jump();
void move( tile * tiles[] );
void player_camera();
void show();
};
player::player( int X , int Y )
{
x = X;
y = Y;
xvel = 0;
yvel = 0;
jumping = false;
frame = 0;
status = FACING_RIGHT;
box.x = x;
box.y = y;
box.w = PLAYER_WIDTH;
box.h = PLAYER_HEIGHT;
}
void player::control()
{
if( event.type == SDL_KEYDOWN )
{
switch( event.key.keysym.sym )
{
case SDLK_d:
xvel += PLAYER_WIDTH / 4;
break;
case SDLK_a:
xvel -= PLAYER_WIDTH / 4;
break;
default: {}
}
}
if( event.type == SDL_KEYUP )
{
switch( event.key.keysym.sym )
{
case SDLK_d:
xvel -= PLAYER_WIDTH / 4;
break;
case SDLK_a:
xvel += PLAYER_WIDTH / 4;
break;
default: {}
}
}
}
void player::jump()
{
Uint8 * keystate = SDL_GetKeyState( NULL );
if( keystate[ SDLK_SPACE ] && jumping == false )
{
jumping = true;
yvel = -50;
}
}
void player::move( tile * tiles[] )
{
box.x += xvel;
if( box.x < 0 || box.x + PLAYER_WIDTH > LEVEL_WIDTH || collision( box , tiles ) ) box.x -= xvel;
box.y += yvel;
if( collision( box , tiles ) && yvel >= gravity ) jumping = true;
if( collision( box , tiles ) )
{
if( jumping && yvel >= 0 ) jumping = false;
if( yvel >= 0 ) box.y -= yvel - ( TILE_HEIGHT % yvel );
else box.y -= yvel;
yvel = 0;
}
yvel += gravity;
if( yvel >= gravity * 5 ) yvel = gravity * 5;
if( box.y > LEVEL_HEIGHT + 50 )
{
box.y = 0;
box.x = 0;
status = FACING_RIGHT;
}
x = box.x;
y = box.y;
}
void player::player_camera()
{
camera.x = ( x + PLAYER_WIDTH / 2 ) - SCREEN_WIDTH / 2;
camera.y = ( y + PLAYER_HEIGHT / 2 ) - SCREEN_HEIGHT / 2;
if( camera.x < 0 ) camera.x = 0;
if( camera.x > LEVEL_WIDTH - camera.w ) camera.x = LEVEL_WIDTH - camera.w;
if( camera.y < 0 ) camera.y = 0;
if( camera.y > LEVEL_HEIGHT - camera.h ) camera.y = LEVEL_HEIGHT - camera.h;
}
void player::show()
{
if( xvel < 0 )
{
status = FACING_LEFT;
frame++;
}
else if( xvel > 0 )
{
status = FACING_RIGHT;
frame++;
}
else frame = 0;
if( frame >= 4 ) frame = 0;
if( status == FACING_RIGHT ) apply_surface( x - camera.x , y - camera.y , playersprite , screen , frame * PLAYER_WIDTH , 0 , PLAYER_WIDTH , PLAYER_HEIGHT );
else if( status == FACING_LEFT ) apply_surface( x - camera.x , y - camera.y , playersprite , screen , frame * PLAYER_WIDTH , PLAYER_HEIGHT , PLAYER_WIDTH , PLAYER_HEIGHT );
}
#endif // PLAYER_H_INCLUDED
tiles.h
Code:
#ifndef TILES_H_INCLUDED
#define TILES_H_INCLUDED
#include "globals.h"
#include "startup.h"
enum
{
NONE,
BLUE,
PLATFORM
};
class tile
{
private:
SDL_Rect box;
int tiletype;
public:
tile( int x , int y , int type );
void show();
int get_type();
SDL_Rect get_box();
};
tile::tile( int x , int y , int type )
{
box.x = x;
box.y = y;
box.w = TILE_WIDTH;
box.h = TILE_HEIGHT;
tiletype = type;
}
void tile::show()
{
if( collision( camera , box ) )
{
apply_surface( box.x - camera.x , box.y - camera.y , tilesheet , screen , tiletype * TILE_WIDTH , 0 , TILE_WIDTH , TILE_HEIGHT );
}
}
int tile::get_type()
{
return tiletype;
}
SDL_Rect tile::get_box()
{
return box;
}
void cleanup( tile * tiles[] )
{
for( int t = 0 ; t < TOTAL_TILES ; t++ ) delete tiles[t];
cleanup();
}
bool collision( SDL_Rect a , tile * tiles[] )
{
for( int t = 0 ; t < TOTAL_TILES ; t++ )
{
if( tiles[t]->get_type() == PLATFORM )
{
if( collision( a , tiles[t]->get_box() ) ) return true;
}
}
return false;
}
bool set_tiles( tile * tiles[] )
{
int x = 0;
int y = 0;
std::ifstream map( "tilemap.map" );
if( map == NULL ) return false;
for( int t = 0 ; t < TOTAL_TILES ; t++ )
{
int type = 0;
map >> type;
if( map.fail() )
{
map.close();
return false;
}
if( type >= 0 && type < TILE_SPRITES ) tiles[t] = new tile( x , y , type );
else
{
map.close();
return false;
}
x += TILE_WIDTH;
if( x >= LEVEL_WIDTH )
{
x = 0;
y += TILE_HEIGHT;
}
}
map.close();
return true;
}
#endif // TILES_H_INCLUDED
tileeditor.h
Code:
#ifndef TILEEDITOR_H_INCLUDED
#define TILEEDITOR_H_INCLUDED
#include "startup.h"
int current_tile = NONE;
void editor_camera()
{
int x = 0;
int y = 0;
SDL_GetMouseState( &x , &y );
if( x < TILE_WIDTH ) camera.x -= 20;
if( x > SCREEN_WIDTH - TILE_WIDTH ) camera.x += 20;
if( y < TILE_HEIGHT ) camera.y -= 20;
if( y > SCREEN_HEIGHT - TILE_HEIGHT ) camera.y += 20;
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;
}
void editor_put_tiles( tile * tiles[] , int type )
{
int x = 0;
int y = 0;
SDL_GetMouseState( &x , &y );
x += camera.x;
y += camera.y;
for( int t = 0 ; t < TOTAL_TILES ; t++ )
{
SDL_Rect box = tiles[t]->get_box();
if( x > box.x && x < box.x + box.w && y > box.y && y < box.y + box.h )
{
delete tiles[t];
tiles[t] = new tile( box.x , box.y , type );
}
}
}
bool editor_set_tiles( tile * tiles[] )
{
int x = 0;
int y = 0;
std::ifstream map( "tilemap.map" );
if( map == NULL )
{
for( int t = 0 ; t < TOTAL_TILES ; t++ )
{
tiles[t] = new tile( x , y , NONE );
x += TILE_WIDTH;
if( x >= LEVEL_WIDTH )
{
x = 0;
y += TILE_HEIGHT;
}
}
}
else
{
for( int t = 0 ; t < TOTAL_TILES ; t++ )
{
int type = 0;
map >> type;
if( map.fail() )
{
map.close();
return false;
}
if( type >= 0 && type < TILE_SPRITES ) tiles[t] = new tile( x , y , type );
else
{
map.close();
return false;
}
x += TILE_WIDTH;
if( x >= LEVEL_WIDTH )
{
x = 0;
y += TILE_HEIGHT;
}
}
map.close();
}
return true;
}
void editor_save( tile * tiles[] )
{
std::ofstream map( "tilemap.map" );
for( int t = 0 ; t < TOTAL_TILES ; t++ ) map << tiles[t]->get_type() << " ";
map.close();
}
void editor_show( int tiletype )
{
apply_surface( 20 , 20 , tilesheet , screen , tiletype * TILE_WIDTH , 0 , TILE_WIDTH , TILE_HEIGHT );
}
void editor_control( tile * tiles[] )
{
if( event.type == SDL_MOUSEBUTTONDOWN )
{
if( event.button.button == SDL_BUTTON_LEFT ) editor_put_tiles( tiles , current_tile );
else if( event.button.button == SDL_BUTTON_RIGHT ) editor_put_tiles( tiles , NONE );
else if( event.button.button == SDL_BUTTON_WHEELUP )
{
current_tile--;
if( current_tile < NONE ) current_tile = PLATFORM;
editor_show( current_tile );
}
else if( event.button.button == SDL_BUTTON_WHEELDOWN )
{
current_tile++;
if( current_tile > PLATFORM ) current_tile = NONE;
editor_show( current_tile );
}
}
}
#endif // TILEEDITOR_H_INCLUDED
enemies.h
Code:
#ifndef ENEMIES_H_INCLUDED
#define ENEMIES_H_INCLUDED
#include "globals.h"
#include "startup.h"
enum
{
NO_ENEMY,
BUBBLE
};
class enemy
{
private:
SDL_Rect box;
int enemytype;
int x;
int y;
int xvel;
int yvel;
int status;
public:
enemy( int X , int Y , int type );
void show();
void move( tile * tiles[] );
int get_type();
SDL_Rect get_box();
};
enemy::enemy( int X , int Y , int type )
{
x = X;
y = Y;
xvel = 0;
yvel = 0;
enemytype = type;
status = FACING_LEFT;
box.x = x;
box.y = y;
box.w = TILE_WIDTH;
box.h = TILE_HEIGHT;
}
void enemy::show()
{
if( collision( camera , box ) ) apply_surface( box.x - camera.x , box.y - camera.y , enemysheet , screen , enemytype * TILE_WIDTH , 0 , TILE_WIDTH , TILE_HEIGHT );
}
void enemy::move( tile * tiles[] )
{
if( status == FACING_LEFT ) xvel = -10;
else xvel = 10;
box.x += xvel;
if( collision( box , tiles ) )
{
box.x -= xvel;
if( status == FACING_LEFT ) status = FACING_RIGHT;
else status = FACING_LEFT;
}
box.y += yvel;
if( collision( box , tiles ) )
{
if( yvel <= 0 ) box.y -= yvel - ( TILE_HEIGHT % yvel );
else box.y -= yvel;
yvel = 0;
}
yvel += gravity;
}
int enemy::get_type()
{
return enemytype;
}
SDL_Rect enemy::get_box()
{
return box;
}
#endif // ENEMIES_H_INCLUDED
game.h
Code:
#ifndef GAME_H_INCLUDED
#define GAME_H_INCLUDED
#include "SDL/SDL.h"
#include "SDL/SDL_image.h"
#include <string>
#include "startup.h"
#include "timer.h"
#include "player.h"
#include "tileeditor.h"
#include "enemyeditor.h"
int game()
{
bool quit = false;
bool tileedit = false;
if( init() == false ) return 1;
if( load_files() == false ) return 2;
timer fps;
player player1( 50 , 50 );
tile * tiles[ TOTAL_TILES ];
enemy * enemies[ TOTAL_TILES ];
if( set_tiles( tiles ) == false ) return 4;
while( quit == false )
{
fps.start();
scrolling_background();
if( tileedit ) editor_show( current_tile );
while( SDL_PollEvent( &event ) )
{
if( event.type == SDL_KEYDOWN )
{
if( event.key.keysym.sym == SDLK_t ) tileedit = !tileedit;
}
if( event.type == SDL_QUIT ) quit = true;
if( tileedit == false ) player1.control();
else if( tileedit ) editor_control( tiles );
}
if( tileedit == false )
{
player1.jump();
scrolling_background();
player1.move( tiles );
player1.player_camera();
}
else editor_camera();
for( int t = 0 ; t < TOTAL_TILES ; t++ ) tiles[t]->show();
for( int e = 0 ; e < TOTAL_TILES ; e++ ) enemies[e]->show();
if( tileedit == false ) player1.show();
if( SDL_Flip( screen ) == -1 ) return 5;
if( fps.get_ticks() < 1000 / FPS ) SDL_Delay( ( 1000 / FPS ) - fps.get_ticks() );
}
editor_save( tiles );
cleanup( tiles );
cleanup( enemies );
return 0;
}
#endif // GAME_H_INCLUDED
main.cpp
Code:
#include "game.h"
int main( int argc , char * argv[] )
{
game();
return 0;
}
enemyeditor.h
Code:
#ifndef ENEMYEDITOR_H_INCLUDED
#define ENEMYEDITOR_H_INCLUDED
#include "enemies.h"
void cleanup( enemy * enemies[] )
{
for( int e = 0 ; e < TOTAL_TILES ; e++ ) delete enemies[e];
}
bool collision( SDL_Rect a , enemy * enemies[] )
{
for( int e = 0 ; e < TOTAL_TILES ; e++ )
{
if( enemies[e]->get_type() == BUBBLE )
{
if( collision( a , enemies[e]->get_box() ) ) return true;
}
}
return false;
}
bool set_enemies( enemy * enemies[] )
{
int x = 0;
int y = 0;
std::ifstream map( "enemymap.map" );
if( map == NULL ) return false;
for( int e = 0 ; e < TOTAL_TILES ; e++ )
{
int type = 0;
map >> type;
if( map.fail() )
{
map.close();
return false;
}
if( type >= 0 && type < ENEMY_SPRITES ) enemies[e] = new enemy( x , y , type );
else
{
map.close();
return false;
}
x += TILE_WIDTH;
if( x >= LEVEL_WIDTH )
{
x = 0;
y += TILE_HEIGHT;
}
}
map.close();
return true;
}
#endif // ENEMYEDITOR_H_INCLUDED
If you want I could upload the whole thing, sprites, maps and everything, compressed in a .rar file to have a better look at. :-)
The problem seems to be at the last file, enemyeditor.h
Before I made the program read enemies from an enemy map, I tried creating an enemy entity manually and it worked perfectly.
But ever since I made it read enemies from a map, it returns 3.
enemyeditor.h is practically a copy of the functions that read tiles from a map file.
I did not write the editor functions for the enemies yet, since the problem is at reading the enemy map.
I am pretty new at programming in general, as I already said, so I'm not sure if this is even the right approach to make an enemy placement program to place enemies on the map just like I'm placing tiles.
Any help would be appreciated.
Thank you in advance. :-)