Hi i am trying to make a jump and run game kinda like mario. i have been following a tutorial so im not completly sure how the playing map is generated i want to add more jumps, ledges and make it bigger basically. I have no idea how to do this however. I have included my map.cpp, map.h and main.cpp if anyone could help me achieve this it would be much apprciated :) I am using Visual C++ with SDL if that helps at all

/*
  map.cpp
   CMap
*/

#include "global.h"




void CMap::loadMap(const char *file){
	FILE *mapfile;
	int i, j, t;

	printf("loading map %s... ", file);


	mapfile = fopen(file, "rb");

	if(tiles)		//map has already been initialized
		freetiles();


	fread(&width, sizeof(int), 1, mapfile);		//read map width
	fread(&height, sizeof(int), 1, mapfile);	//read map height

	tiles = new int[width*height];				//get memory for the map

	t = 0;	
	for(j = 0; j < width; j++){
		for(i = 0; i < height; i++){
			fread(&tiles[t], sizeof(int), 1, mapfile);	//read tile
			t++;
		}
	}
	fclose(mapfile);

	tiles2d = new int*[height];					//build 2d index array to map data
	for(i=0; i<height; i++){					
		tiles2d[i] = &(tiles[i*width]);			//tiles[i] is a pointer to tile row i
	}

	printf("done\n");
}

void CMap::saveMap(const char *file){
	FILE *mapfile;
	int i, j, t;

	printf("saving map %s... ", file);

	mapfile = fopen(file, "wb");

	fwrite(&width, sizeof(int), 1, mapfile);
	fwrite(&height, sizeof(int), 1, mapfile);

	t = 0;
	for(j = 0; j < width; j++){
		for(i = 0; i < height; i++){
			fwrite(&tiles[t], sizeof(int), 1, mapfile);
			t++;
		}
	}
	fclose(mapfile);

	printf("done\n");
}

//create a new map and fill it with tile 0
void CMap::emptymap(int w, int h){
	int i, j, t;

	if(tiles)		//map has already been initialized
		freetiles();	

	width = w;
	height = h;

	tiles = new int[width*height];

	t = 0;
	for(j = 0; j < width; j++){
		for(i = 0; i < height; i++){
			tiles[t] = 0;
			t++;
		}
	}

	tiles2d = new int*[height];					//build 2d index array to map data
	for(i=0; i<height; i++){					
		tiles2d[i] = &(tiles[i*width]);			//tiles[i] is a pointer to tile row i
	}
}

//check if we've scrolled to far and fix scroll_x, _y
void CMap::limit_scroll(){

	if(scroll_x < 0)							//too far left?
		scroll_x = 0;

	else if(scroll_x+640 > width*TILESIZE)		//don't scroll over the map boundaries on the right side (640 is the screenwidth)
		scroll_x = width*TILESIZE-640;
	

	if(scroll_y < 0)							//too far up?
		scroll_y = 0;
	
	else if(scroll_y + 480 > height*TILESIZE)	//bottom map boundaries (480 - screenheight)
		scroll_y = height*TILESIZE-480;
}

void CMap::draw(){
	int x, y;	//screen pixel x,y coordinate to draw the current tile to
	int mx, my;
	int sx = 0-(scroll_x%TILESIZE);
	int smx = (sx+scroll_x)/TILESIZE;

	
	for( y = 0-(scroll_y%TILESIZE), my = (y+scroll_y)/TILESIZE;  y < 480;  y+=TILESIZE){		//y draw coordinate, the offset is for smooth scrolling
		for( x = sx, mx = smx;  x < 640;  x+=TILESIZE){	//x draw coordinate
			if(tileset[ tiles2d[my][mx] ].spr != NULL)
				tileset[ tiles2d[my][mx] ].spr->draw(x,y);
			mx++;
		}
		my++;
	}	
}




CMap::~CMap(){
	if(tiles)
		freetiles();
}



void CMap::freetiles(){
	delete [width*height] tiles;
	delete [height] tiles2d;
	tiles = NULL;
	width = 0;
	height = 0;
}
/*
  map.h
   CMap
*/


enum TileType{t_nonsolid, t_solid, t_slopeleft, t_sloperight};



struct CTile{
	TileType	type;	//the type of the tile (solid, slope, ...)
	gfxSprite	*spr;	//sprite to draw

	CTile(){
		type = t_nonsolid;
		spr = NULL;
	};
};




extern CTile		tileset[9];




class CMap{
	public:
		void loadMap(const char *file);		//loads the map from a file
		void saveMap(const char *file);

		~CMap();


		void emptymap(int w, int h);


		void draw();

		TileType map(int x, int y){			//return the tiletype at the specific position (map coordinates)
			return tileset[ tiles[x+y*width] ].type;
		};

