Sign in to follow this  
ASnogarD

C++ Newbie here, need help

Recommended Posts

Hi

Quick background: I used a few online manuals , and C++ Primer Plus to get a handle on C++.
I used Lazy Foo's excellent SDL beginner tutorials to start learning SDL, and made quiet a bit of progress till I wanted to write my little program correctly... ie in seperate classes, thats where I hit the brick wall :P

In short: I made a IO.h and IO.cpp class files to contain SDL worker functions like init() , apply_surface() etc etc... except it wont accept a SDLSurface (or pointer to a SDL_Surface) as a type.



#include"IO.h"


SDL_Surface* IO::load_image( std::string filename )
{
SDL_Surface* loadedImage = NULL;
SDL_Surface* optimizedImage = NULL;

loadedImage = IMG_Load ( filename.c_str() );

if ( loadedImage != NULL )
{
optimizedImage = SDL_DisplayFormat( loadedImage );
SDL_FreeSurface( loadedImage );
if ( optimizedImage != NULL )
{

SDL_SetColorKey( optimizedImage, SDL_SRCCOLORKEY, SDL_MapRGB( optimizedImage->format, 0xA3, 0x4D, 0xFD ) );
}
}

return optimizedImage;
}




NOTE: IO.h DOES include SDL.h, and SDL_image.h (and all the other relevant includes). I have tried including them in the IO.cpp file as well.
I copied pasted the code to the main.cpp and the IDE recognised the SDL_Surface * as a type without issues.
NOTE: this is just one function defined in IO.h ... the IDE doesnt complain about the function in the IO.h file .. or any other thing in the IO.h file...just in the IO.cpp , every refrence to SDL_Surface * is not recognised as a type.

Why wont it recognise SDL_Surface * as a type (return or parameter) when not in the main.cpp ?

Any advise , or a link to relevant material would be greatly appreciated. I have tried reading a number of manuals but cant seem to work out whats wrong.

Thank you for your time and consideration.

Share this post


Link to post
Share on other sites
Post the full contents of IO.h, IO.cpp and main.cpp. Put each one in source tags (not code tags). Also post the exact error message.

Share this post


Link to post
Share on other sites
EDIT: Oh, the code is somewhat disjointed, my goals was first successfully seperate the classes , then neaten the code... I hadn't even remove the stop gap measures I used to get the player class to work outside the main.cpp ... that was before I decided to split up the who program into smaller parts that I can get to do specific jobs.

The error is in the Visual Studio 2010 Express editors error checking, before I even try compiling.
It says "Error: variable 'SDL_Surface' is not a type name" if I hover over SDL_Surface , and complains the declaration is incompatible with the definition of the function, stating the SDL_Surface is a error type.

NOTE: The code is incomplete, when it was a single file with the tile and player classes defined in the main.cpp it ran fine, but I wanted to break it into logical class units... but got stopped by the IDE indicating the IO.cpp file had errors. I intended to work through the errors when the IDE didnt show errors in the code, ie sort out the mess error by error... but I cam stumped by the fact it wont take a SDL_Surface pointer as a type (return or parameter) unless its in the main.cpp .

Heres the main.cpp



// The headers
#include "SDL.h"
#include "SDL_image.h"
#include "SDL_ttf.h"
#include <string>
#include <iostream>
#include <fstream>

#include "timer.h"
#include "player.h"
#include "IO.h"


void set_camera( SDL_Rect box);
void player_update( int frame, SDL_Rect box, int status);


// Global constants and surface declarations - will be moved / removed
// when the classes are seperated

const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
const int PLAYER_VELOCITY = 600;
const int SCREEN_BPP = 32;

// If you adjust the FRAMES_PER_SECOND you need to adjust the ANIMATION_FRAME_INCREMENT
// or the sprite animation speed will be wrong.
// Rough guide : 60 FPS = 0.125 inc , 30 FPS = 0.25 (the more FPS the lower the inc)
const int FRAMES_PER_SECOND = 60;


