Title screen fancy effects added
This commit is contained in:
parent
2d63b9c5cc
commit
7e2bf32734
@ -4,5 +4,6 @@
|
||||
enum class GameState{
|
||||
MAIN_MENU,
|
||||
GAMEPLAY,
|
||||
COMPLETED
|
||||
COMPLETED,
|
||||
CREDITS
|
||||
};
|
@ -44,5 +44,6 @@ enum Image{
|
||||
SPOOK_HOODED_FIGURE,
|
||||
RESTART,
|
||||
RESTART_HOVER,
|
||||
SHIELD_BUBBLE,
|
||||
};
|
||||
|
||||
|
@ -151,4 +151,6 @@ Space - Gravity (Ambient 1)
|
||||
3 Epic Boss Battles (Cut end for loop) (Ambient 3)
|
||||
|
||||
|
||||
1 Glorious Venture (Ending theme?)
|
||||
1 Glorious Venture (Ending theme?)
|
||||
|
||||
Credits
|
@ -47,7 +47,7 @@ void VirusAttack::InitializeImages(){
|
||||
LoadImage(RNG,"assets/rng.png");
|
||||
LoadImage(SPD,"assets/spd.png");
|
||||
LoadImage(TARGETING_LINE,"assets/targetLine.png");
|
||||
LoadImage(ATTACKING_LINE,"assets/attackLine.png");
|
||||
LoadImage(ATTACKING_LINE,"assets/attackLine.png",false,false);
|
||||
LoadImage(RLD_ICON,"assets/rld_icon.png");
|
||||
LoadImage(PRC_ICON,"assets/prc_icon.png");
|
||||
LoadImage(RNG_ICON,"assets/rng_icon.png");
|
||||
@ -66,6 +66,18 @@ void VirusAttack::InitializeImages(){
|
||||
LoadImage(SPOOK_HOODED_FIGURE,"assets/spook_hooded_figure.png");
|
||||
LoadImage(RESTART,"assets/restart.png");
|
||||
LoadImage(RESTART_HOVER,"assets/restartHover.png");
|
||||
LoadImage(SHIELD_BUBBLE,"assets/shieldbubble.png");
|
||||
|
||||
titleScreenText.Create(426,100,false,true);
|
||||
SetDrawTarget(titleScreenText.Sprite());
|
||||
Clear(BLANK);
|
||||
float textScale=3;
|
||||
vf2d textSize=GetTextSizeProp("Virus Attack")*textScale;
|
||||
DrawShadowStringProp(titleScreenText.Sprite()->Size()/2-textSize/2,"Virus Attack",WHITE,BLACK,{textScale,textScale},textScale);
|
||||
SetDrawTarget(nullptr);
|
||||
titleScreenText.Decal()->Update();
|
||||
textOrientationX=titleScreenText.Sprite()->width/2;
|
||||
textOrientationY=titleScreenText.Sprite()->height-12;
|
||||
}
|
||||
|
||||
void VirusAttack::InitializeLevelData(){
|
||||
@ -119,6 +131,7 @@ void VirusAttack::InitializeLevelData(){
|
||||
|
||||
bool VirusAttack::OnUserCreate(){
|
||||
srand(time(NULL));
|
||||
currentBackCol=newCol=colorChangeOptions[rand()%colorChangeOptions.size()];
|
||||
SetPixelMode(Pixel::MASK);
|
||||
|
||||
game.Initialise(GetScreenSize());
|
||||
@ -142,6 +155,8 @@ bool VirusAttack::OnUserCreate(){
|
||||
IMAGES[MATRIX]->Create(64,64,false,false);
|
||||
IMAGES[MATRIX]->Sprite()->SetSampleMode(Sprite::PERIODIC);
|
||||
|
||||
attackingLineModified.Create(IMAGES[ATTACKING_LINE]->Sprite()->width,IMAGES[ATTACKING_LINE]->Sprite()->height,false,false);
|
||||
|
||||
AL.AudioSystemInit();
|
||||
InitializeSounds();
|
||||
|
||||
@ -244,7 +259,8 @@ void VirusAttack::InitializeGUIs(){
|
||||
campaignStartButton=new QuickGUI::TransparentButton(mainMenu,"Start Campaign",{float(ScreenWidth()/2)-120.f,80+47.5f*0+10},{240,24},CONSTANT::INCREASE_VALUE_COLOR);
|
||||
audioToggleButton=new QuickGUI::TransparentButton(mainMenu,"Audio: On",{float(ScreenWidth()/2)-120.f,80+47.5f*1+10},{240,24},CONSTANT::INCREASE_VALUE_COLOR);
|
||||
difficultyToggleButton=new QuickGUI::TransparentButton(mainMenu,"Difficulty: Normal",{float(ScreenWidth()/2)-120.f,80+47.5f*2+10},{240,24},CONSTANT::INCREASE_VALUE_COLOR);
|
||||
exitGameButton=new QuickGUI::TransparentButton(mainMenu,"Exit Game",{float(ScreenWidth()/2)-120.f,80+47.5f*3+10},{240,24},CONSTANT::INCREASE_VALUE_COLOR);
|
||||
creditsButton=new QuickGUI::TransparentButton(mainMenu,"Credits",{float(ScreenWidth()/2)-120.f,80+47.5f*3+10},{240,24},CONSTANT::INCREASE_VALUE_COLOR);
|
||||
exitGameButton=new QuickGUI::TransparentButton(mainMenu,"Exit Game",{float(ScreenWidth()/2)-120.f,80+47.5f*4+10},{240,24},CONSTANT::INCREASE_VALUE_COLOR);
|
||||
}
|
||||
|
||||
void VirusAttack::InitializeScenarios(){
|
||||
@ -672,6 +688,77 @@ bool VirusAttack::OnUserUpdate(float fElapsedTime){
|
||||
#pragma region MAIN_MENU
|
||||
case GameState::MAIN_MENU:{
|
||||
mainMenu.Update(this);
|
||||
titleScreenY=std::min(0.f,titleScreenY+fElapsedTime*120);
|
||||
nextColorChange=std::max(0.f,nextColorChange-fElapsedTime);
|
||||
transition=std::min(1.f,transition+fElapsedTime);
|
||||
if(nextColorChange==0){
|
||||
currentBackCol=newCol;
|
||||
newCol=colorChangeOptions[rand()%colorChangeOptions.size()];
|
||||
randomBackgroundOffset={util::random(128),util::random(128)};
|
||||
nextColorChange=10;
|
||||
transition=0;
|
||||
}
|
||||
if(titleScreenY==0){
|
||||
textOrientationX=std::max(0.f,textOrientationX-fElapsedTime*50);
|
||||
textOrientationY=std::max(0.f,textOrientationY-fElapsedTime*25);
|
||||
}
|
||||
DrawPartialDecal({0,0},GetScreenSize(),IMAGES[MATRIX]->Decal(),randomBackgroundOffset+game.GetWorldOffset()*(vf2d{32,32}/vf2d(GetScreenSize()))*game.GetWorldScale(),{32,32},PixelLerp(Pixel{currentBackCol.r,currentBackCol.g,currentBackCol.b,255},Pixel{newCol.r,newCol.g,newCol.b,255},transition));
|
||||
|
||||
vf2d setPieceOffset={48,titleScreenY};
|
||||
{
|
||||
vf2d offset=vf2d{0,0}+setPieceOffset;
|
||||
DrawWarpedDecal(IMAGES[RAM_BANK]->Decal(),{vf2d{24,24}+offset,vf2d{24,104}+offset,vf2d{72,88}+offset,vf2d{72,40}+offset},Pixel{192,192,255});
|
||||
}
|
||||
{
|
||||
vf2d offset=vf2d{100,-52}+setPieceOffset;
|
||||
DrawWarpedDecal(IMAGES[MEMORY_GUARD]->Decal(),{vf2d{20,48}+offset,vf2d{20,108}+offset,vf2d{96,104}+offset,vf2d{96,52}+offset},Pixel{192,192,255});
|
||||
}
|
||||
{
|
||||
vf2d offset=vf2d{76,-20}+setPieceOffset;
|
||||
DrawWarpedDecal(IMAGES[BIT_RESTORER]->Decal(),{vf2d{12,52}+offset,vf2d{12,104}+offset,vf2d{64,92}+offset,vf2d{64,64}+offset},Pixel{192,192,255});
|
||||
}
|
||||
DrawCurvedTexture(vf2d{170-48,70}+setPieceOffset,{-30,-20},attackingLineModified.Decal(),{arrowScroll/2,0},CONSTANT::HEALER_ATTACK_COL,1.5);
|
||||
{
|
||||
vf2d offset=vf2d{48,0}+setPieceOffset;
|
||||
DrawWarpedDecal(IMAGES[LEFT_SHIFTER]->Decal(),{vf2d{20,48}+offset,vf2d{20,108}+offset,vf2d{68,96}+offset,vf2d{68,60}+offset},Pixel{192,192,255});
|
||||
}
|
||||
if(flickerAmt>0.6){
|
||||
flickerAmt-=util::random(0.4);
|
||||
} else {
|
||||
flickerAmt=1;
|
||||
}
|
||||
DrawDecal(vf2d{12,-28}+setPieceOffset,IMAGES[SHIELD_BUBBLE]->Decal(),{2.4,2.8},{255,255,255,uint8_t(flickerAmt*255)});
|
||||
{
|
||||
vf2d offset=vf2d{250,-18}+setPieceOffset;
|
||||
DrawWarpedDecal(IMAGES[RAM_BANK]->Decal(),{vf2d{8,38}+offset,vf2d{8,90}+offset,vf2d{68,102}+offset,vf2d{68,26}+offset},Pixel{255,192,192});
|
||||
}
|
||||
{
|
||||
vf2d offset=vf2d{220,0}+setPieceOffset;
|
||||
DrawWarpedDecal(IMAGES[MEMORY_SWAPPER]->Decal(),{vf2d{20,60}+offset,vf2d{20,96}+offset,vf2d{68,108}+offset,vf2d{68,48}+offset},Pixel{255,192,192});
|
||||
}
|
||||
arrowScroll-=fElapsedTime*2;
|
||||
SetDrawTarget(attackingLineModified.Sprite());
|
||||
Clear(BLANK);
|
||||
for(int y=0;y<IMAGES[ATTACKING_LINE]->Sprite()->height;y++){
|
||||
for(int x=0;x<IMAGES[ATTACKING_LINE]->Sprite()->width;x++){
|
||||
Pixel col=IMAGES[ATTACKING_LINE]->Sprite()->GetPixel(x,y);
|
||||
if(col.a>0){
|
||||
if(col==WHITE){
|
||||
Draw(x,y,IMAGES[MATRIX]->Sprite()->GetPixel(x,y));
|
||||
}else{
|
||||
Draw(x,y,IMAGES[ATTACKING_LINE]->Sprite()->GetPixel(x,y));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
SetDrawTarget(nullptr);
|
||||
attackingLineModified.Decal()->Update();
|
||||
//DrawPartialWarpedDecal()
|
||||
DrawCurvedTexture(vf2d{150-48,80}+setPieceOffset,{160,-30},attackingLineModified.Decal(),{arrowScroll,0},CONSTANT::ATTACKER_ATTACK_COL,0.8);
|
||||
{
|
||||
vf2d offset={0,20};
|
||||
DrawWarpedDecal(titleScreenText.Decal(),{vf2d{float(textOrientationX),float(textOrientationY)}+offset,vf2d{0,float(titleScreenText.Sprite()->height)}+offset,vf2d{float(titleScreenText.Sprite()->width),float(titleScreenText.Sprite()->height)}+offset,vf2d{float(titleScreenText.Sprite()->width-textOrientationX),float(textOrientationY)}+offset});
|
||||
}
|
||||
mainMenu.DrawDecal(this);
|
||||
}break;
|
||||
#pragma endregion
|
||||
@ -831,6 +918,11 @@ bool VirusAttack::OnUserUpdate(float fElapsedTime){
|
||||
DrawPartialDecal({0,0},GetScreenSize(),IMAGES[MATRIX]->Decal(),randomBackgroundOffset+game.GetWorldOffset()*(vf2d{32,32}/vf2d(GetScreenSize()))*game.GetWorldScale(),{32,32},Pixel{currentLevel->levelColor.r,currentLevel->levelColor.g,currentLevel->levelColor.b,164}/2);
|
||||
}break;
|
||||
#pragma endregion
|
||||
#pragma region CREDITS
|
||||
case GameState::CREDITS:{
|
||||
DrawPartialDecal({0,0},GetScreenSize(),IMAGES[MATRIX]->Decal(),randomBackgroundOffset+game.GetWorldOffset()*(vf2d{32,32}/vf2d(GetScreenSize()))*game.GetWorldScale(),{32,32},Pixel{currentLevel->levelColor.r,currentLevel->levelColor.g,currentLevel->levelColor.b,164}/2);
|
||||
}break;
|
||||
#pragma endregion
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -1114,6 +1206,43 @@ void VirusAttack::HandleRestartButton(float fElapsedTime){
|
||||
}
|
||||
}
|
||||
|
||||
void VirusAttack::DrawCurvedTexture(vf2d offset,vf2d size,Decal*decal,vf2d texOffset,Pixel col,float curveThickness){
|
||||
vf2d curveMultiplier=size;
|
||||
vf2d curveDisplacement=offset;
|
||||
std::vector<vf2d>curvePoints={{0.f,abs(sin((0)*float(PI)))},{0.1,abs(sin((0.1f)*float(PI)))},{0.2,abs(sin((0.2f)*float(PI)))},{0.3,abs(sin((0.3f)*float(PI)))},{0.4,abs(sin((0.4f)*float(PI)))},{0.5,abs(sin((0.5f)*float(PI)))},{0.6,abs(sin((0.6f)*float(PI)))},{0.7,abs(sin((0.7f)*float(PI)))},{0.8,abs(sin((0.8f)*float(PI)))},{0.9,abs(sin((0.9f)*float(PI)))},{1.f,abs(sin((1.f)*float(PI)))}};
|
||||
vf2d curve2offset={0.f,curveThickness};
|
||||
std::vector<vf2d>curvePoints2={vf2d{0.f,abs(sin((0)*float(PI)))}+curve2offset,vf2d{0.1,abs(sin((0.1f)*float(PI)))}+curve2offset,vf2d{0.2,abs(sin((0.2f)*float(PI)))}+curve2offset,vf2d{0.3,abs(sin((0.3f)*float(PI)))}+curve2offset,vf2d{0.4,abs(sin((0.4f)*float(PI)))}+curve2offset,vf2d{0.5,abs(sin((0.5f)*float(PI)))}+curve2offset,vf2d{0.6f,abs(sin((0.6f)*float(PI)))}+curve2offset,vf2d{0.7,abs(sin((0.7f)*float(PI)))}+curve2offset,vf2d{0.8,abs(sin((0.8f)*float(PI)))}+curve2offset,vf2d{0.9,abs(sin((0.9f)*float(PI)))}+curve2offset,vf2d{1.f,abs(sin((1.f)*float(PI)))}+curve2offset};
|
||||
std::vector<vf2d>combinedCurvePoints={
|
||||
curvePoints2[0]*curveMultiplier+curveDisplacement,curvePoints[0]*curveMultiplier+curveDisplacement,
|
||||
curvePoints2[1]*curveMultiplier+curveDisplacement,curvePoints[1]*curveMultiplier+curveDisplacement,
|
||||
curvePoints2[2]*curveMultiplier+curveDisplacement,curvePoints[2]*curveMultiplier+curveDisplacement,
|
||||
curvePoints2[3]*curveMultiplier+curveDisplacement,curvePoints[3]*curveMultiplier+curveDisplacement,
|
||||
curvePoints2[4]*curveMultiplier+curveDisplacement,curvePoints[4]*curveMultiplier+curveDisplacement,
|
||||
curvePoints2[5]*curveMultiplier+curveDisplacement,curvePoints[5]*curveMultiplier+curveDisplacement,
|
||||
curvePoints2[6]*curveMultiplier+curveDisplacement,curvePoints[6]*curveMultiplier+curveDisplacement,
|
||||
curvePoints2[7]*curveMultiplier+curveDisplacement,curvePoints[7]*curveMultiplier+curveDisplacement,
|
||||
curvePoints2[8]*curveMultiplier+curveDisplacement,curvePoints[8]*curveMultiplier+curveDisplacement,
|
||||
curvePoints2[9]*curveMultiplier+curveDisplacement,curvePoints[9]*curveMultiplier+curveDisplacement,
|
||||
curvePoints2[10]*curveMultiplier+curveDisplacement,curvePoints[10]*curveMultiplier+curveDisplacement,
|
||||
};
|
||||
std::vector<vf2d>combinedUVPoints={
|
||||
{curvePoints[0].y+texOffset.x,1},{curvePoints[0].y+texOffset.x,0},
|
||||
{curvePoints[1].y+texOffset.x,1},{curvePoints[1].y+texOffset.x,0},
|
||||
{curvePoints[2].y+texOffset.x,1},{curvePoints[2].y+texOffset.x,0},
|
||||
{curvePoints[3].y+texOffset.x,1},{curvePoints[3].y+texOffset.x,0},
|
||||
{curvePoints[4].y+texOffset.x,1},{curvePoints[4].y+texOffset.x,0},
|
||||
{1-curvePoints[5].y+texOffset.x+1,1},{1-curvePoints[5].y+texOffset.x+1,0},
|
||||
{1-curvePoints[6].y+texOffset.x+1,1},{1-curvePoints[6].y+texOffset.x+1,0},
|
||||
{1-curvePoints[7].y+texOffset.x+1,1},{1-curvePoints[7].y+texOffset.x+1,0},
|
||||
{1-curvePoints[8].y+texOffset.x+1,1},{1-curvePoints[8].y+texOffset.x+1,0},
|
||||
{1-curvePoints[9].y+texOffset.x+1,1},{1-curvePoints[9].y+texOffset.x+1,0},
|
||||
{1-curvePoints[10].y+texOffset.x+1,1},{1-curvePoints[10].y+texOffset.x+1,0},
|
||||
};
|
||||
SetDecalStructure(DecalStructure::STRIP);
|
||||
DrawPolygonDecal(decal,combinedCurvePoints,combinedUVPoints,col);
|
||||
SetDecalStructure(DecalStructure::FAN);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
VirusAttack app;
|
||||
|
@ -70,6 +70,7 @@ private:
|
||||
QuickGUI::TransparentButton*campaignStartButton;
|
||||
QuickGUI::TransparentButton*audioToggleButton;
|
||||
QuickGUI::TransparentButton*difficultyToggleButton;
|
||||
QuickGUI::TransparentButton*creditsButton;
|
||||
QuickGUI::TransparentButton*exitGameButton;
|
||||
QuickGUI::Manager restartManager;
|
||||
QuickGUI::TransparentImageButton*restartButton;
|
||||
@ -111,6 +112,18 @@ private:
|
||||
bool restartButtonHeldDown=false;
|
||||
float restartButtonHoldTime=0;
|
||||
GameState state=GameState::MAIN_MENU;
|
||||
float nextColorChange=10;
|
||||
std::array<Pixel,7>colorChangeOptions={VERY_DARK_BLUE,VERY_DARK_CYAN,VERY_DARK_GREEN,VERY_DARK_GREY,VERY_DARK_MAGENTA,VERY_DARK_RED,VERY_DARK_YELLOW};
|
||||
Pixel currentBackCol;
|
||||
Pixel newCol;
|
||||
float transition=0;
|
||||
float flickerAmt=1;
|
||||
float arrowScroll=0;
|
||||
Renderable attackingLineModified;
|
||||
Renderable titleScreenText;
|
||||
float titleScreenY=-200;
|
||||
float textOrientationY=0;
|
||||
float textOrientationX=0;
|
||||
|
||||
std::string objective="";
|
||||
|
||||
@ -149,6 +162,7 @@ private:
|
||||
void PerformLevelTransition(float fElapsedTime);
|
||||
void RestartLevel();
|
||||
void HandleRestartButton(float fElapsedTime);
|
||||
void DrawCurvedTexture(vf2d offset,vf2d size,Decal*decal,vf2d texOffset,Pixel col=WHITE,float curveThickness=0.8);
|
||||
|
||||
public:
|
||||
VirusAttack();
|
||||
|
BIN
olcCodeJam2023Entry/assets/shieldbubble.png
Normal file
BIN
olcCodeJam2023Entry/assets/shieldbubble.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.3 KiB |
@ -1108,8 +1108,9 @@ namespace olc
|
||||
void DrawString(const olc::vi2d& pos, const std::string& sText, Pixel col = olc::WHITE, uint32_t scale = 1);
|
||||
olc::vi2d GetTextSize(const std::string& s);
|
||||
// Draws a single line of text - non-monospaced
|
||||
void DrawStringProp(int32_t x, int32_t y, const std::string& sText, Pixel col = olc::WHITE, uint32_t scale = 1);
|
||||
void DrawStringProp(const olc::vi2d& pos, const std::string& sText, Pixel col = olc::WHITE, uint32_t scale = 1);
|
||||
void DrawStringProp(int32_t x, int32_t y, const std::string& sText, Pixel col = olc::WHITE, uint32_t scale = 1);
|
||||
void DrawShadowStringProp(const olc::vi2d& pos, const std::string& sText, Pixel col = olc::WHITE, const Pixel shadowCol = olc::BLACK, const olc::vf2d& scale = { 1.0f, 1.0f },const float shadowSizeFactor=1);
|
||||
olc::vi2d GetTextSizeProp(const std::string& s);
|
||||
|
||||
// Decal Quad functions
|
||||
@ -3520,6 +3521,17 @@ namespace olc
|
||||
SetPixelMode(m);
|
||||
}
|
||||
|
||||
void PixelGameEngine::DrawShadowStringProp(const olc::vi2d& pos, const std::string& sText, Pixel col, const Pixel shadowCol, const olc::vf2d& scale,const float shadowSizeFactor){
|
||||
for(float y=-shadowSizeFactor;y<=shadowSizeFactor+0.1;y+=shadowSizeFactor/2){
|
||||
for(float x=-shadowSizeFactor;x<=shadowSizeFactor+0.1;x+=shadowSizeFactor/2){
|
||||
if(x!=0||y!=0){
|
||||
DrawStringProp(pos.x+x,pos.y+y, sText, shadowCol,int(scale.x));
|
||||
}
|
||||
}
|
||||
}
|
||||
DrawStringProp(pos.x,pos.y, sText, col,int(scale.x));
|
||||
}
|
||||
|
||||
void PixelGameEngine::SetPixelMode(Pixel::Mode m)
|
||||
{ nPixelMode = m; }
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user