@ -20,13 +20,27 @@ public:
bool OnUserCreate ( ) override
bool OnUserCreate ( ) override
{
{
// Called once at the start, so create things here
// Called once at the start, so create things here
smx . EnableLogMessages ( true ) ;
return true ;
return true ;
}
}
std : : vector < vf2d > snow ;
struct Snow {
std : : vector < vf2d > backgroundSnow ;
vf2d pos ;
int id ;
} ;
float backgroundSnowIntervalTimer { 0.03f } ;
struct ExpandCircle {
vi2d pos ;
float radius ;
Pixel col ;
} ;
std : : vector < Snow > snow ;
std : : vector < Snow > backgroundSnow ;
std : : vector < ExpandCircle > expandCircles ;
const float backgroundSnowInterval { 0.1f } ;
float backgroundSnowIntervalTimer { backgroundSnowInterval } ;
float backgroundSnowDirectionInterval { 60.f } ;
float backgroundSnowDirectionInterval { 60.f } ;
# define RIGHT true
# define RIGHT true
@ -35,37 +49,157 @@ public:
float snowTimer { snowInterval } ;
float snowTimer { snowInterval } ;
const float snowIntervalChangeInterval { 60.f } ;
const float snowIntervalChangeInterval { 60.f } ;
float snowIntervalTimer { snowIntervalChangeInterval } ;
float snowIntervalTimer { snowIntervalChangeInterval } ;
double totalElapsedTime { } ;
double totalElapsedTime { 0. } ;
float fallSpd { 6.f } ;
float fallSpd { 6.f } ;
float snowAmplitude { 2.f } ;
float snowAmplitude { 2.f } ;
std : : map < std : : pair < Key , int > , float > recreateCircleTimer { } ;
const float recreateCircleInterval { 0.25f } ;
uint64_t SNOW_ID { 0U } ;
bool OnUserUpdate ( float fElapsedTime ) override
bool OnUserUpdate ( float fElapsedTime ) override
{
{
Clear ( { 0 , 0 , 32 } ) ;
Clear ( { 0 , 0 , 32 } ) ;
backgroundSnowIntervalTimer - = fElapsedTime ;
backgroundSnowIntervalTimer - = fElapsedTime ;
snowTimer - = fElapsedTime ;
snowTimer - = fElapsedTime ;
snowIntervalTimer - = fElapsedTime ;
snowIntervalTimer - = fElapsedTime ;
for ( auto & [ KEY , time ] : recreateCircleTimer ) {
recreateCircleTimer [ KEY ] - = fElapsedTime ;
}
if ( snowTimer < = 0.f ) {
if ( snowTimer < = 0.f ) {
snow . emplace_back ( util : : random ( ScreenWidth ( ) ) , - 2.f ) ;
snow . emplace_back ( vf2d { util : : random ( ScreenWidth ( ) ) , - 2.f } , SNOW_ID + + ) ;
snowTimer = snowInterval ;
snowTimer = snowInterval ;
}
}
if ( backgroundSnowIntervalTimer < = 0.f ) {
if ( backgroundSnowIntervalTimer < = 0.f ) {
backgroundSnowIntervalTimer = snowIntervalTimer * 26.66666667f ;
int xOffset { int ( util : : random ( ScreenWidth ( ) ) ) } ;
if ( backgroundSnowDirection = = RIGHT ) {
xOffset - = ScreenWidth ( ) / 2 ;
} else {
xOffset + = ScreenWidth ( ) / 2 ;
}
backgroundSnow . emplace_back ( vf2d { float ( xOffset ) , - 2.f } , SNOW_ID + + ) ;
backgroundSnowIntervalTimer = backgroundSnowInterval ;
}
}
if ( snowIntervalTimer < = 0.f ) {
if ( snowIntervalTimer < = 0.f ) {
snowInterval = util : : random_range ( 0.1f , 2.f ) ;
snowInterval = util : : random_range ( 0.1f , 2.f ) ;
backgroundSnowDirection = ! RIGHT ;
if ( rand ( ) % 2 = = 0 ) backgroundSnowDirection = RIGHT ;
snowIntervalTimer = snowIntervalChangeInterval ;
snowIntervalTimer = snowIntervalChangeInterval ;
}
}
for ( int ind { 0 } ; vf2d & snow : snow ) {
for ( Snow & backSnow : backgroundSnow ) {
snow . y + = fallSpd * fElapsedTime ;
srand ( backSnow . id ) ;
srand ( ind ) ;
if ( backgroundSnowDirection = = RIGHT ) {
FillCircle ( vi2d { int ( snow . x + sin ( totalElapsedTime + ind * 0.5f * fallSpd ) * snowAmplitude ) , int ( snow . y ) } , rand ( ) % 2 + 1 , { uint8_t ( 200 + rand ( ) % 55 ) , uint8_t ( 235 + rand ( ) % 20 ) , 255 } ) ;
backSnow . pos . x + = fElapsedTime * snowAmplitude ;
ind + + ;
} else {
backSnow . pos . x - = fElapsedTime * snowAmplitude ;
}
backSnow . pos . y + = fallSpd * fElapsedTime / 2.f ;
uint8_t randCol { uint8_t ( 10 + rand ( ) % 50 ) } ;
Draw ( backSnow . pos , Pixel { randCol , randCol , randCol } ) ;
}
}
for ( Snow & snow : snow ) {
srand ( snow . id ) ;
float fallSpdMult { ( rand ( ) % 25 ) / 100.f } ;
snow . pos . y + = ( fallSpd * ( 1.f - fallSpdMult ) ) * fElapsedTime ;
FillCircle ( vi2d { int ( snow . pos . x + sin ( totalElapsedTime + snow . id * 0.5f * fallSpd ) * snowAmplitude ) , int ( snow . pos . y ) } , rand ( ) % 2 + 1 , { uint8_t ( 150 + rand ( ) % 105 ) , uint8_t ( 190 + rand ( ) % 65 ) , uint8_t ( 190 + rand ( ) % 65 ) } ) ;
}
SetPixelMode ( Pixel : : ALPHA ) ;
for ( ExpandCircle & circle : expandCircles ) {
circle . radius + = fallSpd * fElapsedTime * 6 ;
DrawCircle ( circle . pos , circle . radius , circle . col ) ;
}
std : : erase_if ( snow , [ this ] ( const Snow & snow ) { return snow . pos . y > ScreenHeight ( ) + 2 ; } ) ;
std : : erase_if ( backgroundSnow , [ this ] ( const Snow & backSnow ) { return backSnow . pos . y > ScreenHeight ( ) + 2 ; } ) ;
std : : erase_if ( expandCircles , [ this ] ( const ExpandCircle & circle ) { return circle . radius > 24 + 2 ; } ) ;
double previousTotalElapsedTime { totalElapsedTime } ;
totalElapsedTime = fmod ( totalElapsedTime + fElapsedTime , 10000. ) ;
totalElapsedTime = fmod ( totalElapsedTime + fElapsedTime , 10000. ) ;
# undef RIGHT
if ( smx . GetPanel ( RIGHT , 0 ) . bHeld ) {
FillRect ( { 8 , 7 } , { 3 , 6 } , { VERY_DARK_MAGENTA . r , VERY_DARK_MAGENTA . g , VERY_DARK_MAGENTA . b , 64 } ) ;
DrawRect ( { 8 , 7 } , { 3 , 6 } , VERY_DARK_MAGENTA ) ;
if ( recreateCircleTimer [ { RIGHT , 0 } ] < = 0.f ) {
expandCircles . emplace_back ( vi2d { 8 + 1 , 7 + 3 } , 1 , Pixel { DARK_MAGENTA . r , DARK_MAGENTA . g , DARK_MAGENTA . b , 64 } ) ;
expandCircles . emplace_back ( vi2d { 8 + 1 , 7 + 3 } , 0.5f , Pixel { DARK_MAGENTA . r , DARK_MAGENTA . g , DARK_MAGENTA . b , 64 } ) ;
expandCircles . emplace_back ( vi2d { 8 + 1 , 7 + 3 } , 0.f , Pixel { DARK_MAGENTA . r , DARK_MAGENTA . g , DARK_MAGENTA . b , 64 } ) ;
recreateCircleTimer [ { RIGHT , 0 } ] = recreateCircleInterval ;
}
}
if ( smx . GetPanel ( UP , 0 ) . bHeld ) {
FillRect ( { 4 , 0 } , { 3 , 6 } , { VERY_DARK_MAGENTA . r , VERY_DARK_MAGENTA . g , VERY_DARK_MAGENTA . b , 64 } ) ;
DrawRect ( { 4 , 0 } , { 3 , 6 } , VERY_DARK_MAGENTA ) ;
if ( recreateCircleTimer [ { UP , 0 } ] < = 0.f ) {
expandCircles . emplace_back ( vi2d { 4 + 1 , 0 + 3 } , 1 , Pixel { DARK_MAGENTA . r , DARK_MAGENTA . g , DARK_MAGENTA . b , 64 } ) ;
expandCircles . emplace_back ( vi2d { 4 + 1 , 0 + 3 } , 0.5f , Pixel { DARK_MAGENTA . r , DARK_MAGENTA . g , DARK_MAGENTA . b , 64 } ) ;
expandCircles . emplace_back ( vi2d { 4 + 1 , 0 + 3 } , 0.f , Pixel { DARK_MAGENTA . r , DARK_MAGENTA . g , DARK_MAGENTA . b , 64 } ) ;
recreateCircleTimer [ { UP , 0 } ] = recreateCircleInterval ;
}
}
if ( smx . GetPanel ( DOWN , 0 ) . bHeld ) {
FillRect ( { 4 , 14 } , { 3 , 6 } , { VERY_DARK_MAGENTA . r , VERY_DARK_MAGENTA . g , VERY_DARK_MAGENTA . b , 64 } ) ;
DrawRect ( { 4 , 14 } , { 3 , 6 } , VERY_DARK_MAGENTA ) ;
if ( recreateCircleTimer [ { DOWN , 0 } ] < = 0.f ) {
expandCircles . emplace_back ( vi2d { 4 + 1 , 14 + 3 } , 1 , Pixel { DARK_MAGENTA . r , DARK_MAGENTA . g , DARK_MAGENTA . b , 64 } ) ;
expandCircles . emplace_back ( vi2d { 4 + 1 , 14 + 3 } , 0.5f , Pixel { DARK_MAGENTA . r , DARK_MAGENTA . g , DARK_MAGENTA . b , 64 } ) ;
expandCircles . emplace_back ( vi2d { 4 + 1 , 14 + 3 } , 0.f , Pixel { DARK_MAGENTA . r , DARK_MAGENTA . g , DARK_MAGENTA . b , 64 } ) ;
recreateCircleTimer [ { DOWN , 0 } ] = recreateCircleInterval ;
}
}
if ( smx . GetPanel ( LEFT , 0 ) . bHeld ) {
FillRect ( { 0 , 7 } , { 3 , 6 } , { VERY_DARK_MAGENTA . r , VERY_DARK_MAGENTA . g , VERY_DARK_MAGENTA . b , 64 } ) ;
DrawRect ( { 0 , 7 } , { 3 , 6 } , VERY_DARK_MAGENTA ) ;
if ( recreateCircleTimer [ { LEFT , 0 } ] < = 0.f ) {
expandCircles . emplace_back ( vi2d { 0 + 1 , 7 + 3 } , 1 , Pixel { DARK_MAGENTA . r , DARK_MAGENTA . g , DARK_MAGENTA . b , 64 } ) ;
expandCircles . emplace_back ( vi2d { 0 + 1 , 7 + 3 } , 0.5f , Pixel { DARK_MAGENTA . r , DARK_MAGENTA . g , DARK_MAGENTA . b , 64 } ) ;
expandCircles . emplace_back ( vi2d { 0 + 1 , 7 + 3 } , 0.f , Pixel { DARK_MAGENTA . r , DARK_MAGENTA . g , DARK_MAGENTA . b , 64 } ) ;
recreateCircleTimer [ { LEFT , 0 } ] = recreateCircleInterval ;
}
}
if ( smx . GetPanel ( RIGHT , 1 ) . bHeld ) {
FillRect ( { 20 , 7 } , { 3 , 6 } , { VERY_DARK_CYAN . r , VERY_DARK_CYAN . g , VERY_DARK_CYAN . b , 64 } ) ;
DrawRect ( { 20 , 7 } , { 3 , 6 } , VERY_DARK_CYAN ) ;
if ( recreateCircleTimer [ { RIGHT , 1 } ] < = 0.f ) {
expandCircles . emplace_back ( vi2d { 20 + 1 , 7 + 3 } , 1 , Pixel { DARK_CYAN . r , DARK_CYAN . g , DARK_CYAN . b , 64 } ) ;
expandCircles . emplace_back ( vi2d { 20 + 1 , 7 + 3 } , 0.5f , Pixel { DARK_CYAN . r , DARK_CYAN . g , DARK_CYAN . b , 64 } ) ;
expandCircles . emplace_back ( vi2d { 20 + 1 , 7 + 3 } , 0.f , Pixel { DARK_CYAN . r , DARK_CYAN . g , DARK_CYAN . b , 64 } ) ;
recreateCircleTimer [ { RIGHT , 1 } ] = recreateCircleInterval ;
}
}
if ( smx . GetPanel ( UP , 1 ) . bHeld ) {
FillRect ( { 16 , 0 } , { 3 , 6 } , { VERY_DARK_CYAN . r , VERY_DARK_CYAN . g , VERY_DARK_CYAN . b , 64 } ) ;
DrawRect ( { 16 , 0 } , { 3 , 6 } , VERY_DARK_CYAN ) ;
if ( recreateCircleTimer [ { UP , 1 } ] < = 0.f ) {
expandCircles . emplace_back ( vi2d { 16 + 1 , 3 + 3 } , 1 , Pixel { DARK_CYAN . r , DARK_CYAN . g , DARK_CYAN . b , 64 } ) ;
expandCircles . emplace_back ( vi2d { 16 + 1 , 3 + 3 } , 0.5f , Pixel { DARK_CYAN . r , DARK_CYAN . g , DARK_CYAN . b , 64 } ) ;
expandCircles . emplace_back ( vi2d { 16 + 1 , 3 + 3 } , 0.f , Pixel { DARK_CYAN . r , DARK_CYAN . g , DARK_CYAN . b , 64 } ) ;
recreateCircleTimer [ { UP , 1 } ] = recreateCircleInterval ;
}
}
if ( smx . GetPanel ( DOWN , 1 ) . bHeld ) {
FillRect ( { 16 , 14 } , { 3 , 6 } , { VERY_DARK_CYAN . r , VERY_DARK_CYAN . g , VERY_DARK_CYAN . b , 64 } ) ;
DrawRect ( { 16 , 14 } , { 3 , 6 } , VERY_DARK_CYAN ) ;
if ( recreateCircleTimer [ { DOWN , 1 } ] < = 0.f ) {
expandCircles . emplace_back ( vi2d { 16 + 1 , 14 + 3 } , 1 , Pixel { DARK_CYAN . r , DARK_CYAN . g , DARK_CYAN . b , 64 } ) ;
expandCircles . emplace_back ( vi2d { 16 + 1 , 14 + 3 } , 0.5f , Pixel { DARK_CYAN . r , DARK_CYAN . g , DARK_CYAN . b , 64 } ) ;
expandCircles . emplace_back ( vi2d { 16 + 1 , 14 + 3 } , 0.f , Pixel { DARK_CYAN . r , DARK_CYAN . g , DARK_CYAN . b , 64 } ) ;
recreateCircleTimer [ { DOWN , 1 } ] = recreateCircleInterval ;
}
}
if ( smx . GetPanel ( LEFT , 1 ) . bHeld ) {
FillRect ( { 12 , 7 } , { 3 , 6 } , { VERY_DARK_CYAN . r , VERY_DARK_CYAN . g , VERY_DARK_CYAN . b , 64 } ) ;
DrawRect ( { 12 , 7 } , { 3 , 6 } , VERY_DARK_CYAN ) ;
if ( recreateCircleTimer [ { LEFT , 1 } ] < = 0.f ) {
expandCircles . emplace_back ( vi2d { 12 + 1 , 3 + 3 } , 1 , Pixel { DARK_CYAN . r , DARK_CYAN . g , DARK_CYAN . b , 64 } ) ;
expandCircles . emplace_back ( vi2d { 12 + 1 , 3 + 3 } , 0.5f , Pixel { DARK_CYAN . r , DARK_CYAN . g , DARK_CYAN . b , 64 } ) ;
expandCircles . emplace_back ( vi2d { 12 + 1 , 3 + 3 } , 0.f , Pixel { DARK_CYAN . r , DARK_CYAN . g , DARK_CYAN . b , 64 } ) ;
recreateCircleTimer [ { LEFT , 1 } ] = recreateCircleInterval ;
}
}
SetPixelMode ( Pixel : : MASK ) ;
return true ;
return true ;
}
}
@ -75,7 +209,7 @@ public:
int main ( )
int main ( )
{
{
SMX_PGE demo ;
SMX_PGE demo ;
if ( demo . Construct ( 24 , 21 , 50 , 50 ) )
if ( demo . Construct ( 24 , 21 , 50 , 50 , false , true ) )
demo . Start ( ) ;
demo . Start ( ) ;
return 0 ;
return 0 ;