/*
Regarding the sprite animation , it may be an idea to use time to increment the
change of frames instea of a abitury number as it is now, then I could release
the game from the FPS cap... in theory.
*/


enum {

PLAYER_WIDTH = 96,
PLAYER_HEIGHT = 166,

LEVEL_WIDTH = 1760,
LEVEL_HEIGHT = 1320,
TILE_WIDTH = 110,
TILE_HEIGHT = 110,
TOTAL_TILES = 192,
TILE_SPRITES = 12

};

enum { TILE_RED = 0, TILE_GREEN = 1, TILE_BLUE = 2, TILE_CENTER = 3, TILE_TOP = 4,
TILE_TOPRIGHT = 5, TILE_RIGHT = 6, TILE_BOTTOMRIGHT = 7, TILE_BOTTOM = 8,
TILE_BOTTOMLEFT = 9, TILE_LEFT = 10, TILE_TOPLEFT = 11
};

enum { PLAYER_RIGHT = 0, PLAYER_LEFT = 1, PLAYER_UP = 2, PLAYER_DOWN = 3 };



// Debug - Surface, font and color var for debug text
using namespace std;

SDL_Color textColor = { 0, 0, 0 };



// Will need another surface soon, to seperate the player from the tiles
// probably need to move the tiles from the sprite sheet



SDL_Rect clips[ TILE_SPRITES ];

SDL_Rect clipsRight[ 5 ];
SDL_Rect clipsLeft[ 5 ];
SDL_Rect clipsUp[ 5 ];
SDL_Rect clipsDown[ 5 ];

// NOTE: Will have to change this objects name as event is a keyword



int main( int argc, char* args[] )
{

bool quit = false;

Player kicker;


Tile *tiles[ TOTAL_TILES ];

Timer delta;

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

if( load_files() == false )
{
return 1;
}

clip_tiles();

if( set_tiles( tiles ) == false )
{
return 1;
}

delta.start();

while( quit == false )
{

while( SDL_PollEvent( &kicker.event ) )
{
kicker.handle_input();

if( kicker.event.type == SDL_QUIT )
{
quit = true;
}
}


// -------------------- move player temp code ----------------




kicker.x += kicker.get_xVel() * ( delta.get_ticks() / 1000.f );

kicker.player_box.x = (int)kicker.x;

if( touches_wall( kicker.player_box, tiles ) )
{
kicker.x -= kicker.get_xVel() * ( delta.get_ticks() / 1000.f );
kicker.player_box.x = (int)kicker.x;
}

kicker.y += kicker.get_yVel() * ( delta.get_ticks() / 1000.f );

kicker.player_box.y = (int)kicker.y;

if( touches_wall( kicker.player_box, tiles ) )
{
kicker.y -= kicker.get_yVel() * ( delta.get_ticks() / 1000.f );
kicker.player_box.y = (int)kicker.y;
}


// ------------------------------------------------------------

delta.start();

set_camera( kicker.player_box );

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

kicker.update_player();
player_update( kicker.frame, kicker.player_box, kicker.status );

// Uses draw_text function to write text and variable data to the screen

int playerX = kicker.get_X();
int playerY = kicker.get_Y();
int playerxVel = kicker.get_xVel();
int playeryVel = kicker.get_yVel();



char buffer[256];

sprintf(buffer, "Kickin' Sticks - Animation Test " );
draw_text( screen, buffer, 50, 10, 26, textColor );

sprintf(buffer, "Player X %d - Y %d ", playerX, playerY );
draw_text( screen, buffer, 50, 50, 22, textColor );

sprintf(buffer, "Player XVEL %d - YVEL %d", playerxVel, playeryVel);
draw_text( screen, buffer, 50, 80, 22, textColor );

sprintf(buffer, "Ver: 00001a 15092010 ");
draw_text( screen, buffer, 330, 450, 16, textColor );

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

if( delta.get_ticks() < 1000 / FRAMES_PER_SECOND )
{
SDL_Delay( ( 1000 / FRAMES_PER_SECOND ) - delta.get_ticks() );
}
}

clean_up( tiles );

return 0;
}



