#include"SDL/SDL.h" #include"SDL/SDL_ttf.h" #include"SDL/SDL_image.h" #include #include"SDL/SDL_mixer.h" #include #include #include //Dimensions const int SCREEN_WIDTH = 1000; const int SCREEN_HEIGHT = 450; const int BPP = 32; //Screen, event and font SDL_Surface* screen = NULL; SDL_Event event; TTF_Font* font; class projectile; std::vector allProjectiles; //Background camera (allows me to change the position of the background) SDL_Rect backgroundCam = {0, 50, 1000, 500}; //Music Mix_Music* songs[1]; void handleMusic() { static int time = SDL_GetTicks(); static int playing = 0; if( SDL_GetTicks() - time >= 100000 && (!playing) ) { Mix_PlayMusic( songs[1], 0 ); time = SDL_GetTicks(); playing = 1; } if( (SDL_GetTicks() - time >= 18000) && (playing) ) { Mix_PlayMusic( songs[0], 0 ); time = SDL_GetTicks(); playing = 0; } } void blitSurface( int srcX, int srcY, SDL_Surface* source, SDL_Rect* clip = NULL ) { SDL_Rect offsets; offsets.x = srcX; offsets.y = srcY; SDL_BlitSurface( source, clip, screen, &offsets ); } int init( std::string caption ) { if( SDL_Init(SDL_INIT_EVERYTHING) == -1 ) { return -1; } if( Mix_OpenAudio( 22050, MIX_DEFAULT_FORMAT, 2, 4096 ) == -1 ) { return -1; } if( TTF_Init() == -1 ) { return -1; } if( (screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, BPP, SDL_SWSURFACE )) == NULL ) { return -1; } SDL_WM_SetCaption( caption.c_str(), NULL ); return 0; } void clearUp() { TTF_CloseFont( font ); Mix_FreeMusic( songs[0] ); Mix_FreeMusic( songs[1] ); SDL_Quit(); TTF_Quit(); Mix_CloseAudio(); } void clearScreen() { SDL_FillRect( screen, &screen->clip_rect, SDL_MapRGB( screen->format, 255, 255, 255 ) ); } SDL_Surface* loadImage( std::string path ) { SDL_Surface* loadedImage = NULL; SDL_Surface* optimizedImage = NULL; loadedImage = IMG_Load( path.c_str() ); if( loadedImage != NULL ) { optimizedImage = SDL_DisplayFormat( loadedImage ); SDL_FreeSurface( loadedImage ); } if( optimizedImage != NULL ) { Uint32 colorkey = SDL_MapRGB( optimizedImage->format, 255, 0, 255 ); SDL_SetColorKey( optimizedImage, SDL_SRCCOLORKEY, colorkey ); } return optimizedImage; } int checkCollison( SDL_Rect* rect1, SDL_Rect* rect2 ) { if(rect1->y >= rect2->y + rect2->h) return 0; if(rect1->x >= rect2->x + rect2->w) return 0; if(rect1->y + rect1->h <= rect2->y) return 0; if(rect1->x + rect1->w <= rect2->x) return 0; return 1; } void displayTTF( std::string text, int x, int y, int red = 0, int green = 0, int blue = 0 ) { SDL_Color colour = { red, green, blue }; SDL_Surface* temp = TTF_RenderText_Solid( font, text.c_str(), colour ); blitSurface( x, y, temp ); SDL_FreeSurface( temp ); temp = NULL; } void displayTTF( int num, int x, int y, int red = 0, int green = 0, int blue = 0 ) { SDL_Color colour = { red, green, blue }; std::stringstream stream; stream << num; SDL_Surface* temp = TTF_RenderText_Solid( font, stream.str().c_str(), colour ); blitSurface( x, y, temp ); SDL_FreeSurface( temp ); temp = NULL; } class projectile { public: int x, y, w, h, velocity; std::string filePath; SDL_Surface* sprite; projectile( int X, int Y, int VEL, int W, int H, std::string path ): x(X), y(Y), w(W), h(H), velocity(VEL), filePath(path) { sprite = loadImage( path.c_str() ); } projectile( const projectile& proj ) { this->x = proj.x; this->y = proj.y; this->w = proj.w; this->h = proj.h; this->velocity = proj.velocity; this->filePath = proj.filePath; this->sprite = loadImage( filePath.c_str() ); } ~projectile(){ SDL_FreeSurface(sprite); } void show(){ blitSurface( x, y, sprite ); } }; projectile spawnProjectile( int x, int y, int w, int h, int velocity, std::string path ) { projectile proj( x, y, velocity, w, h, path ); return proj; } class player; class enemy { protected: SDL_Surface* spriteSheet; SDL_Rect walk_left[3]; int x, y, w, h, xVel, hitDamage, frame; virtual void setClips(); void handle_animation(); public: enemy( std::string path, int X, int Y, int W, int H, int damage = 5, int VEL = -2 ); ~enemy(); void move(); void show(); void shootBullet(); int getDamage() const { return hitDamage; } SDL_Rect getStats(); }; void enemy::shootBullet() { static int counter = SDL_GetTicks(); if( SDL_GetTicks() - counter >= 1000 ) { allProjectiles.push_back( spawnProjectile( x - 10, y, 10, 10, -3, "Lazer.png" ) ); counter = SDL_GetTicks(); } } SDL_Rect enemy::getStats() { SDL_Rect temp = {x, y, w, h}; return temp; } void enemy::show() { blitSurface( x, y, spriteSheet, &walk_left[frame] ); } void enemy::setClips() { } void enemy::move() { x += xVel; if( x + w < 0 ) { x = SCREEN_WIDTH; y = rand() % SCREEN_HEIGHT; } handle_animation(); } void enemy::handle_animation() { frame = (SDL_GetTicks() / 150) % 3; if( frame > 3 ) { frame = 0; } } enemy::enemy( std::string path, int X, int Y, int W, int H, int damage, int VEL ): x(X), y(Y), w(W), h(H), xVel(VEL), hitDamage(damage), frame(0) { setClips(); spriteSheet = loadImage( path.c_str() ); } enemy::~enemy() { SDL_FreeSurface( spriteSheet ); } class bunny : public enemy { private: void setClips(); public: bunny( std::string path, int X, int Y, int W, int H, int damage, int VEL ): enemy::enemy( path, X, Y, W, H, damage, VEL ) { setClips(); } }; void bunny::setClips() { walk_left[0].x = 0; walk_left[0].y = 0; walk_left[0].w = 39; walk_left[0].h = 44; walk_left[1].x = 43; walk_left[1].y = 2; walk_left[1].w = 39; walk_left[1].h = 44; walk_left[2].x = 87; walk_left[2].y = 5; walk_left[2].w = 39; walk_left[2].h = 44; } bunny createBunny( int x, int y ) { bunny bunny( "Bunny.png", x, y, 39, 44, 5, -1 ); return bunny; } class player { private: int x, y, w, h, yVel; SDL_Surface* sprite; public: void move(); void show(); void handle_events(); player( int X, int Y, int W, int H, std::string path ); ~player(); }; player::player( int X, int Y, int W, int H, std::string path ): x(X), y(W), w(W), h(H), yVel(0) { sprite = loadImage( path.c_str() ); } player::~player() { SDL_FreeSurface( sprite ); } void player::handle_events() { if( event.type == SDL_KEYDOWN ) { switch( event.key.keysym.sym ) { case(SDLK_w): yVel-= 3; break; case(SDLK_s): yVel+= 3; break; } } if( event.type == SDL_KEYUP ) { switch( event.key.keysym.sym ) { case(SDLK_w): yVel+= 3; break; case(SDLK_s): yVel-= 3; break; } } } void player::move() { y += yVel; if( (y + h) > SCREEN_HEIGHT - 10 ) { y -= yVel; backgroundCam.y++; } if( backgroundCam.y + SCREEN_HEIGHT > backgroundCam.h ) { backgroundCam.y--; } if( y < 10 ) { y -= yVel; backgroundCam.y-=2; } if( backgroundCam.y < 0 ) { backgroundCam.y+=2; } } void player::show() { SDL_Rect clip; clip.x = 385; clip.y = 11; blitSurface( x, y, sprite, &clip ); } //THIS DELETES THE REDUNDANT BULLETS void handleProjectiles() { if( !allProjectiles.empty() ) { std::vector::iterator it = allProjectiles.begin(); for( ; it != allProjectiles.end(); it++ ) { it->x += it->velocity; it->show(); if( it->x + it->w < 0 ) { allProjectiles.erase( allProjectiles.begin(), it ); } } } } int main( int argv, char* argc[] ) { //Initialisation stage init( "Space Game!" ); font = TTF_OpenFont( "arial.ttf", 15 ); songs[0] = Mix_LoadMUS( "music.ogg" ); songs[1] = Mix_LoadMUS( "music3.ogg" ); Mix_PlayMusic( songs[0], 0 ); Mix_VolumeMusic( 20 ); //Determines whether the game will run bool quit = false; player player( 50, 0, 153, 36, "Superman.png" ); SDL_Surface* background = loadImage( "Background.JPG" ); bunny bun = createBunny( 800, 20 ); while( !quit ) { //Event handling while( SDL_PollEvent(&event) ) { if( event.type == SDL_QUIT ) { quit = true; } player.handle_events(); } player.move(); bun.move(); //Clears the previous frame clearScreen(); //Rendering //blitSurface( 0, 0, background, &backgroundCam ); player.show(); bun.show(); bun.shootBullet(); handleProjectiles(); SDL_Flip( screen ); SDL_Delay(20); handleMusic(); } SDL_FreeSurface( background ); clearUp(); return 0; }