Fog of War with ghost unit permanenance.
This commit is contained in:
parent
0e5689ad0c
commit
342bb8a5c9
3
olcCodeJam2023Entry/TileManager.cpp
Normal file
3
olcCodeJam2023Entry/TileManager.cpp
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
#include "TileManager.h"
|
||||||
|
|
||||||
|
std::map<vi2d,float> TileManager::visibleTiles;
|
7
olcCodeJam2023Entry/TileManager.h
Normal file
7
olcCodeJam2023Entry/TileManager.h
Normal file
@ -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…
x
Reference in New Issue
Block a user