Added target line indicators.

CorrectiveAction
sigonasr2 1 year ago
parent d393e0331b
commit 18e8a02579
  1. 6
      olcCodeJam2023Entry/Constant.cpp
  2. 5
      olcCodeJam2023Entry/Constant.h
  3. 2
      olcCodeJam2023Entry/Image.h
  4. 11
      olcCodeJam2023Entry/Info.txt
  5. 5
      olcCodeJam2023Entry/Sound.h
  6. 118
      olcCodeJam2023Entry/Unit.cpp
  7. 51
      olcCodeJam2023Entry/Unit.h
  8. 69
      olcCodeJam2023Entry/VirusAttack.cpp
  9. 3
      olcCodeJam2023Entry/VirusAttack.h
  10. BIN
      olcCodeJam2023Entry/assets/attackLine.png
  11. BIN
      olcCodeJam2023Entry/assets/targetLine.png
  12. 1
      olcCodeJam2023Entry/olcCodeJam2023Entry.vcxproj
  13. 3
      olcCodeJam2023Entry/olcCodeJam2023Entry.vcxproj.filters
  14. 6
      olcCodeJam2023Entry/olcPGEX_AudioListener.h
  15. 14
      olcCodeJam2023Entry/olcPGEX_AudioSource.h
  16. BIN
      olcCodeJam2023Entry/pge.data
  17. 36
      olcCodeJam2023Entry/pge.js
  18. BIN
      olcCodeJam2023Entry/pge.wasm
  19. 17
      olcCodeJam2023Entry/util.cpp
  20. 2
      olcCodeJam2023Entry/util.h

@ -15,3 +15,9 @@ vi2d CONSTANT::WORLD_SIZE={64,64};
float CONSTANT::SCROLL_BOUNDARY=36; float CONSTANT::SCROLL_BOUNDARY=36;
float CONSTANT::DEATH_FADE_TIME=1; float CONSTANT::DEATH_FADE_TIME=1;
Pixel CONSTANT::ATTACKER_TARGET_COL={196, 101, 0, 196};
Pixel CONSTANT::ATTACKER_ATTACK_COL={171, 0, 0, 220};
Pixel CONSTANT::HEALER_TARGET_COL={0, 134, 230, 196};
Pixel CONSTANT::HEALER_ATTACK_COL={91, 222, 104, 220};

@ -20,4 +20,9 @@ public:
static float SCROLL_BOUNDARY; static float SCROLL_BOUNDARY;
static float DEATH_FADE_TIME; static float DEATH_FADE_TIME;
static Pixel ATTACKER_TARGET_COL;
static Pixel ATTACKER_ATTACK_COL;
static Pixel HEALER_TARGET_COL;
static Pixel HEALER_ATTACK_COL;
}; };

@ -24,5 +24,7 @@ enum Image{
PRC, PRC,
RNG, RNG,
SPD, SPD,
TARGETING_LINE,
ATTACKING_LINE,
}; };

@ -23,7 +23,16 @@ Player build Memory Allocators using Resources.
(HEALTH,RANGE,ATKSPD,MOVESPD,PROCEDURE) (HEALTH,RANGE,ATKSPD,MOVESPD,PROCEDURE)
Memory Allocator costs 1/1/1/1/1. Memory Allocator costs 1/1/1/1/1.
Day 4 Visuals/Clarity
Line Follow Indicators
Attacking Lines
Buff/Debuff Indicators
Day 5 Enemy AI / Resource Management + Collectors
(Or Day 7): Hotkeys
Day 6 Multiple Levels
Day 7 Tutorializing
Day 8 Customized Units
Day 9 Sounds/Music - Timer (Speedrun) Difficulty Selection
Tutorial Tutorial
(Grey out non-important bars) (Grey out non-important bars)

@ -0,0 +1,5 @@
#pragma once
enum class Sound{
HUM,
};

