武器装备

嗨,我想给我的小精灵一些武器-一个枪和另一把剑,但是我不知道我在做什么,有人可以帮我做这个吗?我已经包括了我的main.cpp,player.cpp和player.h(如果有帮助的话。),我使用视觉c ++和SDL并尝试制作马里奥式游戏。

/*
  player.cpp
   CPlayer
*/

#include "global.h"



CPlayer::CPlayer(){
	x		= 50;			//start coordinates
	y		= 1500;

	h		= PLAYERHEIGHT;	//save player height and width
	w		= PLAYERWIDTH;

	velx	= 0;			//speed
	vely	= 0;


	lockjump = true;		//player may jump
	faceright = true;		//player looks right
	jumping = false;

	slope_prevtilex = (x + (w>>1)) / TILESIZE;
	slope_prevtiley = (y + h) / TILESIZE;
}

void CPlayer::unlockjump(){		//this function is called if the player hits the ground
	//this if is quite tricky:
	//the player may jump again:
	//a) if he fell of an edge (!jumping) - without releasing the jump key on the ground
	//b) if he jumped - only when he releases the jump key on the ground
	if(!jumping || !keystates[SDLK_RSHIFT]){
		lockjump = false;
		jumping = false;
	}
}

void CPlayer::draw(){
	
	if(faceright)
		spr_player[1].draw((x-4) - scroll_x, (y-2) - scroll_y);
	else
		spr_player[0].draw((x-17) - scroll_x, (y-2) - scroll_y);
}

bool CPlayer::collision_hor_down(int x, int y, int &tilecoordy){
	int tilexpixels = x-(x%TILESIZE);	//calculate the x position (pixels!) of the tiles we check against
	int testend = x + w;		//calculate the end of testing (just to save the x+w calculation each for loop)

	tilecoordy = y/TILESIZE;			//calculate the y position (map coordinates!) of the tiles we want to test

	int tilecoordx = tilexpixels/TILESIZE;	//calculate map x coordinate for first tile


	//loop while the start point (pixels!) of the test tile is inside the players bounding box
	while(tilexpixels <= testend){
		if(map.map(tilecoordx, tilecoordy) == t_solid)	//is a solid tile is found at tilecoordx, tilecoordy?
			return true;	

		tilecoordx++;		//increase tile x map coordinate
		tilexpixels+=TILESIZE;	//increase tile x pixel coordinate
	}

	return false;
}


bool CPlayer::collision_hor_up(int x, int y, int &tilecoordy){
	int tilexpixels = x-(x%TILESIZE);
	int testend = x + w;

	tilecoordy = y/TILESIZE;

	int tilecoordx = tilexpixels/TILESIZE;


	while(tilexpixels <= testend){
		if(map.map(tilecoordx, tilecoordy) != t_nonsolid) //only this changed: when jumping (moving up) we don't want to go through slopes
			return true;	

		tilecoordx++;
		tilexpixels+=TILESIZE;
	}
	return false;
}

//for explanation see CPlayer::collision_hor()
bool CPlayer::collision_ver(int x, int y, int &tilecoordx){
	int tileypixels = y-(y%TILESIZE);
	int testend = y + h;

	tilecoordx = x/TILESIZE;

	int tilecoordy = tileypixels/TILESIZE;

	while(tileypixels <= testend){
		if(map.map(tilecoordx, tilecoordy) == t_solid)
			return true;

		tilecoordy++;
		tileypixels += TILESIZE;
	}

	return false;
}



bool CPlayer::collision_slope(int sx, int sy, int &tsx, int &tsy){	
	tsx = sx / TILESIZE;	//map coordinates of the tile we check against
	tsy = sy / TILESIZE;

	TileType t = map.map(tsx, tsy);
	
	//if we found a slope we set align y to the slope.
	//take a look at jnrdev #2, why it's calculated this way
	if(t == t_sloperight){
		//sloperight -> \  
		y =  (tsy+1)*TILESIZE - (TILESIZE - (sx%TILESIZE))  - h - 1;
		return true;;
	}
	else if(t == t_slopeleft){
		//slopeleft -> /
		y =  (tsy+1)*TILESIZE - sx%TILESIZE  - h - 1 ;
		return true;
	}
	
	return false;
}