void set_camera(SDL_Rect box)
{
camera.x = ( box.x + PLAYER_WIDTH / 2 ) - SCREEN_WIDTH / 2;
camera.y = ( box.y + PLAYER_HEIGHT / 2 ) - SCREEN_HEIGHT / 2;

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 player_update( int frame, SDL_Rect box, int status)
{

//Show the Player sprite
if( status == PLAYER_RIGHT )
{
apply_surface( box.x - camera.x, box.y - camera.y, player, screen, &clipsRight[ (int)frame ] );
}
else if( status == PLAYER_LEFT )
{
apply_surface( box.x - camera.x, box.y - camera.y, player, screen, &clipsLeft[ (int)frame ] );
}

if( status == PLAYER_UP )
{
apply_surface( box.x - camera.x, box.y - camera.y, player, screen, &clipsUp[ (int)frame ] );
}
else if( status == PLAYER_DOWN )
{
apply_surface( box.x - camera.x, box.y - camera.y, player, screen, &clipsDown[ (int)frame ] );
}

}






Here is the IO.h


#ifndef IO_H_
#define IO_H_

#include"SDL.h"
#include"SDL_image.h"
#include"SDL_ttf.h"

#include<iostream>
#include<fstream>
#include<string>

#include"tile.h"

class IO
{
private:

public:

SDL_Surface *game;
SDL_Surface *player;
SDL_Surface *screen;

static const int SCREEN_WIDTH = 640;
static const int SCREEN_HEIGHT = 480;
static const int PLAYER_VELOCITY = 600;
static const int SCREEN_BPP = 32;

enum {

PLAYER_WIDTH = 96,
PLAYER_HEIGHT = 166,

LEVEL_WIDTH = 1760,
LEVEL_HEIGHT = 1320,
TILE_WIDTH = 110,
TILE_HEIGHT = 110,
TOTAL_TILES = 192,
TILE_SPRITES = 12

};


SDL_Surface* load_image( std::string filename );
void apply_surface( int x, int y, SDL_Surface* source, SDL_Surface* destination, SDL_Rect* clip = NULL);
bool check_collision( SDL_Rect A, SDL_Rect B );
bool init();
bool load_files();
void clean_up( Tile *tiles[] );
bool IO::set_tiles( Tile *tiles[] );
bool IO::touches_wall( SDL_Rect box, Tile *tiles[] );

void draw_text( SDL_Surface *destination, string msg, int x, int y, int size, SDL_Color color );

}

#endif




and the IO.cpp



#include"IO.h"


SDL_Surface* IO::load_image( std::string filename )
{
SDL_Surface* loadedImage = NULL;
SDL_Surface* optimizedImage = NULL;

loadedImage = IMG_Load ( filename.c_str() );

if ( loadedImage != NULL )
{
optimizedImage = SDL_DisplayFormat( loadedImage );
SDL_FreeSurface( loadedImage );
if ( optimizedImage != NULL )
{

SDL_SetColorKey( optimizedImage, SDL_SRCCOLORKEY, SDL_MapRGB( optimizedImage->format, 0xA3, 0x4D, 0xFD ) );
}
}

return optimizedImage;
}

void IO::apply_surface( int x, int y, SDL_Surface* source, SDL_Surface* destination, SDL_Rect* clip = NULL)
{
SDL_Rect offset;

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

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

bool IO::check_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 ( bottomA <= topB ) return false;
if ( topA >= bottomB ) return false;
if ( rightA <= leftB ) return false;
if ( leftA >= rightB ) return false;

return true;
}

bool IO::init()
{
if ( SDL_Init( SDL_INIT_EVERYTHING ) == -1 )
{
return false;
}

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

if ( screen == NULL )
{
return false;
}

if( TTF_Init() == -1 )
{
return false;
}


SDL_WM_SetCaption( " Kickin' Sticks - Frame Independant Movement ", NULL );

return true;
}

bool IO::load_files()
{

game = load_image( "GFX/tiles.png" );

if ( game == NULL )
{
return false;
}

player = load_image( "GFX/stick.png" );

if ( player == NULL )
{
return false;
}

return true;
}

void IO::clean_up( Tile *tiles[] )
{

SDL_FreeSurface( game );
SDL_FreeSurface( player );


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

TTF_Quit();
SDL_Quit();
}



bool IO::set_tiles( Tile *tiles[] )
{
int x = 0, y = 0;

std::ifstream map( "GFX/lazy.map" );

if ( map == NULL )
{
return false;
}

for ( int t = 0; t < TOTAL_TILES; t++ )
{
int tileType = -1;
map >> tileType;

if( map.fail() == true )
{
map.close();
return false;
}

if( ( tileType >=0 ) && ( tileType < TILE_SPRITES ) )
{
tiles[ t ] = new Tile( x, y, tileType );
}

else
{
map.close();
return false;
}

x += TILE_WIDTH;

if( x >= LEVEL_WIDTH )
{
x = 0;
y += TILE_HEIGHT;
}
}

map.close();
return true;
}



void IO::draw_text( SDL_Surface *destination, string msg, int x, int y, int size, SDL_Color color )
{
TTF_Font *font;
font = TTF_OpenFont( "GFX/8-PM___.ttf", size );
if ( !font )
cerr<<"Error loading 8-PM___.ttf"<<endl;

SDL_Rect coordinates;
coordinates.x = (int)x;
coordinates.y = (int)y;
SDL_Surface *message = NULL;
message = TTF_RenderText_Solid( font, msg.c_str(), textColor );

SDL_BlitSurface( message, NULL, destination, &coordinates );

TTF_CloseFont( font );

SDL_FreeSurface( message );
}




Share this post


Link to post
Share on other sites
Quote:
Original post by ASnogarD
The error is in the Visual Studio 2010 Express editors error checking, before I even try compiling.


What happens if you try to compile? do you get the same error message? Try compiling just IO.cpp.

Also, uncomment the entire contents of IO.cpp and put this instead:

#include <SDL.h>

SDL_Surface *surface;


Does IO.cpp compile with just these two lines? Again, try compiling just IO.cpp, not building the whole project.

Share this post


Link to post
Share on other sites
You need to add a semi-colon after your class definition in io.h.

class IO
{
...
};

other things are declaring member function prototypes as :

bool IO::set_tiles( Tile *tiles[] );
bool IO::touches_wall( SDL_Rect box, Tile *tiles[] );

remove IO::.

you cant refer to "string" without referring to the std namespace, either add "using namespace std" at the head of the file or use std::string (which you have done for one function).

actually there are plenty of problems with your files and it wont compile without closer scrutiny. try fixing these problems and paste your compiler errors again.

Share this post


Link to post
Share on other sites
Thank you , it was the missing ; that caused the SDL_Surface not recognised as a type error.

I really appreciate the assistance, both Gage64 and Karpatzio.

Now I can move on fixing the other bugs :)

