Compare commits
46 Commits
2024-11-20
...
2024-12-31
| Author | SHA1 | Date | |
|---|---|---|---|
| 40dfc32e84 | |||
| 4cd1d91560 | |||
| e43badd703 | |||
| 71dcf9cf87 | |||
| 3a8521a1da | |||
| 74d9c9a2b9 | |||
| 9532caace8 | |||
| 0bbd14067a | |||
| cfaa143c44 | |||
| e61daeb92e | |||
| d57cc15aee | |||
| de3b18a407 | |||
| 7f444fef33 | |||
| ca18baefd7 | |||
| b8dca0a46f | |||
| ca2c48ea17 | |||
| fb4d0d12db | |||
| fb31445731 | |||
| cf4f0459b3 | |||
| fe0900a686 | |||
| 3367b70cd5 | |||
| 7016849587 | |||
| 301c059a26 | |||
| e3d0145417 | |||
| f0863b3691 | |||
| 80e366b208 | |||
| 3c5bbf2ab0 | |||
| 1aa0dd3864 | |||
| ab45c984a2 | |||
| 020ee81479 | |||
| 0cd96aced5 | |||
| ad32bb7d45 | |||
| c3a5166ee1 | |||
| 687d329d23 | |||
| faba87c06d | |||
| eed45bdbc6 | |||
| 6ed37425bf | |||
| b987d06aca | |||
| 9c9cfdabc2 | |||
| 9f2448753b | |||
| 736bf7e544 | |||
| a2d4331430 | |||
| fd7beee5a1 | |||
| a36120cf0c | |||
| ad221243cb | |||
| b8d4c8f17c |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -15,4 +15,5 @@ thumbs.db
|
|||||||
*score.bin
|
*score.bin
|
||||||
coffee_crisis*
|
coffee_crisis*
|
||||||
debug.txt
|
debug.txt
|
||||||
cppcheck-result*
|
cppcheck-result*
|
||||||
|
desktop.ini
|
||||||
|
|||||||
156
Makefile
156
Makefile
@@ -1,59 +1,63 @@
|
|||||||
# Directorios
|
# Directorios
|
||||||
DIR_ROOT := $(dir $(abspath $(MAKEFILE_LIST)))
|
DIR_ROOT := $(dir $(abspath $(MAKEFILE_LIST)))
|
||||||
DIR_SOURCES:= $(addsuffix /, $(DIR_ROOT)source)
|
DIR_SOURCES := $(addsuffix /, $(DIR_ROOT)source)
|
||||||
DIR_BIN := $(addsuffix /, $(DIR_ROOT))
|
DIR_BIN := $(addsuffix /, $(DIR_ROOT))
|
||||||
DIR_BUILD := $(addsuffix /, $(DIR_ROOT)build)
|
DIR_BUILD := $(addsuffix /, $(DIR_ROOT)build)
|
||||||
|
|
||||||
# Variables
|
# Variables
|
||||||
TARGET_NAME := coffee_crisis_arcade_edition
|
TARGET_NAME := coffee_crisis_arcade_edition
|
||||||
TARGET_FILE := $(DIR_BIN)$(TARGET_NAME)
|
TARGET_FILE := $(DIR_BIN)$(TARGET_NAME)
|
||||||
APP_NAME := Coffee Crisis Arcade Edition
|
APP_NAME := Coffee Crisis Arcade Edition
|
||||||
RELEASE_FOLDER:= ccae_release
|
RELEASE_FOLDER := ccae_release
|
||||||
RELEASE_FILE := $(RELEASE_FOLDER)/$(TARGET_NAME)
|
RELEASE_FILE := $(RELEASE_FOLDER)/$(TARGET_NAME)
|
||||||
VERSION := v0.01
|
RESOURCE_FILE := release/coffee.res
|
||||||
|
VERSION := 2024-12-31
|
||||||
|
|
||||||
# Nombres para los ficheros de lanzamiento
|
# 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_INTEL_RELEASE := $(TARGET_FILE)-$(VERSION)-macos-intel.dmg
|
||||||
MACOS_APPLE_SILICON_RELEASE:= $(TARGET_FILE)-$(VERSION)-macos-apple-silicon.dmg
|
MACOS_APPLE_SILICON_RELEASE := $(TARGET_FILE)-$(VERSION)-macos-apple-silicon.dmg
|
||||||
LINUX_RELEASE := $(TARGET_FILE)-$(VERSION)-linux.tar.gz
|
LINUX_RELEASE := $(TARGET_FILE)-$(VERSION)-linux.tar.gz
|
||||||
|
RASPI_RELEASE := $(TARGET_FILE)-$(VERSION)-raspberry.tar.gz
|
||||||
|
|
||||||
# Includes
|
# Includes
|
||||||
INCLUDES:= -I$(DIR_SOURCES)
|
INCLUDES := -I$(DIR_SOURCES)
|
||||||
|
|
||||||
# Variables según el sistema operativo
|
# Variables según el sistema operativo
|
||||||
ifeq ($(OS),Windows_NT)
|
ifeq ($(OS),Windows_NT)
|
||||||
FixPath = $(subst /,\,$1)
|
FixPath = $(subst /,\\,$1)
|
||||||
SOURCES := source/*.cpp
|
SOURCES := source/*.cpp
|
||||||
CXXFLAGS:= -std=c++20 -Wall -Os -ffunction-sections -fdata-sections -Wl,--gc-sections -static-libstdc++ -Wl,-subsystem,windows
|
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
|
CXXFLAGS_DEBUG := -std=c++20 -Wall -g
|
||||||
LDFLAGS := -lmingw32 -lws2_32 -lSDL2main -lSDL2 -lopengl32
|
LDFLAGS := -lmingw32 -lws2_32 -lSDL2main -lSDL2 -lopengl32
|
||||||
RM = del /Q
|
RM := del /Q
|
||||||
MKD:= mkdir
|
MKDIR := mkdir
|
||||||
else
|
else
|
||||||
FixPath = $1
|
FixPath = $1
|
||||||
SOURCES := $(shell find $(DIR_SOURCES) -name '*.cpp')
|
SOURCES := $(shell find $(DIR_SOURCES) -name '*.cpp')
|
||||||
SOURCES := source/*.cpp
|
SOURCES := source/*.cpp
|
||||||
CXXFLAGS:= -std=c++20 -Wall -Os -ffunction-sections -fdata-sections
|
CXXFLAGS := -std=c++20 -Wall -Os -ffunction-sections -fdata-sections
|
||||||
CXXFLAGS_DEBUG:= -std=c++20 -Wall -g
|
CXXFLAGS_DEBUG := -std=c++20 -Wall -g
|
||||||
LDFLAGS := -lSDL2
|
LDFLAGS := -lSDL2
|
||||||
RM = rm -f
|
RMFILE := rm -f
|
||||||
MKD:= mkdir -p
|
RMDIR := rm -rdf
|
||||||
UNAME_S := $(shell uname -s)
|
MKDIR := mkdir -p
|
||||||
|
UNAME_S := $(shell uname -s)
|
||||||
ifeq ($(UNAME_S),Linux)
|
ifeq ($(UNAME_S),Linux)
|
||||||
LDFLAGS += -lGL
|
LDFLAGS += -lGL
|
||||||
endif
|
endif
|
||||||
ifeq ($(UNAME_S),Darwin)
|
ifeq ($(UNAME_S),Darwin)
|
||||||
CXXFLAGS += -Wno-deprecated
|
CXXFLAGS += -Wno-deprecated
|
||||||
CXXFLAGS_DEBUG += -Wno-deprecated
|
CXXFLAGS_DEBUG += -Wno-deprecated
|
||||||
LDFLAGS += -framework OpenGL
|
LDFLAGS += -framework OpenGL
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# Rules
|
# Reglas para compilación
|
||||||
windows:
|
windows:
|
||||||
@echo off
|
@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
|
strip -s -R .comment -R .gnu.version "$(TARGET_FILE).exe" --strip-unneeded
|
||||||
|
|
||||||
windows_rec:
|
windows_rec:
|
||||||
@@ -80,12 +84,13 @@ windows_release:
|
|||||||
powershell Copy-Item "release\*.dll" -Destination "$(RELEASE_FOLDER)"
|
powershell Copy-Item "release\*.dll" -Destination "$(RELEASE_FOLDER)"
|
||||||
|
|
||||||
# Compila
|
# Compila
|
||||||
$(CXX) $(SOURCES) $(CXXFLAGS) $(LDFLAGS) -o "$(RELEASE_FILE).exe"
|
windres release/coffee.rc -O coff -o $(RESOURCE_FILE)
|
||||||
strip -s -R .comment -R .gnu.version "$(RELEASE_FOLDER)/$(TARGET_FILE).exe" --strip-unneeded
|
$(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
|
# Crea el fichero .zip
|
||||||
powershell if (Test-Path $(WINDOWS_RELEASE)) {Remove-Item $(WINDOWS_RELEASE)}
|
powershell if (Test-Path "$(WINDOWS_RELEASE)") {Remove-Item "$(WINDOWS_RELEASE)"}
|
||||||
powershell Compress-Archive -Path "$(RELEASE_FOLDER)"/* -DestinationPath $(WINDOWS_RELEASE)
|
powershell Compress-Archive -Path "$(RELEASE_FOLDER)"/* -DestinationPath "$(WINDOWS_RELEASE)"
|
||||||
|
|
||||||
# Elimina la carpeta temporal 'RELEASE_FOLDER'
|
# Elimina la carpeta temporal 'RELEASE_FOLDER'
|
||||||
powershell if (Test-Path "$(RELEASE_FOLDER)") {Remove-Item "$(RELEASE_FOLDER)" -Recurse -Force}
|
powershell if (Test-Path "$(RELEASE_FOLDER)") {Remove-Item "$(RELEASE_FOLDER)" -Recurse -Force}
|
||||||
@@ -98,17 +103,17 @@ macos_debug:
|
|||||||
|
|
||||||
macos_release:
|
macos_release:
|
||||||
# Elimina datos de compilaciones anteriores
|
# Elimina datos de compilaciones anteriores
|
||||||
rm -rdf "$(RELEASE_FOLDER)"
|
$(RMDIR) "$(RELEASE_FOLDER)"
|
||||||
rm -rdf Frameworks
|
$(RMDIR) Frameworks
|
||||||
rm -f tmp.dmg
|
$(RMFILE) tmp.dmg
|
||||||
rm -f "$(MACOS_INTEL_RELEASE)"
|
$(RMFILE) "$(MACOS_INTEL_RELEASE)"
|
||||||
rm -f "$(MACOS_APPLE_SILICON_RELEASE)"
|
$(RMFILE) "$(MACOS_APPLE_SILICON_RELEASE)"
|
||||||
|
|
||||||
# Crea la carpeta temporal para hacer el trabajo y las carpetas obligatorias para crear una app de macos
|
# 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) "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Frameworks"
|
||||||
mkdir -p "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/MacOS"
|
$(MKDIR) "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/MacOS"
|
||||||
mkdir -p "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Resources"
|
$(MKDIR) "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Resources"
|
||||||
mkdir -p Frameworks
|
$(MKDIR) Frameworks
|
||||||
|
|
||||||
# Copia carpetas y ficheros
|
# Copia carpetas y ficheros
|
||||||
cp -R data "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Resources"
|
cp -R data "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Resources"
|
||||||
@@ -123,24 +128,24 @@ macos_release:
|
|||||||
ln -s /Applications "$(RELEASE_FOLDER)"/Applications
|
ln -s /Applications "$(RELEASE_FOLDER)"/Applications
|
||||||
|
|
||||||
# Compila la versión para procesadores Intel
|
# 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
|
# Empaqueta el .dmg de la versión Intel
|
||||||
hdiutil create tmp.dmg -ov -volname "$(APP_NAME)" -fs HFS+ -srcfolder "$(RELEASE_FOLDER)"
|
hdiutil create tmp.dmg -ov -volname "$(APP_NAME)" -fs HFS+ -srcfolder "$(RELEASE_FOLDER)"
|
||||||
hdiutil convert tmp.dmg -format UDZO -o "$(MACOS_INTEL_RELEASE)"
|
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
|
# 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
|
# Empaqueta el .dmg de la versión Apple Silicon
|
||||||
hdiutil create tmp.dmg -ov -volname "$(APP_NAME)" -fs HFS+ -srcfolder "$(RELEASE_FOLDER)"
|
hdiutil create tmp.dmg -ov -volname "$(APP_NAME)" -fs HFS+ -srcfolder "$(RELEASE_FOLDER)"
|
||||||
hdiutil convert tmp.dmg -format UDZO -o "$(MACOS_APPLE_SILICON_RELEASE)"
|
hdiutil convert tmp.dmg -format UDZO -o "$(MACOS_APPLE_SILICON_RELEASE)"
|
||||||
rm -f tmp.dmg
|
$(RMFILE) tmp.dmg
|
||||||
|
|
||||||
# Elimina las carpetas temporales
|
# Elimina las carpetas temporales
|
||||||
$(RM) Frameworks
|
$(RMDIR) Frameworks
|
||||||
$(RM) "$(RELEASE_FOLDER)"
|
$(RMDIR) "$(RELEASE_FOLDER)"
|
||||||
|
|
||||||
linux:
|
linux:
|
||||||
$(CXX) $(SOURCES) $(CXXFLAGS) $(LDFLAGS) -o "$(TARGET_FILE)"
|
$(CXX) $(SOURCES) $(CXXFLAGS) $(LDFLAGS) -o "$(TARGET_FILE)"
|
||||||
@@ -151,10 +156,10 @@ linux_debug:
|
|||||||
|
|
||||||
linux_release:
|
linux_release:
|
||||||
# Elimina carpetas previas
|
# Elimina carpetas previas
|
||||||
$(RM) "$(RELEASE_FOLDER)"
|
$(RMDIR) "$(RELEASE_FOLDER)"
|
||||||
|
|
||||||
# Crea la carpeta temporal para realizar el lanzamiento
|
# Crea la carpeta temporal para realizar el lanzamiento
|
||||||
mkdir -p "$(RELEASE_FOLDER)"
|
$(MKDIR) "$(RELEASE_FOLDER)"
|
||||||
|
|
||||||
# Copia ficheros
|
# Copia ficheros
|
||||||
cp -R data "$(RELEASE_FOLDER)"
|
cp -R data "$(RELEASE_FOLDER)"
|
||||||
@@ -166,11 +171,11 @@ linux_release:
|
|||||||
strip -s -R .comment -R .gnu.version "$(RELEASE_FILE)" --strip-unneeded
|
strip -s -R .comment -R .gnu.version "$(RELEASE_FILE)" --strip-unneeded
|
||||||
|
|
||||||
# Empaqueta ficheros
|
# Empaqueta ficheros
|
||||||
$(RM) "$(LINUX_RELEASE)"
|
$(RMFILE) "$(LINUX_RELEASE)"
|
||||||
cd "$(RELEASE_FOLDER)" && tar -czvf "../$(LINUX_RELEASE)" *
|
cd "$(RELEASE_FOLDER)" && tar -czvf "$(LINUX_RELEASE)" *
|
||||||
|
|
||||||
# Elimina la carpeta temporal
|
# Elimina la carpeta temporal
|
||||||
$(RM) "$(RELEASE_FOLDER)"
|
$(RMDIR) "$(RELEASE_FOLDER)"
|
||||||
|
|
||||||
raspi:
|
raspi:
|
||||||
$(CXX) $(SOURCES) -D ARCADE -D VERBOSE $(CXXFLAGS) $(LDFLAGS) -o $(TARGET_FILE)
|
$(CXX) $(SOURCES) -D ARCADE -D VERBOSE $(CXXFLAGS) $(LDFLAGS) -o $(TARGET_FILE)
|
||||||
@@ -179,12 +184,35 @@ raspi:
|
|||||||
raspi_debug:
|
raspi_debug:
|
||||||
$(CXX) $(SOURCES) -D ARCADE -D VERBOSE -D DEBUG $(CXXFLAGS_DEBUG) $(LDFLAGS) -o "$(TARGET_FILE)_debug"
|
$(CXX) $(SOURCES) -D ARCADE -D VERBOSE -D DEBUG $(CXXFLAGS_DEBUG) $(LDFLAGS) -o "$(TARGET_FILE)_debug"
|
||||||
|
|
||||||
anbernic:
|
raspi_release:
|
||||||
# Elimina carpetas previas
|
# Elimina carpetas previas
|
||||||
$(RM) "$(RELEASE_FOLDER)"_anbernic
|
$(RMDIR) "$(RELEASE_FOLDER)"
|
||||||
|
|
||||||
# Crea la carpeta temporal para realizar el lanzamiento
|
# 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
|
# Copia ficheros
|
||||||
cp -R data "$(RELEASE_FOLDER)"_anbernic
|
cp -R data "$(RELEASE_FOLDER)"_anbernic
|
||||||
|
|||||||
@@ -28,6 +28,12 @@ Les tecles son les següents:
|
|||||||
|
|
||||||
- **Tecla F4**: Activa o desactiva els shaders
|
- **Tecla F4**: Activa o desactiva els shaders
|
||||||
|
|
||||||
|
- **Tecla F5**: Activa o desactiva l'audio
|
||||||
|
|
||||||
|
- **Tecla F6**: Activa o desactiva el dispar automàtic
|
||||||
|
|
||||||
|
- **Tecla F7**: Canvia el idioma del joc i reinicia
|
||||||
|
|
||||||
- **Tecla F10**: Reset
|
- **Tecla F10**: Reset
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ fade.num_squares_height 120
|
|||||||
fade.random_squares_delay 1
|
fade.random_squares_delay 1
|
||||||
fade.random_squares_mult 500
|
fade.random_squares_mult 500
|
||||||
fade.post_duration 80
|
fade.post_duration 80
|
||||||
fade.venetian_size 16
|
fade.venetian_size 12
|
||||||
|
|
||||||
## SCOREBOARD
|
## SCOREBOARD
|
||||||
scoreboard.x 0
|
scoreboard.x 0
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ fade.num_squares_height 128
|
|||||||
fade.random_squares_delay 1
|
fade.random_squares_delay 1
|
||||||
fade.random_squares_mult 500
|
fade.random_squares_mult 500
|
||||||
fade.post_duration 80
|
fade.post_duration 80
|
||||||
fade.venetian_size 16
|
fade.venetian_size 12
|
||||||
|
|
||||||
## SCOREBOARD
|
## SCOREBOARD
|
||||||
scoreboard.x 0
|
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 |
@@ -359,4 +359,16 @@ SuperPoder!
|
|||||||
Temps!
|
Temps!
|
||||||
|
|
||||||
## 120 - SCOREBOARD
|
## 120 - SCOREBOARD
|
||||||
Puntuacio
|
Puntuacio
|
||||||
|
|
||||||
|
## 121 - CREDITS
|
||||||
|
PROGRAMAT I DISSENYAT PER
|
||||||
|
|
||||||
|
## 122 - CREDITS
|
||||||
|
GRAFICS DIBUIXATS PER
|
||||||
|
|
||||||
|
## 123 - CREDITS
|
||||||
|
MUSICA COMPOSADA PER
|
||||||
|
|
||||||
|
## 124 - CREDITS
|
||||||
|
EFECTES DE SO
|
||||||
@@ -359,4 +359,16 @@ PowerUp
|
|||||||
Stop!
|
Stop!
|
||||||
|
|
||||||
## 120 - SCOREBOARD
|
## 120 - SCOREBOARD
|
||||||
Score
|
Score
|
||||||
|
|
||||||
|
## 121 - CREDITS
|
||||||
|
PROGRAMMED AND DESIGNED BY
|
||||||
|
|
||||||
|
## 122 - CREDITS
|
||||||
|
PIXELART DRAWN BY
|
||||||
|
|
||||||
|
## 123 - CREDITS
|
||||||
|
MUSIC COMPOSED BY
|
||||||
|
|
||||||
|
## 124 - CREDITS
|
||||||
|
SOUND EFFECTS
|
||||||
@@ -359,4 +359,16 @@ Potenciador
|
|||||||
Tiempo!
|
Tiempo!
|
||||||
|
|
||||||
## 120 - SCOREBOARD
|
## 120 - SCOREBOARD
|
||||||
Puntuacion
|
Puntuacion
|
||||||
|
|
||||||
|
## 121 - CREDITS
|
||||||
|
PROGRAMADO Y DISE{ADO POR
|
||||||
|
|
||||||
|
## 122 - CREDITS
|
||||||
|
GRAFICOS DIBUJADOS POR
|
||||||
|
|
||||||
|
## 123 - CREDITS
|
||||||
|
MUSICA COMPUESTA POR
|
||||||
|
|
||||||
|
## 124 - CREDITS
|
||||||
|
EFECTOS DE SONIDO
|
||||||
BIN
data/music/credits.ogg
Normal file
BIN
data/music/credits.ogg
Normal file
Binary file not shown.
234
data/shaders/crtpi_240.glsl
Normal file
234
data/shaders/crtpi_240.glsl
Normal file
@@ -0,0 +1,234 @@
|
|||||||
|
/*
|
||||||
|
crt-pi - A Raspberry Pi friendly CRT shader.
|
||||||
|
|
||||||
|
Copyright (C) 2015-2016 davej
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by the Free
|
||||||
|
Software Foundation; either version 2 of the License, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
|
||||||
|
This shader is designed to work well on Raspberry Pi GPUs (i.e. 1080P @ 60Hz on a game with a 4:3 aspect ratio). It pushes the Pi's GPU hard and enabling some features will slow it down so that it is no longer able to match 1080P @ 60Hz. You will need to overclock your Pi to the fastest setting in raspi-config to get the best results from this shader: 'Pi2' for Pi2 and 'Turbo' for original Pi and Pi Zero. Note: Pi2s are slower at running the shader than other Pis, this seems to be down to Pi2s lower maximum memory speed. Pi2s don't quite manage 1080P @ 60Hz - they drop about 1 in 1000 frames. You probably won't notice this, but if you do, try enabling FAKE_GAMMA.
|
||||||
|
|
||||||
|
SCANLINES enables scanlines. You'll almost certainly want to use it with MULTISAMPLE to reduce moire effects. SCANLINE_WEIGHT defines how wide scanlines are (it is an inverse value so a higher number = thinner lines). SCANLINE_GAP_BRIGHTNESS defines how dark the gaps between the scan lines are. Darker gaps between scan lines make moire effects more likely.
|
||||||
|
|
||||||
|
GAMMA enables gamma correction using the values in INPUT_GAMMA and OUTPUT_GAMMA. FAKE_GAMMA causes it to ignore the values in INPUT_GAMMA and OUTPUT_GAMMA and approximate gamma correction in a way which is faster than true gamma whilst still looking better than having none. You must have GAMMA defined to enable FAKE_GAMMA.
|
||||||
|
|
||||||
|
CURVATURE distorts the screen by CURVATURE_X and CURVATURE_Y. Curvature slows things down a lot.
|
||||||
|
|
||||||
|
By default the shader uses linear blending horizontally. If you find this too blury, enable SHARPER.
|
||||||
|
|
||||||
|
BLOOM_FACTOR controls the increase in width for bright scanlines.
|
||||||
|
|
||||||
|
MASK_TYPE defines what, if any, shadow mask to use. MASK_BRIGHTNESS defines how much the mask type darkens the screen.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma parameter CURVATURE_X "Screen curvature - horizontal" 0.10 0.0 1.0 0.01
|
||||||
|
#pragma parameter CURVATURE_Y "Screen curvature - vertical" 0.15 0.0 1.0 0.01
|
||||||
|
#pragma parameter MASK_BRIGHTNESS "Mask brightness" 0.70 0.0 1.0 0.01
|
||||||
|
#pragma parameter SCANLINE_WEIGHT "Scanline weight" 6.0 0.0 15.0 0.1
|
||||||
|
#pragma parameter SCANLINE_GAP_BRIGHTNESS "Scanline gap brightness" 0.12 0.0 1.0 0.01
|
||||||
|
#pragma parameter BLOOM_FACTOR "Bloom factor" 1.5 0.0 5.0 0.01
|
||||||
|
#pragma parameter INPUT_GAMMA "Input gamma" 2.4 0.0 5.0 0.01
|
||||||
|
#pragma parameter OUTPUT_GAMMA "Output gamma" 2.2 0.0 5.0 0.01
|
||||||
|
|
||||||
|
// Haven't put these as parameters as it would slow the code down.
|
||||||
|
#define SCANLINES
|
||||||
|
#define MULTISAMPLE
|
||||||
|
#define GAMMA
|
||||||
|
//#define FAKE_GAMMA
|
||||||
|
//#define CURVATURE
|
||||||
|
//#define SHARPER
|
||||||
|
// MASK_TYPE: 0 = none, 1 = green/magenta, 2 = trinitron(ish)
|
||||||
|
#define MASK_TYPE 2
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef GL_ES
|
||||||
|
#define COMPAT_PRECISION mediump
|
||||||
|
precision mediump float;
|
||||||
|
#else
|
||||||
|
#define COMPAT_PRECISION
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef PARAMETER_UNIFORM
|
||||||
|
uniform COMPAT_PRECISION float CURVATURE_X;
|
||||||
|
uniform COMPAT_PRECISION float CURVATURE_Y;
|
||||||
|
uniform COMPAT_PRECISION float MASK_BRIGHTNESS;
|
||||||
|
uniform COMPAT_PRECISION float SCANLINE_WEIGHT;
|
||||||
|
uniform COMPAT_PRECISION float SCANLINE_GAP_BRIGHTNESS;
|
||||||
|
uniform COMPAT_PRECISION float BLOOM_FACTOR;
|
||||||
|
uniform COMPAT_PRECISION float INPUT_GAMMA;
|
||||||
|
uniform COMPAT_PRECISION float OUTPUT_GAMMA;
|
||||||
|
#else
|
||||||
|
#define CURVATURE_X 0.05
|
||||||
|
#define CURVATURE_Y 0.1
|
||||||
|
#define MASK_BRIGHTNESS 0.80
|
||||||
|
#define SCANLINE_WEIGHT 6.0
|
||||||
|
#define SCANLINE_GAP_BRIGHTNESS 0.12
|
||||||
|
#define BLOOM_FACTOR 3.5
|
||||||
|
#define INPUT_GAMMA 2.4
|
||||||
|
#define OUTPUT_GAMMA 2.2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* COMPATIBILITY
|
||||||
|
- GLSL compilers
|
||||||
|
*/
|
||||||
|
|
||||||
|
//uniform vec2 TextureSize;
|
||||||
|
#if defined(CURVATURE)
|
||||||
|
varying vec2 screenScale;
|
||||||
|
#endif
|
||||||
|
varying vec2 TEX0;
|
||||||
|
varying float filterWidth;
|
||||||
|
|
||||||
|
#if defined(VERTEX)
|
||||||
|
//uniform mat4 MVPMatrix;
|
||||||
|
//attribute vec4 VertexCoord;
|
||||||
|
//attribute vec2 TexCoord;
|
||||||
|
//uniform vec2 InputSize;
|
||||||
|
//uniform vec2 OutputSize;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
#if defined(CURVATURE)
|
||||||
|
screenScale = vec2(1.0, 1.0); //TextureSize / InputSize;
|
||||||
|
#endif
|
||||||
|
filterWidth = (768.0 / 240.0) / 3.0;
|
||||||
|
TEX0 = vec2(gl_MultiTexCoord0.x, 1.0-gl_MultiTexCoord0.y)*1.0001;
|
||||||
|
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
|
||||||
|
}
|
||||||
|
#elif defined(FRAGMENT)
|
||||||
|
|
||||||
|
uniform sampler2D Texture;
|
||||||
|
|
||||||
|
#if defined(CURVATURE)
|
||||||
|
vec2 Distort(vec2 coord)
|
||||||
|
{
|
||||||
|
vec2 CURVATURE_DISTORTION = vec2(CURVATURE_X, CURVATURE_Y);
|
||||||
|
// Barrel distortion shrinks the display area a bit, this will allow us to counteract that.
|
||||||
|
vec2 barrelScale = 1.0 - (0.23 * CURVATURE_DISTORTION);
|
||||||
|
coord *= screenScale;
|
||||||
|
coord -= vec2(0.5);
|
||||||
|
float rsq = coord.x * coord.x + coord.y * coord.y;
|
||||||
|
coord += coord * (CURVATURE_DISTORTION * rsq);
|
||||||
|
coord *= barrelScale;
|
||||||
|
if (abs(coord.x) >= 0.5 || abs(coord.y) >= 0.5)
|
||||||
|
coord = vec2(-1.0); // If out of bounds, return an invalid value.
|
||||||
|
else
|
||||||
|
{
|
||||||
|
coord += vec2(0.5);
|
||||||
|
coord /= screenScale;
|
||||||
|
}
|
||||||
|
|
||||||
|
return coord;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
float CalcScanLineWeight(float dist)
|
||||||
|
{
|
||||||
|
return max(1.0-dist*dist*SCANLINE_WEIGHT, SCANLINE_GAP_BRIGHTNESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
float CalcScanLine(float dy)
|
||||||
|
{
|
||||||
|
float scanLineWeight = CalcScanLineWeight(dy);
|
||||||
|
#if defined(MULTISAMPLE)
|
||||||
|
scanLineWeight += CalcScanLineWeight(dy-filterWidth);
|
||||||
|
scanLineWeight += CalcScanLineWeight(dy+filterWidth);
|
||||||
|
scanLineWeight *= 0.3333333;
|
||||||
|
#endif
|
||||||
|
return scanLineWeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec2 TextureSize = vec2(320.0, 240.0);
|
||||||
|
#if defined(CURVATURE)
|
||||||
|
vec2 texcoord = Distort(TEX0);
|
||||||
|
if (texcoord.x < 0.0)
|
||||||
|
gl_FragColor = vec4(0.0);
|
||||||
|
else
|
||||||
|
#else
|
||||||
|
vec2 texcoord = TEX0;
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
vec2 texcoordInPixels = texcoord * TextureSize;
|
||||||
|
#if defined(SHARPER)
|
||||||
|
vec2 tempCoord = floor(texcoordInPixels) + 0.5;
|
||||||
|
vec2 coord = tempCoord / TextureSize;
|
||||||
|
vec2 deltas = texcoordInPixels - tempCoord;
|
||||||
|
float scanLineWeight = CalcScanLine(deltas.y);
|
||||||
|
vec2 signs = sign(deltas);
|
||||||
|
deltas.x *= 2.0;
|
||||||
|
deltas = deltas * deltas;
|
||||||
|
deltas.y = deltas.y * deltas.y;
|
||||||
|
deltas.x *= 0.5;
|
||||||
|
deltas.y *= 8.0;
|
||||||
|
deltas /= TextureSize;
|
||||||
|
deltas *= signs;
|
||||||
|
vec2 tc = coord + deltas;
|
||||||
|
#else
|
||||||
|
float tempY = floor(texcoordInPixels.y) + 0.5;
|
||||||
|
float yCoord = tempY / TextureSize.y;
|
||||||
|
float dy = texcoordInPixels.y - tempY;
|
||||||
|
float scanLineWeight = CalcScanLine(dy);
|
||||||
|
float signY = sign(dy);
|
||||||
|
dy = dy * dy;
|
||||||
|
dy = dy * dy;
|
||||||
|
dy *= 8.0;
|
||||||
|
dy /= TextureSize.y;
|
||||||
|
dy *= signY;
|
||||||
|
vec2 tc = vec2(texcoord.x, yCoord + dy);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
vec3 colour = texture2D(Texture, tc).rgb;
|
||||||
|
|
||||||
|
#if defined(SCANLINES)
|
||||||
|
#if defined(GAMMA)
|
||||||
|
#if defined(FAKE_GAMMA)
|
||||||
|
colour = colour * colour;
|
||||||
|
#else
|
||||||
|
colour = pow(colour, vec3(INPUT_GAMMA));
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
scanLineWeight *= BLOOM_FACTOR;
|
||||||
|
colour *= scanLineWeight;
|
||||||
|
|
||||||
|
#if defined(GAMMA)
|
||||||
|
#if defined(FAKE_GAMMA)
|
||||||
|
colour = sqrt(colour);
|
||||||
|
#else
|
||||||
|
colour = pow(colour, vec3(1.0/OUTPUT_GAMMA));
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#if MASK_TYPE == 0
|
||||||
|
gl_FragColor = vec4(colour, 1.0);
|
||||||
|
#else
|
||||||
|
#if MASK_TYPE == 1
|
||||||
|
float whichMask = fract((gl_FragCoord.x*1.0001) * 0.5);
|
||||||
|
vec3 mask;
|
||||||
|
if (whichMask < 0.5)
|
||||||
|
mask = vec3(MASK_BRIGHTNESS, 1.0, MASK_BRIGHTNESS);
|
||||||
|
else
|
||||||
|
mask = vec3(1.0, MASK_BRIGHTNESS, 1.0);
|
||||||
|
#elif MASK_TYPE == 2
|
||||||
|
float whichMask = fract((gl_FragCoord.x*1.0001) * 0.3333333);
|
||||||
|
vec3 mask = vec3(MASK_BRIGHTNESS, MASK_BRIGHTNESS, MASK_BRIGHTNESS);
|
||||||
|
if (whichMask < 0.3333333)
|
||||||
|
mask.x = 1.0;
|
||||||
|
else if (whichMask < 0.6666666)
|
||||||
|
mask.y = 1.0;
|
||||||
|
else
|
||||||
|
mask.z = 1.0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
gl_FragColor = vec4(colour * mask, 1.0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
@@ -97,7 +97,6 @@ void main()
|
|||||||
#if defined(CURVATURE)
|
#if defined(CURVATURE)
|
||||||
screenScale = vec2(1.0, 1.0); //TextureSize / InputSize;
|
screenScale = vec2(1.0, 1.0); //TextureSize / InputSize;
|
||||||
#endif
|
#endif
|
||||||
//filterWidth = (768.0 / 240.0) / 3.0;
|
|
||||||
filterWidth = (768.0 / 256.0) / 3.0;
|
filterWidth = (768.0 / 256.0) / 3.0;
|
||||||
TEX0 = vec2(gl_MultiTexCoord0.x, 1.0-gl_MultiTexCoord0.y)*1.0001;
|
TEX0 = vec2(gl_MultiTexCoord0.x, 1.0-gl_MultiTexCoord0.y)*1.0001;
|
||||||
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
|
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
|
||||||
BIN
data/sound/game_start.wav
Normal file
BIN
data/sound/game_start.wav
Normal file
Binary file not shown.
BIN
data/sound/logo.wav
Normal file
BIN
data/sound/logo.wav
Normal file
Binary file not shown.
BIN
data/sound/tabe.wav
Normal file
BIN
data/sound/tabe.wav
Normal file
Binary file not shown.
BIN
data/sound/voice_coffee.wav
Normal file
BIN
data/sound/voice_coffee.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.
BIN
data/sound/voice_no.wav
Normal file
BIN
data/sound/voice_no.wav
Normal file
Binary file not shown.
BIN
data/sound/voice_power_up.wav
Normal file
BIN
data/sound/voice_power_up.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 |
@@ -5,9 +5,11 @@
|
|||||||
#include "param.h" // Para Param, param, ParamBalloon, ParamGame
|
#include "param.h" // Para Param, param, ParamBalloon, ParamGame
|
||||||
#include "sprite.h" // Para Sprite
|
#include "sprite.h" // Para Sprite
|
||||||
#include "texture.h" // Para Texture
|
#include "texture.h" // Para Texture
|
||||||
|
#include "resource.h"
|
||||||
|
#include "jail_audio.h"
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
Balloon::Balloon(float x, float y, BalloonType type, BalloonSize size, float vel_x, float speed, Uint16 creation_timer, std::shared_ptr<Texture> texture, const std::vector<std::string> &animation)
|
Balloon::Balloon(float x, float y, BalloonType type, BalloonSize size, float vel_x, float speed, Uint16 creation_timer, SDL_Rect play_area, std::shared_ptr<Texture> texture, const std::vector<std::string> &animation)
|
||||||
: sprite_(std::make_unique<AnimatedSprite>(texture, animation)),
|
: sprite_(std::make_unique<AnimatedSprite>(texture, animation)),
|
||||||
x_(x),
|
x_(x),
|
||||||
y_(y),
|
y_(y),
|
||||||
@@ -19,7 +21,8 @@ Balloon::Balloon(float x, float y, BalloonType type, BalloonSize size, float vel
|
|||||||
creation_counter_ini_(creation_timer),
|
creation_counter_ini_(creation_timer),
|
||||||
type_(type),
|
type_(type),
|
||||||
size_(size),
|
size_(size),
|
||||||
speed_(speed)
|
speed_(speed),
|
||||||
|
play_area_(play_area)
|
||||||
{
|
{
|
||||||
switch (type_)
|
switch (type_)
|
||||||
{
|
{
|
||||||
@@ -35,6 +38,7 @@ Balloon::Balloon(float x, float y, BalloonType type, BalloonSize size, float vel
|
|||||||
power_ = BALLOON_POWER[index];
|
power_ = BALLOON_POWER[index];
|
||||||
menace_ = BALLOON_MENACE[index];
|
menace_ = BALLOON_MENACE[index];
|
||||||
score_ = BALLOON_SCORE[index];
|
score_ = BALLOON_SCORE[index];
|
||||||
|
sound_ = BALLOON_SOUND[index];
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -49,14 +53,16 @@ Balloon::Balloon(float x, float y, BalloonType type, BalloonSize size, float vel
|
|||||||
power_ = BALLOON_POWER[index];
|
power_ = BALLOON_POWER[index];
|
||||||
menace_ = BALLOON_MENACE[index];
|
menace_ = BALLOON_MENACE[index];
|
||||||
score_ = BALLOON_SCORE[index];
|
score_ = BALLOON_SCORE[index];
|
||||||
|
sound_ = BALLOON_SOUND[index];
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case BalloonType::POWERBALL:
|
case BalloonType::POWERBALL:
|
||||||
{
|
{
|
||||||
const int index = 3;
|
constexpr int index = 3;
|
||||||
h_ = w_ = BALLOON_SIZE[4];
|
h_ = w_ = BALLOON_SIZE[4];
|
||||||
|
sound_ = BALLOON_SOUND[3];
|
||||||
power_ = score_ = menace_ = 0;
|
power_ = score_ = menace_ = 0;
|
||||||
|
|
||||||
vy_ = 0;
|
vy_ = 0;
|
||||||
@@ -91,8 +97,8 @@ Balloon::Balloon(float x, float y, BalloonType type, BalloonSize size, float vel
|
|||||||
void Balloon::alignTo(int x)
|
void Balloon::alignTo(int x)
|
||||||
{
|
{
|
||||||
x_ = static_cast<float>(x - (w_ / 2));
|
x_ = static_cast<float>(x - (w_ / 2));
|
||||||
const int min_x = param.game.play_area.rect.x;
|
const int min_x = play_area_.x;
|
||||||
const int max_x = param.game.play_area.rect.w - w_;
|
const int max_x = play_area_.w - w_;
|
||||||
x_ = std::clamp(x_, static_cast<float>(min_x), static_cast<float>(max_x));
|
x_ = std::clamp(x_, static_cast<float>(min_x), static_cast<float>(max_x));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,6 +111,7 @@ void Balloon::render()
|
|||||||
SDL_Point p = {24, 24};
|
SDL_Point p = {24, 24};
|
||||||
sprite_->setRotatingCenter(&p);
|
sprite_->setRotatingCenter(&p);
|
||||||
sprite_->render();
|
sprite_->render();
|
||||||
|
|
||||||
// Añade la máscara del borde y los reflejos
|
// Añade la máscara del borde y los reflejos
|
||||||
auto sp = std::make_unique<Sprite>(sprite_->getTexture(), sprite_->getPosition());
|
auto sp = std::make_unique<Sprite>(sprite_->getTexture(), sprite_->getPosition());
|
||||||
sp->setSpriteClip(BALLOON_SIZE[4], 0, BALLOON_SIZE[4], BALLOON_SIZE[4]);
|
sp->setSpriteClip(BALLOON_SIZE[4], 0, BALLOON_SIZE[4], BALLOON_SIZE[4]);
|
||||||
@@ -122,18 +129,8 @@ void Balloon::render()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (bouncing_.enabled)
|
// Renderizado normal
|
||||||
{
|
sprite_->render();
|
||||||
// Renderizado con efecto de bouncing
|
|
||||||
sprite_->setPos(x_ + bouncing_.despX, y_ + bouncing_.despY);
|
|
||||||
sprite_->render();
|
|
||||||
// sprite_->setPos(x_ - bouncing_.despX, y_ - bouncing_.despY);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Renderizado normal
|
|
||||||
sprite_->render();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -149,10 +146,11 @@ void Balloon::move()
|
|||||||
|
|
||||||
// Colisión en las partes laterales de la zona de juego
|
// Colisión en las partes laterales de la zona de juego
|
||||||
const int clip = 2;
|
const int clip = 2;
|
||||||
const float min_x = param.game.play_area.rect.x - clip;
|
const float min_x = play_area_.x - clip;
|
||||||
const float max_x = param.game.play_area.rect.w - w_ + clip;
|
const float max_x = play_area_.x + play_area_.w - w_ + clip;
|
||||||
if (x_ < min_x || x_ > max_x)
|
if (x_ < min_x || x_ > max_x)
|
||||||
{
|
{
|
||||||
|
playSound();
|
||||||
x_ = std::clamp(x_, min_x, max_x);
|
x_ = std::clamp(x_, min_x, max_x);
|
||||||
vx_ = -vx_;
|
vx_ = -vx_;
|
||||||
// Activa el efecto de rebote o invierte la rotación
|
// Activa el efecto de rebote o invierte la rotación
|
||||||
@@ -170,21 +168,35 @@ void Balloon::move()
|
|||||||
y_ += vy_ * speed_;
|
y_ += vy_ * speed_;
|
||||||
|
|
||||||
// Colisión en la parte superior de la zona de juego excepto para la PowerBall
|
// Colisión en la parte superior de la zona de juego excepto para la PowerBall
|
||||||
if (type_ != BalloonType::POWERBALL)
|
/*if (type_ != BalloonType::POWERBALL)
|
||||||
{
|
{
|
||||||
const int min_y = param.game.play_area.rect.y;
|
const int min_y = play_area_.y;
|
||||||
if (y_ < min_y)
|
if (y_ < min_y)
|
||||||
{
|
{
|
||||||
y_ = min_y;
|
y_ = min_y;
|
||||||
vy_ = -vy_;
|
vy_ = -vy_;
|
||||||
enableBounce();
|
enableBounce();
|
||||||
}
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
|
// Colisión en la parte superior solo si el globo va de subida
|
||||||
|
if (vy_ < 0)
|
||||||
|
{
|
||||||
|
const int min_y = play_area_.y;
|
||||||
|
if (y_ < min_y)
|
||||||
|
{
|
||||||
|
playSound();
|
||||||
|
y_ = min_y;
|
||||||
|
vy_ = -vy_;
|
||||||
|
enableBounce();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Colisión en la parte inferior de la zona de juego
|
// Colisión en la parte inferior de la zona de juego
|
||||||
const int max_y = param.game.play_area.rect.h - h_;
|
const int max_y = play_area_.y + play_area_.h - h_;
|
||||||
if (y_ > max_y)
|
if (y_ > max_y)
|
||||||
{
|
{
|
||||||
|
playSound();
|
||||||
y_ = max_y;
|
y_ = max_y;
|
||||||
vy_ = -default_vy_;
|
vy_ = -default_vy_;
|
||||||
if (type_ != BalloonType::POWERBALL)
|
if (type_ != BalloonType::POWERBALL)
|
||||||
@@ -254,8 +266,8 @@ void Balloon::updateState()
|
|||||||
x_ += vx_;
|
x_ += vx_;
|
||||||
|
|
||||||
// Comprueba no se salga por los laterales
|
// Comprueba no se salga por los laterales
|
||||||
const int min_x = param.game.play_area.rect.x;
|
const int min_x = play_area_.x;
|
||||||
const int max_x = param.game.play_area.rect.w - w_;
|
const int max_x = play_area_.w - w_;
|
||||||
|
|
||||||
if (x_ < min_x || x_ > max_x)
|
if (x_ < min_x || x_ > max_x)
|
||||||
{
|
{
|
||||||
@@ -375,12 +387,10 @@ void Balloon::updateBounce()
|
|||||||
|
|
||||||
zoomSprite();
|
zoomSprite();
|
||||||
|
|
||||||
const auto spriteClip = sprite_->getSpriteClip();
|
|
||||||
bouncing_.despX = spriteClip.w * (1.0f - bouncing_.zoomW);
|
|
||||||
bouncing_.despY = spriteClip.h * (1.0f - bouncing_.zoomH);
|
|
||||||
|
|
||||||
if (++bouncing_.counter / bouncing_.speed >= MAX_BOUNCE)
|
if (++bouncing_.counter / bouncing_.speed >= MAX_BOUNCE)
|
||||||
|
{
|
||||||
disableBounce();
|
disableBounce();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -399,4 +409,13 @@ void Balloon::useNormalColor()
|
|||||||
{
|
{
|
||||||
use_reversed_colors_ = false;
|
use_reversed_colors_ = false;
|
||||||
setAnimation();
|
setAnimation();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reproduce el sonido al rebotar
|
||||||
|
void Balloon::playSound()
|
||||||
|
{
|
||||||
|
if (sound_enabled_)
|
||||||
|
{
|
||||||
|
JA_PlaySound(Resource::get()->getSound(sound_));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,12 +1,13 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <SDL2/SDL_rect.h> // Para SDL_Rect
|
||||||
#include <SDL2/SDL_stdinc.h> // Para Uint8, Uint16, Uint32
|
#include <SDL2/SDL_stdinc.h> // Para Uint8, Uint16, Uint32
|
||||||
#include <memory> // Para shared_ptr, unique_ptr
|
#include <memory> // Para shared_ptr, unique_ptr
|
||||||
#include <string> // Para string
|
#include <string> // Para string
|
||||||
#include <vector> // Para vector
|
#include <vector> // Para vector
|
||||||
#include "animated_sprite.h" // Para AnimatedSprite
|
#include "animated_sprite.h" // Para AnimatedSprite
|
||||||
#include "utils.h" // Para Circle
|
#include "utils.h" // Para Circle
|
||||||
class Texture; // lines 10-10
|
class Texture; // lines 9-9
|
||||||
|
|
||||||
// Cantidad de elementos del vector con los valores de la deformación del globo al rebotar
|
// Cantidad de elementos del vector con los valores de la deformación del globo al rebotar
|
||||||
constexpr int MAX_BOUNCE = 10;
|
constexpr int MAX_BOUNCE = 10;
|
||||||
@@ -16,6 +17,7 @@ constexpr int BALLOON_SCORE[] = {50, 100, 200, 400};
|
|||||||
constexpr int BALLOON_POWER[] = {1, 3, 7, 15};
|
constexpr int BALLOON_POWER[] = {1, 3, 7, 15};
|
||||||
constexpr int BALLOON_MENACE[] = {1, 2, 4, 8};
|
constexpr int BALLOON_MENACE[] = {1, 2, 4, 8};
|
||||||
constexpr int BALLOON_SIZE[] = {10, 16, 26, 48, 49};
|
constexpr int BALLOON_SIZE[] = {10, 16, 26, 48, 49};
|
||||||
|
const std::string BALLOON_SOUND[] = {"bubble1.wav", "bubble2.wav", "bubble3.wav", "bubble4.wav"};
|
||||||
|
|
||||||
// Tamaños de globo
|
// Tamaños de globo
|
||||||
enum class BalloonSize : Uint8
|
enum class BalloonSize : Uint8
|
||||||
@@ -111,6 +113,9 @@ private:
|
|||||||
float travel_y_ = 1.0f; // Distancia que ha de recorrer el globo en el eje Y antes de que se le aplique la gravedad
|
float travel_y_ = 1.0f; // Distancia que ha de recorrer el globo en el eje Y antes de que se le aplique la gravedad
|
||||||
float speed_; // Velocidad a la que se mueven los globos
|
float speed_; // Velocidad a la que se mueven los globos
|
||||||
Uint8 power_; // Cantidad de poder que alberga el globo
|
Uint8 power_; // Cantidad de poder que alberga el globo
|
||||||
|
SDL_Rect play_area_; // Zona por donde se puede mover el globo
|
||||||
|
std::string sound_; // Archivo de sonido que hace el globo al rebotar
|
||||||
|
bool sound_enabled_ = false; // Indica si ha de sonar el sonido del globo al rebotar
|
||||||
|
|
||||||
// Alinea el circulo de colisión con la posición del objeto globo
|
// Alinea el circulo de colisión con la posición del objeto globo
|
||||||
void shiftColliders();
|
void shiftColliders();
|
||||||
@@ -136,9 +141,22 @@ private:
|
|||||||
// Establece la animación correspondiente
|
// Establece la animación correspondiente
|
||||||
void setAnimation();
|
void setAnimation();
|
||||||
|
|
||||||
|
// Reproduce el sonido al rebotar
|
||||||
|
void playSound();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Constructor
|
// Constructor
|
||||||
Balloon(float x, float y, BalloonType type, BalloonSize size, float vel_x, float speed, Uint16 creation_timer, std::shared_ptr<Texture> texture, const std::vector<std::string> &animation);
|
Balloon(
|
||||||
|
float x,
|
||||||
|
float y,
|
||||||
|
BalloonType type,
|
||||||
|
BalloonSize size,
|
||||||
|
float vel_x,
|
||||||
|
float speed,
|
||||||
|
Uint16 creation_timer,
|
||||||
|
SDL_Rect play_area,
|
||||||
|
std::shared_ptr<Texture> texture,
|
||||||
|
const std::vector<std::string> &animation);
|
||||||
|
|
||||||
// Destructor
|
// Destructor
|
||||||
~Balloon() = default;
|
~Balloon() = default;
|
||||||
@@ -196,4 +214,5 @@ public:
|
|||||||
void setVelY(float vel_y) { vy_ = vel_y; }
|
void setVelY(float vel_y) { vy_ = vel_y; }
|
||||||
void setSpeed(float speed) { speed_ = speed; }
|
void setSpeed(float speed) { speed_ = speed; }
|
||||||
void setInvulnerable(bool value) { invulnerable_ = value; }
|
void setInvulnerable(bool value) { invulnerable_ = value; }
|
||||||
|
void setSound(bool value) { sound_enabled_ = value; }
|
||||||
};
|
};
|
||||||
@@ -38,7 +38,6 @@ struct BalloonFormationUnit
|
|||||||
BalloonFormationUnit() : number_of_balloons(0), init() {}
|
BalloonFormationUnit() : number_of_balloons(0), init() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
using BalloonFormationPool = std::vector<const BalloonFormationUnit *>;
|
using BalloonFormationPool = std::vector<const BalloonFormationUnit *>;
|
||||||
|
|
||||||
class BalloonFormations
|
class BalloonFormations
|
||||||
@@ -67,4 +66,5 @@ public:
|
|||||||
// Getters
|
// Getters
|
||||||
const BalloonFormationPool &getPool(int pool) { return balloon_formation_pool_.at(pool); }
|
const BalloonFormationPool &getPool(int pool) { return balloon_formation_pool_.at(pool); }
|
||||||
const BalloonFormationUnit &getSet(int pool, int set) { return *balloon_formation_pool_.at(pool).at(set); }
|
const BalloonFormationUnit &getSet(int pool, int set) { return *balloon_formation_pool_.at(pool).at(set); }
|
||||||
|
const BalloonFormationUnit &getSet(int set) const { return balloon_formation_.at(set); }
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -119,6 +119,30 @@ void BalloonManager::deployBalloonFormation(int stage)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Crea una formación de enemigos específica
|
||||||
|
void BalloonManager::deploySet(int set_number)
|
||||||
|
{
|
||||||
|
const auto set = balloon_formations_->getSet(set_number);
|
||||||
|
const auto numEnemies = set.number_of_balloons;
|
||||||
|
for (int i = 0; i < numEnemies; ++i)
|
||||||
|
{
|
||||||
|
auto p = set.init[i];
|
||||||
|
createBalloon(p.x, p.y, p.type, p.size, p.vel_x, balloon_speed_, p.creation_counter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Crea una formación de enemigos específica
|
||||||
|
void BalloonManager::deploySet(int set_number, int y)
|
||||||
|
{
|
||||||
|
const auto set = balloon_formations_->getSet(set_number);
|
||||||
|
const auto numEnemies = set.number_of_balloons;
|
||||||
|
for (int i = 0; i < numEnemies; ++i)
|
||||||
|
{
|
||||||
|
auto p = set.init[i];
|
||||||
|
createBalloon(p.x, y, p.type, p.size, p.vel_x, balloon_speed_, p.creation_counter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Vacia del vector de globos los globos que ya no sirven
|
// Vacia del vector de globos los globos que ya no sirven
|
||||||
void BalloonManager::freeBalloons()
|
void BalloonManager::freeBalloons()
|
||||||
{
|
{
|
||||||
@@ -150,7 +174,7 @@ int BalloonManager::calculateScreenPower()
|
|||||||
std::shared_ptr<Balloon> BalloonManager::createBalloon(float x, int y, BalloonType type, BalloonSize size, float velx, float speed, int creation_timer)
|
std::shared_ptr<Balloon> BalloonManager::createBalloon(float x, int y, BalloonType type, BalloonSize size, float velx, float speed, int creation_timer)
|
||||||
{
|
{
|
||||||
const int index = static_cast<int>(size);
|
const int index = static_cast<int>(size);
|
||||||
balloons_.emplace_back(std::make_shared<Balloon>(x, y, type, size, velx, speed, creation_timer, balloon_textures_.at(index), balloon_animations_.at(index)));
|
balloons_.emplace_back(std::make_shared<Balloon>(x, y, type, size, velx, speed, creation_timer, play_area_, balloon_textures_.at(index), balloon_animations_.at(index)));
|
||||||
return balloons_.back();
|
return balloons_.back();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -188,7 +212,7 @@ void BalloonManager::createPowerBall()
|
|||||||
const int x[values] = {left, left, center, center, right, right};
|
const int x[values] = {left, left, center, center, right, right};
|
||||||
const float vx[values] = {BALLOON_VELX_POSITIVE, BALLOON_VELX_POSITIVE, BALLOON_VELX_POSITIVE, BALLOON_VELX_NEGATIVE, BALLOON_VELX_NEGATIVE, BALLOON_VELX_NEGATIVE};
|
const float vx[values] = {BALLOON_VELX_POSITIVE, BALLOON_VELX_POSITIVE, BALLOON_VELX_POSITIVE, BALLOON_VELX_NEGATIVE, BALLOON_VELX_NEGATIVE, BALLOON_VELX_NEGATIVE};
|
||||||
|
|
||||||
balloons_.emplace_back(std::make_unique<Balloon>(x[luck], pos_y, BalloonType::POWERBALL, BalloonSize::SIZE4, vx[luck], balloon_speed_, creation_time, balloon_textures_[4], balloon_animations_[4]));
|
balloons_.emplace_back(std::make_unique<Balloon>(x[luck], pos_y, BalloonType::POWERBALL, BalloonSize::SIZE4, vx[luck], balloon_speed_, creation_time, play_area_, balloon_textures_[4], balloon_animations_[4]));
|
||||||
|
|
||||||
power_ball_enabled_ = true;
|
power_ball_enabled_ = true;
|
||||||
power_ball_counter_ = POWERBALL_COUNTER;
|
power_ball_counter_ = POWERBALL_COUNTER;
|
||||||
@@ -279,7 +303,7 @@ int BalloonManager::destroyAllBalloons()
|
|||||||
|
|
||||||
balloon_deploy_counter_ = 300;
|
balloon_deploy_counter_ = 300;
|
||||||
JA_PlaySound(Resource::get()->getSound("powerball.wav"));
|
JA_PlaySound(Resource::get()->getSound("powerball.wav"));
|
||||||
Screen::get()->flash(flash_color, 100);
|
Screen::get()->flash(flash_color, 3);
|
||||||
Screen::get()->shake();
|
Screen::get()->shake();
|
||||||
|
|
||||||
return score;
|
return score;
|
||||||
@@ -339,13 +363,7 @@ void BalloonManager::reLoad()
|
|||||||
// Crea dos globos gordos
|
// Crea dos globos gordos
|
||||||
void BalloonManager::createTwoBigBalloons()
|
void BalloonManager::createTwoBigBalloons()
|
||||||
{
|
{
|
||||||
const auto set = balloon_formations_->getSet(0, 1);
|
deploySet(1);
|
||||||
const auto numEnemies = set.number_of_balloons;
|
|
||||||
for (int i = 0; i < numEnemies; ++i)
|
|
||||||
{
|
|
||||||
auto p = set.init[i];
|
|
||||||
createBalloon(p.x, p.y, p.type, p.size, p.vel_x, balloon_speed_, p.creation_counter);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Obtiene el nivel de ameza actual generado por los globos
|
// Obtiene el nivel de ameza actual generado por los globos
|
||||||
@@ -353,4 +371,13 @@ int BalloonManager::getMenace()
|
|||||||
{
|
{
|
||||||
return std::accumulate(balloons_.begin(), balloons_.end(), 0, [](int sum, const auto &balloon)
|
return std::accumulate(balloons_.begin(), balloons_.end(), 0, [](int sum, const auto &balloon)
|
||||||
{ return sum + (balloon->isEnabled() ? balloon->getMenace() : 0); });
|
{ return sum + (balloon->isEnabled() ? balloon->getMenace() : 0); });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Establece el sonido de los globos
|
||||||
|
void BalloonManager::setSounds(bool value)
|
||||||
|
{
|
||||||
|
for (auto &balloon : balloons_)
|
||||||
|
{
|
||||||
|
balloon->setSound(value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,12 +1,15 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <SDL2/SDL_rect.h> // Para SDL_Rect
|
||||||
#include <memory> // Para shared_ptr, unique_ptr
|
#include <memory> // Para shared_ptr, unique_ptr
|
||||||
#include <string> // Para string
|
#include <string> // Para string
|
||||||
#include <vector> // Para vector
|
#include <vector> // Para vector
|
||||||
#include "balloon.h" // Para BALLOON_SPEED, Balloon
|
#include "balloon.h" // Para BALLOON_SPEED, Balloon
|
||||||
#include "balloon_formations.h" // Para BalloonFormations
|
#include "balloon_formations.h" // Para BalloonFormations
|
||||||
#include "explosions.h" // Para Explosions
|
#include "explosions.h" // Para Explosions
|
||||||
class Texture;
|
#include "param.h" // Para Param, ParamGame, param
|
||||||
|
#include "utils.h" // Para Zone
|
||||||
|
class Texture; // lines 10-10
|
||||||
|
|
||||||
using Balloons = std::vector<std::shared_ptr<Balloon>>;
|
using Balloons = std::vector<std::shared_ptr<Balloon>>;
|
||||||
|
|
||||||
@@ -29,6 +32,7 @@ private:
|
|||||||
bool power_ball_enabled_ = false; // Indica si hay una powerball ya activa
|
bool power_ball_enabled_ = false; // Indica si hay una powerball ya activa
|
||||||
int power_ball_counter_ = 0; // Contador de formaciones enemigas entre la aparicion de una PowerBall y otra
|
int power_ball_counter_ = 0; // Contador de formaciones enemigas entre la aparicion de una PowerBall y otra
|
||||||
int last_balloon_deploy_ = 0; // Guarda cual ha sido la última formación desplegada para no repetir;
|
int last_balloon_deploy_ = 0; // Guarda cual ha sido la última formación desplegada para no repetir;
|
||||||
|
SDL_Rect play_area_ = param.game.play_area.rect; // Zona por donde se moveran los globos
|
||||||
|
|
||||||
// Inicializa
|
// Inicializa
|
||||||
void init();
|
void init();
|
||||||
@@ -49,9 +53,13 @@ public:
|
|||||||
// Vacia del vector de globos los globos que ya no sirven
|
// Vacia del vector de globos los globos que ya no sirven
|
||||||
void freeBalloons();
|
void freeBalloons();
|
||||||
|
|
||||||
// Crea una formación de enemigos
|
// Crea una formación de enemigos al azar
|
||||||
void deployBalloonFormation(int stage);
|
void deployBalloonFormation(int stage);
|
||||||
|
|
||||||
|
// Crea una formación de enemigos específica
|
||||||
|
void deploySet(int set);
|
||||||
|
void deploySet(int set, int y);
|
||||||
|
|
||||||
// Actualiza la variable enemyDeployCounter
|
// Actualiza la variable enemyDeployCounter
|
||||||
void updateBalloonDeployCounter();
|
void updateBalloonDeployCounter();
|
||||||
|
|
||||||
@@ -103,6 +111,9 @@ public:
|
|||||||
// Obtiene el nivel de ameza actual generado por los globos
|
// Obtiene el nivel de ameza actual generado por los globos
|
||||||
int getMenace();
|
int getMenace();
|
||||||
|
|
||||||
|
// Establece el sonido de los globos
|
||||||
|
void setSounds(bool value);
|
||||||
|
|
||||||
// Getters
|
// Getters
|
||||||
float getBalloonSpeed() const { return balloon_speed_; }
|
float getBalloonSpeed() const { return balloon_speed_; }
|
||||||
Balloons &getBalloons() { return balloons_; }
|
Balloons &getBalloons() { return balloons_; }
|
||||||
@@ -110,4 +121,5 @@ public:
|
|||||||
// Setters
|
// Setters
|
||||||
void setDefaultBalloonSpeed(float speed) { default_balloon_speed_ = speed; }
|
void setDefaultBalloonSpeed(float speed) { default_balloon_speed_ = speed; }
|
||||||
void resetBalloonSpeed() { setBalloonSpeed(default_balloon_speed_); }
|
void resetBalloonSpeed() { setBalloonSpeed(default_balloon_speed_); }
|
||||||
|
void setPlayArea(SDL_Rect play_area) { play_area_ = play_area; }
|
||||||
};
|
};
|
||||||
471
source/credits.cpp
Normal file
471
source/credits.cpp
Normal file
@@ -0,0 +1,471 @@
|
|||||||
|
#include "credits.h"
|
||||||
|
#include <SDL2/SDL_blendmode.h> // Para SDL_BLENDMODE_BLEND
|
||||||
|
#include <SDL2/SDL_events.h> // Para SDL_PollEvent, SDL_Event, SDL_QUIT
|
||||||
|
#include <SDL2/SDL_pixels.h> // Para SDL_PIXELFORMAT_RGBA8888
|
||||||
|
#include <SDL2/SDL_rect.h> // Para SDL_Rect
|
||||||
|
#include <SDL2/SDL_timer.h> // Para SDL_GetTicks
|
||||||
|
#include <algorithm>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <string> // Para basic_string, string
|
||||||
|
#include <vector> // Para vector
|
||||||
|
#include "balloon_manager.h" // Para BalloonManager
|
||||||
|
#include "global_inputs.h" // Para check
|
||||||
|
#include "input.h" // Para Input
|
||||||
|
#include "jail_audio.h" // Para JA_PlayMusic, JA_StopMusic
|
||||||
|
#include "param.h" // Para Param, ParamGame, param
|
||||||
|
#include "resource.h" // Para Resource
|
||||||
|
#include "screen.h" // Para Screen
|
||||||
|
#include "section.h" // Para Name, name, Options, options
|
||||||
|
#include "text.h" // Para Text, TEXT_CENTER, TEXT_SHADOW
|
||||||
|
#include "tiled_bg.h" // Para TiledBG, TiledBGMode
|
||||||
|
#include "utils.h" // Para Color, no_color, shdw_txt_color, Zone
|
||||||
|
#include "player.h"
|
||||||
|
#include "fade.h"
|
||||||
|
#include "lang.h"
|
||||||
|
|
||||||
|
// Textos
|
||||||
|
constexpr const char TEXT_COPYRIGHT[] = "@2020,2024 JailDesigner";
|
||||||
|
|
||||||
|
// Constructor
|
||||||
|
Credits::Credits()
|
||||||
|
: balloon_manager_(std::make_unique<BalloonManager>()),
|
||||||
|
text_texture_(SDL_CreateTexture(Screen::get()->getRenderer(), SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, param.game.width, param.game.height)),
|
||||||
|
tiled_bg_(std::make_unique<TiledBG>(param.game.game_area.rect, TiledBGMode::DIAGONAL)),
|
||||||
|
fade_in_(std::make_unique<Fade>()),
|
||||||
|
fade_out_(std::make_unique<Fade>())
|
||||||
|
{
|
||||||
|
if (!text_texture_)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Failed to create SDL texture for text.");
|
||||||
|
}
|
||||||
|
section::name = section::Name::CREDITS;
|
||||||
|
//top_black_rect_ = {play_area_.x, 0, play_area_.w, black_bars_size_};
|
||||||
|
//bottom_black_rect_ = {play_area_.x, param.game.game_area.rect.h - black_bars_size_, play_area_.w, black_bars_size_};
|
||||||
|
balloon_manager_->setPlayArea(play_area_);
|
||||||
|
|
||||||
|
fade_in_->setColor(fade_color.r, fade_color.g, fade_color.b);
|
||||||
|
fade_in_->setType(FadeType::FULLSCREEN);
|
||||||
|
fade_in_->setPost(50);
|
||||||
|
fade_in_->setMode(FadeMode::IN);
|
||||||
|
fade_in_->activate();
|
||||||
|
|
||||||
|
fade_out_->setColor(0, 0, 0);
|
||||||
|
fade_out_->setType(FadeType::FULLSCREEN);
|
||||||
|
fade_out_->setPost(400);
|
||||||
|
|
||||||
|
initPlayers();
|
||||||
|
SDL_SetTextureBlendMode(text_texture_, SDL_BLENDMODE_BLEND);
|
||||||
|
fillTextTexture();
|
||||||
|
steps_ = std::abs((top_black_rect_.h - param.game.game_area.center_y - 1) + ((left_black_rect_.w - param.game.game_area.center_x) / 4));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Destructor
|
||||||
|
Credits::~Credits()
|
||||||
|
{
|
||||||
|
SDL_DestroyTexture(text_texture_);
|
||||||
|
resetVolume();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bucle principal
|
||||||
|
void Credits::run()
|
||||||
|
{
|
||||||
|
while (section::name == section::Name::CREDITS)
|
||||||
|
{
|
||||||
|
checkInput();
|
||||||
|
update();
|
||||||
|
checkEvents(); // Tiene que ir antes del render
|
||||||
|
render();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Actualiza las variables
|
||||||
|
void Credits::update()
|
||||||
|
{
|
||||||
|
if (SDL_GetTicks() - ticks_ > ticks_speed_)
|
||||||
|
{
|
||||||
|
ticks_ = SDL_GetTicks();
|
||||||
|
tiled_bg_->update();
|
||||||
|
balloon_manager_->update();
|
||||||
|
updateTextureDstRects();
|
||||||
|
throwBalloons();
|
||||||
|
for (auto &player : players_)
|
||||||
|
{
|
||||||
|
player->update();
|
||||||
|
}
|
||||||
|
updateAllFades();
|
||||||
|
Screen::get()->update();
|
||||||
|
globalInputs::update();
|
||||||
|
++counter_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dibuja Credits::en patalla
|
||||||
|
void Credits::render()
|
||||||
|
{
|
||||||
|
// Prepara para empezar a dibujar en la textura de juego
|
||||||
|
Screen::get()->start();
|
||||||
|
|
||||||
|
// Limpia la pantalla
|
||||||
|
Screen::get()->clean();
|
||||||
|
|
||||||
|
// Dibuja el fondo, los globos y los jugadores
|
||||||
|
tiled_bg_->render();
|
||||||
|
balloon_manager_->render();
|
||||||
|
for (auto const &player : players_)
|
||||||
|
{
|
||||||
|
player->render();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dibuja los titulos de credito
|
||||||
|
SDL_RenderCopy(Screen::get()->getRenderer(), text_texture_, &credits_rect_src_, &credits_rect_dst_);
|
||||||
|
|
||||||
|
// Dibuja el mini_logo
|
||||||
|
SDL_RenderCopy(Screen::get()->getRenderer(), text_texture_, &mini_logo_rect_src_, &mini_logo_rect_dst_);
|
||||||
|
|
||||||
|
// Dibuja los rectangulos negros
|
||||||
|
SDL_SetRenderDrawColor(Screen::get()->getRenderer(), 0, 0, 0, 255);
|
||||||
|
SDL_RenderFillRect(Screen::get()->getRenderer(), &top_black_rect_);
|
||||||
|
SDL_RenderFillRect(Screen::get()->getRenderer(), &bottom_black_rect_);
|
||||||
|
SDL_RenderFillRect(Screen::get()->getRenderer(), &left_black_rect_);
|
||||||
|
SDL_RenderFillRect(Screen::get()->getRenderer(), &right_black_rect_);
|
||||||
|
|
||||||
|
// Si el mini_logo está en su destino, lo dibuja encima de lo anterior
|
||||||
|
if (mini_logo_on_position_)
|
||||||
|
{
|
||||||
|
SDL_RenderCopy(Screen::get()->getRenderer(), text_texture_, &mini_logo_rect_src_, &mini_logo_rect_dst_);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dibuja el fade sobre el resto de elementos
|
||||||
|
fade_in_->render();
|
||||||
|
fade_out_->render();
|
||||||
|
|
||||||
|
// Vuelca el contenido del renderizador en pantalla
|
||||||
|
Screen::get()->blit();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Comprueba el manejador de eventos
|
||||||
|
void Credits::checkEvents()
|
||||||
|
{
|
||||||
|
SDL_Event event;
|
||||||
|
|
||||||
|
// Comprueba los eventos que hay en la cola
|
||||||
|
while (SDL_PollEvent(&event))
|
||||||
|
{
|
||||||
|
// Evento de salida de la aplicación
|
||||||
|
if (event.type == SDL_QUIT)
|
||||||
|
{
|
||||||
|
section::name = section::Name::QUIT;
|
||||||
|
section::options = section::Options::QUIT_FROM_EVENT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Comprueba las entradas
|
||||||
|
void Credits::checkInput()
|
||||||
|
{
|
||||||
|
// Comprueba si se ha pulsado cualquier botón (de los usados para jugar)
|
||||||
|
if (Input::get()->checkAnyButtonPressed())
|
||||||
|
{
|
||||||
|
if (mini_logo_on_position_)
|
||||||
|
{
|
||||||
|
// Si el mini_logo ha llegado a su posición final, al pulsar cualquier tecla se activa el fundido
|
||||||
|
fading_ = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Si todavía estan los creditos en marcha, se pasan solos a toda pastilla
|
||||||
|
want_to_pass_ = true;
|
||||||
|
ticks_speed_ = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Comprueba los inputs que se pueden introducir en cualquier sección del juego
|
||||||
|
globalInputs::check();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Crea la textura con el texto
|
||||||
|
void Credits::fillTextTexture()
|
||||||
|
{
|
||||||
|
auto text = Resource::get()->getText("smb2");
|
||||||
|
SDL_SetRenderTarget(Screen::get()->getRenderer(), text_texture_);
|
||||||
|
|
||||||
|
SDL_SetRenderDrawColor(Screen::get()->getRenderer(), 0, 0, 0, 0);
|
||||||
|
SDL_RenderClear(Screen::get()->getRenderer());
|
||||||
|
|
||||||
|
std::vector<std::string> texts = {
|
||||||
|
lang::getText(121),
|
||||||
|
lang::getText(122),
|
||||||
|
lang::getText(123),
|
||||||
|
lang::getText(124),
|
||||||
|
"JAILDESIGNER",
|
||||||
|
"JAILDOCTOR (INTRO)",
|
||||||
|
"ERIC MATYAS (SOUNDIMAGE.ORG)",
|
||||||
|
"WWW.THEMOTIONMONKEY.CO.UK",
|
||||||
|
"WWW.KENNEY.NL",
|
||||||
|
"JAILDOCTOR"};
|
||||||
|
|
||||||
|
const int space_post_title = 3 + text->getCharacterSize();
|
||||||
|
const int space_pre_title = text->getCharacterSize() * 4;
|
||||||
|
const int texts_height = 1 * text->getCharacterSize() + 7 * space_post_title + 3 * space_pre_title;
|
||||||
|
credits_rect_dst_.h = credits_rect_src_.h = texts_height;
|
||||||
|
|
||||||
|
int y = (param.game.height - texts_height) / 2;
|
||||||
|
y = 0;
|
||||||
|
text->setPalette(1);
|
||||||
|
text->writeDX(TEXT_CENTER | TEXT_SHADOW, param.game.game_area.center_x, y, texts.at(0), 1, no_color, 1, shdw_txt_color);
|
||||||
|
|
||||||
|
text->setPalette(0);
|
||||||
|
y += space_post_title;
|
||||||
|
text->writeDX(TEXT_CENTER | TEXT_SHADOW, param.game.game_area.center_x, y, texts.at(4), 1, no_color, 1, shdw_txt_color);
|
||||||
|
|
||||||
|
y += space_pre_title;
|
||||||
|
text->setPalette(1);
|
||||||
|
text->writeDX(TEXT_CENTER | TEXT_SHADOW, param.game.game_area.center_x, y, texts.at(1), 1, no_color, 1, shdw_txt_color);
|
||||||
|
text->setPalette(0);
|
||||||
|
y += space_post_title;
|
||||||
|
text->writeDX(TEXT_CENTER | TEXT_SHADOW, param.game.game_area.center_x, y, texts.at(4), 1, no_color, 1, shdw_txt_color);
|
||||||
|
|
||||||
|
y += space_pre_title;
|
||||||
|
text->setPalette(1);
|
||||||
|
text->writeDX(TEXT_CENTER | TEXT_SHADOW, param.game.game_area.center_x, y, texts.at(2), 1, no_color, 1, shdw_txt_color);
|
||||||
|
text->setPalette(0);
|
||||||
|
|
||||||
|
y += space_post_title;
|
||||||
|
text->writeDX(TEXT_CENTER | TEXT_SHADOW, param.game.game_area.center_x, y, texts.at(5), 1, no_color, 1, shdw_txt_color);
|
||||||
|
y += space_post_title;
|
||||||
|
text->writeDX(TEXT_CENTER | TEXT_SHADOW, param.game.game_area.center_x, y, texts.at(6), 1, no_color, 1, shdw_txt_color);
|
||||||
|
|
||||||
|
y += space_pre_title;
|
||||||
|
text->setPalette(1);
|
||||||
|
text->writeDX(TEXT_CENTER | TEXT_SHADOW, param.game.game_area.center_x, y, texts.at(3), 1, no_color, 1, shdw_txt_color);
|
||||||
|
text->setPalette(0);
|
||||||
|
y += space_post_title;
|
||||||
|
text->writeDX(TEXT_CENTER | TEXT_SHADOW, param.game.game_area.center_x, y, texts.at(7), 1, no_color, 1, shdw_txt_color);
|
||||||
|
y += space_post_title;
|
||||||
|
text->writeDX(TEXT_CENTER | TEXT_SHADOW, param.game.game_area.center_x, y, texts.at(8), 1, no_color, 1, shdw_txt_color);
|
||||||
|
y += space_post_title;
|
||||||
|
text->writeDX(TEXT_CENTER | TEXT_SHADOW, param.game.game_area.center_x, y, texts.at(9), 1, no_color, 1, shdw_txt_color);
|
||||||
|
|
||||||
|
// Mini logo
|
||||||
|
y += space_pre_title;
|
||||||
|
mini_logo_rect_src_.y = y;
|
||||||
|
auto mini_logo_sprite = std::make_unique<Sprite>(Resource::get()->getTexture("logo_jailgames_mini.png"));
|
||||||
|
mini_logo_sprite->setPosition(1 + param.game.game_area.center_x - mini_logo_sprite->getWidth() / 2, 1 + y);
|
||||||
|
Resource::get()->getTexture("logo_jailgames_mini.png")->setColor(shdw_txt_color.r, shdw_txt_color.g, shdw_txt_color.b);
|
||||||
|
mini_logo_sprite->render();
|
||||||
|
|
||||||
|
mini_logo_sprite->setPosition(param.game.game_area.center_x - mini_logo_sprite->getWidth() / 2, y);
|
||||||
|
Resource::get()->getTexture("logo_jailgames_mini.png")->setColor(255, 255, 255);
|
||||||
|
mini_logo_sprite->render();
|
||||||
|
|
||||||
|
// Texto con el copyright
|
||||||
|
y += mini_logo_sprite->getHeight() + 3;
|
||||||
|
text->writeDX(TEXT_CENTER | TEXT_SHADOW, param.game.game_area.center_x, y, TEXT_COPYRIGHT, 1, no_color, 1, shdw_txt_color);
|
||||||
|
|
||||||
|
// Resetea el renderizador
|
||||||
|
SDL_SetRenderTarget(Screen::get()->getRenderer(), nullptr);
|
||||||
|
|
||||||
|
// Actualiza las variables
|
||||||
|
mini_logo_rect_dst_.h = mini_logo_rect_src_.h = mini_logo_sprite->getHeight() + 3 + text->getCharacterSize();
|
||||||
|
credits_rect_dst_.y = param.game.game_area.rect.h;
|
||||||
|
mini_logo_rect_dst_.y = credits_rect_dst_.y + credits_rect_dst_.h + 30;
|
||||||
|
mini_logo_final_pos_ = param.game.game_area.center_y - mini_logo_rect_src_.h / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Actualiza el destino de los rectangulos de las texturas
|
||||||
|
void Credits::updateTextureDstRects()
|
||||||
|
{
|
||||||
|
if (counter_ % 10 == 0)
|
||||||
|
{
|
||||||
|
// Comprueba la posición de la textura con los titulos de credito
|
||||||
|
if (credits_rect_dst_.y + credits_rect_dst_.h > play_area_.y)
|
||||||
|
{
|
||||||
|
--credits_rect_dst_.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Comprueba la posición de la textura con el mini_logo
|
||||||
|
if (mini_logo_rect_dst_.y == mini_logo_final_pos_)
|
||||||
|
{
|
||||||
|
mini_logo_on_position_ = true;
|
||||||
|
|
||||||
|
// Si el jugador quiere pasar los titulos de credito, el fade se inicia solo
|
||||||
|
if (want_to_pass_)
|
||||||
|
{
|
||||||
|
fading_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Se activa el contador para evitar que la sección sea infinita
|
||||||
|
if (counter_prevent_endless_ == 1000)
|
||||||
|
{
|
||||||
|
fading_ = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
++counter_prevent_endless_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
--mini_logo_rect_dst_.y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tira globos al escenario
|
||||||
|
void Credits::throwBalloons()
|
||||||
|
{
|
||||||
|
constexpr int speed = 200;
|
||||||
|
const std::vector<int> sets = {0, 63, 25, 67, 17, 75, 13, 50};
|
||||||
|
|
||||||
|
if (counter_ > ((sets.size() - 1) * speed) * 3)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (counter_ % speed == 0)
|
||||||
|
{
|
||||||
|
const int index = (counter_ / speed) % sets.size();
|
||||||
|
balloon_manager_->deploySet(sets.at(index), -60);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (counter_ % (speed * 4) == 0 && counter_ > 0)
|
||||||
|
{
|
||||||
|
balloon_manager_->createPowerBall();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inicializa los jugadores
|
||||||
|
void Credits::initPlayers()
|
||||||
|
{
|
||||||
|
std::vector<std::vector<std::shared_ptr<Texture>>> player_textures; // Vector con todas las texturas de los jugadores;
|
||||||
|
std::vector<std::vector<std::string>> player_animations; // Vector con las animaciones del jugador
|
||||||
|
|
||||||
|
// Texturas - Player1
|
||||||
|
{
|
||||||
|
std::vector<std::shared_ptr<Texture>> player_texture;
|
||||||
|
player_texture.emplace_back(Resource::get()->getTexture("player1.gif"));
|
||||||
|
player_texture.emplace_back(Resource::get()->getTexture("player1_power.png"));
|
||||||
|
player_textures.push_back(player_texture);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Texturas - Player2
|
||||||
|
{
|
||||||
|
std::vector<std::shared_ptr<Texture>> player_texture;
|
||||||
|
player_texture.emplace_back(Resource::get()->getTexture("player2.gif"));
|
||||||
|
player_texture.emplace_back(Resource::get()->getTexture("player2_power.png"));
|
||||||
|
player_textures.push_back(player_texture);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Animaciones -- Jugador
|
||||||
|
{
|
||||||
|
player_animations.emplace_back(Resource::get()->getAnimation("player.ani"));
|
||||||
|
player_animations.emplace_back(Resource::get()->getAnimation("player_power.ani"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Crea los dos jugadores
|
||||||
|
constexpr int player_width = 30;
|
||||||
|
const int y = play_area_.y + play_area_.h - player_width;
|
||||||
|
constexpr bool demo = false;
|
||||||
|
constexpr int away_distance = 700;
|
||||||
|
players_.emplace_back(std::make_unique<Player>(1, play_area_.x - away_distance - player_width, y, demo, play_area_, player_textures.at(0), player_animations));
|
||||||
|
players_.back()->setWalkingState(PlayerState::WALKING_RIGHT);
|
||||||
|
players_.back()->setPlayingState(PlayerState::CREDITS);
|
||||||
|
players_.back()->setInvulnerable(false);
|
||||||
|
|
||||||
|
players_.emplace_back(std::make_unique<Player>(2, play_area_.x + play_area_.w + away_distance, y, demo, play_area_, player_textures.at(1), player_animations));
|
||||||
|
players_.back()->setWalkingState(PlayerState::WALKING_LEFT);
|
||||||
|
players_.back()->setPlayingState(PlayerState::CREDITS);
|
||||||
|
players_.back()->setInvulnerable(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Actualiza los rectangulos negros
|
||||||
|
void Credits::updateBlackRects()
|
||||||
|
{
|
||||||
|
static int current_step = steps_;
|
||||||
|
if (top_black_rect_.h != param.game.game_area.center_y - 1 && bottom_black_rect_.y != param.game.game_area.center_y + 1)
|
||||||
|
{
|
||||||
|
// Si los rectangulos superior e inferior no han llegado al centro
|
||||||
|
if (counter_ % 4 == 0)
|
||||||
|
{
|
||||||
|
// Incrementa la altura del rectangulo superior
|
||||||
|
top_black_rect_.h = std::min(top_black_rect_.h + 1, param.game.game_area.center_y - 1);
|
||||||
|
|
||||||
|
// Incrementa la altura y modifica la posición del rectangulo inferior
|
||||||
|
++bottom_black_rect_.h;
|
||||||
|
bottom_black_rect_.y = std::max(bottom_black_rect_.y - 1, param.game.game_area.center_y + 1);
|
||||||
|
|
||||||
|
--current_step;
|
||||||
|
setVolume(static_cast<int>(initial_volume_ * current_step / steps_));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Si los rectangulos superior e inferior han llegado al centro
|
||||||
|
if (left_black_rect_.w != param.game.game_area.center_x && right_black_rect_.x != param.game.game_area.center_x)
|
||||||
|
{
|
||||||
|
// Si los rectangulos izquierdo y derecho no han llegado al centro
|
||||||
|
// Incrementa la anchura del rectangulo situado a la izquierda
|
||||||
|
left_black_rect_.w = std::min(left_black_rect_.w + 4, param.game.game_area.center_x);
|
||||||
|
|
||||||
|
// Incrementa la anchura y modifica la posición del rectangulo situado a la derecha
|
||||||
|
right_black_rect_.w += 4;
|
||||||
|
right_black_rect_.x = std::max(right_black_rect_.x - 4, param.game.game_area.center_x);
|
||||||
|
|
||||||
|
--current_step;
|
||||||
|
setVolume(static_cast<int>(initial_volume_ * current_step / steps_));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Si los rectangulos izquierdo y derecho han llegado al centro
|
||||||
|
setVolume(0);
|
||||||
|
JA_StopMusic();
|
||||||
|
if (counter_pre_fade_ == 400)
|
||||||
|
{
|
||||||
|
fade_out_->activate();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
++counter_pre_fade_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Actualiza el estado de fade
|
||||||
|
void Credits::updateAllFades()
|
||||||
|
{
|
||||||
|
if (fading_)
|
||||||
|
{
|
||||||
|
updateBlackRects();
|
||||||
|
}
|
||||||
|
|
||||||
|
fade_in_->update();
|
||||||
|
if (fade_in_->hasEnded())
|
||||||
|
{
|
||||||
|
if (JA_GetMusicState() == JA_MUSIC_INVALID || JA_GetMusicState() == JA_MUSIC_STOPPED)
|
||||||
|
{
|
||||||
|
JA_PlayMusic(Resource::get()->getMusic("credits.ogg"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fade_out_->update();
|
||||||
|
if (fade_out_->hasEnded())
|
||||||
|
{
|
||||||
|
section::name = section::Name::LOGO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Establece el nivel de volumen
|
||||||
|
void Credits::setVolume(int amount)
|
||||||
|
{
|
||||||
|
options.audio.music.volume = std::clamp(amount, 0, 100);
|
||||||
|
JA_SetMusicVolume(to_JA_volume(options.audio.music.volume));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reestablece el nivel de volumen
|
||||||
|
void Credits::resetVolume()
|
||||||
|
{
|
||||||
|
options.audio.music.volume = initial_volume_;
|
||||||
|
JA_SetMusicVolume(to_JA_volume(options.audio.music.volume));
|
||||||
|
}
|
||||||
100
source/credits.h
Normal file
100
source/credits.h
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <SDL2/SDL_render.h> // Para SDL_Texture
|
||||||
|
#include <SDL2/SDL_stdinc.h> // Para Uint32
|
||||||
|
#include <memory> // Para unique_ptr
|
||||||
|
#include "param.h"
|
||||||
|
#include "options.h"
|
||||||
|
class BalloonManager;
|
||||||
|
class TiledBG;
|
||||||
|
class Player;
|
||||||
|
class Fade;
|
||||||
|
|
||||||
|
constexpr int PLAY_AREA_HEIGHT = 200;
|
||||||
|
|
||||||
|
class Credits
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
// Objetos
|
||||||
|
std::unique_ptr<BalloonManager> balloon_manager_; // Objeto para gestionar los globos
|
||||||
|
SDL_Texture *text_texture_; // Textura con el texto
|
||||||
|
std::unique_ptr<TiledBG> tiled_bg_; // Objeto para dibujar el mosaico animado de fondo
|
||||||
|
std::unique_ptr<Fade> fade_in_; // Objeto para realizar el fundido de entrada
|
||||||
|
std::unique_ptr<Fade> fade_out_; // Objeto para realizar el fundido de salida
|
||||||
|
std::vector<std::shared_ptr<Player>> players_; // Vector con los jugadores
|
||||||
|
|
||||||
|
// Variables
|
||||||
|
Uint32 ticks_ = 0; // Contador de ticks para ajustar la velocidad del programa
|
||||||
|
Uint32 ticks_speed_ = 15; // Velocidad del bucle update
|
||||||
|
Uint32 counter_ = 0; // Contador para la lógica de la clase
|
||||||
|
Uint32 counter_pre_fade_ = 0; // Contador para activar el fundido final
|
||||||
|
Uint32 counter_prevent_endless_ = 0; // Contador para evitar que el juego se quede para siempre en los creditos
|
||||||
|
int black_bars_size_ = (param.game.game_area.rect.h - PLAY_AREA_HEIGHT) / 2; // Tamaño de las barras negras
|
||||||
|
int mini_logo_final_pos_ = 0; // Ubicación donde se detiene el minilogo
|
||||||
|
bool fading_ = false; // Indica si se está realizando el fade final
|
||||||
|
bool want_to_pass_ = false; // Indica si el jugador quiere saltarse los titulos de crédito
|
||||||
|
bool mini_logo_on_position_ = false; // Indica si el minilogo ya se ha quedado en su posición
|
||||||
|
int initial_volume_ = options.audio.music.volume; // Volumen actual al crear el objeto
|
||||||
|
int steps_ = 0; // Cantidad de pasos a dar para ir reduciendo el audio
|
||||||
|
|
||||||
|
// Rectangulos
|
||||||
|
SDL_Rect credits_rect_src_ = param.game.game_area.rect; // Rectangulo con el texto de los créditos (origen)
|
||||||
|
SDL_Rect credits_rect_dst_ = param.game.game_area.rect; // Rectangulo con el texto de los créditos (destino)
|
||||||
|
SDL_Rect mini_logo_rect_src_ = param.game.game_area.rect; // Rectangulo con el mini logo de JailGames y el texto de copyright (origen)
|
||||||
|
SDL_Rect mini_logo_rect_dst_ = param.game.game_area.rect; // Rectangulo con el mini logo de JailGames y el texto de copyright (destino)
|
||||||
|
SDL_Rect play_area_ = {
|
||||||
|
param.game.game_area.rect.x,
|
||||||
|
param.game.game_area.rect.y + black_bars_size_,
|
||||||
|
param.game.game_area.rect.w,
|
||||||
|
PLAY_AREA_HEIGHT}; // Area visible para los creditos
|
||||||
|
SDL_Rect top_black_rect_ = {play_area_.x, param.game.game_area.rect.y, play_area_.w, black_bars_size_}; // Rectangulo negro superior
|
||||||
|
SDL_Rect bottom_black_rect_ = {play_area_.x, param.game.game_area.rect.h - black_bars_size_, play_area_.w, black_bars_size_}; // Rectangulo negro inferior
|
||||||
|
SDL_Rect left_black_rect_ = {play_area_.x, param.game.game_area.center_y - 1, 0, 2}; // Rectangulo negro situado a la izquierda
|
||||||
|
SDL_Rect right_black_rect_ = {play_area_.x + play_area_.w, param.game.game_area.center_y - 1, 0, 2}; // Rectangulo negro situado a la derecha
|
||||||
|
|
||||||
|
// Actualiza las variables
|
||||||
|
void update();
|
||||||
|
|
||||||
|
// Dibuja en pantalla
|
||||||
|
void render();
|
||||||
|
|
||||||
|
// Comprueba el manejador de eventos
|
||||||
|
void checkEvents();
|
||||||
|
|
||||||
|
// Comprueba las entradas
|
||||||
|
void checkInput();
|
||||||
|
|
||||||
|
// Crea la textura con el texto
|
||||||
|
void fillTextTexture();
|
||||||
|
|
||||||
|
// Actualiza el destino de los rectangulos de las texturas
|
||||||
|
void updateTextureDstRects();
|
||||||
|
|
||||||
|
// Tira globos al escenario
|
||||||
|
void throwBalloons();
|
||||||
|
|
||||||
|
// Inicializa los jugadores
|
||||||
|
void initPlayers();
|
||||||
|
|
||||||
|
// Actualiza los rectangulos negros
|
||||||
|
void updateBlackRects();
|
||||||
|
|
||||||
|
// Actualiza el estado de fade
|
||||||
|
void updateAllFades();
|
||||||
|
|
||||||
|
// Establece el nivel de volumen
|
||||||
|
void setVolume(int amount);
|
||||||
|
|
||||||
|
// Reestablece el nivel de volumen
|
||||||
|
void resetVolume();
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Constructor
|
||||||
|
Credits();
|
||||||
|
|
||||||
|
// Destructor
|
||||||
|
~Credits();
|
||||||
|
|
||||||
|
// Bucle principal
|
||||||
|
void run();
|
||||||
|
};
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// IWYU pragma: no_include <bits/chrono.h>
|
||||||
#include "director.h"
|
#include "director.h"
|
||||||
#include <SDL2/SDL.h> // Para SDL_Init, SDL_Quit, SDL_INIT_EV...
|
#include <SDL2/SDL.h> // Para SDL_Init, SDL_Quit, SDL_INIT_EV...
|
||||||
#include <SDL2/SDL_audio.h> // Para AUDIO_S16
|
#include <SDL2/SDL_audio.h> // Para AUDIO_S16
|
||||||
@@ -7,7 +8,7 @@
|
|||||||
#include <SDL2/SDL_hints.h> // Para SDL_SetHint, SDL_HINT_RENDER_DR...
|
#include <SDL2/SDL_hints.h> // Para SDL_SetHint, SDL_HINT_RENDER_DR...
|
||||||
#include <SDL2/SDL_scancode.h> // Para SDL_SCANCODE_0, SDL_SCANCODE_DOWN
|
#include <SDL2/SDL_scancode.h> // Para SDL_SCANCODE_0, SDL_SCANCODE_DOWN
|
||||||
#include <SDL2/SDL_stdinc.h> // Para SDL_bool, Uint32
|
#include <SDL2/SDL_stdinc.h> // Para SDL_bool, Uint32
|
||||||
#include <bits/chrono.h> // Para duration, system_clock
|
#include <chrono> // Para duration, system_clock
|
||||||
#include <errno.h> // Para errno, EEXIST, EACCES, ENAMETOO...
|
#include <errno.h> // Para errno, EEXIST, EACCES, ENAMETOO...
|
||||||
#include <stdio.h> // Para printf, perror
|
#include <stdio.h> // Para printf, perror
|
||||||
#include <sys/stat.h> // Para mkdir, stat, S_IRWXU
|
#include <sys/stat.h> // Para mkdir, stat, S_IRWXU
|
||||||
@@ -20,6 +21,7 @@
|
|||||||
#include <string> // Para operator+, char_traits, allocator
|
#include <string> // Para operator+, char_traits, allocator
|
||||||
#include <vector> // Para vector
|
#include <vector> // Para vector
|
||||||
#include "asset.h" // Para Asset, AssetType
|
#include "asset.h" // Para Asset, AssetType
|
||||||
|
#include "credits.h" // Para Credits
|
||||||
#include "dbgtxt.h" // Para dbg_init
|
#include "dbgtxt.h" // Para dbg_init
|
||||||
#include "game.h" // Para Game, GAME_MODE_DEMO_OFF, GAME_...
|
#include "game.h" // Para Game, GAME_MODE_DEMO_OFF, GAME_...
|
||||||
#include "global_inputs.h" // Para init
|
#include "global_inputs.h" // Para init
|
||||||
@@ -45,13 +47,6 @@
|
|||||||
#include <pwd.h> // para getpwuid, passwd
|
#include <pwd.h> // para getpwuid, passwd
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Inicia la semilla aleatoria
|
|
||||||
void initRand()
|
|
||||||
{
|
|
||||||
unsigned int seed = static_cast<unsigned int>(std::chrono::system_clock::now().time_since_epoch().count());
|
|
||||||
std::srand(seed);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
Director::Director(int argc, const char *argv[])
|
Director::Director(int argc, const char *argv[])
|
||||||
{
|
{
|
||||||
@@ -60,7 +55,7 @@ Director::Director(int argc, const char *argv[])
|
|||||||
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::LOGO;
|
||||||
#else
|
#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;
|
||||||
#endif
|
#endif
|
||||||
@@ -73,42 +68,36 @@ Director::Director(int argc, const char *argv[])
|
|||||||
|
|
||||||
std::cout << "Game start" << std::endl;
|
std::cout << "Game start" << std::endl;
|
||||||
|
|
||||||
initRand();
|
// Inicia la semilla aleatoria
|
||||||
|
unsigned int seed = static_cast<unsigned int>(std::chrono::system_clock::now().time_since_epoch().count());
|
||||||
|
std::srand(seed);
|
||||||
|
|
||||||
// Comprueba los parametros del programa
|
// Comprueba los parametros del programa
|
||||||
checkProgramArguments(argc, argv);
|
checkProgramArguments(argc, argv);
|
||||||
|
|
||||||
// Crea la carpeta del sistema donde guardar datos
|
// Crea la carpeta del sistema donde guardar los datos persistentes
|
||||||
createSystemFolder("jailgames");
|
createSystemFolder("jailgames");
|
||||||
createSystemFolder("jailgames/coffee_crisis_arcade_edition");
|
createSystemFolder("jailgames/coffee_crisis_arcade_edition");
|
||||||
|
|
||||||
// Crea el objeto que controla los ficheros de recursos
|
init();
|
||||||
Asset::init(executable_path_);
|
}
|
||||||
|
|
||||||
// Crea el indice de ficheros
|
Director::~Director()
|
||||||
setFileList();
|
{
|
||||||
|
close();
|
||||||
|
std::cout << "\nBye!" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
// Carga el fichero de configuración
|
// Inicializa todo
|
||||||
loadOptionsFile(Asset::get()->get("config.txt"));
|
void Director::init()
|
||||||
|
{
|
||||||
|
Asset::init(executable_path_); // Crea el objeto que controla los ficheros de recursos
|
||||||
|
setFileList(); // Crea el indice de ficheros
|
||||||
|
loadOptionsFile(Asset::get()->get("config.txt")); // Carga el fichero de configuración
|
||||||
|
loadParams(); // Carga los parametros
|
||||||
|
loadScoreFile(); // Carga el fichero de puntuaciones
|
||||||
|
|
||||||
// Carga los parametros para configurar el juego
|
// Inicializa y crea el resto de objetos
|
||||||
#ifdef ANBERNIC
|
|
||||||
const std::string paramFilePath = asset->get("param_320x240.txt");
|
|
||||||
#else
|
|
||||||
const std::string paramFilePath = overrides.param_file == "--320x240" ? Asset::get()->get("param_320x240.txt") : Asset::get()->get("param_320x256.txt");
|
|
||||||
#endif
|
|
||||||
loadParamsFromFile(paramFilePath);
|
|
||||||
|
|
||||||
// Carga el fichero de puntuaciones
|
|
||||||
{
|
|
||||||
auto manager = std::make_unique<ManageHiScoreTable>(options.game.hi_score_table);
|
|
||||||
if (overrides.clear_hi_score_table)
|
|
||||||
manager->clear();
|
|
||||||
else
|
|
||||||
manager->loadFromFile(Asset::get()->get("score.bin"));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Inicializa todo
|
|
||||||
initSDL();
|
initSDL();
|
||||||
initJailAudio();
|
initJailAudio();
|
||||||
dbg_init(renderer_);
|
dbg_init(renderer_);
|
||||||
@@ -117,12 +106,12 @@ Director::Director(int argc, const char *argv[])
|
|||||||
Resource::init();
|
Resource::init();
|
||||||
Input::init(Asset::get()->get("gamecontrollerdb.txt"));
|
Input::init(Asset::get()->get("gamecontrollerdb.txt"));
|
||||||
bindInputs();
|
bindInputs();
|
||||||
Notifier::init(std::string(), Resource::get()->getText("8bithud"), Asset::get()->get("notify.wav"));
|
Notifier::init(std::string(), Resource::get()->getText("8bithud"));
|
||||||
OnScreenHelp::init();
|
OnScreenHelp::init();
|
||||||
globalInputs::init();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Director::~Director()
|
// Cierra todo
|
||||||
|
void Director::close()
|
||||||
{
|
{
|
||||||
saveOptionsFile(Asset::get()->get("config.txt"));
|
saveOptionsFile(Asset::get()->get("config.txt"));
|
||||||
|
|
||||||
@@ -133,12 +122,38 @@ Director::~Director()
|
|||||||
Notifier::destroy();
|
Notifier::destroy();
|
||||||
OnScreenHelp::destroy();
|
OnScreenHelp::destroy();
|
||||||
|
|
||||||
|
JA_Quit();
|
||||||
|
|
||||||
SDL_DestroyRenderer(renderer_);
|
SDL_DestroyRenderer(renderer_);
|
||||||
SDL_DestroyWindow(window_);
|
SDL_DestroyWindow(window_);
|
||||||
|
|
||||||
SDL_Quit();
|
SDL_Quit();
|
||||||
|
}
|
||||||
|
|
||||||
std::cout << "\nBye!" << std::endl;
|
// Carga los parametros
|
||||||
|
void Director::loadParams()
|
||||||
|
{
|
||||||
|
// Carga los parametros para configurar el juego
|
||||||
|
#ifdef ANBERNIC
|
||||||
|
const std::string paramFilePath = asset->get("param_320x240.txt");
|
||||||
|
#else
|
||||||
|
const std::string paramFilePath = overrides.param_file == "--320x240" ? Asset::get()->get("param_320x240.txt") : Asset::get()->get("param_320x256.txt");
|
||||||
|
#endif
|
||||||
|
loadParamsFromFile(paramFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Carga el fichero de puntuaciones
|
||||||
|
void Director::loadScoreFile()
|
||||||
|
{
|
||||||
|
auto manager = std::make_unique<ManageHiScoreTable>(options.game.hi_score_table);
|
||||||
|
if (overrides.clear_hi_score_table)
|
||||||
|
{
|
||||||
|
manager->clear();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
manager->loadFromFile(Asset::get()->get("score.bin"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Asigna los botones y teclas al objeto Input
|
// Asigna los botones y teclas al objeto Input
|
||||||
@@ -165,7 +180,9 @@ void Director::bindInputs()
|
|||||||
Input::get()->bindKey(InputType::WINDOW_FULLSCREEN, SDL_SCANCODE_F3);
|
Input::get()->bindKey(InputType::WINDOW_FULLSCREEN, SDL_SCANCODE_F3);
|
||||||
Input::get()->bindKey(InputType::VIDEO_SHADERS, SDL_SCANCODE_F4);
|
Input::get()->bindKey(InputType::VIDEO_SHADERS, SDL_SCANCODE_F4);
|
||||||
Input::get()->bindKey(InputType::MUTE, SDL_SCANCODE_F5);
|
Input::get()->bindKey(InputType::MUTE, SDL_SCANCODE_F5);
|
||||||
Input::get()->bindKey(InputType::SHOWINFO, SDL_SCANCODE_F6);
|
Input::get()->bindKey(InputType::AUTO_FIRE, SDL_SCANCODE_F6);
|
||||||
|
Input::get()->bindKey(InputType::CHANGE_LANG, SDL_SCANCODE_F7);
|
||||||
|
Input::get()->bindKey(InputType::SHOWINFO, SDL_SCANCODE_F8);
|
||||||
Input::get()->bindKey(InputType::RESET, SDL_SCANCODE_F10);
|
Input::get()->bindKey(InputType::RESET, SDL_SCANCODE_F10);
|
||||||
|
|
||||||
// Asigna botones a inputs
|
// Asigna botones a inputs
|
||||||
@@ -279,8 +296,15 @@ bool Director::initSDL()
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// Obtiene información sobre la pantalla
|
||||||
SDL_DisplayMode DM;
|
SDL_DisplayMode DM;
|
||||||
SDL_GetCurrentDisplayMode(0, &DM);
|
SDL_GetCurrentDisplayMode(0, &DM);
|
||||||
|
|
||||||
|
// Calcula el máximo factor de zoom que se puede aplicar a la pantalla
|
||||||
|
options.video.window.max_size = std::min(DM.w / param.game.width, DM.h / param.game.height);
|
||||||
|
options.video.window.size = std::min(options.video.window.size, options.video.window.max_size);
|
||||||
|
|
||||||
|
// Muestra información sobre el tamaño de la pantalla y de la ventana de juego
|
||||||
std::cout << "\nCurrent display mode: " << DM.w << "x" << DM.h << " @ " << DM.refresh_rate << "Hz" << std::endl;
|
std::cout << "\nCurrent display mode: " << DM.w << "x" << DM.h << " @ " << DM.refresh_rate << "Hz" << std::endl;
|
||||||
std::cout << "Window resolution : " << param.game.width << "x" << param.game.height << " x" << options.video.window.size << std::endl;
|
std::cout << "Window resolution : " << param.game.width << "x" << param.game.height << " x" << options.video.window.size << std::endl;
|
||||||
|
|
||||||
@@ -361,8 +385,10 @@ void Director::setFileList()
|
|||||||
Asset::get()->add(prefix + "/data/music/intro.ogg", AssetType::MUSIC);
|
Asset::get()->add(prefix + "/data/music/intro.ogg", AssetType::MUSIC);
|
||||||
Asset::get()->add(prefix + "/data/music/playing.ogg", AssetType::MUSIC);
|
Asset::get()->add(prefix + "/data/music/playing.ogg", AssetType::MUSIC);
|
||||||
Asset::get()->add(prefix + "/data/music/title.ogg", AssetType::MUSIC);
|
Asset::get()->add(prefix + "/data/music/title.ogg", AssetType::MUSIC);
|
||||||
|
Asset::get()->add(prefix + "/data/music/credits.ogg", AssetType::MUSIC);
|
||||||
|
|
||||||
// Sonidos
|
// Sonidos
|
||||||
|
Asset::get()->add(prefix + "/data/sound/game_start.wav", AssetType::SOUND);
|
||||||
Asset::get()->add(prefix + "/data/sound/balloon.wav", AssetType::SOUND);
|
Asset::get()->add(prefix + "/data/sound/balloon.wav", AssetType::SOUND);
|
||||||
Asset::get()->add(prefix + "/data/sound/bubble1.wav", AssetType::SOUND);
|
Asset::get()->add(prefix + "/data/sound/bubble1.wav", AssetType::SOUND);
|
||||||
Asset::get()->add(prefix + "/data/sound/bubble2.wav", AssetType::SOUND);
|
Asset::get()->add(prefix + "/data/sound/bubble2.wav", AssetType::SOUND);
|
||||||
@@ -379,9 +405,16 @@ void Director::setFileList()
|
|||||||
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/powerball.wav", AssetType::SOUND);
|
Asset::get()->add(prefix + "/data/sound/powerball.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/logo.wav", AssetType::SOUND);
|
||||||
|
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
|
// Shaders
|
||||||
Asset::get()->add(prefix + "/data/shaders/crtpi.glsl", AssetType::DATA);
|
Asset::get()->add(prefix + "/data/shaders/crtpi_256.glsl", AssetType::DATA);
|
||||||
|
Asset::get()->add(prefix + "/data/shaders/crtpi_240.glsl", AssetType::DATA);
|
||||||
|
|
||||||
// Texturas
|
// Texturas
|
||||||
|
|
||||||
@@ -420,6 +453,11 @@ void Director::setFileList()
|
|||||||
Asset::get()->add(prefix + "/data/gfx/bullet/bullet.png", AssetType::BITMAP);
|
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
|
{ // Juego
|
||||||
Asset::get()->add(prefix + "/data/gfx/game/game_buildings.png", AssetType::BITMAP);
|
Asset::get()->add(prefix + "/data/gfx/game/game_buildings.png", AssetType::BITMAP);
|
||||||
Asset::get()->add(prefix + "/data/gfx/game/game_clouds1.png", AssetType::BITMAP);
|
Asset::get()->add(prefix + "/data/gfx/game/game_clouds1.png", AssetType::BITMAP);
|
||||||
@@ -630,6 +668,13 @@ void Director::runInstructions()
|
|||||||
instructions->run();
|
instructions->run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ejecuta la sección donde se muestran los creditos del programa
|
||||||
|
void Director::runCredits()
|
||||||
|
{
|
||||||
|
auto credits = std::make_unique<Credits>();
|
||||||
|
credits->run();
|
||||||
|
}
|
||||||
|
|
||||||
// Ejecuta la sección donde se muestra la tabla de puntuaciones
|
// Ejecuta la sección donde se muestra la tabla de puntuaciones
|
||||||
void Director::runHiScoreTable()
|
void Director::runHiScoreTable()
|
||||||
{
|
{
|
||||||
@@ -646,6 +691,16 @@ void Director::runDemoGame()
|
|||||||
game->run();
|
game->run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ejecuta la sección init
|
||||||
|
void Director::runInit()
|
||||||
|
{
|
||||||
|
if (section::options == section::Options::RELOAD)
|
||||||
|
{
|
||||||
|
Resource::get()->reload();
|
||||||
|
}
|
||||||
|
section::name = section::Name::LOGO;
|
||||||
|
}
|
||||||
|
|
||||||
int Director::run()
|
int Director::run()
|
||||||
{
|
{
|
||||||
// Bucle principal
|
// Bucle principal
|
||||||
@@ -654,7 +709,7 @@ int Director::run()
|
|||||||
switch (section::name)
|
switch (section::name)
|
||||||
{
|
{
|
||||||
case section::Name::INIT:
|
case section::Name::INIT:
|
||||||
section::name = section::Name::LOGO;
|
runInit();
|
||||||
break;
|
break;
|
||||||
case section::Name::LOGO:
|
case section::Name::LOGO:
|
||||||
runLogo();
|
runLogo();
|
||||||
@@ -677,6 +732,9 @@ int Director::run()
|
|||||||
case section::Name::INSTRUCTIONS:
|
case section::Name::INSTRUCTIONS:
|
||||||
runInstructions();
|
runInstructions();
|
||||||
break;
|
break;
|
||||||
|
case section::Name::CREDITS:
|
||||||
|
runCredits();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,12 +58,18 @@ private:
|
|||||||
// Ejecuta la sección donde se muestran las instrucciones
|
// Ejecuta la sección donde se muestran las instrucciones
|
||||||
void runInstructions();
|
void runInstructions();
|
||||||
|
|
||||||
|
// Ejecuta la sección donde se muestran los creditos del programa
|
||||||
|
void runCredits();
|
||||||
|
|
||||||
// Ejecuta la sección donde se muestra la tabla de puntuaciones
|
// Ejecuta la sección donde se muestra la tabla de puntuaciones
|
||||||
void runHiScoreTable();
|
void runHiScoreTable();
|
||||||
|
|
||||||
// Ejecuta el juego en modo demo
|
// Ejecuta el juego en modo demo
|
||||||
void runDemoGame();
|
void runDemoGame();
|
||||||
|
|
||||||
|
// Ejecuta la sección init
|
||||||
|
void runInit();
|
||||||
|
|
||||||
// Obtiene una fichero a partir de un lang::Code
|
// Obtiene una fichero a partir de un lang::Code
|
||||||
std::string getLangFile(lang::Code code);
|
std::string getLangFile(lang::Code code);
|
||||||
#ifdef ARCADE
|
#ifdef ARCADE
|
||||||
@@ -71,6 +77,18 @@ private:
|
|||||||
void shutdownSystem();
|
void shutdownSystem();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Inicializa todo
|
||||||
|
void init();
|
||||||
|
|
||||||
|
// Cierra todo
|
||||||
|
void close();
|
||||||
|
|
||||||
|
// Carga los parametros
|
||||||
|
void loadParams();
|
||||||
|
|
||||||
|
// Carga el fichero de puntuaciones
|
||||||
|
void loadScoreFile();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Constructor
|
// Constructor
|
||||||
Director(int argc, const char *argv[]);
|
Director(int argc, const char *argv[]);
|
||||||
|
|||||||
@@ -100,6 +100,8 @@ void Fade::update()
|
|||||||
|
|
||||||
SDL_RenderFillRect(renderer_, &rect1_);
|
SDL_RenderFillRect(renderer_, &rect1_);
|
||||||
SDL_RenderFillRect(renderer_, &rect2_);
|
SDL_RenderFillRect(renderer_, &rect2_);
|
||||||
|
|
||||||
|
value_ = calculateValue(0, counter_, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deja el renderizador como estaba
|
// Deja el renderizador como estaba
|
||||||
@@ -121,7 +123,6 @@ void Fade::update()
|
|||||||
// Dibuja sobre el backbuffer_
|
// Dibuja sobre el backbuffer_
|
||||||
auto temp = SDL_GetRenderTarget(renderer_);
|
auto temp = SDL_GetRenderTarget(renderer_);
|
||||||
SDL_SetRenderTarget(renderer_, backbuffer_);
|
SDL_SetRenderTarget(renderer_, backbuffer_);
|
||||||
|
|
||||||
SDL_SetRenderDrawBlendMode(renderer_, SDL_BLENDMODE_NONE);
|
SDL_SetRenderDrawBlendMode(renderer_, SDL_BLENDMODE_NONE);
|
||||||
SDL_SetRenderDrawColor(renderer_, r_, g_, b_, a_);
|
SDL_SetRenderDrawColor(renderer_, r_, g_, b_, a_);
|
||||||
|
|
||||||
@@ -133,12 +134,12 @@ void Fade::update()
|
|||||||
SDL_RenderFillRect(renderer_, &square_[index2]);
|
SDL_RenderFillRect(renderer_, &square_[index2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_SetRenderDrawBlendMode(renderer_, SDL_BLENDMODE_BLEND);
|
|
||||||
|
|
||||||
// Deja el renderizador como estaba
|
// Deja el renderizador como estaba
|
||||||
SDL_SetRenderTarget(renderer_, temp);
|
SDL_SetRenderTarget(renderer_, temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
value_ = calculateValue(0, static_cast<int>(num_squares_width_ * num_squares_height_), static_cast<int>(counter_ * fade_random_squares_mult_ / fade_random_squares_delay_));
|
||||||
|
|
||||||
// Comprueba si ha terminado
|
// Comprueba si ha terminado
|
||||||
if (counter_ * fade_random_squares_mult_ / fade_random_squares_delay_ >= num_squares_width_ * num_squares_height_)
|
if (counter_ * fade_random_squares_mult_ / fade_random_squares_delay_ >= num_squares_width_ * num_squares_height_)
|
||||||
{
|
{
|
||||||
@@ -156,9 +157,11 @@ void Fade::update()
|
|||||||
// Dibuja sobre el backbuffer_
|
// Dibuja sobre el backbuffer_
|
||||||
auto temp = SDL_GetRenderTarget(renderer_);
|
auto temp = SDL_GetRenderTarget(renderer_);
|
||||||
SDL_SetRenderTarget(renderer_, backbuffer_);
|
SDL_SetRenderTarget(renderer_, backbuffer_);
|
||||||
|
SDL_SetRenderDrawBlendMode(renderer_, SDL_BLENDMODE_NONE);
|
||||||
SDL_SetRenderDrawColor(renderer_, r_, g_, b_, a_);
|
SDL_SetRenderDrawColor(renderer_, r_, g_, b_, a_);
|
||||||
for (auto rect : square_)
|
|
||||||
|
// Dibuja el cuadrado correspondiente
|
||||||
|
for (const auto rect : square_)
|
||||||
{
|
{
|
||||||
SDL_RenderFillRect(renderer_, &rect);
|
SDL_RenderFillRect(renderer_, &rect);
|
||||||
}
|
}
|
||||||
@@ -166,11 +169,12 @@ void Fade::update()
|
|||||||
// Deja el renderizador como estaba
|
// Deja el renderizador como estaba
|
||||||
SDL_SetRenderTarget(renderer_, temp);
|
SDL_SetRenderTarget(renderer_, temp);
|
||||||
|
|
||||||
const auto h = counter_ / 3;
|
// Modifica el tamaño de los rectangulos
|
||||||
for (int i = 0; i < (int)square_.size(); ++i)
|
const auto h = counter_ / 2;
|
||||||
|
for (size_t i = 0; i < square_.size(); ++i)
|
||||||
{
|
{
|
||||||
// A partir del segundo rectangulo se pinta en función del anterior
|
// A partir del segundo rectangulo se pinta en función del anterior
|
||||||
square_[i].h = i == 0 ? h : std::max(square_[i - 1].h - 3, 0);
|
square_.at(i).h = i == 0 ? h : std::max(square_.at(i - 1).h - 2, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -251,12 +255,8 @@ void Fade::activate()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Limpia la textura
|
// Limpia la textura
|
||||||
auto temp = SDL_GetRenderTarget(renderer_);
|
|
||||||
SDL_SetRenderTarget(renderer_, backbuffer_);
|
|
||||||
a_ = mode_ == FadeMode::OUT ? 0 : 255;
|
a_ = mode_ == FadeMode::OUT ? 0 : 255;
|
||||||
SDL_SetRenderDrawColor(renderer_, r_, g_, b_, a_);
|
cleanBackbuffer(r_, g_, b_, a_);
|
||||||
SDL_RenderClear(renderer_);
|
|
||||||
SDL_SetRenderTarget(renderer_, temp);
|
|
||||||
|
|
||||||
// Deja el color listo para usar
|
// Deja el color listo para usar
|
||||||
a_ = mode_ == FadeMode::OUT ? 255 : 0;
|
a_ = mode_ == FadeMode::OUT ? 255 : 0;
|
||||||
@@ -266,12 +266,16 @@ void Fade::activate()
|
|||||||
|
|
||||||
case FadeType::VENETIAN:
|
case FadeType::VENETIAN:
|
||||||
{
|
{
|
||||||
cleanBackbuffer(0, 0, 0, 0);
|
// Limpia la textura
|
||||||
rect1_ = {0, 0, param.game.width, 0};
|
a_ = mode_ == FadeMode::OUT ? 0 : 255;
|
||||||
square_.clear();
|
cleanBackbuffer(r_, g_, b_, a_);
|
||||||
a_ = 255;
|
|
||||||
|
// Deja el color listo para usar
|
||||||
|
a_ = mode_ == FadeMode::OUT ? 255 : 0;
|
||||||
|
|
||||||
// Añade los cuadrados al vector
|
// Añade los cuadrados al vector
|
||||||
|
square_.clear();
|
||||||
|
rect1_ = {0, 0, param.game.width, 0};
|
||||||
const int max = param.game.height / param.fade.venetian_size;
|
const int max = param.game.height / param.fade.venetian_size;
|
||||||
|
|
||||||
for (int i = 0; i < max; ++i)
|
for (int i = 0; i < max; ++i)
|
||||||
@@ -285,31 +289,6 @@ void Fade::activate()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Comprueba si está activo
|
|
||||||
bool Fade::isEnabled() const
|
|
||||||
{
|
|
||||||
return enabled_;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Comprueba si ha terminado la transicion
|
|
||||||
bool Fade::hasEnded() const
|
|
||||||
{
|
|
||||||
// Ha terminado cuando ha finalizado la transición y se ha deshabilitado
|
|
||||||
return !enabled_ && finished_;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Establece el tipo de fade
|
|
||||||
void Fade::setType(FadeType type)
|
|
||||||
{
|
|
||||||
type_ = type;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Establece el modo de fade
|
|
||||||
void Fade::setMode(FadeMode mode)
|
|
||||||
{
|
|
||||||
mode_ = mode;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Establece el color del fade
|
// Establece el color del fade
|
||||||
void Fade::setColor(Uint8 r, Uint8 g, Uint8 b)
|
void Fade::setColor(Uint8 r, Uint8 g, Uint8 b)
|
||||||
{
|
{
|
||||||
@@ -318,12 +297,6 @@ void Fade::setColor(Uint8 r, Uint8 g, Uint8 b)
|
|||||||
b_ = b;
|
b_ = b;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Establece la duración posterior
|
|
||||||
void Fade::setPost(int value)
|
|
||||||
{
|
|
||||||
post_duration_ = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Limpia el backbuffer
|
// Limpia el backbuffer
|
||||||
void Fade::cleanBackbuffer(Uint8 r, Uint8 g, Uint8 b, Uint8 a)
|
void Fade::cleanBackbuffer(Uint8 r, Uint8 g, Uint8 b, Uint8 a)
|
||||||
{
|
{
|
||||||
@@ -337,4 +310,14 @@ void Fade::cleanBackbuffer(Uint8 r, Uint8 g, Uint8 b, Uint8 a)
|
|||||||
|
|
||||||
// Vuelve a dejar el renderizador como estaba
|
// Vuelve a dejar el renderizador como estaba
|
||||||
SDL_SetRenderTarget(renderer_, temp);
|
SDL_SetRenderTarget(renderer_, temp);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calcula el valor del estado del fade
|
||||||
|
int Fade::calculateValue(int min, int max, int current)
|
||||||
|
{
|
||||||
|
if (max == 0)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return std::clamp(current * 100 / max, 0, 100);
|
||||||
}
|
}
|
||||||
@@ -45,6 +45,7 @@ private:
|
|||||||
int fade_random_squares_mult_; // Cantidad de cuadrados que se pintaran cada vez
|
int fade_random_squares_mult_; // Cantidad de cuadrados que se pintaran cada vez
|
||||||
int post_duration_; // Duración posterior del fade tras finalizar
|
int post_duration_; // Duración posterior del fade tras finalizar
|
||||||
int post_counter_; // Contador para la duración posterior
|
int post_counter_; // Contador para la duración posterior
|
||||||
|
int value_ = 0; // Estado actual del fade entre 0 y 100
|
||||||
|
|
||||||
// Inicializa las variables
|
// Inicializa las variables
|
||||||
void init();
|
void init();
|
||||||
@@ -52,6 +53,9 @@ private:
|
|||||||
// Limpia el backbuffer
|
// Limpia el backbuffer
|
||||||
void cleanBackbuffer(Uint8 r, Uint8 g, Uint8 b, Uint8 a);
|
void cleanBackbuffer(Uint8 r, Uint8 g, Uint8 b, Uint8 a);
|
||||||
|
|
||||||
|
// Calcula el valor del estado del fade
|
||||||
|
int calculateValue(int min, int max, int current);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Constructor
|
// Constructor
|
||||||
Fade();
|
Fade();
|
||||||
@@ -71,21 +75,16 @@ public:
|
|||||||
// Activa el fade
|
// Activa el fade
|
||||||
void activate();
|
void activate();
|
||||||
|
|
||||||
// Comprueba si ha terminado la transicion
|
|
||||||
bool hasEnded() const;
|
|
||||||
|
|
||||||
// Comprueba si está activo
|
|
||||||
bool isEnabled() const;
|
|
||||||
|
|
||||||
// Establece el tipo de fade
|
|
||||||
void setType(FadeType type);
|
|
||||||
|
|
||||||
// Establece el modo de fade
|
|
||||||
void setMode(FadeMode mode);
|
|
||||||
|
|
||||||
// Establece el color del fade
|
// Establece el color del fade
|
||||||
void setColor(Uint8 r, Uint8 g, Uint8 b);
|
void setColor(Uint8 r, Uint8 g, Uint8 b);
|
||||||
|
|
||||||
// Establece la duración posterior
|
// Getters
|
||||||
void setPost(int value);
|
int getValue() const { return value_; }
|
||||||
|
bool isEnabled() const { return enabled_; }
|
||||||
|
bool hasEnded() const { return !enabled_ && finished_; }
|
||||||
|
|
||||||
|
// Setters
|
||||||
|
void setType(FadeType type) { type_ = type; }
|
||||||
|
void setMode(FadeMode mode) { mode_ = mode; }
|
||||||
|
void setPost(int value) { post_duration_ = value; }
|
||||||
};
|
};
|
||||||
207
source/game.cpp
207
source/game.cpp
@@ -14,6 +14,7 @@
|
|||||||
#include "balloon.h" // Para Balloon, BALLOON_SPEED
|
#include "balloon.h" // Para Balloon, BALLOON_SPEED
|
||||||
#include "balloon_manager.h" // Para BalloonManager
|
#include "balloon_manager.h" // Para BalloonManager
|
||||||
#include "bullet.h" // Para Bullet, BulletType, BulletMoveStatus
|
#include "bullet.h" // Para Bullet, BulletType, BulletMoveStatus
|
||||||
|
#include "enter_name.h" // Para NAME_LENGHT
|
||||||
#include "fade.h" // Para Fade, FadeType
|
#include "fade.h" // Para Fade, FadeType
|
||||||
#include "global_inputs.h" // Para check
|
#include "global_inputs.h" // Para check
|
||||||
#include "input.h" // Para InputType, Input, INPUT_DO_NOT_ALL...
|
#include "input.h" // Para InputType, Input, INPUT_DO_NOT_ALL...
|
||||||
@@ -30,9 +31,9 @@
|
|||||||
#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
|
||||||
#include "smart_sprite.h" // Para SmartSprite
|
#include "smart_sprite.h" // Para SmartSprite
|
||||||
#include "stage.h" // Para get, number, Stage, power
|
#include "stage.h" // Para number, get, Stage, power, total_p...
|
||||||
|
#include "tabe.h" // Para Tabe
|
||||||
#include "text.h" // Para Text
|
#include "text.h" // Para Text
|
||||||
#include "dbgtxt.h" // Para dbg_print
|
|
||||||
#include "texture.h" // Para Texture
|
#include "texture.h" // Para Texture
|
||||||
struct JA_Sound_t; // lines 37-37
|
struct JA_Sound_t; // lines 37-37
|
||||||
|
|
||||||
@@ -44,8 +45,10 @@ Game::Game(int player_id, int current_stage, bool demo)
|
|||||||
input_(Input::get()),
|
input_(Input::get()),
|
||||||
background_(std::make_unique<Background>()),
|
background_(std::make_unique<Background>()),
|
||||||
canvas_(SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, param.game.play_area.rect.w, param.game.play_area.rect.h)),
|
canvas_(SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, param.game.play_area.rect.w, param.game.play_area.rect.h)),
|
||||||
fade_(std::make_unique<Fade>()),
|
fade_in_(std::make_unique<Fade>()),
|
||||||
balloon_manager_(std::make_unique<BalloonManager>())
|
fade_out_(std::make_unique<Fade>()),
|
||||||
|
balloon_manager_(std::make_unique<BalloonManager>()),
|
||||||
|
tabe_(std::make_unique<Tabe>())
|
||||||
{
|
{
|
||||||
// Pasa variables
|
// Pasa variables
|
||||||
demo_.enabled = demo;
|
demo_.enabled = demo;
|
||||||
@@ -63,9 +66,15 @@ Game::Game(int player_id, int current_stage, bool demo)
|
|||||||
Scoreboard::init();
|
Scoreboard::init();
|
||||||
scoreboard_ = Scoreboard::get();
|
scoreboard_ = Scoreboard::get();
|
||||||
|
|
||||||
fade_->setColor(fade_color.r, fade_color.g, fade_color.b);
|
fade_in_->setColor(fade_color.r, fade_color.g, fade_color.b);
|
||||||
fade_->setPost(param.fade.post_duration);
|
fade_in_->setPost(0);
|
||||||
fade_->setType(FadeType::VENETIAN);
|
fade_in_->setType(FadeType::RANDOM_SQUARE);
|
||||||
|
fade_in_->setMode(FadeMode::IN);
|
||||||
|
fade_in_->activate();
|
||||||
|
|
||||||
|
fade_out_->setColor(fade_color.r, fade_color.g, fade_color.b);
|
||||||
|
fade_out_->setPost(param.fade.post_duration);
|
||||||
|
fade_out_->setType(FadeType::VENETIAN);
|
||||||
|
|
||||||
background_->setPos(param.game.play_area.rect);
|
background_->setPos(param.game.play_area.rect);
|
||||||
|
|
||||||
@@ -87,24 +96,25 @@ Game::Game(int player_id, int current_stage, bool demo)
|
|||||||
Stage::total_power += Stage::get(i).power_to_complete;
|
Stage::total_power += Stage::get(i).power_to_complete;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Crea los primeros globos y el mensaje de inicio
|
|
||||||
if (!demo_.enabled)
|
|
||||||
{
|
|
||||||
balloon_manager_->createTwoBigBalloons();
|
|
||||||
evaluateAndSetMenace();
|
|
||||||
createMessage({paths_.at(0), paths_.at(1)}, Resource::get()->getTexture("get_ready"));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Game::~Game()
|
Game::~Game()
|
||||||
{
|
{
|
||||||
// Guarda las puntuaciones en un fichero
|
// MODO DEMO
|
||||||
if (!demo_.enabled)
|
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);
|
auto manager = std::make_unique<ManageHiScoreTable>(options.game.hi_score_table);
|
||||||
manager->saveToFile(asset_->get("score.bin"));
|
manager->saveToFile(asset_->get("score.bin"));
|
||||||
|
section::attract_mode = section::AttractMode::TITLE_TO_DEMO;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef RECORDING
|
#ifdef RECORDING
|
||||||
saveDemoFile(Asset::get()->get("demo1.bin"), demo_.data.at(0));
|
saveDemoFile(Asset::get()->get("demo1.bin"), demo_.data.at(0));
|
||||||
#endif
|
#endif
|
||||||
@@ -213,8 +223,8 @@ void Game::updatePlayers()
|
|||||||
|
|
||||||
if (demo_.enabled && allPlayersAreNotPlaying())
|
if (demo_.enabled && allPlayersAreNotPlaying())
|
||||||
{
|
{
|
||||||
fade_->setType(FadeType::RANDOM_SQUARE);
|
fade_out_->setType(FadeType::RANDOM_SQUARE);
|
||||||
fade_->activate();
|
fade_out_->activate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -253,7 +263,7 @@ void Game::updateStage()
|
|||||||
++Stage::number;
|
++Stage::number;
|
||||||
JA_PlaySound(Resource::get()->getSound("stage_change.wav"));
|
JA_PlaySound(Resource::get()->getSound("stage_change.wav"));
|
||||||
balloon_manager_->resetBalloonSpeed();
|
balloon_manager_->resetBalloonSpeed();
|
||||||
screen_->flash(flash_color, 100);
|
screen_->flash(flash_color, 3);
|
||||||
screen_->shake();
|
screen_->shake();
|
||||||
|
|
||||||
// Escribe el texto por pantalla
|
// Escribe el texto por pantalla
|
||||||
@@ -262,7 +272,7 @@ void Game::updateStage()
|
|||||||
std::vector<Path> paths = {paths_.at(2), paths_.at(3)};
|
std::vector<Path> paths = {paths_.at(2), paths_.at(3)};
|
||||||
if (Stage::number == 9)
|
if (Stage::number == 9)
|
||||||
{
|
{
|
||||||
createMessage(paths, Resource::get()->getTexture("last_stage"));
|
createMessage(paths, Resource::get()->getTexture("game_text_last_stage"));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -275,6 +285,27 @@ void Game::updateStage()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Actualiza el estado de fade in
|
||||||
|
void Game::updateFadeInState()
|
||||||
|
{
|
||||||
|
if (state_ == GameState::FADE_IN)
|
||||||
|
{
|
||||||
|
if (fade_in_->hasEnded())
|
||||||
|
{
|
||||||
|
state_ = GameState::PLAYING;
|
||||||
|
|
||||||
|
// Crea los primeros globos y el mensaje de inicio
|
||||||
|
if (!demo_.enabled)
|
||||||
|
{
|
||||||
|
balloon_manager_->createTwoBigBalloons();
|
||||||
|
evaluateAndSetMenace();
|
||||||
|
createMessage({paths_.at(0), paths_.at(1)}, Resource::get()->getTexture("game_text_get_ready"));
|
||||||
|
JA_PlaySound(Resource::get()->getSound("voice_get_ready.wav"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Actualiza el estado de fin de la partida
|
// Actualiza el estado de fin de la partida
|
||||||
void Game::updateGameOverState()
|
void Game::updateGameOverState()
|
||||||
{
|
{
|
||||||
@@ -283,27 +314,32 @@ void Game::updateGameOverState()
|
|||||||
if (game_over_counter_ > 0)
|
if (game_over_counter_ > 0)
|
||||||
{
|
{
|
||||||
if (game_over_counter_ == GAME_OVER_COUNTER_)
|
if (game_over_counter_ == GAME_OVER_COUNTER_)
|
||||||
createMessage({paths_.at(2), paths_.at(3)}, Resource::get()->getTexture("game_over"));
|
{
|
||||||
|
createMessage({paths_.at(2), paths_.at(3)}, Resource::get()->getTexture("game_text_game_over"));
|
||||||
|
JA_FadeOutMusic(1000);
|
||||||
|
balloon_manager_->setSounds(true);
|
||||||
|
}
|
||||||
|
|
||||||
game_over_counter_--;
|
game_over_counter_--;
|
||||||
|
|
||||||
if ((game_over_counter_ == 250) || (game_over_counter_ == 200) || (game_over_counter_ == 180) || (game_over_counter_ == 120) || (game_over_counter_ == 60))
|
|
||||||
{
|
|
||||||
// Hace sonar aleatoriamente uno de los 4 sonidos de burbujas
|
|
||||||
const auto index = rand() % 4;
|
|
||||||
JA_Sound_t *sound[4] = {Resource::get()->getSound("bubble1.wav"), Resource::get()->getSound("bubble2.wav"), Resource::get()->getSound("bubble3.wav"), Resource::get()->getSound("bubble4.wav")};
|
|
||||||
JA_PlaySound(sound[index], 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (game_over_counter_ == 150)
|
if (game_over_counter_ == 150)
|
||||||
{
|
{
|
||||||
fade_->activate();
|
fade_out_->activate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fade_->hasEnded())
|
if (fade_out_->hasEnded())
|
||||||
{
|
{
|
||||||
section::name = section::Name::HI_SCORE_TABLE;
|
if (game_completed_counter_ > 0)
|
||||||
|
{
|
||||||
|
// Los jugadores han completado el juego
|
||||||
|
section::name = section::Name::CREDITS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// La partida ha terminado con la derrota de los jugadores
|
||||||
|
section::name = section::Name::HI_SCORE_TABLE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -327,8 +363,8 @@ void Game::updateCompletedState()
|
|||||||
// Muestra el mensaje de felicitación y da los puntos a los jugadores
|
// Muestra el mensaje de felicitación y da los puntos a los jugadores
|
||||||
if (game_completed_counter_ == 200)
|
if (game_completed_counter_ == 200)
|
||||||
{
|
{
|
||||||
createMessage({paths_.at(4), paths_.at(5)}, Resource::get()->getTexture("congratulations"));
|
createMessage({paths_.at(4), paths_.at(5)}, Resource::get()->getTexture("game_text_congratulations"));
|
||||||
createMessage({paths_.at(6), paths_.at(7)}, Resource::get()->getTexture("1000000_points"));
|
createMessage({paths_.at(6), paths_.at(7)}, Resource::get()->getTexture("game_text_1000000_points"));
|
||||||
|
|
||||||
for (auto &player : players_)
|
for (auto &player : players_)
|
||||||
if (player->isPlaying())
|
if (player->isPlaying())
|
||||||
@@ -465,6 +501,7 @@ void Game::checkPlayerItemCollision(std::shared_ptr<Player> &player)
|
|||||||
(item->getWidth() - game_text_textures_[4]->getWidth()) / 2;
|
(item->getWidth() - game_text_textures_[4]->getWidth()) / 2;
|
||||||
createItemText(x, game_text_textures_[4]);
|
createItemText(x, game_text_textures_[4]);
|
||||||
}
|
}
|
||||||
|
JA_PlaySound(Resource::get()->getSound("voice_coffee.wav"));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ItemType::COFFEE_MACHINE:
|
case ItemType::COFFEE_MACHINE:
|
||||||
@@ -475,6 +512,7 @@ void Game::checkPlayerItemCollision(std::shared_ptr<Player> &player)
|
|||||||
item->getPosX() +
|
item->getPosX() +
|
||||||
(item->getWidth() - game_text_textures_[3]->getWidth()) / 2;
|
(item->getWidth() - game_text_textures_[3]->getWidth()) / 2;
|
||||||
createItemText(x, game_text_textures_[3]);
|
createItemText(x, game_text_textures_[3]);
|
||||||
|
JA_PlaySound(Resource::get()->getSound("voice_power_up.wav"));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@@ -713,7 +751,9 @@ void Game::createMessage(const std::vector<Path> &paths, std::shared_ptr<Texture
|
|||||||
|
|
||||||
// Inicializa
|
// Inicializa
|
||||||
for (const auto &path : paths)
|
for (const auto &path : paths)
|
||||||
|
{
|
||||||
path_sprites_.back()->addPath(path, true);
|
path_sprites_.back()->addPath(path, true);
|
||||||
|
}
|
||||||
path_sprites_.back()->enable();
|
path_sprites_.back()->enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -806,13 +846,12 @@ void Game::killPlayer(std::shared_ptr<Player> &player)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Si no tiene cafes, muere
|
// Si no tiene cafes, muere
|
||||||
pauseMusic();
|
// pauseMusic();
|
||||||
balloon_manager_->stopAllBalloons();
|
balloon_manager_->stopAllBalloons();
|
||||||
JA_PlaySound(Resource::get()->getSound("player_collision.wav"));
|
JA_PlaySound(Resource::get()->getSound("player_collision.wav"));
|
||||||
screen_->shake();
|
screen_->shake();
|
||||||
JA_PlaySound(Resource::get()->getSound("coffeeout.wav"));
|
JA_PlaySound(Resource::get()->getSound("voice_no.wav"));
|
||||||
player->setPlayingState(PlayerState::DYING);
|
player->setPlayingState(PlayerState::DYING);
|
||||||
allPlayersAreNotPlaying() ? stopMusic() : resumeMusic();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -860,6 +899,7 @@ void Game::update()
|
|||||||
|
|
||||||
checkMusicStatus();
|
checkMusicStatus();
|
||||||
screen_->update();
|
screen_->update();
|
||||||
|
globalInputs::update();
|
||||||
fillCanvas();
|
fillCanvas();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -902,11 +942,10 @@ void Game::fillCanvas()
|
|||||||
renderItems();
|
renderItems();
|
||||||
renderSmartSprites();
|
renderSmartSprites();
|
||||||
balloon_manager_->render();
|
balloon_manager_->render();
|
||||||
|
tabe_->render();
|
||||||
renderBullets();
|
renderBullets();
|
||||||
renderPathSprites();
|
renderPathSprites();
|
||||||
renderPlayers();
|
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
|
// Deja el renderizador apuntando donde estaba
|
||||||
SDL_SetRenderTarget(renderer_, temp);
|
SDL_SetRenderTarget(renderer_, temp);
|
||||||
@@ -925,7 +964,8 @@ void Game::render()
|
|||||||
scoreboard_->render();
|
scoreboard_->render();
|
||||||
|
|
||||||
// Dibuja el fade
|
// Dibuja el fade
|
||||||
fade_->render();
|
fade_in_->render();
|
||||||
|
fade_out_->render();
|
||||||
|
|
||||||
// Vuelca el contenido del renderizador en pantalla
|
// Vuelca el contenido del renderizador en pantalla
|
||||||
screen_->blit();
|
screen_->blit();
|
||||||
@@ -950,11 +990,11 @@ void Game::disableTimeStopItem()
|
|||||||
// Comprueba si la música ha de estar sonando
|
// Comprueba si la música ha de estar sonando
|
||||||
void Game::checkMusicStatus()
|
void Game::checkMusicStatus()
|
||||||
{
|
{
|
||||||
// Si la música no está sonando
|
// Si se ha completado el juego o los jugadores han terminado, detiene la música
|
||||||
if (JA_GetMusicState() == JA_MUSIC_INVALID ||
|
if (state_ != GameState::COMPLETED && !allPlayersAreGameOver())
|
||||||
JA_GetMusicState() == JA_MUSIC_STOPPED)
|
{
|
||||||
// Si se ha completado el juego o los jugadores han terminado, detiene la música
|
playMusic();
|
||||||
state_ == GameState::COMPLETED || allPlayersAreGameOver() ? JA_StopMusic() : JA_PlayMusic(Resource::get()->getMusic("playing.ogg"));
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bucle para el juego
|
// Bucle para el juego
|
||||||
@@ -979,7 +1019,7 @@ void Game::initPaths()
|
|||||||
{
|
{
|
||||||
// Recorrido para el texto de "Get Ready!" (0,1)
|
// 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 auto w = texture->getWidth();
|
||||||
const int x0 = -w;
|
const int x0 = -w;
|
||||||
const int x1 = param.game.play_area.center_x - w / 2;
|
const int x1 = param.game.play_area.center_x - w / 2;
|
||||||
@@ -989,10 +1029,9 @@ void Game::initPaths()
|
|||||||
paths_.emplace_back(Path(createPath(x1, x2, PathType::HORIZONTAL, y, 80, easeInQuint), 0));
|
paths_.emplace_back(Path(createPath(x1, x2, PathType::HORIZONTAL, y, 80, easeInQuint), 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recorrido para el texto de "Last Stage!" o de "X stages left" o "Game Over"
|
// Recorrido para el texto de "Last Stage!" o de "X stages left" o "Game Over" (2,3)
|
||||||
// (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 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 = param.game.play_area.center_y - h / 2;
|
const int y1 = param.game.play_area.center_y - h / 2;
|
||||||
@@ -1004,7 +1043,7 @@ void Game::initPaths()
|
|||||||
|
|
||||||
// Recorrido para el texto de "Congratulations!!" (3,4)
|
// 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 w = texture->getWidth();
|
||||||
const auto h = texture->getHeight();
|
const auto h = texture->getHeight();
|
||||||
const int x0 = -w;
|
const int x0 = -w;
|
||||||
@@ -1017,7 +1056,7 @@ void Game::initPaths()
|
|||||||
|
|
||||||
// Recorrido para el texto de "1.000.000 points!" (5,6)
|
// 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 w = texture->getWidth();
|
||||||
const auto h = texture->getHeight();
|
const auto h = texture->getHeight();
|
||||||
const int x0 = param.game.play_area.rect.w;
|
const int x0 = param.game.play_area.rect.w;
|
||||||
@@ -1155,18 +1194,23 @@ void Game::checkEvents()
|
|||||||
}
|
}
|
||||||
case SDLK_6: // Crea un mensaje
|
case SDLK_6: // Crea un mensaje
|
||||||
{
|
{
|
||||||
createMessage({paths_.at(4), paths_.at(5)}, Resource::get()->getTexture("congratulations"));
|
createMessage({paths_.at(2), paths_.at(3)}, Resource::get()->getTexture("game_text_congratulations"));
|
||||||
createMessage({paths_.at(6), paths_.at(7)}, Resource::get()->getTexture("1000000_points"));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SDLK_7: // Flash
|
case SDLK_7: // Flash
|
||||||
{
|
{
|
||||||
screen_->flash(flash_color, 100);
|
screen_->flash(flash_color, 3);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SDLK_8:
|
case SDLK_8:
|
||||||
{
|
{
|
||||||
players_.at(0)->setPlayingState(PlayerState::LEAVING_SCREEN);
|
players_.at(0)->setPlayingState(PlayerState::LEAVING_SCREEN);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SDLK_9:
|
||||||
|
{
|
||||||
|
tabe_->enable();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@@ -1333,7 +1377,8 @@ void Game::handleDemoMode()
|
|||||||
|
|
||||||
if (input_->checkAnyButtonPressed())
|
if (input_->checkAnyButtonPressed())
|
||||||
{
|
{
|
||||||
section::name = section::Name::TITLE; // Salir del modo demo y regresar al menú principal.
|
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;
|
return;
|
||||||
}
|
}
|
||||||
++index;
|
++index;
|
||||||
@@ -1682,6 +1727,16 @@ void Game::resumeMusic()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Hace sonar la música
|
||||||
|
void Game::playMusic()
|
||||||
|
{
|
||||||
|
// Si la música no está sonando
|
||||||
|
if (JA_GetMusicState() == JA_MUSIC_INVALID || JA_GetMusicState() == JA_MUSIC_STOPPED)
|
||||||
|
{
|
||||||
|
JA_PlayMusic(Resource::get()->getMusic("playing.ogg"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Detiene la música
|
// Detiene la música
|
||||||
void Game::stopMusic()
|
void Game::stopMusic()
|
||||||
{
|
{
|
||||||
@@ -1703,12 +1758,12 @@ void Game::updateDemo()
|
|||||||
// Activa el fundido antes de acabar con los datos de la demo
|
// Activa el fundido antes de acabar con los datos de la demo
|
||||||
if (demo_.counter == TOTAL_DEMO_DATA - 200)
|
if (demo_.counter == TOTAL_DEMO_DATA - 200)
|
||||||
{
|
{
|
||||||
fade_->setType(FadeType::RANDOM_SQUARE);
|
fade_out_->setType(FadeType::RANDOM_SQUARE);
|
||||||
fade_->activate();
|
fade_out_->activate();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Si ha terminado el fundido, cambia de sección
|
// Si ha terminado el fundido, cambia de sección
|
||||||
if (fade_->hasEnded())
|
if (fade_out_->hasEnded())
|
||||||
{
|
{
|
||||||
section::name = section::Name::HI_SCORE_TABLE;
|
section::name = section::Name::HI_SCORE_TABLE;
|
||||||
return;
|
return;
|
||||||
@@ -1747,15 +1802,18 @@ void Game::updateGame()
|
|||||||
Stage::addPower(5);
|
Stage::addPower(5);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
fade_->update();
|
fade_in_->update();
|
||||||
|
fade_out_->update();
|
||||||
updatePlayers();
|
updatePlayers();
|
||||||
checkPlayersStatusPlaying();
|
checkPlayersStatusPlaying();
|
||||||
updateScoreboard();
|
updateScoreboard();
|
||||||
updateBackground();
|
updateBackground();
|
||||||
balloon_manager_->update();
|
balloon_manager_->update();
|
||||||
|
tabe_->update();
|
||||||
moveBullets();
|
moveBullets();
|
||||||
updateItems();
|
updateItems();
|
||||||
updateStage();
|
updateStage();
|
||||||
|
updateFadeInState();
|
||||||
updateGameOverState();
|
updateGameOverState();
|
||||||
updateCompletedState();
|
updateCompletedState();
|
||||||
updateSmartSprites();
|
updateSmartSprites();
|
||||||
@@ -1783,21 +1841,24 @@ void Game::cleanVectors()
|
|||||||
// Gestiona el nivel de amenaza
|
// Gestiona el nivel de amenaza
|
||||||
void Game::updateMenace()
|
void Game::updateMenace()
|
||||||
{
|
{
|
||||||
const auto stage = Stage::get(Stage::number);
|
if (state_ == GameState::PLAYING)
|
||||||
const float percent = Stage::power / stage.power_to_complete;
|
|
||||||
const int difference = stage.max_menace - stage.min_menace;
|
|
||||||
|
|
||||||
// Aumenta el nivel de amenaza en función de la puntuación
|
|
||||||
menace_threshold_ = stage.min_menace + (difference * percent);
|
|
||||||
|
|
||||||
// Si el nivel de amenza es inferior al umbral
|
|
||||||
if (menace_current_ < menace_threshold_)
|
|
||||||
{
|
{
|
||||||
// Crea una formación de enemigos
|
const auto stage = Stage::get(Stage::number);
|
||||||
balloon_manager_->deployBalloonFormation(Stage::number);
|
const float percent = Stage::power / stage.power_to_complete;
|
||||||
|
const int difference = stage.max_menace - stage.min_menace;
|
||||||
|
|
||||||
// Recalcula el nivel de amenaza con el nuevo globo
|
// Aumenta el nivel de amenaza en función de la puntuación
|
||||||
evaluateAndSetMenace();
|
menace_threshold_ = stage.min_menace + (difference * percent);
|
||||||
|
|
||||||
|
// Si el nivel de amenza es inferior al umbral
|
||||||
|
if (menace_current_ < menace_threshold_)
|
||||||
|
{
|
||||||
|
// Crea una formación de enemigos
|
||||||
|
balloon_manager_->deployBalloonFormation(Stage::number);
|
||||||
|
|
||||||
|
// Recalcula el nivel de amenaza con el nuevo globo
|
||||||
|
evaluateAndSetMenace();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
class Asset; // lines 13-13
|
class Asset; // lines 13-13
|
||||||
class Background; // lines 14-14
|
class Background; // lines 14-14
|
||||||
class BalloonManager;
|
class BalloonManager;
|
||||||
|
class Tabe;
|
||||||
class Bullet; // lines 15-15
|
class Bullet; // lines 15-15
|
||||||
class Fade; // lines 16-16
|
class Fade; // lines 16-16
|
||||||
class Input; // lines 17-17
|
class Input; // lines 17-17
|
||||||
@@ -65,6 +66,7 @@ private:
|
|||||||
// Enum
|
// Enum
|
||||||
enum class GameState
|
enum class GameState
|
||||||
{
|
{
|
||||||
|
FADE_IN,
|
||||||
PLAYING,
|
PLAYING,
|
||||||
COMPLETED,
|
COMPLETED,
|
||||||
GAME_OVER,
|
GAME_OVER,
|
||||||
@@ -140,8 +142,10 @@ private:
|
|||||||
std::vector<std::vector<std::string>> item_animations_; // Vector con las animaciones de los items
|
std::vector<std::vector<std::string>> item_animations_; // Vector con las animaciones de los items
|
||||||
std::vector<std::vector<std::string>> player_animations_; // Vector con las animaciones del jugador
|
std::vector<std::vector<std::string>> player_animations_; // Vector con las animaciones del jugador
|
||||||
|
|
||||||
std::unique_ptr<Fade> fade_; // Objeto para renderizar fades
|
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<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
|
std::vector<Path> paths_; // Vector con los recorridos precalculados almacenados
|
||||||
|
|
||||||
// Variables
|
// Variables
|
||||||
@@ -164,7 +168,7 @@ private:
|
|||||||
int total_power_to_complete_game_; // La suma del poder necesario para completar todas las fases
|
int total_power_to_complete_game_; // La suma del poder necesario para completar todas las fases
|
||||||
int menace_current_ = 0; // Nivel de amenaza actual
|
int menace_current_ = 0; // Nivel de amenaza actual
|
||||||
int menace_threshold_ = 0; // Umbral del nivel de amenaza. Si el nivel de amenaza cae por debajo del umbral, se generan más globos. Si el umbral aumenta, aumenta el número de globos
|
int menace_threshold_ = 0; // Umbral del nivel de amenaza. Si el nivel de amenaza cae por debajo del umbral, se generan más globos. Si el umbral aumenta, aumenta el número de globos
|
||||||
GameState state_ = GameState::PLAYING; // Estado
|
GameState state_ = GameState::FADE_IN; // Estado
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
bool auto_pop_balloons_ = false; // Si es true, incrementa automaticamente los globos explotados
|
bool auto_pop_balloons_ = false; // Si es true, incrementa automaticamente los globos explotados
|
||||||
#endif
|
#endif
|
||||||
@@ -193,6 +197,9 @@ private:
|
|||||||
// Comprueba si hay cambio de fase y actualiza las variables
|
// Comprueba si hay cambio de fase y actualiza las variables
|
||||||
void updateStage();
|
void updateStage();
|
||||||
|
|
||||||
|
// Actualiza el estado de fade in
|
||||||
|
void updateFadeInState();
|
||||||
|
|
||||||
// Actualiza el estado de fin de la partida
|
// Actualiza el estado de fin de la partida
|
||||||
void updateGameOverState();
|
void updateGameOverState();
|
||||||
|
|
||||||
@@ -373,6 +380,9 @@ private:
|
|||||||
// Reanuda la música
|
// Reanuda la música
|
||||||
void resumeMusic();
|
void resumeMusic();
|
||||||
|
|
||||||
|
// Hace sonar la música
|
||||||
|
void playMusic();
|
||||||
|
|
||||||
// Detiene la música
|
// Detiene la música
|
||||||
void stopMusic();
|
void stopMusic();
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#include "game_logo.h"
|
#include "game_logo.h"
|
||||||
|
#include <SDL2/SDL.h>
|
||||||
#include <SDL2/SDL_render.h> // Para SDL_FLIP_HORIZONTAL
|
#include <SDL2/SDL_render.h> // Para SDL_FLIP_HORIZONTAL
|
||||||
#include <algorithm> // Para max
|
#include <algorithm> // Para max
|
||||||
#include "animated_sprite.h" // Para AnimatedSprite
|
#include "animated_sprite.h" // Para AnimatedSprite
|
||||||
@@ -8,6 +9,11 @@
|
|||||||
#include "smart_sprite.h" // Para SmartSprite
|
#include "smart_sprite.h" // Para SmartSprite
|
||||||
#include "sprite.h" // Para Sprite
|
#include "sprite.h" // Para Sprite
|
||||||
#include "texture.h" // Para Texture
|
#include "texture.h" // Para Texture
|
||||||
|
#include "screen.h"
|
||||||
|
|
||||||
|
constexpr int ZOOM_FACTOR = 5;
|
||||||
|
constexpr int FLASH_DELAY = 3;
|
||||||
|
constexpr int FLASH_LENGHT = FLASH_DELAY + 3;
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
GameLogo::GameLogo(int x, int y)
|
GameLogo::GameLogo(int x, int y)
|
||||||
@@ -15,36 +21,25 @@ GameLogo::GameLogo(int x, int y)
|
|||||||
coffee_texture_(Resource::get()->getTexture("title_coffee.png")),
|
coffee_texture_(Resource::get()->getTexture("title_coffee.png")),
|
||||||
crisis_texture_(Resource::get()->getTexture("title_crisis.png")),
|
crisis_texture_(Resource::get()->getTexture("title_crisis.png")),
|
||||||
arcade_edition_texture_(Resource::get()->getTexture("title_arcade_edition.png")),
|
arcade_edition_texture_(Resource::get()->getTexture("title_arcade_edition.png")),
|
||||||
|
|
||||||
dust_left_sprite_(std::make_unique<AnimatedSprite>(dust_texture_, Resource::get()->getAnimation("title_dust.ani"))),
|
dust_left_sprite_(std::make_unique<AnimatedSprite>(dust_texture_, Resource::get()->getAnimation("title_dust.ani"))),
|
||||||
dust_right_sprite_(std::make_unique<AnimatedSprite>(dust_texture_, Resource::get()->getAnimation("title_dust.ani"))),
|
dust_right_sprite_(std::make_unique<AnimatedSprite>(dust_texture_, Resource::get()->getAnimation("title_dust.ani"))),
|
||||||
|
|
||||||
coffee_sprite_(std::make_unique<SmartSprite>(coffee_texture_)),
|
coffee_sprite_(std::make_unique<SmartSprite>(coffee_texture_)),
|
||||||
crisis_sprite_(std::make_unique<SmartSprite>(crisis_texture_)),
|
crisis_sprite_(std::make_unique<SmartSprite>(crisis_texture_)),
|
||||||
|
|
||||||
arcade_edition_sprite_(std::make_unique<Sprite>(arcade_edition_texture_, (param.game.width - arcade_edition_texture_->getWidth()) / 2, param.title.arcade_edition_position, arcade_edition_texture_->getWidth(), arcade_edition_texture_->getHeight())),
|
arcade_edition_sprite_(std::make_unique<Sprite>(arcade_edition_texture_, (param.game.width - arcade_edition_texture_->getWidth()) / 2, param.title.arcade_edition_position, arcade_edition_texture_->getWidth(), arcade_edition_texture_->getHeight())),
|
||||||
|
|
||||||
x_(x),
|
x_(x),
|
||||||
y_(y)
|
y_(y) {}
|
||||||
{
|
|
||||||
// Inicializa las variables
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Inicializa las variables
|
// Inicializa las variables
|
||||||
void GameLogo::init()
|
void GameLogo::init()
|
||||||
{
|
{
|
||||||
const auto xp = x_ - coffee_sprite_->getWidth() / 2;
|
const auto xp = x_ - coffee_texture_->getWidth() / 2;
|
||||||
const auto desp = getInitialVerticalDesp();
|
const auto desp = getInitialVerticalDesp();
|
||||||
|
|
||||||
// Variables
|
// Variables
|
||||||
status_ = Status::DISABLED;
|
coffee_crisis_status_ = Status::DISABLED;
|
||||||
shake_.desp = 1;
|
arcade_edition_status_ = Status::DISABLED;
|
||||||
shake_.delay = 2;
|
shake_.init(1, 2, 8, xp);
|
||||||
shake_.lenght = 8;
|
zoom_ = 3.0f * ZOOM_FACTOR;
|
||||||
shake_.remaining = shake_.lenght;
|
|
||||||
shake_.counter = shake_.delay;
|
|
||||||
shake_.origin = xp;
|
|
||||||
|
|
||||||
// Inicializa el bitmap de 'Coffee'
|
// Inicializa el bitmap de 'Coffee'
|
||||||
coffee_sprite_->setPosX(xp);
|
coffee_sprite_->setPosX(xp);
|
||||||
@@ -90,6 +85,9 @@ void GameLogo::init()
|
|||||||
dust_left_sprite_->setPosY(y_);
|
dust_left_sprite_->setPosY(y_);
|
||||||
dust_left_sprite_->setWidth(16);
|
dust_left_sprite_->setWidth(16);
|
||||||
dust_left_sprite_->setHeight(16);
|
dust_left_sprite_->setHeight(16);
|
||||||
|
|
||||||
|
// Inicializa el bitmap de 'Arcade Edition'
|
||||||
|
arcade_edition_sprite_->setZoom(zoom_);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pinta la clase en pantalla
|
// Pinta la clase en pantalla
|
||||||
@@ -99,8 +97,10 @@ void GameLogo::render()
|
|||||||
coffee_sprite_->render();
|
coffee_sprite_->render();
|
||||||
crisis_sprite_->render();
|
crisis_sprite_->render();
|
||||||
|
|
||||||
if (status_ == Status::FINISHED)
|
if (arcade_edition_status_ != Status::DISABLED)
|
||||||
|
{
|
||||||
arcade_edition_sprite_->render();
|
arcade_edition_sprite_->render();
|
||||||
|
}
|
||||||
|
|
||||||
// Dibuja el polvillo del logo
|
// Dibuja el polvillo del logo
|
||||||
dust_right_sprite_->render();
|
dust_right_sprite_->render();
|
||||||
@@ -110,20 +110,22 @@ void GameLogo::render()
|
|||||||
// Actualiza la lógica de la clase
|
// Actualiza la lógica de la clase
|
||||||
void GameLogo::update()
|
void GameLogo::update()
|
||||||
{
|
{
|
||||||
switch (status_)
|
switch (coffee_crisis_status_)
|
||||||
{
|
{
|
||||||
case Status::MOVING:
|
case Status::MOVING:
|
||||||
{
|
{
|
||||||
coffee_sprite_->update();
|
coffee_sprite_->update();
|
||||||
crisis_sprite_->update();
|
crisis_sprite_->update();
|
||||||
|
|
||||||
// Si los objetos han llegado a su destino, cambiamos de Sección
|
// Si los objetos han llegado a su destino, cambia el estado
|
||||||
if (coffee_sprite_->hasFinished() && crisis_sprite_->hasFinished())
|
if (coffee_sprite_->hasFinished() && crisis_sprite_->hasFinished())
|
||||||
{
|
{
|
||||||
status_ = Status::SHAKING;
|
coffee_crisis_status_ = Status::SHAKING;
|
||||||
|
|
||||||
// Reproduce el efecto sonoro
|
// Reproduce el efecto sonoro
|
||||||
JA_PlaySound(Resource::get()->getSound("title.wav"));
|
JA_PlaySound(Resource::get()->getSound("title.wav"));
|
||||||
|
Screen::get()->flash(Color(0xFF, 0xFF, 0xFF), FLASH_LENGHT, FLASH_DELAY);
|
||||||
|
Screen::get()->shake();
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -131,7 +133,7 @@ void GameLogo::update()
|
|||||||
|
|
||||||
case Status::SHAKING:
|
case Status::SHAKING:
|
||||||
{
|
{
|
||||||
// Agita el logo
|
// Agita "COFFEE CRISIS"
|
||||||
if (shake_.remaining > 0)
|
if (shake_.remaining > 0)
|
||||||
{
|
{
|
||||||
if (shake_.counter > 0)
|
if (shake_.counter > 0)
|
||||||
@@ -151,7 +153,8 @@ void GameLogo::update()
|
|||||||
{
|
{
|
||||||
coffee_sprite_->setPosX(shake_.origin);
|
coffee_sprite_->setPosX(shake_.origin);
|
||||||
crisis_sprite_->setPosX(shake_.origin + 15);
|
crisis_sprite_->setPosX(shake_.origin + 15);
|
||||||
status_ = Status::FINISHED;
|
coffee_crisis_status_ = Status::FINISHED;
|
||||||
|
arcade_edition_status_ = Status::MOVING;
|
||||||
}
|
}
|
||||||
|
|
||||||
dust_right_sprite_->update();
|
dust_right_sprite_->update();
|
||||||
@@ -171,19 +174,74 @@ void GameLogo::update()
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch (arcade_edition_status_)
|
||||||
|
{
|
||||||
|
case Status::MOVING:
|
||||||
|
{
|
||||||
|
zoom_ -= 0.1f * ZOOM_FACTOR;
|
||||||
|
arcade_edition_sprite_->setZoom(zoom_);
|
||||||
|
if (zoom_ <= 1.0f)
|
||||||
|
{
|
||||||
|
arcade_edition_status_ = Status::SHAKING;
|
||||||
|
zoom_ = 1.0f;
|
||||||
|
arcade_edition_sprite_->setZoom(zoom_);
|
||||||
|
shake_.init(1, 2, 8, arcade_edition_sprite_->getX());
|
||||||
|
JA_PlaySound(Resource::get()->getSound("title.wav"));
|
||||||
|
Screen::get()->flash(Color(0xFF, 0xFF, 0xFF), FLASH_LENGHT, FLASH_DELAY);
|
||||||
|
Screen::get()->shake();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case Status::SHAKING:
|
||||||
|
{
|
||||||
|
// Agita "ARCADE EDITION"
|
||||||
|
if (shake_.remaining > 0)
|
||||||
|
{
|
||||||
|
if (shake_.counter > 0)
|
||||||
|
{
|
||||||
|
shake_.counter--;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
shake_.counter = shake_.delay;
|
||||||
|
const auto desp = shake_.remaining % 2 == 0 ? shake_.desp * (-1) : shake_.desp;
|
||||||
|
arcade_edition_sprite_->setX(shake_.origin + desp);
|
||||||
|
shake_.remaining--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
arcade_edition_sprite_->setX(shake_.origin);
|
||||||
|
arcade_edition_status_ = Status::FINISHED;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (coffee_crisis_status_ == Status::FINISHED &&
|
||||||
|
arcade_edition_status_ == Status::FINISHED &&
|
||||||
|
post_finished_counter_ > 0)
|
||||||
|
{
|
||||||
|
--post_finished_counter_;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Activa la clase
|
// Activa la clase
|
||||||
void GameLogo::enable()
|
void GameLogo::enable()
|
||||||
{
|
{
|
||||||
init();
|
init();
|
||||||
status_ = Status::MOVING;
|
coffee_crisis_status_ = Status::MOVING;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Indica si ha terminado la animación
|
// Indica si ha terminado la animación
|
||||||
bool GameLogo::hasFinished() const
|
bool GameLogo::hasFinished() const
|
||||||
{
|
{
|
||||||
return status_ == Status::FINISHED;
|
return post_finished_counter_ == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recarga las texturas
|
// Recarga las texturas
|
||||||
@@ -192,6 +250,7 @@ void GameLogo::reLoad()
|
|||||||
dust_texture_->reLoad();
|
dust_texture_->reLoad();
|
||||||
coffee_texture_->reLoad();
|
coffee_texture_->reLoad();
|
||||||
crisis_texture_->reLoad();
|
crisis_texture_->reLoad();
|
||||||
|
arcade_edition_texture_->reLoad();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calcula el desplazamiento vertical inicial
|
// Calcula el desplazamiento vertical inicial
|
||||||
|
|||||||
@@ -20,12 +20,30 @@ private:
|
|||||||
|
|
||||||
struct Shake
|
struct Shake
|
||||||
{
|
{
|
||||||
int desp; // Pixels de desplazamiento para agitar la pantalla en el eje x
|
int desp = 1; // Pixels de desplazamiento para agitar la pantalla en el eje x
|
||||||
int delay; // Retraso entre cada desplazamiento de la pantalla al agitarse
|
int delay = 2; // Retraso entre cada desplazamiento de la pantalla al agitarse
|
||||||
int counter; // Contador para el retraso
|
int lenght = 8; // Cantidad de desplazamientos a realizar
|
||||||
int lenght; // Cantidad de desplazamientos a realizar
|
int remaining = lenght; // Cantidad de desplazamientos pendientes a realizar
|
||||||
int remaining; // Cantidad de desplazamientos pendientes a realizar
|
int counter = delay; // Contador para el retraso
|
||||||
int origin; // Valor inicial de la pantalla para dejarla igual tras el desplazamiento
|
int origin; // Valor inicial de la pantalla para dejarla igual tras el desplazamiento
|
||||||
|
|
||||||
|
// Constructor por defect
|
||||||
|
Shake() = default;
|
||||||
|
|
||||||
|
// Constructor
|
||||||
|
Shake(int d, int de, int l, int o)
|
||||||
|
: desp(d), delay(de), lenght(l), remaining(l), counter(de), origin(o) {}
|
||||||
|
|
||||||
|
// Inicializa los miembros
|
||||||
|
void init(int d, int de, int l, int o)
|
||||||
|
{
|
||||||
|
desp = d;
|
||||||
|
delay = de;
|
||||||
|
lenght = l;
|
||||||
|
remaining = l;
|
||||||
|
counter = de;
|
||||||
|
origin = o;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Objetos y punteros
|
// Objetos y punteros
|
||||||
@@ -43,11 +61,14 @@ private:
|
|||||||
std::unique_ptr<Sprite> arcade_edition_sprite_; // Sprite con los graficos de "Arcade Edition"
|
std::unique_ptr<Sprite> arcade_edition_sprite_; // Sprite con los graficos de "Arcade Edition"
|
||||||
|
|
||||||
// Variables
|
// Variables
|
||||||
int x_; // Posición donde dibujar el logo
|
int x_; // Posición donde dibujar el logo
|
||||||
int y_; // Posición donde dibujar el logo
|
int y_; // Posición donde dibujar el logo
|
||||||
|
float zoom_; // Zoom aplicado al texto "ARCADE EDITION"
|
||||||
|
int post_finished_counter_ = 1; // Contador final una vez terminada las animaciones de los logos
|
||||||
|
|
||||||
Status status_; // Estado en el que se encuentra la clase
|
Status coffee_crisis_status_ = Status::DISABLED; // Estado en el que se encuentra el texto "COFFEE CRISIS"
|
||||||
Shake shake_; // Estructura para generar el efecto de agitación
|
Status arcade_edition_status_ = Status::DISABLED; // Estado en el que se encuentra el texto "ARCADE_EDITION"
|
||||||
|
Shake shake_; // Estructura para generar el efecto de agitación
|
||||||
|
|
||||||
// Inicializa las variables
|
// Inicializa las variables
|
||||||
void init();
|
void init();
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "global_inputs.h"
|
#include "global_inputs.h"
|
||||||
#include <string> // Para operator+, string
|
#include <string> // Para operator+, string
|
||||||
#include "input.h" // Para Input, InputType, INPUT_DO_NOT_ALLOW_REPEAT
|
#include "input.h" // Para Input, InputType, INPUT_DO_NOT_ALLOW_REPEAT
|
||||||
|
#include "asset.h"
|
||||||
#include "jail_audio.h" // Para JA_EnableMusic, JA_EnableSound
|
#include "jail_audio.h" // Para JA_EnableMusic, JA_EnableSound
|
||||||
#include "lang.h" // Para getText
|
#include "lang.h" // Para getText
|
||||||
#include "notifier.h" // Para Notifier
|
#include "notifier.h" // Para Notifier
|
||||||
@@ -13,18 +14,8 @@
|
|||||||
namespace globalInputs
|
namespace globalInputs
|
||||||
{
|
{
|
||||||
// Variables
|
// Variables
|
||||||
std::vector<int> service_pressed_counter;
|
int service_pressed_counter = 0;
|
||||||
|
bool service_pressed = false;
|
||||||
// Inicializa variables
|
|
||||||
void init()
|
|
||||||
{
|
|
||||||
const auto num_inputs = Input::get()->getNumControllers() + 1;
|
|
||||||
service_pressed_counter.reserve(num_inputs);
|
|
||||||
for (int i = 0; i < num_inputs; ++i)
|
|
||||||
{
|
|
||||||
service_pressed_counter.push_back(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Termina
|
// Termina
|
||||||
void quit(section::Options code)
|
void quit(section::Options code)
|
||||||
@@ -33,11 +24,13 @@ namespace globalInputs
|
|||||||
auto code_found = stringInVector(Notifier::get()->getCodes(), exit_code);
|
auto code_found = stringInVector(Notifier::get()->getCodes(), exit_code);
|
||||||
if (code_found)
|
if (code_found)
|
||||||
{
|
{
|
||||||
|
// Si la notificación de salir está activa, cambia de sección
|
||||||
section::name = section::Name::QUIT;
|
section::name = section::Name::QUIT;
|
||||||
section::options = code;
|
section::options = code;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// Si la notificación de salir no está activa, muestra la notificación
|
||||||
#ifdef ARCADE
|
#ifdef ARCADE
|
||||||
const int index = code == section::Options::QUIT_WITH_CONTROLLER ? 116 : 94;
|
const int index = code == section::Options::QUIT_WITH_CONTROLLER ? 116 : 94;
|
||||||
Notifier::get()->showText({lang::getText(index), std::string()}, -1, exit_code);
|
Notifier::get()->showText({lang::getText(index), std::string()}, -1, exit_code);
|
||||||
@@ -71,6 +64,57 @@ namespace globalInputs
|
|||||||
Notifier::get()->showText({"Audio " + boolToOnOff(options.audio.enabled)});
|
Notifier::get()->showText({"Audio " + boolToOnOff(options.audio.enabled)});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Obtiene una fichero a partir de un lang::Code
|
||||||
|
std::string getLangFile(lang::Code code)
|
||||||
|
{
|
||||||
|
switch (code)
|
||||||
|
{
|
||||||
|
case lang::Code::ba_BA:
|
||||||
|
return Asset::get()->get("ba_BA.txt");
|
||||||
|
break;
|
||||||
|
case lang::Code::es_ES:
|
||||||
|
return Asset::get()->get("es_ES.txt");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return Asset::get()->get("en_UK.txt");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Obtiene una cadena a partir de un lang::Code
|
||||||
|
std::string getLangName(lang::Code code)
|
||||||
|
{
|
||||||
|
switch (code)
|
||||||
|
{
|
||||||
|
case lang::Code::ba_BA:
|
||||||
|
return "ba_BA";
|
||||||
|
break;
|
||||||
|
case lang::Code::es_ES:
|
||||||
|
return "es_ES";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return "en_UK";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cambia el idioma
|
||||||
|
void changeLang()
|
||||||
|
{
|
||||||
|
options.game.language = lang::change(options.game.language);
|
||||||
|
lang::loadFromFile(getLangFile(static_cast<lang::Code>(options.game.language)));
|
||||||
|
section::name = section::Name::INIT;
|
||||||
|
section::options = section::Options::RELOAD;
|
||||||
|
Notifier::get()->showText({getLangName(options.game.language)});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cambia el modo de disparo
|
||||||
|
void toggleFireMode()
|
||||||
|
{
|
||||||
|
options.game.autofire = !options.game.autofire;
|
||||||
|
Notifier::get()->showText({"Autofire " + boolToOnOff(options.game.autofire)});
|
||||||
|
}
|
||||||
|
|
||||||
// Comprueba los inputs que se pueden introducir en cualquier sección del juego
|
// Comprueba los inputs que se pueden introducir en cualquier sección del juego
|
||||||
void check()
|
void check()
|
||||||
{
|
{
|
||||||
@@ -125,6 +169,20 @@ namespace globalInputs
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Autofire
|
||||||
|
if (Input::get()->checkInput(InputType::AUTO_FIRE, INPUT_DO_NOT_ALLOW_REPEAT, InputDeviceToUse::KEYBOARD))
|
||||||
|
{
|
||||||
|
toggleFireMode();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Idioma
|
||||||
|
if (Input::get()->checkInput(InputType::CHANGE_LANG, INPUT_DO_NOT_ALLOW_REPEAT, InputDeviceToUse::KEYBOARD))
|
||||||
|
{
|
||||||
|
changeLang();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Shaders
|
// Shaders
|
||||||
if (Input::get()->checkInput(InputType::VIDEO_SHADERS, INPUT_DO_NOT_ALLOW_REPEAT, InputDeviceToUse::KEYBOARD))
|
if (Input::get()->checkInput(InputType::VIDEO_SHADERS, INPUT_DO_NOT_ALLOW_REPEAT, InputDeviceToUse::KEYBOARD))
|
||||||
{
|
{
|
||||||
@@ -143,17 +201,9 @@ namespace globalInputs
|
|||||||
// OnScreenHelp
|
// OnScreenHelp
|
||||||
if (Input::get()->checkInput(InputType::SERVICE, INPUT_ALLOW_REPEAT, InputDeviceToUse::KEYBOARD))
|
if (Input::get()->checkInput(InputType::SERVICE, INPUT_ALLOW_REPEAT, InputDeviceToUse::KEYBOARD))
|
||||||
{
|
{
|
||||||
service_pressed_counter[0]++;
|
service_pressed = true;
|
||||||
|
|
||||||
if (service_pressed_counter[0] >= 3000)
|
|
||||||
{
|
|
||||||
OnScreenHelp::get()->toggleState();
|
|
||||||
service_pressed_counter[0] = 0;
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
service_pressed_counter[0] = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mandos
|
// Mandos
|
||||||
@@ -203,18 +253,30 @@ namespace globalInputs
|
|||||||
// OnScreenHelp
|
// OnScreenHelp
|
||||||
if (Input::get()->checkInput(InputType::SERVICE, INPUT_ALLOW_REPEAT, InputDeviceToUse::CONTROLLER, i))
|
if (Input::get()->checkInput(InputType::SERVICE, INPUT_ALLOW_REPEAT, InputDeviceToUse::CONTROLLER, i))
|
||||||
{
|
{
|
||||||
service_pressed_counter[i + 1]++;
|
service_pressed = true;
|
||||||
|
|
||||||
if (service_pressed_counter[i + 1] >= 3000)
|
|
||||||
{
|
|
||||||
OnScreenHelp::get()->toggleState();
|
|
||||||
service_pressed_counter[i + 1] = 0;
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
service_pressed_counter[i + 1] = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Actualiza variables
|
||||||
|
void update()
|
||||||
|
{
|
||||||
|
if (service_pressed)
|
||||||
|
{
|
||||||
|
++service_pressed_counter;
|
||||||
|
if (service_pressed_counter >= 200)
|
||||||
|
{
|
||||||
|
OnScreenHelp::get()->toggleState();
|
||||||
|
service_pressed_counter = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
service_pressed_counter = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
service_pressed = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,11 +1,12 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
namespace globalInputs
|
namespace globalInputs
|
||||||
{
|
{
|
||||||
extern std::vector<int> service_pressed_counter;
|
extern int service_pressed_counter;
|
||||||
|
extern bool service_pressed;
|
||||||
// Inicializa variables
|
|
||||||
void init();
|
|
||||||
|
|
||||||
// Comprueba los inputs que se pueden introducir en cualquier sección del juego
|
// Comprueba los inputs que se pueden introducir en cualquier sección del juego
|
||||||
void check();
|
void check();
|
||||||
|
|
||||||
|
// Actualiza variables
|
||||||
|
void update();
|
||||||
}
|
}
|
||||||
@@ -77,6 +77,9 @@ void HiScoreTable::update()
|
|||||||
// Actualiza el objeto screen
|
// Actualiza el objeto screen
|
||||||
Screen::get()->update();
|
Screen::get()->update();
|
||||||
|
|
||||||
|
// Actualiza las variables de globalInputs
|
||||||
|
globalInputs::update();
|
||||||
|
|
||||||
// Actualiza el fondo
|
// Actualiza el fondo
|
||||||
background_->update();
|
background_->update();
|
||||||
|
|
||||||
@@ -202,9 +205,10 @@ void HiScoreTable::checkInput()
|
|||||||
// Comprueba si se ha pulsado cualquier botón (de los usados para jugar)
|
// Comprueba si se ha pulsado cualquier botón (de los usados para jugar)
|
||||||
if (Input::get()->checkAnyButtonPressed())
|
if (Input::get()->checkAnyButtonPressed())
|
||||||
{
|
{
|
||||||
JA_StopMusic();
|
//JA_StopMusic();
|
||||||
section::name = section::Name::TITLE;
|
section::name = section::Name::TITLE;
|
||||||
section::options = section::Options::TITLE_1;
|
section::options = section::Options::TITLE_1;
|
||||||
|
section::attract_mode = section::AttractMode::TITLE_TO_DEMO;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -40,9 +40,11 @@ enum class InputType : int
|
|||||||
VIDEO_SHADERS,
|
VIDEO_SHADERS,
|
||||||
RESET,
|
RESET,
|
||||||
MUTE,
|
MUTE,
|
||||||
|
CHANGE_LANG,
|
||||||
SHOWINFO,
|
SHOWINFO,
|
||||||
CONFIG,
|
CONFIG,
|
||||||
SWAP_CONTROLLERS,
|
SWAP_CONTROLLERS,
|
||||||
|
AUTO_FIRE,
|
||||||
|
|
||||||
// Input obligatorio
|
// Input obligatorio
|
||||||
NONE,
|
NONE,
|
||||||
|
|||||||
@@ -27,18 +27,16 @@ Instructions::Instructions()
|
|||||||
texture_(SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, param.game.width, param.game.height)),
|
texture_(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)),
|
backbuffer_(SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, param.game.width, param.game.height)),
|
||||||
text_(Resource::get()->getText("smb2")),
|
text_(Resource::get()->getText("smb2")),
|
||||||
tiled_bg_(std::make_unique<TiledBG>((SDL_Rect){0, 0, param.game.width, param.game.height}, TiledBGMode::STATIC)),
|
tiled_bg_(std::make_unique<TiledBG>(param.game.game_area.rect, TiledBGMode::STATIC)),
|
||||||
fade_(std::make_unique<Fade>())
|
fade_(std::make_unique<Fade>())
|
||||||
{
|
{
|
||||||
// Crea un backbuffer para el renderizador
|
// Configura las texturas
|
||||||
SDL_SetTextureBlendMode(backbuffer_, SDL_BLENDMODE_BLEND);
|
SDL_SetTextureBlendMode(backbuffer_, SDL_BLENDMODE_BLEND);
|
||||||
|
|
||||||
// Crea una textura para el texto fijo
|
|
||||||
SDL_SetTextureBlendMode(texture_, SDL_BLENDMODE_BLEND);
|
SDL_SetTextureBlendMode(texture_, SDL_BLENDMODE_BLEND);
|
||||||
|
|
||||||
// Inicializa variables
|
// Inicializa variables
|
||||||
section::name = section::Name::INSTRUCTIONS;
|
section::name = section::Name::INSTRUCTIONS;
|
||||||
view_ = {0, 0, param.game.width, param.game.height};
|
view_ = param.game.game_area.rect;
|
||||||
|
|
||||||
// Inicializa objetos
|
// Inicializa objetos
|
||||||
fade_->setColor(fade_color.r, fade_color.g, fade_color.b);
|
fade_->setColor(fade_color.r, fade_color.g, fade_color.b);
|
||||||
@@ -211,11 +209,16 @@ void Instructions::update()
|
|||||||
|
|
||||||
// Mantiene la música sonando
|
// Mantiene la música sonando
|
||||||
if ((JA_GetMusicState() == JA_MUSIC_INVALID) || (JA_GetMusicState() == JA_MUSIC_STOPPED))
|
if ((JA_GetMusicState() == JA_MUSIC_INVALID) || (JA_GetMusicState() == JA_MUSIC_STOPPED))
|
||||||
|
{
|
||||||
JA_PlayMusic(Resource::get()->getMusic("title.ogg"));
|
JA_PlayMusic(Resource::get()->getMusic("title.ogg"));
|
||||||
|
}
|
||||||
|
|
||||||
// Actualiza el objeto screen
|
// Actualiza el objeto screen
|
||||||
Screen::get()->update();
|
Screen::get()->update();
|
||||||
|
|
||||||
|
// Actualiza las variables de globalInputs
|
||||||
|
globalInputs::update();
|
||||||
|
|
||||||
// Incrementa el contador
|
// Incrementa el contador
|
||||||
counter_++;
|
counter_++;
|
||||||
|
|
||||||
@@ -307,9 +310,10 @@ void Instructions::checkInput()
|
|||||||
// Comprueba si se ha pulsado cualquier botón (de los usados para jugar)
|
// Comprueba si se ha pulsado cualquier botón (de los usados para jugar)
|
||||||
if (Input::get()->checkAnyButtonPressed())
|
if (Input::get()->checkAnyButtonPressed())
|
||||||
{
|
{
|
||||||
JA_StopMusic();
|
//JA_StopMusic();
|
||||||
section::name = section::Name::TITLE;
|
section::name = section::Name::TITLE;
|
||||||
section::options = section::Options::TITLE_1;
|
section::options = section::Options::TITLE_1;
|
||||||
|
section::attract_mode = section::AttractMode::TITLE_TO_DEMO;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -382,6 +382,9 @@ void Intro::update()
|
|||||||
|
|
||||||
// Actualiza las escenas de la intro
|
// Actualiza las escenas de la intro
|
||||||
updateScenes();
|
updateScenes();
|
||||||
|
|
||||||
|
// Actualiza las variables de globalInputs
|
||||||
|
globalInputs::update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -413,7 +416,6 @@ void Intro::render()
|
|||||||
void Intro::run()
|
void Intro::run()
|
||||||
{
|
{
|
||||||
JA_PlayMusic(Resource::get()->getMusic("intro.ogg"), 0);
|
JA_PlayMusic(Resource::get()->getMusic("intro.ogg"), 0);
|
||||||
|
|
||||||
while (section::name == section::Name::INTRO)
|
while (section::name == section::Name::INTRO)
|
||||||
{
|
{
|
||||||
checkInput();
|
checkInput();
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
#include "item.h"
|
#include "item.h"
|
||||||
#include <algorithm> // para std::clamp
|
#include <stdlib.h> // Para rand
|
||||||
#include <stdlib.h> // para rand
|
#include <algorithm> // Para clamp
|
||||||
#include "animated_sprite.h" // para SpriteAnimated
|
#include "animated_sprite.h" // Para AnimatedSprite
|
||||||
#include "param.h" // para param
|
#include "param.h" // Para Param, ParamGame, param
|
||||||
class Texture;
|
class Texture; // lines 6-6
|
||||||
|
|
||||||
Item::Item(ItemType type, float x, float y, SDL_Rect &play_area, std::shared_ptr<Texture> texture, const std::vector<std::string> &animation)
|
Item::Item(ItemType type, float x, float y, SDL_Rect &play_area, std::shared_ptr<Texture> texture, const std::vector<std::string> &animation)
|
||||||
: sprite_(std::make_unique<AnimatedSprite>(texture, animation)),
|
: sprite_(std::make_unique<AnimatedSprite>(texture, animation)),
|
||||||
@@ -73,8 +73,6 @@ void Item::render()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#include <algorithm> // Necesario para std::clamp
|
|
||||||
|
|
||||||
void Item::move()
|
void Item::move()
|
||||||
{
|
{
|
||||||
floor_collision_ = false;
|
floor_collision_ = false;
|
||||||
|
|||||||
@@ -1,91 +1,92 @@
|
|||||||
#ifndef JA_USESDLMIXER
|
#ifndef JA_USESDLMIXER
|
||||||
|
|
||||||
#include "jail_audio.h"
|
#include "jail_audio.h"
|
||||||
#include <stdint.h> // para uint8_t
|
#include "stb_vorbis.c"
|
||||||
#include <stdio.h> // para NULL, fseek, fclose, fopen, fread, ftell, FILE
|
#include <SDL2/SDL.h>
|
||||||
#include <stdlib.h> // para free, malloc
|
#include <stdio.h>
|
||||||
#include "stb_vorbis.c" // para stb_vorbis_decode_memory
|
|
||||||
|
|
||||||
#define JA_MAX_SIMULTANEOUS_CHANNELS 5
|
#define JA_MAX_SIMULTANEOUS_CHANNELS 20
|
||||||
|
|
||||||
struct JA_Sound_t
|
struct JA_Sound_t {
|
||||||
{
|
Uint32 length {0};
|
||||||
Uint32 length{0};
|
Uint8* buffer {NULL};
|
||||||
Uint8 *buffer{NULL};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct JA_Channel_t
|
struct JA_Channel_t {
|
||||||
{
|
JA_Sound_t *sound;
|
||||||
JA_Sound_t *sound;
|
int pos {0};
|
||||||
int pos{0};
|
int times {0};
|
||||||
int times{0};
|
JA_Channel_state state { JA_CHANNEL_FREE };
|
||||||
JA_Channel_state state{JA_CHANNEL_FREE};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct JA_Music_t
|
struct JA_Music_t {
|
||||||
{
|
int samples {0};
|
||||||
int samples{0};
|
Uint32 length {0};
|
||||||
int pos{0};
|
int pos {0};
|
||||||
int times{0};
|
int times {0};
|
||||||
short *output{NULL};
|
short* output {NULL};
|
||||||
JA_Music_state state{JA_MUSIC_INVALID};
|
JA_Music_state state {JA_MUSIC_INVALID};
|
||||||
};
|
};
|
||||||
|
|
||||||
JA_Music_t *current_music{NULL};
|
JA_Music_t *current_music{NULL};
|
||||||
JA_Channel_t channels[JA_MAX_SIMULTANEOUS_CHANNELS];
|
JA_Channel_t channels[JA_MAX_SIMULTANEOUS_CHANNELS];
|
||||||
|
|
||||||
int JA_freq{48000};
|
int JA_freq {48000};
|
||||||
SDL_AudioFormat JA_format{AUDIO_S16};
|
SDL_AudioFormat JA_format {AUDIO_S16};
|
||||||
Uint8 JA_channels{2};
|
Uint8 JA_channels {2};
|
||||||
int JA_musicVolume = 128;
|
int JA_musicVolume = 128;
|
||||||
int JA_soundVolume = 64;
|
int JA_soundVolume = 64;
|
||||||
bool JA_musicEnabled = true;
|
bool JA_musicEnabled = true;
|
||||||
bool JA_soundEnabled = true;
|
bool JA_soundEnabled = true;
|
||||||
SDL_AudioDeviceID sdlAudioDevice = 0;
|
SDL_AudioDeviceID sdlAudioDevice = 0;
|
||||||
|
|
||||||
void audioCallback(void *userdata, uint8_t *stream, int len)
|
bool fading = false;
|
||||||
{
|
int fade_start_time;
|
||||||
|
int fade_duration;
|
||||||
|
int fade_initial_volume;
|
||||||
|
|
||||||
|
void audioCallback(void * userdata, uint8_t * stream, int len) {
|
||||||
SDL_memset(stream, 0, len);
|
SDL_memset(stream, 0, len);
|
||||||
if (current_music != NULL && current_music->state == JA_MUSIC_PLAYING)
|
if (current_music != NULL && current_music->state == JA_MUSIC_PLAYING) {
|
||||||
{
|
int volume = JA_musicVolume;
|
||||||
const int size = SDL_min(len, current_music->samples * 2 - current_music->pos);
|
if (fading) {
|
||||||
SDL_MixAudioFormat(stream, (Uint8 *)(current_music->output + current_music->pos), AUDIO_S16, size, JA_musicVolume);
|
int time = SDL_GetTicks();
|
||||||
current_music->pos += size / 2;
|
if (time > (fade_start_time+fade_duration)) {
|
||||||
if (size < len)
|
fading = false;
|
||||||
{
|
current_music->pos = 0;
|
||||||
if (current_music->times != 0)
|
current_music->state = JA_MUSIC_STOPPED;
|
||||||
{
|
volume = 0;
|
||||||
SDL_MixAudioFormat(stream + size, (Uint8 *)current_music->output, AUDIO_S16, len - size, JA_musicVolume);
|
} else {
|
||||||
current_music->pos = (len - size) / 2;
|
const int time_passed = time - fade_start_time;
|
||||||
if (current_music->times > 0)
|
const float percent = (float)time_passed / (float)fade_duration;
|
||||||
current_music->times--;
|
volume = JA_musicVolume * (1.0 - percent);
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
{
|
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;
|
||||||
|
if (current_music->times > 0) current_music->times--;
|
||||||
|
} else {
|
||||||
current_music->pos = 0;
|
current_music->pos = 0;
|
||||||
current_music->state = JA_MUSIC_STOPPED;
|
current_music->state = JA_MUSIC_STOPPED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Mixar els channels mi amol
|
// Mixar els channels mi amol
|
||||||
for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++)
|
for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) {
|
||||||
{
|
if (channels[i].state == JA_CHANNEL_PLAYING) {
|
||||||
if (channels[i].state == JA_CHANNEL_PLAYING)
|
|
||||||
{
|
|
||||||
const int size = SDL_min(len, channels[i].sound->length - channels[i].pos);
|
const int size = SDL_min(len, channels[i].sound->length - channels[i].pos);
|
||||||
SDL_MixAudioFormat(stream, channels[i].sound->buffer + channels[i].pos, AUDIO_S16, size, JA_soundVolume);
|
SDL_MixAudioFormat(stream, channels[i].sound->buffer + channels[i].pos, AUDIO_S16, size, JA_soundVolume);
|
||||||
channels[i].pos += size;
|
channels[i].pos += size;
|
||||||
if (size < len)
|
if (size < len) {
|
||||||
{
|
if (channels[i].times != 0) {
|
||||||
if (channels[i].times != 0)
|
SDL_MixAudioFormat(stream + size, channels[i].sound->buffer, AUDIO_S16, len-size, JA_soundVolume);
|
||||||
{
|
channels[i].pos = len-size;
|
||||||
SDL_MixAudioFormat(stream + size, channels[i].sound->buffer, AUDIO_S16, len - size, JA_soundVolume);
|
if (channels[i].times > 0) channels[i].times--;
|
||||||
channels[i].pos = len - size;
|
} else {
|
||||||
if (channels[i].times > 0)
|
|
||||||
channels[i].times--;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
JA_StopChannel(i);
|
JA_StopChannel(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -95,69 +96,84 @@ void audioCallback(void *userdata, uint8_t *stream, int len)
|
|||||||
|
|
||||||
void JA_Init(const int freq, const SDL_AudioFormat format, const int channels)
|
void JA_Init(const int freq, const SDL_AudioFormat format, const int channels)
|
||||||
{
|
{
|
||||||
|
#ifdef DEBUG
|
||||||
|
SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_DEBUG);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
SDL_Log("Iniciant JailAudio...");
|
||||||
JA_freq = freq;
|
JA_freq = freq;
|
||||||
JA_format = format;
|
JA_format = format;
|
||||||
JA_channels = channels;
|
JA_channels = channels;
|
||||||
SDL_AudioSpec audioSpec{JA_freq, JA_format, JA_channels, 0, 1024, 0, 0, audioCallback, NULL};
|
SDL_AudioSpec audioSpec{JA_freq, JA_format, JA_channels, 0, 1024, 0, 0, audioCallback, NULL};
|
||||||
if (sdlAudioDevice != 0)
|
if (sdlAudioDevice != 0) SDL_CloseAudioDevice(sdlAudioDevice);
|
||||||
SDL_CloseAudioDevice(sdlAudioDevice);
|
|
||||||
sdlAudioDevice = SDL_OpenAudioDevice(NULL, 0, &audioSpec, NULL, 0);
|
sdlAudioDevice = SDL_OpenAudioDevice(NULL, 0, &audioSpec, NULL, 0);
|
||||||
|
if (sdlAudioDevice==0)
|
||||||
|
{
|
||||||
|
SDL_Log("FAILED!\n");
|
||||||
|
SDL_Log("Failed to initialize SDL audio!\n");
|
||||||
|
} else {
|
||||||
|
SDL_Log("OK!\n");
|
||||||
|
}
|
||||||
SDL_PauseAudioDevice(sdlAudioDevice, 0);
|
SDL_PauseAudioDevice(sdlAudioDevice, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JA_Quit()
|
void JA_Quit() {
|
||||||
{
|
|
||||||
SDL_PauseAudioDevice(sdlAudioDevice, 1);
|
SDL_PauseAudioDevice(sdlAudioDevice, 1);
|
||||||
if (sdlAudioDevice != 0)
|
if (sdlAudioDevice != 0) SDL_CloseAudioDevice(sdlAudioDevice);
|
||||||
SDL_CloseAudioDevice(sdlAudioDevice);
|
|
||||||
sdlAudioDevice = 0;
|
sdlAudioDevice = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
JA_Music_t *JA_LoadMusic(const char *filename)
|
JA_Music_t *JA_LoadMusic(Uint8* buffer, Uint32 length)
|
||||||
{
|
{
|
||||||
int chan, samplerate;
|
int chan, samplerate;
|
||||||
|
|
||||||
// [RZC 28/08/22] Carreguem primer el arxiu en memòria i després el descomprimim. Es algo més rapid.
|
|
||||||
FILE *f = fopen(filename, "rb");
|
|
||||||
fseek(f, 0, SEEK_END);
|
|
||||||
long fsize = ftell(f);
|
|
||||||
fseek(f, 0, SEEK_SET);
|
|
||||||
Uint8 *buffer = (Uint8 *)malloc(fsize + 1);
|
|
||||||
if (fread(buffer, fsize, 1, f) != 1)
|
|
||||||
return NULL;
|
|
||||||
fclose(f);
|
|
||||||
|
|
||||||
JA_Music_t *music = new JA_Music_t();
|
JA_Music_t *music = new JA_Music_t();
|
||||||
|
|
||||||
music->samples = stb_vorbis_decode_memory(buffer, fsize, &chan, &samplerate, &music->output);
|
music->samples = stb_vorbis_decode_memory(buffer, length, &chan, &samplerate, &music->output);
|
||||||
free(buffer);
|
|
||||||
// [RZC 28/08/22] Abans el descomprimiem mentre el teniem obert
|
// [RZC 28/08/22] Abans el descomprimiem mentre el teniem obert
|
||||||
// music->samples = stb_vorbis_decode_filename(filename, &chan, &samplerate, &music->output);
|
// music->samples = stb_vorbis_decode_filename(filename, &chan, &samplerate, &music->output);
|
||||||
|
|
||||||
SDL_AudioCVT cvt;
|
SDL_AudioCVT cvt;
|
||||||
SDL_BuildAudioCVT(&cvt, AUDIO_S16, chan, samplerate, JA_format, JA_channels, JA_freq);
|
SDL_BuildAudioCVT(&cvt, AUDIO_S16, chan, samplerate, JA_format, JA_channels, JA_freq);
|
||||||
if (cvt.needed)
|
SDL_Log("Music length: %f\n", float(music->samples)/float(JA_freq));
|
||||||
{
|
if (cvt.needed) {
|
||||||
cvt.len = music->samples * chan * 2;
|
cvt.len = music->samples * chan * 2;
|
||||||
cvt.buf = (Uint8 *)SDL_malloc(cvt.len * cvt.len_mult);
|
music->length = cvt.len;
|
||||||
|
cvt.buf = (Uint8 *) SDL_malloc(cvt.len * cvt.len_mult);
|
||||||
SDL_memcpy(cvt.buf, music->output, cvt.len);
|
SDL_memcpy(cvt.buf, music->output, cvt.len);
|
||||||
SDL_ConvertAudio(&cvt);
|
SDL_ConvertAudio(&cvt);
|
||||||
free(music->output);
|
free(music->output);
|
||||||
music->output = (short *)cvt.buf;
|
music->output = (short*)cvt.buf;
|
||||||
}
|
}
|
||||||
|
music->length = music->samples * chan * 2;
|
||||||
music->pos = 0;
|
music->pos = 0;
|
||||||
music->state = JA_MUSIC_STOPPED;
|
music->state = JA_MUSIC_STOPPED;
|
||||||
|
|
||||||
return music;
|
return music;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JA_Music_t *JA_LoadMusic(const char* filename)
|
||||||
|
{
|
||||||
|
// [RZC 28/08/22] Carreguem primer el arxiu en memòria i després el descomprimim. Es algo més rapid.
|
||||||
|
FILE *f = fopen(filename, "rb");
|
||||||
|
fseek(f, 0, SEEK_END);
|
||||||
|
long fsize = ftell(f);
|
||||||
|
fseek(f, 0, SEEK_SET);
|
||||||
|
Uint8 *buffer = (Uint8*)malloc(fsize + 1);
|
||||||
|
if (fread(buffer, fsize, 1, f)!=1) return NULL;
|
||||||
|
fclose(f);
|
||||||
|
|
||||||
|
JA_Music_t *music = JA_LoadMusic(buffer, fsize);
|
||||||
|
|
||||||
|
free(buffer);
|
||||||
|
|
||||||
|
return music;
|
||||||
|
}
|
||||||
|
|
||||||
void JA_PlayMusic(JA_Music_t *music, const int loop)
|
void JA_PlayMusic(JA_Music_t *music, const int loop)
|
||||||
{
|
{
|
||||||
if (!JA_musicEnabled || !music)
|
if (!JA_musicEnabled) return;
|
||||||
return;
|
|
||||||
|
|
||||||
if (current_music != NULL)
|
if (current_music != NULL) {
|
||||||
{
|
|
||||||
current_music->pos = 0;
|
current_music->pos = 0;
|
||||||
current_music->state = JA_MUSIC_STOPPED;
|
current_music->state = JA_MUSIC_STOPPED;
|
||||||
}
|
}
|
||||||
@@ -169,78 +185,108 @@ void JA_PlayMusic(JA_Music_t *music, const int loop)
|
|||||||
|
|
||||||
void JA_PauseMusic()
|
void JA_PauseMusic()
|
||||||
{
|
{
|
||||||
if (!JA_musicEnabled)
|
if (!JA_musicEnabled) return;
|
||||||
return;
|
|
||||||
|
|
||||||
if (current_music == NULL || current_music->state == JA_MUSIC_INVALID)
|
if (current_music == NULL || current_music->state == JA_MUSIC_INVALID) return;
|
||||||
return;
|
|
||||||
current_music->state = JA_MUSIC_PAUSED;
|
current_music->state = JA_MUSIC_PAUSED;
|
||||||
}
|
}
|
||||||
|
|
||||||
void JA_ResumeMusic()
|
void JA_ResumeMusic()
|
||||||
{
|
{
|
||||||
if (!JA_musicEnabled)
|
if (!JA_musicEnabled) return;
|
||||||
return;
|
|
||||||
|
|
||||||
if (current_music == NULL || current_music->state == JA_MUSIC_INVALID)
|
if (current_music == NULL || current_music->state == JA_MUSIC_INVALID) return;
|
||||||
return;
|
|
||||||
current_music->state = JA_MUSIC_PLAYING;
|
current_music->state = JA_MUSIC_PLAYING;
|
||||||
}
|
}
|
||||||
|
|
||||||
void JA_StopMusic()
|
void JA_StopMusic()
|
||||||
{
|
{
|
||||||
if (!JA_musicEnabled)
|
if (!JA_musicEnabled) return;
|
||||||
return;
|
|
||||||
|
|
||||||
if (current_music == NULL || current_music->state == JA_MUSIC_INVALID)
|
if (current_music == NULL || current_music->state == JA_MUSIC_INVALID) return;
|
||||||
return;
|
|
||||||
current_music->pos = 0;
|
current_music->pos = 0;
|
||||||
current_music->state = JA_MUSIC_STOPPED;
|
current_music->state = JA_MUSIC_STOPPED;
|
||||||
}
|
}
|
||||||
|
|
||||||
JA_Music_state JA_GetMusicState()
|
void JA_FadeOutMusic(const int milliseconds)
|
||||||
{
|
{
|
||||||
if (!JA_musicEnabled)
|
if (!JA_musicEnabled) return;
|
||||||
return JA_MUSIC_DISABLED;
|
if (current_music == NULL || current_music->state == JA_MUSIC_INVALID) return;
|
||||||
|
|
||||||
if (current_music == NULL)
|
fading = true;
|
||||||
return JA_MUSIC_INVALID;
|
fade_start_time = SDL_GetTicks();
|
||||||
|
fade_duration = milliseconds;
|
||||||
|
fade_initial_volume = JA_musicVolume;
|
||||||
|
}
|
||||||
|
|
||||||
|
JA_Music_state JA_GetMusicState() {
|
||||||
|
if (!JA_musicEnabled) return JA_MUSIC_DISABLED;
|
||||||
|
|
||||||
|
if (current_music == NULL) return JA_MUSIC_INVALID;
|
||||||
return current_music->state;
|
return current_music->state;
|
||||||
}
|
}
|
||||||
|
|
||||||
void JA_DeleteMusic(JA_Music_t *music)
|
void JA_DeleteMusic(JA_Music_t *music) {
|
||||||
{
|
if (current_music == music) current_music = NULL;
|
||||||
if (current_music == music)
|
|
||||||
current_music = NULL;
|
|
||||||
free(music->output);
|
free(music->output);
|
||||||
delete music;
|
delete music;
|
||||||
}
|
}
|
||||||
|
|
||||||
int JA_SetMusicVolume(int volume)
|
int JA_SetMusicVolume(int volume)
|
||||||
{
|
{
|
||||||
JA_musicVolume = volume > 128 ? 128 : volume < 0 ? 0
|
JA_musicVolume = volume > 128 ? 128 : volume < 0 ? 0 : volume;
|
||||||
: volume;
|
|
||||||
return JA_musicVolume;
|
return JA_musicVolume;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void JA_SetMusicPosition(float value)
|
||||||
|
{
|
||||||
|
if (!current_music) return;
|
||||||
|
current_music->pos = value * JA_freq;
|
||||||
|
}
|
||||||
|
|
||||||
|
float JA_GetMusicPosition()
|
||||||
|
{
|
||||||
|
if (!current_music) return 0;
|
||||||
|
return float(current_music->pos)/float(JA_freq);
|
||||||
|
}
|
||||||
|
|
||||||
void JA_EnableMusic(const bool value)
|
void JA_EnableMusic(const bool value)
|
||||||
{
|
{
|
||||||
if (!value && current_music != NULL && current_music->state == JA_MUSIC_PLAYING)
|
if (!value && current_music != NULL && current_music->state==JA_MUSIC_PLAYING) JA_StopMusic();
|
||||||
JA_StopMusic();
|
|
||||||
|
|
||||||
JA_musicEnabled = value;
|
JA_musicEnabled = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
JA_Sound_t *JA_NewSound(Uint8 *buffer, Uint32 length)
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
|
JA_Sound_t *JA_NewSound(Uint8* buffer, Uint32 length) {
|
||||||
JA_Sound_t *sound = new JA_Sound_t();
|
JA_Sound_t *sound = new JA_Sound_t();
|
||||||
sound->buffer = buffer;
|
sound->buffer = buffer;
|
||||||
sound->length = length;
|
sound->length = length;
|
||||||
return sound;
|
return sound;
|
||||||
}
|
}
|
||||||
|
|
||||||
JA_Sound_t *JA_LoadSound(const char *filename)
|
JA_Sound_t *JA_LoadSound(uint8_t* buffer, uint32_t size) {
|
||||||
{
|
JA_Sound_t *sound = new JA_Sound_t();
|
||||||
|
SDL_AudioSpec wavSpec;
|
||||||
|
SDL_LoadWAV_RW(SDL_RWFromMem(buffer, size),1, &wavSpec, &sound->buffer, &sound->length);
|
||||||
|
|
||||||
|
SDL_AudioCVT cvt;
|
||||||
|
SDL_BuildAudioCVT(&cvt, wavSpec.format, wavSpec.channels, wavSpec.freq, JA_format, JA_channels, JA_freq);
|
||||||
|
cvt.len = sound->length;
|
||||||
|
cvt.buf = (Uint8 *) SDL_malloc(cvt.len * cvt.len_mult);
|
||||||
|
SDL_memcpy(cvt.buf, sound->buffer, sound->length);
|
||||||
|
SDL_ConvertAudio(&cvt);
|
||||||
|
SDL_FreeWAV(sound->buffer);
|
||||||
|
sound->buffer = cvt.buf;
|
||||||
|
sound->length = cvt.len_cvt;
|
||||||
|
|
||||||
|
return sound;
|
||||||
|
}
|
||||||
|
|
||||||
|
JA_Sound_t *JA_LoadSound(const char* filename) {
|
||||||
JA_Sound_t *sound = new JA_Sound_t();
|
JA_Sound_t *sound = new JA_Sound_t();
|
||||||
SDL_AudioSpec wavSpec;
|
SDL_AudioSpec wavSpec;
|
||||||
SDL_LoadWAV(filename, &wavSpec, &sound->buffer, &sound->length);
|
SDL_LoadWAV(filename, &wavSpec, &sound->buffer, &sound->length);
|
||||||
@@ -248,7 +294,7 @@ JA_Sound_t *JA_LoadSound(const char *filename)
|
|||||||
SDL_AudioCVT cvt;
|
SDL_AudioCVT cvt;
|
||||||
SDL_BuildAudioCVT(&cvt, wavSpec.format, wavSpec.channels, wavSpec.freq, JA_format, JA_channels, JA_freq);
|
SDL_BuildAudioCVT(&cvt, wavSpec.format, wavSpec.channels, wavSpec.freq, JA_format, JA_channels, JA_freq);
|
||||||
cvt.len = sound->length;
|
cvt.len = sound->length;
|
||||||
cvt.buf = (Uint8 *)SDL_malloc(cvt.len * cvt.len_mult);
|
cvt.buf = (Uint8 *) SDL_malloc(cvt.len * cvt.len_mult);
|
||||||
SDL_memcpy(cvt.buf, sound->buffer, sound->length);
|
SDL_memcpy(cvt.buf, sound->buffer, sound->length);
|
||||||
SDL_ConvertAudio(&cvt);
|
SDL_ConvertAudio(&cvt);
|
||||||
SDL_FreeWAV(sound->buffer);
|
SDL_FreeWAV(sound->buffer);
|
||||||
@@ -260,16 +306,24 @@ JA_Sound_t *JA_LoadSound(const char *filename)
|
|||||||
|
|
||||||
int JA_PlaySound(JA_Sound_t *sound, const int loop)
|
int JA_PlaySound(JA_Sound_t *sound, const int loop)
|
||||||
{
|
{
|
||||||
if (!JA_soundEnabled || !sound)
|
if (!JA_soundEnabled) return -1;
|
||||||
return 0;
|
|
||||||
|
|
||||||
int channel = 0;
|
int channel = 0;
|
||||||
while (channel < JA_MAX_SIMULTANEOUS_CHANNELS && channels[channel].state != JA_CHANNEL_FREE)
|
while (channel < JA_MAX_SIMULTANEOUS_CHANNELS && channels[channel].state != JA_CHANNEL_FREE) { channel++; }
|
||||||
{
|
if (channel == JA_MAX_SIMULTANEOUS_CHANNELS) channel = 0;
|
||||||
channel++;
|
|
||||||
}
|
channels[channel].sound = sound;
|
||||||
if (channel == JA_MAX_SIMULTANEOUS_CHANNELS)
|
channels[channel].times = loop;
|
||||||
channel = 0;
|
channels[channel].pos = 0;
|
||||||
|
channels[channel].state = JA_CHANNEL_PLAYING;
|
||||||
|
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].sound = sound;
|
||||||
channels[channel].times = loop;
|
channels[channel].times = loop;
|
||||||
@@ -280,10 +334,8 @@ int JA_PlaySound(JA_Sound_t *sound, const int loop)
|
|||||||
|
|
||||||
void JA_DeleteSound(JA_Sound_t *sound)
|
void JA_DeleteSound(JA_Sound_t *sound)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++)
|
for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) {
|
||||||
{
|
if (channels[i].sound == sound) JA_StopChannel(i);
|
||||||
if (channels[i].sound == sound)
|
|
||||||
JA_StopChannel(i);
|
|
||||||
}
|
}
|
||||||
SDL_free(sound->buffer);
|
SDL_free(sound->buffer);
|
||||||
delete sound;
|
delete sound;
|
||||||
@@ -291,60 +343,41 @@ void JA_DeleteSound(JA_Sound_t *sound)
|
|||||||
|
|
||||||
void JA_PauseChannel(const int channel)
|
void JA_PauseChannel(const int channel)
|
||||||
{
|
{
|
||||||
if (!JA_soundEnabled)
|
if (!JA_soundEnabled) return;
|
||||||
return;
|
|
||||||
|
|
||||||
if (channel == -1)
|
if (channel == -1) {
|
||||||
{
|
for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) {
|
||||||
for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++)
|
if (channels[i].state == JA_CHANNEL_PLAYING) channels[i].state = JA_CHANNEL_PAUSED;
|
||||||
{
|
|
||||||
if (channels[i].state == JA_CHANNEL_PLAYING)
|
|
||||||
channels[i].state = JA_CHANNEL_PAUSED;
|
|
||||||
}
|
}
|
||||||
}
|
} else if (channel >= 0 && channel < JA_MAX_SIMULTANEOUS_CHANNELS) {
|
||||||
else if (channel >= 0 && channel < JA_MAX_SIMULTANEOUS_CHANNELS)
|
if (channels[channel].state == JA_CHANNEL_PLAYING) channels[channel].state = JA_CHANNEL_PAUSED;
|
||||||
{
|
|
||||||
if (channels[channel].state == JA_CHANNEL_PLAYING)
|
|
||||||
channels[channel].state = JA_CHANNEL_PAUSED;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void JA_ResumeChannel(const int channel)
|
void JA_ResumeChannel(const int channel)
|
||||||
{
|
{
|
||||||
if (!JA_soundEnabled)
|
if (!JA_soundEnabled) return;
|
||||||
return;
|
|
||||||
|
|
||||||
if (channel == -1)
|
if (channel == -1) {
|
||||||
{
|
for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) {
|
||||||
for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++)
|
if (channels[i].state == JA_CHANNEL_PAUSED) channels[i].state = JA_CHANNEL_PLAYING;
|
||||||
{
|
|
||||||
if (channels[i].state == JA_CHANNEL_PAUSED)
|
|
||||||
channels[i].state = JA_CHANNEL_PLAYING;
|
|
||||||
}
|
}
|
||||||
}
|
} else if (channel >= 0 && channel < JA_MAX_SIMULTANEOUS_CHANNELS) {
|
||||||
else if (channel >= 0 && channel < JA_MAX_SIMULTANEOUS_CHANNELS)
|
if (channels[channel].state == JA_CHANNEL_PAUSED) channels[channel].state = JA_CHANNEL_PLAYING;
|
||||||
{
|
|
||||||
if (channels[channel].state == JA_CHANNEL_PAUSED)
|
|
||||||
channels[channel].state = JA_CHANNEL_PLAYING;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void JA_StopChannel(const int channel)
|
void JA_StopChannel(const int channel)
|
||||||
{
|
{
|
||||||
if (!JA_soundEnabled)
|
if (!JA_soundEnabled) return;
|
||||||
return;
|
|
||||||
|
|
||||||
if (channel == -1)
|
if (channel == -1) {
|
||||||
{
|
for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) {
|
||||||
for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++)
|
|
||||||
{
|
|
||||||
channels[i].state = JA_CHANNEL_FREE;
|
channels[i].state = JA_CHANNEL_FREE;
|
||||||
channels[i].pos = 0;
|
channels[i].pos = 0;
|
||||||
channels[i].sound = NULL;
|
channels[i].sound = NULL;
|
||||||
}
|
}
|
||||||
}
|
} else if (channel >= 0 && channel < JA_MAX_SIMULTANEOUS_CHANNELS) {
|
||||||
else if (channel >= 0 && channel < JA_MAX_SIMULTANEOUS_CHANNELS)
|
|
||||||
{
|
|
||||||
channels[channel].state = JA_CHANNEL_FREE;
|
channels[channel].state = JA_CHANNEL_FREE;
|
||||||
channels[channel].pos = 0;
|
channels[channel].pos = 0;
|
||||||
channels[channel].sound = NULL;
|
channels[channel].sound = NULL;
|
||||||
@@ -353,18 +386,15 @@ void JA_StopChannel(const int channel)
|
|||||||
|
|
||||||
JA_Channel_state JA_GetChannelState(const int channel)
|
JA_Channel_state JA_GetChannelState(const int channel)
|
||||||
{
|
{
|
||||||
if (!JA_soundEnabled)
|
if (!JA_soundEnabled) return JA_SOUND_DISABLED;
|
||||||
return JA_SOUND_DISABLED;
|
|
||||||
|
|
||||||
if (channel < 0 || channel >= JA_MAX_SIMULTANEOUS_CHANNELS)
|
if (channel < 0 || channel >= JA_MAX_SIMULTANEOUS_CHANNELS) return JA_CHANNEL_INVALID;
|
||||||
return JA_CHANNEL_INVALID;
|
|
||||||
return channels[channel].state;
|
return channels[channel].state;
|
||||||
}
|
}
|
||||||
|
|
||||||
int JA_SetSoundVolume(int volume)
|
int JA_SetSoundVolume(int volume)
|
||||||
{
|
{
|
||||||
JA_soundVolume = volume > 128 ? 128 : volume < 0 ? 0
|
JA_soundVolume = volume > 128 ? 128 : volume < 0 ? 0 : volume;
|
||||||
: volume;
|
|
||||||
return JA_soundVolume;
|
return JA_soundVolume;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -372,17 +402,15 @@ void JA_EnableSound(const bool value)
|
|||||||
{
|
{
|
||||||
for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++)
|
for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++)
|
||||||
{
|
{
|
||||||
if (channels[i].state == JA_CHANNEL_PLAYING)
|
if (channels[i].state == JA_CHANNEL_PLAYING) JA_StopChannel(i);
|
||||||
JA_StopChannel(i);
|
|
||||||
}
|
}
|
||||||
JA_soundEnabled = value;
|
JA_soundEnabled = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
int JA_SetVolume(int volume)
|
int JA_SetVolume(int volume)
|
||||||
{
|
{
|
||||||
JA_musicVolume = volume > 128 ? 128 : volume < 0 ? 0
|
JA_musicVolume = volume > 128 ? 128 : volume < 0 ? 0 : volume;
|
||||||
: volume;
|
JA_soundVolume = JA_musicVolume/2;
|
||||||
JA_soundVolume = JA_musicVolume / 2;
|
|
||||||
return JA_musicVolume;
|
return JA_musicVolume;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,43 +1,34 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include <SDL2/SDL.h>
|
||||||
|
|
||||||
#include <SDL2/SDL_audio.h> // para SDL_AudioFormat
|
enum JA_Channel_state { JA_CHANNEL_INVALID, JA_CHANNEL_FREE, JA_CHANNEL_PLAYING, JA_CHANNEL_PAUSED, JA_SOUND_DISABLED };
|
||||||
#include <SDL2/SDL_stdinc.h> // para Uint32, Uint8
|
enum JA_Music_state { JA_MUSIC_INVALID, JA_MUSIC_PLAYING, JA_MUSIC_PAUSED, JA_MUSIC_STOPPED, JA_MUSIC_DISABLED };
|
||||||
struct JA_Music_t; // lines 5-5
|
|
||||||
struct JA_Sound_t; // lines 6-6
|
|
||||||
|
|
||||||
enum JA_Channel_state
|
struct JA_Sound_t;
|
||||||
{
|
struct JA_Music_t;
|
||||||
JA_CHANNEL_INVALID,
|
|
||||||
JA_CHANNEL_FREE,
|
|
||||||
JA_CHANNEL_PLAYING,
|
|
||||||
JA_CHANNEL_PAUSED,
|
|
||||||
JA_SOUND_DISABLED
|
|
||||||
};
|
|
||||||
enum JA_Music_state
|
|
||||||
{
|
|
||||||
JA_MUSIC_INVALID,
|
|
||||||
JA_MUSIC_PLAYING,
|
|
||||||
JA_MUSIC_PAUSED,
|
|
||||||
JA_MUSIC_STOPPED,
|
|
||||||
JA_MUSIC_DISABLED
|
|
||||||
};
|
|
||||||
|
|
||||||
void JA_Init(const int freq, const SDL_AudioFormat format, const int channels);
|
void JA_Init(const int freq, const SDL_AudioFormat format, const int channels);
|
||||||
void JA_Quit();
|
void JA_Quit();
|
||||||
|
|
||||||
JA_Music_t *JA_LoadMusic(const char *filename);
|
JA_Music_t *JA_LoadMusic(const char* filename);
|
||||||
|
JA_Music_t *JA_LoadMusic(Uint8* buffer, Uint32 length);
|
||||||
void JA_PlayMusic(JA_Music_t *music, const int loop = -1);
|
void JA_PlayMusic(JA_Music_t *music, const int loop = -1);
|
||||||
void JA_PauseMusic();
|
void JA_PauseMusic();
|
||||||
void JA_ResumeMusic();
|
void JA_ResumeMusic();
|
||||||
void JA_StopMusic();
|
void JA_StopMusic();
|
||||||
|
void JA_FadeOutMusic(const int milliseconds);
|
||||||
JA_Music_state JA_GetMusicState();
|
JA_Music_state JA_GetMusicState();
|
||||||
void JA_DeleteMusic(JA_Music_t *music);
|
void JA_DeleteMusic(JA_Music_t *music);
|
||||||
int JA_SetMusicVolume(int volume);
|
int JA_SetMusicVolume(int volume);
|
||||||
|
void JA_SetMusicPosition(float value);
|
||||||
|
float JA_GetMusicPosition();
|
||||||
void JA_EnableMusic(const bool value);
|
void JA_EnableMusic(const bool value);
|
||||||
|
|
||||||
JA_Sound_t *JA_NewSound(Uint8 *buffer, Uint32 length);
|
JA_Sound_t *JA_NewSound(Uint8* buffer, Uint32 length);
|
||||||
JA_Sound_t *JA_LoadSound(const char *filename);
|
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_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_PauseChannel(const int channel);
|
||||||
void JA_ResumeChannel(const int channel);
|
void JA_ResumeChannel(const int channel);
|
||||||
void JA_StopChannel(const int channel);
|
void JA_StopChannel(const int channel);
|
||||||
|
|||||||
@@ -40,4 +40,12 @@ namespace lang
|
|||||||
{
|
{
|
||||||
return texts.at(index);
|
return texts.at(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Cambia el idioma seleccionado al siguiente idioma disponible
|
||||||
|
Code change(Code current_lang)
|
||||||
|
{
|
||||||
|
auto index = static_cast<int>(current_lang);
|
||||||
|
index = (index + 1) % 3;
|
||||||
|
return static_cast<Code>(index);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -16,4 +16,7 @@ namespace lang
|
|||||||
|
|
||||||
// Obtiene la cadena de texto del indice
|
// Obtiene la cadena de texto del indice
|
||||||
std::string getText(int index);
|
std::string getText(int index);
|
||||||
|
|
||||||
|
// Cambia el idioma seleccionado al siguiente idioma disponible
|
||||||
|
Code change(Code current_lang);
|
||||||
}
|
}
|
||||||
@@ -59,6 +59,7 @@ Logo::~Logo()
|
|||||||
{
|
{
|
||||||
jail_texture_->setColor(255, 255, 255);
|
jail_texture_->setColor(255, 255, 255);
|
||||||
since_texture_->setColor(255, 255, 255);
|
since_texture_->setColor(255, 255, 255);
|
||||||
|
JA_StopChannel(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recarga todas las texturas
|
// Recarga todas las texturas
|
||||||
@@ -100,7 +101,6 @@ void Logo::checkInput()
|
|||||||
// Comprueba si se ha pulsado cualquier botón (de los usados para jugar)
|
// Comprueba si se ha pulsado cualquier botón (de los usados para jugar)
|
||||||
if (Input::get()->checkAnyButtonPressed())
|
if (Input::get()->checkAnyButtonPressed())
|
||||||
{
|
{
|
||||||
JA_StopMusic();
|
|
||||||
section::name = section::Name::TITLE;
|
section::name = section::Name::TITLE;
|
||||||
section::options = section::Options::TITLE_1;
|
section::options = section::Options::TITLE_1;
|
||||||
return;
|
return;
|
||||||
@@ -113,6 +113,11 @@ void Logo::checkInput()
|
|||||||
// Gestiona el logo de JAILGAME
|
// Gestiona el logo de JAILGAME
|
||||||
void Logo::updateJAILGAMES()
|
void Logo::updateJAILGAMES()
|
||||||
{
|
{
|
||||||
|
if (counter_ == 30)
|
||||||
|
{
|
||||||
|
JA_PlaySound(Resource::get()->getSound("logo.wav"));
|
||||||
|
}
|
||||||
|
|
||||||
if (counter_ > 30)
|
if (counter_ > 30)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < (int)jail_sprite_.size(); ++i)
|
for (int i = 0; i < (int)jail_sprite_.size(); ++i)
|
||||||
@@ -195,6 +200,9 @@ void Logo::update()
|
|||||||
{
|
{
|
||||||
section::name = section::Name::INTRO;
|
section::name = section::Name::INTRO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Actualiza las variables de globalInputs
|
||||||
|
globalInputs::update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -226,7 +234,7 @@ void Logo::render()
|
|||||||
void Logo::run()
|
void Logo::run()
|
||||||
{
|
{
|
||||||
// Detiene la música
|
// Detiene la música
|
||||||
JA_StopMusic();
|
JA_FadeOutMusic(300);
|
||||||
|
|
||||||
while (section::name == section::Name::LOGO)
|
while (section::name == section::Name::LOGO)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -10,14 +10,15 @@
|
|||||||
#include "sprite.h" // Para Sprite
|
#include "sprite.h" // Para Sprite
|
||||||
#include "text.h" // Para Text
|
#include "text.h" // Para Text
|
||||||
#include "texture.h" // Para Texture
|
#include "texture.h" // Para Texture
|
||||||
|
#include "resource.h"
|
||||||
|
|
||||||
// [SINGLETON] Hay que definir las variables estáticas, desde el .h sólo la hemos declarado
|
// [SINGLETON] Hay que definir las variables estáticas, desde el .h sólo la hemos declarado
|
||||||
Notifier *Notifier::notifier_ = nullptr;
|
Notifier *Notifier::notifier_ = nullptr;
|
||||||
|
|
||||||
// [SINGLETON] Crearemos el objeto screen con esta función estática
|
// [SINGLETON] Crearemos el objeto screen con esta función estática
|
||||||
void Notifier::init(const std::string &icon_file, std::shared_ptr<Text> text, const std::string &sound_file)
|
void Notifier::init(const std::string &icon_file, std::shared_ptr<Text> text)
|
||||||
{
|
{
|
||||||
Notifier::notifier_ = new Notifier(icon_file, text, sound_file);
|
Notifier::notifier_ = new Notifier(icon_file, text);
|
||||||
}
|
}
|
||||||
|
|
||||||
// [SINGLETON] Destruiremos el objeto screen con esta función estática
|
// [SINGLETON] Destruiremos el objeto screen con esta función estática
|
||||||
@@ -33,21 +34,14 @@ Notifier *Notifier::get()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
Notifier::Notifier(std::string icon_file, std::shared_ptr<Text> text, const std::string &sound_file)
|
Notifier::Notifier(std::string icon_file, std::shared_ptr<Text> text)
|
||||||
: renderer_(Screen::get()->getRenderer()),
|
: renderer_(Screen::get()->getRenderer()),
|
||||||
icon_texture_(!icon_file.empty() ? std::make_unique<Texture>(renderer_, icon_file) : nullptr),
|
icon_texture_(!icon_file.empty() ? std::make_unique<Texture>(renderer_, icon_file) : nullptr),
|
||||||
text_(text),
|
text_(text),
|
||||||
bg_color_(param.notification.color),
|
bg_color_(param.notification.color),
|
||||||
wait_time_(150),
|
wait_time_(150),
|
||||||
stack_(false),
|
stack_(false),
|
||||||
has_icons_(!icon_file.empty()),
|
has_icons_(!icon_file.empty()) {}
|
||||||
sound_(JA_LoadSound(sound_file.c_str())) {}
|
|
||||||
|
|
||||||
// Destructor
|
|
||||||
Notifier::~Notifier()
|
|
||||||
{
|
|
||||||
JA_DeleteSound(sound_);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dibuja las notificaciones por pantalla
|
// Dibuja las notificaciones por pantalla
|
||||||
void Notifier::render()
|
void Notifier::render()
|
||||||
@@ -80,8 +74,9 @@ void Notifier::update()
|
|||||||
if (param.notification.sound)
|
if (param.notification.sound)
|
||||||
{
|
{
|
||||||
if (notifications_[i].status == NotificationStatus::RISING)
|
if (notifications_[i].status == NotificationStatus::RISING)
|
||||||
{ // Reproduce el sonido de la notificación
|
{
|
||||||
JA_PlaySound(sound_);
|
// Reproduce el sonido de la notificación
|
||||||
|
JA_PlaySound(Resource::get()->getSound("notify.wav"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,7 +62,6 @@ private:
|
|||||||
std::vector<Notification> notifications_; // La lista de notificaciones activas
|
std::vector<Notification> notifications_; // La lista de notificaciones activas
|
||||||
bool stack_; // Indica si las notificaciones se apilan
|
bool stack_; // Indica si las notificaciones se apilan
|
||||||
bool has_icons_; // Indica si el notificador tiene textura para iconos
|
bool has_icons_; // Indica si el notificador tiene textura para iconos
|
||||||
JA_Sound_t *sound_; // Sonido a reproducir cuando suena la notificación
|
|
||||||
|
|
||||||
// Elimina las notificaciones finalizadas
|
// Elimina las notificaciones finalizadas
|
||||||
void clearFinishedNotifications();
|
void clearFinishedNotifications();
|
||||||
@@ -73,14 +72,14 @@ private:
|
|||||||
// [SINGLETON] Ahora el constructor y el destructor son privados, para no poder crear objetos notifier desde fuera
|
// [SINGLETON] Ahora el constructor y el destructor son privados, para no poder crear objetos notifier desde fuera
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
Notifier(std::string icon_file, std::shared_ptr<Text> text, const std::string &sound_file);
|
Notifier(std::string icon_file, std::shared_ptr<Text> text);
|
||||||
|
|
||||||
// Destructor
|
// Destructor
|
||||||
~Notifier();
|
~Notifier() = default;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// [SINGLETON] Crearemos el objeto notifier con esta función estática
|
// [SINGLETON] Crearemos el objeto notifier con esta función estática
|
||||||
static void init(const std::string &icon_file, std::shared_ptr<Text> text, const std::string &sound_file);
|
static void init(const std::string &icon_file, std::shared_ptr<Text> text);
|
||||||
|
|
||||||
// [SINGLETON] Destruiremos el objeto notifier con esta función estática
|
// [SINGLETON] Destruiremos el objeto notifier con esta función estática
|
||||||
static void destroy();
|
static void destroy();
|
||||||
|
|||||||
@@ -23,7 +23,8 @@ enum class GameDifficulty
|
|||||||
// Estructura para las opciones de la ventana
|
// Estructura para las opciones de la ventana
|
||||||
struct OptionsWindow
|
struct OptionsWindow
|
||||||
{
|
{
|
||||||
int size; // Contiene el valor por el que se multiplica el tamaño de la ventana
|
int size = 1; // Contiene el valor por el que se multiplica el tamaño de la ventana
|
||||||
|
int max_size = 1; // Tamaño máximo para que el tamaño de la ventana no sea mayor que el tamaño de la pantalla
|
||||||
};
|
};
|
||||||
|
|
||||||
// Estructura con opciones para el video
|
// Estructura con opciones para el video
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
#include "path_sprite.h"
|
#include "path_sprite.h"
|
||||||
#include <cmath> // Para abs
|
#include <cstdlib> // Para abs
|
||||||
#include <stdlib.h> // Para abs
|
|
||||||
#include <functional> // Para function
|
#include <functional> // Para function
|
||||||
#include <utility> // Para move
|
#include <utility> // Para move
|
||||||
|
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
#include "player.h"
|
#include "player.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, SDL...
|
||||||
#include <SDL2/SDL_timer.h> // Para SDL_GetTicks
|
#include <SDL2/SDL_timer.h> // Para SDL_GetTicks
|
||||||
#include <stdlib.h> // Para rand
|
#include <stdlib.h> // Para rand
|
||||||
#include <algorithm> // Para max, min
|
#include <algorithm> // Para clamp, max, min
|
||||||
#include "animated_sprite.h" // Para AnimatedSprite
|
#include "animated_sprite.h" // Para AnimatedSprite
|
||||||
#include "input.h" // Para InputType
|
#include "input.h" // Para InputType
|
||||||
#include "manage_hiscore_table.h" // Para HiScoreEntry
|
#include "param.h" // Para Param, ParamGame, param
|
||||||
#include "options.h" // Para Options, OptionsGame, options
|
#include "scoreboard.h" // Para Scoreboard, ScoreboardMode
|
||||||
#include "param.h" // Para Param, ParamGame, param
|
#include "texture.h" // Para Texture
|
||||||
#include "scoreboard.h" // Para Scoreboard, ScoreboardMode
|
#include "resource.h"
|
||||||
#include "texture.h" // Para Texture
|
#include "jail_audio.h"
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
Player::Player(int id, float x, int y, bool demo, SDL_Rect &play_area, std::vector<std::shared_ptr<Texture>> texture, const std::vector<std::vector<std::string>> &animations)
|
Player::Player(int id, float x, int y, bool demo, SDL_Rect &play_area, std::vector<std::shared_ptr<Texture>> texture, const std::vector<std::vector<std::string>> &animations)
|
||||||
@@ -164,7 +164,7 @@ void Player::move()
|
|||||||
pos_x_ += vel_x_;
|
pos_x_ += vel_x_;
|
||||||
|
|
||||||
// Si el jugador abandona el area de juego por los laterales, restaura su posición
|
// Si el jugador abandona el area de juego por los laterales, restaura su posición
|
||||||
const float min_x = param.game.play_area.rect.x - 5;
|
const float min_x = play_area_.x - 5;
|
||||||
const float max_x = play_area_.w + 5 - WIDTH_;
|
const float max_x = play_area_.w + 5 - WIDTH_;
|
||||||
pos_x_ = std::clamp(pos_x_, min_x, max_x);
|
pos_x_ = std::clamp(pos_x_, min_x, max_x);
|
||||||
|
|
||||||
@@ -174,13 +174,14 @@ void Player::move()
|
|||||||
case PlayerState::DYING:
|
case PlayerState::DYING:
|
||||||
{
|
{
|
||||||
// Si el cadaver abandona el area de juego por los laterales lo hace rebotar
|
// Si el cadaver abandona el area de juego por los laterales lo hace rebotar
|
||||||
if ((player_sprite_->getPosX() < param.game.play_area.rect.x) || (player_sprite_->getPosX() + WIDTH_ > play_area_.w))
|
if ((player_sprite_->getPosX() < play_area_.x) || (player_sprite_->getPosX() + WIDTH_ > play_area_.w))
|
||||||
{
|
{
|
||||||
player_sprite_->setVelX(-player_sprite_->getVelX());
|
player_sprite_->setVelX(-player_sprite_->getVelX());
|
||||||
|
JA_PlaySound(Resource::get()->getSound("bubble4.wav"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Si el cadaver toca el suelo cambia el estado
|
// Si el cadaver toca el suelo cambia el estado
|
||||||
if (player_sprite_->getPosY() > param.game.play_area.rect.h - HEIGHT_)
|
if (player_sprite_->getPosY() > play_area_.h - HEIGHT_)
|
||||||
{
|
{
|
||||||
if (player_sprite_->getVelY() < 2.0f)
|
if (player_sprite_->getVelY() < 2.0f)
|
||||||
{
|
{
|
||||||
@@ -190,13 +191,15 @@ void Player::move()
|
|||||||
pos_y_ = default_pos_y_;
|
pos_y_ = default_pos_y_;
|
||||||
player_sprite_->clear();
|
player_sprite_->clear();
|
||||||
shiftSprite();
|
shiftSprite();
|
||||||
|
JA_PlaySound(Resource::get()->getSound("bubble4.wav"));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Decrementa las velocidades de rebote
|
// Decrementa las velocidades de rebote
|
||||||
player_sprite_->setPosY(param.game.play_area.rect.h - HEIGHT_);
|
player_sprite_->setPosY(play_area_.h - HEIGHT_);
|
||||||
player_sprite_->setVelY(player_sprite_->getVelY() * -0.5f);
|
player_sprite_->setVelY(player_sprite_->getVelY() * -0.5f);
|
||||||
player_sprite_->setVelX(player_sprite_->getVelX() * 0.75f);
|
player_sprite_->setVelX(player_sprite_->getVelX() * 0.75f);
|
||||||
|
JA_PlaySound(Resource::get()->getSound("bubble4.wav"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -224,6 +227,41 @@ void Player::move()
|
|||||||
setPlayingState(PlayerState::GAME_OVER);
|
setPlayingState(PlayerState::GAME_OVER);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case PlayerState::CREDITS:
|
||||||
|
{
|
||||||
|
pos_x_ += vel_x_ / 2.0f;
|
||||||
|
if (vel_x_ > 0)
|
||||||
|
{
|
||||||
|
// setInputPlaying(InputType::RIGHT);
|
||||||
|
if (pos_x_ > param.game.game_area.rect.w - WIDTH_)
|
||||||
|
{
|
||||||
|
pos_x_ = param.game.game_area.rect.w - WIDTH_;
|
||||||
|
vel_x_ *= -1;
|
||||||
|
// setInputPlaying(InputType::LEFT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// setInputPlaying(InputType::LEFT);
|
||||||
|
if (pos_x_ < param.game.game_area.rect.x)
|
||||||
|
{
|
||||||
|
pos_x_ = param.game.game_area.rect.x;
|
||||||
|
vel_x_ *= -1;
|
||||||
|
// setInputPlaying(InputType::RIGHT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pos_x_ > param.game.game_area.center_x - WIDTH_ / 2)
|
||||||
|
{
|
||||||
|
setWalkingState(PlayerState::WALKING_LEFT);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setWalkingState(PlayerState::WALKING_RIGHT);
|
||||||
|
}
|
||||||
|
shiftSprite();
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -254,6 +292,7 @@ void Player::setAnimation()
|
|||||||
case PlayerState::PLAYING:
|
case PlayerState::PLAYING:
|
||||||
case PlayerState::ENTERING_NAME_GAME_COMPLETED:
|
case PlayerState::ENTERING_NAME_GAME_COMPLETED:
|
||||||
case PlayerState::LEAVING_SCREEN:
|
case PlayerState::LEAVING_SCREEN:
|
||||||
|
case PlayerState::CREDITS:
|
||||||
{
|
{
|
||||||
// Crea cadenas de texto para componer el nombre de la animación
|
// Crea cadenas de texto para componer el nombre de la animación
|
||||||
const std::string a_walking = walking_state_ == PlayerState::WALKING_STOP ? "stand" : "walk";
|
const std::string a_walking = walking_state_ == PlayerState::WALKING_STOP ? "stand" : "walk";
|
||||||
@@ -470,6 +509,11 @@ void Player::setPlayingState(PlayerState state)
|
|||||||
setScoreboardMode(ScoreboardMode::GAME_COMPLETED);
|
setScoreboardMode(ScoreboardMode::GAME_COMPLETED);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case PlayerState::CREDITS:
|
||||||
|
{
|
||||||
|
vel_x_ = (walking_state_ == PlayerState::WALKING_RIGHT) ? BASE_SPEED_ : -BASE_SPEED_;
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -615,9 +659,13 @@ void Player::decEnterNameCounter()
|
|||||||
{
|
{
|
||||||
enter_name_counter_ = param.game.enter_name_seconds;
|
enter_name_counter_ = param.game.enter_name_seconds;
|
||||||
if (playing_state_ == PlayerState::ENTERING_NAME)
|
if (playing_state_ == PlayerState::ENTERING_NAME)
|
||||||
|
{
|
||||||
setPlayingState(PlayerState::CONTINUE);
|
setPlayingState(PlayerState::CONTINUE);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
setPlayingState(PlayerState::LEAVING_SCREEN);
|
setPlayingState(PlayerState::LEAVING_SCREEN);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -625,7 +673,9 @@ void Player::decEnterNameCounter()
|
|||||||
int Player::getRecordNamePos() const
|
int Player::getRecordNamePos() const
|
||||||
{
|
{
|
||||||
if (enter_name_)
|
if (enter_name_)
|
||||||
|
{
|
||||||
return enter_name_->getPosition();
|
return enter_name_->getPosition();
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "animated_sprite.h" // Para AnimatedSprite
|
#include <SDL2/SDL_rect.h> // Para SDL_Rect
|
||||||
#include "enter_name.h" // Para EnterName
|
#include <SDL2/SDL_stdinc.h> // Para Uint32
|
||||||
#include "utils.h" // Para Circle
|
#include <memory> // Para unique_ptr, shared_ptr
|
||||||
#include <SDL2/SDL_rect.h> // Para SDL_Rect
|
#include <string> // Para string
|
||||||
#include <SDL2/SDL_stdinc.h> // Para Uint32
|
#include <vector> // Para vector
|
||||||
#include <memory> // Para unique_ptr, shared_ptr
|
#include "animated_sprite.h" // Para AnimatedSprite
|
||||||
#include <string> // Para string
|
#include "enter_name.h" // Para EnterName
|
||||||
#include <vector> // Para vector
|
#include "manage_hiscore_table.h" // Para HiScoreEntry
|
||||||
#include "options.h"
|
#include "options.h" // Para Options, OptionsGame, options
|
||||||
|
#include "utils.h" // Para Circle
|
||||||
class Texture; // lines 12-12
|
class Texture; // lines 13-13
|
||||||
enum class InputType : int; // lines 13-13
|
enum class InputType : int; // lines 14-14
|
||||||
enum class ScoreboardMode; // lines 14-14
|
enum class ScoreboardMode; // lines 15-15
|
||||||
|
|
||||||
// Estados del jugador
|
// Estados del jugador
|
||||||
enum class PlayerState
|
enum class PlayerState
|
||||||
@@ -40,6 +40,7 @@ enum class PlayerState
|
|||||||
CELEBRATING, // Poniendo pose de victoria
|
CELEBRATING, // Poniendo pose de victoria
|
||||||
ENTERING_NAME_GAME_COMPLETED, // Poniendo nombre en el tramo final del juego
|
ENTERING_NAME_GAME_COMPLETED, // Poniendo nombre en el tramo final del juego
|
||||||
LEAVING_SCREEN, // Moviendose fuera de la pantalla
|
LEAVING_SCREEN, // Moviendose fuera de la pantalla
|
||||||
|
CREDITS, // Estado para los creditos del juego
|
||||||
};
|
};
|
||||||
|
|
||||||
// Clase Player
|
// Clase Player
|
||||||
|
|||||||
@@ -34,6 +34,24 @@ Resource *Resource::get()
|
|||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
Resource::Resource()
|
Resource::Resource()
|
||||||
|
{
|
||||||
|
load();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Vacia todos los vectores de recursos
|
||||||
|
void Resource::clear()
|
||||||
|
{
|
||||||
|
clearSounds();
|
||||||
|
clearMusics();
|
||||||
|
textures_.clear();
|
||||||
|
text_files_.clear();
|
||||||
|
texts_.clear();
|
||||||
|
animations_.clear();
|
||||||
|
demos_.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Carga todos los recursos
|
||||||
|
void Resource::load()
|
||||||
{
|
{
|
||||||
std::cout << "** LOADING RESOURCES" << std::endl;
|
std::cout << "** LOADING RESOURCES" << std::endl;
|
||||||
loadSounds();
|
loadSounds();
|
||||||
@@ -48,6 +66,13 @@ Resource::Resource()
|
|||||||
std::cout << "\n** RESOURCES LOADED" << std::endl;
|
std::cout << "\n** RESOURCES LOADED" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Recarga todos los recursos
|
||||||
|
void Resource::reload()
|
||||||
|
{
|
||||||
|
clear();
|
||||||
|
load();
|
||||||
|
}
|
||||||
|
|
||||||
// Obtiene el sonido a partir de un nombre
|
// Obtiene el sonido a partir de un nombre
|
||||||
JA_Sound_t *Resource::getSound(const std::string &name)
|
JA_Sound_t *Resource::getSound(const std::string &name)
|
||||||
{
|
{
|
||||||
@@ -265,7 +290,7 @@ void Resource::createTextures()
|
|||||||
NameAndText("game_text_powerup", lang::getText(117)),
|
NameAndText("game_text_powerup", lang::getText(117)),
|
||||||
NameAndText("game_text_one_hit", lang::getText(118)),
|
NameAndText("game_text_one_hit", lang::getText(118)),
|
||||||
NameAndText("game_text_stop", lang::getText(119)),
|
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");
|
auto text = getText("04b_25");
|
||||||
for (const auto &s : strings)
|
for (const auto &s : strings)
|
||||||
@@ -276,10 +301,10 @@ void Resource::createTextures()
|
|||||||
|
|
||||||
// Tamaño doble
|
// Tamaño doble
|
||||||
std::vector<NameAndText> strings2X = {
|
std::vector<NameAndText> strings2X = {
|
||||||
NameAndText("get_ready", lang::getText(75)),
|
NameAndText("game_text_get_ready", lang::getText(75)),
|
||||||
NameAndText("last_stage", lang::getText(79)),
|
NameAndText("game_text_last_stage", lang::getText(79)),
|
||||||
NameAndText("congratulations", lang::getText(50)),
|
NameAndText("game_text_congratulations", lang::getText(50)),
|
||||||
NameAndText("game_over", "Game Over")};
|
NameAndText("game_text_game_over", "Game Over")};
|
||||||
|
|
||||||
auto text2 = getText("04b_25_2x");
|
auto text2 = getText("04b_25_2x");
|
||||||
for (const auto &s : strings2X)
|
for (const auto &s : strings2X)
|
||||||
@@ -307,3 +332,33 @@ void Resource::createText()
|
|||||||
printWithDots("Text : ", resource.first, "[ DONE ]");
|
printWithDots("Text : ", resource.first, "[ DONE ]");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Vacía el vector de sonidos
|
||||||
|
void Resource::clearSounds()
|
||||||
|
{
|
||||||
|
// Itera sobre el vector y libera los recursos asociados a cada JA_Sound_t
|
||||||
|
for (auto &sound : sounds_)
|
||||||
|
{
|
||||||
|
if (sound.sound)
|
||||||
|
{
|
||||||
|
JA_DeleteSound(sound.sound);
|
||||||
|
sound.sound = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sounds_.clear(); // Limpia el vector después de liberar todos los recursos
|
||||||
|
}
|
||||||
|
|
||||||
|
// Vacía el vector de musicas
|
||||||
|
void Resource::clearMusics()
|
||||||
|
{
|
||||||
|
// Itera sobre el vector y libera los recursos asociados a cada JA_Music_t
|
||||||
|
for (auto &music : musics_)
|
||||||
|
{
|
||||||
|
if (music.music)
|
||||||
|
{
|
||||||
|
JA_DeleteMusic(music.music);
|
||||||
|
music.music = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
musics_.clear(); // Limpia el vector después de liberar todos los recursos
|
||||||
|
}
|
||||||
@@ -117,6 +117,18 @@ private:
|
|||||||
// Crea los objetos de texto
|
// Crea los objetos de texto
|
||||||
void createText();
|
void createText();
|
||||||
|
|
||||||
|
// Vacia todos los vectores de recursos
|
||||||
|
void clear();
|
||||||
|
|
||||||
|
// Carga todos los recursos
|
||||||
|
void load();
|
||||||
|
|
||||||
|
// Vacía el vector de sonidos
|
||||||
|
void clearSounds();
|
||||||
|
|
||||||
|
// Vacía el vector de musicas
|
||||||
|
void clearMusics();
|
||||||
|
|
||||||
// [SINGLETON] Ahora el constructor y el destructor son privados, para no poder crear objetos resource desde fuera
|
// [SINGLETON] Ahora el constructor y el destructor son privados, para no poder crear objetos resource desde fuera
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
@@ -155,4 +167,7 @@ public:
|
|||||||
|
|
||||||
// Obtiene el fichero con los datos para el modo demostración a partir de un çindice
|
// Obtiene el fichero con los datos para el modo demostración a partir de un çindice
|
||||||
DemoData &getDemoData(int index);
|
DemoData &getDemoData(int index);
|
||||||
|
|
||||||
|
// Recarga todos los recursos
|
||||||
|
void reload();
|
||||||
};
|
};
|
||||||
@@ -11,7 +11,6 @@
|
|||||||
#include "asset.h" // Para Asset
|
#include "asset.h" // Para Asset
|
||||||
#include "dbgtxt.h" // Para dbg_print
|
#include "dbgtxt.h" // Para dbg_print
|
||||||
#include "global_inputs.h" // Para service_pressed_counter
|
#include "global_inputs.h" // Para service_pressed_counter
|
||||||
#include "jail_shader.h" // Para init, render
|
|
||||||
#include "notifier.h" // Para Notifier
|
#include "notifier.h" // Para Notifier
|
||||||
#include "on_screen_help.h" // Para OnScreenHelp
|
#include "on_screen_help.h" // Para OnScreenHelp
|
||||||
#include "options.h" // Para Options, OptionsVideo, options, Options...
|
#include "options.h" // Para Options, OptionsVideo, options, Options...
|
||||||
@@ -89,10 +88,10 @@ void Screen::blit()
|
|||||||
fps_counter_++;
|
fps_counter_++;
|
||||||
|
|
||||||
// Actualiza y dibuja el efecto de flash en la pantalla
|
// Actualiza y dibuja el efecto de flash en la pantalla
|
||||||
doFlash();
|
renderFlash();
|
||||||
|
|
||||||
// Atenua la pantalla
|
// Atenua la pantalla
|
||||||
doAttenuate();
|
renderAttenuate();
|
||||||
|
|
||||||
// Muestra la ayuda por pantalla
|
// Muestra la ayuda por pantalla
|
||||||
OnScreenHelp::get()->render();
|
OnScreenHelp::get()->render();
|
||||||
@@ -201,7 +200,8 @@ void Screen::setVideoMode(ScreenVideoMode videoMode)
|
|||||||
if (options.video.shaders)
|
if (options.video.shaders)
|
||||||
{
|
{
|
||||||
#ifndef NO_SHADERS
|
#ifndef NO_SHADERS
|
||||||
std::ifstream f(Asset::get()->get("crtpi.glsl").c_str());
|
const std::string glsl_file = param.game.game_area.rect.h == 256 ? "crtpi_256.glsl" : "crtpi_240.glsl";
|
||||||
|
std::ifstream f(Asset::get()->get(glsl_file).c_str());
|
||||||
std::string source((std::istreambuf_iterator<char>(f)), std::istreambuf_iterator<char>());
|
std::string source((std::istreambuf_iterator<char>(f)), std::istreambuf_iterator<char>());
|
||||||
|
|
||||||
shader::init(window_, shader_canvas_, source.c_str());
|
shader::init(window_, shader_canvas_, source.c_str());
|
||||||
@@ -235,7 +235,7 @@ void Screen::decWindowSize()
|
|||||||
void Screen::incWindowSize()
|
void Screen::incWindowSize()
|
||||||
{
|
{
|
||||||
++options.video.window.size;
|
++options.video.window.size;
|
||||||
options.video.window.size = std::min(options.video.window.size, 4);
|
options.video.window.size = std::min(options.video.window.size, options.video.window.max_size);
|
||||||
setVideoMode(ScreenVideoMode::WINDOW);
|
setVideoMode(ScreenVideoMode::WINDOW);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -255,6 +255,7 @@ void Screen::setBlendMode(SDL_BlendMode blendMode)
|
|||||||
void Screen::update()
|
void Screen::update()
|
||||||
{
|
{
|
||||||
updateShakeEffect();
|
updateShakeEffect();
|
||||||
|
updateFlash();
|
||||||
Notifier::get()->update();
|
Notifier::get()->update();
|
||||||
updateFPS();
|
updateFPS();
|
||||||
OnScreenHelp::get()->update();
|
OnScreenHelp::get()->update();
|
||||||
@@ -307,27 +308,29 @@ void Screen::updateShakeEffect()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Pone la pantalla de color
|
// Pone la pantalla de color
|
||||||
void Screen::flash(Color color, int lenght)
|
void Screen::flash(Color color, int lenght, int delay)
|
||||||
{
|
{
|
||||||
flash_effect_ = FlashEffect(true, lenght, color);
|
flash_effect_ = FlashEffect(true, lenght, delay, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Actualiza y dibuja el efecto de flash en la pantalla
|
// Actualiza y dibuja el efecto de flash en la pantalla
|
||||||
void Screen::doFlash()
|
void Screen::renderFlash()
|
||||||
{
|
{
|
||||||
if (flash_effect_.enabled)
|
if (flash_effect_.isRendarable())
|
||||||
{
|
{
|
||||||
// Dibuja el color del flash en la textura
|
|
||||||
SDL_SetRenderDrawColor(renderer_, flash_effect_.color.r, flash_effect_.color.g, flash_effect_.color.b, 0xFF);
|
SDL_SetRenderDrawColor(renderer_, flash_effect_.color.r, flash_effect_.color.g, flash_effect_.color.b, 0xFF);
|
||||||
SDL_RenderClear(renderer_);
|
SDL_RenderClear(renderer_);
|
||||||
|
|
||||||
// Actualiza la lógica del efecto
|
|
||||||
flash_effect_.counter > 0 ? flash_effect_.counter-- : flash_effect_.enabled = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Actualiza el efecto de flash
|
||||||
|
void Screen::updateFlash()
|
||||||
|
{
|
||||||
|
flash_effect_.update();
|
||||||
|
}
|
||||||
|
|
||||||
// Atenua la pantalla
|
// Atenua la pantalla
|
||||||
void Screen::doAttenuate()
|
void Screen::renderAttenuate()
|
||||||
{
|
{
|
||||||
if (attenuate_effect_)
|
if (attenuate_effect_)
|
||||||
{
|
{
|
||||||
@@ -387,7 +390,7 @@ void Screen::renderInfo()
|
|||||||
dbg_print(0, 0, info_resolution_.c_str(), 255, 255, 0);
|
dbg_print(0, 0, info_resolution_.c_str(), 255, 255, 0);
|
||||||
|
|
||||||
// Contador de service_pressed_counter
|
// Contador de service_pressed_counter
|
||||||
if (const int counter = globalInputs::service_pressed_counter[0]; counter > 0)
|
if (const int counter = globalInputs::service_pressed_counter; counter > 0)
|
||||||
dbg_print(0, 8, std::to_string(counter).c_str(), 255, 0, 255);
|
dbg_print(0, 8, std::to_string(counter).c_str(), 255, 0, 255);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,12 +51,20 @@ private:
|
|||||||
struct FlashEffect
|
struct FlashEffect
|
||||||
{
|
{
|
||||||
bool enabled; // Indica si el efecto está activo
|
bool enabled; // Indica si el efecto está activo
|
||||||
|
int lenght; // Duración del efecto
|
||||||
|
int delay; // Frames iniciales en los que no se aplica
|
||||||
int counter; // Contador para el efecto
|
int counter; // Contador para el efecto
|
||||||
Color color; // Color del efecto
|
Color color; // Color del efecto
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
explicit FlashEffect(bool en = false, int cnt = 0, Color col = Color(0xFF, 0xFF, 0xFF))
|
explicit FlashEffect(bool enabled = false, int lenght = 0, int delay = 0, Color color = Color(0xFF, 0xFF, 0xFF))
|
||||||
: enabled(en), counter(cnt), color(col) {}
|
: enabled(enabled), lenght(lenght), delay(delay), counter(lenght), color(color) {}
|
||||||
|
|
||||||
|
// Actualiza
|
||||||
|
void update() { (enabled && counter > 0) ? counter-- : enabled = false; }
|
||||||
|
|
||||||
|
// Indica si se pude dibujar
|
||||||
|
bool isRendarable() { return enabled && counter < lenght - delay; }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ShakeEffect
|
struct ShakeEffect
|
||||||
@@ -82,11 +90,14 @@ private:
|
|||||||
// Actualiza la logica para agitar la pantalla
|
// Actualiza la logica para agitar la pantalla
|
||||||
void updateShakeEffect();
|
void updateShakeEffect();
|
||||||
|
|
||||||
// Actualiza y dibuja el efecto de flash en la pantalla
|
// Dibuja el efecto de flash en la pantalla
|
||||||
void doFlash();
|
void renderFlash();
|
||||||
|
|
||||||
|
// Actualiza el efecto de flash
|
||||||
|
void updateFlash();
|
||||||
|
|
||||||
// Atenua la pantalla
|
// Atenua la pantalla
|
||||||
void doAttenuate();
|
void renderAttenuate();
|
||||||
|
|
||||||
// Calcula los frames por segundo
|
// Calcula los frames por segundo
|
||||||
void updateFPS();
|
void updateFPS();
|
||||||
@@ -152,7 +163,7 @@ public:
|
|||||||
void shake();
|
void shake();
|
||||||
|
|
||||||
// Pone la pantalla de color
|
// Pone la pantalla de color
|
||||||
void flash(Color color, int lenght);
|
void flash(Color color, int lenght, int delay = 0);
|
||||||
|
|
||||||
// Activa / desactiva los shaders
|
// Activa / desactiva los shaders
|
||||||
void toggleShaders();
|
void toggleShaders();
|
||||||
|
|||||||
@@ -13,7 +13,8 @@ namespace section
|
|||||||
HI_SCORE_TABLE = 5,
|
HI_SCORE_TABLE = 5,
|
||||||
GAME_DEMO = 6,
|
GAME_DEMO = 6,
|
||||||
INSTRUCTIONS = 7,
|
INSTRUCTIONS = 7,
|
||||||
QUIT = 8,
|
CREDITS = 8,
|
||||||
|
QUIT = 9,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Opciones para la sección
|
// Opciones para la sección
|
||||||
@@ -26,7 +27,8 @@ namespace section
|
|||||||
QUIT_WITH_KEYBOARD = 4,
|
QUIT_WITH_KEYBOARD = 4,
|
||||||
QUIT_WITH_CONTROLLER = 5,
|
QUIT_WITH_CONTROLLER = 5,
|
||||||
QUIT_FROM_EVENT = 6,
|
QUIT_FROM_EVENT = 6,
|
||||||
NONE = 7,
|
RELOAD = 7,
|
||||||
|
NONE = 8,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Variables para el Attract Mode
|
// Variables para el Attract Mode
|
||||||
|
|||||||
@@ -19,31 +19,7 @@ Sprite::Sprite(std::shared_ptr<Texture> texture)
|
|||||||
// Muestra el sprite por pantalla
|
// Muestra el sprite por pantalla
|
||||||
void Sprite::render()
|
void Sprite::render()
|
||||||
{
|
{
|
||||||
texture_->render(pos_.x, pos_.y, &sprite_clip_);
|
texture_->render(pos_.x, pos_.y, &sprite_clip_, zoom_, zoom_);
|
||||||
}
|
|
||||||
|
|
||||||
// Obten el valor de la variable
|
|
||||||
int Sprite::getX() const
|
|
||||||
{
|
|
||||||
return pos_.x;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Obten el valor de la variable
|
|
||||||
int Sprite::getY() const
|
|
||||||
{
|
|
||||||
return pos_.y;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Obten el valor de la variable
|
|
||||||
int Sprite::getWidth() const
|
|
||||||
{
|
|
||||||
return pos_.w;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Obten el valor de la variable
|
|
||||||
int Sprite::getHeight() const
|
|
||||||
{
|
|
||||||
return pos_.h;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Establece la posición del objeto
|
// Establece la posición del objeto
|
||||||
@@ -60,84 +36,6 @@ void Sprite::setPosition(SDL_Point p)
|
|||||||
pos_.y = p.y;
|
pos_.y = p.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Establece la posición del objeto
|
|
||||||
void Sprite::setPosition(SDL_Rect r)
|
|
||||||
{
|
|
||||||
pos_ = r;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Establece el valor de la variable
|
|
||||||
void Sprite::setX(int x)
|
|
||||||
{
|
|
||||||
pos_.x = x;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Establece el valor de la variable
|
|
||||||
void Sprite::setY(int y)
|
|
||||||
{
|
|
||||||
pos_.y = y;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Establece el valor de la variable
|
|
||||||
void Sprite::setWidth(int w)
|
|
||||||
{
|
|
||||||
pos_.w = w;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Establece el valor de la variable
|
|
||||||
void Sprite::setHeight(int h)
|
|
||||||
{
|
|
||||||
pos_.h = h;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Obten el valor de la variable
|
|
||||||
SDL_Rect Sprite::getSpriteClip() const
|
|
||||||
{
|
|
||||||
return sprite_clip_;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Establece el valor de la variable
|
|
||||||
void Sprite::setSpriteClip(SDL_Rect rect)
|
|
||||||
{
|
|
||||||
sprite_clip_ = rect;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Establece el valor de la variable
|
|
||||||
void Sprite::setSpriteClip(int x, int y, int w, int h)
|
|
||||||
{
|
|
||||||
sprite_clip_ = (SDL_Rect){x, y, w, h};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Obten el valor de la variable
|
|
||||||
std::shared_ptr<Texture> Sprite::getTexture() const
|
|
||||||
{
|
|
||||||
return texture_;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Establece el valor de la variable
|
|
||||||
void Sprite::setTexture(std::shared_ptr<Texture> texture)
|
|
||||||
{
|
|
||||||
texture_ = texture;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Devuelve el rectangulo donde está el sprite
|
|
||||||
SDL_Rect Sprite::getPosition() const
|
|
||||||
{
|
|
||||||
return pos_;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Incrementa el valor de la variable
|
|
||||||
void Sprite::incX(int value)
|
|
||||||
{
|
|
||||||
pos_.x += value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Incrementa el valor de la variable
|
|
||||||
void Sprite::incY(int value)
|
|
||||||
{
|
|
||||||
pos_.y += value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reinicia las variables a cero
|
// Reinicia las variables a cero
|
||||||
void Sprite::clear()
|
void Sprite::clear()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ protected:
|
|||||||
std::shared_ptr<Texture> texture_; // Textura donde estan todos los dibujos del sprite
|
std::shared_ptr<Texture> texture_; // Textura donde estan todos los dibujos del sprite
|
||||||
SDL_Rect pos_; // Posición y tamaño donde dibujar el sprite
|
SDL_Rect pos_; // Posición y tamaño donde dibujar el sprite
|
||||||
SDL_Rect sprite_clip_; // Rectangulo de origen de la textura que se dibujará en pantalla
|
SDL_Rect sprite_clip_; // Rectangulo de origen de la textura que se dibujará en pantalla
|
||||||
|
double zoom_ = 1.0f; // Zoom aplicado a la textura
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Constructor
|
// Constructor
|
||||||
@@ -28,40 +29,43 @@ public:
|
|||||||
// Reinicia las variables a cero
|
// Reinicia las variables a cero
|
||||||
virtual void clear();
|
virtual void clear();
|
||||||
|
|
||||||
// Obten el valor de la variable
|
// Obtiene la posición y el tamaño
|
||||||
int getX() const;
|
int getX() const { return pos_.x; }
|
||||||
int getY() const;
|
int getY() const { return pos_.y; }
|
||||||
int getWidth() const;
|
int getWidth() const { return pos_.w; }
|
||||||
int getHeight() const;
|
int getHeight() const { return pos_.h; }
|
||||||
|
|
||||||
// Devuelve el rectangulo donde está el sprite
|
// Devuelve el rectangulo donde está el sprite
|
||||||
SDL_Rect getPosition() const;
|
SDL_Rect getPosition() const { return pos_; }
|
||||||
|
|
||||||
// Establece el valor de la variable
|
// Establece la posición y el tamaño
|
||||||
void setX(int x);
|
void setX(int x) { pos_.x = x; }
|
||||||
void setY(int y);
|
void setY(int y) { pos_.y = y; }
|
||||||
void setWidth(int w);
|
void setWidth(int w) { pos_.w = w; }
|
||||||
void setHeight(int h);
|
void setHeight(int h) { pos_.h = h; }
|
||||||
|
|
||||||
// Establece la posición del objeto
|
// Establece la posición del objeto
|
||||||
void setPosition(int x, int y);
|
void setPosition(int x, int y);
|
||||||
void setPosition(SDL_Point p);
|
void setPosition(SDL_Point p);
|
||||||
void setPosition(SDL_Rect r);
|
void setPosition(SDL_Rect r) { pos_ = r; }
|
||||||
|
|
||||||
// Incrementa el valor de la variable
|
// Establece el nivel de zoom
|
||||||
void incX(int value);
|
void setZoom(float zoom) { zoom_ = zoom; }
|
||||||
void incY(int value);
|
|
||||||
|
|
||||||
// Obten el valor de la variable
|
// Aumenta o disminuye la posición
|
||||||
SDL_Rect getSpriteClip() const;
|
void incX(int value) { pos_.x += value; }
|
||||||
|
void incY(int value) { pos_.y += value; }
|
||||||
|
|
||||||
// Establece el valor de la variable
|
// Obtiene el rectangulo que se dibuja de la textura
|
||||||
void setSpriteClip(SDL_Rect rect);
|
SDL_Rect getSpriteClip() const { return sprite_clip_; }
|
||||||
void setSpriteClip(int x, int y, int w, int h);
|
|
||||||
|
|
||||||
// Obten el valor de la variable
|
// Establece el rectangulo que se dibuja de la textura
|
||||||
std::shared_ptr<Texture> getTexture() const;
|
void setSpriteClip(SDL_Rect rect) { sprite_clip_ = rect; }
|
||||||
|
void setSpriteClip(int x, int y, int w, int h) { sprite_clip_ = (SDL_Rect){x, y, w, h}; }
|
||||||
|
|
||||||
// Establece el valor de la variable
|
// Obtiene un puntero a la textura
|
||||||
void setTexture(std::shared_ptr<Texture> texture);
|
std::shared_ptr<Texture> getTexture() const { return texture_; }
|
||||||
|
|
||||||
|
// Establece la textura a utilizar
|
||||||
|
void setTexture(std::shared_ptr<Texture> texture) { texture_ = texture; }
|
||||||
};
|
};
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
#include "stage.h"
|
#include "stage.h"
|
||||||
#include <vector>
|
#include <algorithm> // Para min
|
||||||
|
#include <vector> // Para vector
|
||||||
|
|
||||||
namespace Stage
|
namespace Stage
|
||||||
{
|
{
|
||||||
|
|||||||
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 texture = std::make_shared<Texture>(renderer);
|
||||||
auto width = lenght(text, kerning) * zoom;
|
auto width = lenght(text, kerning) * zoom;
|
||||||
auto height = box_height_ * zoom;
|
auto height = box_height_ * zoom;
|
||||||
|
auto temp = SDL_GetRenderTarget(renderer);
|
||||||
texture->createBlank(width, height, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET);
|
texture->createBlank(width, height, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET);
|
||||||
texture->setBlendMode(SDL_BLENDMODE_BLEND);
|
texture->setBlendMode(SDL_BLENDMODE_BLEND);
|
||||||
texture->setAsRenderTarget(renderer);
|
texture->setAsRenderTarget(renderer);
|
||||||
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
|
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
|
||||||
SDL_RenderClear(renderer);
|
SDL_RenderClear(renderer);
|
||||||
zoom == 1 ? write(0, 0, text, kerning) : write2X(0, 0, text, kerning);
|
zoom == 1 ? write(0, 0, text, kerning) : write2X(0, 0, text, kerning);
|
||||||
|
SDL_SetRenderTarget(renderer, temp);
|
||||||
|
|
||||||
return texture;
|
return texture;
|
||||||
}
|
}
|
||||||
@@ -264,4 +266,13 @@ void Text::reLoadTexture()
|
|||||||
void Text::setFixedWidth(bool value)
|
void Text::setFixedWidth(bool value)
|
||||||
{
|
{
|
||||||
fixed_width_ = value;
|
fixed_width_ = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Establece una paleta
|
||||||
|
void Text::setPalette(int number)
|
||||||
|
{
|
||||||
|
auto temp = SDL_GetRenderTarget(Screen::get()->getRenderer());
|
||||||
|
SDL_SetRenderTarget(Screen::get()->getRenderer(), nullptr);
|
||||||
|
sprite_->getTexture()->setPalette(number);
|
||||||
|
SDL_SetRenderTarget(Screen::get()->getRenderer(), temp);
|
||||||
}
|
}
|
||||||
@@ -78,4 +78,7 @@ public:
|
|||||||
|
|
||||||
// Establece si se usa un tamaño fijo de letra
|
// Establece si se usa un tamaño fijo de letra
|
||||||
void setFixedWidth(bool value);
|
void setFixedWidth(bool value);
|
||||||
|
|
||||||
|
// Establece una paleta
|
||||||
|
void setPalette(int number);
|
||||||
};
|
};
|
||||||
@@ -190,8 +190,16 @@ void Texture::render(int x, int y, SDL_Rect *clip, float zoomW, float zoomH, dou
|
|||||||
renderQuad.h = clip->h;
|
renderQuad.h = clip->h;
|
||||||
}
|
}
|
||||||
|
|
||||||
renderQuad.w = renderQuad.w * zoomW;
|
// Calcula el zoom y las coordenadas
|
||||||
renderQuad.h = renderQuad.h * zoomH;
|
if (zoomH != 1.0f || zoomW != 1.0f)
|
||||||
|
{
|
||||||
|
renderQuad.x = renderQuad.x + (renderQuad.w / 2);
|
||||||
|
renderQuad.y = renderQuad.y + (renderQuad.h / 2);
|
||||||
|
renderQuad.w = renderQuad.w * zoomW;
|
||||||
|
renderQuad.h = renderQuad.h * zoomH;
|
||||||
|
renderQuad.x = renderQuad.x - (renderQuad.w / 2);
|
||||||
|
renderQuad.y = renderQuad.y - (renderQuad.h / 2);
|
||||||
|
}
|
||||||
|
|
||||||
// Renderiza a pantalla
|
// Renderiza a pantalla
|
||||||
SDL_RenderCopyEx(renderer_, texture_, clip, &renderQuad, angle, center, flip);
|
SDL_RenderCopyEx(renderer_, texture_, clip, &renderQuad, angle, center, flip);
|
||||||
|
|||||||
@@ -29,15 +29,16 @@
|
|||||||
Title::Title()
|
Title::Title()
|
||||||
: text_(Resource::get()->getText("smb2")),
|
: text_(Resource::get()->getText("smb2")),
|
||||||
fade_(std::make_unique<Fade>()),
|
fade_(std::make_unique<Fade>()),
|
||||||
tiled_bg_(std::make_unique<TiledBG>((SDL_Rect){0, 0, param.game.width, param.game.height}, TiledBGMode::RANDOM)),
|
tiled_bg_(std::make_unique<TiledBG>(param.game.game_area.rect, TiledBGMode::RANDOM)),
|
||||||
game_logo_(std::make_unique<GameLogo>(param.game.game_area.center_x, param.title.title_c_c_position)),
|
game_logo_(std::make_unique<GameLogo>(param.game.game_area.center_x, param.title.title_c_c_position)),
|
||||||
mini_logo_texture_(Resource::get()->getTexture("logo_jailgames_mini.png")),
|
mini_logo_sprite_(std::make_unique<Sprite>(Resource::get()->getTexture("logo_jailgames_mini.png"))),
|
||||||
mini_logo_sprite_(std::make_unique<Sprite>(mini_logo_texture_, param.game.game_area.center_x - mini_logo_texture_->getWidth() / 2, 0, mini_logo_texture_->getWidth(), mini_logo_texture_->getHeight())),
|
|
||||||
define_buttons_(std::make_unique<DefineButtons>()),
|
define_buttons_(std::make_unique<DefineButtons>()),
|
||||||
num_controllers_(Input::get()->getNumControllers())
|
num_controllers_(Input::get()->getNumControllers()),
|
||||||
|
state_(TitleState::LOGO_ANIMATING)
|
||||||
{
|
{
|
||||||
// Configura objetos
|
// Configura objetos
|
||||||
game_logo_->enable();
|
game_logo_->enable();
|
||||||
|
mini_logo_sprite_->setX(param.game.game_area.center_x - mini_logo_sprite_->getWidth() / 2);
|
||||||
fade_->setColor(fade_color.r, fade_color.g, fade_color.b);
|
fade_->setColor(fade_color.r, fade_color.g, fade_color.b);
|
||||||
fade_->setType(FadeType::RANDOM_SQUARE);
|
fade_->setType(FadeType::RANDOM_SQUARE);
|
||||||
fade_->setPost(param.fade.post_duration);
|
fade_->setPost(param.fade.post_duration);
|
||||||
@@ -54,6 +55,7 @@ Title::Title()
|
|||||||
Title::~Title()
|
Title::~Title()
|
||||||
{
|
{
|
||||||
Resource::get()->getTexture("smb2.gif")->setPalette(0);
|
Resource::get()->getTexture("smb2.gif")->setPalette(0);
|
||||||
|
JA_StopChannel(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Actualiza las variables del objeto
|
// Actualiza las variables del objeto
|
||||||
@@ -69,7 +71,10 @@ void Title::update()
|
|||||||
// Actualiza el objeto screen
|
// Actualiza el objeto screen
|
||||||
Screen::get()->update();
|
Screen::get()->update();
|
||||||
|
|
||||||
// Comprueba el fade_ y si se ha acabado
|
// Actualiza las variables de globalInputs
|
||||||
|
globalInputs::update();
|
||||||
|
|
||||||
|
// Comprueba el fundido
|
||||||
fade_->update();
|
fade_->update();
|
||||||
if (fade_->hasEnded())
|
if (fade_->hasEnded())
|
||||||
{
|
{
|
||||||
@@ -85,18 +90,19 @@ void Title::update()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sección 1 - Titulo animandose
|
// Establece la lógica según el estado
|
||||||
if (section::options == section::Options::TITLE_1)
|
switch (state_)
|
||||||
|
{
|
||||||
|
case TitleState::LOGO_ANIMATING:
|
||||||
{
|
{
|
||||||
game_logo_->update();
|
game_logo_->update();
|
||||||
if (game_logo_->hasFinished())
|
if (game_logo_->hasFinished())
|
||||||
{
|
{
|
||||||
section::options = section::Options::TITLE_2;
|
state_ = TitleState::LOGO_FINISHED;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
case TitleState::LOGO_FINISHED:
|
||||||
// Sección 2 - La pantalla con el titulo, el fondo animado y la música
|
|
||||||
else if (section::options == section::Options::TITLE_2)
|
|
||||||
{
|
{
|
||||||
// El contador solo sube si no estamos definiendo botones
|
// El contador solo sube si no estamos definiendo botones
|
||||||
counter_ = define_buttons_->isEnabled() ? 0 : counter_ + 1;
|
counter_ = define_buttons_->isEnabled() ? 0 : counter_ + 1;
|
||||||
@@ -118,6 +124,27 @@ void Title::update()
|
|||||||
fade_->activate();
|
fade_->activate();
|
||||||
post_fade_ = -1;
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -137,16 +164,10 @@ void Title::render()
|
|||||||
// Dibuja el logo con el título del juego
|
// Dibuja el logo con el título del juego
|
||||||
game_logo_->render();
|
game_logo_->render();
|
||||||
|
|
||||||
if (section::options == section::Options::TITLE_2)
|
constexpr Color shadow = Color(0x14, 0x87, 0xc4);
|
||||||
|
|
||||||
|
if (state_ != TitleState::LOGO_ANIMATING)
|
||||||
{
|
{
|
||||||
constexpr Color shadow = Color(0x14, 0x87, 0xc4);
|
|
||||||
|
|
||||||
// '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);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mini logo
|
// Mini logo
|
||||||
const int pos1 = (param.game.height / 5 * 4) + BLOCK;
|
const int pos1 = (param.game.height / 5 * 4) + BLOCK;
|
||||||
const int pos2 = pos1 + mini_logo_sprite_->getHeight() + 3;
|
const int pos2 = pos1 + mini_logo_sprite_->getHeight() + 3;
|
||||||
@@ -157,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);
|
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
|
||||||
define_buttons_->render();
|
define_buttons_->render();
|
||||||
|
|
||||||
@@ -238,24 +277,28 @@ void Title::checkEvents()
|
|||||||
// Comprueba las entradas
|
// Comprueba las entradas
|
||||||
void Title::checkInput()
|
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())
|
if (!define_buttons_->isEnabled())
|
||||||
{
|
{
|
||||||
// Comprueba los métodos de control
|
// Comprueba todos los métodos de control
|
||||||
for (const auto &controller : options.controllers)
|
for (const auto &controller : options.controllers)
|
||||||
{
|
{
|
||||||
|
// START
|
||||||
if (Input::get()->checkInput(InputType::START, INPUT_DO_NOT_ALLOW_REPEAT, controller.type, controller.index) &&
|
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))
|
!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_PlaySound(Resource::get()->getSound("game_start.wav"));
|
||||||
|
JA_FadeOutMusic(1500);
|
||||||
post_fade_ = controller.player_id;
|
post_fade_ = controller.player_id;
|
||||||
|
state_ = TitleState::START_HAS_BEEN_PRESSED;
|
||||||
|
counter_ = 0;
|
||||||
return;
|
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) &&
|
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))
|
Input::get()->checkInput(InputType::SWAP_CONTROLLERS, INPUT_DO_NOT_ALLOW_REPEAT, controller.type, controller.index))
|
||||||
{
|
{
|
||||||
@@ -263,7 +306,7 @@ void Title::checkInput()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Comprueba si algun mando quiere ser configurado
|
// CONFIG
|
||||||
if (Input::get()->checkInput(InputType::SERVICE, INPUT_ALLOW_REPEAT, controller.type, controller.index) &&
|
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))
|
Input::get()->checkInput(InputType::CONFIG, INPUT_DO_NOT_ALLOW_REPEAT, controller.type, controller.index))
|
||||||
{
|
{
|
||||||
@@ -342,7 +385,6 @@ void Title::showControllers()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// std::string spaces(lang::getText(100).length() + 3, ' ');
|
// Muestra la notificación
|
||||||
// std::string kb_text = spaces + lang::getText(69);
|
|
||||||
Notifier::get()->showText({text.at(0), text.at(1)});
|
Notifier::get()->showText({text.at(0), text.at(1)});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ namespace section
|
|||||||
constexpr const char TEXT_COPYRIGHT[] = "@2020,2024 JailDesigner";
|
constexpr const char TEXT_COPYRIGHT[] = "@2020,2024 JailDesigner";
|
||||||
|
|
||||||
// Parámetros
|
// Parámetros
|
||||||
constexpr bool ALLOW_TITLE_ANIMATION_SKIP = true;
|
constexpr bool ALLOW_TITLE_ANIMATION_SKIP = false;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Esta clase gestiona un estado del programa. Se encarga de la parte del titulo o menu
|
Esta clase gestiona un estado del programa. Se encarga de la parte del titulo o menu
|
||||||
@@ -27,9 +27,10 @@ constexpr bool ALLOW_TITLE_ANIMATION_SKIP = true;
|
|||||||
- Dibujar el tileado de fondo
|
- Dibujar el tileado de fondo
|
||||||
- Redifinir los botones de los mandos de juego
|
- 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 está animandose, con el fondo estático
|
||||||
- El titulo ya está en su sitio y el fondo se está animando
|
- 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
|
Por razones de diseño, no se permite saltarse la animación del titulo, aunque es
|
||||||
configurable mediante un define
|
configurable mediante un define
|
||||||
@@ -39,12 +40,19 @@ constexpr bool ALLOW_TITLE_ANIMATION_SKIP = true;
|
|||||||
class Title
|
class Title
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
// Enumeraciones
|
||||||
|
enum class TitleState
|
||||||
|
{
|
||||||
|
LOGO_ANIMATING,
|
||||||
|
LOGO_FINISHED,
|
||||||
|
START_HAS_BEEN_PRESSED,
|
||||||
|
};
|
||||||
|
|
||||||
// Objetos y punteros
|
// Objetos y punteros
|
||||||
std::shared_ptr<Text> text_; // Objeto de texto para poder escribir textos en pantalla
|
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
|
std::unique_ptr<Fade> fade_; // Objeto para realizar fundidos en pantalla
|
||||||
std::unique_ptr<TiledBG> tiled_bg_; // Objeto para dibujar el mosaico animado de fondo
|
std::unique_ptr<TiledBG> tiled_bg_; // Objeto para dibujar el mosaico animado de fondo
|
||||||
std::unique_ptr<GameLogo> game_logo_; // Objeto para dibujar el logo con el título del juego
|
std::unique_ptr<GameLogo> game_logo_; // Objeto para dibujar el logo con el título del juego
|
||||||
std::shared_ptr<Texture> mini_logo_texture_; // Textura con el logo de JailGames mini
|
|
||||||
std::unique_ptr<Sprite> mini_logo_sprite_; // Sprite con el logo de JailGames mini
|
std::unique_ptr<Sprite> mini_logo_sprite_; // Sprite con el logo de JailGames mini
|
||||||
std::unique_ptr<DefineButtons> define_buttons_; // Objeto para definir los botones del joystic
|
std::unique_ptr<DefineButtons> define_buttons_; // Objeto para definir los botones del joystic
|
||||||
|
|
||||||
@@ -54,6 +62,7 @@ private:
|
|||||||
section::Name next_section_; // Indica cual es la siguiente sección a cargar cuando termine el contador del titulo
|
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 post_fade_ = 0; // Opción a realizar cuando termina el fundido
|
||||||
int num_controllers_; // Número de mandos conectados
|
int num_controllers_; // Número de mandos conectados
|
||||||
|
TitleState state_; // Estado en el que se encuentra la sección
|
||||||
|
|
||||||
// Actualiza las variables del objeto
|
// Actualiza las variables del objeto
|
||||||
void update();
|
void update();
|
||||||
|
|||||||
Reference in New Issue
Block a user