Implement ability for units to attach to collection points.
This commit is contained in:
parent
a32a998061
commit
b7ab91a3e8
@ -2,6 +2,8 @@
|
||||
#include "olcPixelGameEngine.h"
|
||||
#include "MemoryType.h"
|
||||
|
||||
class Unit;
|
||||
|
||||
class CollectionPoint{
|
||||
public:
|
||||
vf2d pos;
|
||||
@ -10,6 +12,7 @@ public:
|
||||
MemoryType type;
|
||||
vf2d randomOffset;
|
||||
float rot;
|
||||
std::weak_ptr<Unit>attachedUnit;
|
||||
CollectionPoint(PixelGameEngine*pge,vf2d pos,float rot,Renderable&collectionPointImg,MemoryType type);
|
||||
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::PROCEDURE_COLOR={212, 11, 162};
|
||||
|
||||
Pixel CONSTANT::MOVE_LINE_COL={147, 252, 66};
|
||||
|
||||
vf2d CONSTANT::UNSELECTED={-99,-99};
|
||||
|
||||
vi2d CONSTANT::TILE_SIZE={24,24};
|
||||
|
@ -12,6 +12,8 @@ public:
|
||||
static Pixel MOVESPD_COLOR;
|
||||
static Pixel PROCEDURE_COLOR;
|
||||
|
||||
static Pixel MOVE_LINE_COL;
|
||||
|
||||
static vf2d UNSELECTED;
|
||||
|
||||
static vi2d TILE_SIZE;
|
||||
|
@ -31,5 +31,6 @@ enum Image{
|
||||
RNG_ICON,
|
||||
SPD_ICON,
|
||||
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){
|
||||
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()){
|
||||
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){
|
||||
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()){
|
||||
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);
|
||||
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);
|
||||
} 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()){
|
||||
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();
|
||||
if(dist>24){
|
||||
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){
|
||||
this->target=target;
|
||||
this->targetLoc=CONSTANT::UNSELECTED;
|
||||
willAttachWhenReachingDestination=false;
|
||||
}
|
||||
|
||||
void Unit::SetTargetLocation(vf2d targetLoc){
|
||||
this->target.reset();
|
||||
this->targetLoc=targetLoc;
|
||||
willAttachWhenReachingDestination=false;
|
||||
}
|
||||
|
||||
bool Unit::InRange(std::shared_ptr<Unit>target){
|
||||
@ -617,15 +633,15 @@ vf2d Unit::GetGhostPos(){
|
||||
}
|
||||
|
||||
bool Unit::IsMoveable(){
|
||||
return moveable;
|
||||
return moveable&&attachedPoint.expired();
|
||||
}
|
||||
|
||||
bool Unit::CanInteractWithAllies(){
|
||||
return friendlyInteractable;
|
||||
return friendlyInteractable&&attachedPoint.expired();
|
||||
}
|
||||
|
||||
bool Unit::CanInteractWithEnemies(){
|
||||
return enemyInteractable;
|
||||
return enemyInteractable&&attachedPoint.expired();
|
||||
}
|
||||
|
||||
Renderable&Unit::GetImage(){
|
||||
@ -639,3 +655,39 @@ std::weak_ptr<Unit>Unit::GetCurrentTarget(){
|
||||
bool Unit::AutoAcquiresFriendlyTargets(){
|
||||
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();
|
||||
void DrawUnitDamageStats(PixelGameEngine*pge,TileTransformedView&game,std::map<Image,std::unique_ptr<Renderable>>&IMAGES);
|
||||
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){
|
||||
for(int i=0;i<GetMemorySize()-1;i++){
|
||||
@ -121,6 +124,9 @@ private:
|
||||
float lineShift=0;
|
||||
void ApplyMatrixEffect(Renderable&r);
|
||||
std::weak_ptr<CollectionPoint>attachedPoint;
|
||||
std::weak_ptr<CollectionPoint>attachTarget;
|
||||
bool willAttachWhenReachingDestination=false;
|
||||
std::weak_ptr<Unit>self_ptr;
|
||||
};
|
||||
|
||||
struct BasicUnit:Unit{
|
||||
|
@ -47,6 +47,7 @@ void VirusAttack::InitializeImages(){
|
||||
LoadImage(RNG_ICON,"assets/rng_icon.png");
|
||||
LoadImage(SPD_ICON,"assets/spd_icon.png");
|
||||
LoadImage(RESOURCE,"assets/material.png");
|
||||
LoadImage(MEMORY_COLLECTION_POINT_HIGHLIGHT,"assets/memory_collection_point_highlight.png");
|
||||
}
|
||||
|
||||
bool VirusAttack::OnUserCreate(){
|
||||
@ -161,11 +162,25 @@ void VirusAttack::HandleRightClickMove(){
|
||||
}
|
||||
if(!selectedTarget){
|
||||
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());
|
||||
}
|
||||
}
|
||||
}
|
||||
targetFound:
|
||||
int a;
|
||||
}
|
||||
}
|
||||
|
||||
@ -328,6 +343,9 @@ void VirusAttack::RenderCollectionPoints(CollectionPoint*cp){
|
||||
}break;
|
||||
}
|
||||
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();
|
||||
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);
|
||||
DrawRectDecal({0,0},{float(ScreenWidth()),12.f},{3, 194, 252});
|
||||
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(3,player_resources.range,CONSTANT::RANGE_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(){
|
||||
|
@ -29,7 +29,7 @@ class VirusAttack : public olc::PixelGameEngine
|
||||
{
|
||||
private:
|
||||
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<DebuffIcon>debuffIcons;
|
||||
|
||||
@ -63,6 +63,7 @@ private:
|
||||
void RenderCollectionPoints(CollectionPoint*cp);
|
||||
void RenderFogOfWar();
|
||||
void InitializeSounds();
|
||||
void DrawResourceBar();
|
||||
|
||||
public:
|
||||
VirusAttack();
|
||||
|
BIN
olcCodeJam2023Entry/assets/memory_collection_point_highlight.png
Normal file
BIN
olcCodeJam2023Entry/assets/memory_collection_point_highlight.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
Loading…
x
Reference in New Issue
Block a user