Share this post


Link to post
Share on other sites
A few other suggestions:

1)As a rule of thumb, it is better to use forward decelerations if you will only need the type deceleration. For example in io.h declare:

class Tile;

class IO
{
...
};

2) Consider passing arguments by reference instead of by value where copying would be expensive, for example: SDL_Surface* load_image( std::string filename );
would better be defined as: SDL_Surface* load_image(const std::string &filename);

meaning that a constant string is passed by reference and will not be altered. The same can be applied to your rectangle arguements etc.

3) Using vectors instead of normal arrays will handle adding and removing elements for you effectively.

Share this post


Link to post
Share on other sites
I have nearly got them to compile... one issue remains.

tile.h


#ifndef TILE_H_
#define TILE_H_

#include"IO.h"
// #include"player.h"

// class IO;

class Tile
{

private:


int x;
int y;
SDL_Rect tileBox;
int type;

IO mIO;

public:

enum {TOTAL_TILES = 192};

enum { TILE_RED = 0, TILE_GREEN = 1, TILE_BLUE = 2, TILE_CENTER = 3, TILE_TOP = 4,
TILE_TOPRIGHT = 5, TILE_RIGHT = 6, TILE_BOTTOMRIGHT = 7, TILE_BOTTOM = 8,
TILE_BOTTOMLEFT = 9, TILE_LEFT = 10, TILE_TOPLEFT = 11
};

enum {

PLAYER_WIDTH = 96,
PLAYER_HEIGHT = 166,

LEVEL_WIDTH = 1760,
LEVEL_HEIGHT = 1320,
TILE_WIDTH = 110,
TILE_HEIGHT = 110,

TILE_SPRITES = 12

};



Tile();
Tile( int x, int y, int tileType );
void show();
int get_type();
SDL_Rect get_box();


bool touches_wall( SDL_Rect box, Tile *tiles[] );

};

