|
|
|
|
#pragma region License
|
|
|
|
|
/*
|
|
|
|
|
License (OLC-3)
|
|
|
|
|
~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
Copyright 2024 Joshua Sigona <sigonasr2@gmail.com>
|
|
|
|
|
|
|
|
|
|
Redistribution and use in source and binary forms, with or without modification,
|
|
|
|
|
are permitted provided that the following conditions are met:
|
|
|
|
|
|
|
|
|
|
1. Redistributions or derivations of source code must retain the above copyright
|
|
|
|
|
notice, this list of conditions and the following disclaimer.
|
|
|
|
|
|
|
|
|
|
2. Redistributions or derivative works in binary form must reproduce the above
|
|
|
|
|
copyright notice. This list of conditions and the following disclaimer must be
|
|
|
|
|
reproduced in the documentation and/or other materials provided with the distribution.
|
|
|
|
|
|
|
|
|
|
3. Neither the name of the copyright holder nor the names of its contributors may
|
|
|
|
|
be used to endorse or promote products derived from this software without specific
|
|
|
|
|
prior written permission.
|
|
|
|
|
|
|
|
|
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
|
|
|
|
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
|
|
|
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
|
|
|
|
SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
|
|
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
|
|
|
|
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
|
|
|
|
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
|
|
|
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
|
|
|
|
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
|
|
|
SUCH DAMAGE.
|
|
|
|
|
|
|
|
|
|
Portions of this software are copyright <EFBFBD> 2023 The FreeType
|
|
|
|
|
Project (www.freetype.org). Please see LICENSE_FT.txt for more information.
|
|
|
|
|
All rights reserved.
|
|
|
|
|
*/
|
|
|
|
|
#pragma endregion
|
|
|
|
|
#include "TitleScreen.h"
|
|
|
|
|
#include "safemap.h"
|
|
|
|
|
#include "DEFINES.h"
|
|
|
|
|
#include "util.h"
|
|
|
|
|
#include "AdventuresInLestoria.h"
|
|
|
|
|
#include "Menu.h"
|
|
|
|
|
|
|
|
|
|
INCLUDE_GFX
|
|
|
|
|
INCLUDE_game
|
|
|
|
|
|
|
|
|
|
using Particle=TitleScreen::Particle;
|
|
|
|
|
|
|
|
|
|
std::vector<Particle>TitleScreen::particles;
|
|
|
|
|
TitleScreen::State TitleScreen::state=State::BUILDING;
|
|
|
|
|
const float TitleScreen::animationTime=16.0f;
|
|
|
|
|
float TitleScreen::currentAnimationTime=0.0f;
|
|
|
|
|
|
|
|
|
|
void TitleScreen::Initialize(){
|
|
|
|
|
Sprite*titleBackSpr=GFX["title_back.png"].Sprite();
|
|
|
|
|
vf2d titleCenteredOffset={game->ScreenWidth()/2.f-titleBackSpr->width/2,game->ScreenHeight()/2.f-titleBackSpr->height/2};
|
|
|
|
|
for(int y=0;y<titleBackSpr->height;y+=2){
|
|
|
|
|
for(int x=0;x<titleBackSpr->width;x+=2){
|
|
|
|
|
const Pixel&p=titleBackSpr->GetPixel(x,y);
|
|
|
|
|
if(p.a!=0){
|
|
|
|
|
particles.emplace_back(vf2d{0,0},1.f,p,0.f,titleCenteredOffset+vf2d{float(x+1),float(y+1)});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
Reset();
|
|
|
|
|
}
|
|
|
|
|
void TitleScreen::Reset(){
|
|
|
|
|
for(Particle&p:particles){
|
|
|
|
|
switch(util::random()%4){
|
|
|
|
|
case 0:{ //Top Edge
|
|
|
|
|
p.pos.y=-10;
|
|
|
|
|
p.pos.x=util::random(game->ScreenWidth());
|
|
|
|
|
}break;
|
|
|
|
|
case 1:{ //Left Edge
|
|
|
|
|
p.pos.x=-10;
|
|
|
|
|
p.pos.y=util::random(game->ScreenHeight());
|
|
|
|
|
}break;
|
|
|
|
|
case 2:{ //Right Edge
|
|
|
|
|
p.pos.x=game->GetScreenSize().x+10;
|
|
|
|
|
p.pos.y=util::random(game->ScreenHeight());
|
|
|
|
|
}break;
|
|
|
|
|
case 3:{ //Bottom Edge
|
|
|
|
|
p.pos.y=game->GetScreenSize().y+10;
|
|
|
|
|
p.pos.x=util::random(game->ScreenWidth());
|
|
|
|
|
}break;
|
|
|
|
|
}
|
|
|
|
|
p.rot=util::random(4*PI)-2*PI;
|
|
|
|
|
p.scale=util::random(5)+5;
|
|
|
|
|
}
|
|
|
|
|
currentAnimationTime=0.0f;
|
|
|
|
|
}
|
|
|
|
|
void TitleScreen::Update(){
|
|
|
|
|
currentAnimationTime=std::clamp(currentAnimationTime+game->GetElapsedTime(),0.f,5.f);
|
|
|
|
|
switch(state){
|
|
|
|
|
case BUILDING:{
|
|
|
|
|
double t=currentAnimationTime/animationTime;
|
|
|
|
|
for(Particle&p:particles){
|
|
|
|
|
p.pos=p.pos.lerp(p.targetPos,t);
|
|
|
|
|
p.rot=util::lerp(p.rot,0,t);
|
|
|
|
|
p.scale=util::lerp(p.scale,1,t);
|
|
|
|
|
}
|
|
|
|
|
if(currentAnimationTime==5.0f){
|
|
|
|
|
state=WAITING;
|
|
|
|
|
currentAnimationTime=0.f;
|
|
|
|
|
}
|
|
|
|
|
}break;
|
|
|
|
|
case WAITING:{
|
|
|
|
|
if(currentAnimationTime==5.0f){
|
|
|
|
|
state=FINAL;
|
|
|
|
|
currentAnimationTime=0.f;
|
|
|
|
|
Menu::OpenMenu(MAIN_MENU,false);
|
|
|
|
|
}
|
|
|
|
|
}break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
void TitleScreen::Draw(){
|
|
|
|
|
if(state==BUILDING||state==WAITING){
|
|
|
|
|
for(Particle&p:particles){
|
|
|
|
|
game->DrawRotatedDecal(p.pos,GFX["pixel.png"].Decal(),p.rot,{0.5f,0.5f},{p.scale,p.scale},p.col);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if(state!=BUILDING){
|
|
|
|
|
Decal*titleScreenDecal=GFX["title_transparent.png"].Decal();
|
|
|
|
|
uint8_t alpha=state==WAITING?uint8_t(util::lerp(0,255,currentAnimationTime/5.0f)):255;
|
|
|
|
|
vf2d pos=state==WAITING?vf2d(game->GetScreenSize()/2.f):vf2d(game->GetScreenSize()/2).lerp(vf2d{game->ScreenWidth()/2.f,48},currentAnimationTime/5.0f);
|
|
|
|
|
game->DrawRotatedDecal(pos,titleScreenDecal,0.f,titleScreenDecal->sprite->Size()/2,{1.f,1.f},{255,255,255,alpha});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TitleScreen::Skip(){
|
|
|
|
|
if(state!=FINAL){
|
|
|
|
|
for(Particle&p:particles){
|
|
|
|
|
p.pos=p.targetPos;
|
|
|
|
|
}
|
|
|
|
|
state=WAITING;
|
|
|
|
|
currentAnimationTime=5.0f;
|
|
|
|
|
}
|
|
|
|
|
}
|