diff --git a/SmartPointerExample/SmartPointerExample.cpp b/SmartPointerExample/SmartPointerExample.cpp new file mode 100644 index 0000000..b73a6d3 --- /dev/null +++ b/SmartPointerExample/SmartPointerExample.cpp @@ -0,0 +1,188 @@ +#define OLC_PGE_APPLICATION +#include "olcPixelGameEngine.h" + +using namespace olc; + +#define PI 3.14159 + +// Override base class with your custom functionality +class SmartPointerExample : public olc::PixelGameEngine +{ + + struct DamageNumber{ + vf2d pos; + int dmg; + float timer=0; + bool dead=false; + float stopTimer=0; + void Update(SmartPointerExample*pge, float fElapsedTime){ + if(stopTimer>0){ + stopTimer-=fElapsedTime; + } else { + timer-=fElapsedTime; + pos.y-=12*fElapsedTime; + } + if(timer<=0){ + dead=true; + } + } + }; + + std::shared_ptr CreateDamageNumber(vf2d pos,int dmg){ + std::shared_ptr ptr=std::make_shared(pos,dmg,2); + damageNumbers.push_back(ptr); + return ptr; + }; + + struct Object{ + vf2d pos; + Renderable&r; + Pixel col; + float radius; + float dir; + vf2d spd; + bool friendly=false; + bool dead=false; + int health=100; + float invulnTimer=0; + const float friction=100; + std::shared_ptrptrDamageNumber=nullptr; + Object(vf2d pos,Renderable&r,Pixel col,float radius,float dir) + :pos(pos),r(r),col(col),radius(radius),dir(dir){}; + virtual void Collision(SmartPointerExample*pge,Object&collisionObj){}; + void InternalUpdate(SmartPointerExample*pge,float fElapsedTime){ + pos+=spd*fElapsedTime; + pos.x=std::max(0.f,std::min(float(pge->ScreenWidth()),pos.x)); + pos.y=std::max(0.f,std::min(float(pge->ScreenHeight()),pos.y)); + if(spd.x>0){ + spd.x=std::max(0.f,spd.x-friction*fElapsedTime); + } else { + spd.x=std::min(0.f,spd.x+friction*fElapsedTime); + } + if(spd.y>0){ + spd.y=std::max(0.f,spd.y-friction*fElapsedTime); + } else { + spd.y=std::min(0.f,spd.y+friction*fElapsedTime); + } + if(spd.x!=0||spd.y!=0){ + vf2d normSpd = spd.norm(); + dir=atan2(normSpd.y,normSpd.x); + } + if(health<=0){ + dead=true; + } + invulnTimer=std::max(0.f,invulnTimer-fElapsedTime); + } + virtual void Update(SmartPointerExample * pge, float fElapsedTime){} + virtual void Draw(SmartPointerExample*pge){ + pge->DrawRotatedDecal(pos,r.Decal(),dir,r.Sprite()->Size()/2,{1,1},col); + }; + }; + struct Player:Object{ + Player(vf2d pos,Renderable&r,Pixel col,float radius,float dir) + :Object(pos,r,col,radius,dir){ + friendly=true; + } + void Collision(SmartPointerExample*pge,Object&collisionObj)override{ + if(!collisionObj.friendly&&collisionObj.invulnTimer==0){ + collisionObj.health-=10; + collisionObj.invulnTimer=0.5; + if(collisionObj.ptrDamageNumber!=nullptr){ + if(collisionObj.ptrDamageNumber->stopTimer>0||collisionObj.ptrDamageNumber->timer>=1.0){ + collisionObj.ptrDamageNumber->dmg+=10; + collisionObj.ptrDamageNumber->stopTimer=0.5; + } else { + std::shared_ptr ptrDamageNumber = pge->CreateDamageNumber(collisionObj.pos,10); + collisionObj.ptrDamageNumber=ptrDamageNumber; + } + } else { + std::shared_ptr ptrDamageNumber = pge->CreateDamageNumber(collisionObj.pos,10); + collisionObj.ptrDamageNumber=ptrDamageNumber; + } + } + } + void Update(SmartPointerExample*pge,float fElapsedTime)override{ + if(pge->GetKey(UP).bHeld){ + spd.y=-32; + } + if(pge->GetKey(DOWN).bHeld){ + spd.y=32; + } + if(pge->GetKey(RIGHT).bHeld){ + spd.x=32; + } + if(pge->GetKey(LEFT).bHeld){ + spd.x=-32; + } + } + }; + struct Enemy:Object{ + Enemy(vf2d pos,Renderable&r,Pixel col,float radius,float dir) + :Object(pos,r,col,radius,dir){ + friendly=false; + } + }; + + + std::vector>objects; + std::vector>damageNumbers; + +public: + SmartPointerExample() + { + // Name your application + sAppName = "Smart Pointer Example"; + } + + Renderable player_img; + +public: + bool OnUserCreate() override + { + player_img.Load("assets/player.png"); + // Called once at the start, so create things here + objects.push_back(std::make_unique(vf2d{32,32},player_img,GREEN,8,0)); + objects.push_back(std::make_unique(vf2d{64,128},player_img,DARK_RED,8,PI/2)); + objects.push_back(std::make_unique(vf2d{96,164},player_img,DARK_RED,8,1.75*PI)); + objects.push_back(std::make_unique(vf2d{32,196},player_img,DARK_RED,8,1.25*PI)); + objects.push_back(std::make_unique(vf2d{72,220},player_img,DARK_RED,8,PI/8)); + return true; + } + + bool OnUserUpdate(float fElapsedTime) override + { + for(auto&ptrO:objects){ + Object*o=ptrO.get(); + for(auto&ptrO2:objects){ + Object*o2=ptrO2.get(); + if(o!=o2){ + auto dist = [&](vf2d pos1,vf2d pos2){return sqrt(pow(pos1.x-pos2.x,2)+pow(pos1.y-pos2.y,2));}; + if(dist(o->pos,o2->pos)radius+o2->radius){ + o->Collision(this,*o2); + o2->Collision(this,*o); + } + } + } + o->Update(this,fElapsedTime); + o->InternalUpdate(this,fElapsedTime); + o->Draw(this); + } + + for(auto&ptrDamageNumber:damageNumbers){ + ptrDamageNumber->Update(this,fElapsedTime); + DrawStringDecal(ptrDamageNumber->pos,std::to_string(ptrDamageNumber->dmg),RED); + } + + std::erase_if(objects,[&](auto&ptrO){return ptrO->dead;}); + std::erase_if(damageNumbers,[&](auto&ptrDamageNumber){return ptrDamageNumber->dead;}); + return true; + } +}; + +int main() +{ + SmartPointerExample demo; + if (demo.Construct(256, 240, 4, 4)) + demo.Start(); + return 0; +} \ No newline at end of file