		void limit_scroll();

	private:
		int width;
		int height;
		int *tiles;
		int **tiles2d;

		void freetiles();
	

	friend void leveleditor();
};
//---------------- includes ----------------
#include "global.h"				



//---------------- global variables ----------------
//"engine"
Uint8			*keystates;
SDL_Surface		*screen;		//the screen (main sdl surface which is visible on the monitor)

//sprites
gfxSprite		spr_t[7];
gfxSprite		spr_player[2];
gfxSprite		spr_player2[2];


gfxSprite		spr_background;

gfxFont			font;

//game objects

CPlayer			player;
CPlayer			player2;

CMap			map;

CTile			tileset[9];


//scroll offset
int scroll_x = 0;
int scroll_y = 0;



//---------------- main ----------------


int main(int argc, char *argv[]){
	unsigned int	framestart;
	float			fps = 0, framefps = 0;
	int				divisor;
	bool			done;
	SDL_Event		event;


	//---------------- init the "engine" ----------------
	//initialize SDL
	gfx_init(640,480, false);
	//get keystate array
	keystates = SDL_GetKeyState(0);


	//---------------- load resources (graphics) ----------------
	spr_t[0].init("gfx/t1.bmp");					//tile graphics
	spr_t[1].init("gfx/t2.bmp");
	spr_t[2].init("gfx/t3.bmp", 255, 0, 255);
	spr_t[3].init("gfx/tsloper.bmp", 255, 0, 255);
	spr_t[4].init("gfx/tslopel.bmp", 255, 0, 255);
	spr_t[5].init("gfx/t6.bmp", 255, 0, 255);
	spr_t[6].init("gfx/t7.bmp", 255, 0, 255);
	

	spr_player[0].init("gfx/left2.bmp", 255,0,255);	//player graphics
	spr_player[1].init("gfx/right2.bmp", 255,0,255);

	spr_player2[0].init("gfx/Rleft.bmp", 255,0,255);	//player graphics
	spr_player2[1].init("gfx/Rright.bmp", 255,0,255);

	

	spr_background.init("gfx/bg.bmp");				//background

	font.init("gfx/font0.bmp");						//font



	//---------------- init the game variables ----------------
	tileset[0].type = t_nonsolid;		tileset[0].spr = NULL;
	tileset[1].type = t_solid;			tileset[1].spr = NULL;
	tileset[2].type = t_solid;			tileset[2].spr = &spr_t[0];
	tileset[3].type = t_solid;			tileset[3].spr = &spr_t[1];
	tileset[4].type = t_nonsolid;		tileset[4].spr = &spr_t[2];
	tileset[5].type = t_sloperight;		tileset[5].spr = &spr_t[3];
	tileset[6].type = t_slopeleft;		tileset[6].spr = &spr_t[4];
	tileset[7].type = t_solid;			tileset[7].spr = &spr_t[5];
	tileset[8].type = t_solid;			tileset[8].spr = &spr_t[6];




	//initialize the map, the player has already been initialized by its constructor
	map.loadMap("maps/map01.map");


	
	printf("\nhere comes the game loop...\n") ;
	done = false;

	//---------------- game loop ----------------
	while (!done){
		framestart = SDL_GetTicks();

		//handle messages
		while(SDL_PollEvent(&event)){
			switch(event.type){
				case SDL_QUIT:
					done = true;
				break;

				default:
				break;
			}
		}

		if(keystates[SDLK_ESCAPE])		//quit?
			done = true;




		//---------------- update objects (game logic) ----------------
		player.think();
		player2.think2();

		






		//---------------- draw everything (render the scene) ----------------
		
		int sdx = (scroll_x%spr_background.getWidth());
		int sdy = (scroll_y%spr_background.getHeight());
		spr_background.draw(-sdx, - sdy);
		spr_background.draw(spr_background.getWidth() - sdx, -sdy);
		spr_background.draw(- sdx, spr_background.getHeight()-sdy);
		spr_background.draw(spr_background.getWidth() - sdx, spr_background.getHeight()-sdy);

		
		map.draw();

		player.draw();
		player2.draw();


		
		//the info text
		font.drawf(0,0, "fps: frame/real/lock: %.1f/%.1f/%.1f", framefps, fps, (float)(1000 / WAITTIME));




		//---------------- that's it, now flip the buffers and keep the framerate constant ----------------

		divisor = SDL_GetTicks()-framestart;
		if(divisor != 0)
			framefps = (float)( 1000 / divisor );	//this is the framerate without vsync and the frame break
		else
			fps = 1111.11f;


		SDL_Flip(screen);	//double buffering -> flip buffers, also waits for vsync

		while((SDL_GetTicks()-framestart) < WAITTIME);	//framebreak - keep framerate constant at 1000/WAITTIME fps
		
		divisor = SDL_GetTicks()-framestart;
		if(divisor != 0)
			fps = (float)( 1000 / (SDL_GetTicks()-framestart) );		//this is the framerate with vsync and the framebreak (should be equal to 1000/WAITTIME)
		else
			fps = 1111.11f;
	}

	printf("\n\nthat's all folks :)\n");

	return 0;
}

