Compare commits

16 Commits

Author SHA1 Message Date
b01763b749 Dels credits ja passa a la tabla de puntuacions 2025-01-26 21:15:13 +01:00
59b9f61d69 Font nova per a la intro 2025-01-26 21:05:43 +01:00
b9f194a2b1 Afegit efecte d'eixida a les instruccions 2025-01-26 20:16:43 +01:00
59936f13eb Arreglos estetics i de colorets en hiscore_table.cpp 2025-01-26 17:48:10 +01:00
bad0a10328 Ja es mouen els sprites en hiscore_table.cpp, falta decidir-se per un disseny concret 2025-01-25 22:57:49 +01:00
52a0c2b91f Treballant en la nova tabla de records: ja pinta amb sprites 2025-01-25 21:17:45 +01:00
f12a456017 Alguns arreglos en updateTimeStopped() 2025-01-25 18:51:39 +01:00
f39e65afaf Ja no se que he tocat i qué no, cosetes del malo nou 2025-01-25 18:47:06 +01:00
d3183237df Estandaritzats els noms dels fitxers de audio
Eliminat el soroll de TNT que feia ANYS que no existía
2025-01-25 18:15:49 +01:00
60302004f4 Afegits efectes de audio nous
Retocats alguns efectes de audio al afagar items per a no solapar dos audios
2025-01-25 18:11:24 +01:00
e60938cb19 El malo nou ja suca cosetes, falta ajustar un poc els paràmetres 2025-01-25 17:41:45 +01:00
2b3cc719ba Fix del fix: aaaara si que lleva el garbage de la zona negra. Havia posat el clean() on no tocava 2025-01-25 13:14:25 +01:00
d01c91ebde Fix: m'havia carregat el shakeEffect() de la pantalla quan havia shaders, i de paso he vist que el que tenbia fet shakejava també les notificacions i els menus de debug. Ale, ja està tot arreglaet.
Fix: tampoc estava netejant la pantalla, pensava que no feia falta, pero quan SDL replena de negre la finestra en pantalla completa, havia gorrinades
2025-01-24 20:20:50 +01:00
7130f2298a Merge branch 'main' of https://gitea.sustancia.synology.me/JailDesigner/coffee_crisis_arcade_edition 2025-01-24 10:44:58 +01:00
380cc17861 Fix: ara apaga el sistem al final del tot, almenys quan ja ha escrit la configuració a disc 2025-01-24 10:43:00 +01:00
a5388873e3 Actualizar README.md 2025-01-05 15:47:51 +01:00
43 changed files with 951 additions and 210 deletions

View File

@@ -11,7 +11,7 @@ Coffee Crisis Arcade Edition és una versió ampliada i millorada del aclamat Co
Defensa el teu cafè contra les bambolles gegants en aquest trepidant joc d'arcade! 🍵 Defensa el teu cafè contra les bambolles gegants en aquest trepidant joc d'arcade! 🍵
<p align="center"> <p align="center">
<img src="https://php.sustancia.synology.me/images/ccae_title.png" alt="Títol" /> <img src="https://php.sustancia.synology.me/images/ccae_title.png" alt="Títol" width="60%" />
</p> </p>
## Controls ## Controls
@@ -25,7 +25,8 @@ El joc està optimitzat per a ser jugat amb un mando de jocs, encara que un dels
> Nota: El joc suporta nomes un jugador amb teclat. > Nota: El joc suporta nomes un jugador amb teclat.
<p align="center"> <p align="center">
<img src="https://php.sustancia.synology.me/images/ccae1.png" alt="Joc" /> <img src="https://php.sustancia.synology.me/images/ccae1.png" alt="Joc" width="45%" />
<img src="https://php.sustancia.synology.me/images/ccae3.png" alt="Joc" width="45%" />
</p> </p>
## Altres tecles ## Altres tecles
@@ -43,7 +44,7 @@ El joc està optimitzat per a ser jugat amb un mando de jocs, encara que un dels
| **F10** | Reset del joc | | **F10** | Reset del joc |
<p align="center"> <p align="center">
<img src="https://php.sustancia.synology.me/images/ccae2.png" alt="Joc" /> <img src="https://php.sustancia.synology.me/images/ccae2.png" alt="Joc" width="50%" />
</p> </p>
## Com instal·lar i jugar ## Com instal·lar i jugar

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
data/font/04b_25_var01.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

194
data/font/04b_25_var01.txt Normal file
View File

@@ -0,0 +1,194 @@
# box width
14
# box height
14
# 32 espacio ( )
8
# 33 !
5
# 34 "
8
# 35
10
# 36 $
10
# 37 %
9
# 38 &
11
# 39 '
5
# 40 (
7
# 41 )
7
# 42 *
7
# 43 +
9
# 44 ,
5
# 45 -
9
# 46 .
5
# 47 /
12
# 48 0
8
# 49 1
6
# 50 2
8
# 51 3
8
# 52 4
8
# 53 5
8
# 54 6
8
# 55 7
8
# 56 8
8
# 57 9
8
# 58 :
5
# 59 ;
5
# 60 <
8
# 61 =
8
# 62 >
8
# 63 ?
8
# 64 @
11
# 65 A
8
# 66 B
8
# 67 C
8
# 68 D
8
# 69 E
8
# 70 F
8
# 71 G
8
# 72 H
8
# 73 I
5
# 74 J
8
# 75 K
8
# 76 L
8
# 77 M
11
# 78 N
8
# 79 O
8
# 80 P
8
# 81 Q
8
# 82 R
8
# 83 S
8
# 84 T
9
# 85 U
8
# 86 V
8
# 87 W
11
# 88 X
8
# 89 Y
8
# 90 Z
8
# 91 [
7
# 92 \
11
# 93 ]
7
# 94 ^
6
# 95 _
7
# 96 `
6
# 97 a
8
# 98 b
8
# 99 c
8
# 100 d
8
# 101 e
8
# 102 f
8
# 103 g
8
# 104 h
8
# 105 i
5
# 106 j
8
# 107 k
8
# 108 l
8
# 109 m
11
# 110 n
8
# 111 o
8
# 112 p
8
# 113 q
8
# 114 r
8
# 115 s
8
# 116 t
9
# 117 u
8
# 118 v
8
# 119 w
11
# 120 x
8
# 121 y
8
# 122 z
8
# 123 {
1
# 124 |
1
# 125 }
1
# 126 ~
1

View File

@@ -0,0 +1,9 @@
frame_width=20
frame_height=20
[animation]
name=default
speed=10
loop=0
frames=0,1
[/animation]

Binary file not shown.

After

Width:  |  Height:  |  Size: 565 B

View File

@@ -2,8 +2,15 @@ frame_width=32
frame_height=32 frame_height=32
[animation] [animation]
name=default name=fly
speed=2 speed=2
loop=0 loop=0
frames=0,1 frames=0,1
[/animation] [/animation]
[animation]
name=hit
speed=2
loop=0
frames=2,3
[/animation]

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@@ -32,7 +32,7 @@ IDIOMA
[ CANCELAR ] [ CANCELAR ]
## 11 - INSTRUCCIONES ## 11 - INSTRUCCIONES
OBJECTIU Objectiu
## 12 - INSTRUCCIONES ## 12 - INSTRUCCIONES
HAS D'EXPLOTAR HAS D'EXPLOTAR
@@ -47,7 +47,7 @@ LA DIFICULTAT AUGMENTA
A MESURA QUE VAS PUNTUANT A MESURA QUE VAS PUNTUANT
## 16 - INSTRUCCIONES ## 16 - INSTRUCCIONES
OBJECTES Objectes
## 17 - INSTRUCCIONES ## 17 - INSTRUCCIONES
1.000 PUNTS 1.000 PUNTS

BIN
data/sound/debian_drop.wav Normal file

Binary file not shown.

Binary file not shown.

BIN
data/sound/tabe_hit.wav Normal file

Binary file not shown.

Binary file not shown.

View File

@@ -321,7 +321,7 @@ int BalloonManager::destroyAllBalloons()
} }
balloon_deploy_counter_ = 300; balloon_deploy_counter_ = 300;
JA_PlaySound(Resource::get()->getSound("powerball.wav")); JA_PlaySound(Resource::get()->getSound("power_ball_explosion.wav"));
Screen::get()->flash(flash_color, 3); Screen::get()->flash(flash_color, 3);
Screen::get()->shake(); Screen::get()->shake();

View File

@@ -68,6 +68,7 @@ Credits::~Credits()
SDL_DestroyTexture(text_texture_); SDL_DestroyTexture(text_texture_);
SDL_DestroyTexture(canvas_); SDL_DestroyTexture(canvas_);
resetVolume(); resetVolume();
JA_StopMusic();
} }
// Bucle principal // Bucle principal
@@ -477,7 +478,7 @@ void Credits::updateAllFades()
fade_out_->update(); fade_out_->update();
if (fade_out_->hasEnded()) if (fade_out_->hasEnded())
{ {
section::name = section::Name::LOGO; section::name = section::Name::HI_SCORE_TABLE;
} }
} }

View File