@ -1,70 +1,69 @@
#include "Unit.h" #include "Unit.h"
#include "Constant.h"
#include "olcUTIL_Geometry2D.h" #include "olcUTIL_Geometry2D.h"
#include "TileManager.h" #include "TileManager.h"
#include "util.h" #include "util.h"
BasicUnit::BasicUnit(vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly,bool moveable) BasicUnit::BasicUnit(PixelGameEngine*pge,vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly,bool moveable)
:Unit({ :Unit(pge,{
{HEALTH,4}, {HEALTH,4},
{RANGE,2}, {RANGE,2},
{ATKSPD,2}, {ATKSPD,2},
{MOVESPD,3}, {MOVESPD,3},
{PROCEDURE,1}, {PROCEDURE,1},
},pos,12,*IMAGES[VIRUS_IMG1],friendly,moveable){} },pos,12,*IMAGES[VIRUS_IMG1],WHITE,WHITE,friendly,moveable){}
void BasicUnit::Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits){ void BasicUnit::Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits){
victim<<=1; victim<<=1;
} }
BasicUnit2::BasicUnit2(vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly,bool moveable) BasicUnit2::BasicUnit2(PixelGameEngine*pge,vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly,bool moveable)
:Unit({ :Unit(pge,{
{RANGE,2}, {RANGE,2},
{ATKSPD,2}, {ATKSPD,2},
{MOVESPD,3}, {MOVESPD,3},
{PROCEDURE,1}, {PROCEDURE,1},
{HEALTH,4}, {HEALTH,4},
},pos,12,*IMAGES[VIRUS_IMG1],friendly,moveable){} },pos,12,*IMAGES[VIRUS_IMG1],WHITE,WHITE,friendly,moveable){}
void BasicUnit2::Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits){ void BasicUnit2::Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits){
victim>>=1; victim>>=1;
} }
LeftShifter::LeftShifter(vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly,bool moveable) LeftShifter::LeftShifter(PixelGameEngine*pge,vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly,bool moveable)
:Unit({ :Unit(pge,{
{RANGE,2}, {RANGE,2},
{ATKSPD,2}, {ATKSPD,2},
{MOVESPD,3}, {MOVESPD,3},
{PROCEDURE,1}, {PROCEDURE,1},
{HEALTH,4}, {HEALTH,4},
},pos,12,*IMAGES[LEFT_SHIFTER],friendly,moveable){} },pos,12,*IMAGES[LEFT_SHIFTER],CONSTANT::ATTACKER_TARGET_COL,CONSTANT::ATTACKER_ATTACK_COL,friendly,moveable){}
void LeftShifter::Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits){ void LeftShifter::Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits){
victim<<=1; victim<<=1;
} }
RightShifter::RightShifter(vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly,bool moveable) RightShifter::RightShifter(PixelGameEngine*pge,vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly,bool moveable)
:Unit({ :Unit(pge,{
{HEALTH,4}, {HEALTH,4},
{RANGE,2}, {RANGE,2},
{ATKSPD,2}, {ATKSPD,2},
{MOVESPD,3}, {MOVESPD,3},
{PROCEDURE,1}, {PROCEDURE,1},
},pos,12,*IMAGES[RIGHT_SHIFTER],friendly,moveable){} },pos,12,*IMAGES[RIGHT_SHIFTER],CONSTANT::ATTACKER_TARGET_COL,CONSTANT::ATTACKER_ATTACK_COL,friendly,moveable){}
void RightShifter::Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits){ void RightShifter::Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits){
victim>>=1; victim>>=1;
} }
BitRestorer::BitRestorer(vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly,bool moveable) BitRestorer::BitRestorer(PixelGameEngine*pge,vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly,bool moveable)
:Unit({ :Unit(pge,{
{PROCEDURE,6}, {PROCEDURE,6},
{RANGE,1}, {RANGE,1},
{ATKSPD,1}, {ATKSPD,1},
{MOVESPD,1}, {MOVESPD,1},
{HEALTH,2}, {HEALTH,2},
},pos,12,*IMAGES[BIT_RESTORER],friendly,moveable,true,false){} },pos,12,*IMAGES[BIT_RESTORER],CONSTANT::HEALER_TARGET_COL,CONSTANT::HEALER_ATTACK_COL,friendly,moveable,true,false){}
void BitRestorer::Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits){ void BitRestorer::Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits){
std::vector<int>emptyMemoryPositions; std::vector<int>emptyMemoryPositions;
@ -75,6 +74,7 @@ void BitRestorer::Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUni
} }
if(emptyMemoryPositions.size()==0){ if(emptyMemoryPositions.size()==0){
//First see if we can find another damaged target, if we can, then we try healing them. Otherwise we exit. //First see if we can find another damaged target, if we can, then we try healing them. Otherwise we exit.
appliedTarget.reset();
AttemptToHealOtherAllies(otherUnits); AttemptToHealOtherAllies(otherUnits);
return; return;
} }
@ -94,33 +94,36 @@ void BitRestorer::AttemptToHealOtherAllies(std::vector<std::shared_ptr<Unit>>&ot
if(emptyMemoryPositions.size()!=0){ if(emptyMemoryPositions.size()!=0){
int randomBit=emptyMemoryPositions[rand()%emptyMemoryPositions.size()]; int randomBit=emptyMemoryPositions[rand()%emptyMemoryPositions.size()];
u->memory[randomBit]=u->ghostMemory[randomBit]=true; u->memory[randomBit]=u->ghostMemory[randomBit]=true;
appliedTarget=u;
return; return;
} }
} }
} }
} }
MemorySwapper::MemorySwapper(vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly,bool moveable) MemorySwapper::MemorySwapper(PixelGameEngine*pge,vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly,bool moveable)
:Unit({ :Unit(pge,{
{RANGE,3}, {RANGE,3},
{ATKSPD,1}, {ATKSPD,1},
{HEALTH,3}, {HEALTH,3},
{PROCEDURE,3}, {PROCEDURE,3},
{MOVESPD,2}, {MOVESPD,2},
},pos,12,*IMAGES[MEMORY_SWAPPER],friendly,moveable,true){} },pos,12,*IMAGES[MEMORY_SWAPPER],CONSTANT::ATTACKER_TARGET_COL,CONSTANT::ATTACKER_ATTACK_COL,friendly,moveable,true){
autoAcquireFriendlyTarget=false;
}
void MemorySwapper::Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits){ void MemorySwapper::Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits){
} }
Corrupter::Corrupter(vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly,bool moveable) Corrupter::Corrupter(PixelGameEngine*pge,vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly,bool moveable)
:Unit({ :Unit(pge,{
{ATKSPD,3}, {ATKSPD,3},
{RANGE,1}, {RANGE,1},
{PROCEDURE,8}, {PROCEDURE,8},
{MOVESPD,4}, {MOVESPD,4},
{HEALTH,4}, {HEALTH,4},
},pos,12,*IMAGES[CORRUPTER],friendly,moveable){} },pos,12,*IMAGES[CORRUPTER],CONSTANT::ATTACKER_TARGET_COL,CONSTANT::ATTACKER_ATTACK_COL,friendly,moveable){}
void Corrupter::Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits){ void Corrupter::Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits){
//Chooses a bit at random and corrupts it. //Chooses a bit at random and corrupts it.
@ -128,27 +131,27 @@ void Corrupter::Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits
victim.memory[randomBit]=victim.ghostMemory[randomBit]=false; victim.memory[randomBit]=victim.ghostMemory[randomBit]=false;
} }
MemoryAllocator::MemoryAllocator(vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly,bool moveable) MemoryAllocator::MemoryAllocator(PixelGameEngine*pge,vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly,bool moveable)
:Unit({ :Unit(pge,{
{RANGE,1}, {RANGE,1},
{ATKSPD,1}, {ATKSPD,1},
{MOVESPD,1}, {MOVESPD,1},
{PROCEDURE,1}, {PROCEDURE,1},
{HEALTH,1}, {HEALTH,1},
},pos,12,*IMAGES[UNIT_ALLOCATOR],friendly,true,false){} },pos,12,*IMAGES[UNIT_ALLOCATOR],CONSTANT::ATTACKER_TARGET_COL,CONSTANT::ATTACKER_ATTACK_COL,friendly,true,false){}
void MemoryAllocator::Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits){ void MemoryAllocator::Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits){
} }
RAMBank::RAMBank(PixelGameEngine*pge,vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly) RAMBank::RAMBank(PixelGameEngine*pge,vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly)
:Unit({ :Unit(pge,{
{RANGE,0}, {RANGE,0},
{ATKSPD,0}, {ATKSPD,0},
{MOVESPD,0}, {MOVESPD,0},
{PROCEDURE,25}, {PROCEDURE,25},
{HEALTH,16}, {HEALTH,16},
},pos,41,*IMAGES[RAM_BANK],friendly,false },pos,41,*IMAGES[RAM_BANK],WHITE,WHITE,friendly,false
,false,false ,false,false
),randomOffset({util::random(128),util::random(128)}),matrixImg(*IMAGES[MATRIX]), ),randomOffset({util::random(128),util::random(128)}),matrixImg(*IMAGES[MATRIX]),
originalImg(*IMAGES[RAM_BANK]){ originalImg(*IMAGES[RAM_BANK]){
@ -163,7 +166,7 @@ void RAMBank::Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits){
} }
void RAMBank::Update(PixelGameEngine*pge){ void RAMBank::Update(PixelGameEngine*pge,std::map<Sound,std::unique_ptr<Audio>>&SOUNDS){
pge->SetDrawTarget(img.Sprite()); pge->SetDrawTarget(img.Sprite());
for(int y=0;y<img.Sprite()->height;y++){ for(int y=0;y<img.Sprite()->height;y++){
for(int x=0;x<img.Sprite()->width;x++){ for(int x=0;x<img.Sprite()->width;x++){
@ -173,6 +176,10 @@ void RAMBank::Update(PixelGameEngine*pge){
} }
} }
} }
if(!soundStarted){
soundStarted=true;
soundHandle=SOUNDS[Sound::HUM]->Play(GetPos(),0.4,0.4,true);
}
img.Decal()->Update(); img.Decal()->Update();
pge->SetDrawTarget(nullptr); pge->SetDrawTarget(nullptr);
} }
@ -184,8 +191,12 @@ void RAMBank::Draw(TileTransformedView&game,std::map<Image,std::unique_ptr<Rende
} }
} }
Unit::Unit(std::vector<Memory>memory,vf2d pos,float radius,Renderable&img,bool friendly,bool moveable,bool friendlyInteractable,bool enemyInteractable) void RAMBank::OnDeath(std::map<Sound,std::unique_ptr<Audio>>&SOUNDS){
:pos(pos),radius(radius),ghostPos(pos),img(img),friendly(friendly),moveable(moveable),friendlyInteractable(friendlyInteractable),enemyInteractable(enemyInteractable){ SOUNDS[Sound::HUM]->Stop(soundHandle);
}
Unit::Unit(PixelGameEngine*pge,std::vector<Memory>memory,vf2d pos,float radius,Renderable&img,Pixel targetLineColor,Pixel attackingLineColor,bool friendly,bool moveable,bool friendlyInteractable,bool enemyInteractable)
:pos(pos),radius(radius),ghostPos(pos),img(img),targetLineCol(targetLineColor),attackingLineCol(attackingLineColor),friendly(friendly),moveable(moveable),friendlyInteractable(friendlyInteractable),enemyInteractable(enemyInteractable){
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++){
@ -216,6 +227,9 @@ Unit::Unit(std::vector<Memory>memory,vf2d pos,float radius,Renderable&img,bool f
} }
marker+=mem.size; marker+=mem.size;
} }
attackingLine.Create(25,24,false,false);
targetingLine.Create(25,24,false,false);
} }
void Unit::DrawRangeIndicator(PixelGameEngine*pge,TileTransformedView&game,std::map<Image,std::unique_ptr<Renderable>>&IMAGES){ void Unit::DrawRangeIndicator(PixelGameEngine*pge,TileTransformedView&game,std::map<Image,std::unique_ptr<Renderable>>&IMAGES){
@ -317,6 +331,23 @@ void Unit::DrawHud(TileTransformedView&game,std::map<Image,std::unique_ptr<Rende
} }
void Unit::DrawUnitDamageStats(PixelGameEngine*pge,TileTransformedView&game,std::map<Image,std::unique_ptr<Renderable>>&IMAGES){ void Unit::DrawUnitDamageStats(PixelGameEngine*pge,TileTransformedView&game,std::map<Image,std::unique_ptr<Renderable>>&IMAGES){
if(!target.expired()){
geom2d::line<float>lineToTarget(pos,target.lock()->pos);
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,1},targetLineCol);
}
if(!appliedTarget.expired()){
geom2d::line<float>lineToTarget(pos,appliedTarget.lock()->pos);
lineToTarget.start=lineToTarget.rpoint(GetUnitSize().x/2);
lineToTarget.end=lineToTarget.rpoint(lineToTarget.length()-GetUnitSize().x/4);
if(reloadTimer>0){
util::ApplyMatrixEffect(game.GetPGE(),attackingLine,*IMAGES[ATTACKING_LINE],IMAGES[MATRIX]);
float reloadSpd=1.f/(GetAtkSpd()/2.f);
game.DrawPartialRotatedDecal(lineToTarget.upoint(0.5),attackingLine.Decal(),lineToTarget.vector().polar().y,{lineToTarget.length()/2,12},{lineShift*30,0},{lineToTarget.length(),24},{1,1+(reloadTimer/reloadSpd)*0.25f},{attackingLineCol.r,attackingLineCol.g,attackingLineCol.b,uint8_t(IsFriendly()?200:160)});
}
}
float dist=geom2d::line<float>(game.ScreenToWorld(pge->GetMousePos()),GetGhostPos()).length(); float dist=geom2d::line<float>(game.ScreenToWorld(pge->GetMousePos()),GetGhostPos()).length();
float range=12*(GetRange()+1); float range=12*(GetRange()+1);
@ -325,7 +356,7 @@ void Unit::DrawUnitDamageStats(PixelGameEngine*pge,TileTransformedView&game,std:
auto DrawStatDown=[&](Marker&maxStat,int currentStat,vf2d pos,vf2d downDisplayPos,Image img,uint8_t transparency=255){ auto DrawStatDown=[&](Marker&maxStat,int currentStat,vf2d pos,vf2d downDisplayPos,Image img,uint8_t transparency=255){
if(maxStat.size>0){ if(maxStat.size>0){
if(currentStat!=maxStat.size){ if(currentStat!=maxStat.size){
game.DrawDecal(this->pos+pos,IMAGES[img]->Decal(),{1,1},{255,255,255,transparency}); game.DrawDecal(this->pos+pos,IMAGES[img]->Decal(),{1,1},currentStat==0?Pixel{192,64,64,transparency}:Pixel{255,255,255,transparency});
if(currentStat>0){ if(currentStat>0){
game.DrawDecal(this->pos+downDisplayPos,IMAGES[DOWN_ARROW]->Decal(),{1,1},{255,255,255,transparency}); game.DrawDecal(this->pos+downDisplayPos,IMAGES[DOWN_ARROW]->Decal(),{1,1},{255,255,255,transparency});
} else { } else {
@ -337,15 +368,15 @@ void Unit::DrawUnitDamageStats(PixelGameEngine*pge,TileTransformedView&game,std:
if(IsSelected()){ if(IsSelected()){
DrawStatDown(atkSpd,GetAtkSpd(),{-48-8,-24},{-48+8,-18},RLD); DrawStatDown(atkSpd,GetAtkSpd(),{-48-8,-24},{-48+8,-18},RLD);
DrawStatDown(moveSpd,GetMoveSpd(),{-48-8,8},{-48+8,2},SPD); DrawStatDown(moveSpd,GetMoveSpd(),{-48-8,8},{-36+8,2},SPD);
DrawStatDown(this->range,GetRange(),{8,-24},{36,-18},RNG); DrawStatDown(this->range,GetRange(),{8,-24},{20,-18},RNG);
DrawStatDown(procedure,GetProcedure(),{8,8},{36,2},PRC); DrawStatDown(procedure,GetProcedure(),{8,8},{26,2},PRC);
}else }else
if(dist<range*2){ if(dist<range*2){
uint8_t transparency=uint8_t((1.f-(dist/(range*2)))*255); uint8_t transparency=uint8_t((1.f-(dist/(range*2)))*255);
DrawStatDown(atkSpd,GetAtkSpd(),{-48-8,-24},{-48+8,-18},RLD,transparency); DrawStatDown(atkSpd,GetAtkSpd(),{-48-8,-24},{-48+8,-18},RLD,transparency);
DrawStatDown(moveSpd,GetMoveSpd(),{-48-8,8},{-48+8,2},SPD,transparency); DrawStatDown(moveSpd,GetMoveSpd(),{-48-8,8},{-36+8,2},SPD,transparency);
DrawStatDown(this->range,GetRange(),{8,-24},{26,-18},RNG,transparency); DrawStatDown(this->range,GetRange(),{8,-24},{20,-18},RNG,transparency);
DrawStatDown(procedure,GetProcedure(),{8,8},{26,2},PRC,transparency); DrawStatDown(procedure,GetProcedure(),{8,8},{26,2},PRC,transparency);
} }
} }
@ -360,6 +391,8 @@ int Unit::GetBits(Marker&m){
return activeBits; return activeBits;
} }
void Unit::OnDeath(std::map<Sound,std::unique_ptr<Audio>>&SOUNDS){}
int Unit::GetHealth(){ int Unit::GetHealth(){
return GetBits(health); return GetBits(health);
} }
@ -390,7 +423,7 @@ void Unit::_RunAI(PixelGameEngine*pge){
RunAI(pge); RunAI(pge);
} }
void Unit::_Update(PixelGameEngine*pge){ void Unit::_Update(PixelGameEngine*pge,std::map<Sound,std::unique_ptr<Audio>>&SOUNDS){
if(!target.expired()){ if(!target.expired()){
auto ptrTarget=target.lock(); auto ptrTarget=target.lock();
if(!InRange(ptrTarget)){ if(!InRange(ptrTarget)){
@ -413,8 +446,10 @@ void Unit::_Update(PixelGameEngine*pge){
} }
reloadTimer=std::max(0.f,reloadTimer-pge->GetElapsedTime()); reloadTimer=std::max(0.f,reloadTimer-pge->GetElapsedTime());
lineShift-=pge->GetElapsedTime();
if(lineShift<-25)lineShift+=25;
Update(pge); Update(pge,SOUNDS);
} }
std::vector<bool> operator <<(Unit&u,const int n){ std::vector<bool> operator <<(Unit&u,const int n){
@ -511,12 +546,13 @@ void Unit::AttemptAttack(std::weak_ptr<Unit>attacker,std::weak_ptr<Unit>unit,std
} }
if(!finalTarget.expired()){ if(!finalTarget.expired()){
if(InRange(finalTarget.lock())){ if(InRange(finalTarget.lock())){
appliedTarget=finalTarget;
_Attack(attacker,finalTarget,otherUnits); //Call the parent function first, followed by the child. _Attack(attacker,finalTarget,otherUnits); //Call the parent function first, followed by the child.
} }
} }
} }
void Unit::Update(PixelGameEngine*pge){} void Unit::Update(PixelGameEngine*pge,std::map<Sound,std::unique_ptr<Audio>>&SOUNDS){}
void Unit::Attacked(std::weak_ptr<Unit>attacker){} void Unit::Attacked(std::weak_ptr<Unit>attacker){}
@ -575,3 +611,7 @@ Renderable&Unit::GetImage(){
std::weak_ptr<Unit>Unit::GetCurrentTarget(){ std::weak_ptr<Unit>Unit::GetCurrentTarget(){
return target; return target;
} }
bool Unit::AutoAcquiresFriendlyTargets(){
return autoAcquireFriendlyTarget;
}

@ -4,6 +4,9 @@
#include "olcPGEX_TransformedView.h" #include "olcPGEX_TransformedView.h"
#include "Constant.h" #include "Constant.h"
#include "Image.h" #include "Image.h"
#include "Sound.h"
#include "olcPGEX_AudioSource.h"
#include "util.h"
struct Marker{ struct Marker{
size_t index; size_t index;
@ -25,7 +28,7 @@ struct Memory{
struct Unit{ struct Unit{
public: public:
Unit(std::vector<Memory>memory,vf2d pos,float radius,Renderable&img,bool friendly=false,bool moveable=true,bool friendlyInteractable=false,bool enemyInteractable=true); Unit(PixelGameEngine*pge,std::vector<Memory>memory,vf2d pos,float radius,Renderable&img,Pixel targetLineColor,Pixel attackingLineColor,bool friendly=false,bool moveable=true,bool friendlyInteractable=false,bool enemyInteractable=true);
int GetHealth(); int GetHealth();
int GetRange(); int GetRange();
int GetAtkSpd(); int GetAtkSpd();
@ -34,10 +37,11 @@ public:
int GetMemorySize(); int GetMemorySize();
std::vector<bool>memory; std::vector<bool>memory;
std::vector<bool>ghostMemory; std::vector<bool>ghostMemory;
virtual void Update(PixelGameEngine*pge); virtual void Update(PixelGameEngine*pge,std::map<Sound,std::unique_ptr<Audio>>&SOUNDS);
virtual void Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits)=0; virtual void Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits)=0;
virtual void Draw(TileTransformedView&game,std::map<Image,std::unique_ptr<Renderable>>&IMAGES); 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); virtual void DrawHud(TileTransformedView&game,std::map<Image,std::unique_ptr<Renderable>>&IMAGES);
virtual void OnDeath(std::map<Sound,std::unique_ptr<Audio>>&SOUNDS);
bool IsFriendly(); bool IsFriendly();
bool IsSelected(); bool IsSelected();
void Select(); void Select();
@ -53,7 +57,7 @@ public:
bool GhostInFogOfWar(); bool GhostInFogOfWar();
void HideGhost(); void HideGhost();
vf2d GetGhostPos(); vf2d GetGhostPos();
void _Update(PixelGameEngine*pge); void _Update(PixelGameEngine*pge,std::map<Sound,std::unique_ptr<Audio>>&SOUNDS);
bool IsMoveable(); bool IsMoveable();
void DrawRangeIndicator(PixelGameEngine*pge,TileTransformedView&game,std::map<Image,std::unique_ptr<Renderable>>&IMAGES); void DrawRangeIndicator(PixelGameEngine*pge,TileTransformedView&game,std::map<Image,std::unique_ptr<Renderable>>&IMAGES);
bool CanInteractWithEnemies(); bool CanInteractWithEnemies();
@ -65,6 +69,7 @@ public:
void _Attacked(std::weak_ptr<Unit>attacker); void _Attacked(std::weak_ptr<Unit>attacker);
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();
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++){
@ -90,68 +95,75 @@ public:
protected: protected:
bool friendly; bool friendly;
Renderable&img; Renderable&img;
Marker health; Marker health={};
Marker range; Marker range={};
Marker atkSpd; Marker atkSpd={};
Marker moveSpd; Marker moveSpd={};
Marker procedure; Marker procedure={};
std::weak_ptr<Unit>target; std::weak_ptr<Unit>target;
std::weak_ptr<Unit>appliedTarget;
vf2d targetLoc=CONSTANT::UNSELECTED; vf2d targetLoc=CONSTANT::UNSELECTED;
bool InRange(std::shared_ptr<Unit>target); bool InRange(std::shared_ptr<Unit>target);
bool InRange(Unit*target); bool InRange(Unit*target);
bool InRange(vf2d pos); bool InRange(vf2d pos);
float reloadTimer=0;
bool autoAcquireFriendlyTarget=true;
private: private:
Renderable targetingLine;
Renderable attackingLine;
Pixel targetLineCol,attackingLineCol;
vf2d pos; vf2d pos;
vf2d ghostPos; vf2d ghostPos;
float radius; float radius;
int GetBits(Marker&m); int GetBits(Marker&m);
bool selected=false; bool selected=false;
bool dead=false; bool dead=false;
float reloadTimer=0;
void _Attack(std::weak_ptr<Unit>attacker,std::weak_ptr<Unit>finalTarget,std::vector<std::shared_ptr<Unit>>&otherUnits); void _Attack(std::weak_ptr<Unit>attacker,std::weak_ptr<Unit>finalTarget,std::vector<std::shared_ptr<Unit>>&otherUnits);
bool moveable=true; bool moveable=true;
bool friendlyInteractable=false; bool friendlyInteractable=false;
bool enemyInteractable=true; bool enemyInteractable=true;
float lineShift=0;
void ApplyMatrixEffect(Renderable&r);
}; };
struct BasicUnit:Unit{ struct BasicUnit:Unit{
BasicUnit(vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly=false,bool moveable=true); BasicUnit(PixelGameEngine*pge,vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly=false,bool moveable=true);
void Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits)override; void Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits)override;
}; };
struct BasicUnit2:Unit{ struct BasicUnit2:Unit{
BasicUnit2(vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly=false,bool moveable=true); BasicUnit2(PixelGameEngine*pge,vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly=false,bool moveable=true);
void Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits)override; void Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits)override;
}; };
struct LeftShifter:Unit{ struct LeftShifter:Unit{
LeftShifter(vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly=false,bool moveable=true); LeftShifter(PixelGameEngine*pge,vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly=false,bool moveable=true);
void Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits)override; void Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits)override;
}; };
struct RightShifter:Unit{ struct RightShifter:Unit{
RightShifter(vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly=false,bool moveable=true); RightShifter(PixelGameEngine*pge,vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly=false,bool moveable=true);
void Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits)override; void Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits)override;
}; };
struct BitRestorer:Unit{ struct BitRestorer:Unit{
BitRestorer(vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly=false,bool moveable=true); BitRestorer(PixelGameEngine*pge,vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly=false,bool moveable=true);
void Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits)override; void Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits)override;
void AttemptToHealOtherAllies(std::vector<std::shared_ptr<Unit>>&otherUnits); void AttemptToHealOtherAllies(std::vector<std::shared_ptr<Unit>>&otherUnits);
}; };
struct MemorySwapper:Unit{ struct MemorySwapper:Unit{
MemorySwapper(vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly=false,bool moveable=true); MemorySwapper(PixelGameEngine*pge,vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly=false,bool moveable=true);
void Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits)override; void Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits)override;
}; };
struct Corrupter:Unit{ struct Corrupter:Unit{
Corrupter(vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly=false,bool moveable=true); Corrupter(PixelGameEngine*pge,vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly=false,bool moveable=true);
void Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits)override; void Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits)override;
}; };
struct MemoryAllocator:Unit{ struct MemoryAllocator:Unit{
MemoryAllocator(vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly=false,bool moveable=true); MemoryAllocator(PixelGameEngine*pge,vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly=false,bool moveable=true);
void Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits)override; void Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits)override;
}; };
@ -160,8 +172,11 @@ struct RAMBank:Unit{
Renderable img; Renderable img;
Renderable&originalImg; Renderable&originalImg;
Renderable&matrixImg; Renderable&matrixImg;
bool soundStarted=false;
int soundHandle;
RAMBank(PixelGameEngine*pge,vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly=false); RAMBank(PixelGameEngine*pge,vf2d pos,std::map<Image,std::unique_ptr<Renderable>>&IMAGES,bool friendly=false);
void Update(PixelGameEngine*pge)override; void Update(PixelGameEngine*pge,std::map<Sound,std::unique_ptr<Audio>>&SOUNDS)override;
void Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits)override; void Attack(Unit&victim,std::vector<std::shared_ptr<Unit>>&otherUnits)override;
void Draw(TileTransformedView&game,std::map<Image,std::unique_ptr<Renderable>>&IMAGES)override; void Draw(TileTransformedView&game,std::map<Image,std::unique_ptr<Renderable>>&IMAGES)override;
void OnDeath(std::map<Sound,std::unique_ptr<Audio>>&SOUNDS)override;
}; };

