Implement ability for units to attach to collection points.

CorrectiveAction
sigonasr2 1 year ago
parent a32a998061
commit b7ab91a3e8
  1. 3
      olcCodeJam2023Entry/CollectionPoint.h
  2. 2
      olcCodeJam2023Entry/Constant.cpp
  3. 2
      olcCodeJam2023Entry/Constant.h
  4. 1
      olcCodeJam2023Entry/Image.h
  5. 62
      olcCodeJam2023Entry/Unit.cpp
  6. 6
      olcCodeJam2023Entry/Unit.h
  7. 72
      olcCodeJam2023Entry/VirusAttack.cpp
  8. 3
      olcCodeJam2023Entry/VirusAttack.h
  9. BIN
      olcCodeJam2023Entry/assets/memory_collection_point_highlight.png

@ -2,6 +2,8 @@
#include "olcPixelGameEngine.h" #include "olcPixelGameEngine.h"
#include "MemoryType.h" #include "MemoryType.h"
class Unit;
class CollectionPoint{ class CollectionPoint{
public: public:
vf2d pos; vf2d pos;
@ -10,6 +12,7 @@ public:
MemoryType type; MemoryType type;
vf2d randomOffset; vf2d randomOffset;
float rot; float rot;
std::weak_ptr<Unit>attachedUnit;
CollectionPoint(PixelGameEngine*pge,vf2d pos,float rot,Renderable&collectionPointImg,MemoryType type); CollectionPoint(PixelGameEngine*pge,vf2d pos,float rot,Renderable&collectionPointImg,MemoryType type);
void Update(PixelGameEngine*pge,Renderable&matrixImg); void Update(PixelGameEngine*pge,Renderable&matrixImg);
}; };

@ -7,6 +7,8 @@ Pixel CONSTANT::ATKSPD_COLOR={140, 21, 13};
Pixel CONSTANT::MOVESPD_COLOR={11, 135, 212}; Pixel CONSTANT::MOVESPD_COLOR={11, 135, 212};
Pixel CONSTANT::PROCEDURE_COLOR={212, 11, 162}; Pixel CONSTANT::PROCEDURE_COLOR={212, 11, 162};
Pixel CONSTANT::MOVE_LINE_COL={147, 252, 66};
vf2d CONSTANT::UNSELECTED={-99,-99}; vf2d CONSTANT::UNSELECTED={-99,-99};
vi2d CONSTANT::TILE_SIZE={24,24}; vi2d CONSTANT::TILE_SIZE={24,24};

@ -12,6 +12,8 @@ public:
static Pixel MOVESPD_COLOR; static Pixel MOVESPD_COLOR;
static Pixel PROCEDURE_COLOR; static Pixel PROCEDURE_COLOR;
static Pixel MOVE_LINE_COL;
static vf2d UNSELECTED; static vf2d UNSELECTED;
static vi2d TILE_SIZE; static vi2d TILE_SIZE;

@ -31,5 +31,6 @@ enum Image{
RNG_ICON, RNG_ICON,
SPD_ICON, SPD_ICON,
RESOURCE, RESOURCE,
MEMORY_COLLECTION_POINT_HIGHLIGHT,
}; };