@@ -52,7 +52,7 @@ Director::Director(int argc, const char *argv[])
section::name = section::Name::GAME; section::name = section::Name::GAME;
section::options = section::Options::GAME_PLAY_1P; section::options = section::Options::GAME_PLAY_1P;
#elif DEBUG #elif DEBUG
section::name = section::Name::LOGO; section::name = section::Name::CREDITS;
#else // NORMAL GAME #else // NORMAL GAME
section::name = section::Name::LOGO; section::name = section::Name::LOGO;
section::attract_mode = section::AttractMode::TITLE_TO_DEMO; section::attract_mode = section::AttractMode::TITLE_TO_DEMO;
@@ -126,6 +126,10 @@ void Director::close()
SDL_DestroyWindow(window_); SDL_DestroyWindow(window_);
SDL_Quit(); SDL_Quit();
#ifdef ARCADE
shutdownSystem(section::options == section::Options::QUIT_WITH_CONTROLLER);
#endif
} }
// Carga los parametros // Carga los parametros
@@ -393,16 +397,16 @@ void Director::setFileList()
Asset::get()->add(prefix + "/data/sound/bubble4.wav", AssetType::SOUND); Asset::get()->add(prefix + "/data/sound/bubble4.wav", AssetType::SOUND);
Asset::get()->add(prefix + "/data/sound/bullet.wav", AssetType::SOUND); Asset::get()->add(prefix + "/data/sound/bullet.wav", AssetType::SOUND);
Asset::get()->add(prefix + "/data/sound/clock.wav", AssetType::SOUND); Asset::get()->add(prefix + "/data/sound/clock.wav", AssetType::SOUND);
Asset::get()->add(prefix + "/data/sound/coffeeout.wav", AssetType::SOUND); Asset::get()->add(prefix + "/data/sound/coffee_out.wav", AssetType::SOUND);
Asset::get()->add(prefix + "/data/sound/continue_clock.wav", AssetType::SOUND); Asset::get()->add(prefix + "/data/sound/continue_clock.wav", AssetType::SOUND);
Asset::get()->add(prefix + "/data/sound/game_start.wav", AssetType::SOUND); Asset::get()->add(prefix + "/data/sound/game_start.wav", AssetType::SOUND);
Asset::get()->add(prefix + "/data/sound/hiscore.wav", AssetType::SOUND); Asset::get()->add(prefix + "/data/sound/hi_score_achieved.wav", AssetType::SOUND);
Asset::get()->add(prefix + "/data/sound/itemdrop.wav", AssetType::SOUND); Asset::get()->add(prefix + "/data/sound/item_drop.wav", AssetType::SOUND);
Asset::get()->add(prefix + "/data/sound/itempickup.wav", AssetType::SOUND); Asset::get()->add(prefix + "/data/sound/item_pickup.wav", AssetType::SOUND);
Asset::get()->add(prefix + "/data/sound/logo.wav", AssetType::SOUND); Asset::get()->add(prefix + "/data/sound/logo.wav", AssetType::SOUND);
Asset::get()->add(prefix + "/data/sound/notify.wav", AssetType::SOUND); Asset::get()->add(prefix + "/data/sound/notify.wav", AssetType::SOUND);
Asset::get()->add(prefix + "/data/sound/player_collision.wav", AssetType::SOUND); Asset::get()->add(prefix + "/data/sound/player_collision.wav", AssetType::SOUND);
Asset::get()->add(prefix + "/data/sound/powerball.wav", AssetType::SOUND); Asset::get()->add(prefix + "/data/sound/power_ball_explosion.wav", AssetType::SOUND);
Asset::get()->add(prefix + "/data/sound/stage_change.wav", AssetType::SOUND); Asset::get()->add(prefix + "/data/sound/stage_change.wav", AssetType::SOUND);
Asset::get()->add(prefix + "/data/sound/tabe.wav", AssetType::SOUND); Asset::get()->add(prefix + "/data/sound/tabe.wav", AssetType::SOUND);
Asset::get()->add(prefix + "/data/sound/title.wav", AssetType::SOUND); Asset::get()->add(prefix + "/data/sound/title.wav", AssetType::SOUND);
@@ -411,6 +415,9 @@ void Director::setFileList()
Asset::get()->add(prefix + "/data/sound/voice_no.wav", AssetType::SOUND); Asset::get()->add(prefix + "/data/sound/voice_no.wav", AssetType::SOUND);
Asset::get()->add(prefix + "/data/sound/voice_power_up.wav", AssetType::SOUND); Asset::get()->add(prefix + "/data/sound/voice_power_up.wav", AssetType::SOUND);
Asset::get()->add(prefix + "/data/sound/walk.wav", AssetType::SOUND); Asset::get()->add(prefix + "/data/sound/walk.wav", AssetType::SOUND);
Asset::get()->add(prefix + "/data/sound/debian_drop.wav", AssetType::SOUND);
Asset::get()->add(prefix + "/data/sound/debian_pickup.wav", AssetType::SOUND);
Asset::get()->add(prefix + "/data/sound/tabe_hit.wav", AssetType::SOUND);
// Shaders // Shaders
Asset::get()->add(prefix + "/data/shaders/crtpi_256.glsl", AssetType::DATA); Asset::get()->add(prefix + "/data/shaders/crtpi_256.glsl", AssetType::DATA);
@@ -490,6 +497,8 @@ void Director::setFileList()
Asset::get()->add(prefix + "/data/gfx/item/item_clock.ani", AssetType::ANIMATION); Asset::get()->add(prefix + "/data/gfx/item/item_clock.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/gfx/item/item_coffee.png", AssetType::BITMAP); Asset::get()->add(prefix + "/data/gfx/item/item_coffee.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/item/item_coffee.ani", AssetType::ANIMATION); Asset::get()->add(prefix + "/data/gfx/item/item_coffee.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/gfx/item/item_debian.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/item/item_debian.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/gfx/item/item_coffee_machine.png", AssetType::BITMAP); Asset::get()->add(prefix + "/data/gfx/item/item_coffee_machine.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/item/item_coffee_machine.ani", AssetType::ANIMATION); Asset::get()->add(prefix + "/data/gfx/item/item_coffee_machine.ani", AssetType::ANIMATION);
} }
@@ -536,6 +545,8 @@ void Director::setFileList()
Asset::get()->add(prefix + "/data/font/04b_25.txt", AssetType::FONT); Asset::get()->add(prefix + "/data/font/04b_25.txt", AssetType::FONT);
Asset::get()->add(prefix + "/data/font/04b_25_2x.png", AssetType::BITMAP); Asset::get()->add(prefix + "/data/font/04b_25_2x.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/font/04b_25_2x.txt", AssetType::FONT); Asset::get()->add(prefix + "/data/font/04b_25_2x.txt", AssetType::FONT);
Asset::get()->add(prefix + "/data/font/04b_25_var01.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/font/04b_25_var01.txt", AssetType::FONT);
// Textos // Textos
Asset::get()->add(prefix + "/data/lang/es_ES.txt", AssetType::LANG); Asset::get()->add(prefix + "/data/lang/es_ES.txt", AssetType::LANG);
@@ -762,11 +773,6 @@ int Director::run()
// Habilita de nuevo los std::cout // Habilita de nuevo los std::cout
std::cout.rdbuf(orig_buf); std::cout.rdbuf(orig_buf);
#endif #endif
#ifdef ARCADE
// Comprueba si ha de apagar el sistema
if (section::options == section::Options::QUIT_WITH_CONTROLLER)
shutdownSystem();
#endif
return (section::options == section::Options::QUIT_WITH_CONTROLLER) ? 1 : 0; return (section::options == section::Options::QUIT_WITH_CONTROLLER) ? 1 : 0;
} }
@@ -794,20 +800,23 @@ std::string Director::getLangFile(lang::Code code)
#ifdef ARCADE #ifdef ARCADE
// Apaga el sistema // Apaga el sistema
void Director::shutdownSystem() void Director::shutdownSystem(bool shouldShutdown)
{ {
if (shouldShutdown)
{
#ifdef _WIN32 #ifdef _WIN32
// Apaga el sistema en Windows // Apaga el sistema en Windows
system("shutdown /s /t 0"); system("shutdown /s /t 5");
#elif __APPLE__ #elif __APPLE__
// Apaga el sistema en macOS // Apaga el sistema en macOS
system("sudo shutdown -h now"); system("sudo shutdown -h +0.1");
#elif __linux__ #elif __linux__
// Apaga el sistema en Linux // Apaga el sistema en Linux
system("shutdown -h now"); system("sleep 5; shutdown -h now");
#else #else
// Sistema operativo no compatible // Sistema operativo no compatible
#error "Sistema operativo no soportado" #error "Sistema operativo no soportado"
#endif #endif
}
} }
#endif // ARCADE #endif // ARCADE

View File

@@ -74,7 +74,7 @@ private:
std::string getLangFile(lang::Code code); std::string getLangFile(lang::Code code);
#ifdef ARCADE #ifdef ARCADE
// Apaga el sistema // Apaga el sistema
void shutdownSystem(); void shutdownSystem(bool shouldShutdown);
#endif #endif
// Inicializa todo // Inicializa todo

View File