#endif



tile.cpp

#include"tile.h"

Tile::Tile()
{
}

Tile::Tile( int x, int y, int tileType )
{
tileBox.x = x;
tileBox.y = y;

tileBox.w = TILE_WIDTH;
tileBox.h = TILE_HEIGHT;

type = tileType;
}

void Tile::show()
{
if( mIO.check_collision( mIO.camera, tileBox) == true )
{
mIO.apply_surface( tileBox.x - mIO.camera.x, tileBox.y - mIO.camera.y, mIO.game, mIO.screen, &mIO.clips[ type ] );
}
}


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

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


bool Tile::touches_wall( SDL_Rect box, Tile *tiles[] )
{
for( int t = 0; t < TOTAL_TILES; t++ )
{
if( ( tiles[ t ]->get_type() >= TILE_TOP ) && ( tiles[ t ]->get_type() <= TILE_TOPLEFT ))
{
if( mIO.check_collision( box, tiles[ t ]->get_box() ) == true )
{
return true;
}
}
}

return false;
}






IO.h

#ifndef IO_H_
#define IO_H_

#include"SDL.h"
#include"SDL_image.h"
#include"SDL_ttf.h"

#include<iostream>
#include<fstream>
#include<string>

#include"tile.h"

class Tile;

class IO
{
private:



public:

enum { TILE_RED = 0, TILE_GREEN = 1, TILE_BLUE = 2, TILE_CENTER = 3, TILE_TOP = 4,
TILE_TOPRIGHT = 5, TILE_RIGHT = 6, TILE_BOTTOMRIGHT = 7, TILE_BOTTOM = 8,
TILE_BOTTOMLEFT = 9, TILE_LEFT = 10, TILE_TOPLEFT = 11
};

enum {

PLAYER_WIDTH = 96,
PLAYER_HEIGHT = 166,

LEVEL_WIDTH = 1760,
LEVEL_HEIGHT = 1320,
TILE_WIDTH = 110,
TILE_HEIGHT = 110,

TILE_SPRITES = 12

};

enum {TOTAL_TILES = 192};

SDL_Surface *game;
SDL_Surface *player;
SDL_Surface *screen;

SDL_Color textColor;

SDL_Rect camera;

SDL_Rect clips[ TILE_SPRITES ];

static const int SCREEN_WIDTH = 640;
static const int SCREEN_HEIGHT = 480;
static const int PLAYER_VELOCITY = 600;
static const int SCREEN_BPP = 32;



IO();
SDL_Surface* load_image( std::string filename );
void apply_surface( int x, int y, SDL_Surface* source, SDL_Surface* destination, SDL_Rect* clip = NULL);
bool check_collision( SDL_Rect A, SDL_Rect B );
bool init();
bool load_files();
void clean_up( Tile *tiles[] );

void clip_tiles();
bool set_tiles( Tile *tiles[] );

bool touches_wall( SDL_Rect box, Tile *tiles[] );

void draw_text( SDL_Surface *destination, std::string msg, int x, int y, int size, SDL_Color color );

};

