Add in basic units. RAMBank animation

CorrectiveAction
sigonasr2 1 year ago
parent 74871ca4b5
commit 3126621645
  1. 2
      olcCodeJam2023Entry/Constant.cpp
  2. 2
      olcCodeJam2023Entry/Constant.h
  3. 7
      olcCodeJam2023Entry/Image.h
  4. 3
      olcCodeJam2023Entry/Info.txt
  5. 150
      olcCodeJam2023Entry/Unit.cpp
  6. 48
      olcCodeJam2023Entry/Unit.h
  7. 110
      olcCodeJam2023Entry/VirusAttack.cpp
  8. 2
      olcCodeJam2023Entry/VirusAttack.h
  9. BIN
      olcCodeJam2023Entry/assets/ram_bank.png
  10. BIN
      olcCodeJam2023Entry/assets/shell.png

@ -11,3 +11,5 @@ vf2d CONSTANT::UNSELECTED={-99,-99};
vi2d CONSTANT::TILE_SIZE={24,24};
vi2d CONSTANT::WORLD_SIZE={64,64};
float CONSTANT::SCROLL_BOUNDARY=36;

@ -16,4 +16,6 @@ public:
static vi2d TILE_SIZE;
static vi2d WORLD_SIZE;
static float SCROLL_BOUNDARY;
};

@ -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,
};

@ -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.

@ -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<Image,std::unique_ptr<Renderable>>&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<Image,std::unique_ptr<Renderable>>&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<Image,std::unique_ptr<Renderable>>&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<Image,std::unique_ptr<Renderable>>&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<Image,std::unique_ptr<Renderable>>&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<Image,std::unique_ptr<Renderable>>&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<Image,std::unique_ptr<Renderable>>&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<Image,std::unique_ptr<Renderable>>&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<Image,std::unique_ptr<Renderable>>&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;y<img.Sprite()->height;y++){
for(int x=0;x<img.Sprite()->width;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<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});
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::vector<Memory>memory,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<Image,std::unique_ptr<Renderab
}
void Unit::DrawHud(TileTransformedView&game,std::map<Image,std::unique_ptr<Renderable>>&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<float>(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<bool> 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(){

@ -34,7 +34,7 @@ public:
int GetMemorySize();
std::vector<bool>memory;
std::vector<bool>ghostMemory;
void Update(float fElapsedTime);
virtual void Update(PixelGameEngine*pge);
virtual void Attack(Unit&victim)=0;
virtual void Draw(TileTransformedView&game,std::map<Image,std::unique_ptr<Renderable>>&IMAGES);
virtual void DrawHud(TileTransformedView&game,std::map<Image,std::unique_ptr<Renderable>>&IMAGES);
@ -53,6 +53,7 @@ public:
bool GhostInFogOfWar();
void HideGhost();
vf2d GetGhostPos();
void _Update(PixelGameEngine*pge);
std::vector<bool>& operator <<=(const int n){
for(int i=0;i<GetMemorySize()-1;i++){
@ -100,11 +101,52 @@ private:
};
struct BasicUnit:Unit{
BasicUnit(vf2d pos,Renderable&img,bool friendly=false);
BasicUnit(vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&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<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly=false);
void Attack(Unit&victim)override;
};
struct LeftShifter:Unit{
LeftShifter(vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly=false);
void Attack(Unit&victim)override;
};
struct RightShifter:Unit{
RightShifter(vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly=false);
void Attack(Unit&victim)override;
};
struct BitRestorer:Unit{
BitRestorer(vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly=false);
void Attack(Unit&victim)override;
};
struct MemorySwapper:Unit{
MemorySwapper(vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly=false);
void Attack(Unit&victim)override;
};
struct Corrupter:Unit{
Corrupter(vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly=false);
void Attack(Unit&victim)override;
};
struct MemoryAllocator:Unit{
MemoryAllocator(vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&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<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly=false);
void Update(PixelGameEngine*pge)override;
void Attack(Unit&victim)override;
void Draw(TileTransformedView&game,std::map<Image,std::unique_ptr<Renderable>>&IMAGES)override;
};

@ -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<BasicUnit>(vf2d{32,32},*IMAGES[VIRUS_IMG1],true));
for(int i=0;i<10;i++){
if(rand()%2==0){
units.push_back(std::make_unique<BasicUnit>(vf2d{float(rand()%ScreenWidth()),float(rand()%ScreenHeight())},*IMAGES[VIRUS_IMG1],true));
} else {
units.push_back(std::make_unique<BasicUnit2>(vf2d{float(rand()%ScreenWidth()),float(rand()%ScreenHeight())},*IMAGES[VIRUS_IMG1],false));
}
}
units.push_back(std::make_unique<LeftShifter>(vf2d{128,128},IMAGES,true));
units.push_back(std::make_unique<RightShifter>(vf2d{129,129},IMAGES,true));
units.push_back(std::make_unique<BitRestorer>(vf2d{130,130},IMAGES,true));
units.push_back(std::make_unique<MemorySwapper>(vf2d{131,131},IMAGES,true));
units.push_back(std::make_unique<Corrupter>(vf2d{132,132},IMAGES,true));
units.push_back(std::make_unique<MemoryAllocator>(vf2d{133,133},IMAGES,true));
units.push_back(std::make_unique<RAMBank>(this,vf2d{134,134},IMAGES,true));
for(int i=0;i<5;i++){
collectionPoints.push_back(std::make_unique<CollectionPoint>(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::rect<float>cpRect=geom2d::rect<float>({cp->pos-cp->img.Sprite()->Size()/2,cp->img.Sprite()->Size()});
geom2d::rect<float>viewRegion=geom2d::rect<float>({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::rect<float>cpRect=geom2d::rect<float>({collectionPoint->pos-collectionPoint->img.Sprite()->Size()/2,collectionPoint->img.Sprite()->Size()});
geom2d::rect<float>viewRegion=geom2d::rect<float>({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)

@ -49,6 +49,8 @@ private:
void HandleMinimapClick();
void InitializeImages();
void UpdateMatrixTexture(float fElapsedTime);
void RenderCollectionPoints(CollectionPoint*cp);
void RenderFogOfWar();
public:
VirusAttack();

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Loading…
Cancel
Save