@@ -140,6 +140,7 @@ void Game::setResources()
game_text_textures_.emplace_back(Resource::get()->getTexture("game_text_powerup")); game_text_textures_.emplace_back(Resource::get()->getTexture("game_text_powerup"));
game_text_textures_.emplace_back(Resource::get()->getTexture("game_text_one_hit")); game_text_textures_.emplace_back(Resource::get()->getTexture("game_text_one_hit"));
game_text_textures_.emplace_back(Resource::get()->getTexture("game_text_stop")); game_text_textures_.emplace_back(Resource::get()->getTexture("game_text_stop"));
game_text_textures_.emplace_back(Resource::get()->getTexture("game_text_100000_points"));
} }
// Texturas - Items // Texturas - Items
@@ -149,6 +150,7 @@ void Game::setResources()
item_textures_.emplace_back(Resource::get()->getTexture("item_points3_pacmar.png")); item_textures_.emplace_back(Resource::get()->getTexture("item_points3_pacmar.png"));
item_textures_.emplace_back(Resource::get()->getTexture("item_clock.png")); item_textures_.emplace_back(Resource::get()->getTexture("item_clock.png"));
item_textures_.emplace_back(Resource::get()->getTexture("item_coffee.png")); item_textures_.emplace_back(Resource::get()->getTexture("item_coffee.png"));
item_textures_.emplace_back(Resource::get()->getTexture("item_debian.png"));
item_textures_.emplace_back(Resource::get()->getTexture("item_coffee_machine.png")); item_textures_.emplace_back(Resource::get()->getTexture("item_coffee_machine.png"));
} }
@@ -181,6 +183,7 @@ void Game::setResources()
item_animations_.emplace_back(Resource::get()->getAnimation("item_points3_pacmar.ani")); item_animations_.emplace_back(Resource::get()->getAnimation("item_points3_pacmar.ani"));
item_animations_.emplace_back(Resource::get()->getAnimation("item_clock.ani")); item_animations_.emplace_back(Resource::get()->getAnimation("item_clock.ani"));
item_animations_.emplace_back(Resource::get()->getAnimation("item_coffee.ani")); item_animations_.emplace_back(Resource::get()->getAnimation("item_coffee.ani"));
item_animations_.emplace_back(Resource::get()->getAnimation("item_debian.ani"));
item_animations_.emplace_back(Resource::get()->getAnimation("item_coffee_machine.ani")); item_animations_.emplace_back(Resource::get()->getAnimation("item_coffee_machine.ani"));
} }
} }
@@ -202,7 +205,7 @@ void Game::updateHiScore()
if (hi_score_achieved_ == false) if (hi_score_achieved_ == false)
{ {
hi_score_achieved_ = true; hi_score_achieved_ = true;
JA_PlaySound(Resource::get()->getSound("hiscore.wav")); JA_PlaySound(Resource::get()->getSound("hi_score_achieved.wav"));
} }
} }
} }
@@ -280,6 +283,13 @@ void Game::updateStage()
createMessage(paths, text->writeToTexture(caption, 1, -4)); createMessage(paths, text->writeToTexture(caption, 1, -4));
} }
} }
// Modifica el color de fondo al llegar a la Fase 10
if (Stage::number == 9)
{
background_->setColor(Color(0xdd, 0x19, 0x1d).darken());
background_->setAlpha(96);
}
} }
} }
@@ -297,7 +307,7 @@ void Game::updateGameStateGameOver()
updateSmartSprites(); updateSmartSprites();
updatePathSprites(); updatePathSprites();
updateTimeStopped(); updateTimeStopped();
checkBulletBalloonCollision(); checkBulletCollision();
cleanVectors(); cleanVectors();
if (game_over_counter_ > 0) if (game_over_counter_ > 0)
@@ -362,6 +372,7 @@ void Game::updateGameStateCompleted()
balloon_manager_->destroyAllBalloons(); // Destruye a todos los globos balloon_manager_->destroyAllBalloons(); // Destruye a todos los globos
destroyAllItems(); // Destruye todos los items destroyAllItems(); // Destruye todos los items
Stage::power = 0; // Vuelve a dejar el poder a cero, por lo que hubiera podido subir al destruir todos los globos Stage::power = 0; // Vuelve a dejar el poder a cero, por lo que hubiera podido subir al destruir todos los globos
background_->setAlpha(0); // Elimina el tono rojo de las últimas pantallas
} }
// Comienza las celebraciones // Comienza las celebraciones
@@ -462,37 +473,41 @@ void Game::checkPlayerItemCollision(std::shared_ptr<Player> &player)
case ItemType::DISK: case ItemType::DISK:
{ {
player->addScore(1000); player->addScore(1000);
const auto x = const auto x = item->getPosX() + (item->getWidth() - game_text_textures_.at(0)->getWidth()) / 2;
item->getPosX() + createItemText(x, game_text_textures_.at(0));
(item->getWidth() - game_text_textures_[0]->getWidth()) / 2; JA_PlaySound(Resource::get()->getSound("item_pickup.wav"));
createItemText(x, game_text_textures_[0]);
break; break;
} }
case ItemType::GAVINA: case ItemType::GAVINA:
{ {
player->addScore(2500); player->addScore(2500);
const auto x = const auto x = item->getPosX() + (item->getWidth() - game_text_textures_.at(1)->getWidth()) / 2;
item->getPosX() + createItemText(x, game_text_textures_.at(1));
(item->getWidth() - game_text_textures_[1]->getWidth()) / 2; JA_PlaySound(Resource::get()->getSound("item_pickup.wav"));
createItemText(x, game_text_textures_[1]);
break; break;
} }
case ItemType::PACMAR: case ItemType::PACMAR:
{ {
player->addScore(5000); player->addScore(5000);
const auto x = const auto x = item->getPosX() + (item->getWidth() - game_text_textures_.at(2)->getWidth()) / 2;
item->getPosX() + createItemText(x, game_text_textures_.at(2));
(item->getWidth() - game_text_textures_[2]->getWidth()) / 2; JA_PlaySound(Resource::get()->getSound("item_pickup.wav"));
createItemText(x, game_text_textures_[2]); break;
}
case ItemType::DEBIAN:
{
player->addScore(100000);
const auto x = item->getPosX() + (item->getWidth() - game_text_textures_.at(6)->getWidth()) / 2;
createItemText(x, game_text_textures_.at(6));
JA_PlaySound(Resource::get()->getSound("debian_pickup.wav"));
break; break;
} }
case ItemType::CLOCK: case ItemType::CLOCK:
{ {
enableTimeStopItem(); enableTimeStopItem();
const auto x = const auto x = item->getPosX() + (item->getWidth() - game_text_textures_.at(5)->getWidth()) / 2;
item->getPosX() + createItemText(x, game_text_textures_.at(5));
(item->getWidth() - game_text_textures_[5]->getWidth()) / 2; JA_PlaySound(Resource::get()->getSound("item_pickup.wav"));
createItemText(x, game_text_textures_[5]);
break; break;
} }
case ItemType::COFFEE: case ItemType::COFFEE:
@@ -500,18 +515,14 @@ void Game::checkPlayerItemCollision(std::shared_ptr<Player> &player)
if (player->getCoffees() == 2) if (player->getCoffees() == 2)
{ {
player->addScore(5000); player->addScore(5000);
const auto x = const auto x = item->getPosX() + (item->getWidth() - game_text_textures_.at(2)->getWidth()) / 2;
item->getPosX() + createItemText(x, game_text_textures_.at(2));
(item->getWidth() - game_text_textures_[2]->getWidth()) / 2;
createItemText(x, game_text_textures_[2]);
} }
else else
{ {
player->giveExtraHit(); player->giveExtraHit();
const auto x = const auto x = item->getPosX() + (item->getWidth() - game_text_textures_.at(4)->getWidth()) / 2;
item->getPosX() + createItemText(x, game_text_textures_.at(4));
(item->getWidth() - game_text_textures_[4]->getWidth()) / 2;
createItemText(x, game_text_textures_[4]);
} }
JA_PlaySound(Resource::get()->getSound("voice_coffee.wav")); JA_PlaySound(Resource::get()->getSound("voice_coffee.wav"));
break; break;
@@ -520,10 +531,8 @@ void Game::checkPlayerItemCollision(std::shared_ptr<Player> &player)
{ {
player->setPowerUp(); player->setPowerUp();
coffee_machine_enabled_ = false; coffee_machine_enabled_ = false;
const auto x = const auto x = item->getPosX() + (item->getWidth() - game_text_textures_.at(3)->getWidth()) / 2;
item->getPosX() + createItemText(x, game_text_textures_.at(3));
(item->getWidth() - game_text_textures_[3]->getWidth()) / 2;
createItemText(x, game_text_textures_[3]);
JA_PlaySound(Resource::get()->getSound("voice_power_up.wav")); JA_PlaySound(Resource::get()->getSound("voice_power_up.wav"));
break; break;
} }
@@ -532,18 +541,46 @@ void Game::checkPlayerItemCollision(std::shared_ptr<Player> &player)
} }
updateHiScore(); updateHiScore();
JA_PlaySound(Resource::get()->getSound("itempickup.wav"));
item->disable(); item->disable();
} }
} }
} }
} }
// Comprueba y procesa la colisión entre las balas y los globos // Comprueba y procesa la colisión de las balas
void Game::checkBulletBalloonCollision() void Game::checkBulletCollision()
{ {
for (auto &bullet : bullets_) for (auto &bullet : bullets_)
{ {
// Comprueba la colisión con el Tabe
if (bullet->isEnabled() && tabe_->isEnabled())
if (checkCollision(bullet->getCollider(), tabe_->getCollider()))
{
tabe_->setState(TabeState::HIT);
bullet->disable();
auto pos = tabe_->getCollider();
if (tabe_->tryToGetBonus())
{
createItem(ItemType::DEBIAN, pos.x, pos.y);
JA_PlaySound(Resource::get()->getSound("debian_drop.wav"));
}
else
{
if (rand() % 3 == 0)
{
createItem(ItemType::COFFEE, pos.x, pos.y);
// JA_PlaySound(Resource::get()->getSound("item_drop.wav"));
}
else
{
// JA_PlaySound(Resource::get()->getSound("tabe_hit.wav"));
}
JA_PlaySound(Resource::get()->getSound("tabe_hit.wav"));
}
break;
}
// Comprueba la colisión con los globos
for (auto &balloon : balloon_manager_->getBalloons()) for (auto &balloon : balloon_manager_->getBalloons())
{ {
if (balloon->isEnabled() && (!balloon->isInvulnerable()) && bullet->isEnabled()) if (balloon->isEnabled() && (!balloon->isInvulnerable()) && bullet->isEnabled())
@@ -560,7 +597,7 @@ void Game::checkBulletBalloonCollision()
if (dropped_item != ItemType::COFFEE_MACHINE) if (dropped_item != ItemType::COFFEE_MACHINE)
{ {
createItem(dropped_item, balloon->getPosX(), balloon->getPosY()); createItem(dropped_item, balloon->getPosX(), balloon->getPosY());
JA_PlaySound(Resource::get()->getSound("itemdrop.wav")); JA_PlaySound(Resource::get()->getSound("item_drop.wav"));
} }
else else
{ {
@@ -745,7 +782,7 @@ void Game::createItemText(int x, std::shared_ptr<Texture> texture)
const auto h = texture->getHeight(); const auto h = texture->getHeight();
const int y0 = param.game.play_area.rect.h - h; const int y0 = param.game.play_area.rect.h - h;
const int y1 = 155; const int y1 = 160 - (h / 2);
const int y2 = -h; const int y2 = -h;
// Ajusta para que no se dibuje fuera de pantalla // Ajusta para que no se dibuje fuera de pantalla
@@ -865,7 +902,7 @@ void Game::killPlayer(std::shared_ptr<Player> &player)
// Lo pierde // Lo pierde
player->removeExtraHit(); player->removeExtraHit();
throwCoffee(player->getPosX() + (player->getWidth() / 2), player->getPosY() + (player->getHeight() / 2)); throwCoffee(player->getPosX() + (player->getWidth() / 2), player->getPosY() + (player->getHeight() / 2));
JA_PlaySound(Resource::get()->getSound("coffeeout.wav")); JA_PlaySound(Resource::get()->getSound("coffee_out.wav"));
screen_->shake(); screen_->shake();
} }
else else
@@ -893,20 +930,28 @@ void Game::updateTimeStopped()
if (time_stopped_counter_ > 120) if (time_stopped_counter_ > 120)
{ {
if (time_stopped_counter_ % 30 == 0) if (time_stopped_counter_ % 30 == 0)
{
JA_PlaySound(Resource::get()->getSound("clock.wav")); JA_PlaySound(Resource::get()->getSound("clock.wav"));
} }
}
else else
{ {
if (time_stopped_counter_ % 15 == 0)
JA_PlaySound(Resource::get()->getSound("clock.wav"));
if (time_stopped_counter_ % 30 == 0) if (time_stopped_counter_ % 30 == 0)
{
balloon_manager_->normalColorsToAllBalloons(); balloon_manager_->normalColorsToAllBalloons();
if (time_stopped_counter_ % 30 == 15) JA_PlaySound(Resource::get()->getSound("clock.wav"));
}
else if (time_stopped_counter_ % 30 == 15)
{
balloon_manager_->reverseColorsToAllBalloons(); balloon_manager_->reverseColorsToAllBalloons();
JA_PlaySound(Resource::get()->getSound("clock.wav"));
}
} }
} }
else else
{
disableTimeStopItem(); disableTimeStopItem();
}
} }
// Actualiza el juego // Actualiza el juego
@@ -1224,6 +1269,7 @@ void Game::checkEvents()
{ {
auto_pop_balloons_ = !auto_pop_balloons_; auto_pop_balloons_ = !auto_pop_balloons_;
Notifier::get()->showText({"auto advance: " + boolToString(auto_pop_balloons_)}); Notifier::get()->showText({"auto advance: " + boolToString(auto_pop_balloons_)});
if (auto_pop_balloons_)
balloon_manager_->destroyAllBalloons(); balloon_manager_->destroyAllBalloons();
balloon_manager_->setDeployBalloons(!auto_pop_balloons_); balloon_manager_->setDeployBalloons(!auto_pop_balloons_);
break; break;
@@ -1233,10 +1279,10 @@ void Game::checkEvents()
createItem(ItemType::CLOCK, players_.at(0)->getPosX(), players_.at(0)->getPosY() - 40); createItem(ItemType::CLOCK, players_.at(0)->getPosX(), players_.at(0)->getPosY() - 40);
break; break;
} }
case SDLK_5: // Crea un PathSprite case SDLK_5: // 5.000
{ {
const int x = players_.at(0)->getPosX() + (players_.at(0)->getWidth() - game_text_textures_[3]->getWidth()) / 2; const int x = players_.at(0)->getPosX() + (players_.at(0)->getWidth() - game_text_textures_[3]->getWidth()) / 2;
createItemText(x, game_text_textures_.at(3)); createItemText(x, game_text_textures_.at(2));
break; break;
} }
case SDLK_6: // Crea un mensaje case SDLK_6: // Crea un mensaje
@@ -1244,9 +1290,13 @@ void Game::checkEvents()
createMessage({paths_.at(0), paths_.at(1)}, Resource::get()->getTexture("game_text_get_ready")); createMessage({paths_.at(0), paths_.at(1)}, Resource::get()->getTexture("game_text_get_ready"));
break; break;
} }
case SDLK_7: // Flash case SDLK_7: // 100.000
{ {
screen_->flash(flash_color, 3); // screen_->flash(flash_color, 3);
// tabe_->setState(TabeState::HIT);
const int x = players_.at(0)->getPosX() + (players_.at(0)->getWidth() - game_text_textures_[3]->getWidth()) / 2;
createItemText(x, game_text_textures_.at(6));
break;
break; break;
} }
case SDLK_8: case SDLK_8:
@@ -1941,7 +1991,7 @@ void Game::updateGameStatePlaying()
updatePathSprites(); updatePathSprites();
updateTimeStopped(); updateTimeStopped();
updateHelper(); updateHelper();
checkBulletBalloonCollision(); checkBulletCollision();
updateMenace(); updateMenace();
checkAndUpdateBalloonSpeed(); checkAndUpdateBalloonSpeed();
checkState(); checkState();