@ -186,7 +186,7 @@ void RAMBank::Update(PixelGameEngine*pge,std::map<Sound,std::unique_ptr<Audio>>&
} }
void RAMBank::Draw(TileTransformedView&game,std::map<Image,std::unique_ptr<Renderable>>&IMAGES){ void RAMBank::Draw(TileTransformedView&game,std::map<Image,std::unique_ptr<Renderable>>&IMAGES){
game.DrawRotatedDecal(GetGhostPos(),img.Decal(),0,img.Sprite()->Size()/2,{1,1},friendly?Pixel{192,192,255}:Pixel{255,192,192}); game.DrawRotatedDecal(GetGhostPos(),img.Decal(),0,img.Sprite()->Size()/2,{1,1},GetUnitColor());
if(IsSelected()){ 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); game.DrawRotatedDecal(GetGhostPos(),IMAGES[SELECTION_CIRCLE]->Decal(),0,IMAGES[SELECTION_CIRCLE]->Sprite()->Size()/2,vf2d(img.Sprite()->Size())/IMAGES[SELECTION_CIRCLE]->Sprite()->Size(),WHITE);
} }
@ -270,7 +270,7 @@ void Unit::DrawRangeIndicator(PixelGameEngine*pge,TileTransformedView&game,std::
} }
void Unit::Draw(TileTransformedView&game,std::map<Image,std::unique_ptr<Renderable>>&IMAGES){ void Unit::Draw(TileTransformedView&game,std::map<Image,std::unique_ptr<Renderable>>&IMAGES){
game.DrawRotatedDecal(ghostPos,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},GetUnitColor());
if(IsSelected()){ if(IsSelected()){
game.DrawRotatedDecal(ghostPos,IMAGES[SELECTION_CIRCLE]->Decal(),0,IMAGES[SELECTION_CIRCLE]->Sprite()->Size()/2,vf2d(img.Sprite()->Size())/IMAGES[SELECTION_CIRCLE]->Sprite()->Size(),WHITE); game.DrawRotatedDecal(ghostPos,IMAGES[SELECTION_CIRCLE]->Decal(),0,IMAGES[SELECTION_CIRCLE]->Sprite()->Size()/2,vf2d(img.Sprite()->Size())/IMAGES[SELECTION_CIRCLE]->Sprite()->Size(),WHITE);
} }
@ -338,6 +338,13 @@ void Unit::DrawUnitDamageStats(PixelGameEngine*pge,TileTransformedView&game,std:
lineToTarget.end=lineToTarget.rpoint(lineToTarget.length()-GetUnitSize().x/4); lineToTarget.end=lineToTarget.rpoint(lineToTarget.length()-GetUnitSize().x/4);
util::ApplyMatrixEffect(game.GetPGE(),targetingLine,*IMAGES[TARGETING_LINE],IMAGES[MATRIX]); util::ApplyMatrixEffect(game.GetPGE(),targetingLine,*IMAGES[TARGETING_LINE],IMAGES[MATRIX]);
game.DrawPartialRotatedDecal(lineToTarget.upoint(0.5),targetingLine.Decal(),lineToTarget.vector().polar().y,{lineToTarget.length()/2,12},{lineShift*10,0},{lineToTarget.length(),24},{1,1},targetLineCol); game.DrawPartialRotatedDecal(lineToTarget.upoint(0.5),targetingLine.Decal(),lineToTarget.vector().polar().y,{lineToTarget.length()/2,12},{lineShift*10,0},{lineToTarget.length(),24},{1,1},targetLineCol);
} else
if(targetLoc!=CONSTANT::UNSELECTED){
geom2d::line<float>lineToTarget(pos,targetLoc);
lineToTarget.start=lineToTarget.rpoint(GetUnitSize().x/2);
lineToTarget.end=lineToTarget.rpoint(lineToTarget.length()-GetUnitSize().x/4);
util::ApplyMatrixEffect(game.GetPGE(),targetingLine,*IMAGES[TARGETING_LINE],IMAGES[MATRIX]);
game.DrawPartialRotatedDecal(lineToTarget.upoint(0.5),targetingLine.Decal(),lineToTarget.vector().polar().y,{lineToTarget.length()/2,12},{lineShift*10,0},{lineToTarget.length(),24},{1,0.6},CONSTANT::MOVE_LINE_COL);
} }
if(!appliedTarget.expired()){ if(!appliedTarget.expired()){
geom2d::line<float>lineToTarget(pos,appliedTarget.lock()->pos); geom2d::line<float>lineToTarget(pos,appliedTarget.lock()->pos);
@ -435,6 +442,13 @@ void Unit::_Update(PixelGameEngine*pge,std::map<Sound,std::unique_ptr<Audio>>&SO
float dist=geom2d::line<float>(pos,targetLoc).length(); float dist=geom2d::line<float>(pos,targetLoc).length();
if(dist>24){ if(dist>24){
SetPos(GetPos()+(targetLoc-pos).norm()*GetMoveSpd()*24*pge->GetElapsedTime()); SetPos(GetPos()+(targetLoc-pos).norm()*GetMoveSpd()*24*pge->GetElapsedTime());
} else {
if(willAttachWhenReachingDestination&&!attachTarget.expired()){
attachedPoint=attachTarget;
attachedPoint.lock()->attachedUnit=self_ptr;
}
willAttachWhenReachingDestination=false;
targetLoc=CONSTANT::UNSELECTED;
} }
} }
@ -503,11 +517,13 @@ vf2d Unit::GetUnitSize(){
void Unit::SetTargetUnit(std::weak_ptr<Unit>target){ void Unit::SetTargetUnit(std::weak_ptr<Unit>target){
this->target=target; this->target=target;
this->targetLoc=CONSTANT::UNSELECTED; this->targetLoc=CONSTANT::UNSELECTED;
willAttachWhenReachingDestination=false;
} }
void Unit::SetTargetLocation(vf2d targetLoc){ void Unit::SetTargetLocation(vf2d targetLoc){
this->target.reset(); this->target.reset();
this->targetLoc=targetLoc; this->targetLoc=targetLoc;
willAttachWhenReachingDestination=false;
} }
bool Unit::InRange(std::shared_ptr<Unit>target){ bool Unit::InRange(std::shared_ptr<Unit>target){
@ -617,15 +633,15 @@ vf2d Unit::GetGhostPos(){
} }
bool Unit::IsMoveable(){ bool Unit::IsMoveable(){
return moveable; return moveable&&attachedPoint.expired();
} }
bool Unit::CanInteractWithAllies(){ bool Unit::CanInteractWithAllies(){
return friendlyInteractable; return friendlyInteractable&&attachedPoint.expired();
} }
bool Unit::CanInteractWithEnemies(){ bool Unit::CanInteractWithEnemies(){
return enemyInteractable; return enemyInteractable&&attachedPoint.expired();
} }
Renderable&Unit::GetImage(){ Renderable&Unit::GetImage(){
@ -638,4 +654,40 @@ std::weak_ptr<Unit>Unit::GetCurrentTarget(){
bool Unit::AutoAcquiresFriendlyTargets(){ bool Unit::AutoAcquiresFriendlyTargets(){
return autoAcquireFriendlyTarget; return autoAcquireFriendlyTarget;
}
bool Unit::CanMove(){
return moveSpd.size>0&&attachedPoint.expired();
}
void Unit::SetTargetCollectionPoint(std::weak_ptr<CollectionPoint>targetCP,std::weak_ptr<Unit>self_ptr){
SetTargetLocation(targetCP.lock()->pos);
attachTarget=targetCP;
willAttachWhenReachingDestination=true;
this->self_ptr=self_ptr;
}
Pixel Unit::GetUnitColor(){
Pixel col;
if(!attachedPoint.expired()){
switch(attachedPoint.lock()->type){
case HEALTH:{
return CONSTANT::HEALTH_COLOR/2;
}break;
case RANGE:{
return CONSTANT::RANGE_COLOR/2;
}break;
case ATKSPD:{
return CONSTANT::ATKSPD_COLOR/2;
}break;
case MOVESPD:{
return CONSTANT::MOVESPD_COLOR/2;
}break;
case PROCEDURE:{
return CONSTANT::PROCEDURE_COLOR/2;
}break;
}
} else {
return friendly?Pixel{192,192,255}:Pixel{255,192,192};
}
} }

@ -65,6 +65,9 @@ public:
std::weak_ptr<Unit>GetCurrentTarget(); std::weak_ptr<Unit>GetCurrentTarget();
void DrawUnitDamageStats(PixelGameEngine*pge,TileTransformedView&game,std::map<Image,std::unique_ptr<Renderable>>&IMAGES); void DrawUnitDamageStats(PixelGameEngine*pge,TileTransformedView&game,std::map<Image,std::unique_ptr<Renderable>>&IMAGES);
bool AutoAcquiresFriendlyTargets(); bool AutoAcquiresFriendlyTargets();
bool CanMove();
void SetTargetCollectionPoint(std::weak_ptr<CollectionPoint>targetCP,std::weak_ptr<Unit>self_ptr);
Pixel GetUnitColor();
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++){
@ -121,6 +124,9 @@ private:
float lineShift=0; float lineShift=0;
void ApplyMatrixEffect(Renderable&r); void ApplyMatrixEffect(Renderable&r);
std::weak_ptr<CollectionPoint>attachedPoint; std::weak_ptr<CollectionPoint>attachedPoint;
std::weak_ptr<CollectionPoint>attachTarget;
bool willAttachWhenReachingDestination=false;
std::weak_ptr<Unit>self_ptr;
}; };
struct BasicUnit:Unit{ struct BasicUnit:Unit{

@ -47,6 +47,7 @@ void VirusAttack::InitializeImages(){
LoadImage(RNG_ICON,"assets/rng_icon.png"); LoadImage(RNG_ICON,"assets/rng_icon.png");
LoadImage(SPD_ICON,"assets/spd_icon.png"); LoadImage(SPD_ICON,"assets/spd_icon.png");
LoadImage(RESOURCE,"assets/material.png"); LoadImage(RESOURCE,"assets/material.png");
LoadImage(MEMORY_COLLECTION_POINT_HIGHLIGHT,"assets/memory_collection_point_highlight.png");
} }
bool VirusAttack::OnUserCreate(){ bool VirusAttack::OnUserCreate(){
@ -161,11 +162,25 @@ void VirusAttack::HandleRightClickMove(){
} }
if(!selectedTarget){ if(!selectedTarget){
for(auto&u:units){ for(auto&u:units){
if(u->IsFriendly()&&u->IsSelected()){ if(u->IsFriendly()&&u->IsSelected()&&u->CanMove()){
//First see if we can attach to a collection point.
for(auto&cp:collectionPoints){
geom2d::rect<float>cpRect=geom2d::rect<float>({cp->pos-cp->img.Sprite()->Size()/2,cp->img.Sprite()->Size()});
if(geom2d::overlaps(cpRect,GetWorldMousePos())){
if(cp->attachedUnit.expired()){
u->SetTargetCollectionPoint(cp,u);
goto targetFound; //We found a target, so now we can just leave.
}
}
}
//Okay, nothing to do here. Simply move to the selected position.
u->SetTargetLocation(GetWorldMousePos()); u->SetTargetLocation(GetWorldMousePos());
} }
} }
} }
targetFound:
int a;
} }
} }
@ -311,23 +326,26 @@ void VirusAttack::RenderCollectionPoints(CollectionPoint*cp){
if(geom2d::overlaps(cpRect,viewRegion)){ if(geom2d::overlaps(cpRect,viewRegion)){
Pixel col; Pixel col;
switch(cp->type){ switch(cp->type){
case HEALTH:{ case HEALTH:{
col=CONSTANT::HEALTH_COLOR; col=CONSTANT::HEALTH_COLOR;
}break; }break;
case RANGE:{ case RANGE:{
col=CONSTANT::RANGE_COLOR; col=CONSTANT::RANGE_COLOR;
}break; }break;
case ATKSPD:{ case ATKSPD:{
col=CONSTANT::ATKSPD_COLOR; col=CONSTANT::ATKSPD_COLOR;
}break; }break;
case MOVESPD:{ case MOVESPD:{
col=CONSTANT::MOVESPD_COLOR; col=CONSTANT::MOVESPD_COLOR;
}break; }break;
case PROCEDURE:{ case PROCEDURE:{
col=CONSTANT::PROCEDURE_COLOR; col=CONSTANT::PROCEDURE_COLOR;
}break; }break;
} }
game.DrawRotatedDecal(cp->pos,cp->img.Decal(),cp->rot,cp->img.Sprite()->Size()/2,{1,1},col); game.DrawRotatedDecal(cp->pos,cp->img.Decal(),cp->rot,cp->img.Sprite()->Size()/2,{1,1},col);
if(geom2d::overlaps(cpRect,GetWorldMousePos())){
game.DrawRotatedDecal(cp->pos,IMAGES[MEMORY_COLLECTION_POINT_HIGHLIGHT]->Decal(),cp->rot,cp->img.Sprite()->Size()/2,{1,1},col);
}
} }
} }
@ -416,6 +434,19 @@ bool VirusAttack::OnUserUpdate(float fElapsedTime){
DrawSelectionRectangle(); DrawSelectionRectangle();
RenderFogOfWar(); RenderFogOfWar();
DrawResourceBar();
DrawMinimap();
std::sort(units.begin(),units.end(),[&](auto&u1,auto&u2){
float dist1=geom2d::line<float>(u1->GetGhostPos(),GetWorldMousePos()).length();
float dist2=geom2d::line<float>(u2->GetGhostPos(),GetWorldMousePos()).length();
return dist1>dist2;});
return true;
}
void VirusAttack::DrawResourceBar(){
GradientFillRectDecal({0,0},{float(ScreenWidth()),12.f},BLACK,{VERY_DARK_BLUE.r,VERY_DARK_BLUE.g,VERY_DARK_BLUE.b,128},{VERY_DARK_BLUE.r,VERY_DARK_BLUE.g,VERY_DARK_BLUE.b,128},BLACK); GradientFillRectDecal({0,0},{float(ScreenWidth()),12.f},BLACK,{VERY_DARK_BLUE.r,VERY_DARK_BLUE.g,VERY_DARK_BLUE.b,128},{VERY_DARK_BLUE.r,VERY_DARK_BLUE.g,VERY_DARK_BLUE.b,128},BLACK);
DrawRectDecal({0,0},{float(ScreenWidth()),12.f},{3, 194, 252}); DrawRectDecal({0,0},{float(ScreenWidth()),12.f},{3, 194, 252});
auto DrawResourceDisplay=[&](int index,int resourceValue,Pixel col){ auto DrawResourceDisplay=[&](int index,int resourceValue,Pixel col){
@ -427,15 +458,6 @@ bool VirusAttack::OnUserUpdate(float fElapsedTime){
DrawResourceDisplay(2,player_resources.moveSpd,CONSTANT::MOVESPD_COLOR); DrawResourceDisplay(2,player_resources.moveSpd,CONSTANT::MOVESPD_COLOR);
DrawResourceDisplay(3,player_resources.range,CONSTANT::RANGE_COLOR); DrawResourceDisplay(3,player_resources.range,CONSTANT::RANGE_COLOR);
DrawResourceDisplay(4,player_resources.procedure,CONSTANT::PROCEDURE_COLOR); DrawResourceDisplay(4,player_resources.procedure,CONSTANT::PROCEDURE_COLOR);
DrawMinimap();
std::sort(units.begin(),units.end(),[&](auto&u1,auto&u2){
float dist1=geom2d::line<float>(u1->GetGhostPos(),GetWorldMousePos()).length();
float dist2=geom2d::line<float>(u2->GetGhostPos(),GetWorldMousePos()).length();
return dist1>dist2;});
return true;
} }
void VirusAttack::RenderFogOfWar(){ void VirusAttack::RenderFogOfWar(){

@ -29,7 +29,7 @@ class VirusAttack : public olc::PixelGameEngine
{ {
private: private:
std::vector<std::shared_ptr<Unit>>units; std::vector<std::shared_ptr<Unit>>units;
std::vector<std::unique_ptr<CollectionPoint>>collectionPoints; std::vector<std::shared_ptr<CollectionPoint>>collectionPoints;
std::vector<std::unique_ptr<DeathAnimation>>deathAnimations; std::vector<std::unique_ptr<DeathAnimation>>deathAnimations;
std::vector<DebuffIcon>debuffIcons; std::vector<DebuffIcon>debuffIcons;
@ -63,6 +63,7 @@ private:
void RenderCollectionPoints(CollectionPoint*cp); void RenderCollectionPoints(CollectionPoint*cp);
void RenderFogOfWar(); void RenderFogOfWar();
void InitializeSounds(); void InitializeSounds();
void DrawResourceBar();
public: public:
VirusAttack(); VirusAttack();

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Loading…
Cancel
Save