You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

220 lines
4.4 KiB

#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::vector<Enemy>enemies;
std::vector<Bullet>bullets;
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;
}