View File

@@ -211,8 +211,8 @@ private:
// Comprueba la colisión entre el jugador y los items // Comprueba la colisión entre el jugador y los items
void checkPlayerItemCollision(std::shared_ptr<Player> &player); void checkPlayerItemCollision(std::shared_ptr<Player> &player);
// Comprueba la colisión entre las balas y los globos // Comprueba y procesa la colisión de las balas
void checkBulletBalloonCollision(); void checkBulletCollision();
// Mueve las balas activas // Mueve las balas activas
void updateBullets(); void updateBullets();

View File

@@ -4,23 +4,28 @@
#include <SDL2/SDL_pixels.h> // Para SDL_PIXELFORMAT_RGBA8888 #include <SDL2/SDL_pixels.h> // Para SDL_PIXELFORMAT_RGBA8888
#include <SDL2/SDL_timer.h> // Para SDL_GetTicks #include <SDL2/SDL_timer.h> // Para SDL_GetTicks
#include <SDL2/SDL_video.h> // Para SDL_WINDOWEVENT_SIZE_CHANGED #include <SDL2/SDL_video.h> // Para SDL_WINDOWEVENT_SIZE_CHANGED
#include <stdlib.h> // Para rand
#include <algorithm> // Para max #include <algorithm> // Para max
#include <functional> // Para function
#include <vector> // Para vector #include <vector> // Para vector
#include "background.h" // Para Background #include "background.h" // Para Background
#include "fade.h" // Para Fade, FadeMode, FadeType #include "fade.h" // Para Fade, FadeMode, FadeType
#include "global_inputs.h" // Para check #include "global_inputs.h" // Para check, update
#include "input.h" // Para Input #include "input.h" // Para Input
#include "jail_audio.h" // Para JA_GetMusicState, JA_Music_state #include "jail_audio.h" // Para JA_GetMusicState, JA_Music_state
#include "lang.h" // Para getText #include "lang.h" // Para getText
#include "manage_hiscore_table.h" // Para HiScoreEntry #include "manage_hiscore_table.h" // Para HiScoreEntry
#include "mouse.h" // Para handleEvent
#include "options.h" // Para Options, OptionsGame, options #include "options.h" // Para Options, OptionsGame, options
#include "param.h" // Para Param, param, ParamGame, ParamFade #include "param.h" // Para Param, param, ParamGame, ParamFade
#include "path_sprite.h" // Para PathSprite, Path, PathType
#include "resource.h" // Para Resource #include "resource.h" // Para Resource
#include "screen.h" // Para Screen #include "screen.h" // Para Screen
#include "section.h" // Para Name, name, Options, options #include "section.h" // Para Name, name, Options, options, Attr...
#include "text.h" // Para Text, TEXT_CENTER, TEXT_SHADOW #include "sprite.h" // Para Sprite
#include "utils.h" // Para Color, Zone, fade_color, orange_color #include "text.h" // Para Text, TEXT_COLOR, TEXT_SHADOW
#include "mouse.h" #include "texture.h" // Para Texture
#include "utils.h" // Para Color, easeOutQuint, fade_color
// Constructor // Constructor
HiScoreTable::HiScoreTable() HiScoreTable::HiScoreTable()
@@ -28,31 +33,18 @@ HiScoreTable::HiScoreTable()
backbuffer_(SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, param.game.width, param.game.height)), backbuffer_(SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, param.game.width, param.game.height)),
fade_(std::make_unique<Fade>()), fade_(std::make_unique<Fade>()),
background_(std::make_unique<Background>()), background_(std::make_unique<Background>()),
text_(Resource::get()->getText("smb2")),
counter_(0), counter_(0),
ticks_(0), ticks_(0),
view_area_({0, 0, param.game.width, param.game.height}), view_area_({0, 0, param.game.width, param.game.height}),
fade_mode_(FadeMode::IN) fade_mode_(FadeMode::IN),
background_fade_color_(Color(0, 0, 0))
{ {
// Inicializa el resto de variables // Inicializa el resto
section::name = section::Name::HI_SCORE_TABLE; section::name = section::Name::HI_SCORE_TABLE;
// Inicializa objetos
SDL_SetTextureBlendMode(backbuffer_, SDL_BLENDMODE_BLEND); SDL_SetTextureBlendMode(backbuffer_, SDL_BLENDMODE_BLEND);
background_->setPos(param.game.game_area.rect); initFade();
background_->setCloudsSpeed(-0.1f); initBackground();
background_->setGradientNumber(1); createSprites();
background_->setTransition(0.8f);
background_->setSunProgression(1.0f);
background_->setMoonProgression(0.6f);
fade_->setColor(fade_color.r, fade_color.g, fade_color.b);
fade_->setType(FadeType::RANDOM_SQUARE);
fade_->setPostDuration(param.fade.post_duration);
fade_->setMode(fade_mode_);
fade_->activate();
// Crea el contenido de la textura con la lista de puntuaciones
fillTexture();
} }
// Destructor // Destructor
@@ -77,6 +69,9 @@ void HiScoreTable::update()
JA_PlayMusic(Resource::get()->getMusic("title.ogg")); JA_PlayMusic(Resource::get()->getMusic("title.ogg"));
} }
// Actualiza las posiciones de los sprites de texto
updateSprites();
// Actualiza el objeto screen // Actualiza el objeto screen
Screen::get()->update(); Screen::get()->update();
@@ -94,7 +89,7 @@ void HiScoreTable::update()
if (counter_ == 150) if (counter_ == 150)
{ {
background_->setColor(Color(0, 0, 0)); background_->setColor(background_fade_color_.darken());
background_->setAlpha(96); background_->setAlpha(96);
} }
@@ -102,19 +97,15 @@ void HiScoreTable::update()
{ {
fade_->activate(); fade_->activate();
} }
// Dibuja los sprites en la textura
fillTexture();
} }
} }
// Crea el contenido de la textura con la lista de puntuaciones // Dibuja los sprites en la textura
void HiScoreTable::fillTexture() void HiScoreTable::fillTexture()
{ {
// hay 27 letras - 7 de puntos quedan 20 caracteres 20 - name_lenght 0 num_dots
constexpr auto max_names = 10;
constexpr auto space_between_header = 32;
const auto space_between_lines = text_->getCharacterSize() * 2.0f;
const auto size = space_between_header + space_between_lines * (max_names - 1) + text_->getCharacterSize();
const auto first_line = (param.game.height - size) / 2;
// Pinta en el backbuffer el texto y los sprites // Pinta en el backbuffer el texto y los sprites
auto temp = SDL_GetRenderTarget(renderer_); auto temp = SDL_GetRenderTarget(renderer_);
SDL_SetRenderTarget(renderer_, backbuffer_); SDL_SetRenderTarget(renderer_, backbuffer_);
@@ -122,22 +113,12 @@ void HiScoreTable::fillTexture()
SDL_RenderClear(renderer_); SDL_RenderClear(renderer_);
// Escribe el texto: Mejores puntuaciones // Escribe el texto: Mejores puntuaciones
text_->writeDX(TEXT_CENTER | TEXT_COLOR | TEXT_SHADOW, param.game.game_area.center_x, first_line, lang::getText(42), 1, orange_color, 1, shdw_txt_color); header_->render();
// Escribe los nombres de la tabla de puntuaciones // Escribe los nombres de la tabla de puntuaciones
for (int i = 0; i < max_names; ++i) for (auto const &entry : entry_names_)
{ {
const auto name_lenght = options.game.hi_score_table[i].name.length(); entry->render();
const auto score = format(options.game.hi_score_table[i].score);
const auto score_lenght = score.size();
const auto num_dots = 25 - name_lenght - score_lenght;
std::string dots;
for (int j = 0; j < (int)num_dots; ++j)
{
dots = dots + ".";
}
const auto line = options.game.hi_score_table[i].name + dots + score;
text_->writeDX(TEXT_CENTER | TEXT_SHADOW, param.game.game_area.center_x, (i * space_between_lines) + first_line + space_between_header, line, 1, orange_color, 1, shdw_txt_color);
} }
// Cambia el destino de renderizado // Cambia el destino de renderizado
@@ -172,8 +153,6 @@ void HiScoreTable::render()
// Recarga todas las texturas // Recarga todas las texturas
void HiScoreTable::reloadTextures() void HiScoreTable::reloadTextures()
{ {
text_->reLoadTexture();
fillTexture();
} }
// Comprueba los eventos // Comprueba los eventos
@@ -275,3 +254,196 @@ std::string HiScoreTable::format(int number)
return result; return result;
} }
// Crea los sprites con los textos
void HiScoreTable::createSprites()
{
auto header_text = Resource::get()->getText("04b_25");
auto entry_text = Resource::get()->getText("smb2");
// Obtiene el tamaño de la textura
int backbuffer_width;
int backbuffer_height;
SDL_QueryTexture(backbuffer_, nullptr, nullptr, &backbuffer_width, &backbuffer_height);
// Hay 27 letras - 7 de puntos quedan 20 caracteres 20 - name_lenght 0 num_dots
constexpr int max_names = 10;
constexpr int space_between_header = 32;
const int space_between_lines = entry_text->getCharacterSize() * 2;
const int size = space_between_header + space_between_lines * (max_names - 1) + entry_text->getCharacterSize();
const int first_line = (param.game.height - size) / 2;
// Crea el sprite para el texto de cabecera
header_ = std::make_unique<Sprite>(header_text->writeDXToTexture(TEXT_COLOR, lang::getText(42), -2, background_fade_color_.getInverse().lighten(25)));
header_->setPosition(param.game.game_area.center_x - (header_->getWidth() / 2), first_line);
// Crea los sprites para las entradas en la tabla de puntuaciones
const int animation = rand() % 4;
for (int i = 0; i < max_names; ++i)
{
const auto table_position = (i + 1 >= 10) ? format(i + 1) + ". " : " " + format(i + 1) + ". ";
const auto score = format(options.game.hi_score_table.at(i).score);
const auto num_dots = 25 - table_position.size() - options.game.hi_score_table.at(i).name.size() - score.size();
std::string dots;
for (int j = 0; j < (int)num_dots; ++j)
{
dots = dots + ".";
}
const auto line = table_position + options.game.hi_score_table.at(i).name + dots + score;
entry_names_.emplace_back(std::make_shared<PathSprite>(entry_text->writeDXToTexture(TEXT_SHADOW, line, 1, orange_color, 1, shdw_txt_color)));
switch (animation)
{
case 0: // Ambos lados alternativamente
{
if (i % 2 == 0)
{
entry_names_.back()->addPath(
-entry_names_.back()->getWidth(),
(backbuffer_width - entry_names_.back()->getWidth()) / 2,
PathType::HORIZONTAL,
(i * space_between_lines) + first_line + space_between_header,
80,
easeOutQuint,
0);
entry_names_.back()->setPosition(-entry_names_.back()->getWidth(), 0);
}
else
{
entry_names_.back()->addPath(
backbuffer_width,
(backbuffer_width - entry_names_.back()->getWidth()) / 2,
PathType::HORIZONTAL,
(i * space_between_lines) + first_line + space_between_header,
80,
easeOutQuint,
0);
entry_names_.back()->setPosition(backbuffer_width, 0);
}
break;
}
case 1: // Entran por la izquierda
{
entry_names_.back()->addPath(
-entry_names_.back()->getWidth(),
(backbuffer_width - entry_names_.back()->getWidth()) / 2,
PathType::HORIZONTAL,
(i * space_between_lines) + first_line + space_between_header,
80,
easeOutQuint,
0);
entry_names_.back()->setPosition(-entry_names_.back()->getWidth(), 0);
break;
}
case 2: // Entran por la derecha
{
entry_names_.back()->addPath(
backbuffer_width,
(backbuffer_width - entry_names_.back()->getWidth()) / 2,
PathType::HORIZONTAL,
(i * space_between_lines) + first_line + space_between_header,
80,
easeOutQuint,
0);
entry_names_.back()->setPosition(backbuffer_width, 0);
break;
}
case 3: // Entran desde la parte inferior
{
entry_names_.back()->addPath(
backbuffer_height,
(i * space_between_lines) + first_line + space_between_header,
PathType::VERTICAL,
(backbuffer_width - entry_names_.back()->getWidth()) / 2,
80,
easeOutQuint,
0);
entry_names_.back()->setPosition(0, backbuffer_height);
}
default:
break;
}
}
}
// Actualiza las posiciones de los sprites de texto
void HiScoreTable::updateSprites()
{
constexpr int init_counter = 190;
const int counter_between_entries = 16;
if (counter_ >= init_counter)
{
const int counter2 = counter_ - init_counter;
if (counter2 % counter_between_entries == 0)
{
int index = counter2 / counter_between_entries;
if (index < static_cast<int>(entry_names_.size()))
{
entry_names_.at(index)->enable();
}
}
}
for (auto const &entry : entry_names_)
{
entry->update();
}
}
// Inicializa el fade
void HiScoreTable::initFade()
{
fade_->setColor(fade_color.r, fade_color.g, fade_color.b);
fade_->setType(FadeType::RANDOM_SQUARE);
fade_->setPostDuration(param.fade.post_duration);
fade_->setMode(fade_mode_);
fade_->activate();
}
// Inicializa el fondo
void HiScoreTable::initBackground()
{
background_->setPos(param.game.game_area.rect);
background_->setCloudsSpeed(-0.1f);
const int lucky = rand() % 3;
//const int lucky = 2;
switch (lucky)
{
case 0: // Fondo verde
{
background_->setGradientNumber(2);
background_->setTransition(0.0f);
background_->setSunProgression(1.0f);
background_->setMoonProgression(0.4f);
background_fade_color_ = Color(0x00, 0x79, 0x6b);
break;
}
case 1: // Fondo naranja
{
background_->setGradientNumber(1);
background_->setTransition(0.0f);
background_->setSunProgression(0.65f);
background_->setMoonProgression(0.0f);
background_fade_color_ = Color(0xff, 0x6b, 0x97);
break;
}
case 2: // Fondo azul
{
background_->setGradientNumber(0);
background_->setTransition(0.0f);
background_->setSunProgression(0.0f);
background_->setMoonProgression(0.0f);
background_fade_color_ = Color(0x02, 0x88, 0xd1);
break;
}
default:
break;
}
}

