Fog of War with ghost unit permanenance.

CorrectiveAction
sigonasr2 1 year ago
parent 0e5689ad0c
commit 342bb8a5c9
  1. 3
      olcCodeJam2023Entry/TileManager.cpp
  2. 7
      olcCodeJam2023Entry/TileManager.h
  3. 59
      olcCodeJam2023Entry/Unit.cpp
  4. 17
      olcCodeJam2023Entry/Unit.h
  5. 16
      olcCodeJam2023Entry/VirusAttack.cpp
  6. 1
      olcCodeJam2023Entry/VirusAttack.h
  7. 2
      olcCodeJam2023Entry/olcCodeJam2023Entry.vcxproj
  8. 6
      olcCodeJam2023Entry/olcCodeJam2023Entry.vcxproj.filters

@ -0,0 +1,3 @@
#include "TileManager.h"
std::map<vi2d,float> TileManager::visibleTiles;

@ -0,0 +1,7 @@
#pragma once
#include "olcPixelGameEngine.h"
class TileManager{
public:
static std::map<vi2d,float>visibleTiles;
};

@ -1,6 +1,7 @@
#include "Unit.h" #include "Unit.h"
#include "Constant.h" #include "Constant.h"
#include "olcUTIL_Geometry2D.h" #include "olcUTIL_Geometry2D.h"
#include "TileManager.h"
BasicUnit::BasicUnit(vf2d pos,Renderable&img,bool friendly) BasicUnit::BasicUnit(vf2d pos,Renderable&img,bool friendly)
:Unit({ :Unit({
@ -32,11 +33,12 @@ void BasicUnit2::Attack(Unit&victim){
Unit::Unit(std::vector<Memory>memory,vf2d pos,Renderable&img,bool friendly) Unit::Unit(std::vector<Memory>memory,vf2d pos,Renderable&img,bool friendly)
:pos(pos),img(img),friendly(friendly){ :pos(pos),ghostPos(pos),img(img),friendly(friendly){
int marker=0; int marker=0;
for(Memory&mem:memory){ for(Memory&mem:memory){
for(int i=0;i<mem.size;i++){ for(int i=0;i<mem.size;i++){
this->memory.push_back(true); this->memory.push_back(true);
this->ghostMemory.push_back(true);
} }
switch(mem.type){ switch(mem.type){
case HEALTH:{ case HEALTH:{
@ -67,15 +69,15 @@ Unit::Unit(std::vector<Memory>memory,vf2d pos,Renderable&img,bool friendly)
void Unit::Draw(TileTransformedView&game){ void Unit::Draw(TileTransformedView&game){
game.DrawRotatedDecal(pos,img.Decal(),0,img.Sprite()->Size()/2,{1,1},friendly?Pixel{192,192,255}:Pixel{255,192,192}); game.DrawRotatedDecal(ghostPos,img.Decal(),0,img.Sprite()->Size()/2,{1,1},friendly?Pixel{192,192,255}:Pixel{255,192,192});
if(IsSelected()){ if(IsSelected()){
game.DrawRotatedDecal(pos,CONSTANT::SELECTION_CIRCLE.Decal(),0,CONSTANT::SELECTION_CIRCLE.Sprite()->Size()/2,vf2d(img.Sprite()->Size())/CONSTANT::SELECTION_CIRCLE.Sprite()->Size(),WHITE); game.DrawRotatedDecal(ghostPos,CONSTANT::SELECTION_CIRCLE.Decal(),0,CONSTANT::SELECTION_CIRCLE.Sprite()->Size()/2,vf2d(img.Sprite()->Size())/CONSTANT::SELECTION_CIRCLE.Sprite()->Size(),WHITE);
} }
} }
void Unit::DrawHud(TileTransformedView&game){ void Unit::DrawHud(TileTransformedView&game){
int initialBarX=pos.x-GetMemorySize()/2*CONSTANT::BAR_SQUARE_SIZE.x; int initialBarX=ghostPos.x-GetMemorySize()/2*CONSTANT::BAR_SQUARE_SIZE.x;
int initialBarY=pos.y-CONSTANT::BAR_SQUARE_SIZE.y-img.Sprite()->height/2-2; int initialBarY=ghostPos.y-CONSTANT::BAR_SQUARE_SIZE.y-img.Sprite()->height/2-2;
Pixel col=0; Pixel col=0;
@ -101,7 +103,7 @@ void Unit::DrawHud(TileTransformedView&game){
CheckColor(i,col); CheckColor(i,col);
game.FillRectDecal({float(initialBarX)+i*CONSTANT::BAR_SQUARE_SIZE.x, game.FillRectDecal({float(initialBarX)+i*CONSTANT::BAR_SQUARE_SIZE.x,
float(initialBarY)},CONSTANT::BAR_SQUARE_SIZE,memory[i]?col:col/4); float(initialBarY)},CONSTANT::BAR_SQUARE_SIZE,ghostMemory[i]?col:col/4);
game.DrawRectDecal({float(initialBarX)+i*CONSTANT::BAR_SQUARE_SIZE.x, game.DrawRectDecal({float(initialBarX)+i*CONSTANT::BAR_SQUARE_SIZE.x,
float(initialBarY)},CONSTANT::BAR_SQUARE_SIZE,BLACK); float(initialBarY)},CONSTANT::BAR_SQUARE_SIZE,BLACK);
} }
@ -145,7 +147,7 @@ void Unit::Update(float fElapsedTime){
if(!target.expired()){ if(!target.expired()){
auto ptrTarget=target.lock(); auto ptrTarget=target.lock();
if(!InRange(ptrTarget)){ if(!InRange(ptrTarget)){
pos+=(ptrTarget->GetPos()-pos).norm()*GetMoveSpd()*24*fElapsedTime; SetPos(GetPos()+(ptrTarget->GetPos()-pos).norm()*GetMoveSpd()*24*fElapsedTime);
} else { } else {
//TODO Attack here. //TODO Attack here.
} }
@ -153,10 +155,32 @@ void Unit::Update(float fElapsedTime){
if(targetLoc!=CONSTANT::UNSELECTED){ if(targetLoc!=CONSTANT::UNSELECTED){
float dist=geom2d::line<float>(pos,targetLoc).length(); float dist=geom2d::line<float>(pos,targetLoc).length();
if(dist>24){ if(dist>24){
pos+=(targetLoc-pos).norm()*GetMoveSpd()*24*fElapsedTime; SetPos(GetPos()+(targetLoc-pos).norm()*GetMoveSpd()*24*fElapsedTime);
} }
} }
if(!IsFriendly()){
if(changeDirTimer==0){
changeDirTimer=rand()%30;
switch(rand()%4){
case 0:{
movementVel={16,0};
}break;
case 1:{
movementVel={0,16};
}break;
case 2:{
movementVel={-16,0};
}break;
case 3:{
movementVel={0,-16};
}break;
}
}
SetPos(GetPos()+movementVel*fElapsedTime);
changeDirTimer=std::max(0.f,changeDirTimer-fElapsedTime);
}
reloadTimer=std::max(0.f,reloadTimer-fElapsedTime); reloadTimer=std::max(0.f,reloadTimer-fElapsedTime);
} }
@ -229,6 +253,9 @@ bool Unit::InRange(vf2d pos){
void Unit::SetPos(vf2d newPos){ void Unit::SetPos(vf2d newPos){
pos=newPos; pos=newPos;
if(!InFogOfWar()){
ghostPos=pos;
}
} }
void Unit::AttemptAttack(Unit*unit){ void Unit::AttemptAttack(Unit*unit){
@ -253,4 +280,20 @@ void Unit::AttemptAttack(Unit*unit){
void Unit::_Attack(Unit*finalTarget){ void Unit::_Attack(Unit*finalTarget){
Attack(*finalTarget); Attack(*finalTarget);
reloadTimer=1.f/GetAtkSpd(); reloadTimer=1.f/GetAtkSpd();
}
bool Unit::InFogOfWar(){
return TileManager::visibleTiles.count(GetPos()/96)==0;
}
bool Unit::GhostInFogOfWar(){
return TileManager::visibleTiles.count(ghostPos/96)==0;
}
void Unit::HideGhost(){
ghostPos={99999,-99999};
}
vf2d Unit::GetGhostPos(){
return ghostPos;
} }

@ -32,6 +32,7 @@ public:
int GetProcedure(); int GetProcedure();
int GetMemorySize(); int GetMemorySize();
std::vector<bool>memory; std::vector<bool>memory;
std::vector<bool>ghostMemory;
void Update(float fElapsedTime); void Update(float fElapsedTime);
virtual void Attack(Unit&victim)=0; virtual void Attack(Unit&victim)=0;
virtual void Draw(TileTransformedView&game); virtual void Draw(TileTransformedView&game);
@ -47,13 +48,19 @@ public:
void SetTargetLocation(vf2d targetLoc); void SetTargetLocation(vf2d targetLoc);
void SetPos(vf2d newPos); void SetPos(vf2d newPos);
void AttemptAttack(Unit*unit); void AttemptAttack(Unit*unit);
bool InFogOfWar();
bool GhostInFogOfWar();
void HideGhost();
vf2d GetGhostPos();
std::vector<bool>& operator <<=(const int n){ std::vector<bool>& operator <<=(const int n){
for(int i=0;i<GetMemorySize()-1;i++){ for(int i=0;i<GetMemorySize()-1;i++){
memory[i]=memory[i+1]; memory[i]=memory[i+1];
} }
memory[GetMemorySize()-1]=0; memory[GetMemorySize()-1]=0;
if(!InFogOfWar()){
ghostMemory=memory;
}
return memory; return memory;
} }
@ -62,10 +69,12 @@ public:
memory[i]=memory[i-1]; memory[i]=memory[i-1];
} }
memory[0]=0; memory[0]=0;
if(!InFogOfWar()){
ghostMemory=memory;
}
return memory; return memory;
} }
protected: protected:
vf2d pos;
bool friendly; bool friendly;
Renderable&img; Renderable&img;
Marker health; Marker health;
@ -76,6 +85,8 @@ protected:
std::weak_ptr<Unit>target; std::weak_ptr<Unit>target;
vf2d targetLoc=CONSTANT::UNSELECTED; vf2d targetLoc=CONSTANT::UNSELECTED;
private: private:
vf2d pos;
vf2d ghostPos;
int GetBits(Marker&m); int GetBits(Marker&m);
bool selected=false; bool selected=false;
bool dead=false; bool dead=false;
@ -83,6 +94,8 @@ private:
bool InRange(vf2d pos); bool InRange(vf2d pos);
float reloadTimer=0; float reloadTimer=0;
void _Attack(Unit*finalTarget); void _Attack(Unit*finalTarget);
vf2d movementVel={0,0};
float changeDirTimer=0;
}; };
struct BasicUnit:Unit{ struct BasicUnit:Unit{

@ -2,6 +2,7 @@
#define OLC_SOUNDWAVE #define OLC_SOUNDWAVE
#define OLC_PGEX_TRANSFORMEDVIEW #define OLC_PGEX_TRANSFORMEDVIEW
#include "olcUTIL_Geometry2D.h" #include "olcUTIL_Geometry2D.h"
#include "TileManager.h"
#include "VirusAttack.h" #include "VirusAttack.h"
@ -132,7 +133,7 @@ void VirusAttack::DrawMinimap(){
} }
DrawRect((game.GetWorldOffset()/worldPixelSize*64),viewingTilesPct*64/game.GetWorldScale()); DrawRect((game.GetWorldOffset()/worldPixelSize*64),viewingTilesPct*64/game.GetWorldScale());
for(auto&u:units){ for(auto&u:units){
FillRect(u->GetPos()/worldPixelSize*64,vf2d{2,2}*u->GetUnitSize()/24,u->IsFriendly()?GREEN:RED); FillRect(u->GetGhostPos()/worldPixelSize*64,vf2d{2,2}*u->GetUnitSize()/24,u->IsFriendly()?GREEN:RED);
} }
MINIMAP_OUTLINE.Decal()->Update(); MINIMAP_OUTLINE.Decal()->Update();
SetDrawTarget(nullptr); SetDrawTarget(nullptr);
@ -179,11 +180,11 @@ bool VirusAttack::OnUserUpdate(float fElapsedTime){
HandlePanAndZoom(fElapsedTime); HandlePanAndZoom(fElapsedTime);
HandleMinimapClick(); HandleMinimapClick();
for(auto&tile:visibleTiles){ for(auto&tile:TileManager::visibleTiles){
tile.second-=fElapsedTime; tile.second-=fElapsedTime;
} }
std::erase_if(visibleTiles,[](std::pair<vf2d,float> key){return key.second<=0;}); std::erase_if(TileManager::visibleTiles,[](std::pair<vf2d,float> key){return key.second<=0;});
for(auto&u:units){ for(auto&u:units){
Unit*closestUnit=nullptr; Unit*closestUnit=nullptr;
@ -195,13 +196,18 @@ bool VirusAttack::OnUserUpdate(float fElapsedTime){
if(u->IsFriendly()){ if(u->IsFriendly()){
for(int y=-1;y<2;y++){ for(int y=-1;y<2;y++){
for(int x=-1;x<2;x++){ for(int x=-1;x<2;x++){
visibleTiles[u->GetPos()/24/4+vi2d(x,y)]=5; TileManager::visibleTiles[u->GetPos()/24/4+vi2d(x,y)]=5;
} }
} }
} }
u->AttemptAttack(closestUnit); u->AttemptAttack(closestUnit);
u->Update(fElapsedTime); u->Update(fElapsedTime);
} }
for(auto&u:units){
if(!u->GhostInFogOfWar()&&u->InFogOfWar()){
u->HideGhost();
}
}
game.DrawPartialDecal({0,0},CONSTANT::WORLD_SIZE*CONSTANT::TILE_SIZE,TILE.Decal(),{0,0},CONSTANT::WORLD_SIZE*CONSTANT::TILE_SIZE,DARK_GREEN); game.DrawPartialDecal({0,0},CONSTANT::WORLD_SIZE*CONSTANT::TILE_SIZE,TILE.Decal(),{0,0},CONSTANT::WORLD_SIZE*CONSTANT::TILE_SIZE,DARK_GREEN);
for(auto&u:units){ for(auto&u:units){
@ -214,7 +220,7 @@ bool VirusAttack::OnUserUpdate(float fElapsedTime){
DrawSelectionRectangle(); DrawSelectionRectangle();
for(int y=game.GetTopLeftTile().y/96-1;y<=game.GetBottomRightTile().y/96+1;y++){ 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++){ for(int x=game.GetTopLeftTile().x/96-1;x<=game.GetBottomRightTile().x/96+1;x++){
if(visibleTiles.count(vi2d{x,y})==0){ if(TileManager::visibleTiles.count(vi2d{x,y})==0){
if(x>=0&&y>=0&&x<=CONSTANT::WORLD_SIZE.x*CONSTANT::TILE_SIZE.x&&y<=CONSTANT::WORLD_SIZE.y*CONSTANT::TILE_SIZE.y){ if(x>=0&&y>=0&&x<=CONSTANT::WORLD_SIZE.x*CONSTANT::TILE_SIZE.x&&y<=CONSTANT::WORLD_SIZE.y*CONSTANT::TILE_SIZE.y){
game.FillRectDecal(vf2d{float(x),float(y)}*96,{96,96},{0,0,0,128}); game.FillRectDecal(vf2d{float(x),float(y)}*96,{96,96},{0,0,0,128});
} }

@ -7,7 +7,6 @@ class VirusAttack : public olc::PixelGameEngine
{ {
private: private:
std::vector<std::shared_ptr<Unit>>units; std::vector<std::shared_ptr<Unit>>units;
std::map<vi2d,float>visibleTiles;
Renderable TILE,MINIMAP_HUD,OUTLINE,MINIMAP_OUTLINE; Renderable TILE,MINIMAP_HUD,OUTLINE,MINIMAP_OUTLINE;

@ -142,11 +142,13 @@
<ClInclude Include="olcUTIL_Geometry2D.h" /> <ClInclude Include="olcUTIL_Geometry2D.h" />
<ClInclude Include="resource.h" /> <ClInclude Include="resource.h" />
<ClInclude Include="resource1.h" /> <ClInclude Include="resource1.h" />
<ClInclude Include="TileManager.h" />
<ClInclude Include="Unit.h" /> <ClInclude Include="Unit.h" />
<ClInclude Include="VirusAttack.h" /> <ClInclude Include="VirusAttack.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="Constant.cpp" /> <ClCompile Include="Constant.cpp" />
<ClCompile Include="TileManager.cpp" />
<ClCompile Include="Unit.cpp" /> <ClCompile Include="Unit.cpp" />
<ClCompile Include="VirusAttack.cpp" /> <ClCompile Include="VirusAttack.cpp" />
</ItemGroup> </ItemGroup>

@ -57,6 +57,9 @@
<ClInclude Include="Constant.h"> <ClInclude Include="Constant.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="TileManager.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="VirusAttack.cpp"> <ClCompile Include="VirusAttack.cpp">
@ -68,6 +71,9 @@
<ClCompile Include="Constant.cpp"> <ClCompile Include="Constant.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="TileManager.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ResourceCompile Include="olcCodeJam2023Entry.rc"> <ResourceCompile Include="olcCodeJam2023Entry.rc">

Loading…
Cancel
Save