#endif



IO.cpp



#include"IO.h"

IO::IO()
{
SDL_Color textColor = { 0, 0, 0 };
SDL_Rect camera = { 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT };

}


SDL_Surface* IO::load_image( std::string filename )
{
SDL_Surface* loadedImage = NULL;
SDL_Surface* optimizedImage = NULL;

loadedImage = IMG_Load ( filename.c_str() );

if ( loadedImage != NULL )
{
optimizedImage = SDL_DisplayFormat( loadedImage );
SDL_FreeSurface( loadedImage );
if ( optimizedImage != NULL )
{

SDL_SetColorKey( optimizedImage, SDL_SRCCOLORKEY, SDL_MapRGB( optimizedImage->format, 0xA3, 0x4D, 0xFD ) );
}
}

return optimizedImage;
}

void IO::apply_surface( int x, int y, SDL_Surface* source, SDL_Surface* destination, SDL_Rect* clip)
{
SDL_Rect offset;

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

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

bool IO::check_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 ( bottomA <= topB ) return false;
if ( topA >= bottomB ) return false;
if ( rightA <= leftB ) return false;
if ( leftA >= rightB ) return false;

return true;
}

bool IO::init()
{
if ( SDL_Init( SDL_INIT_EVERYTHING ) == -1 )
{
return false;
}

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

if ( screen == NULL )
{
return false;
}

if( TTF_Init() == -1 )
{
return false;
}


SDL_WM_SetCaption( " Kickin' Sticks - Frame Independant Movement ", NULL );

return true;
}

bool IO::load_files()
{

game = load_image( "GFX/tiles.png" );

if ( game == NULL )
{
return false;
}

player = load_image( "GFX/stick.png" );

if ( player == NULL )
{
return false;
}

return true;
}

void IO::clean_up( Tile *tiles[] )
{

SDL_FreeSurface( game );
SDL_FreeSurface( player );


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

TTF_Quit();
SDL_Quit();
}



bool IO::set_tiles( Tile *tiles[] )
{
int x = 0, y = 0;

std::ifstream map( "GFX/lazy.map" );

if ( map == NULL )
{
return false;
}

for ( int t = 0; t < TOTAL_TILES; t++ )
{
int tileType = -1;
map >> tileType;

if( map.fail() == true )
{
map.close();
return false;
}

if( ( tileType >=0 ) && ( tileType < TILE_SPRITES ) )
{
tiles[ t ] = new Tile( x, y, tileType );
}

else
{
map.close();
return false;
}

x += TILE_WIDTH;

if( x >= LEVEL_WIDTH )
{
x = 0;
y += TILE_HEIGHT;
}
}

map.close();
return true;
}



void IO::draw_text( SDL_Surface *destination, std::string msg, int x, int y, int size, SDL_Color color )
{
TTF_Font *font;
font = TTF_OpenFont( "GFX/8-PM___.ttf", size );
if ( !font )
std::cerr<<"Error loading 8-PM___.ttf"<< std::endl;

SDL_Rect coordinates;
coordinates.x = (int)x;
coordinates.y = (int)y;
SDL_Surface *message = NULL;
message = TTF_RenderText_Solid( font, msg.c_str(), textColor );

SDL_BlitSurface( message, NULL, destination, &coordinates );

TTF_CloseFont( font );

SDL_FreeSurface( message );
}