@ -40,6 +40,8 @@ void VirusAttack::InitializeImages(){
LoadImage(PRC,"assets/prc.png"); LoadImage(PRC,"assets/prc.png");
LoadImage(RNG,"assets/rng.png"); LoadImage(RNG,"assets/rng.png");
LoadImage(SPD,"assets/spd.png"); LoadImage(SPD,"assets/spd.png");
LoadImage(TARGETING_LINE,"assets/targetLine.png");
LoadImage(ATTACKING_LINE,"assets/attackLine.png");
} }
bool VirusAttack::OnUserCreate(){ bool VirusAttack::OnUserCreate(){
@ -59,13 +61,13 @@ bool VirusAttack::OnUserCreate(){
AL.AudioSystemInit(); AL.AudioSystemInit();
InitializeSounds(); InitializeSounds();
units.push_back(std::make_unique<LeftShifter>(vf2d{128,128},IMAGES,true)); units.push_back(std::make_unique<LeftShifter>(this,vf2d{128,128},IMAGES,true));
units.push_back(std::make_unique<RightShifter>(vf2d{129,129},IMAGES,true)); units.push_back(std::make_unique<RightShifter>(this,vf2d{129,129},IMAGES,true));
units.push_back(std::make_unique<BitRestorer>(vf2d{130,130},IMAGES,true)); units.push_back(std::make_unique<BitRestorer>(this,vf2d{130,130},IMAGES,true));
units.push_back(std::make_unique<BitRestorer>(vf2d{130,140},IMAGES,true)); units.push_back(std::make_unique<BitRestorer>(this,vf2d{130,140},IMAGES,true));
units.push_back(std::make_unique<MemorySwapper>(vf2d{131,131},IMAGES,true)); units.push_back(std::make_unique<MemorySwapper>(this,vf2d{131,131},IMAGES,true));
units.push_back(std::make_unique<Corrupter>(vf2d{132,132},IMAGES,true)); units.push_back(std::make_unique<Corrupter>(this,vf2d{132,132},IMAGES,true));
units.push_back(std::make_unique<MemoryAllocator>(vf2d{133,133},IMAGES,true)); units.push_back(std::make_unique<MemoryAllocator>(this,vf2d{133,133},IMAGES,true));
units.push_back(std::make_unique<RAMBank>(this,vf2d{134,134},IMAGES,true)); units.push_back(std::make_unique<RAMBank>(this,vf2d{134,134},IMAGES,true));
@ -74,30 +76,25 @@ bool VirusAttack::OnUserCreate(){
collectionPoints.push_back(std::make_unique<CollectionPoint>(this,vf2d{32.f,32.f+48*i},-PI/2,*IMAGES[MEMORY_COLLECTION_POINT],MemoryType(i))); collectionPoints.push_back(std::make_unique<CollectionPoint>(this,vf2d{32.f,32.f+48*i},-PI/2,*IMAGES[MEMORY_COLLECTION_POINT],MemoryType(i)));
} }
units.push_back(std::make_unique<RAMBank>(this,vf2d{320,320},IMAGES,false)); units.push_back(std::make_unique<RAMBank>(this,vf2d{1200,1200},IMAGES,false));
units.push_back(std::make_unique<RightShifter>(vf2d{360,300},IMAGES,false)); units.push_back(std::make_unique<RightShifter>(this,vf2d{1260,1200},IMAGES,false));
units.push_back(std::make_unique<RightShifter>(this,vf2d{360,300},IMAGES,false));
for(int i=0;i<units[0]->GetMemorySize();i++){ units.push_back(std::make_unique<RightShifter>(this,vf2d{361,300},IMAGES,false));
units[0]->memory[i]=units[0]->ghostMemory[i]=i%2==0;
}
return true; return true;
} }
void VirusAttack::InitializeSounds(){ void VirusAttack::InitializeSounds(){
int soundIndex=0; int soundIndex=0;
auto LoadSound=[&](Audio&audio,std::string soundFilename){ auto LoadSound=[&](Sound sound,std::string soundFilename){
audio.AL=&AL; SOUNDS[sound]=std::make_unique<Audio>();
audio.LoadAudioSample(soundIndex,std::string("./assets/"+soundFilename).c_str()); SOUNDS[sound]->AL=&AL;
SOUNDS[sound]->LoadAudioSample(soundIndex,std::string("./assets/"+soundFilename).c_str());
soundIndex++; soundIndex++;
}; };
AS_Test.SetDefaults(5,1,0,1,false); LoadSound(Sound::HUM,"machine2.wav");
AS_Test.fPlaySpeed=5;
LoadSound(AS_Test,"test.wav");
LoadSound(explosion,"SampleA.wav");
} }
void VirusAttack::HandleDraggingSelection(){ void VirusAttack::HandleDraggingSelection(){
@ -117,14 +114,6 @@ void VirusAttack::HandleDraggingSelection(){
if(endDragPos.x<startingDragPos.x){std::swap(startingDragPos.x,endDragPos.x);} if(endDragPos.x<startingDragPos.x){std::swap(startingDragPos.x,endDragPos.x);}
if(endDragPos.y<startingDragPos.y){std::swap(startingDragPos.y,endDragPos.y);} if(endDragPos.y<startingDragPos.y){std::swap(startingDragPos.y,endDragPos.y);}
geom2d::rect<float> selectionRegion(startingDragPos,endDragPos-startingDragPos); geom2d::rect<float> selectionRegion(startingDragPos,endDragPos-startingDragPos);
if(selectionRegion.size.x<12){
selectionRegion.pos.x-=12-selectionRegion.size.x/2;
selectionRegion.size.x+=12-selectionRegion.size.x/2;
}
if(selectionRegion.size.y<12){
selectionRegion.pos.y-=12-selectionRegion.size.y/2;
selectionRegion.size.y+=12-selectionRegion.size.y/2;
}
for(auto&u:units){ for(auto&u:units){
if(u->IsFriendly()){ if(u->IsFriendly()){
if(geom2d::overlaps(selectionRegion,geom2d::circle<float>(u->GetPos(),u->GetUnitSize().x/2))){ if(geom2d::overlaps(selectionRegion,geom2d::circle<float>(u->GetPos(),u->GetUnitSize().x/2))){
@ -150,8 +139,7 @@ void VirusAttack::HandleRightClickMove(){
if (GetMouse(1).bHeld){ if (GetMouse(1).bHeld){
bool selectedTarget=false; bool selectedTarget=false;
for(auto&u:units){ for(auto&u:units){
geom2d::rect<float> unitRegion(u->GetPos()-u->GetUnitSize()/2,u->GetUnitSize()); if(geom2d::overlaps(geom2d::circle<float>(u->GetPos(),u->GetUnitSize().x/2),GetWorldMousePos())){
if(geom2d::overlaps(unitRegion,GetWorldMousePos())){
for(auto&u2:units){ for(auto&u2:units){
if(&u!=&u2){ if(&u!=&u2){
if(!u->IsFriendly()&&u2->IsFriendly()&&u2->IsSelected()&&u2->CanInteractWithEnemies()){ if(!u->IsFriendly()&&u2->IsFriendly()&&u2->IsSelected()&&u2->CanInteractWithEnemies()){
@ -196,9 +184,9 @@ void VirusAttack::IdentifyClosestTarget(std::weak_ptr<Unit>&closestUnit,float&cl
bool canInteract; bool canInteract;
canInteract= canInteract=
(u->IsFriendly()&&u->CanInteractWithEnemies()&&!u2->IsFriendly())|| (u->IsFriendly()&&u->CanInteractWithEnemies()&&!u2->IsFriendly())||
(u->IsFriendly()&&u->CanInteractWithAllies()&&u2->IsFriendly())|| (u->IsFriendly()&&u->CanInteractWithAllies()&&u2->IsFriendly()&&u->AutoAcquiresFriendlyTargets())||
(!u->IsFriendly()&&u->CanInteractWithEnemies()&&u2->IsFriendly())|| (!u->IsFriendly()&&u->CanInteractWithEnemies()&&u2->IsFriendly())||
(!u->IsFriendly()&&u->CanInteractWithAllies()&&!u2->IsFriendly()); (!u->IsFriendly()&&u->CanInteractWithAllies()&&!u2->IsFriendly()&&u->AutoAcquiresFriendlyTargets());
if(canInteract){ if(canInteract){
geom2d::line<float>unitLine(u->GetPos(),u2->GetPos()); geom2d::line<float>unitLine(u->GetPos(),u2->GetPos());
if(unitLine.length()<closestDist){ if(unitLine.length()<closestDist){
@ -344,7 +332,8 @@ bool VirusAttack::OnUserUpdate(float fElapsedTime){
HandleRightClickMove(); HandleRightClickMove();
HandlePanAndZoom(fElapsedTime); HandlePanAndZoom(fElapsedTime);
HandleMinimapClick(); HandleMinimapClick();
AL.vecPos=game.GetWorldOffset()+GetScreenSize()/2; AL.vecPos=game.ScreenToWorld(GetScreenSize()/2);
AL.fSoundFXVolume=std::min(1.f,game.GetWorldScale().x);
AL.OnUserUpdate(fElapsedTime); AL.OnUserUpdate(fElapsedTime);
for(auto&tile:TileManager::visibleTiles){ for(auto&tile:TileManager::visibleTiles){
@ -361,18 +350,21 @@ bool VirusAttack::OnUserUpdate(float fElapsedTime){
CollisionChecking(u,u2); CollisionChecking(u,u2);
} }
if(u->IsFriendly()){ if(u->IsFriendly()){
for(int y=-1;y<2;y++){ for(int y=-2;y<3;y++){
for(int x=-1;x<2;x++){ for(int x=-2;x<3;x++){
if(abs(x)+abs(y)<=2){
TileManager::visibleTiles[u->GetPos()/24/4+vi2d(x,y)]=5; TileManager::visibleTiles[u->GetPos()/24/4+vi2d(x,y)]=5;
} }
} }
} }
}
u->AttemptAttack(u,closestUnit,units); u->AttemptAttack(u,closestUnit,units);
u->_Update(this); u->_Update(this,SOUNDS);
} }
std::erase_if(units,[&](std::shared_ptr<Unit>u){ std::erase_if(units,[&](std::shared_ptr<Unit>u){
if(u->GetHealth()==0){ if(u->GetHealth()==0){
u->OnDeath(SOUNDS);
deathAnimations.emplace_back(std::make_unique<DeathAnimation>(this,u->GetPos(),u->GetImage(),*IMAGES[MATRIX],u->IsFriendly())); deathAnimations.emplace_back(std::make_unique<DeathAnimation>(this,u->GetPos(),u->GetImage(),*IMAGES[MATRIX],u->IsFriendly()));
return true; return true;
} else { } else {
@ -404,6 +396,9 @@ bool VirusAttack::OnUserUpdate(float fElapsedTime){
for(auto&u:units){ for(auto&u:units){
u->DrawUnitDamageStats(this,game,IMAGES); u->DrawUnitDamageStats(this,game,IMAGES);
}
for(auto&u:units){
u->DrawHud(game,IMAGES); u->DrawHud(game,IMAGES);
} }

@ -7,6 +7,7 @@
#include "DeathAnimation.h" #include "DeathAnimation.h"
#include "olcPGEX_AudioListener.h" #include "olcPGEX_AudioListener.h"
#include "olcPGEX_AudioSource.h" #include "olcPGEX_AudioSource.h"
#include "Sound.h"
struct Letter{ struct Letter{
vf2d pos; vf2d pos;
@ -33,9 +34,9 @@ private:
std::vector<std::unique_ptr<DeathAnimation>>deathAnimations; std::vector<std::unique_ptr<DeathAnimation>>deathAnimations;
std::map<Image,std::unique_ptr<Renderable>>IMAGES; std::map<Image,std::unique_ptr<Renderable>>IMAGES;
std::map<Sound,std::unique_ptr<Audio>>SOUNDS;
olcPGEX_AudioListener AL; olcPGEX_AudioListener AL;
Audio AS_Test,explosion;
Audio*bgm; Audio*bgm;
TileTransformedView game; TileTransformedView game;

Binary file not shown.

After

Width:  |  Height:  |  Size: 641 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 622 B

@ -154,6 +154,7 @@
<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="Sound.h" />
<ClInclude Include="TileManager.h" /> <ClInclude Include="TileManager.h" />
<ClInclude Include="Unit.h" /> <ClInclude Include="Unit.h" />
<ClInclude Include="util.h" /> <ClInclude Include="util.h" />

@ -75,6 +75,9 @@
<ClInclude Include="olcPGEX_AudioSource.h"> <ClInclude Include="olcPGEX_AudioSource.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="Sound.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="VirusAttack.cpp"> <ClCompile Include="VirusAttack.cpp">

@ -199,8 +199,8 @@ public:
olc::vf2d vecPos = { 0.0f, 0.0f }; olc::vf2d vecPos = { 0.0f, 0.0f };
// Global volume settings // Global volume settings
float fMusicVolume = 0.2f; float fMusicVolume = 1.f;
float fSoundFXVolume = 0.4f; float fSoundFXVolume = 1.f;
bool bMusicOn = true; bool bMusicOn = true;
bool bSoundOn = true; bool bSoundOn = true;
@ -293,7 +293,7 @@ void olcPGEX_AudioListener::OnUserUpdate(float fElapsedTime){
std::erase_if(handles,[&](PlayingInstance&handle){return !soloud.isValidVoiceHandle(handle.handle);}); std::erase_if(handles,[&](PlayingInstance&handle){return !soloud.isValidVoiceHandle(handle.handle);});
for(PlayingInstance&handle:handles){ for(PlayingInstance&handle:handles){
soloud.setPan(handle.handle,std::clamp((handle.pos.x-vecPos.x)/1024,-1.f,1.f)); soloud.setPan(handle.handle,std::clamp((handle.pos.x-vecPos.x)/1024,-1.f,1.f));
soloud.setVolume(handle.handle,handle.vol*std::max(0.f,abs(1-std::min(1.0f,(GetDistance(handle.pos)/1024.f))))); soloud.setVolume(handle.handle,handle.vol*std::max(0.f,abs(1-std::min(1.0f,(GetDistance(handle.pos)/1024.f))))*(handle.pos!=vf2d{0,0}?fSoundFXVolume:1));
} }
} }

@ -107,7 +107,7 @@ public:
void PlayCentered(float speed = 1.0f, float vol = 1.0f, bool looping = false, bool paused = false); void PlayCentered(float speed = 1.0f, float vol = 1.0f, bool looping = false, bool paused = false);
// Play the Audio Sample, with given parameters // Play the Audio Sample, with given parameters
void Play(vf2d pos, float speed = 1.0f, float vol = 1.0f, bool looping = false, bool paused = false); int Play(vf2d pos, float speed = 1.0f, float vol = 1.0f, bool looping = false, bool paused = false);
// Pause or Un-Pause - maintains the playback position and handle // Pause or Un-Pause - maintains the playback position and handle
void Pause(bool pauseState = true); void Pause(bool pauseState = true);
@ -115,6 +115,8 @@ public:
// Stop - playback position and handle will be lost // Stop - playback position and handle will be lost
void Stop(); void Stop();
void Stop(int handle);
// Audio Modulation - control the speed of playback // Audio Modulation - control the speed of playback
void ModulateAudio(float minPlaySpeed, float maxPlaySpeed, float modulation, bool precise = false, bool deferred = false); void ModulateAudio(float minPlaySpeed, float maxPlaySpeed, float modulation, bool precise = false, bool deferred = false);
@ -158,7 +160,7 @@ void olcPGEX_AudioSource::PlayCentered(float speed, float vol, bool looping, boo
bIsPlaying = true; bIsPlaying = true;
} }
void olcPGEX_AudioSource::Play(vf2d pos, float speed, float vol, bool looping, bool paused) int olcPGEX_AudioSource::Play(vf2d pos, float speed, float vol, bool looping, bool paused)
{ {
// Set parameters // Set parameters
fPlaySpeed = speed; fPlaySpeed = speed;
@ -180,6 +182,8 @@ void olcPGEX_AudioSource::Play(vf2d pos, float speed, float vol, bool looping, b
// Update Play status // Update Play status
bIsPlaying = true; bIsPlaying = true;
return handle;
} }
void olcPGEX_AudioSource::Pause(bool pauseState) void olcPGEX_AudioSource::Pause(bool pauseState)
@ -191,6 +195,12 @@ void olcPGEX_AudioSource::Pause(bool pauseState)
bIsPlaying = !pauseState; bIsPlaying = !pauseState;
} }
void olcPGEX_AudioSource::Stop(int handle)
{
// Use the Audio Listener to stop the sound
AL->soloud.stop(handle);
}
void olcPGEX_AudioSource::Stop() void olcPGEX_AudioSource::Stop()
{ {
// Use the Audio Listener to stop the sound // Use the Audio Listener to stop the sound

Binary file not shown.

Before

Width:  |  Height:  |  Size: 465 KiB

After

Width:  |  Height:  |  Size: 438 KiB

@ -190,7 +190,7 @@ Module['FS_createPath']("/", "assets", true, true);
} }
} }
loadPackage({"files": [{"filename": "/assets/MAINICON.ico", "start": 0, "end": 766}, {"filename": "/assets/bit_restorer.png", "start": 766, "end": 10314}, {"filename": "/assets/corrupter.png", "start": 10314, "end": 21377}, {"filename": "/assets/left_shifter.png", "start": 21377, "end": 30582}, {"filename": "/assets/memory_collection_point.png", "start": 30582, "end": 31528}, {"filename": "/assets/memory_swapper.png", "start": 31528, "end": 42978}, {"filename": "/assets/minimap_hud.png", "start": 42978, "end": 46436}, {"filename": "/assets/outline.png", "start": 46436, "end": 47045}, {"filename": "/assets/ram_bank.png", "start": 47045, "end": 49309}, {"filename": "/assets/range_indicator.png", "start": 49309, "end": 58344}, {"filename": "/assets/right_shifter.png", "start": 58344, "end": 67568}, {"filename": "/assets/selection_circle.png", "start": 67568, "end": 68247}, {"filename": "/assets/shell.png", "start": 68247, "end": 75121}, {"filename": "/assets/test.wav", "start": 75121, "end": 474001, "audio": 1}, {"filename": "/assets/tile.png", "start": 474001, "end": 475336}, {"filename": "/assets/unit.png", "start": 475336, "end": 476066}], "remote_package_size": 476066}); loadPackage({"files": [{"filename": "/assets/MAINICON.ico", "start": 0, "end": 766}, {"filename": "/assets/atk.png", "start": 766, "end": 1443}, {"filename": "/assets/bit_restorer.png", "start": 1443, "end": 10991}, {"filename": "/assets/corrupter.png", "start": 10991, "end": 22054}, {"filename": "/assets/down_arrow.png", "start": 22054, "end": 22695}, {"filename": "/assets/left_shifter.png", "start": 22695, "end": 31900}, {"filename": "/assets/machine2.wav", "start": 31900, "end": 110508, "audio": 1}, {"filename": "/assets/memory_collection_point.png", "start": 110508, "end": 111454}, {"filename": "/assets/memory_swapper.png", "start": 111454, "end": 122904}, {"filename": "/assets/minimap_hud.png", "start": 122904, "end": 126362}, {"filename": "/assets/outline.png", "start": 126362, "end": 126971}, {"filename": "/assets/prc.png", "start": 126971, "end": 136274}, {"filename": "/assets/ram_bank.png", "start": 136274, "end": 138538}, {"filename": "/assets/range_indicator.png", "start": 138538, "end": 147573}, {"filename": "/assets/red_x.png", "start": 147573, "end": 148185}, {"filename": "/assets/right_shifter.png", "start": 148185, "end": 157409}, {"filename": "/assets/rld.png", "start": 157409, "end": 165080}, {"filename": "/assets/rng.png", "start": 165080, "end": 174212}, {"filename": "/assets/selection_circle.png", "start": 174212, "end": 174891}, {"filename": "/assets/shell.png", "start": 174891, "end": 181765}, {"filename": "/assets/sonar.wav", "start": 181765, "end": 438253, "audio": 1}, {"filename": "/assets/spd.png", "start": 438253, "end": 446795}, {"filename": "/assets/tile.png", "start": 446795, "end": 448130}, {"filename": "/assets/unit.png", "start": 448130, "end": 448860}], "remote_package_size": 448860});
})(); })();
@ -1187,23 +1187,23 @@ function dbg(text) {
// === Body === // === Body ===
var ASM_CONSTS = { var ASM_CONSTS = {
5369292: () => { window.onunload = Module._olc_OnPageUnload; }, 5369420: () => { window.onunload = Module._olc_OnPageUnload; },
5369336: ($0, $1) => { Module.olc_AspectRatio = $0 / $1; Module.olc_AssumeDefaultShells = (document.querySelectorAll('.emscripten').length >= 3) ? true : false; var olc_ResizeHandler = function() { let isFullscreen = (document.fullscreenElement != null); let width = (isFullscreen) ? window.innerWidth : Module.canvas.parentNode.clientWidth; let height = (isFullscreen) ? window.innerHeight : Module.canvas.parentNode.clientHeight; let viewWidth = width; let viewHeight = width / Module.olc_AspectRatio; if(viewHeight > height) { viewWidth = height * Module.olc_AspectRatio; viewHeight = height; } viewWidth = parseInt(viewWidth); viewHeight = parseInt(viewHeight); setTimeout(function() { if(Module.olc_AssumeDefaultShells) Module.canvas.parentNode.setAttribute('style', 'width: 100%; height: 70vh; margin-left: auto; margin-right: auto;'); Module.canvas.setAttribute('width', viewWidth); Module.canvas.setAttribute('height', viewHeight); Module.canvas.setAttribute('style', `width: ${viewWidth}px; height: ${viewHeight}px;`); Module._olc_PGE_UpdateWindowSize(viewWidth, viewHeight); Module.canvas.focus(); }, 200); }; var olc_Init = function() { if(Module.olc_AspectRatio === undefined) { setTimeout(function() { Module.olc_Init(); }, 50); return; } let resizeObserver = new ResizeObserver(function(entries) { Module.olc_ResizeHandler(); }).observe(Module.canvas.parentNode); let mutationObserver = new MutationObserver(function(mutationsList, observer) { setTimeout(function() { Module.olc_ResizeHandler(); }, 200); }).observe(Module.canvas.parentNode, { attributes: false, childList: true, subtree: false }); window.addEventListener('fullscreenchange', function(e) { setTimeout(function() { Module.olc_ResizeHandler();}, 200); }); }; Module.olc_ResizeHandler = (Module.olc_ResizeHandler != undefined) ? Module.olc_ResizeHandler : olc_ResizeHandler; Module.olc_Init = (Module.olc_Init != undefined) ? Module.olc_Init : olc_Init; Module.olc_Init(); }, 5369464: ($0, $1) => { Module.olc_AspectRatio = $0 / $1; Module.olc_AssumeDefaultShells = (document.querySelectorAll('.emscripten').length >= 3) ? true : false; var olc_ResizeHandler = function() { let isFullscreen = (document.fullscreenElement != null); let width = (isFullscreen) ? window.innerWidth : Module.canvas.parentNode.clientWidth; let height = (isFullscreen) ? window.innerHeight : Module.canvas.parentNode.clientHeight; let viewWidth = width; let viewHeight = width / Module.olc_AspectRatio; if(viewHeight > height) { viewWidth = height * Module.olc_AspectRatio; viewHeight = height; } viewWidth = parseInt(viewWidth); viewHeight = parseInt(viewHeight); setTimeout(function() { if(Module.olc_AssumeDefaultShells) Module.canvas.parentNode.setAttribute('style', 'width: 100%; height: 70vh; margin-left: auto; margin-right: auto;'); Module.canvas.setAttribute('width', viewWidth); Module.canvas.setAttribute('height', viewHeight); Module.canvas.setAttribute('style', `width: ${viewWidth}px; height: ${viewHeight}px;`); Module._olc_PGE_UpdateWindowSize(viewWidth, viewHeight); Module.canvas.focus(); }, 200); }; var olc_Init = function() { if(Module.olc_AspectRatio === undefined) { setTimeout(function() { Module.olc_Init(); }, 50); return; } let resizeObserver = new ResizeObserver(function(entries) { Module.olc_ResizeHandler(); }).observe(Module.canvas.parentNode); let mutationObserver = new MutationObserver(function(mutationsList, observer) { setTimeout(function() { Module.olc_ResizeHandler(); }, 200); }).observe(Module.canvas.parentNode, { attributes: false, childList: true, subtree: false }); window.addEventListener('fullscreenchange', function(e) { setTimeout(function() { Module.olc_ResizeHandler();}, 200); }); }; Module.olc_ResizeHandler = (Module.olc_ResizeHandler != undefined) ? Module.olc_ResizeHandler : olc_ResizeHandler; Module.olc_Init = (Module.olc_Init != undefined) ? Module.olc_Init : olc_Init; Module.olc_Init(); },
5371268: () => { if (typeof(AudioContext) !== 'undefined') { return true; } else if (typeof(webkitAudioContext) !== 'undefined') { return true; } return false; }, 5371396: () => { if (typeof(AudioContext) !== 'undefined') { return true; } else if (typeof(webkitAudioContext) !== 'undefined') { return true; } return false; },
5371415: () => { if ((typeof(navigator.mediaDevices) !== 'undefined') && (typeof(navigator.mediaDevices.getUserMedia) !== 'undefined')) { return true; } else if (typeof(navigator.webkitGetUserMedia) !== 'undefined') { return true; } return false; }, 5371543: () => { if ((typeof(navigator.mediaDevices) !== 'undefined') && (typeof(navigator.mediaDevices.getUserMedia) !== 'undefined')) { return true; } else if (typeof(navigator.webkitGetUserMedia) !== 'undefined') { return true; } return false; },
5371649: ($0) => { if(typeof(Module['SDL2']) === 'undefined') { Module['SDL2'] = {}; } var SDL2 = Module['SDL2']; if (!$0) { SDL2.audio = {}; } else { SDL2.capture = {}; } if (!SDL2.audioContext) { if (typeof(AudioContext) !== 'undefined') { SDL2.audioContext = new AudioContext(); } else if (typeof(webkitAudioContext) !== 'undefined') { SDL2.audioContext = new webkitAudioContext(); } if (SDL2.audioContext) { autoResumeAudioContext(SDL2.audioContext); } } return SDL2.audioContext === undefined ? -1 : 0; }, 5371777: ($0) => { if(typeof(Module['SDL2']) === 'undefined') { Module['SDL2'] = {}; } var SDL2 = Module['SDL2']; if (!$0) { SDL2.audio = {}; } else { SDL2.capture = {}; } if (!SDL2.audioContext) { if (typeof(AudioContext) !== 'undefined') { SDL2.audioContext = new AudioContext(); } else if (typeof(webkitAudioContext) !== 'undefined') { SDL2.audioContext = new webkitAudioContext(); } if (SDL2.audioContext) { autoResumeAudioContext(SDL2.audioContext); } } return SDL2.audioContext === undefined ? -1 : 0; },
5372142: () => { var SDL2 = Module['SDL2']; return SDL2.audioContext.sampleRate; }, 5372270: () => { var SDL2 = Module['SDL2']; return SDL2.audioContext.sampleRate; },
5372210: ($0, $1, $2, $3) => { var SDL2 = Module['SDL2']; var have_microphone = function(stream) { if (SDL2.capture.silenceTimer !== undefined) { clearTimeout(SDL2.capture.silenceTimer); SDL2.capture.silenceTimer = undefined; } SDL2.capture.mediaStreamNode = SDL2.audioContext.createMediaStreamSource(stream); SDL2.capture.scriptProcessorNode = SDL2.audioContext.createScriptProcessor($1, $0, 1); SDL2.capture.scriptProcessorNode.onaudioprocess = function(audioProcessingEvent) { if ((SDL2 === undefined) || (SDL2.capture === undefined)) { return; } audioProcessingEvent.outputBuffer.getChannelData(0).fill(0.0); SDL2.capture.currentCaptureBuffer = audioProcessingEvent.inputBuffer; dynCall('vi', $2, [$3]); }; SDL2.capture.mediaStreamNode.connect(SDL2.capture.scriptProcessorNode); SDL2.capture.scriptProcessorNode.connect(SDL2.audioContext.destination); SDL2.capture.stream = stream; }; var no_microphone = function(error) { }; SDL2.capture.silenceBuffer = SDL2.audioContext.createBuffer($0, $1, SDL2.audioContext.sampleRate); SDL2.capture.silenceBuffer.getChannelData(0).fill(0.0); var silence_callback = function() { SDL2.capture.currentCaptureBuffer = SDL2.capture.silenceBuffer; dynCall('vi', $2, [$3]); }; SDL2.capture.silenceTimer = setTimeout(silence_callback, ($1 / SDL2.audioContext.sampleRate) * 1000); if ((navigator.mediaDevices !== undefined) && (navigator.mediaDevices.getUserMedia !== undefined)) { navigator.mediaDevices.getUserMedia({ audio: true, video: false }).then(have_microphone).catch(no_microphone); } else if (navigator.webkitGetUserMedia !== undefined) { navigator.webkitGetUserMedia({ audio: true, video: false }, have_microphone, no_microphone); } }, 5372338: ($0, $1, $2, $3) => { var SDL2 = Module['SDL2']; var have_microphone = function(stream) { if (SDL2.capture.silenceTimer !== undefined) { clearTimeout(SDL2.capture.silenceTimer); SDL2.capture.silenceTimer = undefined; } SDL2.capture.mediaStreamNode = SDL2.audioContext.createMediaStreamSource(stream); SDL2.capture.scriptProcessorNode = SDL2.audioContext.createScriptProcessor($1, $0, 1); SDL2.capture.scriptProcessorNode.onaudioprocess = function(audioProcessingEvent) { if ((SDL2 === undefined) || (SDL2.capture === undefined)) { return; } audioProcessingEvent.outputBuffer.getChannelData(0).fill(0.0); SDL2.capture.currentCaptureBuffer = audioProcessingEvent.inputBuffer; dynCall('vi', $2, [$3]); }; SDL2.capture.mediaStreamNode.connect(SDL2.capture.scriptProcessorNode); SDL2.capture.scriptProcessorNode.connect(SDL2.audioContext.destination); SDL2.capture.stream = stream; }; var no_microphone = function(error) { }; SDL2.capture.silenceBuffer = SDL2.audioContext.createBuffer($0, $1, SDL2.audioContext.sampleRate); SDL2.capture.silenceBuffer.getChannelData(0).fill(0.0); var silence_callback = function() { SDL2.capture.currentCaptureBuffer = SDL2.capture.silenceBuffer; dynCall('vi', $2, [$3]); }; SDL2.capture.silenceTimer = setTimeout(silence_callback, ($1 / SDL2.audioContext.sampleRate) * 1000); if ((navigator.mediaDevices !== undefined) && (navigator.mediaDevices.getUserMedia !== undefined)) { navigator.mediaDevices.getUserMedia({ audio: true, video: false }).then(have_microphone).catch(no_microphone); } else if (navigator.webkitGetUserMedia !== undefined) { navigator.webkitGetUserMedia({ audio: true, video: false }, have_microphone, no_microphone); } },
5373862: ($0, $1, $2, $3) => { var SDL2 = Module['SDL2']; SDL2.audio.scriptProcessorNode = SDL2.audioContext['createScriptProcessor']($1, 0, $0); SDL2.audio.scriptProcessorNode['onaudioprocess'] = function (e) { if ((SDL2 === undefined) || (SDL2.audio === undefined)) { return; } SDL2.audio.currentOutputBuffer = e['outputBuffer']; dynCall('vi', $2, [$3]); }; SDL2.audio.scriptProcessorNode['connect'](SDL2.audioContext['destination']); }, 5373990: ($0, $1, $2, $3) => { var SDL2 = Module['SDL2']; SDL2.audio.scriptProcessorNode = SDL2.audioContext['createScriptProcessor']($1, 0, $0); SDL2.audio.scriptProcessorNode['onaudioprocess'] = function (e) { if ((SDL2 === undefined) || (SDL2.audio === undefined)) { return; } SDL2.audio.currentOutputBuffer = e['outputBuffer']; dynCall('vi', $2, [$3]); }; SDL2.audio.scriptProcessorNode['connect'](SDL2.audioContext['destination']); },
5374272: ($0, $1) => { var SDL2 = Module['SDL2']; var numChannels = SDL2.capture.currentCaptureBuffer.numberOfChannels; for (var c = 0; c < numChannels; ++c) { var channelData = SDL2.capture.currentCaptureBuffer.getChannelData(c); if (channelData.length != $1) { throw 'Web Audio capture buffer length mismatch! Destination size: ' + channelData.length + ' samples vs expected ' + $1 + ' samples!'; } if (numChannels == 1) { for (var j = 0; j < $1; ++j) { setValue($0 + (j * 4), channelData[j], 'float'); } } else { for (var j = 0; j < $1; ++j) { setValue($0 + (((j * numChannels) + c) * 4), channelData[j], 'float'); } } } }, 5374400: ($0, $1) => { var SDL2 = Module['SDL2']; var numChannels = SDL2.capture.currentCaptureBuffer.numberOfChannels; for (var c = 0; c < numChannels; ++c) { var channelData = SDL2.capture.currentCaptureBuffer.getChannelData(c); if (channelData.length != $1) { throw 'Web Audio capture buffer length mismatch! Destination size: ' + channelData.length + ' samples vs expected ' + $1 + ' samples!'; } if (numChannels == 1) { for (var j = 0; j < $1; ++j) { setValue($0 + (j * 4), channelData[j], 'float'); } } else { for (var j = 0; j < $1; ++j) { setValue($0 + (((j * numChannels) + c) * 4), channelData[j], 'float'); } } } },
5374877: ($0, $1) => { var SDL2 = Module['SDL2']; var numChannels = SDL2.audio.currentOutputBuffer['numberOfChannels']; for (var c = 0; c < numChannels; ++c) { var channelData = SDL2.audio.currentOutputBuffer['getChannelData'](c); if (channelData.length != $1) { throw 'Web Audio output buffer length mismatch! Destination size: ' + channelData.length + ' samples vs expected ' + $1 + ' samples!'; } for (var j = 0; j < $1; ++j) { channelData[j] = HEAPF32[$0 + ((j*numChannels + c) << 2) >> 2]; } } }, 5375005: ($0, $1) => { var SDL2 = Module['SDL2']; var numChannels = SDL2.audio.currentOutputBuffer['numberOfChannels']; for (var c = 0; c < numChannels; ++c) { var channelData = SDL2.audio.currentOutputBuffer['getChannelData'](c); if (channelData.length != $1) { throw 'Web Audio output buffer length mismatch! Destination size: ' + channelData.length + ' samples vs expected ' + $1 + ' samples!'; } for (var j = 0; j < $1; ++j) { channelData[j] = HEAPF32[$0 + ((j*numChannels + c) << 2) >> 2]; } } },
5375357: ($0) => { var SDL2 = Module['SDL2']; if ($0) { if (SDL2.capture.silenceTimer !== undefined) { clearTimeout(SDL2.capture.silenceTimer); } if (SDL2.capture.stream !== undefined) { var tracks = SDL2.capture.stream.getAudioTracks(); for (var i = 0; i < tracks.length; i++) { SDL2.capture.stream.removeTrack(tracks[i]); } SDL2.capture.stream = undefined; } if (SDL2.capture.scriptProcessorNode !== undefined) { SDL2.capture.scriptProcessorNode.onaudioprocess = function(audioProcessingEvent) {}; SDL2.capture.scriptProcessorNode.disconnect(); SDL2.capture.scriptProcessorNode = undefined; } if (SDL2.capture.mediaStreamNode !== undefined) { SDL2.capture.mediaStreamNode.disconnect(); SDL2.capture.mediaStreamNode = undefined; } if (SDL2.capture.silenceBuffer !== undefined) { SDL2.capture.silenceBuffer = undefined } SDL2.capture = undefined; } else { if (SDL2.audio.scriptProcessorNode != undefined) { SDL2.audio.scriptProcessorNode.disconnect(); SDL2.audio.scriptProcessorNode = undefined; } SDL2.audio = undefined; } if ((SDL2.audioContext !== undefined) && (SDL2.audio === undefined) && (SDL2.capture === undefined)) { SDL2.audioContext.close(); SDL2.audioContext = undefined; } }, 5375485: ($0) => { var SDL2 = Module['SDL2']; if ($0) { if (SDL2.capture.silenceTimer !== undefined) { clearTimeout(SDL2.capture.silenceTimer); } if (SDL2.capture.stream !== undefined) { var tracks = SDL2.capture.stream.getAudioTracks(); for (var i = 0; i < tracks.length; i++) { SDL2.capture.stream.removeTrack(tracks[i]); } SDL2.capture.stream = undefined; } if (SDL2.capture.scriptProcessorNode !== undefined) { SDL2.capture.scriptProcessorNode.onaudioprocess = function(audioProcessingEvent) {}; SDL2.capture.scriptProcessorNode.disconnect(); SDL2.capture.scriptProcessorNode = undefined; } if (SDL2.capture.mediaStreamNode !== undefined) { SDL2.capture.mediaStreamNode.disconnect(); SDL2.capture.mediaStreamNode = undefined; } if (SDL2.capture.silenceBuffer !== undefined) { SDL2.capture.silenceBuffer = undefined } SDL2.capture = undefined; } else { if (SDL2.audio.scriptProcessorNode != undefined) { SDL2.audio.scriptProcessorNode.disconnect(); SDL2.audio.scriptProcessorNode = undefined; } SDL2.audio = undefined; } if ((SDL2.audioContext !== undefined) && (SDL2.audio === undefined) && (SDL2.capture === undefined)) { SDL2.audioContext.close(); SDL2.audioContext = undefined; } },
5376529: ($0, $1, $2) => { var w = $0; var h = $1; var pixels = $2; if (!Module['SDL2']) Module['SDL2'] = {}; var SDL2 = Module['SDL2']; if (SDL2.ctxCanvas !== Module['canvas']) { SDL2.ctx = Module['createContext'](Module['canvas'], false, true); SDL2.ctxCanvas = Module['canvas']; } if (SDL2.w !== w || SDL2.h !== h || SDL2.imageCtx !== SDL2.ctx) { SDL2.image = SDL2.ctx.createImageData(w, h); SDL2.w = w; SDL2.h = h; SDL2.imageCtx = SDL2.ctx; } var data = SDL2.image.data; var src = pixels >> 2; var dst = 0; var num; if (typeof CanvasPixelArray !== 'undefined' && data instanceof CanvasPixelArray) { num = data.length; while (dst < num) { var val = HEAP32[src]; data[dst ] = val & 0xff; data[dst+1] = (val >> 8) & 0xff; data[dst+2] = (val >> 16) & 0xff; data[dst+3] = 0xff; src++; dst += 4; } } else { if (SDL2.data32Data !== data) { SDL2.data32 = new Int32Array(data.buffer); SDL2.data8 = new Uint8Array(data.buffer); SDL2.data32Data = data; } var data32 = SDL2.data32; num = data32.length; data32.set(HEAP32.subarray(src, src + num)); var data8 = SDL2.data8; var i = 3; var j = i + 4*num; if (num % 8 == 0) { while (i < j) { data8[i] = 0xff; i = i + 4 | 0; data8[i] = 0xff; i = i + 4 | 0; data8[i] = 0xff; i = i + 4 | 0; data8[i] = 0xff; i = i + 4 | 0; data8[i] = 0xff; i = i + 4 | 0; data8[i] = 0xff; i = i + 4 | 0; data8[i] = 0xff; i = i + 4 | 0; data8[i] = 0xff; i = i + 4 | 0; } } else { while (i < j) { data8[i] = 0xff; i = i + 4 | 0; } } } SDL2.ctx.putImageData(SDL2.image, 0, 0); }, 5376657: ($0, $1, $2) => { var w = $0; var h = $1; var pixels = $2; if (!Module['SDL2']) Module['SDL2'] = {}; var SDL2 = Module['SDL2']; if (SDL2.ctxCanvas !== Module['canvas']) { SDL2.ctx = Module['createContext'](Module['canvas'], false, true); SDL2.ctxCanvas = Module['canvas']; } if (SDL2.w !== w || SDL2.h !== h || SDL2.imageCtx !== SDL2.ctx) { SDL2.image = SDL2.ctx.createImageData(w, h); SDL2.w = w; SDL2.h = h; SDL2.imageCtx = SDL2.ctx; } var data = SDL2.image.data; var src = pixels >> 2; var dst = 0; var num; if (typeof CanvasPixelArray !== 'undefined' && data instanceof CanvasPixelArray) { num = data.length; while (dst < num) { var val = HEAP32[src]; data[dst ] = val & 0xff; data[dst+1] = (val >> 8) & 0xff; data[dst+2] = (val >> 16) & 0xff; data[dst+3] = 0xff; src++; dst += 4; } } else { if (SDL2.data32Data !== data) { SDL2.data32 = new Int32Array(data.buffer); SDL2.data8 = new Uint8Array(data.buffer); SDL2.data32Data = data; } var data32 = SDL2.data32; num = data32.length; data32.set(HEAP32.subarray(src, src + num)); var data8 = SDL2.data8; var i = 3; var j = i + 4*num; if (num % 8 == 0) { while (i < j) { data8[i] = 0xff; i = i + 4 | 0; data8[i] = 0xff; i = i + 4 | 0; data8[i] = 0xff; i = i + 4 | 0; data8[i] = 0xff; i = i + 4 | 0; data8[i] = 0xff; i = i + 4 | 0; data8[i] = 0xff; i = i + 4 | 0; data8[i] = 0xff; i = i + 4 | 0; data8[i] = 0xff; i = i + 4 | 0; } } else { while (i < j) { data8[i] = 0xff; i = i + 4 | 0; } } } SDL2.ctx.putImageData(SDL2.image, 0, 0); },
5377998: ($0, $1, $2, $3, $4) => { var w = $0; var h = $1; var hot_x = $2; var hot_y = $3; var pixels = $4; var canvas = document.createElement("canvas"); canvas.width = w; canvas.height = h; var ctx = canvas.getContext("2d"); var image = ctx.createImageData(w, h); var data = image.data; var src = pixels >> 2; var dst = 0; var num; if (typeof CanvasPixelArray !== 'undefined' && data instanceof CanvasPixelArray) { num = data.length; while (dst < num) { var val = HEAP32[src]; data[dst ] = val & 0xff; data[dst+1] = (val >> 8) & 0xff; data[dst+2] = (val >> 16) & 0xff; data[dst+3] = (val >> 24) & 0xff; src++; dst += 4; } } else { var data32 = new Int32Array(data.buffer); num = data32.length; data32.set(HEAP32.subarray(src, src + num)); } ctx.putImageData(image, 0, 0); var url = hot_x === 0 && hot_y === 0 ? "url(" + canvas.toDataURL() + "), auto" : "url(" + canvas.toDataURL() + ") " + hot_x + " " + hot_y + ", auto"; var urlBuf = _malloc(url.length + 1); stringToUTF8(url, urlBuf, url.length + 1); return urlBuf; }, 5378126: ($0, $1, $2, $3, $4) => { var w = $0; var h = $1; var hot_x = $2; var hot_y = $3; var pixels = $4; var canvas = document.createElement("canvas"); canvas.width = w; canvas.height = h; var ctx = canvas.getContext("2d"); var image = ctx.createImageData(w, h); var data = image.data; var src = pixels >> 2; var dst = 0; var num; if (typeof CanvasPixelArray !== 'undefined' && data instanceof CanvasPixelArray) { num = data.length; while (dst < num) { var val = HEAP32[src]; data[dst ] = val & 0xff; data[dst+1] = (val >> 8) & 0xff; data[dst+2] = (val >> 16) & 0xff; data[dst+3] = (val >> 24) & 0xff; src++; dst += 4; } } else { var data32 = new Int32Array(data.buffer); num = data32.length; data32.set(HEAP32.subarray(src, src + num)); } ctx.putImageData(image, 0, 0); var url = hot_x === 0 && hot_y === 0 ? "url(" + canvas.toDataURL() + "), auto" : "url(" + canvas.toDataURL() + ") " + hot_x + " " + hot_y + ", auto"; var urlBuf = _malloc(url.length + 1); stringToUTF8(url, urlBuf, url.length + 1); return urlBuf; },
5378987: ($0) => { if (Module['canvas']) { Module['canvas'].style['cursor'] = UTF8ToString($0); } }, 5379115: ($0) => { if (Module['canvas']) { Module['canvas'].style['cursor'] = UTF8ToString($0); } },
5379070: () => { if (Module['canvas']) { Module['canvas'].style['cursor'] = 'none'; } }, 5379198: () => { if (Module['canvas']) { Module['canvas'].style['cursor'] = 'none'; } },
5379139: () => { return window.innerWidth; }, 5379267: () => { return window.innerWidth; },
5379169: () => { return window.innerHeight; } 5379297: () => { return window.innerHeight; }
}; };

Binary file not shown.

@ -1,8 +1,23 @@
#include "util.h" #include "util.h"
#include "olcPixelGameEngine.h"
namespace util{ namespace util{
float random(float range){ float random(float range){
return float(rand())/RAND_MAX*range; return float(rand())/RAND_MAX*range;
} }
void ApplyMatrixEffect(PixelGameEngine*pge,Renderable&r,Renderable&originalImg,std::unique_ptr<Renderable>&matrixImg){
pge->SetDrawTarget(r.Sprite());
pge->Clear(BLANK);
for(int y=0;y<r.Sprite()->height;y++){
for(int x=0;x<r.Sprite()->width;x++){
Pixel col=originalImg.Sprite()->GetPixel(x,y);
if(col==WHITE){
pge->Draw({x,y},matrixImg->Sprite()->GetPixel(x,y));
} else {
pge->Draw({x,y},originalImg.Sprite()->GetPixel(x,y));
}
}
}
pge->SetDrawTarget(nullptr);
r.Decal()->Update();
};
} }

@ -1,5 +1,7 @@
#pragma once #pragma once
#include "olcPixelGameEngine.h"
namespace util{ namespace util{
float random(float range); float random(float range);
void ApplyMatrixEffect(PixelGameEngine*pge,Renderable&r,Renderable&originalImg,std::unique_ptr<Renderable>&matrixImg);
} }
Loading…
Cancel
Save