void CPlayer::collision_detection_map(){
	//check for slopes (only if moving down)
	if(vely > 0){
		int tsx, tsy;				//slope tile coordinates
		int sx = x + (w>>1) + velx;	//slope chechpoint x coordinate


		if(collision_slope(sx, (y + h), tsx, tsy) ){	//we entered a slope (y is set by collision_slope)
			x += velx;	//move on
			//y has been set by collision_slope
			
			unlockjump();	//we hit the ground - the player may jump again

			vely = 1;		//test against the ground again in the next frame


			slope_prevtilex = tsx;	//save slope koordinate
			slope_prevtiley = tsy;

			return;
		}
		else{				//we're not on a slope this frame - check if we left a slope
			//-1 ... we didn't move from slope to slope
			//0 ... we left a slope after moving down
			//1 ... we left a slope after moving up
			int what = -1;

			if(map.map(slope_prevtilex, slope_prevtiley) == t_sloperight){
				if(velx > 0)	//sloperight + velx > 0  = we left a slope after moving up the slope
					what = 0;
				else
					what = 1;	//we left after moving down the slope
			}
			else if(map.map(slope_prevtilex, slope_prevtiley) == t_slopeleft){
				if(velx < 0)	//sloperight + velx > 0  = we left a slope after moving up the slope
					what = 0;
				else
					what = 1;	//we left after moving down the slope
			}

			if(what != -1){		//if we left a slope and now are on a slope
				int sy;

				if(what == 1){
					y =  tsy*TILESIZE - h -1;		//move y to top of the slope tile
					sy = y + h;
				}
				else{
					y =  (tsy+1)*TILESIZE - h -1;	//move y to the bottom of the slope tile
					sy = y + h + TILESIZE;			//test one tile lower than the bottom of the slope (to test if we move down a long slope)
													//it's physically incorrect, but looks a lot smoother ingame
				}

				
				//check for slopes on new position
				if( collision_slope(sx, sy, tsx, tsy) ){	//slope on new pos (entered a slope after we left a slope)
															//-> we moved from slope to slope
					x += velx;

					unlockjump();

					vely = 1;

					slope_prevtilex = tsx;
					slope_prevtiley = tsy;

					return;
				}
			}	
		}
	}



	//no slope collisions were found -> check for collisions with the map
	int tilecoord;

	//x axis first (--)
	if(velx > 0){		//moving right
		if(collision_ver(x+velx+w, y, tilecoord))	//collision on the right side.
			x = tilecoord*TILESIZE -w-1;			//move to the edge of the tile (tile on the right -> mind the player width)
		else			//no collision
			x += velx;
	}		 
	else if(velx < 0){	//moving left
		if(collision_ver(x+velx, y, tilecoord))		//collision on the left side
			x = (tilecoord+1)*TILESIZE +1;			//move to the edge of the tile
		else
			x += velx;
	}
	

	//then y axis (|)
	if(vely < 0){	//moving up
		if(collision_hor_up(x, y+vely, tilecoord)){
			y		= (tilecoord+1)*TILESIZE +1;
			vely	= 0;
		}
		else{
			y		+= vely;
			vely	+=GRAVITATION;
		}
	}		 
	else{		//moving down / on ground
		//printf("test: down, vely:%d\n", vely);
		if(collision_hor_down(x, y+vely+h, tilecoord)){	//on ground
			y		= tilecoord*TILESIZE -h-1;
			vely	= 1;				//1 so we test against the ground again int the next frame (0 would test against the ground in the next+1 frame)

			unlockjump();
		}
		else{	//falling (in air)
			y		+= vely;
			vely	+= GRAVITATION;

			if(vely >= TILESIZE)		//if the speed is higher than this we might fall through a tile
				vely = TILESIZE;

			lockjump = true;			//don't allow jumping after falling of an edge
		}
	}


	slope_prevtilex = (x + (w>>1)) / TILESIZE;
	slope_prevtiley = (y + h) / TILESIZE;
}



void CPlayer::think(){
	velx=0;	//don't move left / right by default

	if(keystates[SDLK_RIGHT]){
		velx = VELMOVING;		//move right
		faceright = true;		//player graphic is facing right
	}
	if(keystates[SDLK_LEFT]){
		velx = -VELMOVING;		//move left
		faceright = false;		//player graphic is facing left
	}
	if(keystates[SDLK_UP] && !lockjump){	//if the player isn't jumping already
		vely = -VELJUMP;		//jump!
		lockjump = true;		//player is not allowed to jump anymore
		jumping = true;
	}

	
	collision_detection_map();


	//now that we have our new position it's time to update the scrolling position
	scroll_x = x - 270;
	scroll_y = y - 260;

	map.limit_scroll();
}

void CPlayer::think2(){
	velx=0;	//don't move left / right by default

	if(keystates[SDLK_d]){
		velx = VELMOVING;		//move right
		faceright = true;		//player graphic is facing right
	}
	if(keystates[SDLK_a]){
		velx = -VELMOVING;		//move left
		faceright = false;		//player graphic is facing left
	}
	if(keystates[SDLK_w] && !lockjump){	//if the player isn't jumping already
		vely = -VELJUMP;		//jump!
		lockjump = true;		//player is not allowed to jump anymore
		jumping = true;
	}

	

	collision_detection_map();


	//now that we have our new position it's time to update the scrolling position
	scroll_x = x - 270;
	scroll_y = y - 260;

	map.limit_scroll();
}
/*
  player.h
   CPlayer
*/


class CPlayer{
	public:
		void think();			//handle input, collision detection, ...
		void draw();
		void think2();			//handle input, collision detection, ...
		void draw2();

		CPlayer();

	
	private:
		int x, y;			//x, y coordinate (top left of the player rectangle)
		int x2, y2;
		int h, w;			//height, width
		int velx, vely;		//velocity on x, y axis
		
		bool faceright;		//player facing right? -> graphics

		bool lockjump;		//may the player jump
		bool jumping;
		
		int slope_prevtilex;//the tile at slopex, slopey in the last frame
		int slope_prevtiley;



		void collision_detection_map();								//does the whole collision detection

		bool collision_ver(int x, int y, int &tilecoordx);			//tests for collision with a tile on the vertikal line from [x,y] to [x,y+height]
		bool collision_hor_up(int x, int y, int &tilecoordy);		//horizontal line from [x,y] to [x+width, y]
		bool collision_hor_down(int x, int y, int &tilecoordy);		//same as hor_up, but we don't want to go through slopes here
		
		bool collision_slope(int sx, int sy, int &tsx, int &tsy);	//test for collisions against a slope at sx, sy - if a slope is found y is set accordingly

		
		void unlockjump();											//the player may jump again if the conditions in this function are true
};
//---------------- 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;
	}

	return 0;
}