void IO::clip_tiles()
{

// Clip the tile sprites for the level

clips[ TILE_RED ].x = 0;
clips[ TILE_RED ].y = TILE_HEIGHT * 3;
clips[ TILE_RED ].w = TILE_WIDTH;
clips[ TILE_RED ].h = TILE_HEIGHT;

clips[ TILE_GREEN ].x = TILE_WIDTH;
clips[ TILE_GREEN ].y = TILE_HEIGHT * 3;
clips[ TILE_GREEN ].w = TILE_WIDTH;
clips[ TILE_GREEN ].h = TILE_HEIGHT;

clips[ TILE_BLUE ].x = TILE_WIDTH * 2;
clips[ TILE_BLUE ].y = TILE_HEIGHT * 3;
clips[ TILE_BLUE ].w = TILE_WIDTH;
clips[ TILE_BLUE ].h = TILE_HEIGHT;

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

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

clips[ TILE_BOTTOMLEFT ].x = 0;
clips[ TILE_BOTTOMLEFT ].y = TILE_HEIGHT * 2;
clips[ TILE_BOTTOMLEFT ].w = TILE_WIDTH;
clips[ TILE_BOTTOMLEFT ].h = TILE_HEIGHT;

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

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

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

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

clips[ TILE_RIGHT ].x = TILE_WIDTH * 2;
clips[ TILE_RIGHT ].y = TILE_HEIGHT;
clips[ TILE_RIGHT ].w = TILE_WIDTH;
clips[ TILE_RIGHT ].h = TILE_HEIGHT;

clips[ TILE_BOTTOMRIGHT ].x = TILE_WIDTH * 2;
clips[ TILE_BOTTOMRIGHT ].y = TILE_HEIGHT * 2;
clips[ TILE_BOTTOMRIGHT ].w = TILE_WIDTH;
clips[ TILE_BOTTOMRIGHT ].h = TILE_HEIGHT;
}




Compiling IO.cpp results in:

1>c:\users\xxxxxxxx\documents\visual studio 2010\projects\framework\framework\tile.h(21): error C2146: syntax error : missing ';' before identifier 'mIO'
1>c:\users\xxxxxxx\documents\visual studio 2010\projects\framework\framework\tile.h(21): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\users\xxxxxxxx\documents\visual studio 2010\projects\framework\framework\tile.h(21): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int

Compiling Tile.cpp results in a successfull build.

If I use the ' class IO; ' declaration it complains IO is refering to a undefined class.

As far as I can see the issue is due to me trying to use class function members in other classes, I am really struggling with multiple classes and passing data to and from classes.
The study material I used only used 1 class (+header) and a main.cpp to demonstrate classes each time... which is pretty easy.

Can you call on other classes functions from another class ?
Do I have to rewrite the classes so no fuction calls on any function outside the class ?
Is there any online material I can refrence that will assist me in learning to deal with multiple classes (so that I can teach myself, instead of bugging you guys constantly ) ?

I am reading that Thinking in C++ vol 1 and 2 at the moment, but would love to get over this hurdle as well... reading and doing stock samples, or counting the elements in your name samples is making me vegitate :P

Thanks again for your help.

Share this post


Link to post
Share on other sites
There are many ways to handle this. One way is to store a (smart) pointer to an IO instance as a member, this should be done in the Tile constructor. Another is to pass a pointer or reference to an IO instance to the functions that need them.

Your IO class is too big, this is causing it to be an unnecessary dependency. For instance, if "check_collision" were a free function rather than a member function, then you wouldn't need the IO instance in Tile::touches_wall().

All the functions in the IO class which do not use any of its members should be free functions, possibly in their own namespace. You shouldn't require someone to call a function on an object when the function is stateless.

Share this post


Link to post
Share on other sites
I made the IO class to remove the none class (or main.cpp) functions as I have no idea how to get a class to refer to a function that I havent declared a object for.

I assume by free functions you mean functions that you dont define a class for ?