Recommended Answers

All 16 Replies

Are you using arrays to make data that you can be turned into a map by your program?

no i don't think so, i was doing a tutorial and it didn't really mention but from what i can see it implements a map file, which is premade. I want to edit this map file but i have no idea how as all it comes up with is a linker address map as the sort of file it is. I have tried editing it in a map editior program but it just comes up blank. Im so lost!

It will be much simpler to do it this way:
1. Your map is in a text file and consits of numbers.
2. Your program will load this data into an multi-demisional array.
3. It needs to interpret the numbers as different object. (eg. 0 = nothing, 1 = block)
4. You need to have drawing and updating functions for sprites that you can use each time that sprite appears (no matter where)

Ok so from what you have said it is dealing with this part in the code- however it only specifies x and y as its numbers. would these numbers be stored in the map file?

void CMap::loadMap(const char *file){
	FILE *mapfile;
	int i, j, t;

	mapfile = fopen(file, "rb");

	if(tiles)		//map has already been initialized
		freetiles();


	fread(&width, sizeof(int), 1, mapfile);		//read map width
	fread(&height, sizeof(int), 1, mapfile);	//read map height

	tiles = new int[width*height];				//get memory for the map

	t = 0;	
	for(j = 0; j < width; j++){
		for(i = 0; i < height; i++){
			fread(&tiles[t], sizeof(int), 1, mapfile);	//read tile
			t++;
		}
	}
	fclose(mapfile);

	tiles2d = new int*[height];					//build 2d index array to map data
	for(i=0; i<height; i++){					
		tiles2d[i] = &(tiles[i*width]);			//tiles[i] is a pointer to tile row i
	}

}

void CMap::draw(){
	int x, y;	//screen coord for current tile
	int mx, my;	//current tile map coord
	int sx = 0-(scroll_x%TILESIZE);	//startx
	int smx = (sx+scroll_x)/TILESIZE;	//starty

	
	for( y = 0-(scroll_y%TILESIZE), my = (y+scroll_y)/TILESIZE;  y < 480;  y+=TILESIZE){
		for( x = sx, mx = smx;  x < 640;  x+=TILESIZE){
			if(tileset[ tiles2d[my][mx] ].spr != NULL)
				tileset[ tiles2d[my][mx] ].spr->draw(x,y);
			mx++;
		}
		my++;
	}
}

erm...sorry im not getting your last post? What is the x and y of? or are x and y the values that you will use to make an array for your map?

well if you look in the code the array values are not specified they are just x and y, which makes me believe that these coordinates are specified in the map file(linker address map) that i cannot open or view at all. I could be wrong as im not 100% as to what is happening in the code.

Can you post a link to the tutorial?

Sorry, but the link wasn't much help. I used to use C++ but I gave it up in favour of python a while ago. I suppose that you could take the base ideas and code from that and add in your own functionality.

:( thanks anyways. I really wish i could but ive got a week left to finish the whole game and my tutor didn't bother teaching us any C++ so it really has been a learn what you have to in the time you have class.

your tutor is harsh

i know. Its been really hard. But i guess i will just try and do something else now.

Have you tried opening the file in a simple text editor (notepad)? If the file itself is in binary and you don't have the map editor the writer used to create it, you may be slightly out of luck. But, lucky for you, you're a programmer. You may want to take this as an opportunity to write your own map class and determine how YOU want it to work, rather than just following the tutorial. You can follow the main idea of how this map class works, or write it from scratch, thinking it through as you go.

I'll give you one tip from how I write my 2D stuff, whether or not you care to read further and/or use it is up to you... Draw everything relative to your character's position. If your character is at position x:763 and y:129, draw everything -763 and -129 (values may differ depending on rendering technology used). If you have a tile at x:0 y:0 (left, bottom) and your character has run super far to the right, then it should draw super far off the left side of the screen. If you're really into games, this will also help you get a handle on culling, which is not drawing anything that isn't actually supposed to show up on screen.

yes when i open it is in binary or little squares if that is binary. Hmm i'll try that but i am seriously running out of time.

Yeah, sorry about that. I didn't realize there was a second page when I posted and didn't notice that your stuff was due so soon. Best of luck to you, though. Hopefully you'll get something accomplished by the end of the week.

By the way, if that file shows up as all little squares and/or a random assortment of characters, then yeah, it's unfortunately a binary file.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.