View File

@@ -1,14 +1,18 @@
#pragma once #pragma once
#include <SDL2/SDL_rect.h> // para SDL_Rect #include <SDL2/SDL_rect.h> // Para SDL_Rect
#include <SDL2/SDL_render.h> // para SDL_Renderer, SDL_Texture #include <SDL2/SDL_render.h> // Para SDL_Renderer, SDL_Texture
#include <SDL2/SDL_stdinc.h> // para Uint16, Uint32, Uint8 #include <SDL2/SDL_stdinc.h> // Para Uint16, Uint32, Uint8
#include <memory> // para unique_ptr #include <memory> // Para unique_ptr, shared_ptr
#include <string> // para string #include <string> // Para string
class Background; // lines 8-8 #include <vector> // Para vector
class Fade; // lines 9-9 #include "utils.h"
class Text; // lines 10-10 class Background; // lines 10-10
enum class FadeMode : Uint8; // lines 11-11 class Fade; // lines 11-11
class PathSprite;
class Sprite;
enum class FadeMode : Uint8; // lines 13-13
struct Path;
/* /*
Esta clase gestiona un estado del programa. Se encarga de mostrar la tabla con las puntuaciones Esta clase gestiona un estado del programa. Se encarga de mostrar la tabla con las puntuaciones
@@ -33,13 +37,16 @@ private:
std::unique_ptr<Fade> fade_; // Objeto para renderizar fades std::unique_ptr<Fade> fade_; // Objeto para renderizar fades
std::unique_ptr<Background> background_; // Objeto para dibujar el fondo del juego std::unique_ptr<Background> background_; // Objeto para dibujar el fondo del juego
std::shared_ptr<Text> text_; // Objeto para escribir texto std::unique_ptr<Sprite> header_; // Sprite con la cabecera del texto
std::vector<std::shared_ptr<PathSprite>> entry_names_; // Lista con los spritres de cada uno de los nombres de la tabla de records
std::vector<Path> paths_; // Vector con los recorridos precalculados
// Variables // Variables
Uint16 counter_; // Contador Uint16 counter_ = 0; // Contador
Uint32 ticks_; // Contador de ticks para ajustar la velocidad del programa Uint32 ticks_; // Contador de ticks para ajustar la velocidad del programa
SDL_Rect view_area_; // Parte de la textura que se muestra en pantalla SDL_Rect view_area_; // Parte de la textura que se muestra en pantalla
FadeMode fade_mode_; // Modo de fade a utilizar FadeMode fade_mode_; // Modo de fade a utilizar
Color background_fade_color_; // Color de atenuación del fondo
// Actualiza las variables // Actualiza las variables
void update(); void update();
@@ -56,7 +63,7 @@ private:
// Convierte un entero a un string con separadores de miles // Convierte un entero a un string con separadores de miles
std::string format(int number); std::string format(int number);
// Crea el contenido de la textura con la lista de puntuaciones // Dibuja los sprites en la textura
void fillTexture(); void fillTexture();
// Recarga todas las texturas // Recarga todas las texturas
@@ -65,6 +72,18 @@ private:
// Gestiona el fade // Gestiona el fade
void updateFade(); void updateFade();
// Crea los sprites con los textos
void createSprites();
// Actualiza las posiciones de los sprites de texto
void updateSprites();
// Inicializa el fade
void initFade();
// Inicializa el fondo
void initBackground();
public: public:
// Constructor // Constructor
HiScoreTable(); HiScoreTable();

View File

@@ -22,6 +22,10 @@
#include "utils.h" // Para Color, shdw_txt_color, Zone, no_color #include "utils.h" // Para Color, shdw_txt_color, Zone, no_color
#include "mouse.h" #include "mouse.h"
#include <SDL2/SDL.h>
#include <vector>
#include <cmath>
// Constructor // Constructor
Instructions::Instructions() Instructions::Instructions()
: renderer_(Screen::get()->getRenderer()), : renderer_(Screen::get()->getRenderer()),
@@ -46,6 +50,9 @@ Instructions::Instructions()
fade_->setMode(FadeMode::IN); fade_->setMode(FadeMode::IN);
fade_->activate(); fade_->activate();
// Inicializa las líneas con un retraso progresivo de 50 ms
lines_ = initializeLines(256);
// Rellena la textura de texto // Rellena la textura de texto
fillTexture(); fillTexture();
@@ -159,7 +166,6 @@ void Instructions::fillTexture()
text_->writeDX(TEXT_CENTER | TEXT_COLOR | TEXT_SHADOW, param.game.game_area.center_x, anchor2, lang::getText(16), 1, orange_color, 1, shdw_txt_color); text_->writeDX(TEXT_CENTER | TEXT_COLOR | TEXT_SHADOW, param.game.game_area.center_x, anchor2, lang::getText(16), 1, orange_color, 1, shdw_txt_color);
const int anchor3 = anchor2 + space_post_header; const int anchor3 = anchor2 + space_post_header;
// const int anchor4 = anchor3 + ((param.game.item_size + text->getCharacterSize()) / 2);
text_->writeShadowed(anchor_item + desp_x, anchor3 + space_between_item_lines * 0, lang::getText(17), shdw_txt_color); text_->writeShadowed(anchor_item + desp_x, anchor3 + space_between_item_lines * 0, lang::getText(17), shdw_txt_color);
text_->writeShadowed(anchor_item + desp_x, anchor3 + space_between_item_lines * 1, lang::getText(18), shdw_txt_color); text_->writeShadowed(anchor_item + desp_x, anchor3 + space_between_item_lines * 1, lang::getText(18), shdw_txt_color);
text_->writeShadowed(anchor_item + desp_x, anchor3 + space_between_item_lines * 2, lang::getText(19), shdw_txt_color); text_->writeShadowed(anchor_item + desp_x, anchor3 + space_between_item_lines * 2, lang::getText(19), shdw_txt_color);
@@ -226,14 +232,36 @@ void Instructions::update()
// Actualiza los sprites // Actualiza los sprites
updateSprites(); updateSprites();
// Establece la ventana del backbuffer
view_.y = std::max(0, param.game.height - counter_ + 100);
// Verifica si view_.y == 0 y gestiona el temporizador
if (view_.y == 0)
{
if (!start_delay_triggered_)
{
// Activa el temporizador si no ha sido activado
start_delay_triggered_ = true;
start_delay_time_ = SDL_GetTicks();
}
else if (SDL_GetTicks() - start_delay_time_ >= 4000)
{
// Han pasado tres segundos, mover líneas
all_lines_off_screen_ = moveLines(lines_, 320, 1.0f, 5);
}
}
// Actualiza el mosaico de fondo // Actualiza el mosaico de fondo
tiled_bg_->update(); tiled_bg_->update();
// Actualiza el objeto "fade" // Actualiza el objeto "fade"
fade_->update(); fade_->update();
// Rellena el backbuffer
fillBackbuffer();
// Comprueba si el contador ha llegado al final // Comprueba si el contador ha llegado al final
if (counter_ == counter_end_) if (all_lines_off_screen_)
{ {
section::name = section::Name::TITLE; section::name = section::Name::TITLE;
section::options = section::Options::TITLE_1; section::options = section::Options::TITLE_1;
@@ -244,9 +272,6 @@ void Instructions::update()
// Pinta en pantalla // Pinta en pantalla
void Instructions::render() void Instructions::render()
{ {
// Rellena el backbuffer
fillBackbuffer();
// Prepara para empezar a dibujar en la textura de juego // Prepara para empezar a dibujar en la textura de juego
Screen::get()->start(); Screen::get()->start();
@@ -256,10 +281,10 @@ void Instructions::render()
// Dibuja el mosacico de fondo // Dibuja el mosacico de fondo
tiled_bg_->render(); tiled_bg_->render();
// Establece la ventana del backbuffer
view_.y = std::max(0, param.game.height - counter_ + 100);
// Copia la textura y el backbuffer al renderizador // Copia la textura y el backbuffer al renderizador
if (view_.y == 0)
renderLines(renderer_, backbuffer_, lines_);
else
SDL_RenderCopy(renderer_, backbuffer_, nullptr, &view_); SDL_RenderCopy(renderer_, backbuffer_, nullptr, &view_);
fade_->render(); fade_->render();
@@ -336,3 +361,60 @@ void Instructions::run()
render(); render();
} }
} }
// Método para inicializar las líneas
std::vector<Line> Instructions::initializeLines(int height)
{
std::vector<Line> lines;
for (int y = 0; y < height; y++)
{
int direction = (y % 2 == 0) ? -1 : 1; // Pares a la izquierda, impares a la derecha
lines.emplace_back(y, 0.0f, direction);
}
return lines;
}
// Método para mover las líneas con suavizado
bool Instructions::moveLines(std::vector<Line> &lines, int width, float duration, Uint32 startDelay)
{
Uint32 currentTime = SDL_GetTicks();
bool allLinesOffScreen = true;
for (auto &line : lines)
{
// Establecer startTime en el primer cuadro de animación
if (line.startTime == 0)
{
line.startTime = currentTime + line.y * startDelay;
}
float elapsedTime = (currentTime - line.startTime) / 1000.0f; // Convertir a segundos
if (elapsedTime < 0)
{
allLinesOffScreen = false; // Si aún no se debe mover esta línea, no están todas fuera de pantalla
continue;
}
if (elapsedTime >= duration)
{
continue; // Si la línea ha salido de los límites, no la muevas más
}
float t = elapsedTime / duration;
float smoothFactor = easeInOutQuint(t);
line.x = line.direction * smoothFactor * width;
allLinesOffScreen = false; // Si alguna línea aún se está moviendo, no están todas fuera de pantalla
}
return allLinesOffScreen;
}
// Método para renderizar las líneas
void Instructions::renderLines(SDL_Renderer *renderer, SDL_Texture *texture, const std::vector<Line> &lines)
{
for (const auto &line : lines)
{
SDL_Rect srcRect = {0, line.y, 320, 1};
SDL_Rect dstRect = {static_cast<int>(line.x), line.y, 320, 1};
SDL_RenderCopy(renderer, texture, &srcRect, &dstRect);
}
}

View File

@@ -24,6 +24,19 @@ class TiledBG; // lines 12-12
por la pantalla sobre el mosaico de fondo (gestionado por el correspondiente objeto) por la pantalla sobre el mosaico de fondo (gestionado por el correspondiente objeto)
*/ */
// Estructura para almacenar información de línea
struct Line
{
int y; // Coordenada Y de la línea
float x; // Coordenada X inicial (usamos float para mayor precisión en el suavizado)
int direction; // Dirección de movimiento: -1 para izquierda, 1 para derecha
Uint32 startTime; // Tiempo de inicio del movimiento
// Constructor de Line
Line(int y, float x, int direction)
: y(y), x(x), direction(direction), startTime(0) {}
};
// Clase Instructions // Clase Instructions
class Instructions class Instructions
{ {
@@ -40,12 +53,15 @@ private:
std::unique_ptr<Fade> fade_; // Objeto para renderizar fades std::unique_ptr<Fade> fade_; // Objeto para renderizar fades
// Variables // Variables
int counter_ = 0; // Contador int counter_ = 0; // Contador para manejar el progreso en la pantalla de instrucciones
int counter_end_ = 700; // Valor final para el contador
Uint32 ticks_ = 0; // Contador de ticks para ajustar la velocidad del programa Uint32 ticks_ = 0; // Contador de ticks para ajustar la velocidad del programa
SDL_Rect view_; // Vista del backbuffer que se va amostrar por pantalla SDL_Rect view_; // Vista del backbuffer que se va a mostrar por pantalla
SDL_Point sprite_pos_ = {0, 0}; // Posición del primer sprite SDL_Point sprite_pos_ = {0, 0}; // Posición del primer sprite en la lista
int item_space_ = 2; // Espacio entre los items int item_space_ = 2; // Espacio entre los items en pantalla
std::vector<Line> lines_; // Vector que contiene las líneas animadas en la pantalla
bool all_lines_off_screen_ = false; // Indica si todas las líneas han salido de la pantalla
Uint32 start_delay_time_ = 0; // Tiempo de inicio del retraso para mover las líneas
bool start_delay_triggered_ = false; // Bandera para determinar si el retraso ha comenzado
// Actualiza las variables // Actualiza las variables
void update(); void update();
@@ -74,6 +90,15 @@ private:
// Recarga todas las texturas // Recarga todas las texturas
void reloadTextures(); void reloadTextures();
// Método para inicializar las líneas
std::vector<Line> initializeLines(int height);
// Método para mover las líneas
bool moveLines(std::vector<Line> &lines, int width, float duration, Uint32 startDelay);
// Método para renderizar las líneas
void renderLines(SDL_Renderer *renderer, SDL_Texture *texture, const std::vector<Line> &lines);
public: public:
// Constructor // Constructor
Instructions(); Instructions();

View File

@@ -21,7 +21,7 @@
// Constructor // Constructor
Intro::Intro() Intro::Intro()
: texture_(Resource::get()->getTexture("intro.png")), : texture_(Resource::get()->getTexture("intro.png")),
text_(Resource::get()->getText("nokia")) text_(Resource::get()->getText("04b_25_var01"))
{ {
// Inicializa variables // Inicializa variables
@@ -97,7 +97,7 @@ Intro::Intro()
auto w = std::make_unique<Writer>(text_); auto w = std::make_unique<Writer>(text_);
w->setPosX(BLOCK * 0); w->setPosX(BLOCK * 0);
w->setPosY(param.game.height - (BLOCK * 6)); w->setPosY(param.game.height - (BLOCK * 6));
w->setKerning(-1); w->setKerning(-2);
w->setEnabled(false); w->setEnabled(false);
w->setFinishedCounter(180); w->setFinishedCounter(180);
texts_.push_back(std::move(w)); texts_.push_back(std::move(w));

View File

@@ -22,8 +22,9 @@ enum class ItemType : int
PACMAR = 3, /**< Pacman */ PACMAR = 3, /**< Pacman */
CLOCK = 4, /**< Reloj */ CLOCK = 4, /**< Reloj */
COFFEE = 5, /**< Café */ COFFEE = 5, /**< Café */
COFFEE_MACHINE = 6,/**< Máquina de café */ DEBIAN = 6, /**< Debian */
NONE = 7, /**< Ninguno */ COFFEE_MACHINE = 7,/**< Máquina de café */
NONE = 8, /**< Ninguno */
}; };
/** /**

View File

@@ -96,7 +96,7 @@ void PathSprite::addPath(std::vector<SDL_Point> spots, int waiting_counter)
// Habilita el objeto // Habilita el objeto
void PathSprite::enable() void PathSprite::enable()
{ {
if (paths_.size() == 0) if (paths_.size() == 0 || enabled_)
{ {
return; return;
} }
@@ -133,10 +133,14 @@ void PathSprite::moveThroughCurrentPath()
if (path.on_destination) if (path.on_destination)
{ {
if (path.waiting_counter == 0) if (path.waiting_counter == 0)
{
path.finished = true; path.finished = true;
}
else else
{
--path.waiting_counter; --path.waiting_counter;
} }
}
} }
// Cambia de recorrido o finaliza // Cambia de recorrido o finaliza
@@ -144,11 +148,15 @@ void PathSprite::goToNextPathOrDie()
{ {
// Comprueba si ha terminado el recorrdo actual // Comprueba si ha terminado el recorrdo actual
if (paths_.at(current_path_).finished) if (paths_.at(current_path_).finished)
{
++current_path_; ++current_path_;
}
// Comprueba si quedan mas recorridos // Comprueba si quedan mas recorridos
if (current_path_ >= static_cast<int>(paths_.size())) if (current_path_ >= static_cast<int>(paths_.size()))
{
enabled_ = false; enabled_ = false;
}
} }
// Indica si ha terminado todos los recorridos // Indica si ha terminado todos los recorridos

View File

@@ -301,6 +301,7 @@ void Resource::createTextures()
// Tamaño doble // Tamaño doble
std::vector<NameAndText> strings2X = { std::vector<NameAndText> strings2X = {
NameAndText("game_text_100000_points", "100.000"),
NameAndText("game_text_get_ready", lang::getText(75)), NameAndText("game_text_get_ready", lang::getText(75)),
NameAndText("game_text_last_stage", lang::getText(79)), NameAndText("game_text_last_stage", lang::getText(79)),
NameAndText("game_text_congratulations", lang::getText(50)), NameAndText("game_text_congratulations", lang::getText(50)),
@@ -322,6 +323,7 @@ void Resource::createText()
std::vector<std::pair<std::string, std::string>> resources = { std::vector<std::pair<std::string, std::string>> resources = {
{"04b_25", "04b_25.png"}, {"04b_25", "04b_25.png"},
{"04b_25_2x", "04b_25_2x.png"}, {"04b_25_2x", "04b_25_2x.png"},
{"04b_25_var01", "04b_25_var01.png"},
{"8bithud", "8bithud.png"}, {"8bithud", "8bithud.png"},
{"nokia", "nokia.png"}, {"nokia", "nokia.png"},
{"smb2", "smb2.gif"}}; {"smb2", "smb2.gif"}};

View File

@@ -89,23 +89,26 @@ void Screen::render()
// Dibuja efectos y elementos sobre el game_canvas_ // Dibuja efectos y elementos sobre el game_canvas_
renderFlash(); renderFlash();
renderAttenuate(); renderAttenuate();
renderShake();
OnScreenHelp::get()->render(); OnScreenHelp::get()->render();
renderInfo(); renderInfo();
Notifier::get()->render(); Notifier::get()->render();
// Restablece el objetivo de renderizado al buffer de pantalla predeterminado // Renderiza el contenido del game_canvas_
SDL_SetRenderTarget(renderer_, nullptr);
// Renderiza el contenido del game_canvas_ o aplica shaders según configuración
renderScreen(); renderScreen();
} }
// Selecciona y ejecuta el método de renderizado adecuado basado en la configuración de shaders // Renderiza el contenido del game_canvas_
void Screen::renderScreen() void Screen::renderScreen()
{ {
// Restablece el objetivo de renderizado al buffer de pantalla predeterminado
SDL_SetRenderTarget(renderer_, nullptr);
clean();
#ifdef NO_SHADERS #ifdef NO_SHADERS
// Actualiza la pantalla con el contenido del game_canvas_ // Actualiza la pantalla con el contenido del buffer de renderizado
presentGameCanvas(); SDL_RenderCopy(renderer_, game_canvas_, nullptr, nullptr);
SDL_RenderPresent(renderer_);
#else #else
if (options.video.shaders) if (options.video.shaders)
{ {
@@ -114,8 +117,9 @@ void Screen::renderScreen()
} }
else else
{ {
// Actualiza la pantalla con el contenido del game_canvas_ // Actualiza la pantalla con el contenido del buffer de renderizado
presentGameCanvas(); SDL_RenderCopy(renderer_, game_canvas_, nullptr, nullptr);
SDL_RenderPresent(renderer_);
} }
#endif #endif
} }
@@ -311,6 +315,33 @@ void Screen::renderAttenuate()
} }
} }
// Aplica el efecto de agitar la pantalla
void Screen::renderShake()
{
if (shake_effect_.enabled)
{
// Guarda el renderizador actual para dejarlo despues como estaba
auto current_target = SDL_GetRenderTarget(renderer_);
// Crea una textura temporal
auto temp_texture = SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, param.game.width, param.game.height);
// Vuelca game_canvas_ a la textura temporal
SDL_SetRenderTarget(renderer_, temp_texture);
SDL_RenderCopy(renderer_, game_canvas_, nullptr, nullptr);
// Vuelca textura temporal a game_canvas_
SDL_SetRenderTarget(renderer_, game_canvas_);
SDL_RenderCopy(renderer_, temp_texture, &src_rect_, &dst_rect_);
// Elimina la textura temporal
SDL_DestroyTexture(temp_texture);
// Restaura el renderizador de destino original
SDL_SetRenderTarget(renderer_, current_target);
}
}
// Activa / desactiva los shaders // Activa / desactiva los shaders
void Screen::toggleShaders() void Screen::toggleShaders()
{ {
@@ -405,18 +436,3 @@ SDL_Point Screen::getNewPosition()
return new_pos; return new_pos;
} }
// Actualiza la pantalla con el contenido del game_canvas_
void Screen::presentGameCanvas()
{
// Copia la textura de juego en el renderizador en la posición adecuada
if (shake_effect_.enabled)
{
// Esta copia es para evitar que se vea negro por los laterales
SDL_RenderCopy(renderer_, game_canvas_, nullptr, nullptr);
}
SDL_RenderCopy(renderer_, game_canvas_, &src_rect_, &dst_rect_);
// Actualiza la pantalla con el contenido del buffer de renderizado
SDL_RenderPresent(renderer_);
}

View File

@@ -98,6 +98,9 @@ private:
// Atenua la pantalla // Atenua la pantalla
void renderAttenuate(); void renderAttenuate();
// Aplica el efecto de agitar la pantalla
void renderShake();
// Calcula los frames por segundo // Calcula los frames por segundo
void updateFPS(); void updateFPS();

View File

@@ -37,6 +37,7 @@ public:
// Devuelve el rectangulo donde está el sprite // Devuelve el rectangulo donde está el sprite
SDL_Rect getPosition() const { return pos_; } SDL_Rect getPosition() const { return pos_; }
SDL_Rect &getRect() { return pos_; }
// Establece la posición y el tamaño // Establece la posición y el tamaño
void setX(int x) { pos_.x = x; } void setX(int x) { pos_.x = x; }

View File

@@ -2,6 +2,7 @@
#include "tabe.h" #include "tabe.h"
#include <SDL2/SDL_render.h> // Para SDL_FLIP_HORIZONTAL, SDL_FLIP_NONE #include <SDL2/SDL_render.h> // Para SDL_FLIP_HORIZONTAL, SDL_FLIP_NONE
#include <stdlib.h> // Para rand, abs #include <stdlib.h> // Para rand, abs
#include <algorithm> // Para max
#include "jail_audio.h" // Para JA_PlaySound #include "jail_audio.h" // Para JA_PlaySound
#include "param.h" // Para Param, ParamGame, param #include "param.h" // Para Param, ParamGame, param
#include "resource.h" // Para Resource #include "resource.h" // Para Resource
@@ -18,6 +19,7 @@ void Tabe::update()
{ {
sprite_->update(); sprite_->update();
move(); move();
updateState();
} }
} }
@@ -100,7 +102,10 @@ void Tabe::enable()
if (!enabled_) if (!enabled_)
{ {
enabled_ = true; enabled_ = true;
y_ = 20.0f; has_bonus_ = true;
hit_counter_ = 0;
number_of_hits_ = 0;
y_ = param.game.game_area.rect.y + 20.0f;
// Establece una dirección aleatoria // Establece una dirección aleatoria
destiny_ = direction_ = rand() % 2 == 0 ? TabeDirection::TO_THE_LEFT : TabeDirection::TO_THE_RIGHT; destiny_ = direction_ = rand() % 2 == 0 ? TabeDirection::TO_THE_LEFT : TabeDirection::TO_THE_RIGHT;
@@ -146,3 +151,52 @@ void Tabe::setRandomFlyPath(TabeDirection direction, int lenght)
break; break;
} }
} }
// Establece el estado
void Tabe::setState(TabeState state)
{
if (enabled_)
{
state_ = state;
switch (state)
{
case TabeState::FLY:
sprite_->setCurrentAnimation("fly");
break;
case TabeState::HIT:
sprite_->setCurrentAnimation("hit");
hit_counter_ = 5;
++number_of_hits_;
break;
default:
break;
}
}
}
// Actualiza el estado
void Tabe::updateState()
{
if (state_ == TabeState::HIT)
{
--hit_counter_;
if (hit_counter_ == 0)
{
setState(TabeState::FLY);
}
}
}
// Intenta obtener el bonus
bool Tabe::tryToGetBonus()
{
if (has_bonus_ && rand() % std::max(1, 10 - number_of_hits_) == 0)
{
has_bonus_ = false;
return true;
}
return false;
}

View File

@@ -1,7 +1,8 @@
#pragma once #pragma once
#include "animated_sprite.h" #include <SDL2/SDL_rect.h> // Para SDL_Rect
#include <memory> #include <memory> // Para unique_ptr
#include "animated_sprite.h" // Para AnimatedSprite
enum class TabeDirection : int enum class TabeDirection : int
{ {
@@ -9,6 +10,12 @@ enum class TabeDirection : int
TO_THE_RIGHT = 1, TO_THE_RIGHT = 1,
}; };
enum class TabeState : int
{
FLY = 0,
HIT = 1,
};
// Clase Tabe // Clase Tabe
class Tabe class Tabe
{ {
@@ -30,6 +37,10 @@ private:
bool enabled_ = false; // Indica si el objeto está activo bool enabled_ = false; // Indica si el objeto está activo
TabeDirection direction_; // Dirección del objeto TabeDirection direction_; // Dirección del objeto
TabeDirection destiny_; // Destino del objeto TabeDirection destiny_; // Destino del objeto
TabeState state_ = TabeState::FLY; // Estado
int hit_counter_ = 0; // Contador para el estado HIT
int number_of_hits_ = 0; // Cantidad de disparos que ha recibido
bool has_bonus_ = true; // Indica si el Tabe aun tiene el bonus para soltar
// Mueve el objeto // Mueve el objeto
void move(); void move();
@@ -40,6 +51,9 @@ private:
// Establece un vuelo aleatorio // Establece un vuelo aleatorio
void setRandomFlyPath(TabeDirection direction, int lenght); void setRandomFlyPath(TabeDirection direction, int lenght);
// Actualiza el estado
void updateState();
public: public:
// Constructor // Constructor
Tabe(); Tabe();
@@ -55,4 +69,16 @@ public:
// Habilita el objeto // Habilita el objeto
void enable(); void enable();
// Establece el estado
void setState(TabeState state);
// Intenta obtener el bonus
bool tryToGetBonus();
// Obtiene el area de colisión
SDL_Rect &getCollider() { return sprite_->getRect(); }
// Getters
bool isEnabled() const { return enabled_; }
}; };

View File

@@ -173,6 +173,25 @@ std::shared_ptr<Texture> Text::writeToTexture(const std::string &text, int zoom,
return texture; return texture;
} }
// Escribe el texto con extras en una textura
std::shared_ptr<Texture> Text::writeDXToTexture(Uint8 flags, const std::string &text, int kerning, Color textColor, Uint8 shadow_distance, Color shadow_color, int lenght)
{
auto renderer = Screen::get()->getRenderer();
auto texture = std::make_shared<Texture>(renderer);
auto width = Text::lenght(text, kerning) + shadow_distance;
auto height = box_height_ + shadow_distance;
auto temp = SDL_GetRenderTarget(renderer);
texture->createBlank(width, height, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET);
texture->setBlendMode(SDL_BLENDMODE_BLEND);
texture->setAsRenderTarget(renderer);
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
SDL_RenderClear(renderer);
writeDX(flags, 0, 0, text, kerning, textColor, shadow_distance, shadow_color, lenght);
SDL_SetRenderTarget(renderer, temp);
return texture;
}
// Escribe el texto con colores // Escribe el texto con colores
void Text::writeColored(int x, int y, const std::string &text, Color color, int kerning, int lenght) void Text::writeColored(int x, int y, const std::string &text, Color color, int kerning, int lenght)
{ {

View File

@@ -55,6 +55,9 @@ public:
// Escribe el texto en una textura // Escribe el texto en una textura
std::shared_ptr<Texture> writeToTexture(const std::string &text, int zoom = 1, int kerning = 1); std::shared_ptr<Texture> writeToTexture(const std::string &text, int zoom = 1, int kerning = 1);
// Escribe el texto con extras en una textura
std::shared_ptr<Texture> writeDXToTexture(Uint8 flags, const std::string &text, int kerning = 1, Color textColor = Color(), Uint8 shadow_distance = 1, Color shadow_color = Color(), int lenght = -1);
// Escribe el texto con colores // Escribe el texto con colores
void writeColored(int x, int y, const std::string &text, Color color, int kerning = 1, int lenght = -1); void writeColored(int x, int y, const std::string &text, Color color, int kerning = 1, int lenght = -1);

View File

@@ -164,6 +164,10 @@ void Texture::setColor(Uint8 red, Uint8 green, Uint8 blue)
{ {
SDL_SetTextureColorMod(texture_, red, green, blue); SDL_SetTextureColorMod(texture_, red, green, blue);
} }
void Texture::setColor(Color color)
{
SDL_SetTextureColorMod(texture_, color.r, color.g, color.b);
}
// Establece el blending // Establece el blending
void Texture::setBlendMode(SDL_BlendMode blending) void Texture::setBlendMode(SDL_BlendMode blending)

View File

@@ -1,13 +1,14 @@
#pragma once #pragma once
#include <SDL2/SDL_blendmode.h> // para SDL_BlendMode #include <SDL2/SDL_blendmode.h> // Para SDL_BlendMode
#include <SDL2/SDL_pixels.h> // para SDL_PIXELFORMAT_RGBA8888, SDL_PixelF... #include <SDL2/SDL_pixels.h> // Para SDL_PIXELFORMAT_RGBA8888, SDL_PixelF...
#include <SDL2/SDL_rect.h> // para SDL_Point, SDL_Rect #include <SDL2/SDL_rect.h> // Para SDL_Point, SDL_Rect
#include <SDL2/SDL_render.h> // para SDL_Renderer, SDL_FLIP_NONE, SDL_TEX... #include <SDL2/SDL_render.h> // Para SDL_Renderer, SDL_FLIP_NONE, SDL_TEX...
#include <SDL2/SDL_stdinc.h> // para Uint8, Uint32, Uint16 #include <SDL2/SDL_stdinc.h> // Para Uint8, Uint16, Uint32
#include <string> // para string, basic_string #include <memory> // Para shared_ptr
#include <vector> // para vector #include <string> // Para string
#include <memory> #include <vector> // Para vector
struct Color;
// Definiciones de tipos // Definiciones de tipos
struct Surface struct Surface
@@ -65,6 +66,7 @@ public:
// Establece el color para la modulacion // Establece el color para la modulacion
void setColor(Uint8 red, Uint8 green, Uint8 blue); void setColor(Uint8 red, Uint8 green, Uint8 blue);
void setColor(Color color);
// Establece el blending // Establece el blending
void setBlendMode(SDL_BlendMode blending); void setBlendMode(SDL_BlendMode blending);

View File

@@ -23,6 +23,7 @@ const Color scoreboard_hard_color = Color(0x76, 0x42, 0x8A);
const Color flash_color = Color(0xFF, 0xFF, 0xFF); const Color flash_color = Color(0xFF, 0xFF, 0xFF);
const Color fade_color = Color(0x27, 0x27, 0x36); const Color fade_color = Color(0x27, 0x27, 0x36);
const Color orange_color = Color(0xFF, 0x7A, 0x00); const Color orange_color = Color(0xFF, 0x7A, 0x00);
const Color orange_soft_color = Color(0xFF, 0xA0, 0x33);
// Calcula el cuadrado de la distancia entre dos puntos // Calcula el cuadrado de la distancia entre dos puntos
double distanceSquared(int x1, int y1, int x2, int y2) double distanceSquared(int x1, int y1, int x2, int y2)
@@ -212,6 +213,12 @@ double easeInOutSine(double t)
return -0.5 * (std::cos(M_PI * t) - 1); return -0.5 * (std::cos(M_PI * t) - 1);
} }
// Función de suavizado
double easeInOut(double t)
{
return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t;
}
// Comprueba si una vector contiene una cadena // Comprueba si una vector contiene una cadena
bool stringInVector(const std::vector<std::string> &vec, const std::string &str) bool stringInVector(const std::vector<std::string> &vec, const std::string &str)
{ {

View File

@@ -44,6 +44,30 @@ struct Color
Uint8 r, g, b; Uint8 r, g, b;
constexpr Color() : r(0), g(0), b(0) {} constexpr Color() : r(0), g(0), b(0) {}
explicit constexpr Color(int red, int green, int blue) : r(red), g(green), b(blue) {} explicit constexpr Color(int red, int green, int blue) : r(red), g(green), b(blue) {}
// Método para obtener el color inverso
constexpr Color getInverse() const
{
return Color(255 - r, 255 - g, 255 - b);
}
// Método para aclarar el color
Color lighten(int amount = 50) const
{
return Color(
std::min(255, r + amount),
std::min(255, g + amount),
std::min(255, b + amount));
}
// Método para oscurecer el color
Color darken(int amount = 50) const
{
return Color(
std::max(0, r - amount),
std::max(0, g - amount),
std::max(0, b - amount));
}
}; };
// Posiciones de las notificaciones // Posiciones de las notificaciones
@@ -146,6 +170,7 @@ double easeInOutQuint(double t);
double easeInQuad(double t); double easeInQuad(double t);
double easeOutQuad(double t); double easeOutQuad(double t);
double easeInOutSine(double t); double easeInOutSine(double t);
double easeInOut(double t);
// Comprueba si una vector contiene una cadena // Comprueba si una vector contiene una cadena
bool stringInVector(const std::vector<std::string> &vec, const std::string &str); bool stringInVector(const std::vector<std::string> &vec, const std::string &str);
@@ -178,3 +203,4 @@ extern const Color scoreboard_hard_color;
extern const Color flash_color; extern const Color flash_color;
extern const Color fade_color; extern const Color fade_color;
extern const Color orange_color; extern const Color orange_color;
extern const Color orange_soft_color;