diff --git a/olcCodeJam2023Entry/Constant.cpp b/olcCodeJam2023Entry/Constant.cpp index ffecd6a..75c2481 100644 --- a/olcCodeJam2023Entry/Constant.cpp +++ b/olcCodeJam2023Entry/Constant.cpp @@ -10,4 +10,6 @@ Pixel CONSTANT::PROCEDURE_COLOR={212, 11, 162}; vf2d CONSTANT::UNSELECTED={-99,-99}; vi2d CONSTANT::TILE_SIZE={24,24}; -vi2d CONSTANT::WORLD_SIZE={64,64}; \ No newline at end of file +vi2d CONSTANT::WORLD_SIZE={64,64}; + +float CONSTANT::SCROLL_BOUNDARY=36; \ No newline at end of file diff --git a/olcCodeJam2023Entry/Constant.h b/olcCodeJam2023Entry/Constant.h index 70a14db..aa73b4f 100644 --- a/olcCodeJam2023Entry/Constant.h +++ b/olcCodeJam2023Entry/Constant.h @@ -16,4 +16,6 @@ public: static vi2d TILE_SIZE; static vi2d WORLD_SIZE; + + static float SCROLL_BOUNDARY; }; \ No newline at end of file diff --git a/olcCodeJam2023Entry/Image.h b/olcCodeJam2023Entry/Image.h index 44fceae..c36ec41 100644 --- a/olcCodeJam2023Entry/Image.h +++ b/olcCodeJam2023Entry/Image.h @@ -10,5 +10,12 @@ enum Image{ SELECTION_CIRCLE, MATRIX, MEMORY_COLLECTION_POINT, + LEFT_SHIFTER, + RIGHT_SHIFTER, + BIT_RESTORER, + MEMORY_SWAPPER, + CORRUPTER, + UNIT_ALLOCATOR, + RAM_BANK, }; diff --git a/olcCodeJam2023Entry/Info.txt b/olcCodeJam2023Entry/Info.txt index d2d99e9..f6c70d3 100644 --- a/olcCodeJam2023Entry/Info.txt +++ b/olcCodeJam2023Entry/Info.txt @@ -8,6 +8,9 @@ Corrupter (Randomly destroys bits) Memory Structure (Allocators) RAM Bank (Creates new Memory Structures) has its own rate of creation based on Procedure amount. +Range: 2 Points = 1 Tile (24 pixels) 1 Point = 12 Pixels +Attack Speed: 1/(AtkSpd/2) attacks per second + Range/Attack indicators System has limited resources, both sides fight for resources. diff --git a/olcCodeJam2023Entry/Unit.cpp b/olcCodeJam2023Entry/Unit.cpp index 4910b10..20a258d 100644 --- a/olcCodeJam2023Entry/Unit.cpp +++ b/olcCodeJam2023Entry/Unit.cpp @@ -2,35 +2,153 @@ #include "Constant.h" #include "olcUTIL_Geometry2D.h" #include "TileManager.h" +#include "util.h" -BasicUnit::BasicUnit(vf2d pos,Renderable&img,bool friendly) +BasicUnit::BasicUnit(vf2d pos,std::map>&IMAGES,bool friendly) :Unit({ {HEALTH,4}, {RANGE,2}, {ATKSPD,2}, {MOVESPD,3}, {PROCEDURE,1}, - },pos,img,friendly){} + },pos,*IMAGES[VIRUS_IMG1],friendly){} void BasicUnit::Attack(Unit&victim){ victim<<=1; } -BasicUnit2::BasicUnit2(vf2d pos,Renderable&img,bool friendly) +BasicUnit2::BasicUnit2(vf2d pos,std::map>&IMAGES,bool friendly) :Unit({ {RANGE,2}, {ATKSPD,2}, {MOVESPD,3}, {PROCEDURE,1}, {HEALTH,4}, - },pos,img,friendly){} + },pos,*IMAGES[VIRUS_IMG1],friendly){} void BasicUnit2::Attack(Unit&victim){ } +LeftShifter::LeftShifter(vf2d pos,std::map>&IMAGES,bool friendly) + :Unit({ + {RANGE,2}, + {ATKSPD,2}, + {MOVESPD,3}, + {PROCEDURE,1}, + {HEALTH,4}, + },pos,*IMAGES[LEFT_SHIFTER],friendly){} + +void LeftShifter::Attack(Unit&victim){ + +} + +RightShifter::RightShifter(vf2d pos,std::map>&IMAGES,bool friendly) + :Unit({ + {HEALTH,4}, + {RANGE,2}, + {ATKSPD,2}, + {MOVESPD,3}, + {PROCEDURE,1}, + },pos,*IMAGES[RIGHT_SHIFTER],friendly){} + +void RightShifter::Attack(Unit&victim){ + +} + +BitRestorer::BitRestorer(vf2d pos,std::map>&IMAGES,bool friendly) + :Unit({ + {PROCEDURE,6}, + {RANGE,1}, + {ATKSPD,1}, + {MOVESPD,1}, + {HEALTH,2}, + },pos,*IMAGES[BIT_RESTORER],friendly){} + +void BitRestorer::Attack(Unit&victim){ + +} + +MemorySwapper::MemorySwapper(vf2d pos,std::map>&IMAGES,bool friendly) + :Unit({ + {RANGE,3}, + {ATKSPD,1}, + {HEALTH,3}, + {PROCEDURE,3}, + {MOVESPD,2}, + },pos,*IMAGES[MEMORY_SWAPPER],friendly){} + +void MemorySwapper::Attack(Unit&victim){ +} + +Corrupter::Corrupter(vf2d pos,std::map>&IMAGES,bool friendly) + :Unit({ + {ATKSPD,3}, + {RANGE,1}, + {PROCEDURE,8}, + {MOVESPD,4}, + {HEALTH,4}, + },pos,*IMAGES[CORRUPTER],friendly){} + +void Corrupter::Attack(Unit&victim){ + +} + +MemoryAllocator::MemoryAllocator(vf2d pos,std::map>&IMAGES,bool friendly) + :Unit({ + {RANGE,1}, + {ATKSPD,1}, + {MOVESPD,1}, + {PROCEDURE,1}, + {HEALTH,1}, + },pos,*IMAGES[UNIT_ALLOCATOR],friendly){} + +void MemoryAllocator::Attack(Unit&victim){ + +} + +RAMBank::RAMBank(PixelGameEngine*pge,vf2d pos,std::map>&IMAGES,bool friendly) + :Unit({ + {RANGE,0}, + {ATKSPD,0}, + {MOVESPD,0}, + {PROCEDURE,25}, + {HEALTH,16}, + },pos,*IMAGES[RAM_BANK],friendly),randomOffset({util::random(128),util::random(128)}),matrixImg(*IMAGES[MATRIX]), + originalImg(*IMAGES[RAM_BANK]){ + img.Create(IMAGES[RAM_BANK]->Sprite()->width,IMAGES[RAM_BANK]->Sprite()->height); + pge->SetDrawTarget(img.Sprite()); + pge->Clear(BLANK); + pge->DrawSprite({0,0},IMAGES[RAM_BANK]->Sprite()); + pge->SetDrawTarget(nullptr); +} + +void RAMBank::Attack(Unit&victim){ + +} + +void RAMBank::Update(PixelGameEngine*pge){ + pge->SetDrawTarget(img.Sprite()); + for(int y=0;yheight;y++){ + for(int x=0;xwidth;x++){ + Pixel col = originalImg.Sprite()->GetPixel(x,y); + if(col==WHITE){ + pge->Draw(x,y,matrixImg.Sprite()->GetPixel(int(x+randomOffset.x),int(y+randomOffset.y))); + } + } + } + img.Decal()->Update(); + pge->SetDrawTarget(nullptr); +} + +void RAMBank::Draw(TileTransformedView&game,std::map>&IMAGES){ + game.DrawRotatedDecal(GetGhostPos(),img.Decal(),0,img.Sprite()->Size()/2,{1,1},friendly?Pixel{192,192,255}:Pixel{255,192,192}); + if(IsSelected()){ + game.DrawRotatedDecal(GetGhostPos(),IMAGES[SELECTION_CIRCLE]->Decal(),0,IMAGES[SELECTION_CIRCLE]->Sprite()->Size()/2,vf2d(img.Sprite()->Size())/IMAGES[SELECTION_CIRCLE]->Sprite()->Size(),WHITE); + } +} Unit::Unit(std::vectormemory,vf2d pos,Renderable&img,bool friendly) :pos(pos),ghostPos(pos),img(img),friendly(friendly){ @@ -76,7 +194,7 @@ void Unit::Draw(TileTransformedView&game,std::map>&IMAGES){ - int initialBarX=ghostPos.x-GetMemorySize()/2*CONSTANT::BAR_SQUARE_SIZE.x; + int initialBarX=ghostPos.x-GetMemorySize()/2*CONSTANT::BAR_SQUARE_SIZE.x-CONSTANT::BAR_SQUARE_SIZE.x/2; int initialBarY=ghostPos.y-CONSTANT::BAR_SQUARE_SIZE.y-img.Sprite()->height/2-2; Pixel col=0; @@ -143,11 +261,11 @@ int Unit::GetMemorySize(){ return memory.size(); } -void Unit::Update(float fElapsedTime){ +void Unit::_Update(PixelGameEngine*pge){ if(!target.expired()){ auto ptrTarget=target.lock(); if(!InRange(ptrTarget)){ - SetPos(GetPos()+(ptrTarget->GetPos()-pos).norm()*GetMoveSpd()*24*fElapsedTime); + SetPos(GetPos()+(ptrTarget->GetPos()-pos).norm()*GetMoveSpd()*24*pge->GetElapsedTime()); } else { //TODO Attack here. } @@ -155,7 +273,7 @@ void Unit::Update(float fElapsedTime){ if(targetLoc!=CONSTANT::UNSELECTED){ float dist=geom2d::line(pos,targetLoc).length(); if(dist>24){ - SetPos(GetPos()+(targetLoc-pos).norm()*GetMoveSpd()*24*fElapsedTime); + SetPos(GetPos()+(targetLoc-pos).norm()*GetMoveSpd()*24*pge->GetElapsedTime()); } } @@ -177,11 +295,17 @@ void Unit::Update(float fElapsedTime){ }break; } } - SetPos(GetPos()+movementVel*fElapsedTime); - changeDirTimer=std::max(0.f,changeDirTimer-fElapsedTime); + SetPos(GetPos()+movementVel*pge->GetElapsedTime()); + changeDirTimer=std::max(0.f,changeDirTimer-pge->GetElapsedTime()); + } + + if(!GhostInFogOfWar()&&InFogOfWar()){ + HideGhost(); } - reloadTimer=std::max(0.f,reloadTimer-fElapsedTime); + reloadTimer=std::max(0.f,reloadTimer-pge->GetElapsedTime()); + + Update(pge); } std::vector operator <<(Unit&u,const int n){ @@ -277,9 +401,11 @@ void Unit::AttemptAttack(Unit*unit){ } } +void Unit::Update(PixelGameEngine*pge){} + void Unit::_Attack(Unit*finalTarget){ Attack(*finalTarget); - reloadTimer=1.f/GetAtkSpd(); + reloadTimer=1.f/(GetAtkSpd()/2.f); } bool Unit::InFogOfWar(){ diff --git a/olcCodeJam2023Entry/Unit.h b/olcCodeJam2023Entry/Unit.h index 47b70ed..d5c5c76 100644 --- a/olcCodeJam2023Entry/Unit.h +++ b/olcCodeJam2023Entry/Unit.h @@ -34,7 +34,7 @@ public: int GetMemorySize(); std::vectormemory; std::vectorghostMemory; - void Update(float fElapsedTime); + virtual void Update(PixelGameEngine*pge); virtual void Attack(Unit&victim)=0; virtual void Draw(TileTransformedView&game,std::map>&IMAGES); virtual void DrawHud(TileTransformedView&game,std::map>&IMAGES); @@ -53,6 +53,7 @@ public: bool GhostInFogOfWar(); void HideGhost(); vf2d GetGhostPos(); + void _Update(PixelGameEngine*pge); std::vector& operator <<=(const int n){ for(int i=0;i>&IMAGES,bool friendly=false); void Attack(Unit&victim)override; }; struct BasicUnit2:Unit{ - BasicUnit2(vf2d pos,Renderable&img,bool friendly=false); + BasicUnit2(vf2d pos,std::map>&IMAGES,bool friendly=false); void Attack(Unit&victim)override; +}; + +struct LeftShifter:Unit{ + LeftShifter(vf2d pos,std::map>&IMAGES,bool friendly=false); + void Attack(Unit&victim)override; +}; + +struct RightShifter:Unit{ + RightShifter(vf2d pos,std::map>&IMAGES,bool friendly=false); + void Attack(Unit&victim)override; +}; + +struct BitRestorer:Unit{ + BitRestorer(vf2d pos,std::map>&IMAGES,bool friendly=false); + void Attack(Unit&victim)override; +}; + +struct MemorySwapper:Unit{ + MemorySwapper(vf2d pos,std::map>&IMAGES,bool friendly=false); + void Attack(Unit&victim)override; +}; + +struct Corrupter:Unit{ + Corrupter(vf2d pos,std::map>&IMAGES,bool friendly=false); + void Attack(Unit&victim)override; +}; + +struct MemoryAllocator:Unit{ + MemoryAllocator(vf2d pos,std::map>&IMAGES,bool friendly=false); + void Attack(Unit&victim)override; +}; + +struct RAMBank:Unit{ + vf2d randomOffset; + Renderable img; + Renderable&originalImg; + Renderable&matrixImg; + RAMBank(PixelGameEngine*pge,vf2d pos,std::map>&IMAGES,bool friendly=false); + void Update(PixelGameEngine*pge)override; + void Attack(Unit&victim)override; + void Draw(TileTransformedView&game,std::map>&IMAGES)override; }; \ No newline at end of file diff --git a/olcCodeJam2023Entry/VirusAttack.cpp b/olcCodeJam2023Entry/VirusAttack.cpp index 774c9ae..46d1e95 100644 --- a/olcCodeJam2023Entry/VirusAttack.cpp +++ b/olcCodeJam2023Entry/VirusAttack.cpp @@ -24,6 +24,13 @@ void VirusAttack::InitializeImages(){ LoadImage(VIRUS_IMG1,"assets/unit.png"); LoadImage(SELECTION_CIRCLE,"assets/selection_circle.png"); LoadImage(MEMORY_COLLECTION_POINT,"assets/memory_collection_point.png"); + LoadImage(LEFT_SHIFTER,"assets/left_shifter.png"); + LoadImage(RIGHT_SHIFTER,"assets/right_shifter.png"); + LoadImage(BIT_RESTORER,"assets/bit_restorer.png"); + LoadImage(MEMORY_SWAPPER,"assets/memory_swapper.png"); + LoadImage(CORRUPTER,"assets/corrupter.png"); + LoadImage(UNIT_ALLOCATOR,"assets/shell.png"); + LoadImage(RAM_BANK,"assets/ram_bank.png"); } bool VirusAttack::OnUserCreate(){ @@ -40,14 +47,14 @@ bool VirusAttack::OnUserCreate(){ IMAGES[MATRIX]->Create(64,64,false,false); IMAGES[MATRIX]->Sprite()->SetSampleMode(Sprite::PERIODIC); - units.push_back(std::make_unique(vf2d{32,32},*IMAGES[VIRUS_IMG1],true)); - for(int i=0;i<10;i++){ - if(rand()%2==0){ - units.push_back(std::make_unique(vf2d{float(rand()%ScreenWidth()),float(rand()%ScreenHeight())},*IMAGES[VIRUS_IMG1],true)); - } else { - units.push_back(std::make_unique(vf2d{float(rand()%ScreenWidth()),float(rand()%ScreenHeight())},*IMAGES[VIRUS_IMG1],false)); - } - } + units.push_back(std::make_unique(vf2d{128,128},IMAGES,true)); + units.push_back(std::make_unique(vf2d{129,129},IMAGES,true)); + units.push_back(std::make_unique(vf2d{130,130},IMAGES,true)); + units.push_back(std::make_unique(vf2d{131,131},IMAGES,true)); + units.push_back(std::make_unique(vf2d{132,132},IMAGES,true)); + units.push_back(std::make_unique(vf2d{133,133},IMAGES,true)); + units.push_back(std::make_unique(this,vf2d{134,134},IMAGES,true)); + for(int i=0;i<5;i++){ collectionPoints.push_back(std::make_unique(this,vf2d{32.f+48*i,32.f},0,*IMAGES[MEMORY_COLLECTION_POINT],MemoryType(i))); @@ -161,16 +168,16 @@ void VirusAttack::DrawMinimap(){ void VirusAttack::HandlePanAndZoom(float fElapsedTime){ float speedScale=std::min(1.f,game.GetWorldScale().x); - if(GetKey(A).bHeld){ + if(GetKey(A).bHeld/*||GetMouseX()<=CONSTANT::SCROLL_BOUNDARY*/){ game.MoveWorldOffset(vf2d{-256*fElapsedTime,0}/speedScale); } - if(GetKey(W).bHeld){ + if(GetKey(W).bHeld/*||GetMouseY()<=CONSTANT::SCROLL_BOUNDARY*/){ game.MoveWorldOffset(vf2d{0,-256*fElapsedTime}/speedScale); } - if(GetKey(S).bHeld){ + if(GetKey(S).bHeld/*||GetMouseY()>=ScreenHeight()-CONSTANT::SCROLL_BOUNDARY*/){ game.MoveWorldOffset(vf2d{0,256*fElapsedTime}/speedScale); } - if(GetKey(D).bHeld){ + if(GetKey(D).bHeld/*||GetMouseX()>=ScreenWidth()-CONSTANT::SCROLL_BOUNDARY*/){ game.MoveWorldOffset(vf2d{256*fElapsedTime,0}/speedScale); } @@ -179,11 +186,11 @@ void VirusAttack::HandlePanAndZoom(float fElapsedTime){ game.ZoomAtScreenPos(1.25,GetMousePos()); } } else - if(GetMouseWheel()<0){ - if(game.GetWorldScale().x>0.5){ - game.ZoomAtScreenPos(0.75,GetMousePos()); - } + if(GetMouseWheel()<0){ + if(game.GetWorldScale().x>0.5){ + game.ZoomAtScreenPos(0.75,GetMousePos()); } + } } void VirusAttack::HandleMinimapClick(){ @@ -244,6 +251,32 @@ void VirusAttack::UpdateMatrixTexture(float fElapsedTime){ std::erase_if(activeLetters,[](Letter&letter){return letter.pos.y<-32;}); } +void VirusAttack::RenderCollectionPoints(CollectionPoint*cp){ + geom2d::rectcpRect=geom2d::rect({cp->pos-cp->img.Sprite()->Size()/2,cp->img.Sprite()->Size()}); + geom2d::rectviewRegion=geom2d::rect({game.GetWorldTL(),game.GetWorldVisibleArea()}); + if(geom2d::overlaps(cpRect,viewRegion)){ + Pixel col; + switch(cp->type){ + case HEALTH:{ + col=CONSTANT::HEALTH_COLOR; + }break; + case RANGE:{ + col=CONSTANT::RANGE_COLOR; + }break; + case ATKSPD:{ + col=CONSTANT::ATKSPD_COLOR; + }break; + case MOVESPD:{ + col=CONSTANT::MOVESPD_COLOR; + }break; + case PROCEDURE:{ + col=CONSTANT::PROCEDURE_COLOR; + }break; + } + game.DrawRotatedDecal(cp->pos,cp->img.Decal(),cp->rot,cp->img.Sprite()->Size()/2,{1,1},col); + } +} + bool VirusAttack::OnUserUpdate(float fElapsedTime){ UpdateMatrixTexture(fElapsedTime); HandleDraggingSelection(); @@ -272,12 +305,7 @@ bool VirusAttack::OnUserUpdate(float fElapsedTime){ } } u->AttemptAttack(closestUnit); - u->Update(fElapsedTime); - } - for(auto&u:units){ - if(!u->GhostInFogOfWar()&&u->InFogOfWar()){ - u->HideGhost(); - } + u->_Update(this); } game.DrawPartialDecal({0,0},CONSTANT::WORLD_SIZE*CONSTANT::TILE_SIZE,IMAGES[TILE]->Decal(),{0,0},CONSTANT::WORLD_SIZE*CONSTANT::TILE_SIZE,DARK_GREEN); @@ -287,29 +315,7 @@ bool VirusAttack::OnUserUpdate(float fElapsedTime){ for(auto&collectionPoint:collectionPoints){ collectionPoint->Update(this,*IMAGES[MATRIX]); - geom2d::rectcpRect=geom2d::rect({collectionPoint->pos-collectionPoint->img.Sprite()->Size()/2,collectionPoint->img.Sprite()->Size()}); - geom2d::rectviewRegion=geom2d::rect({game.GetWorldTL(),game.GetWorldVisibleArea()}); - if(geom2d::overlaps(cpRect,viewRegion)){ - Pixel col; - switch(collectionPoint->type){ - case HEALTH:{ - col=CONSTANT::HEALTH_COLOR; - }break; - case RANGE:{ - col=CONSTANT::RANGE_COLOR; - }break; - case ATKSPD:{ - col=CONSTANT::ATKSPD_COLOR; - }break; - case MOVESPD:{ - col=CONSTANT::MOVESPD_COLOR; - }break; - case PROCEDURE:{ - col=CONSTANT::PROCEDURE_COLOR; - }break; - } - game.DrawRotatedDecal(collectionPoint->pos,collectionPoint->img.Decal(),collectionPoint->rot,collectionPoint->img.Sprite()->Size()/2,{1,1},col); - } + RenderCollectionPoints(collectionPoint.get()); } for(auto&u:units){ @@ -317,6 +323,14 @@ bool VirusAttack::OnUserUpdate(float fElapsedTime){ } DrawSelectionRectangle(); + RenderFogOfWar(); + + DrawMinimap(); + + return true; +} + +void VirusAttack::RenderFogOfWar(){ for(int y=game.GetTopLeftTile().y/96-1;y<=game.GetBottomRightTile().y/96+1;y++){ for(int x=game.GetTopLeftTile().x/96-1;x<=game.GetBottomRightTile().x/96+1;x++){ if(TileManager::visibleTiles.count(vi2d{x,y})==0){ @@ -326,12 +340,6 @@ bool VirusAttack::OnUserUpdate(float fElapsedTime){ } } } - - DrawMinimap(); - - DrawDecal({0,0},IMAGES[MATRIX]->Decal(),{1,1},{128,0,128}); - - return true; } VirusAttack::CollectionPoint::CollectionPoint(PixelGameEngine*pge,vf2d pos,float rot,Renderable&collectionPointImg,MemoryType type) diff --git a/olcCodeJam2023Entry/VirusAttack.h b/olcCodeJam2023Entry/VirusAttack.h index 22fe37f..fa315ae 100644 --- a/olcCodeJam2023Entry/VirusAttack.h +++ b/olcCodeJam2023Entry/VirusAttack.h @@ -49,6 +49,8 @@ private: void HandleMinimapClick(); void InitializeImages(); void UpdateMatrixTexture(float fElapsedTime); + void RenderCollectionPoints(CollectionPoint*cp); + void RenderFogOfWar(); public: VirusAttack(); diff --git a/olcCodeJam2023Entry/assets/ram_bank.png b/olcCodeJam2023Entry/assets/ram_bank.png new file mode 100644 index 0000000..c5deb58 Binary files /dev/null and b/olcCodeJam2023Entry/assets/ram_bank.png differ diff --git a/olcCodeJam2023Entry/assets/shell.png b/olcCodeJam2023Entry/assets/shell.png new file mode 100644 index 0000000..b5b9266 Binary files /dev/null and b/olcCodeJam2023Entry/assets/shell.png differ