Most of the IO functions were in the main.cpp without a class definition, the Tile, Player and Timer classes were defined in the main.cpp and the whole program was in one file (except the png's, the level map file, font ect.).
It used to run fine but its not much value to gain experience in OOP if I dont break up the code :P

My knowledge is still limited, basically read most of C++ Primer Plus , bits and pieces of the Beginners Guide as posted at MS's Visual Studio pages, started on Thinking in C++ Vol 1, Lazy Foo's SDL tutorials.
Thing is I learn faster by actually doing stuff, if I try just reading I forget much of what I read and the sample code offered by the books (which I did... most of them) was ... dull.

I did go back and re-read classes, but didnt help in refrencing class's from classes ... and didnt see a thing about refering to a function defined in main.cpp from a class outside main.cpp.


karpatzio - by removing the include file from the header and moving it to the cpp resulted in both IO.cpp and Tile.cpp compiling.
Thank you.

I do appreciate the help guys, its very encouraging to have such help in the beginning.

Share this post


Link to post
Share on other sites
I got it to compile and execute... but it opens a window and then spits out :

First-chance exception at 0x68128c2c in framework.exe: 0xC0000005: Access violation reading location 0xbaadf039.
Unhandled exception at 0x68128c2c in framework.exe: 0xC0000005: Access violation reading location 0xbaadf039.
The program '[3120] framework.exe: Native' has exited with code -1073741819 (0xc0000005).

... of course I havent advanced to throwing and catching exceptions, and I doubt that I could handle this type of exception while its running.

I get the idea its due to me trying to use objects to refer to the functions in the IO class, specifically passing a object that contains a refrence to the SDL_Surfaces.

I know the code as a whole functions, as I can run the code as a single main.cpp ( ok I did seperate the timer class at the last successfull run).

Guess I'll have to look at rewriting the code in such away it doesnt need to depend on other functions in other classes to work... and *sigh* 'read sum moar' :P

Thanks for your assistance, I am not giving up.. just stepping back and having a look again from another angle... after I read up.

Share this post


Link to post
Share on other sites
Step through the program with the debugger to find out what line causes the crash. If you don't know how to use the debugger, read this.

Share this post


Link to post
Share on other sites
Those aren't C++ exceptions, they are Windows Structured Exceptions. The error code 0xC0000005 means you have dereferenced (implicitly or explicitly) a bad address. This might be caused by accessing an invalid pointer or reference.

The value of the address is suspiciously close to 0xbaadf00d, which is a pattern used by the Heap. These special values will give you a clue as to what you are doing wrong.

Note that if you don't pass pointers or references to a pre-exisiting IO object, you will have mutliple, independent instances of this class, which is almost certainly what you don't want.

Quote:

I assume by free functions you mean functions that you dont define a class for ?

You are correct.

Quote:

Most of the IO functions were in the main.cpp without a class definition, the Tile, Player and Timer classes were defined in the main.cpp and the whole program was in one file (except the png's, the level map file, font ect.).
It used to run fine but its not much value to gain experience in OOP if I dont break up the code :P

OOP is not a panacea. Use it where it makes sense. Bundling code and state together makes sense, but bundling stateless code does not. You can still split the code into multiple files and use the free functions.

Read this if you haven't already.

[Edited by - Zahlman on October 1, 2010 3:00:17 PM]

Share this post


Link to post
Share on other sites
Hi all.

A much delayed update , took me some time to read up and examine other source code.
I am happy to say I have made some progress and my code compiles, my tiles display correctly and my player is running about the screen within the world boundries.
Its not all perfect, in fact much of it is rather clunky and clumsy but at least now I have some visual feedback so I can see how changes effect the code... not some obscure hexidecimal laden error message.

Thank you for all your help you gave me, hopefully in the near future I will be announcing my completed game :)

The thing that helped me out was to create objects in my main.cpp and send classes a pointer to those objects to allow the class to access function of the pointed at object via a -> (indirect membership) operator.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this