#define OLC_PGE_APPLICATION #include "olcPixelGameEngine.h" struct Rect{ int x,y,w,h; }; class Enemy{ olc::vf2d pos; Rect*sprite; int health; public: Enemy(olc::vi2d pos,Rect*sprite,int health=1) :pos(pos),sprite(sprite),health(health){}; olc::vf2d GetPos(){ return pos; } olc::vi2d GetSprPos(){ return {sprite->x,sprite->y}; } olc::vi2d GetSprSize(){ return {sprite->w,sprite->h}; } void Hurt(int damage=1){ health-=damage; } bool IsAlive(){ return health>0; } void Move(olc::vi2d moveAmt){ pos+=moveAmt; } olc::Pixel GetColor(){ if(health>1){ return {255,96,96}; } else { return olc::GREEN; } } }; class Player{ olc::vf2d pos; Rect*sprite; float lastShootTime=0; public: Player(olc::vi2d pos,Rect*sprite) :pos(pos),sprite(sprite){} olc::vf2d GetPos(){ return pos; } olc::vi2d GetSprPos(){ return {sprite->x,sprite->y}; } olc::vi2d GetSprSize(){ return {sprite->w,sprite->h}; } void Update(float fElapsedTime){ lastShootTime=std::max(lastShootTime-fElapsedTime,0.f); } bool CanShoot(){ return lastShootTime==0; } void OnShoot(){ lastShootTime=0.5; } void Move(olc::vf2d moveAmt){ pos+=moveAmt; } }; class Bullet{ olc::vf2d pos; bool alive=true; public: Bullet(olc::vi2d pos) :pos(pos){} olc::vf2d GetPos(){ return pos; } void Update(float fElapsedTime){ pos+={0,-72*fElapsedTime}; } bool CollidesWith(Enemy&enemy){ float dist2=pow(enemy.GetPos().x+enemy.GetSprSize().x-pos.x,2)+pow(enemy.GetPos().y+enemy.GetSprSize().y-pos.y,2); return dist2<64; } void KillBullet(){ alive=false; } bool IsAlive(){ return alive||pos.y<0; } }; // Override base class with your custom functionality class ShooterExample : public olc::PixelGameEngine { public: ShooterExample() { // Name your application sAppName = "Shooter Example"; } public: olc::Renderable spriteSheet; Rect enemyA={5,21, 11,9}; Rect enemyB={19,22, 12,6}; Rect enemyC={34,20, 11,8}; Rect ship={35,6, 11,7}; std::vectorenemies; std::vectorbullets; Player player{{ScreenWidth()/2,ScreenHeight()-36},&ship}; int alienShift=0; bool movingRight=true; float lastShiftTime=0; bool OnUserCreate() override { spriteSheet.Load("8-bit Aliens.png"); olc::vf2d alienOffset={24,38}; for (int y=0;y<4;y++){ for (int x=0;x<12;x++){ switch(rand()%3){ case 0:{ Enemy enemy{alienOffset+olc::vi2d{x*16,y*12},&enemyA}; enemies.push_back(enemy); }break; case 1:{ Enemy enemy{alienOffset+olc::vi2d{x*16,y*12},&enemyB}; enemies.push_back(enemy); }break; case 2:{ Enemy enemy{alienOffset+olc::vi2d{x*16,y*12},&enemyC,2}; enemies.push_back(enemy); }break; } } } return true; } bool OnUserUpdate(float fElapsedTime) override { //Update Game Objects player.Update(fElapsedTime); for(Bullet&b:bullets){ b.Update(fElapsedTime); } lastShiftTime+=fElapsedTime; if(lastShiftTime>0.8){ lastShiftTime-=0.8; if(abs(alienShift)>=3){ alienShift+=movingRight?-1:1; movingRight=!movingRight; for(Enemy&e:enemies){ e.Move({0,12}); } } else if(movingRight){ alienShift++; for(Enemy&e:enemies){ e.Move({12,0}); } } else { alienShift--; for(Enemy&e:enemies){ e.Move({-12,0}); } } } if(GetKey(olc::SPACE).bHeld){ if(player.CanShoot()){ player.OnShoot(); bullets.push_back({player.GetPos()+player.GetSprSize()}); } } if(GetKey(olc::LEFT).bHeld){ player.Move({-48*fElapsedTime,0}); } if(GetKey(olc::RIGHT).bHeld){ player.Move({48*fElapsedTime,0}); } // Called once per frame, draws random coloured pixels Clear(olc::BLACK); for(Enemy&e:enemies){ for(Bullet&b:bullets){ if(!b.IsAlive())continue; if(b.CollidesWith(e)){ e.Hurt(); b.KillBullet(); } DrawLineDecal(b.GetPos(),b.GetPos()+olc::vi2d{0,-4},olc::WHITE); } DrawPartialDecal(e.GetPos()+e.GetSprSize()/2,e.GetSprSize(),spriteSheet.Decal(),e.GetSprPos(),e.GetSprSize(),e.GetColor()); } DrawPartialDecal(player.GetPos()+player.GetSprSize()/2,player.GetSprSize(),spriteSheet.Decal(),player.GetSprPos(),player.GetSprSize()); enemies.erase(std::remove_if(enemies.begin(),enemies.end(),[](Enemy&e){return !e.IsAlive();}),enemies.end()); bullets.erase(std::remove_if(bullets.begin(),bullets.end(),[](Bullet&b){return !b.IsAlive();}),bullets.end()); return true; } }; int main() { ShooterExample demo; if (demo.Construct(256, 240, 4, 4)) demo.Start(); return 0; }