Compare commits
13 Commits
ca18baefd7
...
2024-12-31
| Author | SHA1 | Date | |
|---|---|---|---|
| 40dfc32e84 | |||
| 4cd1d91560 | |||
| e43badd703 | |||
| 71dcf9cf87 | |||
| 3a8521a1da | |||
| 74d9c9a2b9 | |||
| 9532caace8 | |||
| 0bbd14067a | |||
| cfaa143c44 | |||
| e61daeb92e | |||
| d57cc15aee | |||
| de3b18a407 | |||
| 7f444fef33 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -16,3 +16,4 @@ thumbs.db
|
||||
coffee_crisis*
|
||||
debug.txt
|
||||
cppcheck-result*
|
||||
desktop.ini
|
||||
|
||||
100
Makefile
100
Makefile
@@ -10,26 +10,28 @@ TARGET_FILE := $(DIR_BIN)$(TARGET_NAME)
|
||||
APP_NAME := Coffee Crisis Arcade Edition
|
||||
RELEASE_FOLDER := ccae_release
|
||||
RELEASE_FILE := $(RELEASE_FOLDER)/$(TARGET_NAME)
|
||||
VERSION := v0.01
|
||||
RESOURCE_FILE := release/coffee.res
|
||||
VERSION := 2024-12-31
|
||||
|
||||
# Nombres para los ficheros de lanzamiento
|
||||
WINDOWS_RELEASE := $(TARGET_FILE)-$(VERSION)-win32-x64.zip
|
||||
WINDOWS_RELEASE := $(TARGET_NAME)-$(VERSION)-win32-x64.zip
|
||||
MACOS_INTEL_RELEASE := $(TARGET_FILE)-$(VERSION)-macos-intel.dmg
|
||||
MACOS_APPLE_SILICON_RELEASE := $(TARGET_FILE)-$(VERSION)-macos-apple-silicon.dmg
|
||||
LINUX_RELEASE := $(TARGET_FILE)-$(VERSION)-linux.tar.gz
|
||||
RASPI_RELEASE := $(TARGET_FILE)-$(VERSION)-raspberry.tar.gz
|
||||
|
||||
# Includes
|
||||
INCLUDES := -I$(DIR_SOURCES)
|
||||
|
||||
# Variables según el sistema operativo
|
||||
ifeq ($(OS),Windows_NT)
|
||||
FixPath = $(subst /,\,$1)
|
||||
FixPath = $(subst /,\\,$1)
|
||||
SOURCES := source/*.cpp
|
||||
CXXFLAGS := -std=c++20 -Wall -Os -ffunction-sections -fdata-sections -Wl,--gc-sections -static-libstdc++ -Wl,-subsystem,windows
|
||||
CXXFLAGS_DEBUG := -std=c++20 -Wall -g
|
||||
LDFLAGS := -lmingw32 -lws2_32 -lSDL2main -lSDL2 -lopengl32
|
||||
RM = del /Q
|
||||
MKD:= mkdir
|
||||
RM := del /Q
|
||||
MKDIR := mkdir
|
||||
else
|
||||
FixPath = $1
|
||||
SOURCES := $(shell find $(DIR_SOURCES) -name '*.cpp')
|
||||
@@ -37,8 +39,9 @@ else
|
||||
CXXFLAGS := -std=c++20 -Wall -Os -ffunction-sections -fdata-sections
|
||||
CXXFLAGS_DEBUG := -std=c++20 -Wall -g
|
||||
LDFLAGS := -lSDL2
|
||||
RM = rm -f
|
||||
MKD:= mkdir -p
|
||||
RMFILE := rm -f
|
||||
RMDIR := rm -rdf
|
||||
MKDIR := mkdir -p
|
||||
UNAME_S := $(shell uname -s)
|
||||
ifeq ($(UNAME_S),Linux)
|
||||
LDFLAGS += -lGL
|
||||
@@ -50,10 +53,11 @@ else
|
||||
endif
|
||||
endif
|
||||
|
||||
# Rules
|
||||
# Reglas para compilación
|
||||
windows:
|
||||
@echo off
|
||||
$(CXX) $(SOURCES) $(CXXFLAGS) $(LDFLAGS) -o "$(TARGET_FILE).exe"
|
||||
windres release/coffee.rc -O coff -o $(RESOURCE_FILE)
|
||||
$(CXX) $(SOURCES) $(RESOURCE_FILE) $(CXXFLAGS) $(LDFLAGS) -o "$(TARGET_FILE).exe"
|
||||
strip -s -R .comment -R .gnu.version "$(TARGET_FILE).exe" --strip-unneeded
|
||||
|
||||
windows_rec:
|
||||
@@ -80,12 +84,13 @@ windows_release:
|
||||
powershell Copy-Item "release\*.dll" -Destination "$(RELEASE_FOLDER)"
|
||||
|
||||
# Compila
|
||||
$(CXX) $(SOURCES) $(CXXFLAGS) $(LDFLAGS) -o "$(RELEASE_FILE).exe"
|
||||
strip -s -R .comment -R .gnu.version "$(RELEASE_FOLDER)/$(TARGET_FILE).exe" --strip-unneeded
|
||||
windres release/coffee.rc -O coff -o $(RESOURCE_FILE)
|
||||
$(CXX) $(SOURCES) $(RESOURCE_FILE) $(CXXFLAGS) $(LDFLAGS) -o "$(RELEASE_FILE).exe"
|
||||
strip -s -R .comment -R .gnu.version "$(RELEASE_FILE).exe" --strip-unneeded
|
||||
|
||||
# Crea el fichero .zip
|
||||
powershell if (Test-Path $(WINDOWS_RELEASE)) {Remove-Item $(WINDOWS_RELEASE)}
|
||||
powershell Compress-Archive -Path "$(RELEASE_FOLDER)"/* -DestinationPath $(WINDOWS_RELEASE)
|
||||
powershell if (Test-Path "$(WINDOWS_RELEASE)") {Remove-Item "$(WINDOWS_RELEASE)"}
|
||||
powershell Compress-Archive -Path "$(RELEASE_FOLDER)"/* -DestinationPath "$(WINDOWS_RELEASE)"
|
||||
|
||||
# Elimina la carpeta temporal 'RELEASE_FOLDER'
|
||||
powershell if (Test-Path "$(RELEASE_FOLDER)") {Remove-Item "$(RELEASE_FOLDER)" -Recurse -Force}
|
||||
@@ -98,17 +103,17 @@ macos_debug:
|
||||
|
||||
macos_release:
|
||||
# Elimina datos de compilaciones anteriores
|
||||
rm -rdf "$(RELEASE_FOLDER)"
|
||||
rm -rdf Frameworks
|
||||
rm -f tmp.dmg
|
||||
rm -f "$(MACOS_INTEL_RELEASE)"
|
||||
rm -f "$(MACOS_APPLE_SILICON_RELEASE)"
|
||||
$(RMDIR) "$(RELEASE_FOLDER)"
|
||||
$(RMDIR) Frameworks
|
||||
$(RMFILE) tmp.dmg
|
||||
$(RMFILE) "$(MACOS_INTEL_RELEASE)"
|
||||
$(RMFILE) "$(MACOS_APPLE_SILICON_RELEASE)"
|
||||
|
||||
# Crea la carpeta temporal para hacer el trabajo y las carpetas obligatorias para crear una app de macos
|
||||
mkdir -p "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Frameworks"
|
||||
mkdir -p "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/MacOS"
|
||||
mkdir -p "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Resources"
|
||||
mkdir -p Frameworks
|
||||
$(MKDIR) "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Frameworks"
|
||||
$(MKDIR) "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/MacOS"
|
||||
$(MKDIR) "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Resources"
|
||||
$(MKDIR) Frameworks
|
||||
|
||||
# Copia carpetas y ficheros
|
||||
cp -R data "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Resources"
|
||||
@@ -123,24 +128,24 @@ macos_release:
|
||||
ln -s /Applications "$(RELEASE_FOLDER)"/Applications
|
||||
|
||||
# Compila la versión para procesadores Intel
|
||||
$(CXX) $(SOURCES) -D MACOS_BUNDLE $(CXXFLAGS) $(LDFLAGS) -o "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/MacOS/$(TARGET_FILE)" -rpath @executable_path/../Frameworks/ -target x86_64-apple-macos10.12
|
||||
$(CXX) $(SOURCES) -D MACOS_BUNDLE $(CXXFLAGS) $(LDFLAGS) -o "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/MacOS/$(TARGET_NAME)" -rpath @executable_path/../Frameworks/ -target x86_64-apple-macos10.12
|
||||
|
||||
# Empaqueta el .dmg de la versión Intel
|
||||
hdiutil create tmp.dmg -ov -volname "$(APP_NAME)" -fs HFS+ -srcfolder "$(RELEASE_FOLDER)"
|
||||
hdiutil convert tmp.dmg -format UDZO -o "$(MACOS_INTEL_RELEASE)"
|
||||
rm -f tmp.dmg
|
||||
$(RMFILE) tmp.dmg
|
||||
|
||||
# Compila la versión para procesadores Apple Silicon
|
||||
$(CXX) $(SOURCES) -D MACOS_BUNDLE $(CXXFLAGS) $(LDFLAGS) -o "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/MacOS/$(TARGET_FILE)" -rpath @executable_path/../Frameworks/ -target arm64-apple-macos11
|
||||
$(CXX) $(SOURCES) -D MACOS_BUNDLE -D SDL_DISABLE_IMMINTRIN_H $(CXXFLAGS) $(LDFLAGS) -o "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/MacOS/$(TARGET_NAME)" -rpath @executable_path/../Frameworks/ -target arm64-apple-macos11
|
||||
|
||||
# Empaqueta el .dmg de la versión Apple Silicon
|
||||
hdiutil create tmp.dmg -ov -volname "$(APP_NAME)" -fs HFS+ -srcfolder "$(RELEASE_FOLDER)"
|
||||
hdiutil convert tmp.dmg -format UDZO -o "$(MACOS_APPLE_SILICON_RELEASE)"
|
||||
rm -f tmp.dmg
|
||||
$(RMFILE) tmp.dmg
|
||||
|
||||
# Elimina las carpetas temporales
|
||||
$(RM) Frameworks
|
||||
$(RM) "$(RELEASE_FOLDER)"
|
||||
$(RMDIR) Frameworks
|
||||
$(RMDIR) "$(RELEASE_FOLDER)"
|
||||
|
||||
linux:
|
||||
$(CXX) $(SOURCES) $(CXXFLAGS) $(LDFLAGS) -o "$(TARGET_FILE)"
|
||||
@@ -151,10 +156,10 @@ linux_debug:
|
||||
|
||||
linux_release:
|
||||
# Elimina carpetas previas
|
||||
$(RM) "$(RELEASE_FOLDER)"
|
||||
$(RMDIR) "$(RELEASE_FOLDER)"
|
||||
|
||||
# Crea la carpeta temporal para realizar el lanzamiento
|
||||
mkdir -p "$(RELEASE_FOLDER)"
|
||||
$(MKDIR) "$(RELEASE_FOLDER)"
|
||||
|
||||
# Copia ficheros
|
||||
cp -R data "$(RELEASE_FOLDER)"
|
||||
@@ -166,11 +171,11 @@ linux_release:
|
||||
strip -s -R .comment -R .gnu.version "$(RELEASE_FILE)" --strip-unneeded
|
||||
|
||||
# Empaqueta ficheros
|
||||
$(RM) "$(LINUX_RELEASE)"
|
||||
cd "$(RELEASE_FOLDER)" && tar -czvf "../$(LINUX_RELEASE)" *
|
||||
$(RMFILE) "$(LINUX_RELEASE)"
|
||||
cd "$(RELEASE_FOLDER)" && tar -czvf "$(LINUX_RELEASE)" *
|
||||
|
||||
# Elimina la carpeta temporal
|
||||
$(RM) "$(RELEASE_FOLDER)"
|
||||
$(RMDIR) "$(RELEASE_FOLDER)"
|
||||
|
||||
raspi:
|
||||
$(CXX) $(SOURCES) -D ARCADE -D VERBOSE $(CXXFLAGS) $(LDFLAGS) -o $(TARGET_FILE)
|
||||
@@ -179,12 +184,35 @@ raspi:
|
||||
raspi_debug:
|
||||
$(CXX) $(SOURCES) -D ARCADE -D VERBOSE -D DEBUG $(CXXFLAGS_DEBUG) $(LDFLAGS) -o "$(TARGET_FILE)_debug"
|
||||
|
||||
anbernic:
|
||||
raspi_release:
|
||||
# Elimina carpetas previas
|
||||
$(RM) "$(RELEASE_FOLDER)"_anbernic
|
||||
$(RMDIR) "$(RELEASE_FOLDER)"
|
||||
|
||||
# Crea la carpeta temporal para realizar el lanzamiento
|
||||
mkdir -p "$(RELEASE_FOLDER)"_anbernic
|
||||
$(MKDIR) "$(RELEASE_FOLDER)"
|
||||
|
||||
# Copia ficheros
|
||||
cp -R data "$(RELEASE_FOLDER)"
|
||||
cp LICENSE "$(RELEASE_FOLDER)"
|
||||
cp README.md "$(RELEASE_FOLDER)"
|
||||
|
||||
# Complia
|
||||
$(CXX) $(SOURCES) -D ARCADE -D VERBOSE $(CXXFLAGS) $(LDFLAGS) -o "$(RELEASE_FILE)"
|
||||
strip -s -R .comment -R .gnu.version "$(RELEASE_FILE)" --strip-unneeded
|
||||
|
||||
# Empaqueta ficheros
|
||||
$(RMFILE) "$(LINUX_RELEASE)"
|
||||
cd "$(RELEASE_FOLDER)" && tar -czvf "$(RASPI_RELEASE)" *
|
||||
|
||||
# Elimina la carpeta temporal
|
||||
$(RMDIR) "$(RELEASE_FOLDER)"
|
||||
|
||||
anbernic:
|
||||
# Elimina carpetas previas
|
||||
$(RMDIR) "$(RELEASE_FOLDER)"_anbernic
|
||||
|
||||
# Crea la carpeta temporal para realizar el lanzamiento
|
||||
$(MKDIR) "$(RELEASE_FOLDER)"_anbernic
|
||||
|
||||
# Copia ficheros
|
||||
cp -R data "$(RELEASE_FOLDER)"_anbernic
|
||||
|
||||
@@ -14,7 +14,7 @@ fade.num_squares_height 120
|
||||
fade.random_squares_delay 1
|
||||
fade.random_squares_mult 500
|
||||
fade.post_duration 80
|
||||
fade.venetian_size 16
|
||||
fade.venetian_size 12
|
||||
|
||||
## SCOREBOARD
|
||||
scoreboard.x 0
|
||||
|
||||
9
data/gfx/tabe/tabe.ani
Normal file
9
data/gfx/tabe/tabe.ani
Normal file
@@ -0,0 +1,9 @@
|
||||
frame_width=32
|
||||
frame_height=32
|
||||
|
||||
[animation]
|
||||
name=default
|
||||
speed=2
|
||||
loop=0
|
||||
frames=0,1
|
||||
[/animation]
|
||||
BIN
data/gfx/tabe/tabe.png
Normal file
BIN
data/gfx/tabe/tabe.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.8 KiB |
BIN
data/sound/tabe.wav
Normal file
BIN
data/sound/tabe.wav
Normal file
Binary file not shown.
BIN
data/sound/voice_get_ready.wav
Normal file
BIN
data/sound/voice_get_ready.wav
Normal file
Binary file not shown.
2
release/coffee.rc
Normal file
2
release/coffee.rc
Normal file
@@ -0,0 +1,2 @@
|
||||
// coffee.rc
|
||||
IDI_ICON1 ICON "icon.ico"
|
||||
BIN
release/coffee.res
Normal file
BIN
release/coffee.res
Normal file
Binary file not shown.
BIN
release/icon.ico
Normal file
BIN
release/icon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 38 KiB |
@@ -409,6 +409,8 @@ void Director::setFileList()
|
||||
Asset::get()->add(prefix + "/data/sound/voice_coffee.wav", AssetType::SOUND);
|
||||
Asset::get()->add(prefix + "/data/sound/voice_power_up.wav", AssetType::SOUND);
|
||||
Asset::get()->add(prefix + "/data/sound/voice_no.wav", AssetType::SOUND);
|
||||
Asset::get()->add(prefix + "/data/sound/voice_get_ready.wav", AssetType::SOUND);
|
||||
Asset::get()->add(prefix + "/data/sound/tabe.wav", AssetType::SOUND);
|
||||
|
||||
// Shaders
|
||||
Asset::get()->add(prefix + "/data/shaders/crtpi_256.glsl", AssetType::DATA);
|
||||
@@ -451,6 +453,11 @@ void Director::setFileList()
|
||||
Asset::get()->add(prefix + "/data/gfx/bullet/bullet.png", AssetType::BITMAP);
|
||||
}
|
||||
|
||||
{ // Tabe
|
||||
Asset::get()->add(prefix + "/data/gfx/tabe/tabe.png", AssetType::BITMAP);
|
||||
Asset::get()->add(prefix + "/data/gfx/tabe/tabe.ani", AssetType::ANIMATION);
|
||||
}
|
||||
|
||||
{ // Juego
|
||||
Asset::get()->add(prefix + "/data/gfx/game/game_buildings.png", AssetType::BITMAP);
|
||||
Asset::get()->add(prefix + "/data/gfx/game/game_clouds1.png", AssetType::BITMAP);
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include "section.h" // Para Name, name, Options, options
|
||||
#include "smart_sprite.h" // Para SmartSprite
|
||||
#include "stage.h" // Para number, get, Stage, power, total_p...
|
||||
#include "tabe.h" // Para Tabe
|
||||
#include "text.h" // Para Text
|
||||
#include "texture.h" // Para Texture
|
||||
struct JA_Sound_t; // lines 37-37
|
||||
@@ -46,7 +47,8 @@ Game::Game(int player_id, int current_stage, bool demo)
|
||||
canvas_(SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, param.game.play_area.rect.w, param.game.play_area.rect.h)),
|
||||
fade_in_(std::make_unique<Fade>()),
|
||||
fade_out_(std::make_unique<Fade>()),
|
||||
balloon_manager_(std::make_unique<BalloonManager>())
|
||||
balloon_manager_(std::make_unique<BalloonManager>()),
|
||||
tabe_(std::make_unique<Tabe>())
|
||||
{
|
||||
// Pasa variables
|
||||
demo_.enabled = demo;
|
||||
@@ -66,7 +68,7 @@ Game::Game(int player_id, int current_stage, bool demo)
|
||||
|
||||
fade_in_->setColor(fade_color.r, fade_color.g, fade_color.b);
|
||||
fade_in_->setPost(0);
|
||||
fade_in_->setType(FadeType::VENETIAN);
|
||||
fade_in_->setType(FadeType::RANDOM_SQUARE);
|
||||
fade_in_->setMode(FadeMode::IN);
|
||||
fade_in_->activate();
|
||||
|
||||
@@ -98,17 +100,21 @@ Game::Game(int player_id, int current_stage, bool demo)
|
||||
|
||||
Game::~Game()
|
||||
{
|
||||
// Guarda las puntuaciones en un fichero
|
||||
if (!demo_.enabled)
|
||||
{
|
||||
auto manager = std::make_unique<ManageHiScoreTable>(options.game.hi_score_table);
|
||||
manager->saveToFile(asset_->get("score.bin"));
|
||||
}
|
||||
else
|
||||
// MODO DEMO
|
||||
if (demo_.enabled)
|
||||
{
|
||||
// Habilita los sonidos
|
||||
JA_EnableSound(true);
|
||||
}
|
||||
// MODO JUEGO
|
||||
else
|
||||
{
|
||||
// Guarda las puntuaciones en un fichero
|
||||
auto manager = std::make_unique<ManageHiScoreTable>(options.game.hi_score_table);
|
||||
manager->saveToFile(asset_->get("score.bin"));
|
||||
section::attract_mode = section::AttractMode::TITLE_TO_DEMO;
|
||||
}
|
||||
|
||||
#ifdef RECORDING
|
||||
saveDemoFile(Asset::get()->get("demo1.bin"), demo_.data.at(0));
|
||||
#endif
|
||||
@@ -266,7 +272,7 @@ void Game::updateStage()
|
||||
std::vector<Path> paths = {paths_.at(2), paths_.at(3)};
|
||||
if (Stage::number == 9)
|
||||
{
|
||||
createMessage(paths, Resource::get()->getTexture("last_stage"));
|
||||
createMessage(paths, Resource::get()->getTexture("game_text_last_stage"));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -293,7 +299,8 @@ void Game::updateFadeInState()
|
||||
{
|
||||
balloon_manager_->createTwoBigBalloons();
|
||||
evaluateAndSetMenace();
|
||||
createMessage({paths_.at(0), paths_.at(1)}, Resource::get()->getTexture("get_ready"));
|
||||
createMessage({paths_.at(0), paths_.at(1)}, Resource::get()->getTexture("game_text_get_ready"));
|
||||
JA_PlaySound(Resource::get()->getSound("voice_get_ready.wav"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -308,8 +315,8 @@ void Game::updateGameOverState()
|
||||
{
|
||||
if (game_over_counter_ == GAME_OVER_COUNTER_)
|
||||
{
|
||||
createMessage({paths_.at(2), paths_.at(3)}, Resource::get()->getTexture("game_over"));
|
||||
stopMusic();
|
||||
createMessage({paths_.at(2), paths_.at(3)}, Resource::get()->getTexture("game_text_game_over"));
|
||||
JA_FadeOutMusic(1000);
|
||||
balloon_manager_->setSounds(true);
|
||||
}
|
||||
|
||||
@@ -356,8 +363,8 @@ void Game::updateCompletedState()
|
||||
// Muestra el mensaje de felicitación y da los puntos a los jugadores
|
||||
if (game_completed_counter_ == 200)
|
||||
{
|
||||
createMessage({paths_.at(4), paths_.at(5)}, Resource::get()->getTexture("congratulations"));
|
||||
createMessage({paths_.at(6), paths_.at(7)}, Resource::get()->getTexture("1000000_points"));
|
||||
createMessage({paths_.at(4), paths_.at(5)}, Resource::get()->getTexture("game_text_congratulations"));
|
||||
createMessage({paths_.at(6), paths_.at(7)}, Resource::get()->getTexture("game_text_1000000_points"));
|
||||
|
||||
for (auto &player : players_)
|
||||
if (player->isPlaying())
|
||||
@@ -845,7 +852,6 @@ void Game::killPlayer(std::shared_ptr<Player> &player)
|
||||
screen_->shake();
|
||||
JA_PlaySound(Resource::get()->getSound("voice_no.wav"));
|
||||
player->setPlayingState(PlayerState::DYING);
|
||||
// allPlayersAreNotPlaying() ? stopMusic() : resumeMusic();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -936,11 +942,10 @@ void Game::fillCanvas()
|
||||
renderItems();
|
||||
renderSmartSprites();
|
||||
balloon_manager_->render();
|
||||
tabe_->render();
|
||||
renderBullets();
|
||||
renderPathSprites();
|
||||
renderPlayers();
|
||||
// dbg_print(0, 40, std::to_string(menace_current_).c_str(), 255, 0, 0);
|
||||
// dbg_print(0, 50, std::to_string(menace_threshold_).c_str(), 255, 0, 0);
|
||||
|
||||
// Deja el renderizador apuntando donde estaba
|
||||
SDL_SetRenderTarget(renderer_, temp);
|
||||
@@ -986,7 +991,10 @@ void Game::disableTimeStopItem()
|
||||
void Game::checkMusicStatus()
|
||||
{
|
||||
// Si se ha completado el juego o los jugadores han terminado, detiene la música
|
||||
state_ == GameState::FADE_IN || state_ == GameState::COMPLETED || allPlayersAreGameOver() ? stopMusic() : playMusic();
|
||||
if (state_ != GameState::COMPLETED && !allPlayersAreGameOver())
|
||||
{
|
||||
playMusic();
|
||||
}
|
||||
}
|
||||
|
||||
// Bucle para el juego
|
||||
@@ -1011,7 +1019,7 @@ void Game::initPaths()
|
||||
{
|
||||
// Recorrido para el texto de "Get Ready!" (0,1)
|
||||
{
|
||||
const auto &texture = Resource::get()->getTexture("get_ready");
|
||||
const auto &texture = Resource::get()->getTexture("game_text_get_ready");
|
||||
const auto w = texture->getWidth();
|
||||
const int x0 = -w;
|
||||
const int x1 = param.game.play_area.center_x - w / 2;
|
||||
@@ -1023,7 +1031,7 @@ void Game::initPaths()
|
||||
|
||||
// Recorrido para el texto de "Last Stage!" o de "X stages left" o "Game Over" (2,3)
|
||||
{
|
||||
const auto &texture = Resource::get()->getTexture("last_stage");
|
||||
const auto &texture = Resource::get()->getTexture("game_text_last_stage");
|
||||
const auto h = texture->getHeight();
|
||||
const int y0 = param.game.play_area.rect.h - h;
|
||||
const int y1 = param.game.play_area.center_y - h / 2;
|
||||
@@ -1035,7 +1043,7 @@ void Game::initPaths()
|
||||
|
||||
// Recorrido para el texto de "Congratulations!!" (3,4)
|
||||
{
|
||||
const auto &texture = Resource::get()->getTexture("congratulations");
|
||||
const auto &texture = Resource::get()->getTexture("game_text_congratulations");
|
||||
const auto w = texture->getWidth();
|
||||
const auto h = texture->getHeight();
|
||||
const int x0 = -w;
|
||||
@@ -1048,7 +1056,7 @@ void Game::initPaths()
|
||||
|
||||
// Recorrido para el texto de "1.000.000 points!" (5,6)
|
||||
{
|
||||
const auto &texture = Resource::get()->getTexture("1000000_points");
|
||||
const auto &texture = Resource::get()->getTexture("game_text_1000000_points");
|
||||
const auto w = texture->getWidth();
|
||||
const auto h = texture->getHeight();
|
||||
const int x0 = param.game.play_area.rect.w;
|
||||
@@ -1186,8 +1194,7 @@ void Game::checkEvents()
|
||||
}
|
||||
case SDLK_6: // Crea un mensaje
|
||||
{
|
||||
createMessage({paths_.at(4), paths_.at(5)}, Resource::get()->getTexture("congratulations"));
|
||||
createMessage({paths_.at(6), paths_.at(7)}, Resource::get()->getTexture("1000000_points"));
|
||||
createMessage({paths_.at(2), paths_.at(3)}, Resource::get()->getTexture("game_text_congratulations"));
|
||||
break;
|
||||
}
|
||||
case SDLK_7: // Flash
|
||||
@@ -1198,6 +1205,12 @@ void Game::checkEvents()
|
||||
case SDLK_8:
|
||||
{
|
||||
players_.at(0)->setPlayingState(PlayerState::LEAVING_SCREEN);
|
||||
break;
|
||||
}
|
||||
case SDLK_9:
|
||||
{
|
||||
tabe_->enable();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
@@ -1365,6 +1378,7 @@ void Game::handleDemoMode()
|
||||
if (input_->checkAnyButtonPressed())
|
||||
{
|
||||
section::name = section::Name::TITLE; // Salir del modo demo y regresar al menú principal.
|
||||
section::attract_mode = section::AttractMode::TITLE_TO_DEMO; // El juego volverá a mostrar la demo
|
||||
return;
|
||||
}
|
||||
++index;
|
||||
@@ -1795,6 +1809,7 @@ void Game::updateGame()
|
||||
updateScoreboard();
|
||||
updateBackground();
|
||||
balloon_manager_->update();
|
||||
tabe_->update();
|
||||
moveBullets();
|
||||
updateItems();
|
||||
updateStage();
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
class Asset; // lines 13-13
|
||||
class Background; // lines 14-14
|
||||
class BalloonManager;
|
||||
class Tabe;
|
||||
class Bullet; // lines 15-15
|
||||
class Fade; // lines 16-16
|
||||
class Input; // lines 17-17
|
||||
@@ -144,6 +145,7 @@ private:
|
||||
std::unique_ptr<Fade> fade_in_; // Objeto para renderizar fades
|
||||
std::unique_ptr<Fade> fade_out_; // Objeto para renderizar fades
|
||||
std::unique_ptr<BalloonManager> balloon_manager_; // Objeto para gestionar los globos
|
||||
std::unique_ptr<Tabe> tabe_; // Objeto para gestionar el Tabe Volaor
|
||||
std::vector<Path> paths_; // Vector con los recorridos precalculados almacenados
|
||||
|
||||
// Variables
|
||||
|
||||
@@ -205,9 +205,10 @@ void HiScoreTable::checkInput()
|
||||
// Comprueba si se ha pulsado cualquier botón (de los usados para jugar)
|
||||
if (Input::get()->checkAnyButtonPressed())
|
||||
{
|
||||
JA_StopMusic();
|
||||
//JA_StopMusic();
|
||||
section::name = section::Name::TITLE;
|
||||
section::options = section::Options::TITLE_1;
|
||||
section::attract_mode = section::AttractMode::TITLE_TO_DEMO;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -310,9 +310,10 @@ void Instructions::checkInput()
|
||||
// Comprueba si se ha pulsado cualquier botón (de los usados para jugar)
|
||||
if (Input::get()->checkAnyButtonPressed())
|
||||
{
|
||||
JA_StopMusic();
|
||||
//JA_StopMusic();
|
||||
section::name = section::Name::TITLE;
|
||||
section::options = section::Options::TITLE_1;
|
||||
section::attract_mode = section::AttractMode::TITLE_TO_DEMO;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -416,7 +416,6 @@ void Intro::render()
|
||||
void Intro::run()
|
||||
{
|
||||
JA_PlayMusic(Resource::get()->getMusic("intro.ogg"), 0);
|
||||
|
||||
while (section::name == section::Name::INTRO)
|
||||
{
|
||||
checkInput();
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include <SDL2/SDL.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define JA_MAX_SIMULTANEOUS_CHANNELS 5
|
||||
#define JA_MAX_SIMULTANEOUS_CHANNELS 20
|
||||
|
||||
struct JA_Sound_t {
|
||||
Uint32 length {0};
|
||||
@@ -20,6 +20,7 @@ struct JA_Channel_t {
|
||||
|
||||
struct JA_Music_t {
|
||||
int samples {0};
|
||||
Uint32 length {0};
|
||||
int pos {0};
|
||||
int times {0};
|
||||
short* output {NULL};
|
||||
@@ -60,13 +61,13 @@ void audioCallback(void * userdata, uint8_t * stream, int len) {
|
||||
volume = JA_musicVolume * (1.0 - percent);
|
||||
}
|
||||
}
|
||||
const int size = SDL_min(len, (current_music->samples-current_music->pos)*2);
|
||||
SDL_MixAudioFormat(stream, (Uint8*)(current_music->output+current_music->pos), AUDIO_S16, size, volume);
|
||||
current_music->pos += size/2;
|
||||
const int size = SDL_min(len, current_music->length - current_music->pos);
|
||||
SDL_MixAudioFormat(stream, (Uint8*)(current_music->output)+current_music->pos, AUDIO_S16, size, volume);
|
||||
current_music->pos += size;
|
||||
if (size < len) {
|
||||
if (current_music->times != 0) {
|
||||
SDL_MixAudioFormat(stream+size, (Uint8*)current_music->output, AUDIO_S16, len-size, volume);
|
||||
current_music->pos = (len-size)/2;
|
||||
current_music->pos = len-size;
|
||||
if (current_music->times > 0) current_music->times--;
|
||||
} else {
|
||||
current_music->pos = 0;
|
||||
@@ -136,12 +137,14 @@ JA_Music_t *JA_LoadMusic(Uint8* buffer, Uint32 length)
|
||||
SDL_Log("Music length: %f\n", float(music->samples)/float(JA_freq));
|
||||
if (cvt.needed) {
|
||||
cvt.len = music->samples * chan * 2;
|
||||
music->length = cvt.len;
|
||||
cvt.buf = (Uint8 *) SDL_malloc(cvt.len * cvt.len_mult);
|
||||
SDL_memcpy(cvt.buf, music->output, cvt.len);
|
||||
SDL_ConvertAudio(&cvt);
|
||||
free(music->output);
|
||||
music->output = (short*)cvt.buf;
|
||||
}
|
||||
music->length = music->samples * chan * 2;
|
||||
music->pos = 0;
|
||||
music->state = JA_MUSIC_STOPPED;
|
||||
|
||||
@@ -316,6 +319,19 @@ int JA_PlaySound(JA_Sound_t *sound, const int loop)
|
||||
return channel;
|
||||
}
|
||||
|
||||
int JA_PlaySoundOnChannel(JA_Sound_t *sound, const int channel, const int loop)
|
||||
{
|
||||
if (!JA_soundEnabled) return -1;
|
||||
|
||||
if (channel >= JA_MAX_SIMULTANEOUS_CHANNELS) return -1;
|
||||
|
||||
channels[channel].sound = sound;
|
||||
channels[channel].times = loop;
|
||||
channels[channel].pos = 0;
|
||||
channels[channel].state = JA_CHANNEL_PLAYING;
|
||||
return channel;
|
||||
}
|
||||
|
||||
void JA_DeleteSound(JA_Sound_t *sound)
|
||||
{
|
||||
for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) {
|
||||
|
||||
@@ -28,6 +28,7 @@ JA_Sound_t *JA_NewSound(Uint8* buffer, Uint32 length);
|
||||
JA_Sound_t *JA_LoadSound(Uint8* buffer, Uint32 length);
|
||||
JA_Sound_t *JA_LoadSound(const char* filename);
|
||||
int JA_PlaySound(JA_Sound_t *sound, const int loop = 0);
|
||||
int JA_PlaySoundOnChannel(JA_Sound_t *sound, const int channel, const int loop = 0);
|
||||
void JA_PauseChannel(const int channel);
|
||||
void JA_ResumeChannel(const int channel);
|
||||
void JA_StopChannel(const int channel);
|
||||
|
||||
@@ -234,7 +234,7 @@ void Logo::render()
|
||||
void Logo::run()
|
||||
{
|
||||
// Detiene la música
|
||||
JA_StopMusic();
|
||||
JA_FadeOutMusic(300);
|
||||
|
||||
while (section::name == section::Name::LOGO)
|
||||
{
|
||||
|
||||
@@ -290,7 +290,7 @@ void Resource::createTextures()
|
||||
NameAndText("game_text_powerup", lang::getText(117)),
|
||||
NameAndText("game_text_one_hit", lang::getText(118)),
|
||||
NameAndText("game_text_stop", lang::getText(119)),
|
||||
NameAndText("1000000_points", lang::getText(76))};
|
||||
NameAndText("game_text_1000000_points", lang::getText(76))};
|
||||
|
||||
auto text = getText("04b_25");
|
||||
for (const auto &s : strings)
|
||||
@@ -301,10 +301,10 @@ void Resource::createTextures()
|
||||
|
||||
// Tamaño doble
|
||||
std::vector<NameAndText> strings2X = {
|
||||
NameAndText("get_ready", lang::getText(75)),
|
||||
NameAndText("last_stage", lang::getText(79)),
|
||||
NameAndText("congratulations", lang::getText(50)),
|
||||
NameAndText("game_over", "Game Over")};
|
||||
NameAndText("game_text_get_ready", lang::getText(75)),
|
||||
NameAndText("game_text_last_stage", lang::getText(79)),
|
||||
NameAndText("game_text_congratulations", lang::getText(50)),
|
||||
NameAndText("game_text_game_over", "Game Over")};
|
||||
|
||||
auto text2 = getText("04b_25_2x");
|
||||
for (const auto &s : strings2X)
|
||||
|
||||
145
source/tabe.cpp
Normal file
145
source/tabe.cpp
Normal file
@@ -0,0 +1,145 @@
|
||||
#include "tabe.h"
|
||||
#include "resource.h"
|
||||
#include "param.h"
|
||||
#include "jail_audio.h"
|
||||
#include <algorithm>
|
||||
|
||||
// Constructor
|
||||
Tabe::Tabe()
|
||||
: sprite_(std::make_unique<AnimatedSprite>(Resource::get()->getTexture("tabe.png"), Resource::get()->getAnimation("tabe.ani"))) {}
|
||||
|
||||
// Actualiza la lógica
|
||||
void Tabe::update()
|
||||
{
|
||||
if (enabled_)
|
||||
{
|
||||
sprite_->update();
|
||||
move();
|
||||
}
|
||||
}
|
||||
|
||||
// Dibuja el objeto
|
||||
void Tabe::render()
|
||||
{
|
||||
if (enabled_)
|
||||
{
|
||||
sprite_->render();
|
||||
}
|
||||
}
|
||||
|
||||
// Mueve el objeto
|
||||
void Tabe::move()
|
||||
{
|
||||
const int x = static_cast<int>(x_);
|
||||
speed_ += accel_;
|
||||
x_ += speed_;
|
||||
fly_distance_ -= std::abs(x - static_cast<int>(x_));
|
||||
|
||||
// Comprueba si sale por los bordes
|
||||
const float min_x = param.game.game_area.rect.x - WIDTH_;
|
||||
const float max_x = param.game.game_area.rect.x + param.game.game_area.rect.w;
|
||||
switch (destiny_)
|
||||
{
|
||||
case TabeDirection::TO_THE_LEFT:
|
||||
{
|
||||
if (x_ < min_x)
|
||||
{
|
||||
enabled_ = false;
|
||||
}
|
||||
if (x_ > param.game.game_area.rect.x + param.game.game_area.rect.w - WIDTH_ && direction_ == TabeDirection::TO_THE_RIGHT)
|
||||
{
|
||||
setRandomFlyPath(TabeDirection::TO_THE_LEFT, 80);
|
||||
x_ = param.game.game_area.rect.x + param.game.game_area.rect.w - WIDTH_;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case TabeDirection::TO_THE_RIGHT:
|
||||
{
|
||||
if (x_ > max_x)
|
||||
{
|
||||
enabled_ = false;
|
||||
}
|
||||
if (x_ < param.game.game_area.rect.x && direction_ == TabeDirection::TO_THE_LEFT)
|
||||
{
|
||||
setRandomFlyPath(TabeDirection::TO_THE_RIGHT, 80);
|
||||
x_ = param.game.game_area.rect.x;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (fly_distance_ <= 0)
|
||||
{
|
||||
if (waiting_counter_ > 0)
|
||||
{
|
||||
accel_ = speed_ = 0.0f;
|
||||
--waiting_counter_;
|
||||
}
|
||||
else
|
||||
{
|
||||
constexpr int CHOICES = 4;
|
||||
const TabeDirection left[CHOICES] = {TabeDirection::TO_THE_LEFT, TabeDirection::TO_THE_LEFT, TabeDirection::TO_THE_LEFT, TabeDirection::TO_THE_RIGHT};
|
||||
const TabeDirection right[CHOICES] = {TabeDirection::TO_THE_LEFT, TabeDirection::TO_THE_RIGHT, TabeDirection::TO_THE_RIGHT, TabeDirection::TO_THE_RIGHT};
|
||||
const TabeDirection direction = destiny_ == TabeDirection::TO_THE_LEFT ? left[rand() % CHOICES] : right[rand() % CHOICES];
|
||||
setRandomFlyPath(direction, 20 + rand() % 40);
|
||||
}
|
||||
}
|
||||
|
||||
shiftSprite();
|
||||
}
|
||||
|
||||
// Habilita el objeto
|
||||
void Tabe::enable()
|
||||
{
|
||||
if (!enabled_)
|
||||
{
|
||||
enabled_ = true;
|
||||
y_ = 20.0f;
|
||||
|
||||
// Establece una dirección aleatoria
|
||||
destiny_ = direction_ = rand() % 2 == 0 ? TabeDirection::TO_THE_LEFT : TabeDirection::TO_THE_RIGHT;
|
||||
|
||||
// Establece la posición inicial
|
||||
x_ = (direction_ == TabeDirection::TO_THE_LEFT) ? param.game.game_area.rect.x + param.game.game_area.rect.w : param.game.game_area.rect.x - WIDTH_;
|
||||
|
||||
// Crea una ruta de vuelo
|
||||
setRandomFlyPath(direction_, 60);
|
||||
shiftSprite();
|
||||
}
|
||||
}
|
||||
|
||||
// Establece un vuelo aleatorio
|
||||
void Tabe::setRandomFlyPath(TabeDirection direction, int lenght)
|
||||
{
|
||||
direction_ = direction;
|
||||
fly_distance_ = lenght;
|
||||
waiting_counter_ = 5 + rand() % 15;
|
||||
JA_PlaySound(Resource::get()->getSound("tabe.wav"));
|
||||
|
||||
constexpr float SPEED = 2.0f;
|
||||
|
||||
switch (direction)
|
||||
{
|
||||
case TabeDirection::TO_THE_LEFT:
|
||||
{
|
||||
speed_ = -1.0f * SPEED;
|
||||
accel_ = -1.0f * (1 + rand() % 10) / 30.0f;
|
||||
sprite_->setFlip(SDL_FLIP_NONE);
|
||||
break;
|
||||
}
|
||||
|
||||
case TabeDirection::TO_THE_RIGHT:
|
||||
{
|
||||
speed_ = SPEED;
|
||||
accel_ = (1 + rand() % 10) / 30.0f;
|
||||
sprite_->setFlip(SDL_FLIP_HORIZONTAL);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
58
source/tabe.h
Normal file
58
source/tabe.h
Normal file
@@ -0,0 +1,58 @@
|
||||
#pragma once
|
||||
|
||||
#include "animated_sprite.h"
|
||||
#include <memory>
|
||||
|
||||
enum class TabeDirection : int
|
||||
{
|
||||
TO_THE_LEFT = 0,
|
||||
TO_THE_RIGHT = 1,
|
||||
};
|
||||
|
||||
// Clase Tabe
|
||||
class Tabe
|
||||
{
|
||||
private:
|
||||
// Constantes
|
||||
static constexpr int WIDTH_ = 32;
|
||||
static constexpr int HEIGHT_ = 32;
|
||||
|
||||
// Punteros
|
||||
std::unique_ptr<AnimatedSprite> sprite_; // Sprite con los graficos y animaciones
|
||||
|
||||
// Variables
|
||||
float x_ = 0; // Posición del objeto
|
||||
float y_ = 0; // Posición del objeto
|
||||
float speed_ = 0.0f; // Velocidad de movimiento del objeto
|
||||
float accel_ = 0.0f; // Aceleración del objeto
|
||||
int fly_distance_ = 0; // Distancia de vuelo
|
||||
int waiting_counter_ = 0; // Tiempo que pasa quieto el objeto
|
||||
bool enabled_ = false; // Indica si el objeto está activo
|
||||
TabeDirection direction_; // Dirección del objeto
|
||||
TabeDirection destiny_; // Destino del objeto
|
||||
|
||||
// Mueve el objeto
|
||||
void move();
|
||||
|
||||
// Actualiza la posición del sprite
|
||||
void shiftSprite() { sprite_->setPos(x_, y_); }
|
||||
|
||||
// Establece un vuelo aleatorio
|
||||
void setRandomFlyPath(TabeDirection direction, int lenght);
|
||||
|
||||
public:
|
||||
// Constructor
|
||||
Tabe();
|
||||
|
||||
// Destructor
|
||||
~Tabe() = default;
|
||||
|
||||
// Actualiza la lógica
|
||||
void update();
|
||||
|
||||
// Dibuja el objeto
|
||||
void render();
|
||||
|
||||
// Habilita el objeto
|
||||
void enable();
|
||||
};
|
||||
@@ -161,12 +161,14 @@ std::shared_ptr<Texture> Text::writeToTexture(const std::string &text, int zoom,
|
||||
auto texture = std::make_shared<Texture>(renderer);
|
||||
auto width = lenght(text, kerning) * zoom;
|
||||
auto height = box_height_ * zoom;
|
||||
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);
|
||||
zoom == 1 ? write(0, 0, text, kerning) : write2X(0, 0, text, kerning);
|
||||
SDL_SetRenderTarget(renderer, temp);
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
@@ -33,7 +33,8 @@ Title::Title()
|
||||
game_logo_(std::make_unique<GameLogo>(param.game.game_area.center_x, param.title.title_c_c_position)),
|
||||
mini_logo_sprite_(std::make_unique<Sprite>(Resource::get()->getTexture("logo_jailgames_mini.png"))),
|
||||
define_buttons_(std::make_unique<DefineButtons>()),
|
||||
num_controllers_(Input::get()->getNumControllers())
|
||||
num_controllers_(Input::get()->getNumControllers()),
|
||||
state_(TitleState::LOGO_ANIMATING)
|
||||
{
|
||||
// Configura objetos
|
||||
game_logo_->enable();
|
||||
@@ -73,9 +74,8 @@ void Title::update()
|
||||
// Actualiza las variables de globalInputs
|
||||
globalInputs::update();
|
||||
|
||||
// Comprueba el fundido y si se ha acabado
|
||||
// Comprueba el fundido
|
||||
fade_->update();
|
||||
// JA_SetMusicVolume(100 - fade_->getValue());
|
||||
if (fade_->hasEnded())
|
||||
{
|
||||
if (post_fade_ == -1)
|
||||
@@ -90,30 +90,28 @@ void Title::update()
|
||||
}
|
||||
}
|
||||
|
||||
// Sección 1 - Titulo animandose
|
||||
if (section::options == section::Options::TITLE_1)
|
||||
// Establece la lógica según el estado
|
||||
switch (state_)
|
||||
{
|
||||
case TitleState::LOGO_ANIMATING:
|
||||
{
|
||||
game_logo_->update();
|
||||
if (game_logo_->hasFinished())
|
||||
{
|
||||
section::options = section::Options::TITLE_2;
|
||||
state_ = TitleState::LOGO_FINISHED;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Sección 2 - La pantalla con el titulo, el fondo animado y la música
|
||||
else if (section::options == section::Options::TITLE_2)
|
||||
case TitleState::LOGO_FINISHED:
|
||||
{
|
||||
// El contador solo sube si no estamos definiendo botones
|
||||
counter_ = define_buttons_->isEnabled() ? 0 : counter_ + 1;
|
||||
|
||||
// Reproduce la música
|
||||
if ((JA_GetMusicState() == JA_MUSIC_INVALID) || (JA_GetMusicState() == JA_MUSIC_STOPPED))
|
||||
{
|
||||
if (!fade_->isEnabled())
|
||||
{
|
||||
JA_PlayMusic(Resource::get()->getMusic("title.ogg"));
|
||||
}
|
||||
}
|
||||
|
||||
// Actualiza el logo con el título del juego
|
||||
game_logo_->update();
|
||||
@@ -126,6 +124,27 @@ void Title::update()
|
||||
fade_->activate();
|
||||
post_fade_ = -1;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case TitleState::START_HAS_BEEN_PRESSED:
|
||||
{
|
||||
// Actualiza el logo con el título del juego
|
||||
game_logo_->update();
|
||||
|
||||
// Actualiza el mosaico de fondo
|
||||
tiled_bg_->update();
|
||||
|
||||
if (counter_ == 100)
|
||||
{
|
||||
fade_->activate();
|
||||
}
|
||||
++counter_;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -145,16 +164,10 @@ void Title::render()
|
||||
// Dibuja el logo con el título del juego
|
||||
game_logo_->render();
|
||||
|
||||
if (section::options == section::Options::TITLE_2)
|
||||
{
|
||||
constexpr Color shadow = Color(0x14, 0x87, 0xc4);
|
||||
|
||||
// 'PRESS TO PLAY'
|
||||
if (counter_ % 50 > 14 && !define_buttons_->isEnabled())
|
||||
if (state_ != TitleState::LOGO_ANIMATING)
|
||||
{
|
||||
text_->writeDX(TEXT_CENTER | TEXT_SHADOW, param.game.game_area.center_x, param.title.press_start_position, lang::getText(23), 1, no_color, 1, shadow);
|
||||
}
|
||||
|
||||
// Mini logo
|
||||
const int pos1 = (param.game.height / 5 * 4) + BLOCK;
|
||||
const int pos2 = pos1 + mini_logo_sprite_->getHeight() + 3;
|
||||
@@ -165,6 +178,24 @@ void Title::render()
|
||||
text_->writeDX(TEXT_CENTER | TEXT_SHADOW, param.game.game_area.center_x, pos2, TEXT_COPYRIGHT, 1, no_color, 1, shadow);
|
||||
}
|
||||
|
||||
if (state_ == TitleState::LOGO_FINISHED)
|
||||
{
|
||||
// 'PRESS TO PLAY'
|
||||
if (counter_ % 50 > 14 && !define_buttons_->isEnabled())
|
||||
{
|
||||
text_->writeDX(TEXT_CENTER | TEXT_SHADOW, param.game.game_area.center_x, param.title.press_start_position, lang::getText(23), 1, no_color, 1, shadow);
|
||||
}
|
||||
}
|
||||
|
||||
if (state_ == TitleState::START_HAS_BEEN_PRESSED)
|
||||
{
|
||||
// 'PRESS TO PLAY'
|
||||
if (counter_ % 10 > 4 && !define_buttons_->isEnabled())
|
||||
{
|
||||
text_->writeDX(TEXT_CENTER | TEXT_SHADOW, param.game.game_area.center_x, param.title.press_start_position, lang::getText(23), 1, no_color, 1, shadow);
|
||||
}
|
||||
}
|
||||
|
||||
// Define Buttons
|
||||
define_buttons_->render();
|
||||
|
||||
@@ -246,26 +277,28 @@ void Title::checkEvents()
|
||||
// Comprueba las entradas
|
||||
void Title::checkInput()
|
||||
{
|
||||
// Comprueba los controladores solo si no se estan definiendo los botones
|
||||
// Comprueba las entradas solo si no se estan definiendo los botones
|
||||
if (!define_buttons_->isEnabled())
|
||||
{
|
||||
// Comprueba los métodos de control
|
||||
// Comprueba todos los métodos de control
|
||||
for (const auto &controller : options.controllers)
|
||||
{
|
||||
// START
|
||||
if (Input::get()->checkInput(InputType::START, INPUT_DO_NOT_ALLOW_REPEAT, controller.type, controller.index) &&
|
||||
!Input::get()->checkInput(InputType::SERVICE, INPUT_DO_NOT_ALLOW_REPEAT, controller.type, controller.index))
|
||||
{
|
||||
if (section::options == section::Options::TITLE_2 || ALLOW_TITLE_ANIMATION_SKIP)
|
||||
if (state_ == TitleState::LOGO_FINISHED || ALLOW_TITLE_ANIMATION_SKIP)
|
||||
{
|
||||
fade_->activate();
|
||||
JA_FadeOutMusic(1500);
|
||||
JA_PlaySound(Resource::get()->getSound("game_start.wav"));
|
||||
JA_FadeOutMusic(1500);
|
||||
post_fade_ = controller.player_id;
|
||||
state_ = TitleState::START_HAS_BEEN_PRESSED;
|
||||
counter_ = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Comprueba si se va a intercambiar la asignación de mandos a jugadores
|
||||
// SWAP_CONTROLLERS
|
||||
if (Input::get()->checkInput(InputType::SERVICE, INPUT_ALLOW_REPEAT, controller.type, controller.index) &&
|
||||
Input::get()->checkInput(InputType::SWAP_CONTROLLERS, INPUT_DO_NOT_ALLOW_REPEAT, controller.type, controller.index))
|
||||
{
|
||||
@@ -273,7 +306,7 @@ void Title::checkInput()
|
||||
return;
|
||||
}
|
||||
|
||||
// Comprueba si algun mando quiere ser configurado
|
||||
// CONFIG
|
||||
if (Input::get()->checkInput(InputType::SERVICE, INPUT_ALLOW_REPEAT, controller.type, controller.index) &&
|
||||
Input::get()->checkInput(InputType::CONFIG, INPUT_DO_NOT_ALLOW_REPEAT, controller.type, controller.index))
|
||||
{
|
||||
@@ -352,7 +385,6 @@ void Title::showControllers()
|
||||
}
|
||||
}
|
||||
|
||||
// std::string spaces(lang::getText(100).length() + 3, ' ');
|
||||
// std::string kb_text = spaces + lang::getText(69);
|
||||
// Muestra la notificación
|
||||
Notifier::get()->showText({text.at(0), text.at(1)});
|
||||
}
|
||||
|
||||
@@ -27,9 +27,10 @@ constexpr bool ALLOW_TITLE_ANIMATION_SKIP = false;
|
||||
- Dibujar el tileado de fondo
|
||||
- Redifinir los botones de los mandos de juego
|
||||
|
||||
Esta clase tiene dos estados:
|
||||
Esta clase tiene tres estados:
|
||||
- El titulo está animandose, con el fondo estático
|
||||
- El titulo ya está en su sitio y el fondo se está animando
|
||||
- Se ha pulsado el botón de start
|
||||
|
||||
Por razones de diseño, no se permite saltarse la animación del titulo, aunque es
|
||||
configurable mediante un define
|
||||
@@ -39,6 +40,14 @@ constexpr bool ALLOW_TITLE_ANIMATION_SKIP = false;
|
||||
class Title
|
||||
{
|
||||
private:
|
||||
// Enumeraciones
|
||||
enum class TitleState
|
||||
{
|
||||
LOGO_ANIMATING,
|
||||
LOGO_FINISHED,
|
||||
START_HAS_BEEN_PRESSED,
|
||||
};
|
||||
|
||||
// Objetos y punteros
|
||||
std::shared_ptr<Text> text_; // Objeto de texto para poder escribir textos en pantalla
|
||||
std::unique_ptr<Fade> fade_; // Objeto para realizar fundidos en pantalla
|
||||
@@ -53,6 +62,7 @@ private:
|
||||
section::Name next_section_; // Indica cual es la siguiente sección a cargar cuando termine el contador del titulo
|
||||
int post_fade_ = 0; // Opción a realizar cuando termina el fundido
|
||||
int num_controllers_; // Número de mandos conectados
|
||||
TitleState state_; // Estado en el que se encuentra la sección
|
||||
|
||||
// Actualiza las variables del objeto
|
||||
void update();
|
||||
|
||||
Reference in New Issue
Block a user