Compare commits
197 Commits
2025-08-10
...
metal
| Author | SHA1 | Date | |
|---|---|---|---|
| d6ffbda00d | |||
| ff7aef827c | |||
| 6ff7ccf69a | |||
| e347e04d33 | |||
| 7946ea54a6 | |||
| 79033346c0 | |||
| 62b73d6f41 | |||
| 218ddabb5e | |||
| 427f40632a | |||
| a29b4d4379 | |||
| d851cdd2fe | |||
| 3354d00814 | |||
| 7bd7ba84e0 | |||
| 6ad34eaf57 | |||
| b4f2251508 | |||
| 473a52f986 | |||
| bcdd48d622 | |||
| 6985569573 | |||
| 5db43e674d | |||
| 34baa3c97d | |||
| bddb790fe2 | |||
| 6fae12ba02 | |||
| 4e083a8cdb | |||
| cbe4315701 | |||
| 49d561b583 | |||
| 6e56a6fd79 | |||
| 267d9647e0 | |||
| 13b3702d00 | |||
| 4500845dcd | |||
| a4abc02f88 | |||
| a0fb6934b0 | |||
| 19645445b2 | |||
| efe8628a3c | |||
| c98cb0d29f | |||
| c16fc1bae5 | |||
| fa0af1179a | |||
| d1e4a5eb07 | |||
| e18d1b186a | |||
| d056a5e336 | |||
| b9e26aa755 | |||
| b2afef2226 | |||
| c400aa96c0 | |||
| 8818954dcd | |||
| b92e5df98b | |||
| 83871273ec | |||
| 0459b39366 | |||
| 5bb0ff19bc | |||
| a867b3cf4d | |||
| 8a6ce8e66d | |||
| a40f04a739 | |||
| 0c670fd344 | |||
| 35f4bf690c | |||
| abeaf47f96 | |||
| 6498c35628 | |||
| d1c6af02db | |||
| 5edef17d84 | |||
| e4532fcef2 | |||
| 7a8d66c29d | |||
| 54292c9f8f | |||
| 3897553704 | |||
| 308f5c20fb | |||
| 987dcd0205 | |||
| d56f23544c | |||
| c79a846b29 | |||
| ad39d55e79 | |||
| 853ef426f0 | |||
| cadf7de3d8 | |||
| ec65ff9acb | |||
| d077374883 | |||
| 40a2b2cc00 | |||
| b3f3f151da | |||
| 3fdd61655a | |||
| 504727b95f | |||
| ff5446fcdf | |||
| 545eb70082 | |||
| 232a23a5dd | |||
| c9a29e26dd | |||
| 2977869ab5 | |||
| 6a223b68ba | |||
| 3fafff026b | |||
| 159528adc9 | |||
| 6c8f231b34 | |||
| c5d6d77ebf | |||
| 5e73327b2f | |||
| 720d286dcf | |||
| dd13a2bd7c | |||
| 1a6ef79466 | |||
| 8f83a1d13e | |||
| 9edfe6877f | |||
| 91b26631c6 | |||
| 331a690b78 | |||
| 5e3946e28b | |||
| d4a0189dc8 | |||
| 568b941990 | |||
| 49a3989ecf | |||
| af7cb01ead | |||
| 5c82916650 | |||
| 0c0518adac | |||
| cb7b290818 | |||
| ae30c9b34f | |||
| 9acd9aa631 | |||
| 577510ff8c | |||
| 66566913f6 | |||
| 3e6cc9dfab | |||
| a15e29344f | |||
| a96a17e11b | |||
| e0f6a424a9 | |||
| 49e30f947a | |||
| 470a07d28c | |||
| 65716fce20 | |||
| dfa66b0e95 | |||
| 3d9ffe356e | |||
| 19768cb72b | |||
| 26e0fd7247 | |||
| e2fd470ad3 | |||
| a72ae0a5fc | |||
| 7579594c22 | |||
| 6c702e7e23 | |||
| fb9c78eb49 | |||
| 62f65cbd5a | |||
| 057d3dcfee | |||
| c85336a4d0 | |||
| e4702e4e24 | |||
| 928335576c | |||
| fe950e6f17 | |||
| 6e81b6e60c | |||
| 74f6fe3501 | |||
| dfdb679054 | |||
| 26ed479306 | |||
| 32e9da55ef | |||
| 610083578e | |||
| 7250073d60 | |||
| dfa06870e4 | |||
| 81f3a25143 | |||
| 5aca95f3d2 | |||
| 7b193605e6 | |||
| 089a5b15d7 | |||
| e6a14ca57d | |||
| 467d609c28 | |||
| e03c798000 | |||
| 52d76b7338 | |||
| 83ee9c2649 | |||
| 43788bb01a | |||
| 58cf78e1e3 | |||
| 6bf8490776 | |||
| 8cfe28922c | |||
| 63990c75c2 | |||
| 94dca528ab | |||
| 4b6b89ceb2 | |||
| ed077c1da5 | |||
| 2819b3628e | |||
| 1e9e664012 | |||
| 0c8b39cee7 | |||
| d7b3af5ab8 | |||
| 5e5227305f | |||
| 3fc15a9512 | |||
| e774e0e8ad | |||
| a95776e6c7 | |||
| 0428ff26d5 | |||
| fc3e2deb1f | |||
| 65ca17f938 | |||
| ff2a51a507 | |||
| fe0083abd4 | |||
| 1c058694fd | |||
| cb0c3266d5 | |||
| 8ddc5d94f1 | |||
| b359a73d50 | |||
| 142603db71 | |||
| 1ec272f017 | |||
| 327987447d | |||
| ada5025c65 | |||
| 1ced698093 | |||
| 2a4c47a6ca | |||
| 6102504d32 | |||
| a123b3aa93 | |||
| 81d486f2d3 | |||
| 0c10898bdc | |||
| a3cd404545 | |||
| 5c708fc60a | |||
| 960ee367df | |||
| a7519fc372 | |||
| a983269080 | |||
| 3964503f1c | |||
| 8fcb7d1eb5 | |||
| 3e68afa4be | |||
| ca6edcccc0 | |||
| a388005968 | |||
| ea7628259a | |||
| a13e024934 | |||
| 4cc5102d70 | |||
| b2139d8e06 | |||
| ea3e704d34 | |||
| d5ab5748a7 | |||
| e950eb335d | |||
| e667063767 | |||
| 3534e4cc54 | |||
| 685b04c840 |
@@ -6,7 +6,16 @@ BreakBeforeBraces: Attach # Llaves en la misma línea
|
|||||||
AllowShortIfStatementsOnASingleLine: true
|
AllowShortIfStatementsOnASingleLine: true
|
||||||
AllowShortBlocksOnASingleLine: true
|
AllowShortBlocksOnASingleLine: true
|
||||||
AllowShortFunctionsOnASingleLine: All
|
AllowShortFunctionsOnASingleLine: All
|
||||||
AlignOperands: false
|
AlignOperands: DontAlign
|
||||||
AlignAfterOpenBracket: DontAlign
|
AlignAfterOpenBracket: DontAlign
|
||||||
BinPackArguments: false
|
BinPackArguments: false
|
||||||
BinPackParameters: false
|
BinPackParameters: false
|
||||||
|
ContinuationIndentWidth: 4
|
||||||
|
ConstructorInitializerIndentWidth: 4
|
||||||
|
IndentWrappedFunctionNames: false
|
||||||
|
Cpp11BracedListStyle: true
|
||||||
|
BreakConstructorInitializers: BeforeColon
|
||||||
|
AllowAllConstructorInitializersOnNextLine: false
|
||||||
|
PackConstructorInitializers: Never
|
||||||
|
AllowAllArgumentsOnNextLine: false
|
||||||
|
AllowAllParametersOfDeclarationOnNextLine: false
|
||||||
|
|||||||
15
.clang-tidy
@@ -1,8 +1,21 @@
|
|||||||
Checks: >
|
Checks: >
|
||||||
readability-*,
|
readability-*,
|
||||||
modernize-*,
|
modernize-*,
|
||||||
|
performance-*,
|
||||||
|
bugprone-unchecked-optional-access,
|
||||||
|
bugprone-sizeof-expression,
|
||||||
|
bugprone-suspicious-missing-comma,
|
||||||
|
bugprone-suspicious-index,
|
||||||
|
bugprone-undefined-memory-manipulation,
|
||||||
|
bugprone-use-after-move,
|
||||||
|
bugprone-out-of-bound-access,
|
||||||
-readability-identifier-length,
|
-readability-identifier-length,
|
||||||
-readability-magic-numbers
|
-readability-magic-numbers,
|
||||||
|
-bugprone-narrowing-conversions,
|
||||||
|
-performance-enum-size,
|
||||||
|
-performance-inefficient-string-concatenation,
|
||||||
|
-bugprone-integer-division,
|
||||||
|
-bugprone-easily-swappable-parameters,
|
||||||
|
|
||||||
WarningsAsErrors: '*'
|
WarningsAsErrors: '*'
|
||||||
# Solo incluir archivos de tu código fuente
|
# Solo incluir archivos de tu código fuente
|
||||||
|
|||||||
4
.gitignore
vendored
@@ -1,4 +1,5 @@
|
|||||||
.vscode
|
.vscode
|
||||||
|
.claude
|
||||||
build/
|
build/
|
||||||
data/config/config.txt
|
data/config/config.txt
|
||||||
*.DS_Store
|
*.DS_Store
|
||||||
@@ -16,4 +17,5 @@ coffee_crisis*
|
|||||||
debug.txt
|
debug.txt
|
||||||
cppcheck-result*
|
cppcheck-result*
|
||||||
desktop.ini
|
desktop.ini
|
||||||
ccae_release/
|
ccae_release/
|
||||||
|
resources.pack
|
||||||
@@ -14,6 +14,22 @@ set(CMAKE_CXX_STANDARD_REQUIRED True)
|
|||||||
cmake_policy(SET CMP0072 NEW)
|
cmake_policy(SET CMP0072 NEW)
|
||||||
set(OpenGL_GL_PREFERENCE GLVND)
|
set(OpenGL_GL_PREFERENCE GLVND)
|
||||||
|
|
||||||
|
# --- GENERACIÓN DE VERSIÓN AUTOMÁTICA ---
|
||||||
|
find_package(Git QUIET)
|
||||||
|
if(GIT_FOUND)
|
||||||
|
execute_process(
|
||||||
|
COMMAND ${GIT_EXECUTABLE} rev-parse --short=7 HEAD
|
||||||
|
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||||
|
OUTPUT_VARIABLE GIT_HASH
|
||||||
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||||
|
ERROR_QUIET
|
||||||
|
)
|
||||||
|
else()
|
||||||
|
set(GIT_HASH "unknown")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Configurar archivo de versión
|
||||||
|
configure_file(${CMAKE_SOURCE_DIR}/source/version.h.in ${CMAKE_BINARY_DIR}/version.h @ONLY)
|
||||||
|
|
||||||
# --- 1. LISTA EXPLÍCITA DE FUENTES ---
|
# --- 1. LISTA EXPLÍCITA DE FUENTES ---
|
||||||
set(APP_SOURCES
|
set(APP_SOURCES
|
||||||
@@ -28,6 +44,9 @@ set(APP_SOURCES
|
|||||||
source/main.cpp
|
source/main.cpp
|
||||||
source/param.cpp
|
source/param.cpp
|
||||||
source/resource.cpp
|
source/resource.cpp
|
||||||
|
source/resource_helper.cpp
|
||||||
|
source/resource_loader.cpp
|
||||||
|
source/resource_pack.cpp
|
||||||
source/screen.cpp
|
source/screen.cpp
|
||||||
source/text.cpp
|
source/text.cpp
|
||||||
source/writer.cpp
|
source/writer.cpp
|
||||||
@@ -45,6 +64,7 @@ set(APP_SOURCES
|
|||||||
source/balloon_manager.cpp
|
source/balloon_manager.cpp
|
||||||
source/balloon.cpp
|
source/balloon.cpp
|
||||||
source/bullet.cpp
|
source/bullet.cpp
|
||||||
|
source/bullet_manager.cpp
|
||||||
source/enter_name.cpp
|
source/enter_name.cpp
|
||||||
source/explosions.cpp
|
source/explosions.cpp
|
||||||
source/game_logo.cpp
|
source/game_logo.cpp
|
||||||
@@ -76,6 +96,7 @@ set(APP_SOURCES
|
|||||||
|
|
||||||
# --- Otros ---
|
# --- Otros ---
|
||||||
source/color.cpp
|
source/color.cpp
|
||||||
|
source/demo.cpp
|
||||||
source/define_buttons.cpp
|
source/define_buttons.cpp
|
||||||
source/difficulty.cpp
|
source/difficulty.cpp
|
||||||
source/input_types.cpp
|
source/input_types.cpp
|
||||||
@@ -89,28 +110,37 @@ set(APP_SOURCES
|
|||||||
|
|
||||||
# Fuentes de librerías de terceros
|
# Fuentes de librerías de terceros
|
||||||
set(EXTERNAL_SOURCES
|
set(EXTERNAL_SOURCES
|
||||||
source/external/jail_shader.cpp
|
source/external/jail_audio.cpp
|
||||||
source/external/json.hpp
|
source/external/json.hpp
|
||||||
source/external/gif.cpp
|
source/external/gif.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
# Añadir jail_audio.cpp solo si el audio está habilitado
|
# Fuentes del sistema de renderizado
|
||||||
if(NOT DISABLE_AUDIO)
|
set(RENDERING_SOURCES
|
||||||
list(APPEND EXTERNAL_SOURCES source/external/jail_audio.cpp)
|
source/rendering/opengl/opengl_shader.cpp
|
||||||
endif()
|
)
|
||||||
|
|
||||||
|
# Añadir backend de Metal en macOS
|
||||||
|
if(APPLE)
|
||||||
|
list(APPEND RENDERING_SOURCES
|
||||||
|
source/rendering/metal/metal_shader.mm
|
||||||
|
)
|
||||||
|
message(STATUS "Metal backend habilitado para macOS")
|
||||||
|
endif()
|
||||||
|
|
||||||
# Configuración de SDL3
|
# Configuración de SDL3
|
||||||
find_package(SDL3 REQUIRED CONFIG REQUIRED COMPONENTS SDL3)
|
find_package(SDL3 REQUIRED CONFIG REQUIRED COMPONENTS SDL3)
|
||||||
message(STATUS "SDL3 encontrado: ${SDL3_INCLUDE_DIRS}")
|
message(STATUS "SDL3 encontrado: ${SDL3_INCLUDE_DIRS}")
|
||||||
|
|
||||||
# --- 2. AÑADIR EJECUTABLE ---
|
# --- 2. AÑADIR EJECUTABLE ---
|
||||||
add_executable(${PROJECT_NAME} ${APP_SOURCES} ${EXTERNAL_SOURCES})
|
add_executable(${PROJECT_NAME} ${APP_SOURCES} ${EXTERNAL_SOURCES} ${RENDERING_SOURCES})
|
||||||
|
|
||||||
# --- 3. DIRECTORIOS DE INCLUSIÓN ---
|
# --- 3. DIRECTORIOS DE INCLUSIÓN ---
|
||||||
target_include_directories(${PROJECT_NAME} PUBLIC
|
target_include_directories(${PROJECT_NAME} PUBLIC
|
||||||
"${CMAKE_SOURCE_DIR}/source"
|
"${CMAKE_SOURCE_DIR}/source"
|
||||||
"${CMAKE_SOURCE_DIR}/source/external"
|
"${CMAKE_SOURCE_DIR}/source/external"
|
||||||
|
"${CMAKE_SOURCE_DIR}/source/rendering"
|
||||||
|
"${CMAKE_BINARY_DIR}"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Enlazar la librería SDL3
|
# Enlazar la librería SDL3
|
||||||
@@ -125,16 +155,9 @@ target_compile_options(${PROJECT_NAME} PRIVATE $<$<CONFIG:RELEASE>:-Os -ffunctio
|
|||||||
# Definir _DEBUG en modo Debug
|
# Definir _DEBUG en modo Debug
|
||||||
target_compile_definitions(${PROJECT_NAME} PRIVATE $<$<CONFIG:DEBUG>:_DEBUG>)
|
target_compile_definitions(${PROJECT_NAME} PRIVATE $<$<CONFIG:DEBUG>:_DEBUG>)
|
||||||
|
|
||||||
# Opción para habilitar/deshabilitar audio
|
# Descomentar la siguiente línea para activar el modo grabación de demos
|
||||||
option(DISABLE_AUDIO "Disable audio system" OFF)
|
# target_compile_definitions(${PROJECT_NAME} PRIVATE RECORDING)
|
||||||
|
|
||||||
# Definir NO_AUDIO si la opción está activada
|
|
||||||
if(DISABLE_AUDIO)
|
|
||||||
target_compile_definitions(${PROJECT_NAME} PRIVATE NO_AUDIO)
|
|
||||||
message(STATUS "Audio deshabilitado - NO_AUDIO definido")
|
|
||||||
else()
|
|
||||||
message(STATUS "Audio habilitado")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Configuración específica para cada plataforma
|
# Configuración específica para cada plataforma
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
@@ -144,6 +167,11 @@ elseif(APPLE)
|
|||||||
target_compile_definitions(${PROJECT_NAME} PRIVATE MACOS_BUILD)
|
target_compile_definitions(${PROJECT_NAME} PRIVATE MACOS_BUILD)
|
||||||
target_compile_options(${PROJECT_NAME} PRIVATE -Wno-deprecated)
|
target_compile_options(${PROJECT_NAME} PRIVATE -Wno-deprecated)
|
||||||
set(CMAKE_OSX_ARCHITECTURES "arm64")
|
set(CMAKE_OSX_ARCHITECTURES "arm64")
|
||||||
|
# Enlazar frameworks de Metal
|
||||||
|
target_link_libraries(${PROJECT_NAME} PRIVATE
|
||||||
|
"-framework Metal"
|
||||||
|
"-framework QuartzCore"
|
||||||
|
)
|
||||||
elseif(UNIX AND NOT APPLE)
|
elseif(UNIX AND NOT APPLE)
|
||||||
target_compile_definitions(${PROJECT_NAME} PRIVATE LINUX_BUILD)
|
target_compile_definitions(${PROJECT_NAME} PRIVATE LINUX_BUILD)
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
22
LICENSE
@@ -1 +1,21 @@
|
|||||||
GNU General Public License v3.0 only
|
Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License
|
||||||
|
|
||||||
|
Copyright (c) 2025 Coffee Crisis Arcade Edition
|
||||||
|
|
||||||
|
This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
|
||||||
|
|
||||||
|
You are free to:
|
||||||
|
- Share — copy and redistribute the material in any medium or format
|
||||||
|
- Adapt — remix, transform, and build upon the material
|
||||||
|
|
||||||
|
Under the following terms:
|
||||||
|
- Attribution — You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use.
|
||||||
|
- NonCommercial — You may not use the material for commercial purposes.
|
||||||
|
- ShareAlike — If you remix, transform, or build upon the material, you must distribute your contributions under the same license as the original.
|
||||||
|
|
||||||
|
No additional restrictions — You may not apply legal terms or technological measures that legally restrict others from doing anything the license permits.
|
||||||
|
|
||||||
|
To view a copy of this license, visit:
|
||||||
|
https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
231
Makefile
@@ -3,6 +3,7 @@ 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)
|
||||||
|
DIR_TOOLS := $(addsuffix /, $(DIR_ROOT)tools)
|
||||||
|
|
||||||
# Variables
|
# Variables
|
||||||
TARGET_NAME := coffee_crisis_arcade_edition
|
TARGET_NAME := coffee_crisis_arcade_edition
|
||||||
@@ -11,7 +12,33 @@ 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)
|
||||||
RESOURCE_FILE := release/coffee.res
|
RESOURCE_FILE := release/coffee.res
|
||||||
VERSION := 2025-08-10
|
|
||||||
|
# Variables para herramienta de empaquetado
|
||||||
|
ifeq ($(OS),Windows_NT)
|
||||||
|
PACK_TOOL := $(DIR_TOOLS)pack_resources.exe
|
||||||
|
PACK_CXX := $(CXX)
|
||||||
|
else
|
||||||
|
PACK_TOOL := $(DIR_TOOLS)pack_resources
|
||||||
|
PACK_CXX := $(CXX)
|
||||||
|
endif
|
||||||
|
PACK_SOURCES := $(DIR_TOOLS)pack_resources.cpp $(DIR_SOURCES)resource_pack.cpp
|
||||||
|
PACK_INCLUDES := -I$(DIR_ROOT)
|
||||||
|
|
||||||
|
# Versión automática basada en la fecha actual (específica por SO)
|
||||||
|
ifeq ($(OS),Windows_NT)
|
||||||
|
VERSION := $(shell powershell -Command "Get-Date -Format 'yyyy-MM-dd'")
|
||||||
|
else
|
||||||
|
VERSION := $(shell date +%Y-%m-%d)
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Variables específicas para Windows (usando APP_NAME)
|
||||||
|
ifeq ($(OS),Windows_NT)
|
||||||
|
WIN_TARGET_FILE := $(DIR_BIN)$(APP_NAME)
|
||||||
|
WIN_RELEASE_FILE := $(RELEASE_FOLDER)/$(APP_NAME)
|
||||||
|
else
|
||||||
|
WIN_TARGET_FILE := $(TARGET_FILE)
|
||||||
|
WIN_RELEASE_FILE := $(RELEASE_FILE)
|
||||||
|
endif
|
||||||
|
|
||||||
# Nombres para los ficheros de lanzamiento
|
# Nombres para los ficheros de lanzamiento
|
||||||
WINDOWS_RELEASE := $(TARGET_NAME)-$(VERSION)-win32-x64.zip
|
WINDOWS_RELEASE := $(TARGET_NAME)-$(VERSION)-win32-x64.zip
|
||||||
@@ -56,6 +83,9 @@ APP_SOURCES := \
|
|||||||
source/path_sprite.cpp \
|
source/path_sprite.cpp \
|
||||||
source/player.cpp \
|
source/player.cpp \
|
||||||
source/resource.cpp \
|
source/resource.cpp \
|
||||||
|
source/resource_helper.cpp \
|
||||||
|
source/resource_loader.cpp \
|
||||||
|
source/resource_pack.cpp \
|
||||||
source/scoreboard.cpp \
|
source/scoreboard.cpp \
|
||||||
source/screen.cpp \
|
source/screen.cpp \
|
||||||
source/sections/credits.cpp \
|
source/sections/credits.cpp \
|
||||||
@@ -89,7 +119,7 @@ INCLUDES := -Isource -Isource/external
|
|||||||
# 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)
|
||||||
CXXFLAGS := -std=c++20 -Wall -Os -ffunction-sections -fdata-sections -Wl,--gc-sections -static-libstdc++ -Wl,-subsystem,windows -DWINDOWS_BUILD
|
CXXFLAGS := -std=c++20 -Wall -Os -ffunction-sections -fdata-sections -Wl,--gc-sections -static-libstdc++ -static-libgcc -Wl,-Bstatic -lpthread -Wl,-Bdynamic -Wl,-subsystem,windows -DWINDOWS_BUILD
|
||||||
CXXFLAGS_DEBUG := -std=c++20 -Wall -g -D_DEBUG -DWINDOWS_BUILD
|
CXXFLAGS_DEBUG := -std=c++20 -Wall -g -D_DEBUG -DWINDOWS_BUILD
|
||||||
LDFLAGS := -lmingw32 -lws2_32 -lSDL3 -lopengl32
|
LDFLAGS := -lmingw32 -lws2_32 -lSDL3 -lopengl32
|
||||||
RM := del /Q
|
RM := del /Q
|
||||||
@@ -117,30 +147,48 @@ else
|
|||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
# Reglas para herramienta de empaquetado y resources.pack
|
||||||
|
$(PACK_TOOL): $(PACK_SOURCES)
|
||||||
|
@echo "Compilando herramienta de empaquetado..."
|
||||||
|
$(PACK_CXX) -std=c++17 -Wall -Os $(PACK_INCLUDES) $(PACK_SOURCES) -o $(PACK_TOOL)
|
||||||
|
@echo "✓ Herramienta de empaquetado lista: $(PACK_TOOL)"
|
||||||
|
|
||||||
|
pack_tool: $(PACK_TOOL)
|
||||||
|
|
||||||
|
resources.pack: $(PACK_TOOL)
|
||||||
|
@echo "Generando resources.pack desde directorio data/..."
|
||||||
|
$(PACK_TOOL) data resources.pack
|
||||||
|
@echo "✓ resources.pack generado exitosamente"
|
||||||
|
|
||||||
# Reglas para compilación
|
# Reglas para compilación
|
||||||
windows:
|
windows:
|
||||||
@echo off
|
@echo off
|
||||||
|
@echo Compilando para Windows con nombre: "$(APP_NAME).exe"
|
||||||
windres release/coffee.rc -O coff -o $(RESOURCE_FILE)
|
windres release/coffee.rc -O coff -o $(RESOURCE_FILE)
|
||||||
$(CXX) $(APP_SOURCES) $(RESOURCE_FILE) $(INCLUDES) $(CXXFLAGS) $(LDFLAGS) -o "$(TARGET_FILE).exe"
|
$(CXX) $(APP_SOURCES) $(RESOURCE_FILE) $(INCLUDES) $(CXXFLAGS) $(LDFLAGS) -o "$(WIN_TARGET_FILE).exe"
|
||||||
strip -s -R .comment -R .gnu.version "$(TARGET_FILE).exe" --strip-unneeded
|
strip -s -R .comment -R .gnu.version "$(WIN_TARGET_FILE).exe" --strip-unneeded
|
||||||
|
|
||||||
windows_rec:
|
windows_rec:
|
||||||
@echo off
|
@echo off
|
||||||
$(CXX) $(APP_SOURCES) $(INCLUDES) -DRECORDING $(CXXFLAGS) $(LDFLAGS) -o "$(TARGET_FILE)_rec.exe"
|
@echo Compilando version de grabacion para Windows: "$(APP_NAME)_rec.exe"
|
||||||
|
$(CXX) $(APP_SOURCES) $(INCLUDES) -DRECORDING $(CXXFLAGS) $(LDFLAGS) -o "$(WIN_TARGET_FILE)_rec.exe"
|
||||||
|
|
||||||
windows_debug:
|
windows_debug:
|
||||||
@echo off
|
@echo off
|
||||||
$(CXX) $(APP_SOURCES) $(INCLUDES) -DDEBUG -DVERBOSE $(CXXFLAGS_DEBUG) $(LDFLAGS) -o "$(TARGET_FILE)_debug.exe"
|
@echo Compilando version debug para Windows: "$(APP_NAME)_debug.exe"
|
||||||
|
$(CXX) $(APP_SOURCES) $(INCLUDES) -DDEBUG -DVERBOSE $(CXXFLAGS_DEBUG) $(LDFLAGS) -o "$(WIN_TARGET_FILE)_debug.exe"
|
||||||
|
|
||||||
windows_release:
|
windows_release: resources.pack
|
||||||
@echo off
|
@echo off
|
||||||
|
@echo Creando release para Windows - Version: $(VERSION)
|
||||||
|
|
||||||
# Crea carpeta temporal 'RELEASE_FOLDER'
|
# Crea 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}
|
||||||
powershell if (-not (Test-Path "$(RELEASE_FOLDER)")) {New-Item "$(RELEASE_FOLDER)" -ItemType Directory}
|
powershell if (-not (Test-Path "$(RELEASE_FOLDER)")) {New-Item "$(RELEASE_FOLDER)" -ItemType Directory}
|
||||||
|
|
||||||
# Copia la carpeta 'data'
|
# Copia la carpeta 'config' y el archivo 'resources.pack'
|
||||||
powershell Copy-Item -Path "data" -Destination "$(RELEASE_FOLDER)" -recurse -Force
|
powershell Copy-Item -Path "config" -Destination "$(RELEASE_FOLDER)" -recurse -Force
|
||||||
|
powershell Copy-Item -Path "resources.pack" -Destination "$(RELEASE_FOLDER)"
|
||||||
|
|
||||||
# Copia los ficheros que estan en la raíz del proyecto
|
# Copia los ficheros que estan en la raíz del proyecto
|
||||||
powershell Copy-Item "LICENSE" -Destination "$(RELEASE_FOLDER)"
|
powershell Copy-Item "LICENSE" -Destination "$(RELEASE_FOLDER)"
|
||||||
@@ -149,23 +197,27 @@ windows_release:
|
|||||||
|
|
||||||
# Compila
|
# Compila
|
||||||
windres release/coffee.rc -O coff -o $(RESOURCE_FILE)
|
windres release/coffee.rc -O coff -o $(RESOURCE_FILE)
|
||||||
$(CXX) $(APP_SOURCES) $(RESOURCE_FILE) $(INCLUDES) $(CXXFLAGS) $(LDFLAGS) -o "$(RELEASE_FILE).exe"
|
$(CXX) $(APP_SOURCES) $(RESOURCE_FILE) $(INCLUDES) $(CXXFLAGS) $(LDFLAGS) -o "$(WIN_RELEASE_FILE).exe"
|
||||||
strip -s -R .comment -R .gnu.version "$(RELEASE_FILE).exe" --strip-unneeded
|
strip -s -R .comment -R .gnu.version "$(WIN_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)"
|
||||||
|
@echo Release creado: $(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}
|
||||||
|
|
||||||
macos:
|
macos:
|
||||||
|
@echo "Compilando para macOS: $(TARGET_NAME)"
|
||||||
$(CXX) $(APP_SOURCES) $(INCLUDES) $(CXXFLAGS) $(LDFLAGS) -o "$(TARGET_FILE)"
|
$(CXX) $(APP_SOURCES) $(INCLUDES) $(CXXFLAGS) $(LDFLAGS) -o "$(TARGET_FILE)"
|
||||||
|
|
||||||
macos_debug:
|
macos_debug:
|
||||||
|
@echo "Compilando version debug para macOS: $(TARGET_NAME)_debug"
|
||||||
$(CXX) $(APP_SOURCES) $(INCLUDES) -DDEBUG -DVERBOSE $(CXXFLAGS_DEBUG) $(LDFLAGS) -o "$(TARGET_FILE)_debug"
|
$(CXX) $(APP_SOURCES) $(INCLUDES) -DDEBUG -DVERBOSE $(CXXFLAGS_DEBUG) $(LDFLAGS) -o "$(TARGET_FILE)_debug"
|
||||||
|
|
||||||
macos_release:
|
macos_release: resources.pack
|
||||||
|
@echo "Creando release para macOS - Version: $(VERSION)"
|
||||||
# Elimina datos de compilaciones anteriores
|
# Elimina datos de compilaciones anteriores
|
||||||
$(RMDIR) "$(RELEASE_FOLDER)"
|
$(RMDIR) "$(RELEASE_FOLDER)"
|
||||||
$(RMDIR) Frameworks
|
$(RMDIR) Frameworks
|
||||||
@@ -180,7 +232,8 @@ macos_release:
|
|||||||
$(MKDIR) Frameworks
|
$(MKDIR) Frameworks
|
||||||
|
|
||||||
# Copia carpetas y ficheros
|
# Copia carpetas y ficheros
|
||||||
cp -R data "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Resources"
|
cp -R config "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Resources"
|
||||||
|
cp resources.pack "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Resources"
|
||||||
cp -R release/frameworks/SDL3.xcframework "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Frameworks"
|
cp -R release/frameworks/SDL3.xcframework "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Frameworks"
|
||||||
cp -R release/frameworks/SDL3.xcframework Frameworks
|
cp -R release/frameworks/SDL3.xcframework Frameworks
|
||||||
cp release/*.icns "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Resources"
|
cp release/*.icns "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Resources"
|
||||||
@@ -202,6 +255,7 @@ ifdef ENABLE_MACOS_X86_64
|
|||||||
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)"
|
||||||
$(RMFILE) tmp.dmg
|
$(RMFILE) tmp.dmg
|
||||||
|
@echo "Release Intel creado: $(MACOS_INTEL_RELEASE)"
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# Compila la versión para procesadores Apple Silicon
|
# Compila la versión para procesadores Apple Silicon
|
||||||
@@ -214,19 +268,23 @@ endif
|
|||||||
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)"
|
||||||
$(RMFILE) tmp.dmg
|
$(RMFILE) tmp.dmg
|
||||||
|
@echo "Release Apple Silicon creado: $(MACOS_APPLE_SILICON_RELEASE)"
|
||||||
|
|
||||||
# Elimina las carpetas temporales
|
# Elimina las carpetas temporales
|
||||||
$(RMDIR) Frameworks
|
$(RMDIR) Frameworks
|
||||||
$(RMDIR) "$(RELEASE_FOLDER)"
|
$(RMDIR) "$(RELEASE_FOLDER)"
|
||||||
|
|
||||||
linux:
|
linux:
|
||||||
|
@echo "Compilando para Linux: $(TARGET_NAME)"
|
||||||
$(CXX) $(APP_SOURCES) $(INCLUDES) $(CXXFLAGS) $(LDFLAGS) -o "$(TARGET_FILE)"
|
$(CXX) $(APP_SOURCES) $(INCLUDES) $(CXXFLAGS) $(LDFLAGS) -o "$(TARGET_FILE)"
|
||||||
strip -s -R .comment -R .gnu.version "$(TARGET_FILE)" --strip-unneeded
|
strip -s -R .comment -R .gnu.version "$(TARGET_FILE)" --strip-unneeded
|
||||||
|
|
||||||
linux_debug:
|
linux_debug:
|
||||||
|
@echo "Compilando version debug para Linux: $(TARGET_NAME)_debug"
|
||||||
$(CXX) $(APP_SOURCES) $(INCLUDES) -DDEBUG -DVERBOSE $(CXXFLAGS_DEBUG) $(LDFLAGS) -o "$(TARGET_FILE)_debug"
|
$(CXX) $(APP_SOURCES) $(INCLUDES) -DDEBUG -DVERBOSE $(CXXFLAGS_DEBUG) $(LDFLAGS) -o "$(TARGET_FILE)_debug"
|
||||||
|
|
||||||
linux_release:
|
linux_release: resources.pack
|
||||||
|
@echo "Creando release para Linux - Version: $(VERSION)"
|
||||||
# Elimina carpetas previas
|
# Elimina carpetas previas
|
||||||
$(RMDIR) "$(RELEASE_FOLDER)"
|
$(RMDIR) "$(RELEASE_FOLDER)"
|
||||||
|
|
||||||
@@ -234,7 +292,8 @@ linux_release:
|
|||||||
$(MKDIR) "$(RELEASE_FOLDER)"
|
$(MKDIR) "$(RELEASE_FOLDER)"
|
||||||
|
|
||||||
# Copia ficheros
|
# Copia ficheros
|
||||||
cp -R data "$(RELEASE_FOLDER)"
|
cp -R config "$(RELEASE_FOLDER)"
|
||||||
|
cp resources.pack "$(RELEASE_FOLDER)"
|
||||||
cp LICENSE "$(RELEASE_FOLDER)"
|
cp LICENSE "$(RELEASE_FOLDER)"
|
||||||
cp README.md "$(RELEASE_FOLDER)"
|
cp README.md "$(RELEASE_FOLDER)"
|
||||||
|
|
||||||
@@ -245,18 +304,118 @@ linux_release:
|
|||||||
# Empaqueta ficheros
|
# Empaqueta ficheros
|
||||||
$(RMFILE) "$(LINUX_RELEASE)"
|
$(RMFILE) "$(LINUX_RELEASE)"
|
||||||
tar -czvf "$(LINUX_RELEASE)" -C "$(RELEASE_FOLDER)" .
|
tar -czvf "$(LINUX_RELEASE)" -C "$(RELEASE_FOLDER)" .
|
||||||
|
@echo "Release creado: $(LINUX_RELEASE)"
|
||||||
|
|
||||||
|
# Elimina la carpeta temporal
|
||||||
|
$(RMDIR) "$(RELEASE_FOLDER)"
|
||||||
|
|
||||||
|
linux_release_desktop: resources.pack
|
||||||
|
@echo "Creando release con integracion desktop para Linux - Version: $(VERSION)"
|
||||||
|
# Elimina carpetas previas
|
||||||
|
$(RMDIR) "$(RELEASE_FOLDER)"
|
||||||
|
|
||||||
|
# Crea la estructura de directorios estándar para Linux
|
||||||
|
$(MKDIR) "$(RELEASE_FOLDER)/$(TARGET_NAME)"
|
||||||
|
$(MKDIR) "$(RELEASE_FOLDER)/$(TARGET_NAME)/bin"
|
||||||
|
$(MKDIR) "$(RELEASE_FOLDER)/$(TARGET_NAME)/share/applications"
|
||||||
|
$(MKDIR) "$(RELEASE_FOLDER)/$(TARGET_NAME)/share/icons/hicolor/256x256/apps"
|
||||||
|
$(MKDIR) "$(RELEASE_FOLDER)/$(TARGET_NAME)/share/$(TARGET_NAME)"
|
||||||
|
|
||||||
|
# Copia ficheros del juego
|
||||||
|
cp -R config "$(RELEASE_FOLDER)/$(TARGET_NAME)/share/$(TARGET_NAME)/"
|
||||||
|
cp resources.pack "$(RELEASE_FOLDER)/$(TARGET_NAME)/share/$(TARGET_NAME)/"
|
||||||
|
cp LICENSE "$(RELEASE_FOLDER)/$(TARGET_NAME)/"
|
||||||
|
cp README.md "$(RELEASE_FOLDER)/$(TARGET_NAME)/"
|
||||||
|
|
||||||
|
# Compila el ejecutable
|
||||||
|
$(CXX) $(APP_SOURCES) $(INCLUDES) $(CXXFLAGS) $(LDFLAGS) -o "$(RELEASE_FOLDER)/$(TARGET_NAME)/bin/$(TARGET_NAME)"
|
||||||
|
strip -s -R .comment -R .gnu.version "$(RELEASE_FOLDER)/$(TARGET_NAME)/bin/$(TARGET_NAME)" --strip-unneeded
|
||||||
|
|
||||||
|
# Crea el archivo .desktop
|
||||||
|
@echo '[Desktop Entry]' > "$(RELEASE_FOLDER)/$(TARGET_NAME)/share/applications/$(TARGET_NAME).desktop"
|
||||||
|
@echo 'Version=1.0' >> "$(RELEASE_FOLDER)/$(TARGET_NAME)/share/applications/$(TARGET_NAME).desktop"
|
||||||
|
@echo 'Type=Application' >> "$(RELEASE_FOLDER)/$(TARGET_NAME)/share/applications/$(TARGET_NAME).desktop"
|
||||||
|
@echo 'Name=$(APP_NAME)' >> "$(RELEASE_FOLDER)/$(TARGET_NAME)/share/applications/$(TARGET_NAME).desktop"
|
||||||
|
@echo 'Comment=Arcade action game - defend Earth from alien invasion!' >> "$(RELEASE_FOLDER)/$(TARGET_NAME)/share/applications/$(TARGET_NAME).desktop"
|
||||||
|
@echo 'Exec=/opt/$(TARGET_NAME)/bin/$(TARGET_NAME)' >> "$(RELEASE_FOLDER)/$(TARGET_NAME)/share/applications/$(TARGET_NAME).desktop"
|
||||||
|
@echo 'Icon=$(TARGET_NAME)' >> "$(RELEASE_FOLDER)/$(TARGET_NAME)/share/applications/$(TARGET_NAME).desktop"
|
||||||
|
@echo 'Path=/opt/$(TARGET_NAME)/share/$(TARGET_NAME)' >> "$(RELEASE_FOLDER)/$(TARGET_NAME)/share/applications/$(TARGET_NAME).desktop"
|
||||||
|
@echo 'Terminal=false' >> "$(RELEASE_FOLDER)/$(TARGET_NAME)/share/applications/$(TARGET_NAME).desktop"
|
||||||
|
@echo 'StartupNotify=true' >> "$(RELEASE_FOLDER)/$(TARGET_NAME)/share/applications/$(TARGET_NAME).desktop"
|
||||||
|
@echo 'Categories=Game;ArcadeGame;' >> "$(RELEASE_FOLDER)/$(TARGET_NAME)/share/applications/$(TARGET_NAME).desktop"
|
||||||
|
@echo 'Keywords=arcade;action;shooter;retro;' >> "$(RELEASE_FOLDER)/$(TARGET_NAME)/share/applications/$(TARGET_NAME).desktop"
|
||||||
|
|
||||||
|
# Copia el icono (si existe) y lo redimensiona si es necesario
|
||||||
|
@if [ -f "release/icon.png" ]; then \
|
||||||
|
if command -v magick >/dev/null 2>&1; then \
|
||||||
|
magick "release/icon.png" -resize 256x256 "$(RELEASE_FOLDER)/$(TARGET_NAME)/share/icons/hicolor/256x256/apps/$(TARGET_NAME).png"; \
|
||||||
|
echo "Icono redimensionado de release/icon.png (usando ImageMagick)"; \
|
||||||
|
elif command -v convert >/dev/null 2>&1; then \
|
||||||
|
convert "release/icon.png" -resize 256x256 "$(RELEASE_FOLDER)/$(TARGET_NAME)/share/icons/hicolor/256x256/apps/$(TARGET_NAME).png"; \
|
||||||
|
echo "Icono redimensionado de release/icon.png (usando ImageMagick legacy)"; \
|
||||||
|
elif command -v ffmpeg >/dev/null 2>&1; then \
|
||||||
|
ffmpeg -i "release/icon.png" -vf scale=256:256 "$(RELEASE_FOLDER)/$(TARGET_NAME)/share/icons/hicolor/256x256/apps/$(TARGET_NAME).png" -y -loglevel quiet; \
|
||||||
|
echo "Icono redimensionado de release/icon.png (usando ffmpeg)"; \
|
||||||
|
else \
|
||||||
|
cp "release/icon.png" "$(RELEASE_FOLDER)/$(TARGET_NAME)/share/icons/hicolor/256x256/apps/$(TARGET_NAME).png"; \
|
||||||
|
echo "Icono copiado sin redimensionar (instalar ImageMagick o ffmpeg para redimensionado automatico)"; \
|
||||||
|
fi; \
|
||||||
|
elif [ -f "release/coffee.png" ]; then \
|
||||||
|
cp "release/coffee.png" "$(RELEASE_FOLDER)/$(TARGET_NAME)/share/icons/hicolor/256x256/apps/$(TARGET_NAME).png"; \
|
||||||
|
echo "Icono copiado desde release/coffee.png"; \
|
||||||
|
else \
|
||||||
|
echo "Advertencia: No se encontró release/icon.png ni release/coffee.png - crear icono manualmente"; \
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Crea script de instalación
|
||||||
|
@echo '#!/bin/bash' > "$(RELEASE_FOLDER)/$(TARGET_NAME)/install.sh"
|
||||||
|
@echo 'echo "Instalando $(APP_NAME)..."' >> "$(RELEASE_FOLDER)/$(TARGET_NAME)/install.sh"
|
||||||
|
@echo 'sudo mkdir -p /opt/$(TARGET_NAME)' >> "$(RELEASE_FOLDER)/$(TARGET_NAME)/install.sh"
|
||||||
|
@echo 'sudo cp -R bin /opt/$(TARGET_NAME)/' >> "$(RELEASE_FOLDER)/$(TARGET_NAME)/install.sh"
|
||||||
|
@echo 'sudo cp -R share /opt/$(TARGET_NAME)/' >> "$(RELEASE_FOLDER)/$(TARGET_NAME)/install.sh"
|
||||||
|
@echo 'sudo cp LICENSE /opt/$(TARGET_NAME)/' >> "$(RELEASE_FOLDER)/$(TARGET_NAME)/install.sh"
|
||||||
|
@echo 'sudo cp README.md /opt/$(TARGET_NAME)/' >> "$(RELEASE_FOLDER)/$(TARGET_NAME)/install.sh"
|
||||||
|
@echo 'sudo mkdir -p /usr/share/applications' >> "$(RELEASE_FOLDER)/$(TARGET_NAME)/install.sh"
|
||||||
|
@echo 'sudo mkdir -p /usr/share/icons/hicolor/256x256/apps' >> "$(RELEASE_FOLDER)/$(TARGET_NAME)/install.sh"
|
||||||
|
@echo 'sudo cp /opt/$(TARGET_NAME)/share/applications/$(TARGET_NAME).desktop /usr/share/applications/' >> "$(RELEASE_FOLDER)/$(TARGET_NAME)/install.sh"
|
||||||
|
@echo 'sudo cp /opt/$(TARGET_NAME)/share/icons/hicolor/256x256/apps/$(TARGET_NAME).png /usr/share/icons/hicolor/256x256/apps/' >> "$(RELEASE_FOLDER)/$(TARGET_NAME)/install.sh"
|
||||||
|
@echo 'sudo update-desktop-database /usr/share/applications 2>/dev/null || true' >> "$(RELEASE_FOLDER)/$(TARGET_NAME)/install.sh"
|
||||||
|
@echo 'sudo gtk-update-icon-cache /usr/share/icons/hicolor 2>/dev/null || true' >> "$(RELEASE_FOLDER)/$(TARGET_NAME)/install.sh"
|
||||||
|
@echo 'echo "$(APP_NAME) instalado correctamente!"' >> "$(RELEASE_FOLDER)/$(TARGET_NAME)/install.sh"
|
||||||
|
@echo 'echo "Ya puedes encontrarlo en el menu de aplicaciones en la categoria Juegos."' >> "$(RELEASE_FOLDER)/$(TARGET_NAME)/install.sh"
|
||||||
|
chmod +x "$(RELEASE_FOLDER)/$(TARGET_NAME)/install.sh"
|
||||||
|
|
||||||
|
# Crea script de desinstalación
|
||||||
|
@echo '#!/bin/bash' > "$(RELEASE_FOLDER)/$(TARGET_NAME)/uninstall.sh"
|
||||||
|
@echo 'echo "Desinstalando $(APP_NAME)..."' >> "$(RELEASE_FOLDER)/$(TARGET_NAME)/uninstall.sh"
|
||||||
|
@echo 'sudo rm -rf /opt/$(TARGET_NAME)' >> "$(RELEASE_FOLDER)/$(TARGET_NAME)/uninstall.sh"
|
||||||
|
@echo 'sudo rm -f /usr/share/applications/$(TARGET_NAME).desktop' >> "$(RELEASE_FOLDER)/$(TARGET_NAME)/uninstall.sh"
|
||||||
|
@echo 'sudo rm -f /usr/share/icons/hicolor/256x256/apps/$(TARGET_NAME).png' >> "$(RELEASE_FOLDER)/$(TARGET_NAME)/uninstall.sh"
|
||||||
|
@echo 'sudo update-desktop-database /usr/share/applications 2>/dev/null || true' >> "$(RELEASE_FOLDER)/$(TARGET_NAME)/uninstall.sh"
|
||||||
|
@echo 'sudo gtk-update-icon-cache /usr/share/icons/hicolor 2>/dev/null || true' >> "$(RELEASE_FOLDER)/$(TARGET_NAME)/uninstall.sh"
|
||||||
|
@echo 'echo "$(APP_NAME) desinstalado correctamente."' >> "$(RELEASE_FOLDER)/$(TARGET_NAME)/uninstall.sh"
|
||||||
|
chmod +x "$(RELEASE_FOLDER)/$(TARGET_NAME)/uninstall.sh"
|
||||||
|
|
||||||
|
# Empaqueta ficheros
|
||||||
|
$(RMFILE) "$(TARGET_NAME)-$(VERSION)-linux-desktop.tar.gz"
|
||||||
|
tar -czvf "$(TARGET_NAME)-$(VERSION)-linux-desktop.tar.gz" -C "$(RELEASE_FOLDER)" .
|
||||||
|
@echo "Release con integracion desktop creado: $(TARGET_NAME)-$(VERSION)-linux-desktop.tar.gz"
|
||||||
|
@echo "Para instalar: extraer y ejecutar ./$(TARGET_NAME)/install.sh"
|
||||||
|
|
||||||
# Elimina la carpeta temporal
|
# Elimina la carpeta temporal
|
||||||
$(RMDIR) "$(RELEASE_FOLDER)"
|
$(RMDIR) "$(RELEASE_FOLDER)"
|
||||||
|
|
||||||
raspi:
|
raspi:
|
||||||
|
@echo "Compilando para Raspberry Pi: $(TARGET_NAME)"
|
||||||
$(CXX) $(APP_SOURCES) $(INCLUDES) -DVERBOSE $(CXXFLAGS) $(LDFLAGS) -o $(TARGET_FILE)
|
$(CXX) $(APP_SOURCES) $(INCLUDES) -DVERBOSE $(CXXFLAGS) $(LDFLAGS) -o $(TARGET_FILE)
|
||||||
strip -s -R .comment -R .gnu.version $(TARGET_FILE) --strip-unneeded
|
strip -s -R .comment -R .gnu.version $(TARGET_FILE) --strip-unneeded
|
||||||
|
|
||||||
raspi_debug:
|
raspi_debug:
|
||||||
|
@echo "Compilando version debug para Raspberry Pi: $(TARGET_NAME)_debug"
|
||||||
$(CXX) $(APP_SOURCES) $(INCLUDES) -DVERBOSE -DDEBUG $(CXXFLAGS_DEBUG) $(LDFLAGS) -o "$(TARGET_FILE)_debug"
|
$(CXX) $(APP_SOURCES) $(INCLUDES) -DVERBOSE -DDEBUG $(CXXFLAGS_DEBUG) $(LDFLAGS) -o "$(TARGET_FILE)_debug"
|
||||||
|
|
||||||
raspi_release:
|
raspi_release: resources.pack
|
||||||
|
@echo "Creando release para Raspberry Pi - Version: $(VERSION)"
|
||||||
# Elimina carpetas previas
|
# Elimina carpetas previas
|
||||||
$(RMDIR) "$(RELEASE_FOLDER)"
|
$(RMDIR) "$(RELEASE_FOLDER)"
|
||||||
|
|
||||||
@@ -264,7 +423,8 @@ raspi_release:
|
|||||||
$(MKDIR) "$(RELEASE_FOLDER)"
|
$(MKDIR) "$(RELEASE_FOLDER)"
|
||||||
|
|
||||||
# Copia ficheros
|
# Copia ficheros
|
||||||
cp -R data "$(RELEASE_FOLDER)"
|
cp -R config "$(RELEASE_FOLDER)"
|
||||||
|
cp resources.pack "$(RELEASE_FOLDER)"
|
||||||
cp LICENSE "$(RELEASE_FOLDER)"
|
cp LICENSE "$(RELEASE_FOLDER)"
|
||||||
cp README.md "$(RELEASE_FOLDER)"
|
cp README.md "$(RELEASE_FOLDER)"
|
||||||
|
|
||||||
@@ -275,11 +435,13 @@ raspi_release:
|
|||||||
# Empaqueta ficheros
|
# Empaqueta ficheros
|
||||||
$(RMFILE) "$(RASPI_RELEASE)"
|
$(RMFILE) "$(RASPI_RELEASE)"
|
||||||
tar -czvf "$(RASPI_RELEASE)" -C "$(RELEASE_FOLDER)" .
|
tar -czvf "$(RASPI_RELEASE)" -C "$(RELEASE_FOLDER)" .
|
||||||
|
@echo "Release creado: $(RASPI_RELEASE)"
|
||||||
|
|
||||||
# Elimina la carpeta temporal
|
# Elimina la carpeta temporal
|
||||||
$(RMDIR) "$(RELEASE_FOLDER)"
|
$(RMDIR) "$(RELEASE_FOLDER)"
|
||||||
|
|
||||||
anbernic:
|
anbernic: resources.pack
|
||||||
|
@echo "Compilando para Anbernic: $(TARGET_NAME)"
|
||||||
# Elimina carpetas previas
|
# Elimina carpetas previas
|
||||||
$(RMDIR) "$(RELEASE_FOLDER)"_anbernic
|
$(RMDIR) "$(RELEASE_FOLDER)"_anbernic
|
||||||
|
|
||||||
@@ -287,13 +449,42 @@ anbernic:
|
|||||||
$(MKDIR) "$(RELEASE_FOLDER)"_anbernic
|
$(MKDIR) "$(RELEASE_FOLDER)"_anbernic
|
||||||
|
|
||||||
# Copia ficheros
|
# Copia ficheros
|
||||||
cp -R data "$(RELEASE_FOLDER)"_anbernic
|
cp -R config "$(RELEASE_FOLDER)"_anbernic
|
||||||
|
cp resources.pack "$(RELEASE_FOLDER)"_anbernic
|
||||||
|
|
||||||
# Compila
|
# Compila
|
||||||
$(CXX) $(APP_SOURCES) $(INCLUDES) -DANBERNIC -DNO_SHADERS -DARCADE -DVERBOSE $(CXXFLAGS) $(LDFLAGS) -o $(RELEASE_FOLDER)_anbernic/$(TARGET_NAME)
|
$(CXX) $(APP_SOURCES) $(INCLUDES) -DANBERNIC -DNO_SHADERS -DARCADE -DVERBOSE $(CXXFLAGS) $(LDFLAGS) -o $(RELEASE_FOLDER)_anbernic/$(TARGET_NAME)
|
||||||
|
|
||||||
# Opción para deshabilitar audio (equivalente a la opción DISABLE_AUDIO de CMake)
|
# Opción para deshabilitar audio (equivalente a la opción DISABLE_AUDIO de CMake)
|
||||||
no_audio:
|
no_audio:
|
||||||
|
@echo "Compilando sin audio: $(TARGET_NAME)_no_audio"
|
||||||
$(CXX) $(filter-out source/external/jail_audio.cpp,$(APP_SOURCES)) $(INCLUDES) -DNO_AUDIO $(CXXFLAGS) $(LDFLAGS) -o "$(TARGET_FILE)_no_audio"
|
$(CXX) $(filter-out source/external/jail_audio.cpp,$(APP_SOURCES)) $(INCLUDES) -DNO_AUDIO $(CXXFLAGS) $(LDFLAGS) -o "$(TARGET_FILE)_no_audio"
|
||||||
|
|
||||||
.PHONY: windows windows_rec windows_debug windows_release macos macos_debug macos_release linux linux_debug linux_release raspi raspi_debug raspi_release anbernic no_audio
|
# Regla para mostrar la versión actual
|
||||||
|
show_version:
|
||||||
|
@echo "Version actual: $(VERSION)"
|
||||||
|
|
||||||
|
# Regla de ayuda
|
||||||
|
help:
|
||||||
|
@echo "Makefile para Coffee Crisis Arcade Edition"
|
||||||
|
@echo "Comandos disponibles:"
|
||||||
|
@echo " windows - Compilar para Windows"
|
||||||
|
@echo " windows_debug - Compilar debug para Windows"
|
||||||
|
@echo " windows_release - Crear release completo para Windows"
|
||||||
|
@echo " linux - Compilar para Linux"
|
||||||
|
@echo " linux_debug - Compilar debug para Linux"
|
||||||
|
@echo " linux_release - Crear release basico para Linux"
|
||||||
|
@echo " linux_release_desktop - Crear release con integracion desktop para Linux"
|
||||||
|
@echo " macos - Compilar para macOS"
|
||||||
|
@echo " macos_debug - Compilar debug para macOS"
|
||||||
|
@echo " macos_release - Crear release completo para macOS"
|
||||||
|
@echo " raspi - Compilar para Raspberry Pi"
|
||||||
|
@echo " raspi_release - Crear release completo para Raspberry Pi"
|
||||||
|
@echo " anbernic - Compilar para Anbernic"
|
||||||
|
@echo " no_audio - Compilar sin sistema de audio"
|
||||||
|
@echo " pack_tool - Compilar herramienta de empaquetado"
|
||||||
|
@echo " resources.pack - Generar pack de recursos desde data/"
|
||||||
|
@echo " show_version - Mostrar version actual ($(VERSION))"
|
||||||
|
@echo " help - Mostrar esta ayuda"
|
||||||
|
|
||||||
|
.PHONY: windows windows_rec windows_debug windows_release macos macos_debug macos_release linux linux_debug linux_release linux_release_desktop raspi raspi_debug raspi_release anbernic no_audio show_version help pack_tool
|
||||||
61
TODO.md
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
# TODO
|
||||||
|
|
||||||
|
## Tareas pendientes
|
||||||
|
|
||||||
|
- [ ] Revisar todas las variables static de los métodos para ver si se resetean correctamente
|
||||||
|
|
||||||
|
## Mejoras arquitecturales (refactoring)
|
||||||
|
|
||||||
|
### Eliminar variables static locales y usar patrones profesionales:
|
||||||
|
|
||||||
|
**Opción 1: Máquina de Estados**
|
||||||
|
```cpp
|
||||||
|
class GameCompletedState {
|
||||||
|
bool start_celebrations_done = false;
|
||||||
|
bool end_celebrations_done = false;
|
||||||
|
float timer = 0.0f;
|
||||||
|
|
||||||
|
public:
|
||||||
|
void reset() {
|
||||||
|
start_celebrations_done = false;
|
||||||
|
end_celebrations_done = false;
|
||||||
|
timer = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void update(float deltaTime) {
|
||||||
|
timer += deltaTime;
|
||||||
|
// lógica aquí
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
**Opción 2: Sistema de Eventos/Callbacks**
|
||||||
|
```cpp
|
||||||
|
// Al entrar en COMPLETED state
|
||||||
|
eventSystem.scheduleEvent(6.0f, []{ startCelebrations(); });
|
||||||
|
eventSystem.scheduleEvent(14.0f, []{ endCelebrations(); });
|
||||||
|
```
|
||||||
|
|
||||||
|
**Opción 3: Flags como miembros privados**
|
||||||
|
```cpp
|
||||||
|
class Game {
|
||||||
|
private:
|
||||||
|
struct GameOverState {
|
||||||
|
bool game_over_triggered = false;
|
||||||
|
bool start_celebrations_triggered = false;
|
||||||
|
bool end_celebrations_triggered = false;
|
||||||
|
|
||||||
|
void reset() {
|
||||||
|
game_over_triggered = false;
|
||||||
|
start_celebrations_triggered = false;
|
||||||
|
end_celebrations_triggered = false;
|
||||||
|
}
|
||||||
|
} game_over_state_;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
**Ventajas:**
|
||||||
|
- Más fáciles de testear
|
||||||
|
- Más fáciles de debugear
|
||||||
|
- Más fáciles de entender y mantener
|
||||||
|
- No tienen "estado oculto"
|
||||||
@@ -1,41 +1,49 @@
|
|||||||
# Coffee Crisis - Asset Configuration
|
# Coffee Crisis Arcade Edition - Asset Configuration
|
||||||
# Formato: TIPO|RUTA [|OPCIONES]
|
# Formato: TIPO|RUTA [|OPCIONES]
|
||||||
# Opciones: optional, absolute (separadas por comas)
|
# Opciones: optional, absolute (separadas por comas)
|
||||||
# Variables: ${PREFIX}, ${SYSTEM_FOLDER}
|
# Variables: ${PREFIX}, ${SYSTEM_FOLDER}
|
||||||
|
|
||||||
# Archivos de configuración del sistema (absolutos y opcionales)
|
# Archivos de configuración del sistema (absolutos y opcionales)
|
||||||
DATA|${SYSTEM_FOLDER}/config.txt|optional,absolute
|
DATA|${SYSTEM_FOLDER}/config_v2.txt|optional,absolute
|
||||||
DATA|${SYSTEM_FOLDER}/controllers.json|optional,absolute
|
DATA|${SYSTEM_FOLDER}/controllers.json|optional,absolute
|
||||||
DATA|${SYSTEM_FOLDER}/score.bin|optional,absolute
|
DATA|${SYSTEM_FOLDER}/score.bin|optional,absolute
|
||||||
|
|
||||||
# Archivos de configuración del juego
|
# Archivos de configuración del juego
|
||||||
DATA|${PREFIX}/data/config/param_320x240.txt
|
DATA|${PREFIX}/config/formations.txt
|
||||||
DATA|${PREFIX}/data/config/param_320x256.txt
|
DATA|${PREFIX}/config/gamecontrollerdb.txt
|
||||||
DEMODATA|${PREFIX}/data/config/demo1.bin
|
DATA|${PREFIX}/config/param_320x240.txt
|
||||||
DEMODATA|${PREFIX}/data/config/demo2.bin
|
DATA|${PREFIX}/config/param_320x256.txt
|
||||||
DATA|${PREFIX}/data/config/gamecontrollerdb.txt
|
DATA|${PREFIX}/config/param_red.txt
|
||||||
DATA|${PREFIX}/data/config/formations.txt
|
DATA|${PREFIX}/config/pools.txt
|
||||||
DATA|${PREFIX}/data/config/pools.txt
|
DATA|${PREFIX}/config/stages.txt
|
||||||
|
|
||||||
|
# Archivos con los datos de la demo
|
||||||
|
DEMODATA|${PREFIX}/data/demo/demo1.bin
|
||||||
|
DEMODATA|${PREFIX}/data/demo/demo2.bin
|
||||||
|
DEMODATA|${PREFIX}/data/demo/demo3.bin
|
||||||
|
|
||||||
# Música
|
# Música
|
||||||
|
MUSIC|${PREFIX}/data/music/congratulations.ogg
|
||||||
|
MUSIC|${PREFIX}/data/music/credits.ogg
|
||||||
MUSIC|${PREFIX}/data/music/intro.ogg
|
MUSIC|${PREFIX}/data/music/intro.ogg
|
||||||
MUSIC|${PREFIX}/data/music/playing.ogg
|
MUSIC|${PREFIX}/data/music/playing.ogg
|
||||||
MUSIC|${PREFIX}/data/music/title.ogg
|
MUSIC|${PREFIX}/data/music/title.ogg
|
||||||
MUSIC|${PREFIX}/data/music/credits.ogg
|
|
||||||
|
|
||||||
# Sonidos
|
# Sonidos
|
||||||
SOUND|${PREFIX}/data/sound/balloon_pop0.wav
|
|
||||||
SOUND|${PREFIX}/data/sound/balloon_pop1.wav
|
|
||||||
SOUND|${PREFIX}/data/sound/balloon_pop2.wav
|
|
||||||
SOUND|${PREFIX}/data/sound/balloon_pop3.wav
|
|
||||||
SOUND|${PREFIX}/data/sound/balloon_bounce0.wav
|
SOUND|${PREFIX}/data/sound/balloon_bounce0.wav
|
||||||
SOUND|${PREFIX}/data/sound/balloon_bounce1.wav
|
SOUND|${PREFIX}/data/sound/balloon_bounce1.wav
|
||||||
SOUND|${PREFIX}/data/sound/balloon_bounce2.wav
|
SOUND|${PREFIX}/data/sound/balloon_bounce2.wav
|
||||||
SOUND|${PREFIX}/data/sound/balloon_bounce3.wav
|
SOUND|${PREFIX}/data/sound/balloon_bounce3.wav
|
||||||
SOUND|${PREFIX}/data/sound/bullet.wav
|
SOUND|${PREFIX}/data/sound/balloon_pop0.wav
|
||||||
|
SOUND|${PREFIX}/data/sound/balloon_pop1.wav
|
||||||
|
SOUND|${PREFIX}/data/sound/balloon_pop2.wav
|
||||||
|
SOUND|${PREFIX}/data/sound/balloon_pop3.wav
|
||||||
|
SOUND|${PREFIX}/data/sound/bullet1p.wav
|
||||||
|
SOUND|${PREFIX}/data/sound/bullet2p.wav
|
||||||
SOUND|${PREFIX}/data/sound/clock.wav
|
SOUND|${PREFIX}/data/sound/clock.wav
|
||||||
SOUND|${PREFIX}/data/sound/coffee_out.wav
|
SOUND|${PREFIX}/data/sound/coffee_out.wav
|
||||||
SOUND|${PREFIX}/data/sound/continue_clock.wav
|
SOUND|${PREFIX}/data/sound/continue_clock.wav
|
||||||
|
SOUND|${PREFIX}/data/sound/credit.wav
|
||||||
SOUND|${PREFIX}/data/sound/debian_drop.wav
|
SOUND|${PREFIX}/data/sound/debian_drop.wav
|
||||||
SOUND|${PREFIX}/data/sound/debian_pickup.wav
|
SOUND|${PREFIX}/data/sound/debian_pickup.wav
|
||||||
SOUND|${PREFIX}/data/sound/hi_score_achieved.wav
|
SOUND|${PREFIX}/data/sound/hi_score_achieved.wav
|
||||||
@@ -43,10 +51,12 @@ SOUND|${PREFIX}/data/sound/item_drop.wav
|
|||||||
SOUND|${PREFIX}/data/sound/item_pickup.wav
|
SOUND|${PREFIX}/data/sound/item_pickup.wav
|
||||||
SOUND|${PREFIX}/data/sound/jump.wav
|
SOUND|${PREFIX}/data/sound/jump.wav
|
||||||
SOUND|${PREFIX}/data/sound/logo.wav
|
SOUND|${PREFIX}/data/sound/logo.wav
|
||||||
|
SOUND|${PREFIX}/data/sound/name_input_accept.wav
|
||||||
SOUND|${PREFIX}/data/sound/notify.wav
|
SOUND|${PREFIX}/data/sound/notify.wav
|
||||||
SOUND|${PREFIX}/data/sound/player_collision.wav
|
SOUND|${PREFIX}/data/sound/player_collision.wav
|
||||||
SOUND|${PREFIX}/data/sound/power_ball_explosion.wav
|
SOUND|${PREFIX}/data/sound/power_ball_explosion.wav
|
||||||
SOUND|${PREFIX}/data/sound/service_menu_adjust.wav
|
SOUND|${PREFIX}/data/sound/service_menu_adjust.wav
|
||||||
|
SOUND|${PREFIX}/data/sound/service_menu_back.wav
|
||||||
SOUND|${PREFIX}/data/sound/service_menu_move.wav
|
SOUND|${PREFIX}/data/sound/service_menu_move.wav
|
||||||
SOUND|${PREFIX}/data/sound/service_menu_select.wav
|
SOUND|${PREFIX}/data/sound/service_menu_select.wav
|
||||||
SOUND|${PREFIX}/data/sound/stage_change.wav
|
SOUND|${PREFIX}/data/sound/stage_change.wav
|
||||||
@@ -55,57 +65,64 @@ SOUND|${PREFIX}/data/sound/tabe.wav
|
|||||||
SOUND|${PREFIX}/data/sound/title.wav
|
SOUND|${PREFIX}/data/sound/title.wav
|
||||||
SOUND|${PREFIX}/data/sound/voice_aw_aw_aw.wav
|
SOUND|${PREFIX}/data/sound/voice_aw_aw_aw.wav
|
||||||
SOUND|${PREFIX}/data/sound/voice_coffee.wav
|
SOUND|${PREFIX}/data/sound/voice_coffee.wav
|
||||||
|
SOUND|${PREFIX}/data/sound/voice_credit_thankyou.wav
|
||||||
|
SOUND|${PREFIX}/data/sound/voice_game_over.wav
|
||||||
SOUND|${PREFIX}/data/sound/voice_get_ready.wav
|
SOUND|${PREFIX}/data/sound/voice_get_ready.wav
|
||||||
SOUND|${PREFIX}/data/sound/voice_no.wav
|
SOUND|${PREFIX}/data/sound/voice_no.wav
|
||||||
SOUND|${PREFIX}/data/sound/voice_power_up.wav
|
SOUND|${PREFIX}/data/sound/voice_power_up.wav
|
||||||
|
SOUND|${PREFIX}/data/sound/voice_recover.wav
|
||||||
SOUND|${PREFIX}/data/sound/voice_thankyou.wav
|
SOUND|${PREFIX}/data/sound/voice_thankyou.wav
|
||||||
SOUND|${PREFIX}/data/sound/walk.wav
|
SOUND|${PREFIX}/data/sound/walk.wav
|
||||||
|
|
||||||
# Shaders
|
# Shaders OpenGL (Windows/Linux)
|
||||||
DATA|${PREFIX}/data/shaders/crtpi_256.glsl
|
DATA|${PREFIX}/data/shaders/crtpi_vertex.glsl
|
||||||
DATA|${PREFIX}/data/shaders/crtpi_240.glsl
|
DATA|${PREFIX}/data/shaders/crtpi_fragment.glsl
|
||||||
|
|
||||||
|
# Shaders Metal (macOS) - opcionales
|
||||||
|
DATA|${PREFIX}/data/shaders/crtpi_vertex.metal|optional
|
||||||
|
DATA|${PREFIX}/data/shaders/crtpi_fragment.metal|optional
|
||||||
|
|
||||||
# Texturas - Balloons
|
# Texturas - Balloons
|
||||||
BITMAP|${PREFIX}/data/gfx/balloon/balloon0.png
|
|
||||||
ANIMATION|${PREFIX}/data/gfx/balloon/balloon0.ani
|
ANIMATION|${PREFIX}/data/gfx/balloon/balloon0.ani
|
||||||
BITMAP|${PREFIX}/data/gfx/balloon/balloon1.png
|
|
||||||
ANIMATION|${PREFIX}/data/gfx/balloon/balloon1.ani
|
ANIMATION|${PREFIX}/data/gfx/balloon/balloon1.ani
|
||||||
BITMAP|${PREFIX}/data/gfx/balloon/balloon2.png
|
|
||||||
ANIMATION|${PREFIX}/data/gfx/balloon/balloon2.ani
|
ANIMATION|${PREFIX}/data/gfx/balloon/balloon2.ani
|
||||||
BITMAP|${PREFIX}/data/gfx/balloon/balloon3.png
|
|
||||||
ANIMATION|${PREFIX}/data/gfx/balloon/balloon3.ani
|
ANIMATION|${PREFIX}/data/gfx/balloon/balloon3.ani
|
||||||
|
BITMAP|${PREFIX}/data/gfx/balloon/balloon0.png
|
||||||
|
BITMAP|${PREFIX}/data/gfx/balloon/balloon1.png
|
||||||
|
BITMAP|${PREFIX}/data/gfx/balloon/balloon2.png
|
||||||
|
BITMAP|${PREFIX}/data/gfx/balloon/balloon3.png
|
||||||
|
|
||||||
# Texturas - Explosiones
|
# Texturas - Explosiones
|
||||||
BITMAP|${PREFIX}/data/gfx/balloon/explosion0.png
|
|
||||||
ANIMATION|${PREFIX}/data/gfx/balloon/explosion0.ani
|
ANIMATION|${PREFIX}/data/gfx/balloon/explosion0.ani
|
||||||
BITMAP|${PREFIX}/data/gfx/balloon/explosion1.png
|
|
||||||
ANIMATION|${PREFIX}/data/gfx/balloon/explosion1.ani
|
ANIMATION|${PREFIX}/data/gfx/balloon/explosion1.ani
|
||||||
BITMAP|${PREFIX}/data/gfx/balloon/explosion2.png
|
|
||||||
ANIMATION|${PREFIX}/data/gfx/balloon/explosion2.ani
|
ANIMATION|${PREFIX}/data/gfx/balloon/explosion2.ani
|
||||||
BITMAP|${PREFIX}/data/gfx/balloon/explosion3.png
|
|
||||||
ANIMATION|${PREFIX}/data/gfx/balloon/explosion3.ani
|
ANIMATION|${PREFIX}/data/gfx/balloon/explosion3.ani
|
||||||
|
BITMAP|${PREFIX}/data/gfx/balloon/explosion0.png
|
||||||
|
BITMAP|${PREFIX}/data/gfx/balloon/explosion1.png
|
||||||
|
BITMAP|${PREFIX}/data/gfx/balloon/explosion2.png
|
||||||
|
BITMAP|${PREFIX}/data/gfx/balloon/explosion3.png
|
||||||
|
|
||||||
# Texturas - Power Ball
|
# Texturas - Power Ball
|
||||||
BITMAP|${PREFIX}/data/gfx/balloon/powerball.png
|
|
||||||
ANIMATION|${PREFIX}/data/gfx/balloon/powerball.ani
|
ANIMATION|${PREFIX}/data/gfx/balloon/powerball.ani
|
||||||
|
BITMAP|${PREFIX}/data/gfx/balloon/powerball.png
|
||||||
|
|
||||||
# Texturas - Bala
|
# Texturas - Bala
|
||||||
BITMAP|${PREFIX}/data/gfx/bullet/bullet.png
|
|
||||||
ANIMATION|${PREFIX}/data/gfx/bullet/bullet.ani
|
ANIMATION|${PREFIX}/data/gfx/bullet/bullet.ani
|
||||||
|
BITMAP|${PREFIX}/data/gfx/bullet/bullet.png
|
||||||
|
|
||||||
# Texturas - Tabe
|
# Texturas - Tabe
|
||||||
BITMAP|${PREFIX}/data/gfx/tabe/tabe.png
|
|
||||||
ANIMATION|${PREFIX}/data/gfx/tabe/tabe.ani
|
ANIMATION|${PREFIX}/data/gfx/tabe/tabe.ani
|
||||||
|
BITMAP|${PREFIX}/data/gfx/tabe/tabe.png
|
||||||
|
|
||||||
# Texturas - Juego
|
# Texturas - Juego
|
||||||
BITMAP|${PREFIX}/data/gfx/game/game_buildings.png
|
BITMAP|${PREFIX}/data/gfx/game/game_buildings.png
|
||||||
BITMAP|${PREFIX}/data/gfx/game/game_clouds1.png
|
BITMAP|${PREFIX}/data/gfx/game/game_clouds1.png
|
||||||
BITMAP|${PREFIX}/data/gfx/game/game_clouds2.png
|
BITMAP|${PREFIX}/data/gfx/game/game_clouds2.png
|
||||||
BITMAP|${PREFIX}/data/gfx/game/game_grass.png
|
BITMAP|${PREFIX}/data/gfx/game/game_grass.png
|
||||||
|
BITMAP|${PREFIX}/data/gfx/game/game_moon.png
|
||||||
BITMAP|${PREFIX}/data/gfx/game/game_power_meter.png
|
BITMAP|${PREFIX}/data/gfx/game/game_power_meter.png
|
||||||
BITMAP|${PREFIX}/data/gfx/game/game_sky_colors.png
|
BITMAP|${PREFIX}/data/gfx/game/game_sky_colors.png
|
||||||
BITMAP|${PREFIX}/data/gfx/game/game_sun.png
|
BITMAP|${PREFIX}/data/gfx/game/game_sun.png
|
||||||
BITMAP|${PREFIX}/data/gfx/game/game_moon.png
|
|
||||||
|
|
||||||
# Texturas - Intro
|
# Texturas - Intro
|
||||||
BITMAP|${PREFIX}/data/gfx/intro/intro1.png
|
BITMAP|${PREFIX}/data/gfx/intro/intro1.png
|
||||||
@@ -116,75 +133,77 @@ BITMAP|${PREFIX}/data/gfx/intro/intro5.png
|
|||||||
BITMAP|${PREFIX}/data/gfx/intro/intro6.png
|
BITMAP|${PREFIX}/data/gfx/intro/intro6.png
|
||||||
|
|
||||||
# Texturas - Logo
|
# Texturas - Logo
|
||||||
BITMAP|${PREFIX}/data/gfx/logo/logo_jailgames.png
|
|
||||||
BITMAP|${PREFIX}/data/gfx/logo/logo_jailgames_mini.png
|
BITMAP|${PREFIX}/data/gfx/logo/logo_jailgames_mini.png
|
||||||
|
BITMAP|${PREFIX}/data/gfx/logo/logo_jailgames.png
|
||||||
BITMAP|${PREFIX}/data/gfx/logo/logo_since_1998.png
|
BITMAP|${PREFIX}/data/gfx/logo/logo_since_1998.png
|
||||||
|
|
||||||
# Texturas - Items
|
# Texturas - Items
|
||||||
BITMAP|${PREFIX}/data/gfx/item/item_points1_disk.png
|
ANIMATION|${PREFIX}/data/gfx/item/item_clock.ani
|
||||||
|
ANIMATION|${PREFIX}/data/gfx/item/item_coffee_machine.ani
|
||||||
|
ANIMATION|${PREFIX}/data/gfx/item/item_coffee.ani
|
||||||
|
ANIMATION|${PREFIX}/data/gfx/item/item_debian.ani
|
||||||
ANIMATION|${PREFIX}/data/gfx/item/item_points1_disk.ani
|
ANIMATION|${PREFIX}/data/gfx/item/item_points1_disk.ani
|
||||||
BITMAP|${PREFIX}/data/gfx/item/item_points2_gavina.png
|
|
||||||
ANIMATION|${PREFIX}/data/gfx/item/item_points2_gavina.ani
|
ANIMATION|${PREFIX}/data/gfx/item/item_points2_gavina.ani
|
||||||
BITMAP|${PREFIX}/data/gfx/item/item_points3_pacmar.png
|
|
||||||
ANIMATION|${PREFIX}/data/gfx/item/item_points3_pacmar.ani
|
ANIMATION|${PREFIX}/data/gfx/item/item_points3_pacmar.ani
|
||||||
BITMAP|${PREFIX}/data/gfx/item/item_clock.png
|
BITMAP|${PREFIX}/data/gfx/item/item_clock.png
|
||||||
ANIMATION|${PREFIX}/data/gfx/item/item_clock.ani
|
|
||||||
BITMAP|${PREFIX}/data/gfx/item/item_coffee.png
|
|
||||||
ANIMATION|${PREFIX}/data/gfx/item/item_coffee.ani
|
|
||||||
BITMAP|${PREFIX}/data/gfx/item/item_debian.png
|
|
||||||
ANIMATION|${PREFIX}/data/gfx/item/item_debian.ani
|
|
||||||
BITMAP|${PREFIX}/data/gfx/item/item_coffee_machine.png
|
BITMAP|${PREFIX}/data/gfx/item/item_coffee_machine.png
|
||||||
ANIMATION|${PREFIX}/data/gfx/item/item_coffee_machine.ani
|
BITMAP|${PREFIX}/data/gfx/item/item_coffee.png
|
||||||
|
BITMAP|${PREFIX}/data/gfx/item/item_debian.png
|
||||||
|
BITMAP|${PREFIX}/data/gfx/item/item_points1_disk.png
|
||||||
|
BITMAP|${PREFIX}/data/gfx/item/item_points2_gavina.png
|
||||||
|
BITMAP|${PREFIX}/data/gfx/item/item_points3_pacmar.png
|
||||||
|
|
||||||
# Texturas - Titulo
|
# Texturas - Titulo
|
||||||
|
ANIMATION|${PREFIX}/data/gfx/title/title_dust.ani
|
||||||
|
BITMAP|${PREFIX}/data/gfx/title/title_arcade_edition.png
|
||||||
BITMAP|${PREFIX}/data/gfx/title/title_bg_tile.png
|
BITMAP|${PREFIX}/data/gfx/title/title_bg_tile.png
|
||||||
BITMAP|${PREFIX}/data/gfx/title/title_coffee.png
|
BITMAP|${PREFIX}/data/gfx/title/title_coffee.png
|
||||||
BITMAP|${PREFIX}/data/gfx/title/title_crisis.png
|
BITMAP|${PREFIX}/data/gfx/title/title_crisis.png
|
||||||
BITMAP|${PREFIX}/data/gfx/title/title_arcade_edition.png
|
|
||||||
BITMAP|${PREFIX}/data/gfx/title/title_dust.png
|
BITMAP|${PREFIX}/data/gfx/title/title_dust.png
|
||||||
ANIMATION|${PREFIX}/data/gfx/title/title_dust.ani
|
|
||||||
|
|
||||||
# Texturas - Jugador 1
|
# Texturas - Jugador 1
|
||||||
|
BITMAP|${PREFIX}/data/gfx/player/player1_power.png
|
||||||
BITMAP|${PREFIX}/data/gfx/player/player1.gif
|
BITMAP|${PREFIX}/data/gfx/player/player1.gif
|
||||||
PALETTE|${PREFIX}/data/gfx/player/player1_coffee1.pal
|
PALETTE|${PREFIX}/data/gfx/player/player1_coffee1.pal
|
||||||
PALETTE|${PREFIX}/data/gfx/player/player1_coffee2.pal
|
PALETTE|${PREFIX}/data/gfx/player/player1_coffee2.pal
|
||||||
PALETTE|${PREFIX}/data/gfx/player/player1_invencible.pal
|
PALETTE|${PREFIX}/data/gfx/player/player1_invencible.pal
|
||||||
BITMAP|${PREFIX}/data/gfx/player/player1_power.png
|
|
||||||
|
|
||||||
# Texturas - Jugador 2
|
# Texturas - Jugador 2
|
||||||
|
BITMAP|${PREFIX}/data/gfx/player/player2_power.png
|
||||||
BITMAP|${PREFIX}/data/gfx/player/player2.gif
|
BITMAP|${PREFIX}/data/gfx/player/player2.gif
|
||||||
PALETTE|${PREFIX}/data/gfx/player/player2_coffee1.pal
|
PALETTE|${PREFIX}/data/gfx/player/player2_coffee1.pal
|
||||||
PALETTE|${PREFIX}/data/gfx/player/player2_coffee2.pal
|
PALETTE|${PREFIX}/data/gfx/player/player2_coffee2.pal
|
||||||
PALETTE|${PREFIX}/data/gfx/player/player2_invencible.pal
|
PALETTE|${PREFIX}/data/gfx/player/player2_invencible.pal
|
||||||
BITMAP|${PREFIX}/data/gfx/player/player2_power.png
|
|
||||||
|
|
||||||
# Animaciones del jugador
|
# Animaciones del jugador
|
||||||
ANIMATION|${PREFIX}/data/gfx/player/player.ani
|
|
||||||
ANIMATION|${PREFIX}/data/gfx/player/player_power.ani
|
ANIMATION|${PREFIX}/data/gfx/player/player_power.ani
|
||||||
|
ANIMATION|${PREFIX}/data/gfx/player/player.ani
|
||||||
|
|
||||||
# Texturas - Golpe del jugador
|
# Texturas - Golpe del jugador
|
||||||
BITMAP|${PREFIX}/data/gfx/player/hit.png
|
BITMAP|${PREFIX}/data/gfx/player/hit.png
|
||||||
|
|
||||||
# Fuentes de texto
|
# Fuentes de texto
|
||||||
BITMAP|${PREFIX}/data/font/8bithud.png
|
|
||||||
FONT|${PREFIX}/data/font/8bithud.txt
|
|
||||||
BITMAP|${PREFIX}/data/font/aseprite.png
|
|
||||||
FONT|${PREFIX}/data/font/aseprite.txt
|
|
||||||
BITMAP|${PREFIX}/data/font/smb2.png
|
|
||||||
BITMAP|${PREFIX}/data/font/smb2_grad.png
|
|
||||||
FONT|${PREFIX}/data/font/smb2.txt
|
|
||||||
BITMAP|${PREFIX}/data/font/04b_25.png
|
|
||||||
FONT|${PREFIX}/data/font/04b_25.txt
|
|
||||||
BITMAP|${PREFIX}/data/font/04b_25_2x.png
|
BITMAP|${PREFIX}/data/font/04b_25_2x.png
|
||||||
FONT|${PREFIX}/data/font/04b_25_2x.txt
|
BITMAP|${PREFIX}/data/font/04b_25_2x_white.png
|
||||||
BITMAP|${PREFIX}/data/font/04b_25_metal.png
|
|
||||||
BITMAP|${PREFIX}/data/font/04b_25_grey.png
|
|
||||||
BITMAP|${PREFIX}/data/font/04b_25_flat.png
|
|
||||||
BITMAP|${PREFIX}/data/font/04b_25_reversed.png
|
|
||||||
BITMAP|${PREFIX}/data/font/04b_25_flat_2x.png
|
BITMAP|${PREFIX}/data/font/04b_25_flat_2x.png
|
||||||
|
BITMAP|${PREFIX}/data/font/04b_25_flat.png
|
||||||
|
BITMAP|${PREFIX}/data/font/04b_25_grey.png
|
||||||
|
BITMAP|${PREFIX}/data/font/04b_25_metal.png
|
||||||
BITMAP|${PREFIX}/data/font/04b_25_reversed_2x.png
|
BITMAP|${PREFIX}/data/font/04b_25_reversed_2x.png
|
||||||
|
BITMAP|${PREFIX}/data/font/04b_25_reversed.png
|
||||||
|
BITMAP|${PREFIX}/data/font/04b_25_white.png
|
||||||
|
BITMAP|${PREFIX}/data/font/04b_25.png
|
||||||
|
BITMAP|${PREFIX}/data/font/8bithud.png
|
||||||
|
BITMAP|${PREFIX}/data/font/aseprite.png
|
||||||
|
BITMAP|${PREFIX}/data/font/smb2_grad.png
|
||||||
|
BITMAP|${PREFIX}/data/font/smb2.png
|
||||||
|
FONT|${PREFIX}/data/font/04b_25_2x.txt
|
||||||
|
FONT|${PREFIX}/data/font/04b_25.txt
|
||||||
|
FONT|${PREFIX}/data/font/8bithud.txt
|
||||||
|
FONT|${PREFIX}/data/font/aseprite.txt
|
||||||
|
FONT|${PREFIX}/data/font/smb2.txt
|
||||||
|
|
||||||
# Idiomas
|
# Idiomas
|
||||||
LANG|${PREFIX}/data/lang/es_ES.json
|
LANG|${PREFIX}/data/lang/ba_BA.json
|
||||||
LANG|${PREFIX}/data/lang/en_UK.json
|
LANG|${PREFIX}/data/lang/en_UK.json
|
||||||
LANG|${PREFIX}/data/lang/ba_BA.json
|
LANG|${PREFIX}/data/lang/es_ES.json
|
||||||
277
config/formations.txt
Normal file
@@ -0,0 +1,277 @@
|
|||||||
|
# Coffee Crisis Arcade Edition - Archivo de configuración de formaciones de globos
|
||||||
|
# Formato por línea: x, desp, y, vel_x, tipo, tamaño, retraso_tiempo_creacion
|
||||||
|
# Variables disponibles:
|
||||||
|
# X0_0, X0_50, X0_100, X1_0, X1_100, X2_0, X2_100, X3_0, X3_100
|
||||||
|
# X3_25, X3_75, DEFAULT_POS_Y
|
||||||
|
# SMALL, MEDIUM, LARGE, EXTRALARGE
|
||||||
|
# RIGHT, LEFT
|
||||||
|
|
||||||
|
formation: 0
|
||||||
|
# Dos enemigos BALLOON3 uno a cada extremo
|
||||||
|
X3_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, EXTRALARGE, 0.0000
|
||||||
|
X3_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, EXTRALARGE, 0.0000
|
||||||
|
|
||||||
|
formation: 1
|
||||||
|
# Dos enemigos BALLOON3 uno a cada cuarto. Ambos van hacia el centro
|
||||||
|
X3_25, 0, DEFAULT_POS_Y, RIGHT, BALLOON, EXTRALARGE, 0.0000
|
||||||
|
X3_75, 0, DEFAULT_POS_Y, LEFT, BALLOON, EXTRALARGE, 0.0000
|
||||||
|
|
||||||
|
formation: 2
|
||||||
|
# Cuatro enemigos BALLOON1 uno detrás del otro. A la izquierda y hacia el centro
|
||||||
|
X1_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 0.5000
|
||||||
|
X1_0, 1, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 0.3333
|
||||||
|
X1_0, 2, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 0.1667
|
||||||
|
X1_0, 3, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 0.0000
|
||||||
|
|
||||||
|
formation: 3
|
||||||
|
# Cuatro enemigos BALLOON1 uno detrás del otro. A la derecha y hacia el centro
|
||||||
|
X1_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 0.5000
|
||||||
|
X1_100, -1, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 0.3333
|
||||||
|
X1_100, -2, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 0.1667
|
||||||
|
X1_100, -3, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 0.0000
|
||||||
|
|
||||||
|
formation: 4
|
||||||
|
# Tres enemigos BALLOON2. 0, 25, 50. Hacia la derecha
|
||||||
|
X2_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0.3333
|
||||||
|
X2_0, 2, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0.1667
|
||||||
|
X2_0, 4, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0.0000
|
||||||
|
|
||||||
|
formation: 5
|
||||||
|
# Tres enemigos BALLOON2. 50, 75, 100. Hacia la izquierda
|
||||||
|
X2_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0.3333
|
||||||
|
X2_100, -2, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0.1667
|
||||||
|
X2_100, -4, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0.0000
|
||||||
|
|
||||||
|
formation: 6
|
||||||
|
# Tres enemigos BALLOON2. 0, 0, 0. Hacia la derecha
|
||||||
|
X2_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0.3333
|
||||||
|
X2_0, 1, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0.1667
|
||||||
|
X2_0, 2, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0.0000
|
||||||
|
|
||||||
|
formation: 7
|
||||||
|
# Tres enemigos BALLOON2. 100, 100, 100. Hacia la izquierda
|
||||||
|
X2_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0.3333
|
||||||
|
X2_100, -1, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0.1667
|
||||||
|
X2_100, -2, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0.0000
|
||||||
|
|
||||||
|
formation: 8
|
||||||
|
# Seis enemigos BALLOON0. 0, 0, 0, 0, 0, 0. Hacia la derecha
|
||||||
|
X0_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.8333
|
||||||
|
X0_0, 1, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.6667
|
||||||
|
X0_0, 2, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.5000
|
||||||
|
X0_0, 3, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.3333
|
||||||
|
X0_0, 4, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.1667
|
||||||
|
X0_0, 5, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.0000
|
||||||
|
|
||||||
|
formation: 9
|
||||||
|
# Seis enemigos BALLOON0. 100, 100, 100, 100, 100, 100. Hacia la izquierda
|
||||||
|
X0_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.8333
|
||||||
|
X0_100, -1, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.6667
|
||||||
|
X0_100, -2, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.5000
|
||||||
|
X0_100, -3, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.3333
|
||||||
|
X0_100, -4, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.1667
|
||||||
|
X0_100, -5, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.0000
|
||||||
|
|
||||||
|
formation: 10
|
||||||
|
# Tres enemigos BALLOON3 seguidos desde la izquierda. Hacia la derecha
|
||||||
|
X3_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, EXTRALARGE, 0.5000
|
||||||
|
X3_0, 1, DEFAULT_POS_Y, RIGHT, BALLOON, EXTRALARGE, 0.2500
|
||||||
|
X3_0, 2, DEFAULT_POS_Y, RIGHT, BALLOON, EXTRALARGE, 0.0000
|
||||||
|
|
||||||
|
formation: 11
|
||||||
|
# Tres enemigos BALLOON3 seguidos desde la derecha. Hacia la izquierda
|
||||||
|
X3_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, EXTRALARGE, 0.5000
|
||||||
|
X3_100, -1, DEFAULT_POS_Y, LEFT, BALLOON, EXTRALARGE, 0.2500
|
||||||
|
X3_100, -2, DEFAULT_POS_Y, LEFT, BALLOON, EXTRALARGE, 0.0000
|
||||||
|
|
||||||
|
formation: 12
|
||||||
|
# Seis enemigos BALLOON1 uno detrás del otro. A la izquierda y hacia el centro
|
||||||
|
X1_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 0.8333
|
||||||
|
X1_0, 1, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 0.6667
|
||||||
|
X1_0, 2, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 0.5000
|
||||||
|
X1_0, 3, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 0.3333
|
||||||
|
X1_0, 4, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 0.1667
|
||||||
|
X1_0, 5, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 0.0000
|
||||||
|
|
||||||
|
formation: 13
|
||||||
|
# Seis enemigos BALLOON1 uno detrás del otro. A la derecha y hacia el centro
|
||||||
|
X1_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 0.8333
|
||||||
|
X1_100, -1, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 0.6667
|
||||||
|
X1_100, -2, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 0.5000
|
||||||
|
X1_100, -3, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 0.3333
|
||||||
|
X1_100, -4, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 0.1667
|
||||||
|
X1_100, -5, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 0.0000
|
||||||
|
|
||||||
|
formation: 14
|
||||||
|
# Cinco enemigos BALLOON2. Hacia la derecha. Separados
|
||||||
|
X2_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0.6667
|
||||||
|
X2_0, 2, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0.5000
|
||||||
|
X2_0, 4, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0.3333
|
||||||
|
X2_0, 6, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0.1667
|
||||||
|
X2_0, 8, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0.0000
|
||||||
|
|
||||||
|
formation: 15
|
||||||
|
# Cinco enemigos BALLOON2. Hacia la izquierda. Separados
|
||||||
|
X2_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0.6667
|
||||||
|
X2_100, -2, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0.5000
|
||||||
|
X2_100, -4, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0.3333
|
||||||
|
X2_100, -6, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0.1667
|
||||||
|
X2_100, -8, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0.0000
|
||||||
|
|
||||||
|
formation: 16
|
||||||
|
# Cinco enemigos BALLOON2. Hacia la derecha. Juntos
|
||||||
|
X2_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0.6667
|
||||||
|
X2_0, 1, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0.5000
|
||||||
|
X2_0, 2, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0.3333
|
||||||
|
X2_0, 3, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0.1667
|
||||||
|
X2_0, 4, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0.0000
|
||||||
|
|
||||||
|
formation: 17
|
||||||
|
# Cinco enemigos BALLOON2. Hacia la izquierda. Juntos
|
||||||
|
X2_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0.6667
|
||||||
|
X2_100, -1, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0.5000
|
||||||
|
X2_100, -2, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0.3333
|
||||||
|
X2_100, -3, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0.1667
|
||||||
|
X2_100, -4, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0.0000
|
||||||
|
|
||||||
|
formation: 18
|
||||||
|
# Doce enemigos BALLOON0. Hacia la derecha. Juntos
|
||||||
|
X0_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 1.8333
|
||||||
|
X0_0, 1, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 1.6667
|
||||||
|
X0_0, 2, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 1.5000
|
||||||
|
X0_0, 3, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 1.3333
|
||||||
|
X0_0, 4, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 1.1667
|
||||||
|
X0_0, 5, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 1.0000
|
||||||
|
X0_0, 6, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.8333
|
||||||
|
X0_0, 7, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.6667
|
||||||
|
X0_0, 8, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.5000
|
||||||
|
X0_0, 9, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.3333
|
||||||
|
X0_0, 10, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.1667
|
||||||
|
X0_0, 11, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.0000
|
||||||
|
|
||||||
|
formation: 19
|
||||||
|
# Doce enemigos BALLOON0. Hacia la izquierda. Juntos
|
||||||
|
X0_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 1.8333
|
||||||
|
X0_100, -1, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 1.6667
|
||||||
|
X0_100, -2, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 1.5000
|
||||||
|
X0_100, -3, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 1.3333
|
||||||
|
X0_100, -4, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 1.1667
|
||||||
|
X0_100, -5, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 1.0000
|
||||||
|
X0_100, -6, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.8333
|
||||||
|
X0_100, -7, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.6667
|
||||||
|
X0_100, -8, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.5000
|
||||||
|
X0_100, -9, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.3333
|
||||||
|
X0_100, -10, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.1667
|
||||||
|
X0_100, -11, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.0000
|
||||||
|
|
||||||
|
formation: 20
|
||||||
|
# Cuatro enemigos BALLOON3 seguidos desde la izquierda/derecha. Simétricos
|
||||||
|
X3_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, EXTRALARGE, 0.0000
|
||||||
|
X3_0, 1, DEFAULT_POS_Y, RIGHT, BALLOON, EXTRALARGE, 0.0000
|
||||||
|
X3_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, EXTRALARGE, 0.0000
|
||||||
|
X3_100, -1, DEFAULT_POS_Y, LEFT, BALLOON, EXTRALARGE, 0.0000
|
||||||
|
|
||||||
|
formation: 21
|
||||||
|
# Diez enemigos BALLOON1 uno detrás del otro. Izquierda/derecha. Simétricos
|
||||||
|
X1_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 0.2000
|
||||||
|
X1_0, 1, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 0.1500
|
||||||
|
X1_0, 2, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 0.1000
|
||||||
|
X1_0, 3, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 0.0500
|
||||||
|
X1_0, 4, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 0.0000
|
||||||
|
X1_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 0.2000
|
||||||
|
X1_100, -1, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 0.1500
|
||||||
|
X1_100, -2, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 0.1000
|
||||||
|
X1_100, -3, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 0.0500
|
||||||
|
X1_100, -4, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 0.0000
|
||||||
|
|
||||||
|
formation: 22
|
||||||
|
# Diez enemigos BALLOON2. Hacia la derecha/izquierda. Separados. Simétricos
|
||||||
|
X2_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0.6667
|
||||||
|
X2_0, 2, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0.5000
|
||||||
|
X2_0, 4, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0.3333
|
||||||
|
X2_0, 6, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0.1667
|
||||||
|
X2_0, 8, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0.0000
|
||||||
|
X2_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0.6667
|
||||||
|
X2_100, -2, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0.5000
|
||||||
|
X2_100, -4, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0.3333
|
||||||
|
X2_100, -6, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0.1667
|
||||||
|
X2_100, -8, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0.0000
|
||||||
|
|
||||||
|
formation: 23
|
||||||
|
# Diez enemigos BALLOON2. Hacia la derecha. Juntos. Simétricos
|
||||||
|
X2_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0.6667
|
||||||
|
X2_0, 1, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0.5000
|
||||||
|
X2_0, 2, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0.3333
|
||||||
|
X2_0, 3, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0.1667
|
||||||
|
X2_0, 4, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0.0000
|
||||||
|
X2_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0.6667
|
||||||
|
X2_100, -1, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0.5000
|
||||||
|
X2_100, -2, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0.3333
|
||||||
|
X2_100, -3, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0.1667
|
||||||
|
X2_100, -4, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0.0000
|
||||||
|
|
||||||
|
formation: 24
|
||||||
|
# Treinta enemigos BALLOON0. Del centro hacia los extremos. Juntos. Simétricos
|
||||||
|
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.0000
|
||||||
|
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.0833
|
||||||
|
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.1667
|
||||||
|
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.2500
|
||||||
|
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.3333
|
||||||
|
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.4167
|
||||||
|
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.5000
|
||||||
|
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.5833
|
||||||
|
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.6667
|
||||||
|
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.7500
|
||||||
|
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.8333
|
||||||
|
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.9167
|
||||||
|
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 1.0000
|
||||||
|
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 1.0833
|
||||||
|
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 1.1667
|
||||||
|
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.0000
|
||||||
|
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.0833
|
||||||
|
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.1667
|
||||||
|
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.2500
|
||||||
|
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.3333
|
||||||
|
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.4167
|
||||||
|
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.5000
|
||||||
|
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.5833
|
||||||
|
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.6667
|
||||||
|
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.7500
|
||||||
|
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.8333
|
||||||
|
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.9167
|
||||||
|
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 1.0000
|
||||||
|
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 1.0833
|
||||||
|
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 1.1667
|
||||||
|
|
||||||
|
formation: 25
|
||||||
|
# Treinta enemigos BALLOON0. Del centro hacia adentro. Juntos. Simétricos
|
||||||
|
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 1.1667
|
||||||
|
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 1.0833
|
||||||
|
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 1.0000
|
||||||
|
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.9167
|
||||||
|
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.8333
|
||||||
|
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.7500
|
||||||
|
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.6667
|
||||||
|
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.5833
|
||||||
|
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.5000
|
||||||
|
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.4167
|
||||||
|
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.3333
|
||||||
|
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.2500
|
||||||
|
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.1667
|
||||||
|
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.0833
|
||||||
|
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.0000
|
||||||
|
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 1.1667
|
||||||
|
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 1.0833
|
||||||
|
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 1.0000
|
||||||
|
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.9167
|
||||||
|
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.8333
|
||||||
|
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.7500
|
||||||
|
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.6667
|
||||||
|
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.5833
|
||||||
|
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.5000
|
||||||
|
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.4167
|
||||||
|
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.3333
|
||||||
|
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.2500
|
||||||
|
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.1667
|
||||||
|
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.0833
|
||||||
|
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.0000
|
||||||
150
config/param_320x240.txt
Normal file
@@ -0,0 +1,150 @@
|
|||||||
|
# Coffee Crisis Arcade Edition - Fichero de parametros
|
||||||
|
# Formato: PARAMETRO VALOR
|
||||||
|
|
||||||
|
# --- GAME ---
|
||||||
|
game.item_text_outline_color E0E0E0F0 # Color del outline del texto de los items (RGBA hex)
|
||||||
|
game.width 320 # Ancho de la resolución nativa del juego (en píxeles)
|
||||||
|
game.height 240 # Alto de la resolución nativa del juego (en píxeles)
|
||||||
|
game.play_area.rect.x 0 # Posición X de la zona jugable
|
||||||
|
game.play_area.rect.y 0 # Posición Y de la zona jugable
|
||||||
|
game.play_area.rect.w 320 # Ancho de la zona jugable
|
||||||
|
game.play_area.rect.h 200 # Alto de la zona jugable
|
||||||
|
game.name_entry_idle_time 10 # Segundos para introducir el nombre al finalizar la partida si no se pulsa nada
|
||||||
|
game.name_entry_total_time 60 # Segundos totales para introducir el nombre al finalizar la partida
|
||||||
|
game.hit_stop false # Indica si debe haber un paro cuando el jugador es golpeado por un globo
|
||||||
|
game.hit_stop_ms 500 # Cantidad de milisegundos que dura el hit_stop
|
||||||
|
|
||||||
|
# --- FADE ---
|
||||||
|
fade.color 1F2B30 # Color hexadecimal para el efecto de fundido
|
||||||
|
fade.num_squares_width 64 # Número de cuadrados en el eje X para el fundido
|
||||||
|
fade.num_squares_height 48 # Número de cuadrados en el eje Y para el fundido
|
||||||
|
fade.random_squares_duration_ms 1200 # Duración del fade en milisegundos
|
||||||
|
fade.post_duration_ms 500 # Duración tras el fundido en milisegundos
|
||||||
|
fade.venetian_size 12 # Tamaño de las bandas para el efecto veneciano (en píxeles)
|
||||||
|
|
||||||
|
# --- SCOREBOARD ---
|
||||||
|
scoreboard.rect.x 0 # Posición X del marcador
|
||||||
|
scoreboard.rect.y 216 # Posición Y del marcador
|
||||||
|
scoreboard.rect.w 320 # Ancho del marcador
|
||||||
|
scoreboard.rect.h 40 # Alto del marcador
|
||||||
|
scoreboard.separator_autocolor true # ¿El separador usa color automático?
|
||||||
|
scoreboard.separator_color 0D1A2B # Color del separador (hexadecimal)
|
||||||
|
scoreboard.easy_color 4B692F # Color para la dificultad fácil
|
||||||
|
scoreboard.normal_color 2E3F47 # Color para la dificultad normal
|
||||||
|
scoreboard.hard_color 76428A # Color para la dificultad difícil
|
||||||
|
scoreboard.text_autocolor true # ¿El texto usa color automático?
|
||||||
|
scoreboard.text_color1 FFFFFF # Color principal del texto del marcador
|
||||||
|
scoreboard.text_color2 FFFFFF # Color secundario del texto del marcador
|
||||||
|
scoreboard.skip_countdown_value 8 # Valor para saltar la cuenta atrás (segundos)
|
||||||
|
|
||||||
|
# --- TITLE ---
|
||||||
|
title.press_start_position 180 # Posición Y del texto "Press Start"
|
||||||
|
title.title_duration 14 # Duración de la pantalla de título (segundos)
|
||||||
|
title.arcade_edition_position 123 # Posición Y del subtítulo "Arcade Edition"
|
||||||
|
title.title_c_c_position 80 # Posición Y del título principal
|
||||||
|
title.bg_color 41526F # Color de fondo en la sección titulo
|
||||||
|
|
||||||
|
# --- BACKGROUND ---
|
||||||
|
background.attenuate_color FFFFFF00 # Color de atenuación del fondo (RGBA hexadecimal)
|
||||||
|
|
||||||
|
# --- BALLOONS --- (deltaTime en segundos: vel en pixels/s, grav en pixels/s²)
|
||||||
|
balloon.settings[0].vel 165.0f # Velocidad inicial del globo 1 (pixels/s)
|
||||||
|
balloon.settings[0].grav 320.0f # Gravedad aplicada al globo 1 (pixels/s²)
|
||||||
|
balloon.settings[1].vel 222.0f # Velocidad inicial del globo 2 (pixels/s)
|
||||||
|
balloon.settings[1].grav 360.0f # Gravedad aplicada al globo 2 (pixels/s²)
|
||||||
|
balloon.settings[2].vel 282.0f # Velocidad inicial del globo 3 (pixels/s)
|
||||||
|
balloon.settings[2].grav 360.0f # Gravedad aplicada al globo 3 (pixels/s²)
|
||||||
|
balloon.settings[3].vel 327.0f # Velocidad inicial del globo 4 (pixels/s)
|
||||||
|
balloon.settings[3].grav 360.0f # Gravedad aplicada al globo 4 (pixels/s²)
|
||||||
|
|
||||||
|
balloon.color[0] blue # Color de creación del globo normal
|
||||||
|
balloon.color[1] orange # Color del globo normal
|
||||||
|
balloon.color[2] red # Color de creación del globo que rebota
|
||||||
|
balloon.color[3] green # Color del globo que rebota
|
||||||
|
|
||||||
|
balloon.bouncing_sound false # Indica si los globos hacer sonido al rebotar
|
||||||
|
|
||||||
|
# --- NOTIFICATION ---
|
||||||
|
notification.pos_v TOP # Posición vertical de la notificación (TOP/BOTTOM)
|
||||||
|
notification.pos_h LEFT # Posición horizontal de la notificación (LEFT/RIGHT)
|
||||||
|
notification.sound false # ¿La notificación reproduce sonido?
|
||||||
|
notification.color 303030 # Color de fondo de la notificación (hexadecimal)
|
||||||
|
|
||||||
|
# --- SERVICE MENU ---
|
||||||
|
service_menu.title_color 99FF62 # Color del título del menú de servicio
|
||||||
|
service_menu.text_color FFFFFF # Color del texto del menú de servicio
|
||||||
|
service_menu.selected_color FFDC44 # Color de la opción seleccionada en el menú de servicio
|
||||||
|
service_menu.bg_color 000F00F5 # Color de fondo del menú de servicio (RGBA hexadecimal)
|
||||||
|
service_menu.drop_shadow false # ¿El menú de servicio tiene sombra?
|
||||||
|
|
||||||
|
service_menu.window_message.bg_color 141E32F0 # Color de fondo de ventanas de mensaje (RGBA hexadecimal)
|
||||||
|
service_menu.window_message.border_color 6496C8FF # Color del borde de ventanas de mensaje (RGBA hexadecimal)
|
||||||
|
service_menu.window_message.title_color 6496C8FF # Color del título en ventanas de mensaje (RGBA hexadecimal)
|
||||||
|
service_menu.window_message.text_color DCDCDCFF # Color del texto en ventanas de mensaje (RGBA hexadecimal)
|
||||||
|
service_menu.window_message.padding 15.0f # Espaciado interno de ventanas de mensaje (píxeles)
|
||||||
|
service_menu.window_message.line_spacing 5.0f # Espaciado entre líneas de texto (píxeles)
|
||||||
|
service_menu.window_message.title_separator_spacing 20.0f # Espaciado entre título y contenido (píxeles)
|
||||||
|
service_menu.window_message.min_width 200.0f # Ancho mínimo de ventanas de mensaje (píxeles)
|
||||||
|
service_menu.window_message.min_height 32.0f # Alto mínimo de ventanas de mensaje (píxeles)
|
||||||
|
service_menu.window_message.max_width_ratio 0.8f # Ratio máximo de ancho respecto a pantalla (0.0-1.0)
|
||||||
|
service_menu.window_message.max_height_ratio 0.8f # Ratio máximo de alto respecto a pantalla (0.0-1.0)
|
||||||
|
service_menu.window_message.text_safety_margin 15.0f # Margen de seguridad para el texto (píxeles)
|
||||||
|
service_menu.window_message.animation_duration 0.3f # Duración de animaciones de ventanas (segundos)
|
||||||
|
|
||||||
|
# --- INTRO ---
|
||||||
|
intro.bg_color 4664BD # Color de fondo de la intro
|
||||||
|
intro.card_color CBDBFC # Color de las tarjetas en la intro
|
||||||
|
intro.shadow_color 00000080 # Color de la sombra de las tarjetas en la intro
|
||||||
|
intro.text_distance_from_bottom 48 # Posicion del texto
|
||||||
|
|
||||||
|
# --- DEBUG ---
|
||||||
|
debug.color 00FFFF # Color para elementos de depuración
|
||||||
|
|
||||||
|
# --- RESOURCE ---
|
||||||
|
resource.color FFFFFF # Color de recurso 1
|
||||||
|
resource.color FFFFFF # Color de recurso 2
|
||||||
|
|
||||||
|
# --- TABE ---
|
||||||
|
tabe.min_spawn_time 2.0f # Tiempo mínimo en minutos para que aparezca el Tabe
|
||||||
|
tabe.max_spawn_time 3.0f # Tiempo máximo en minutos para que aparezca el Tabe
|
||||||
|
|
||||||
|
# --- PLAYER ---
|
||||||
|
# Jugador 1 - Camiseta por defecto
|
||||||
|
player.default_shirt[0].darkest 028ECFFF # Tono más oscuro - bordes y contornos (Jugador 1, por defecto)
|
||||||
|
player.default_shirt[0].dark 0297DBFF # Tono oscuro - sombras (Jugador 1, por defecto)
|
||||||
|
player.default_shirt[0].base 029FE8FF # Tono principal - color base (Jugador 1, por defecto)
|
||||||
|
player.default_shirt[0].light 03A9F4FF # Tono claro - zonas iluminadas (Jugador 1, por defecto)
|
||||||
|
|
||||||
|
# Jugador 2 - Camiseta por defecto
|
||||||
|
player.default_shirt[1].darkest 8E8E8EFF # Tono más oscuro - bordes y contornos (Jugador 2, por defecto)
|
||||||
|
player.default_shirt[1].dark AEADADFF # Tono oscuro - sombras (Jugador 2, por defecto)
|
||||||
|
player.default_shirt[1].base E4E4E4FF # Tono principal - color base (Jugador 2, por defecto)
|
||||||
|
player.default_shirt[1].light F7F1F1FF # Tono claro - zonas iluminadas (Jugador 2, por defecto)
|
||||||
|
|
||||||
|
# Jugador 1 - Camiseta con 1 café
|
||||||
|
player.one_coffee_shirt[0].darkest 3D9C70FF # Tono más oscuro - bordes y contornos (Jugador 1, 1 café)
|
||||||
|
player.one_coffee_shirt[0].dark 4FA370FF # Tono oscuro - sombras (Jugador 1, 1 café)
|
||||||
|
player.one_coffee_shirt[0].base 5DDE70FF # Tono principal - color base (Jugador 1, 1 café)
|
||||||
|
player.one_coffee_shirt[0].light 7DF25CFF # Tono claro - zonas iluminadas (Jugador 1, 1 café)
|
||||||
|
|
||||||
|
# Jugador 1 - Camiseta con 2 cafés
|
||||||
|
player.two_coffee_shirt[0].darkest D6A41AFF # Tono más oscuro - bordes y contornos (Jugador 1, 2 cafés)
|
||||||
|
player.two_coffee_shirt[0].dark E3AE1BFF # Tono oscuro - sombras (Jugador 1, 2 cafés)
|
||||||
|
player.two_coffee_shirt[0].base EFB71DFF # Tono principal - color base (Jugador 1, 2 cafés)
|
||||||
|
player.two_coffee_shirt[0].light FCC11EFF # Tono claro - zonas iluminadas (Jugador 1, 2 cafés)
|
||||||
|
|
||||||
|
# Jugador 2 - Camiseta con 1 café
|
||||||
|
player.one_coffee_shirt[1].darkest 2E8B57FF # Tono más oscuro - bordes y contornos (Jugador 2, 1 café)
|
||||||
|
player.one_coffee_shirt[1].dark 3CB371FF # Tono oscuro - sombras (Jugador 2, 1 café)
|
||||||
|
player.one_coffee_shirt[1].base 48D181FF # Tono principal - color base (Jugador 2, 1 café)
|
||||||
|
player.one_coffee_shirt[1].light 55EF8DFF # Tono claro - zonas iluminadas (Jugador 2, 1 café)
|
||||||
|
|
||||||
|
# Jugador 2 - Camiseta con 2 cafés
|
||||||
|
player.two_coffee_shirt[1].darkest E08500FF # Tono más oscuro - bordes y contornos (Jugador 2, 2 cafés)
|
||||||
|
player.two_coffee_shirt[1].dark FA7D00FF # Tono oscuro - sombras (Jugador 2, 2 cafés)
|
||||||
|
player.two_coffee_shirt[1].base FAA200FF # Tono principal - color base (Jugador 2, 2 cafés)
|
||||||
|
player.two_coffee_shirt[1].light FA8500FF # Tono claro - zonas iluminadas (Jugador 2, 2 cafés)
|
||||||
|
|
||||||
|
# Colores de contorno de los jugadores
|
||||||
|
player.outline_color[0] 66323FFF # Color del contorno del sprite del Jugador 1
|
||||||
|
player.outline_color[1] 422028FF # Color del contorno del sprite del Jugador 2
|
||||||
150
config/param_320x256.txt
Normal file
@@ -0,0 +1,150 @@
|
|||||||
|
# Coffee Crisis Arcade Edition - Fichero de parametros
|
||||||
|
# Formato: PARAMETRO VALOR
|
||||||
|
|
||||||
|
# --- GAME ---
|
||||||
|
game.item_size 20 # Tamaño de los items del juego (en píxeles)
|
||||||
|
game.item_text_outline_color E0E0E0F0 # Color del outline del texto de los items (RGBA hex)
|
||||||
|
game.width 320 # Ancho de la resolución nativa del juego (en píxeles)
|
||||||
|
game.height 256 # Alto de la resolución nativa del juego (en píxeles)
|
||||||
|
game.play_area.rect.x 0 # Posición X de la zona jugable
|
||||||
|
game.play_area.rect.y 0 # Posición Y de la zona jugable
|
||||||
|
game.play_area.rect.w 320 # Ancho de la zona jugable
|
||||||
|
game.play_area.rect.h 216 # Alto de la zona jugable
|
||||||
|
game.name_entry_idle_time 10 # Segundos para introducir el nombre al finalizar la partida si no se pulsa nada
|
||||||
|
game.name_entry_total_time 60 # Segundos totales para introducir el nombre al finalizar la partida
|
||||||
|
game.hit_stop false # Indica si debe haber un paro cuando el jugador es golpeado por un globo
|
||||||
|
game.hit_stop_ms 500 # Cantidad de milisegundos que dura el hit_stop
|
||||||
|
|
||||||
|
# --- FADE ---
|
||||||
|
fade.color 1F2B30 # Color hexadecimal para el efecto de fundido
|
||||||
|
fade.num_squares_width 64 # Número de cuadrados en el eje X para el fundido
|
||||||
|
fade.num_squares_height 48 # Número de cuadrados en el eje Y para el fundido
|
||||||
|
fade.random_squares_duration_ms 1200 # Duración del fade en milisegundos
|
||||||
|
fade.post_duration_ms 500 # Duración tras el fundido en milisegundos
|
||||||
|
fade.venetian_size 12 # Tamaño de las bandas para el efecto veneciano (en píxeles)
|
||||||
|
|
||||||
|
# --- SCOREBOARD ---
|
||||||
|
scoreboard.rect.x 0 # Posición X del marcador
|
||||||
|
scoreboard.rect.y 216 # Posición Y del marcador
|
||||||
|
scoreboard.rect.w 320 # Ancho del marcador
|
||||||
|
scoreboard.rect.h 40 # Alto del marcador
|
||||||
|
scoreboard.separator_autocolor true # ¿El separador usa color automático?
|
||||||
|
scoreboard.separator_color 0D1A2B # Color del separador (hexadecimal)
|
||||||
|
scoreboard.easy_color 4B692F # Color para la dificultad fácil
|
||||||
|
scoreboard.normal_color 2E3F47 # Color para la dificultad normal
|
||||||
|
scoreboard.hard_color 76428A # Color para la dificultad difícil
|
||||||
|
scoreboard.text_autocolor true # ¿El texto usa color automático?
|
||||||
|
scoreboard.text_color1 FFFFFF # Color principal del texto del marcador
|
||||||
|
scoreboard.text_color2 FFFFFF # Color secundario del texto del marcador
|
||||||
|
scoreboard.skip_countdown_value 8 # Valor para saltar la cuenta atrás (segundos)
|
||||||
|
|
||||||
|
# --- TITLE ---
|
||||||
|
title.press_start_position 180 # Posición Y del texto "Press Start"
|
||||||
|
title.title_duration 14 # Duración de la pantalla de título (segundos)
|
||||||
|
title.arcade_edition_position 123 # Posición Y del subtítulo "Arcade Edition"
|
||||||
|
title.title_c_c_position 80 # Posición Y del título principal
|
||||||
|
title.bg_color 41526F # Color de fondo en la sección titulo
|
||||||
|
|
||||||
|
# --- BACKGROUND ---
|
||||||
|
background.attenuate_color FFFFFF00 # Color de atenuación del fondo (RGBA hexadecimal)
|
||||||
|
|
||||||
|
# --- BALLOONS --- (deltaTime en segundos: vel en pixels/s, grav en pixels/s²)
|
||||||
|
balloon.settings[0].vel 165.0f # Velocidad inicial del globo 1 (pixels/s)
|
||||||
|
balloon.settings[0].grav 320.0f # Gravedad aplicada al globo 1 (pixels/s²)
|
||||||
|
balloon.settings[1].vel 222.0f # Velocidad inicial del globo 2 (pixels/s)
|
||||||
|
balloon.settings[1].grav 360.0f # Gravedad aplicada al globo 2 (pixels/s²)
|
||||||
|
balloon.settings[2].vel 282.0f # Velocidad inicial del globo 3 (pixels/s)
|
||||||
|
balloon.settings[2].grav 360.0f # Gravedad aplicada al globo 3 (pixels/s²)
|
||||||
|
balloon.settings[3].vel 327.0f # Velocidad inicial del globo 4 (pixels/s)
|
||||||
|
balloon.settings[3].grav 360.0f # Gravedad aplicada al globo 4 (pixels/s²)
|
||||||
|
|
||||||
|
balloon.color[0] blue # Color de creación del globo normal
|
||||||
|
balloon.color[1] orange # Color del globo normal
|
||||||
|
balloon.color[2] red # Color de creación del globo que rebota
|
||||||
|
balloon.color[3] green # Color del globo que rebota
|
||||||
|
|
||||||
|
balloon.bouncing_sound false # Indica si los globos hacer sonido al rebotar
|
||||||
|
|
||||||
|
# --- NOTIFICATION ---
|
||||||
|
notification.pos_v TOP # Posición vertical de la notificación (TOP/BOTTOM)
|
||||||
|
notification.pos_h LEFT # Posición horizontal de la notificación (LEFT/RIGHT)
|
||||||
|
notification.sound false # ¿La notificación reproduce sonido?
|
||||||
|
notification.color 303030 # Color de fondo de la notificación (hexadecimal)
|
||||||
|
|
||||||
|
# --- SERVICE MENU ---
|
||||||
|
service_menu.title_color 99FF62 # Color del título del menú de servicio
|
||||||
|
service_menu.text_color FFFFFF # Color del texto del menú de servicio
|
||||||
|
service_menu.selected_color FFDC44 # Color de la opción seleccionada en el menú de servicio
|
||||||
|
service_menu.bg_color 000F00F5 # Color de fondo del menú de servicio (RGBA hexadecimal)
|
||||||
|
service_menu.drop_shadow false # ¿El menú de servicio tiene sombra?
|
||||||
|
|
||||||
|
service_menu.window_message.bg_color 141E32F0 # Color de fondo de ventanas de mensaje (RGBA hexadecimal)
|
||||||
|
service_menu.window_message.border_color 6496C8FF # Color del borde de ventanas de mensaje (RGBA hexadecimal)
|
||||||
|
service_menu.window_message.title_color 6496C8FF # Color del título en ventanas de mensaje (RGBA hexadecimal)
|
||||||
|
service_menu.window_message.text_color DCDCDCFF # Color del texto en ventanas de mensaje (RGBA hexadecimal)
|
||||||
|
service_menu.window_message.padding 15.0f # Espaciado interno de ventanas de mensaje (píxeles)
|
||||||
|
service_menu.window_message.line_spacing 5.0f # Espaciado entre líneas de texto (píxeles)
|
||||||
|
service_menu.window_message.title_separator_spacing 20.0f # Espaciado entre título y contenido (píxeles)
|
||||||
|
service_menu.window_message.min_width 200.0f # Ancho mínimo de ventanas de mensaje (píxeles)
|
||||||
|
service_menu.window_message.min_height 32.0f # Alto mínimo de ventanas de mensaje (píxeles)
|
||||||
|
service_menu.window_message.max_width_ratio 0.8f # Ratio máximo de ancho respecto a pantalla (0.0-1.0)
|
||||||
|
service_menu.window_message.max_height_ratio 0.8f # Ratio máximo de alto respecto a pantalla (0.0-1.0)
|
||||||
|
service_menu.window_message.text_safety_margin 15.0f # Margen de seguridad para el texto (píxeles)
|
||||||
|
service_menu.window_message.animation_duration 0.3f # Duración de animaciones de ventanas (segundos)
|
||||||
|
|
||||||
|
# --- INTRO ---
|
||||||
|
intro.bg_color 4664BD # Color de fondo de la intro
|
||||||
|
intro.card_color CBDBFC # Color de las tarjetas en la intro
|
||||||
|
intro.shadow_color 00000080 # Color de la sombra de las tarjetas en la intro
|
||||||
|
intro.text_distance_from_bottom 48 # Posición del texto desde la parte inferior
|
||||||
|
|
||||||
|
# --- DEBUG ---
|
||||||
|
debug.color 00FFFF # Color para elementos de depuración
|
||||||
|
|
||||||
|
# --- RESOURCE ---
|
||||||
|
resource.color FFFFFF # Color de recursos
|
||||||
|
|
||||||
|
# --- TABE ---
|
||||||
|
tabe.min_spawn_time 2.0f # Tiempo mínimo en segundos para que aparezca el Tabe
|
||||||
|
tabe.max_spawn_time 3.0f # Tiempo máximo en segundos para que aparezca el Tabe
|
||||||
|
|
||||||
|
# --- PLAYER ---
|
||||||
|
# Jugador 1 - Camiseta por defecto
|
||||||
|
player.default_shirt[0].darkest 028ECFFF # Tono más oscuro - bordes y contornos (Jugador 1, por defecto)
|
||||||
|
player.default_shirt[0].dark 0297DBFF # Tono oscuro - sombras (Jugador 1, por defecto)
|
||||||
|
player.default_shirt[0].base 029FE8FF # Tono principal - color base (Jugador 1, por defecto)
|
||||||
|
player.default_shirt[0].light 03A9F4FF # Tono claro - zonas iluminadas (Jugador 1, por defecto)
|
||||||
|
|
||||||
|
# Jugador 2 - Camiseta por defecto
|
||||||
|
player.default_shirt[1].darkest 8E8E8EFF # Tono más oscuro - bordes y contornos (Jugador 2, por defecto)
|
||||||
|
player.default_shirt[1].dark AEADADFF # Tono oscuro - sombras (Jugador 2, por defecto)
|
||||||
|
player.default_shirt[1].base E4E4E4FF # Tono principal - color base (Jugador 2, por defecto)
|
||||||
|
player.default_shirt[1].light F7F1F1FF # Tono claro - zonas iluminadas (Jugador 2, por defecto)
|
||||||
|
|
||||||
|
# Jugador 1 - Camiseta con 1 café
|
||||||
|
player.one_coffee_shirt[0].darkest 3D9C70FF # Tono más oscuro - bordes y contornos (Jugador 1, 1 café)
|
||||||
|
player.one_coffee_shirt[0].dark 4FA370FF # Tono oscuro - sombras (Jugador 1, 1 café)
|
||||||
|
player.one_coffee_shirt[0].base 5DDE70FF # Tono principal - color base (Jugador 1, 1 café)
|
||||||
|
player.one_coffee_shirt[0].light 7DF25CFF # Tono claro - zonas iluminadas (Jugador 1, 1 café)
|
||||||
|
|
||||||
|
# Jugador 1 - Camiseta con 2 cafés
|
||||||
|
player.two_coffee_shirt[0].darkest D6A41AFF # Tono más oscuro - bordes y contornos (Jugador 1, 2 cafés)
|
||||||
|
player.two_coffee_shirt[0].dark E3AE1BFF # Tono oscuro - sombras (Jugador 1, 2 cafés)
|
||||||
|
player.two_coffee_shirt[0].base EFB71DFF # Tono principal - color base (Jugador 1, 2 cafés)
|
||||||
|
player.two_coffee_shirt[0].light FCC11EFF # Tono claro - zonas iluminadas (Jugador 1, 2 cafés)
|
||||||
|
|
||||||
|
# Jugador 2 - Camiseta con 1 café
|
||||||
|
player.one_coffee_shirt[1].darkest 2E8B57FF # Tono más oscuro - bordes y contornos (Jugador 2, 1 café)
|
||||||
|
player.one_coffee_shirt[1].dark 3CB371FF # Tono oscuro - sombras (Jugador 2, 1 café)
|
||||||
|
player.one_coffee_shirt[1].base 48D181FF # Tono principal - color base (Jugador 2, 1 café)
|
||||||
|
player.one_coffee_shirt[1].light 55EF8DFF # Tono claro - zonas iluminadas (Jugador 2, 1 café)
|
||||||
|
|
||||||
|
# Jugador 2 - Camiseta con 2 cafés
|
||||||
|
player.two_coffee_shirt[1].darkest E08500FF # Tono más oscuro - bordes y contornos (Jugador 2, 2 cafés)
|
||||||
|
player.two_coffee_shirt[1].dark FA7D00FF # Tono oscuro - sombras (Jugador 2, 2 cafés)
|
||||||
|
player.two_coffee_shirt[1].base FAA200FF # Tono principal - color base (Jugador 2, 2 cafés)
|
||||||
|
player.two_coffee_shirt[1].light FA8500FF # Tono claro - zonas iluminadas (Jugador 2, 2 cafés)
|
||||||
|
|
||||||
|
# Colores de contorno de los jugadores
|
||||||
|
player.outline_color[0] 66323FFF # Color del contorno del sprite del Jugador 1
|
||||||
|
player.outline_color[1] 422028FF # Color del contorno del sprite del Jugador 2
|
||||||
150
config/param_red.txt
Normal file
@@ -0,0 +1,150 @@
|
|||||||
|
# Coffee Crisis Arcade Edition - Fichero de parametros - RED THEME
|
||||||
|
# Formato: PARAMETRO VALOR
|
||||||
|
|
||||||
|
# --- GAME ---
|
||||||
|
game.item_size 20 # Tamaño de los items del juego (en píxeles)
|
||||||
|
game.item_text_outline_color FFB8B8F0 # Color del outline del texto de los items (RGBA hex) - Rojo claro
|
||||||
|
game.width 320 # Ancho de la resolución nativa del juego (en píxeles)
|
||||||
|
game.height 256 # Alto de la resolución nativa del juego (en píxeles)
|
||||||
|
game.play_area.rect.x 0 # Posición X de la zona jugable
|
||||||
|
game.play_area.rect.y 0 # Posición Y de la zona jugable
|
||||||
|
game.play_area.rect.w 320 # Ancho de la zona jugable
|
||||||
|
game.play_area.rect.h 216 # Alto de la zona jugable
|
||||||
|
game.name_entry_idle_time 10 # Segundos para introducir el nombre al finalizar la partida si no se pulsa nada
|
||||||
|
game.name_entry_total_time 60 # Segundos totales para introducir el nombre al finalizar la partida
|
||||||
|
game.hit_stop false # Indica si debe haber un paro cuando el jugador es golpeado por un globo
|
||||||
|
game.hit_stop_ms 500 # Cantidad de milisegundos que dura el hit_stop
|
||||||
|
|
||||||
|
# --- FADE ---
|
||||||
|
fade.color 5C1F1F # Color hexadecimal para el efecto de fundido - Rojo oscuro
|
||||||
|
fade.num_squares_width 64 # Número de cuadrados en el eje X para el fundido
|
||||||
|
fade.num_squares_height 48 # Número de cuadrados en el eje Y para el fundido
|
||||||
|
fade.random_squares_duration_ms 1200 # Duración del fade en milisegundos
|
||||||
|
fade.post_duration_ms 500 # Duración tras el fundido en milisegundos
|
||||||
|
fade.venetian_size 12 # Tamaño de las bandas para el efecto veneciano (en píxeles)
|
||||||
|
|
||||||
|
# --- SCOREBOARD ---
|
||||||
|
scoreboard.rect.x 0 # Posición X del marcador
|
||||||
|
scoreboard.rect.y 216 # Posición Y del marcador
|
||||||
|
scoreboard.rect.w 320 # Ancho del marcador
|
||||||
|
scoreboard.rect.h 40 # Alto del marcador
|
||||||
|
scoreboard.separator_autocolor true # ¿El separador usa color automático?
|
||||||
|
scoreboard.separator_color 2B0D0D # Color del separador - Rojo muy oscuro
|
||||||
|
scoreboard.easy_color 8B4A2F # Color para la dificultad fácil - Marrón rojizo
|
||||||
|
scoreboard.normal_color 6B2F2F # Color para la dificultad normal - Rojo medio
|
||||||
|
scoreboard.hard_color A73030 # Color para la dificultad difícil - Rojo fuerte
|
||||||
|
scoreboard.text_autocolor true # ¿El texto usa color automático?
|
||||||
|
scoreboard.text_color1 FFE6E6 # Color principal del texto del marcador - Blanco rosado
|
||||||
|
scoreboard.text_color2 FFE6E6 # Color secundario del texto del marcador - Blanco rosado
|
||||||
|
scoreboard.skip_countdown_value 8 # Valor para saltar la cuenta atrás (segundos)
|
||||||
|
|
||||||
|
# --- TITLE ---
|
||||||
|
title.press_start_position 180 # Posición Y del texto "Press Start"
|
||||||
|
title.title_duration 800 # Duración de la pantalla de título (frames)
|
||||||
|
title.arcade_edition_position 123 # Posición Y del subtítulo "Arcade Edition"
|
||||||
|
title.title_c_c_position 80 # Posición Y del título principal
|
||||||
|
title.bg_color 8B4A3A # Color de fondo en la sección titulo - Marrón rojizo
|
||||||
|
|
||||||
|
# --- BACKGROUND ---
|
||||||
|
background.attenuate_color FF4A3A40 # Color de atenuación del fondo (RGBA hexadecimal) - Blanco rosado
|
||||||
|
|
||||||
|
# --- BALLOONS ---
|
||||||
|
balloon.settings[0].vel 2.75f # Velocidad inicial del globo 1
|
||||||
|
balloon.settings[0].grav 0.09f # Gravedad aplicada al globo 1
|
||||||
|
balloon.settings[1].vel 3.70f # Velocidad inicial del globo 2
|
||||||
|
balloon.settings[1].grav 0.10f # Gravedad aplicada al globo 2
|
||||||
|
balloon.settings[2].vel 4.70f # Velocidad inicial del globo 3
|
||||||
|
balloon.settings[2].grav 0.10f # Gravedad aplicada al globo 3
|
||||||
|
balloon.settings[3].vel 5.45f # Velocidad inicial del globo 4
|
||||||
|
balloon.settings[3].grav 0.10f # Gravedad aplicada al globo 4
|
||||||
|
|
||||||
|
balloon.color[0] orange # Color de creación del globo normal
|
||||||
|
balloon.color[1] red # Color del globo normal
|
||||||
|
balloon.color[2] blue # Color de creación del globo que rebota
|
||||||
|
balloon.color[3] green # Color del globo que rebota
|
||||||
|
|
||||||
|
balloon.bouncing_sound false # Indica si los globos hacer sonido al rebotar
|
||||||
|
|
||||||
|
# --- NOTIFICATION ---
|
||||||
|
notification.pos_v TOP # Posición vertical de la notificación (TOP/BOTTOM)
|
||||||
|
notification.pos_h LEFT # Posición horizontal de la notificación (LEFT/RIGHT)
|
||||||
|
notification.sound false # ¿La notificación reproduce sonido?
|
||||||
|
notification.color 4D1A1A # Color de fondo de la notificación - Rojo oscuro
|
||||||
|
|
||||||
|
# --- SERVICE MENU ---
|
||||||
|
service_menu.title_color FF9966 # Color del título del menú de servicio - Naranja claro
|
||||||
|
service_menu.text_color FFE6E6 # Color del texto del menú de servicio - Blanco rosado
|
||||||
|
service_menu.selected_color FFB366 # Color de la opción seleccionada - Naranja dorado
|
||||||
|
service_menu.bg_color 331A0AF5 # Color de fondo del menú de servicio - Marrón rojizo oscuro con alpha
|
||||||
|
service_menu.drop_shadow false # ¿El menú de servicio tiene sombra?
|
||||||
|
|
||||||
|
service_menu.window_message.bg_color 4D1A1AF0 # Color de fondo de ventanas - Rojo oscuro con alpha
|
||||||
|
service_menu.window_message.border_color CC6633FF # Color del borde de ventanas - Naranja rojizo
|
||||||
|
service_menu.window_message.title_color CC6633FF # Color del título en ventanas - Naranja rojizo
|
||||||
|
service_menu.window_message.text_color FFE6E6FF # Color del texto en ventanas - Blanco rosado
|
||||||
|
service_menu.window_message.padding 15.0f # Espaciado interno de ventanas de mensaje (píxeles)
|
||||||
|
service_menu.window_message.line_spacing 5.0f # Espaciado entre líneas de texto (píxeles)
|
||||||
|
service_menu.window_message.title_separator_spacing 20.0f # Espaciado entre título y contenido (píxeles)
|
||||||
|
service_menu.window_message.min_width 200.0f # Ancho mínimo de ventanas de mensaje (píxeles)
|
||||||
|
service_menu.window_message.min_height 32.0f # Alto mínimo de ventanas de mensaje (píxeles)
|
||||||
|
service_menu.window_message.max_width_ratio 0.8f # Ratio máximo de ancho respecto a pantalla (0.0-1.0)
|
||||||
|
service_menu.window_message.max_height_ratio 0.8f # Ratio máximo de alto respecto a pantalla (0.0-1.0)
|
||||||
|
service_menu.window_message.text_safety_margin 15.0f # Margen de seguridad para el texto (píxeles)
|
||||||
|
service_menu.window_message.animation_duration 0.3f # Duración de animaciones de ventanas (segundos)
|
||||||
|
|
||||||
|
# --- INTRO ---
|
||||||
|
intro.bg_color B8664D # Color de fondo de la intro - Naranja tierra
|
||||||
|
intro.card_color FFE6CC # Color de las tarjetas en la intro - Crema rojizo
|
||||||
|
intro.shadow_color 66000080 # Color de la sombra de las tarjetas - Rojo muy oscuro con alpha
|
||||||
|
intro.text_distance_from_bottom 48 # Posición del texto desde la parte inferior
|
||||||
|
|
||||||
|
# --- DEBUG ---
|
||||||
|
debug.color FF6666 # Color para elementos de depuración - Rojo claro
|
||||||
|
|
||||||
|
# --- RESOURCE ---
|
||||||
|
resource.color FFE6E6 # Color de recursos - Blanco rosado
|
||||||
|
|
||||||
|
# --- TABE ---
|
||||||
|
tabe.min_spawn_time 2.0f # Tiempo mínimo en segundos para que aparezca el Tabe
|
||||||
|
tabe.max_spawn_time 3.0f # Tiempo máximo en segundos para que aparezca el Tabe
|
||||||
|
|
||||||
|
# --- PLAYER ---
|
||||||
|
# Jugador 1 - Camiseta por defecto (tonos rojos)
|
||||||
|
player.default_shirt[0].darkest B33030FF # Tono más oscuro - Rojo fuerte
|
||||||
|
player.default_shirt[0].dark CC4040FF # Tono oscuro - Rojo medio
|
||||||
|
player.default_shirt[0].base E65050FF # Tono principal - Rojo claro
|
||||||
|
player.default_shirt[0].light FF6666FF # Tono claro - Rojo muy claro
|
||||||
|
|
||||||
|
# Jugador 2 - Camiseta por defecto (tonos naranjas)
|
||||||
|
player.default_shirt[1].darkest B36030FF # Tono más oscuro - Naranja oscuro
|
||||||
|
player.default_shirt[1].dark CC7540FF # Tono oscuro - Naranja medio
|
||||||
|
player.default_shirt[1].base E68A50FF # Tono principal - Naranja claro
|
||||||
|
player.default_shirt[1].light FF9966FF # Tono claro - Naranja muy claro
|
||||||
|
|
||||||
|
# Jugador 1 - Camiseta con 1 café (tonos rojizos más intensos)
|
||||||
|
player.one_coffee_shirt[0].darkest 8B2635FF # Tono más oscuro - Rojo granate
|
||||||
|
player.one_coffee_shirt[0].dark A53040FF # Tono oscuro - Rojo granate claro
|
||||||
|
player.one_coffee_shirt[0].base BF3A50FF # Tono principal - Rojo vibrante
|
||||||
|
player.one_coffee_shirt[0].light D94460FF # Tono claro - Rojo vibrante claro
|
||||||
|
|
||||||
|
# Jugador 1 - Camiseta con 2 cafés (tonos naranja dorado)
|
||||||
|
player.two_coffee_shirt[0].darkest CC6600FF # Tono más oscuro - Naranja dorado oscuro
|
||||||
|
player.two_coffee_shirt[0].dark E6750AFF # Tono oscuro - Naranja dorado
|
||||||
|
player.two_coffee_shirt[0].base FF8514FF # Tono principal - Naranja dorado claro
|
||||||
|
player.two_coffee_shirt[0].light FF991EFF # Tono claro - Naranja dorado muy claro
|
||||||
|
|
||||||
|
# Jugador 2 - Camiseta con 1 café (tonos terracotas)
|
||||||
|
player.one_coffee_shirt[1].darkest A0472DFF # Tono más oscuro - Terracota oscuro
|
||||||
|
player.one_coffee_shirt[1].dark B8553AFF # Tono oscuro - Terracota medio
|
||||||
|
player.one_coffee_shirt[1].base D06347FF # Tono principal - Terracota claro
|
||||||
|
player.one_coffee_shirt[1].light E87154FF # Tono claro - Terracota muy claro
|
||||||
|
|
||||||
|
# Jugador 2 - Camiseta con 2 cafés (tonos naranjas cálidos)
|
||||||
|
player.two_coffee_shirt[1].darkest CC5500FF # Tono más oscuro - Naranja intenso
|
||||||
|
player.two_coffee_shirt[1].dark E66600FF # Tono oscuro - Naranja fuerte
|
||||||
|
player.two_coffee_shirt[1].base FF7700FF # Tono principal - Naranja brillante
|
||||||
|
player.two_coffee_shirt[1].light FF8800FF # Tono claro - Naranja muy brillante
|
||||||
|
|
||||||
|
# Colores de contorno de los jugadores
|
||||||
|
player.outline_color[0] 994D33FF # Color del contorno del Jugador 1 - Marrón rojizo
|
||||||
|
player.outline_color[1] 664433FF # Color del contorno del Jugador 2 - Marrón tierra
|
||||||
34
config/pools.txt
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
# Coffee Crisis Arcade Edition - Archivo de configuración de pools de formaciones de globos
|
||||||
|
# Formato: POOL: <id> FORMATIONS: <id1>, <id2>, <id3>, ...
|
||||||
|
# Los IDs de formación pueden repetirse
|
||||||
|
# Los pools no necesitan estar ordenados ni ser consecutivos
|
||||||
|
|
||||||
|
# Pool para la fase 1
|
||||||
|
POOL: 0 FORMATIONS: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
|
||||||
|
|
||||||
|
# Pool para la fase 2
|
||||||
|
POOL: 1 FORMATIONS: 10, 11, 12, 13, 14, 15, 16, 17, 18, 19
|
||||||
|
|
||||||
|
# Pool para la fase 3
|
||||||
|
POOL: 2 FORMATIONS: 0, 1, 2, 3, 4, 55, 56, 57, 58, 59
|
||||||
|
|
||||||
|
# Pool para la fase 4
|
||||||
|
POOL: 3 FORMATIONS: 50, 51, 52, 53, 54, 5, 6, 7, 8, 9
|
||||||
|
|
||||||
|
# Pool para la fase 5
|
||||||
|
POOL: 4 FORMATIONS: 60, 61, 62, 63, 64, 65, 66, 67, 68, 69
|
||||||
|
|
||||||
|
# Pool para la fase 6
|
||||||
|
POOL: 5 FORMATIONS: 10, 61, 12, 63, 14, 65, 16, 67, 18, 69
|
||||||
|
|
||||||
|
# Pool para la fase 7
|
||||||
|
POOL: 6 FORMATIONS: 60, 11, 62, 13, 64, 15, 66, 17, 68, 19
|
||||||
|
|
||||||
|
# Pool para la fase 8
|
||||||
|
POOL: 7 FORMATIONS: 20, 21, 22, 23, 24, 65, 66, 67, 68, 69
|
||||||
|
|
||||||
|
# Pool para la fase 9
|
||||||
|
POOL: 8 FORMATIONS: 70, 71, 72, 73, 74, 15, 16, 17, 18, 19
|
||||||
|
|
||||||
|
# Pool para la fase 10
|
||||||
|
POOL: 9 FORMATIONS: 20, 21, 22, 23, 24, 70, 71, 72, 73, 74
|
||||||
19
config/stages.txt
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
# Coffee Crisis Arcade Edition - Archivo de configuración de fases
|
||||||
|
# Formato: power_to_complete,min_menace,max_menace,name
|
||||||
|
# Líneas que empiezan con # son comentarios y se ignoran
|
||||||
|
|
||||||
|
# Fases iniciales - Tutorial y aprendizaje
|
||||||
|
200, 11, 19, Tutorial
|
||||||
|
300, 15, 23, Primeros pasos
|
||||||
|
|
||||||
|
# Fases intermedias - Incremento de dificultad
|
||||||
|
400, 19, 27, Intensificación
|
||||||
|
400, 19, 27, Persistencia
|
||||||
|
400, 23, 31, Desafío medio
|
||||||
|
400, 23, 31, Resistencia
|
||||||
|
|
||||||
|
# Fases avanzadas - Desafío final
|
||||||
|
600, 27, 35, Aproximación final
|
||||||
|
600, 27, 35, Penúltimo obstáculo
|
||||||
|
700, 31, 39, Clímax
|
||||||
|
950, 35, 47, Maestría
|
||||||
|
Before Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 12 KiB |
@@ -1,277 +0,0 @@
|
|||||||
# Archivo de configuración de formaciones de globos
|
|
||||||
# Formato por línea: x, desp, y, vel_x, tipo, tamaño, retraso_tiempo_creacion
|
|
||||||
# Variables disponibles:
|
|
||||||
# X0_0, X0_50, X0_100, X1_0, X1_100, X2_0, X2_100, X3_0, X3_100
|
|
||||||
# X3_25, X3_75, DEFAULT_POS_Y
|
|
||||||
# SMALL, MEDIUM, LARGE, EXTRALARGE
|
|
||||||
# RIGHT, LEFT
|
|
||||||
|
|
||||||
formation: 0
|
|
||||||
# Dos enemigos BALLOON3 uno a cada extremo
|
|
||||||
X3_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, EXTRALARGE, 0
|
|
||||||
X3_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, EXTRALARGE, 0
|
|
||||||
|
|
||||||
formation: 1
|
|
||||||
# Dos enemigos BALLOON3 uno a cada cuarto. Ambos van hacia el centro
|
|
||||||
X3_25, 0, DEFAULT_POS_Y, RIGHT, BALLOON, EXTRALARGE, 0
|
|
||||||
X3_75, 0, DEFAULT_POS_Y, LEFT, BALLOON, EXTRALARGE, 0
|
|
||||||
|
|
||||||
formation: 2
|
|
||||||
# Cuatro enemigos BALLOON1 uno detrás del otro. A la izquierda y hacia el centro
|
|
||||||
X1_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 30
|
|
||||||
X1_0, 1, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 20
|
|
||||||
X1_0, 2, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 10
|
|
||||||
X1_0, 3, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 0
|
|
||||||
|
|
||||||
formation: 3
|
|
||||||
# Cuatro enemigos BALLOON1 uno detrás del otro. A la derecha y hacia el centro
|
|
||||||
X1_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 30
|
|
||||||
X1_100, -1, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 20
|
|
||||||
X1_100, -2, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 10
|
|
||||||
X1_100, -3, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 0
|
|
||||||
|
|
||||||
formation: 4
|
|
||||||
# Tres enemigos BALLOON2. 0, 25, 50. Hacia la derecha
|
|
||||||
X2_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 20
|
|
||||||
X2_0, 2, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 10
|
|
||||||
X2_0, 4, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0
|
|
||||||
|
|
||||||
formation: 5
|
|
||||||
# Tres enemigos BALLOON2. 50, 75, 100. Hacia la izquierda
|
|
||||||
X2_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 20
|
|
||||||
X2_100, -2, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 10
|
|
||||||
X2_100, -4, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0
|
|
||||||
|
|
||||||
formation: 6
|
|
||||||
# Tres enemigos BALLOON2. 0, 0, 0. Hacia la derecha
|
|
||||||
X2_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 20
|
|
||||||
X2_0, 1, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 10
|
|
||||||
X2_0, 2, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0
|
|
||||||
|
|
||||||
formation: 7
|
|
||||||
# Tres enemigos BALLOON2. 100, 100, 100. Hacia la izquierda
|
|
||||||
X2_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 20
|
|
||||||
X2_100, -1, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 10
|
|
||||||
X2_100, -2, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0
|
|
||||||
|
|
||||||
formation: 8
|
|
||||||
# Seis enemigos BALLOON0. 0, 0, 0, 0, 0, 0. Hacia la derecha
|
|
||||||
X0_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 50
|
|
||||||
X0_0, 1, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 40
|
|
||||||
X0_0, 2, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 30
|
|
||||||
X0_0, 3, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 20
|
|
||||||
X0_0, 4, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 10
|
|
||||||
X0_0, 5, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0
|
|
||||||
|
|
||||||
formation: 9
|
|
||||||
# Seis enemigos BALLOON0. 100, 100, 100, 100, 100, 100. Hacia la izquierda
|
|
||||||
X0_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 50
|
|
||||||
X0_100, -1, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 40
|
|
||||||
X0_100, -2, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 30
|
|
||||||
X0_100, -3, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 20
|
|
||||||
X0_100, -4, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 10
|
|
||||||
X0_100, -5, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0
|
|
||||||
|
|
||||||
formation: 10
|
|
||||||
# Tres enemigos BALLOON3 seguidos desde la izquierda. Hacia la derecha
|
|
||||||
X3_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, EXTRALARGE, 30
|
|
||||||
X3_0, 1, DEFAULT_POS_Y, RIGHT, BALLOON, EXTRALARGE, 15
|
|
||||||
X3_0, 2, DEFAULT_POS_Y, RIGHT, BALLOON, EXTRALARGE, 0
|
|
||||||
|
|
||||||
formation: 11
|
|
||||||
# Tres enemigos BALLOON3 seguidos desde la derecha. Hacia la izquierda
|
|
||||||
X3_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, EXTRALARGE, 30
|
|
||||||
X3_100, -1, DEFAULT_POS_Y, LEFT, BALLOON, EXTRALARGE, 15
|
|
||||||
X3_100, -2, DEFAULT_POS_Y, LEFT, BALLOON, EXTRALARGE, 0
|
|
||||||
|
|
||||||
formation: 12
|
|
||||||
# Seis enemigos BALLOON1 uno detrás del otro. A la izquierda y hacia el centro
|
|
||||||
X1_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 50
|
|
||||||
X1_0, 1, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 40
|
|
||||||
X1_0, 2, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 30
|
|
||||||
X1_0, 3, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 20
|
|
||||||
X1_0, 4, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 10
|
|
||||||
X1_0, 5, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 0
|
|
||||||
|
|
||||||
formation: 13
|
|
||||||
# Seis enemigos BALLOON1 uno detrás del otro. A la derecha y hacia el centro
|
|
||||||
X1_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 50
|
|
||||||
X1_100, -1, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 40
|
|
||||||
X1_100, -2, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 30
|
|
||||||
X1_100, -3, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 20
|
|
||||||
X1_100, -4, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 10
|
|
||||||
X1_100, -5, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 0
|
|
||||||
|
|
||||||
formation: 14
|
|
||||||
# Cinco enemigos BALLOON2. Hacia la derecha. Separados
|
|
||||||
X2_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 40
|
|
||||||
X2_0, 2, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 30
|
|
||||||
X2_0, 4, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 20
|
|
||||||
X2_0, 6, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 10
|
|
||||||
X2_0, 8, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0
|
|
||||||
|
|
||||||
formation: 15
|
|
||||||
# Cinco enemigos BALLOON2. Hacia la izquierda. Separados
|
|
||||||
X2_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 40
|
|
||||||
X2_100, -2, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 30
|
|
||||||
X2_100, -4, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 20
|
|
||||||
X2_100, -6, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 10
|
|
||||||
X2_100, -8, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0
|
|
||||||
|
|
||||||
formation: 16
|
|
||||||
# Cinco enemigos BALLOON2. Hacia la derecha. Juntos
|
|
||||||
X2_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 40
|
|
||||||
X2_0, 1, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 30
|
|
||||||
X2_0, 2, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 20
|
|
||||||
X2_0, 3, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 10
|
|
||||||
X2_0, 4, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0
|
|
||||||
|
|
||||||
formation: 17
|
|
||||||
# Cinco enemigos BALLOON2. Hacia la izquierda. Juntos
|
|
||||||
X2_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 40
|
|
||||||
X2_100, -1, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 30
|
|
||||||
X2_100, -2, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 20
|
|
||||||
X2_100, -3, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 10
|
|
||||||
X2_100, -4, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0
|
|
||||||
|
|
||||||
formation: 18
|
|
||||||
# Doce enemigos BALLOON0. Hacia la derecha. Juntos
|
|
||||||
X0_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 110
|
|
||||||
X0_0, 1, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 100
|
|
||||||
X0_0, 2, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 90
|
|
||||||
X0_0, 3, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 80
|
|
||||||
X0_0, 4, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 70
|
|
||||||
X0_0, 5, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 60
|
|
||||||
X0_0, 6, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 50
|
|
||||||
X0_0, 7, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 40
|
|
||||||
X0_0, 8, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 30
|
|
||||||
X0_0, 9, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 20
|
|
||||||
X0_0, 10, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 10
|
|
||||||
X0_0, 11, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0
|
|
||||||
|
|
||||||
formation: 19
|
|
||||||
# Doce enemigos BALLOON0. Hacia la izquierda. Juntos
|
|
||||||
X0_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 110
|
|
||||||
X0_100, -1, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 100
|
|
||||||
X0_100, -2, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 90
|
|
||||||
X0_100, -3, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 80
|
|
||||||
X0_100, -4, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 70
|
|
||||||
X0_100, -5, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 60
|
|
||||||
X0_100, -6, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 50
|
|
||||||
X0_100, -7, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 40
|
|
||||||
X0_100, -8, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 30
|
|
||||||
X0_100, -9, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 20
|
|
||||||
X0_100, -10, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 10
|
|
||||||
X0_100, -11, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0
|
|
||||||
|
|
||||||
formation: 20
|
|
||||||
# Cuatro enemigos BALLOON3 seguidos desde la izquierda/derecha. Simétricos
|
|
||||||
X3_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, EXTRALARGE, 0
|
|
||||||
X3_0, 1, DEFAULT_POS_Y, RIGHT, BALLOON, EXTRALARGE, 0
|
|
||||||
X3_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, EXTRALARGE, 0
|
|
||||||
X3_100, -1, DEFAULT_POS_Y, LEFT, BALLOON, EXTRALARGE, 0
|
|
||||||
|
|
||||||
formation: 21
|
|
||||||
# Diez enemigos BALLOON1 uno detrás del otro. Izquierda/derecha. Simétricos
|
|
||||||
X1_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 12
|
|
||||||
X1_0, 1, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 9
|
|
||||||
X1_0, 2, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 6
|
|
||||||
X1_0, 3, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 3
|
|
||||||
X1_0, 4, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 0
|
|
||||||
X1_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 12
|
|
||||||
X1_100, -1, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 9
|
|
||||||
X1_100, -2, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 6
|
|
||||||
X1_100, -3, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 3
|
|
||||||
X1_100, -4, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 0
|
|
||||||
|
|
||||||
formation: 22
|
|
||||||
# Diez enemigos BALLOON2. Hacia la derecha/izquierda. Separados. Simétricos
|
|
||||||
X2_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 40
|
|
||||||
X2_0, 2, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 30
|
|
||||||
X2_0, 4, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 20
|
|
||||||
X2_0, 6, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 10
|
|
||||||
X2_0, 8, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0
|
|
||||||
X2_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 40
|
|
||||||
X2_100, -2, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 30
|
|
||||||
X2_100, -4, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 20
|
|
||||||
X2_100, -6, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 10
|
|
||||||
X2_100, -8, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0
|
|
||||||
|
|
||||||
formation: 23
|
|
||||||
# Diez enemigos BALLOON2. Hacia la derecha. Juntos. Simétricos
|
|
||||||
X2_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 40
|
|
||||||
X2_0, 1, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 30
|
|
||||||
X2_0, 2, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 20
|
|
||||||
X2_0, 3, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 10
|
|
||||||
X2_0, 4, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0
|
|
||||||
X2_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 40
|
|
||||||
X2_100, -1, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 30
|
|
||||||
X2_100, -2, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 20
|
|
||||||
X2_100, -3, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 10
|
|
||||||
X2_100, -4, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0
|
|
||||||
|
|
||||||
formation: 24
|
|
||||||
# Treinta enemigos BALLOON0. Del centro hacia los extremos. Juntos. Simétricos
|
|
||||||
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0
|
|
||||||
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 5
|
|
||||||
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 10
|
|
||||||
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 15
|
|
||||||
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 20
|
|
||||||
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 25
|
|
||||||
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 30
|
|
||||||
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 35
|
|
||||||
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 40
|
|
||||||
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 45
|
|
||||||
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 50
|
|
||||||
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 55
|
|
||||||
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 60
|
|
||||||
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 65
|
|
||||||
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 70
|
|
||||||
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0
|
|
||||||
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 5
|
|
||||||
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 10
|
|
||||||
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 15
|
|
||||||
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 20
|
|
||||||
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 25
|
|
||||||
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 30
|
|
||||||
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 35
|
|
||||||
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 40
|
|
||||||
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 45
|
|
||||||
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 50
|
|
||||||
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 55
|
|
||||||
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 60
|
|
||||||
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 65
|
|
||||||
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 70
|
|
||||||
|
|
||||||
formation: 25
|
|
||||||
# Treinta enemigos BALLOON0. Del centro hacia adentro. Juntos. Simétricos
|
|
||||||
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 70
|
|
||||||
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 65
|
|
||||||
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 60
|
|
||||||
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 55
|
|
||||||
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 50
|
|
||||||
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 45
|
|
||||||
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 40
|
|
||||||
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 35
|
|
||||||
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 30
|
|
||||||
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 25
|
|
||||||
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 20
|
|
||||||
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 15
|
|
||||||
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 10
|
|
||||||
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 5
|
|
||||||
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0
|
|
||||||
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 70
|
|
||||||
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 65
|
|
||||||
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 60
|
|
||||||
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 55
|
|
||||||
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 50
|
|
||||||
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 45
|
|
||||||
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 40
|
|
||||||
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 35
|
|
||||||
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 30
|
|
||||||
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 25
|
|
||||||
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 20
|
|
||||||
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 15
|
|
||||||
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 10
|
|
||||||
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 5
|
|
||||||
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0
|
|
||||||
@@ -1,89 +0,0 @@
|
|||||||
## --- GAME ---
|
|
||||||
game.item_size 20 # Tamaño de los items del juego (en píxeles)
|
|
||||||
game.width 320 # Ancho de la resolución nativa del juego (en píxeles)
|
|
||||||
game.height 240 # Alto de la resolución nativa del juego (en píxeles)
|
|
||||||
game.play_area.rect.x 0 # Posición X de la zona jugable
|
|
||||||
game.play_area.rect.y 0 # Posición Y de la zona jugable
|
|
||||||
game.play_area.rect.w 320 # Ancho de la zona jugable
|
|
||||||
game.play_area.rect.h 200 # Alto de la zona jugable
|
|
||||||
game.name_entry_idle_time 10 # Segundos para introducir el nombre al finalizar la partida si no se pulsa nada
|
|
||||||
game.name_entry_total_time 60 # Segundos totales para introducir el nombre al finalizar la partida
|
|
||||||
game.hit_stop false # Indica si debe haber un paro cuando el jugador es golpeado por un globo
|
|
||||||
game.hit_stop_ms 500 # Cantidad de milisegundos que dura el hit_stop
|
|
||||||
|
|
||||||
## --- FADE ---
|
|
||||||
fade.color 1F2B30 # Color hexadecimal para el efecto de fundido
|
|
||||||
fade.num_squares_width 160 # Número de cuadrados en el eje X para el fundido
|
|
||||||
fade.num_squares_height 120 # Número de cuadrados en el eje Y para el fundido
|
|
||||||
fade.random_squares_delay 1 # Delay entre aparición de cuadrados aleatorios (frames)
|
|
||||||
fade.random_squares_mult 500 # Multiplicador para la velocidad de aparición aleatoria
|
|
||||||
fade.post_duration 80 # Duración tras el fundido (frames)
|
|
||||||
fade.venetian_size 12 # Tamaño de las bandas para el efecto veneciano (en píxeles)
|
|
||||||
|
|
||||||
## --- SCOREBOARD ---
|
|
||||||
scoreboard.rect.x 0 # Posición X del marcador
|
|
||||||
scoreboard.rect.y 216 # Posición Y del marcador
|
|
||||||
scoreboard.rect.w 320 # Ancho del marcador
|
|
||||||
scoreboard.rect.h 40 # Alto del marcador
|
|
||||||
scoreboard.separator_autocolor true # ¿El separador usa color automático?
|
|
||||||
scoreboard.separator_color 0D1A2B # Color del separador (hexadecimal)
|
|
||||||
scoreboard.easy_color 4B692F # Color para la dificultad fácil
|
|
||||||
scoreboard.normal_color 2E3F47 # Color para la dificultad normal
|
|
||||||
scoreboard.hard_color 76428A # Color para la dificultad difícil
|
|
||||||
scoreboard.text_autocolor true # ¿El texto usa color automático?
|
|
||||||
scoreboard.text_color1 FFFFFF # Color principal del texto del marcador
|
|
||||||
scoreboard.text_color2 FFFFFF # Color secundario del texto del marcador
|
|
||||||
scoreboard.skip_countdown_value 8 # Valor para saltar la cuenta atrás (segundos)
|
|
||||||
|
|
||||||
## --- TITLE ---
|
|
||||||
title.press_start_position 180 # Posición Y del texto "Press Start"
|
|
||||||
title.title_duration 800 # Duración de la pantalla de título (frames)
|
|
||||||
title.arcade_edition_position 123 # Posición Y del subtítulo "Arcade Edition"
|
|
||||||
title.title_c_c_position 80 # Posición Y del título principal
|
|
||||||
title.bg_color 41526F # Color de fondo en la sección titulo
|
|
||||||
|
|
||||||
## --- BACKGROUND ---
|
|
||||||
background.attenuate_color FFFFFF00 # Color de atenuación del fondo (RGBA hexadecimal)
|
|
||||||
|
|
||||||
## --- BALLOONS ---
|
|
||||||
balloon.settings[0].vel 2.75f # Velocidad inicial del globo 1
|
|
||||||
balloon.settings[0].grav 0.09f # Gravedad aplicada al globo 1
|
|
||||||
balloon.settings[1].vel 3.70f # Velocidad inicial del globo 2
|
|
||||||
balloon.settings[1].grav 0.10f # Gravedad aplicada al globo 2
|
|
||||||
balloon.settings[2].vel 4.70f # Velocidad inicial del globo 3
|
|
||||||
balloon.settings[2].grav 0.10f # Gravedad aplicada al globo 3
|
|
||||||
balloon.settings[3].vel 5.45f # Velocidad inicial del globo 4
|
|
||||||
balloon.settings[3].grav 0.10f # Gravedad aplicada al globo 4
|
|
||||||
|
|
||||||
balloon.color[0] blue # Color de creación del globo normal
|
|
||||||
balloon.color[1] orange # Color del globo normal
|
|
||||||
balloon.color[2] red # Color de creación del globo que rebota
|
|
||||||
balloon.color[3] green # Color del globo que rebota
|
|
||||||
|
|
||||||
balloon.bouncing_sound false # Indica si los globos hacer sonido al rebotar
|
|
||||||
|
|
||||||
## --- NOTIFICATION ---
|
|
||||||
notification.pos_v TOP # Posición vertical de la notificación (TOP/BOTTOM)
|
|
||||||
notification.pos_h LEFT # Posición horizontal de la notificación (LEFT/RIGHT)
|
|
||||||
notification.sound false # ¿La notificación reproduce sonido?
|
|
||||||
notification.color 303030 # Color de fondo de la notificación (hexadecimal)
|
|
||||||
|
|
||||||
## --- SERVICE MENU ---
|
|
||||||
service_menu.title_color 99FF62 # Color del título del menú de servicio
|
|
||||||
service_menu.text_color FFFFFF # Color del texto del menú de servicio
|
|
||||||
service_menu.selected_color FFDC44 # Color de la opción seleccionada en el menú de servicio
|
|
||||||
service_menu.bg_color 003000F5 # Color de fondo del menú de servicio (RGBA hexadecimal)
|
|
||||||
service_menu.drop_shadow false # ¿El menú de servicio tiene sombra?
|
|
||||||
|
|
||||||
## --- INTRO ---
|
|
||||||
intro.bg_color 4664BD # Color de fondo de la intro
|
|
||||||
intro.card_color CBDBFC # Color de las tarjetas en la intro
|
|
||||||
intro.shadow_color 00000080 # Color de la sombra de las tarjetas en la intro
|
|
||||||
intro.text_distance_from_bottom 48 # Posicion del texto
|
|
||||||
|
|
||||||
## --- DEBUG ---
|
|
||||||
debug.color 00FFFF # Color para elementos de depuración
|
|
||||||
|
|
||||||
## --- RESOURCE ---
|
|
||||||
resource.color FFFFFF # Color de recurso 1
|
|
||||||
resource.color FFFFFF # Color de recurso 2
|
|
||||||
@@ -1,89 +0,0 @@
|
|||||||
## --- GAME ---
|
|
||||||
game.item_size 20 # Tamaño de los items del juego (en píxeles)
|
|
||||||
game.width 320 # Ancho de la resolución nativa del juego (en píxeles)
|
|
||||||
game.height 256 # Alto de la resolución nativa del juego (en píxeles)
|
|
||||||
game.play_area.rect.x 0 # Posición X de la zona jugable
|
|
||||||
game.play_area.rect.y 0 # Posición Y de la zona jugable
|
|
||||||
game.play_area.rect.w 320 # Ancho de la zona jugable
|
|
||||||
game.play_area.rect.h 216 # Alto de la zona jugable
|
|
||||||
game.name_entry_idle_time 10 # Segundos para introducir el nombre al finalizar la partida si no se pulsa nada
|
|
||||||
game.name_entry_total_time 60 # Segundos totales para introducir el nombre al finalizar la partida
|
|
||||||
game.hit_stop false # Indica si debe haber un paro cuando el jugador es golpeado por un globo
|
|
||||||
game.hit_stop_ms 500 # Cantidad de milisegundos que dura el hit_stop
|
|
||||||
|
|
||||||
## --- FADE ---
|
|
||||||
fade.color 1F2B30 # Color hexadecimal para el efecto de fundido
|
|
||||||
fade.num_squares_width 160 # Número de cuadrados en el eje X para el fundido
|
|
||||||
fade.num_squares_height 128 # Número de cuadrados en el eje Y para el fundido
|
|
||||||
fade.random_squares_delay 1 # Delay entre aparición de cuadrados aleatorios (frames)
|
|
||||||
fade.random_squares_mult 500 # Multiplicador para la velocidad de aparición aleatoria
|
|
||||||
fade.post_duration 80 # Duración tras el fundido (frames)
|
|
||||||
fade.venetian_size 12 # Tamaño de las bandas para el efecto veneciano (en píxeles)
|
|
||||||
|
|
||||||
## --- SCOREBOARD ---
|
|
||||||
scoreboard.rect.x 0 # Posición X del marcador
|
|
||||||
scoreboard.rect.y 216 # Posición Y del marcador
|
|
||||||
scoreboard.rect.w 320 # Ancho del marcador
|
|
||||||
scoreboard.rect.h 40 # Alto del marcador
|
|
||||||
scoreboard.separator_autocolor true # ¿El separador usa color automático?
|
|
||||||
scoreboard.separator_color 0D1A2B # Color del separador (hexadecimal)
|
|
||||||
scoreboard.easy_color 4B692F # Color para la dificultad fácil
|
|
||||||
scoreboard.normal_color 2E3F47 # Color para la dificultad normal
|
|
||||||
scoreboard.hard_color 76428A # Color para la dificultad difícil
|
|
||||||
scoreboard.text_autocolor true # ¿El texto usa color automático?
|
|
||||||
scoreboard.text_color1 FFFFFF # Color principal del texto del marcador
|
|
||||||
scoreboard.text_color2 FFFFFF # Color secundario del texto del marcador
|
|
||||||
scoreboard.skip_countdown_value 8 # Valor para saltar la cuenta atrás (segundos)
|
|
||||||
|
|
||||||
## --- TITLE ---
|
|
||||||
title.press_start_position 180 # Posición Y del texto "Press Start"
|
|
||||||
title.title_duration 800 # Duración de la pantalla de título (frames)
|
|
||||||
title.arcade_edition_position 123 # Posición Y del subtítulo "Arcade Edition"
|
|
||||||
title.title_c_c_position 80 # Posición Y del título principal
|
|
||||||
title.bg_color 41526F # Color de fondo en la sección titulo
|
|
||||||
|
|
||||||
## --- BACKGROUND ---
|
|
||||||
background.attenuate_color FFFFFF00 # Color de atenuación del fondo (RGBA hexadecimal)
|
|
||||||
|
|
||||||
## --- BALLOONS ---
|
|
||||||
balloon.settings[0].vel 2.75f # Velocidad inicial del globo 1
|
|
||||||
balloon.settings[0].grav 0.09f # Gravedad aplicada al globo 1
|
|
||||||
balloon.settings[1].vel 3.70f # Velocidad inicial del globo 2
|
|
||||||
balloon.settings[1].grav 0.10f # Gravedad aplicada al globo 2
|
|
||||||
balloon.settings[2].vel 4.70f # Velocidad inicial del globo 3
|
|
||||||
balloon.settings[2].grav 0.10f # Gravedad aplicada al globo 3
|
|
||||||
balloon.settings[3].vel 5.45f # Velocidad inicial del globo 4
|
|
||||||
balloon.settings[3].grav 0.10f # Gravedad aplicada al globo 4
|
|
||||||
|
|
||||||
balloon.color[0] blue # Color de creación del globo normal
|
|
||||||
balloon.color[1] orange # Color del globo normal
|
|
||||||
balloon.color[2] red # Color de creación del globo que rebota
|
|
||||||
balloon.color[3] green # Color del globo que rebota
|
|
||||||
|
|
||||||
balloon.bouncing_sound false # Indica si los globos hacer sonido al rebotar
|
|
||||||
|
|
||||||
## --- NOTIFICATION ---
|
|
||||||
notification.pos_v TOP # Posición vertical de la notificación (TOP/BOTTOM)
|
|
||||||
notification.pos_h LEFT # Posición horizontal de la notificación (LEFT/RIGHT)
|
|
||||||
notification.sound false # ¿La notificación reproduce sonido?
|
|
||||||
notification.color 303030 # Color de fondo de la notificación (hexadecimal)
|
|
||||||
|
|
||||||
## --- SERVICE MENU ---
|
|
||||||
service_menu.title_color 99FF62 # Color del título del menú de servicio
|
|
||||||
service_menu.text_color FFFFFF # Color del texto del menú de servicio
|
|
||||||
service_menu.selected_color FFDC44 # Color de la opción seleccionada en el menú de servicio
|
|
||||||
service_menu.bg_color 000F00F5 # Color de fondo del menú de servicio (RGBA hexadecimal)
|
|
||||||
service_menu.drop_shadow false # ¿El menú de servicio tiene sombra?
|
|
||||||
|
|
||||||
## --- INTRO ---
|
|
||||||
intro.bg_color 4664BD # Color de fondo de la intro
|
|
||||||
intro.card_color CBDBFC # Color de las tarjetas en la intro
|
|
||||||
intro.shadow_color 00000080 # Color de la sombra de las tarjetas en la intro
|
|
||||||
intro.text_distance_from_bottom 48 # Posicion del texto
|
|
||||||
|
|
||||||
## --- DEBUG ---
|
|
||||||
debug.color 00FFFF # Color para elementos de depuración
|
|
||||||
|
|
||||||
## --- RESOURCE ---
|
|
||||||
resource.color FFFFFF # Color de recurso 1
|
|
||||||
resource.color FFFFFF # Color de recurso 2
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
# Archivo de configuración de pools de formaciones de globos
|
|
||||||
# Formato: POOL: <id> FORMATIONS: <id1>, <id2>, <id3>, ...
|
|
||||||
# Los IDs de formación pueden repetirse
|
|
||||||
# Los pools no necesitan estar ordenados ni ser consecutivos
|
|
||||||
|
|
||||||
# Pool para la fase 1
|
|
||||||
POOL: 0 FORMATIONS: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
|
|
||||||
|
|
||||||
# Pool para la fase 2
|
|
||||||
POOL: 1 FORMATIONS: 10, 11, 12, 13, 14, 15, 16, 17, 18, 19
|
|
||||||
|
|
||||||
# Pool para la fase 3
|
|
||||||
POOL: 2 FORMATIONS: 0, 1, 2, 3, 4, 55, 56, 57, 58, 59
|
|
||||||
|
|
||||||
# Pool para la fase 4
|
|
||||||
POOL: 3 FORMATIONS: 50, 51, 52, 53, 54, 5, 6, 7, 8, 9
|
|
||||||
|
|
||||||
# Pool para la fase 5
|
|
||||||
POOL: 4 FORMATIONS: 60, 61, 62, 63, 64, 65, 66, 67, 68, 69
|
|
||||||
|
|
||||||
# Pool para la fase 6
|
|
||||||
POOL: 5 FORMATIONS: 10, 61, 12, 63, 14, 65, 16, 67, 18, 69
|
|
||||||
|
|
||||||
# Pool para la fase 7
|
|
||||||
POOL: 6 FORMATIONS: 60, 11, 62, 13, 64, 15, 66, 17, 68, 19
|
|
||||||
|
|
||||||
# Pool para la fase 8
|
|
||||||
POOL: 7 FORMATIONS: 20, 21, 22, 23, 24, 65, 66, 67, 68, 69
|
|
||||||
|
|
||||||
# Pool para la fase 9
|
|
||||||
POOL: 8 FORMATIONS: 70, 71, 72, 73, 74, 15, 16, 17, 18, 19
|
|
||||||
|
|
||||||
# Pool para la fase 10
|
|
||||||
POOL: 9 FORMATIONS: 20, 21, 22, 23, 24, 70, 71, 72, 73, 74
|
|
||||||
BIN
data/demo/demo1.bin
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
data/demo/demo2.bin
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
data/demo/demo3.bin
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
data/font/04b_25_2x_white.png
Normal file
|
After Width: | Height: | Size: 4.2 KiB |
BIN
data/font/04b_25_white.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 872 B After Width: | Height: | Size: 882 B |
@@ -3,28 +3,28 @@ frame_height=10
|
|||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=orange
|
name=orange
|
||||||
speed=10
|
speed=0.1667
|
||||||
loop=0
|
loop=0
|
||||||
frames=0,1,2,3,4,5,6,7,8,9
|
frames=0,1,2,3,4,5,6,7,8,9
|
||||||
[/animation]
|
[/animation]
|
||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=blue
|
name=blue
|
||||||
speed=20
|
speed=0.3333
|
||||||
loop=0
|
loop=0
|
||||||
frames=10,11,12,13,14,15,16,17,18,19
|
frames=10,11,12,13,14,15,16,17,18,19
|
||||||
[/animation]
|
[/animation]
|
||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=green
|
name=green
|
||||||
speed=10
|
speed=0.1667
|
||||||
loop=0
|
loop=0
|
||||||
frames=20,21,22,23,24,25,26,27,28,29
|
frames=20,21,22,23,24,25,26,27,28,29
|
||||||
[/animation]
|
[/animation]
|
||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=red
|
name=red
|
||||||
speed=20
|
speed=0.3333
|
||||||
loop=0
|
loop=0
|
||||||
frames=30,31,32,33,34,35,36,37,38,39
|
frames=30,31,32,33,34,35,36,37,38,39
|
||||||
[/animation]
|
[/animation]
|
||||||
@@ -3,28 +3,28 @@ frame_height=16
|
|||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=orange
|
name=orange
|
||||||
speed=10
|
speed=0.1667
|
||||||
loop=0
|
loop=0
|
||||||
frames=0,1,2,3,4,5,6,7,8,9
|
frames=0,1,2,3,4,5,6,7,8,9
|
||||||
[/animation]
|
[/animation]
|
||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=blue
|
name=blue
|
||||||
speed=20
|
speed=0.3333
|
||||||
loop=0
|
loop=0
|
||||||
frames=10,11,12,13,14,15,16,17,18,19
|
frames=10,11,12,13,14,15,16,17,18,19
|
||||||
[/animation]
|
[/animation]
|
||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=green
|
name=green
|
||||||
speed=10
|
speed=0.1667
|
||||||
loop=0
|
loop=0
|
||||||
frames=20,21,22,23,24,25,26,27,28,29
|
frames=20,21,22,23,24,25,26,27,28,29
|
||||||
[/animation]
|
[/animation]
|
||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=red
|
name=red
|
||||||
speed=20
|
speed=0.3333
|
||||||
loop=0
|
loop=0
|
||||||
frames=30,31,32,33,34,35,36,37,38,39
|
frames=30,31,32,33,34,35,36,37,38,39
|
||||||
[/animation]
|
[/animation]
|
||||||
@@ -3,28 +3,28 @@ frame_height=26
|
|||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=orange
|
name=orange
|
||||||
speed=10
|
speed=0.1667
|
||||||
loop=0
|
loop=0
|
||||||
frames=0,1,2,3,4,5,6,7,8,9
|
frames=0,1,2,3,4,5,6,7,8,9
|
||||||
[/animation]
|
[/animation]
|
||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=blue
|
name=blue
|
||||||
speed=20
|
speed=0.3333
|
||||||
loop=0
|
loop=0
|
||||||
frames=10,11,12,13,14,15,16,17,18,19
|
frames=10,11,12,13,14,15,16,17,18,19
|
||||||
[/animation]
|
[/animation]
|
||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=green
|
name=green
|
||||||
speed=10
|
speed=0.1667
|
||||||
loop=0
|
loop=0
|
||||||
frames=20,21,22,23,24,25,26,27,28,29
|
frames=20,21,22,23,24,25,26,27,28,29
|
||||||
[/animation]
|
[/animation]
|
||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=red
|
name=red
|
||||||
speed=20
|
speed=0.3333
|
||||||
loop=0
|
loop=0
|
||||||
frames=30,31,32,33,34,35,36,37,38,39
|
frames=30,31,32,33,34,35,36,37,38,39
|
||||||
[/animation]
|
[/animation]
|
||||||
@@ -3,28 +3,28 @@ frame_height=48
|
|||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=orange
|
name=orange
|
||||||
speed=10
|
speed=0.1667
|
||||||
loop=0
|
loop=0
|
||||||
frames=0,1,2,3,4,5,6,7,8,9
|
frames=0,1,2,3,4,5,6,7,8,9
|
||||||
[/animation]
|
[/animation]
|
||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=blue
|
name=blue
|
||||||
speed=20
|
speed=0.3333
|
||||||
loop=0
|
loop=0
|
||||||
frames=10,11,12,13,14,15,16,17,18,19
|
frames=10,11,12,13,14,15,16,17,18,19
|
||||||
[/animation]
|
[/animation]
|
||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=green
|
name=green
|
||||||
speed=10
|
speed=0.1667
|
||||||
loop=0
|
loop=0
|
||||||
frames=20,21,22,23,24,25,26,27,28,29
|
frames=20,21,22,23,24,25,26,27,28,29
|
||||||
[/animation]
|
[/animation]
|
||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=red
|
name=red
|
||||||
speed=20
|
speed=0.3333
|
||||||
loop=0
|
loop=0
|
||||||
frames=30,31,32,33,34,35,36,37,38,39
|
frames=30,31,32,33,34,35,36,37,38,39
|
||||||
[/animation]
|
[/animation]
|
||||||
@@ -3,7 +3,7 @@ frame_height=10
|
|||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=default
|
name=default
|
||||||
speed=5
|
speed=0.0833
|
||||||
loop=-1
|
loop=-1
|
||||||
frames=0,1,2,3,4,5,6,7,8,9
|
frames=0,1,2,3,4,5,6,7,8,9
|
||||||
[/animation]
|
[/animation]
|
||||||
@@ -3,7 +3,7 @@ frame_height=16
|
|||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=default
|
name=default
|
||||||
speed=5
|
speed=0.0833
|
||||||
loop=-1
|
loop=-1
|
||||||
frames=0,1,2,3,4,5,6,7,8,9
|
frames=0,1,2,3,4,5,6,7,8,9
|
||||||
[/animation]
|
[/animation]
|
||||||
@@ -3,7 +3,7 @@ frame_height=26
|
|||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=default
|
name=default
|
||||||
speed=5
|
speed=0.0833
|
||||||
loop=-1
|
loop=-1
|
||||||
frames=0,1,2,3,4,5,6,7,8,9
|
frames=0,1,2,3,4,5,6,7,8,9
|
||||||
[/animation]
|
[/animation]
|
||||||
@@ -3,7 +3,7 @@ frame_height=48
|
|||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=default
|
name=default
|
||||||
speed=5
|
speed=0.0833
|
||||||
loop=-1
|
loop=-1
|
||||||
frames=0,1,2,3,4,5,6,7,8,9
|
frames=0,1,2,3,4,5,6,7,8,9
|
||||||
[/animation]
|
[/animation]
|
||||||
@@ -3,7 +3,7 @@ frame_height=49
|
|||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=powerball
|
name=powerball
|
||||||
speed=10
|
speed=0.0167
|
||||||
loop=-1
|
loop=-1
|
||||||
frames=1
|
frames=1
|
||||||
[/animation]
|
[/animation]
|
||||||
@@ -2,43 +2,85 @@ frame_width=12
|
|||||||
frame_height=12
|
frame_height=12
|
||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=normal_up
|
name=yellow_up
|
||||||
speed=5
|
speed=20
|
||||||
loop=0
|
loop=-1
|
||||||
frames=0,1,2
|
frames=0
|
||||||
[/animation]
|
[/animation]
|
||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=normal_left
|
name=yellow_left
|
||||||
speed=5
|
speed=20
|
||||||
loop=0
|
loop=-1
|
||||||
frames=3,4,5,5,4,3
|
frames=1
|
||||||
[/animation]
|
[/animation]
|
||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=normal_right
|
name=yellow_right
|
||||||
speed=5
|
speed=20
|
||||||
loop=0
|
loop=-1
|
||||||
frames=6,7,8,8,7,6
|
frames=2
|
||||||
[/animation]
|
[/animation]
|
||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=powered_up
|
name=green_up
|
||||||
speed=5
|
speed=20
|
||||||
loop=0
|
loop=-1
|
||||||
frames=9,10,11,11,10,9
|
frames=3
|
||||||
[/animation]
|
[/animation]
|
||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=powered_left
|
name=green_left
|
||||||
speed=5
|
speed=20
|
||||||
loop=0
|
loop=-1
|
||||||
frames=12,13,14,14,13,12
|
frames=4
|
||||||
[/animation]
|
[/animation]
|
||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=powered_right
|
name=green_right
|
||||||
speed=5
|
speed=20
|
||||||
loop=0
|
loop=-1
|
||||||
frames=15,16,17,17,26,15
|
frames=5
|
||||||
|
[/animation]
|
||||||
|
|
||||||
|
[animation]
|
||||||
|
name=red_up
|
||||||
|
speed=20
|
||||||
|
loop=-1
|
||||||
|
frames=6
|
||||||
|
[/animation]
|
||||||
|
|
||||||
|
[animation]
|
||||||
|
name=red_left
|
||||||
|
speed=20
|
||||||
|
loop=-1
|
||||||
|
frames=7
|
||||||
|
[/animation]
|
||||||
|
|
||||||
|
[animation]
|
||||||
|
name=red_right
|
||||||
|
speed=20
|
||||||
|
loop=-1
|
||||||
|
frames=8
|
||||||
|
[/animation]
|
||||||
|
|
||||||
|
[animation]
|
||||||
|
name=purple_up
|
||||||
|
speed=20
|
||||||
|
loop=-1
|
||||||
|
frames=9
|
||||||
|
[/animation]
|
||||||
|
|
||||||
|
[animation]
|
||||||
|
name=purple_left
|
||||||
|
speed=20
|
||||||
|
loop=-1
|
||||||
|
frames=10
|
||||||
|
[/animation]
|
||||||
|
|
||||||
|
[animation]
|
||||||
|
name=purple_right
|
||||||
|
speed=20
|
||||||
|
loop=-1
|
||||||
|
frames=11
|
||||||
[/animation]
|
[/animation]
|
||||||
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 1.7 KiB |
@@ -3,7 +3,7 @@ frame_height=20
|
|||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=default
|
name=default
|
||||||
speed=8
|
speed=0.1333
|
||||||
loop=0
|
loop=0
|
||||||
frames=0,0,1
|
frames=0,0,1
|
||||||
[/animation]
|
[/animation]
|
||||||
@@ -3,7 +3,7 @@ frame_height=20
|
|||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=default
|
name=default
|
||||||
speed=8
|
speed=0.1333
|
||||||
loop=0
|
loop=0
|
||||||
frames=0,0,1
|
frames=0,0,1
|
||||||
[/animation]
|
[/animation]
|
||||||
@@ -3,7 +3,7 @@ frame_height=39
|
|||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=default
|
name=default
|
||||||
speed=6
|
speed=0.1
|
||||||
loop=0
|
loop=0
|
||||||
frames=0,1,2,3,4,5,6,7,8
|
frames=0,1,2,3,4,5,6,7,8
|
||||||
[/animation]
|
[/animation]
|
||||||
@@ -3,7 +3,7 @@ frame_height=20
|
|||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=default
|
name=default
|
||||||
speed=8
|
speed=0.1333
|
||||||
loop=0
|
loop=0
|
||||||
frames=0,0,1
|
frames=0,0,1
|
||||||
[/animation]
|
[/animation]
|
||||||
@@ -3,7 +3,7 @@ frame_height=20
|
|||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=default
|
name=default
|
||||||
speed=8
|
speed=0.1333
|
||||||
loop=0
|
loop=0
|
||||||
frames=0,0,1
|
frames=0,0,1
|
||||||
[/animation]
|
[/animation]
|
||||||
@@ -3,7 +3,7 @@ frame_height=20
|
|||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=default
|
name=default
|
||||||
speed=8
|
speed=0.1333
|
||||||
loop=0
|
loop=0
|
||||||
frames=0,0,1
|
frames=0,0,1
|
||||||
[/animation]
|
[/animation]
|
||||||
@@ -3,7 +3,7 @@ frame_height=20
|
|||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=default
|
name=default
|
||||||
speed=8
|
speed=0.1333
|
||||||
loop=0
|
loop=0
|
||||||
frames=0,0,1
|
frames=0,0,1
|
||||||
[/animation]
|
[/animation]
|
||||||
@@ -3,126 +3,133 @@ frame_height=32
|
|||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=walk
|
name=walk
|
||||||
speed=5
|
speed=0.0833
|
||||||
loop=0
|
loop=0
|
||||||
frames=0,1,2,3
|
frames=0,1,2,3
|
||||||
[/animation]
|
[/animation]
|
||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=stand
|
name=stand
|
||||||
speed=10
|
speed=0.167
|
||||||
loop=0
|
loop=0
|
||||||
frames=4,5,6,7
|
frames=4,5,6,7
|
||||||
[/animation]
|
[/animation]
|
||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=walk-fire-side
|
name=walk-fire-side
|
||||||
speed=5
|
speed=0.0833
|
||||||
loop=0
|
loop=0
|
||||||
frames=8,9,10,11
|
frames=8,9,10,11
|
||||||
[/animation]
|
[/animation]
|
||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=walk-recoil-side
|
name=walk-recoil-side
|
||||||
speed=5
|
speed=0.0833
|
||||||
loop=0
|
loop=0
|
||||||
frames=12,13,14,15
|
frames=12,13,14,15
|
||||||
[/animation]
|
[/animation]
|
||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=walk-cool-side
|
name=walk-cool-side
|
||||||
speed=5
|
speed=0.0833
|
||||||
loop=0
|
loop=0
|
||||||
frames=16,17,18,19
|
frames=16,17,18,19
|
||||||
[/animation]
|
[/animation]
|
||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=stand-fire-side
|
name=stand-fire-side
|
||||||
speed=5
|
speed=0.0833
|
||||||
loop=0
|
loop=0
|
||||||
frames=20
|
frames=20
|
||||||
[/animation]
|
[/animation]
|
||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=stand-recoil-side
|
name=stand-recoil-side
|
||||||
speed=5
|
speed=0.0833
|
||||||
loop=0
|
loop=0
|
||||||
frames=21
|
frames=21
|
||||||
[/animation]
|
[/animation]
|
||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=stand-cool-side
|
name=stand-cool-side
|
||||||
speed=5
|
speed=0.0833
|
||||||
loop=0
|
loop=0
|
||||||
frames=22
|
frames=22
|
||||||
[/animation]
|
[/animation]
|
||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=walk-fire-center
|
name=walk-fire-center
|
||||||
speed=5
|
speed=0.0833
|
||||||
loop=0
|
loop=0
|
||||||
frames=23,24,25,26
|
frames=23,24,25,26
|
||||||
[/animation]
|
[/animation]
|
||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=walk-recoil-center
|
name=walk-recoil-center
|
||||||
speed=5
|
speed=0.0833
|
||||||
loop=0
|
loop=0
|
||||||
frames=27,28,29,30
|
frames=27,28,29,30
|
||||||
[/animation]
|
[/animation]
|
||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=walk-cool-center
|
name=walk-cool-center
|
||||||
speed=5
|
speed=0.0833
|
||||||
loop=0
|
loop=0
|
||||||
frames=31,32,33,34
|
frames=31,32,33,34
|
||||||
[/animation]
|
[/animation]
|
||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=stand-fire-center
|
name=stand-fire-center
|
||||||
speed=5
|
speed=0.0833
|
||||||
loop=0
|
loop=0
|
||||||
frames=35
|
frames=35
|
||||||
[/animation]
|
[/animation]
|
||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=stand-recoil-center
|
name=stand-recoil-center
|
||||||
speed=5
|
speed=0.0833
|
||||||
loop=0
|
loop=0
|
||||||
frames=36
|
frames=36
|
||||||
[/animation]
|
[/animation]
|
||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=stand-cool-center
|
name=stand-cool-center
|
||||||
speed=5
|
speed=0.0833
|
||||||
loop=0
|
loop=0
|
||||||
frames=37
|
frames=37
|
||||||
[/animation]
|
[/animation]
|
||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=rolling
|
name=rolling
|
||||||
speed=10
|
speed=0.167
|
||||||
loop=0
|
loop=0
|
||||||
frames=38,39,40,41
|
frames=38,39,40,41
|
||||||
[/animation]
|
[/animation]
|
||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=celebration
|
name=celebration
|
||||||
speed=10
|
speed=0.167
|
||||||
loop=-1
|
loop=0
|
||||||
frames=42,42,42,42,42,42,43,44,45,46,46,46,46,46,46,45,45,45,46,46,46,45,45,45,44,43,42,42,42
|
frames=42,42,42,42,42,42,43,44,45,46,46,46,46,46,46,45,45,45,46,46,46,45,45,45,44,43,42,42,42
|
||||||
[/animation]
|
[/animation]
|
||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=dizzy
|
name=dizzy
|
||||||
speed=5
|
speed=0.0833
|
||||||
loop=0
|
loop=0
|
||||||
frames=47,48,49,50,51,52,53
|
frames=47,48,49,50,51,52,53
|
||||||
[/animation]
|
[/animation]
|
||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=hello
|
name=recover
|
||||||
speed=3
|
speed=0.05
|
||||||
loop=-1
|
loop=-1
|
||||||
frames=54,55,56,57,58,59,60,61,62,63,64,64,64,64,64,64,64,64,64,64,64,64,64,65,66,67,68,69,70,71,72,73,73,72,71,70,70,71,72,73,73,72,71,70,70,71,72,73,73,72,71,70,70,71,72,73,73,72,71,70,69,68,67,66,65,64,63,62,61,60,59,58,57,56,55,54
|
frames=54,54,54,54,55,56,57,58,58,58,59,60,61,58,59,60,61,58,59,60,61,62,62,62,62
|
||||||
|
[/animation]
|
||||||
|
|
||||||
|
[animation]
|
||||||
|
name=hello
|
||||||
|
speed=0.05
|
||||||
|
loop=-1
|
||||||
|
frames=63,64,65,66,67,68,69,70,71,72,73,73,73,73,73,73,73,73,73,73,73,73,73,74,75,76,77,78,79,80,81,82,82,81,80,79,79,80,81,82,82,81,80,79,79,80,81,82,82,81,80,79,79,80,81,82,82,81,80,79,78,77,76,75,74,73,72,71,70,69,68,67,66,65,64,63
|
||||||
[/animation]
|
[/animation]
|
||||||
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 16 KiB |
@@ -3,7 +3,7 @@ frame_height=44
|
|||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=default
|
name=default
|
||||||
speed=5
|
speed=0.0833
|
||||||
loop=0
|
loop=0
|
||||||
frames=0,1,2,3
|
frames=0,1,2,3
|
||||||
[/animation]
|
[/animation]
|
||||||
@@ -3,14 +3,14 @@ frame_height=32
|
|||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=fly
|
name=fly
|
||||||
speed=2
|
speed=0.0333
|
||||||
loop=0
|
loop=0
|
||||||
frames=0,1
|
frames=0,1
|
||||||
[/animation]
|
[/animation]
|
||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=hit
|
name=hit
|
||||||
speed=2
|
speed=0.0333
|
||||||
loop=0
|
loop=0
|
||||||
frames=2,3
|
frames=2,3
|
||||||
[/animation]
|
[/animation]
|
||||||
@@ -3,7 +3,7 @@ frame_height=16
|
|||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=default
|
name=default
|
||||||
speed=8
|
speed=0.1333
|
||||||
loop=-1
|
loop=-1
|
||||||
frames=0,1,2,3,4,5,6
|
frames=0,1,2,3,4,5,6
|
||||||
[/animation]
|
[/animation]
|
||||||
@@ -26,6 +26,8 @@
|
|||||||
"[GAME_TEXT] 6": "Temps!",
|
"[GAME_TEXT] 6": "Temps!",
|
||||||
"[GAME_TEXT] 7": "Endavant!",
|
"[GAME_TEXT] 7": "Endavant!",
|
||||||
"[GAME_TEXT] 8": "1.000.000 de punts!",
|
"[GAME_TEXT] 8": "1.000.000 de punts!",
|
||||||
|
"[GAME_TEXT] THANK_YOU": "Gracies!",
|
||||||
|
"[GAME_TEXT] NEW_RECORD": "Nou record!",
|
||||||
|
|
||||||
"[HIGHSCORE_TABLE] CAPTION": "Millors puntuacions",
|
"[HIGHSCORE_TABLE] CAPTION": "Millors puntuacions",
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,8 @@
|
|||||||
"[GAME_TEXT] 6": "Stop!",
|
"[GAME_TEXT] 6": "Stop!",
|
||||||
"[GAME_TEXT] 7": "Get Ready!",
|
"[GAME_TEXT] 7": "Get Ready!",
|
||||||
"[GAME_TEXT] 8": "1,000,000 points!",
|
"[GAME_TEXT] 8": "1,000,000 points!",
|
||||||
|
"[GAME_TEXT] THANK_YOU": "Thank you!",
|
||||||
|
"[GAME_TEXT] NEW_RECORD": "New record!",
|
||||||
|
|
||||||
"[HIGHSCORE_TABLE] CAPTION": "Best scores",
|
"[HIGHSCORE_TABLE] CAPTION": "Best scores",
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,8 @@
|
|||||||
"[GAME_TEXT] 6": "Tiempo!",
|
"[GAME_TEXT] 6": "Tiempo!",
|
||||||
"[GAME_TEXT] 7": "Adelante!",
|
"[GAME_TEXT] 7": "Adelante!",
|
||||||
"[GAME_TEXT] 8": "1.000.000 de puntos!",
|
"[GAME_TEXT] 8": "1.000.000 de puntos!",
|
||||||
|
"[GAME_TEXT] THANK_YOU": "Gracias!",
|
||||||
|
"[GAME_TEXT] NEW_RECORD": "Nuevo record!",
|
||||||
|
|
||||||
"[HIGHSCORE_TABLE] CAPTION": "Mejores puntuaciones",
|
"[HIGHSCORE_TABLE] CAPTION": "Mejores puntuaciones",
|
||||||
|
|
||||||
|
|||||||
BIN
data/music/congratulations.ogg
Normal file
@@ -1,234 +0,0 @@
|
|||||||
/*
|
|
||||||
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
|
|
||||||
@@ -1,234 +0,0 @@
|
|||||||
/*
|
|
||||||
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 / 256.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, 256.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
|
|
||||||
157
data/shaders/crtpi_fragment.glsl
Normal file
@@ -0,0 +1,157 @@
|
|||||||
|
#version 330 core
|
||||||
|
|
||||||
|
// Configuración
|
||||||
|
#define SCANLINES
|
||||||
|
#define MULTISAMPLE
|
||||||
|
#define GAMMA
|
||||||
|
//#define FAKE_GAMMA
|
||||||
|
//#define CURVATURE
|
||||||
|
//#define SHARPER
|
||||||
|
#define MASK_TYPE 2
|
||||||
|
|
||||||
|
#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
|
||||||
|
|
||||||
|
// Inputs desde vertex shader
|
||||||
|
in vec2 vTexCoord;
|
||||||
|
in float vFilterWidth;
|
||||||
|
#if defined(CURVATURE)
|
||||||
|
in vec2 vScreenScale;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Output
|
||||||
|
out vec4 FragColor;
|
||||||
|
|
||||||
|
// Uniforms
|
||||||
|
uniform sampler2D Texture;
|
||||||
|
uniform vec2 TextureSize;
|
||||||
|
|
||||||
|
#if defined(CURVATURE)
|
||||||
|
vec2 Distort(vec2 coord)
|
||||||
|
{
|
||||||
|
vec2 CURVATURE_DISTORTION = vec2(CURVATURE_X, CURVATURE_Y);
|
||||||
|
vec2 barrelScale = 1.0 - (0.23 * CURVATURE_DISTORTION);
|
||||||
|
coord *= vScreenScale;
|
||||||
|
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);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
coord += vec2(0.5);
|
||||||
|
coord /= vScreenScale;
|
||||||
|
}
|
||||||
|
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 - vFilterWidth);
|
||||||
|
scanLineWeight += CalcScanLineWeight(dy + vFilterWidth);
|
||||||
|
scanLineWeight *= 0.3333333;
|
||||||
|
#endif
|
||||||
|
return scanLineWeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
#if defined(CURVATURE)
|
||||||
|
vec2 texcoord = Distort(vTexCoord);
|
||||||
|
if (texcoord.x < 0.0) {
|
||||||
|
FragColor = vec4(0.0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
vec2 texcoord = vTexCoord;
|
||||||
|
#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 = texture(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
|
||||||
|
FragColor = vec4(colour, 1.0);
|
||||||
|
#elif MASK_TYPE == 1
|
||||||
|
float whichMask = fract(gl_FragCoord.x * 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);
|
||||||
|
FragColor = vec4(colour * mask, 1.0);
|
||||||
|
#elif MASK_TYPE == 2
|
||||||
|
float whichMask = fract(gl_FragCoord.x * 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;
|
||||||
|
FragColor = vec4(colour * mask, 1.0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
152
data/shaders/crtpi_fragment.metal
Normal file
@@ -0,0 +1,152 @@
|
|||||||
|
//
|
||||||
|
// CRT-Pi Fragment Shader - Metal Shading Language
|
||||||
|
// Portado desde GLSL a MSL para macOS
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <metal_stdlib>
|
||||||
|
using namespace metal;
|
||||||
|
|
||||||
|
// Configuración (equivalente a los #define en GLSL)
|
||||||
|
constant bool SCANLINES = true;
|
||||||
|
constant bool MULTISAMPLE = true;
|
||||||
|
constant bool GAMMA = true;
|
||||||
|
constant bool FAKE_GAMMA = false;
|
||||||
|
constant bool CURVATURE = false;
|
||||||
|
constant bool SHARPER = false;
|
||||||
|
constant int MASK_TYPE = 2; // 0=none, 1=green/magenta, 2=trinitron
|
||||||
|
|
||||||
|
constant float CURVATURE_X = 0.05;
|
||||||
|
constant float CURVATURE_Y = 0.1;
|
||||||
|
constant float MASK_BRIGHTNESS = 0.80;
|
||||||
|
constant float SCANLINE_WEIGHT = 6.0;
|
||||||
|
constant float SCANLINE_GAP_BRIGHTNESS = 0.12;
|
||||||
|
constant float BLOOM_FACTOR = 3.5;
|
||||||
|
constant float INPUT_GAMMA = 2.4;
|
||||||
|
constant float OUTPUT_GAMMA = 2.2;
|
||||||
|
|
||||||
|
// Estructura de entrada (salida del vertex shader)
|
||||||
|
struct VertexOut {
|
||||||
|
float4 position [[position]];
|
||||||
|
float2 texCoord;
|
||||||
|
float filterWidth;
|
||||||
|
// float2 screenScale; // Solo si CURVATURE está activo
|
||||||
|
};
|
||||||
|
|
||||||
|
// Uniforms
|
||||||
|
struct Uniforms {
|
||||||
|
float2 textureSize;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Función para calcular el peso de la scanline
|
||||||
|
float CalcScanLineWeight(float dist) {
|
||||||
|
return max(1.0 - dist * dist * SCANLINE_WEIGHT, SCANLINE_GAP_BRIGHTNESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Función para calcular scanline con multisampling
|
||||||
|
float CalcScanLine(float dy, float filterWidth) {
|
||||||
|
float scanLineWeight = CalcScanLineWeight(dy);
|
||||||
|
if (MULTISAMPLE) {
|
||||||
|
scanLineWeight += CalcScanLineWeight(dy - filterWidth);
|
||||||
|
scanLineWeight += CalcScanLineWeight(dy + filterWidth);
|
||||||
|
scanLineWeight *= 0.3333333;
|
||||||
|
}
|
||||||
|
return scanLineWeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Entry point del fragment shader
|
||||||
|
fragment float4 fragment_main(VertexOut in [[stage_in]],
|
||||||
|
texture2d<float> colorTexture [[texture(0)]],
|
||||||
|
constant Uniforms& uniforms [[buffer(1)]],
|
||||||
|
sampler textureSampler [[sampler(0)]]) {
|
||||||
|
|
||||||
|
float2 texcoord = in.texCoord;
|
||||||
|
|
||||||
|
// Si CURVATURE estuviera activo, aquí iría la función Distort()
|
||||||
|
|
||||||
|
float2 texcoordInPixels = texcoord * uniforms.textureSize;
|
||||||
|
|
||||||
|
float2 tc;
|
||||||
|
float scanLineWeight;
|
||||||
|
|
||||||
|
if (!SHARPER) {
|
||||||
|
// Modo normal (no SHARPER)
|
||||||
|
float tempY = floor(texcoordInPixels.y) + 0.5;
|
||||||
|
float yCoord = tempY / uniforms.textureSize.y;
|
||||||
|
float dy = texcoordInPixels.y - tempY;
|
||||||
|
scanLineWeight = CalcScanLine(dy, in.filterWidth);
|
||||||
|
float signY = sign(dy);
|
||||||
|
dy = dy * dy;
|
||||||
|
dy = dy * dy;
|
||||||
|
dy *= 8.0;
|
||||||
|
dy /= uniforms.textureSize.y;
|
||||||
|
dy *= signY;
|
||||||
|
tc = float2(texcoord.x, yCoord + dy);
|
||||||
|
} else {
|
||||||
|
// Modo SHARPER
|
||||||
|
float2 tempCoord = floor(texcoordInPixels) + 0.5;
|
||||||
|
float2 coord = tempCoord / uniforms.textureSize;
|
||||||
|
float2 deltas = texcoordInPixels - tempCoord;
|
||||||
|
scanLineWeight = CalcScanLine(deltas.y, in.filterWidth);
|
||||||
|
float2 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 /= uniforms.textureSize;
|
||||||
|
deltas *= signs;
|
||||||
|
tc = coord + deltas;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Muestrear textura (texture() en GLSL = sample() en MSL)
|
||||||
|
float3 colour = colorTexture.sample(textureSampler, tc).rgb;
|
||||||
|
|
||||||
|
if (SCANLINES) {
|
||||||
|
if (GAMMA) {
|
||||||
|
if (FAKE_GAMMA) {
|
||||||
|
colour = colour * colour;
|
||||||
|
} else {
|
||||||
|
colour = pow(colour, float3(INPUT_GAMMA));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
scanLineWeight *= BLOOM_FACTOR;
|
||||||
|
colour *= scanLineWeight;
|
||||||
|
|
||||||
|
if (GAMMA) {
|
||||||
|
if (FAKE_GAMMA) {
|
||||||
|
colour = sqrt(colour);
|
||||||
|
} else {
|
||||||
|
colour = pow(colour, float3(1.0 / OUTPUT_GAMMA));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Aplicar máscara CRT
|
||||||
|
if (MASK_TYPE == 0) {
|
||||||
|
return float4(colour, 1.0);
|
||||||
|
} else if (MASK_TYPE == 1) {
|
||||||
|
// Máscara verde/magenta
|
||||||
|
float whichMask = fract(in.position.x * 0.5);
|
||||||
|
float3 mask;
|
||||||
|
if (whichMask < 0.5) {
|
||||||
|
mask = float3(MASK_BRIGHTNESS, 1.0, MASK_BRIGHTNESS);
|
||||||
|
} else {
|
||||||
|
mask = float3(1.0, MASK_BRIGHTNESS, 1.0);
|
||||||
|
}
|
||||||
|
return float4(colour * mask, 1.0);
|
||||||
|
} else if (MASK_TYPE == 2) {
|
||||||
|
// Máscara trinitron
|
||||||
|
float whichMask = fract(in.position.x * 0.3333333);
|
||||||
|
float3 mask = float3(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;
|
||||||
|
}
|
||||||
|
return float4(colour * mask, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return float4(colour, 1.0);
|
||||||
|
}
|
||||||
48
data/shaders/crtpi_vertex.glsl
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
#version 330 core
|
||||||
|
|
||||||
|
// Configuración
|
||||||
|
#define SCANLINES
|
||||||
|
#define MULTISAMPLE
|
||||||
|
#define GAMMA
|
||||||
|
//#define FAKE_GAMMA
|
||||||
|
//#define CURVATURE
|
||||||
|
//#define SHARPER
|
||||||
|
#define MASK_TYPE 2
|
||||||
|
|
||||||
|
#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
|
||||||
|
|
||||||
|
// Inputs (desde VAO)
|
||||||
|
layout(location = 0) in vec2 aPosition;
|
||||||
|
layout(location = 1) in vec2 aTexCoord;
|
||||||
|
|
||||||
|
// Outputs al fragment shader
|
||||||
|
out vec2 vTexCoord;
|
||||||
|
out float vFilterWidth;
|
||||||
|
#if defined(CURVATURE)
|
||||||
|
out vec2 vScreenScale;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Uniforms
|
||||||
|
uniform vec2 TextureSize;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
#if defined(CURVATURE)
|
||||||
|
vScreenScale = vec2(1.0, 1.0);
|
||||||
|
#endif
|
||||||
|
// Calcula filterWidth dinámicamente basándose en la altura de la textura
|
||||||
|
vFilterWidth = (768.0 / TextureSize.y) / 3.0;
|
||||||
|
|
||||||
|
// Pasar coordenadas de textura (invertir Y para SDL)
|
||||||
|
vTexCoord = vec2(aTexCoord.x, 1.0 - aTexCoord.y) * 1.0001;
|
||||||
|
|
||||||
|
// Posición del vértice (ya en espacio de clip [-1, 1])
|
||||||
|
gl_Position = vec4(aPosition, 0.0, 1.0);
|
||||||
|
}
|
||||||
46
data/shaders/crtpi_vertex.metal
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
//
|
||||||
|
// CRT-Pi Vertex Shader - Metal Shading Language
|
||||||
|
// Portado desde GLSL a MSL para macOS
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <metal_stdlib>
|
||||||
|
using namespace metal;
|
||||||
|
|
||||||
|
// Estructura de entrada del vertex shader (desde el buffer de vértices)
|
||||||
|
struct VertexIn {
|
||||||
|
float2 position [[attribute(0)]]; // Posición del vértice
|
||||||
|
float2 texCoord [[attribute(1)]]; // Coordenadas de textura
|
||||||
|
};
|
||||||
|
|
||||||
|
// Estructura de salida del vertex shader (entrada al fragment shader)
|
||||||
|
struct VertexOut {
|
||||||
|
float4 position [[position]]; // Posición en clip space
|
||||||
|
float2 texCoord; // Coordenadas de textura
|
||||||
|
float filterWidth; // Ancho del filtro calculado
|
||||||
|
// float2 screenScale; // Solo si CURVATURE está activo
|
||||||
|
};
|
||||||
|
|
||||||
|
// Uniforms (constantes del shader)
|
||||||
|
struct Uniforms {
|
||||||
|
float2 textureSize; // Tamaño de la textura (width, height)
|
||||||
|
};
|
||||||
|
|
||||||
|
// Entry point del vertex shader
|
||||||
|
vertex VertexOut vertex_main(VertexIn in [[stage_in]],
|
||||||
|
constant Uniforms& uniforms [[buffer(1)]]) {
|
||||||
|
VertexOut out;
|
||||||
|
|
||||||
|
// Posición del vértice (ya está en espacio de clip [-1, 1])
|
||||||
|
out.position = float4(in.position, 0.0, 1.0);
|
||||||
|
|
||||||
|
// Pasar coordenadas de textura (invertir Y para SDL, igual que en GLSL)
|
||||||
|
out.texCoord = float2(in.texCoord.x, 1.0 - in.texCoord.y) * 1.0001;
|
||||||
|
|
||||||
|
// Calcular filterWidth dinámicamente basándose en la altura de la textura
|
||||||
|
out.filterWidth = (768.0 / uniforms.textureSize.y) / 3.0;
|
||||||
|
|
||||||
|
// Si CURVATURE estuviera activo:
|
||||||
|
// out.screenScale = float2(1.0, 1.0);
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
BIN
data/sound/bullet2p.wav
Normal file
BIN
data/sound/credit.wav
Normal file
BIN
data/sound/name_input_accept.wav
Normal file
BIN
data/sound/service_menu_back.wav
Normal file
BIN
data/sound/voice_credit_thankyou.wav
Normal file
BIN
data/sound/voice_game_over.wav
Normal file
BIN
data/sound/voice_recover.wav
Normal file
43
development_guidelines.md
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
# Directrices de Desarrollo - Coffee Crisis Arcade Edition
|
||||||
|
|
||||||
|
## Directrices Principales Confirmadas
|
||||||
|
|
||||||
|
### 1. **Sistema Temporal**
|
||||||
|
- **TODO migrado de frame based a time based**
|
||||||
|
- **Delta time en segundos (float)**
|
||||||
|
- **Unidades de tiempo: SOLO segundos** (no frames, no milisegundos)
|
||||||
|
|
||||||
|
### 2. **Contadores y Timers**
|
||||||
|
- **CRECIENTES**: para sistemas con múltiples eventos temporales (timeline)
|
||||||
|
- Patrón: `elapsed_time += deltaTime; if (elapsed_time >= EVENT_TIME) { /* acción */ }`
|
||||||
|
- **DECRECIENTES**: para contadores con diferentes valores de inicialización
|
||||||
|
- Patrón: `timer -= deltaTime; if (timer <= 0.0f) { /* acción */ timer = DURATION; }`
|
||||||
|
|
||||||
|
### 3. **Números Mágicos**
|
||||||
|
- **Definidos en constantes**
|
||||||
|
- **Preferencia**: cabecera de la clase
|
||||||
|
- **Excepción**: si es algo local a un método específico
|
||||||
|
|
||||||
|
## Problemas Pendientes de Reparación (game.cpp)
|
||||||
|
|
||||||
|
### ❌ PENDIENTES
|
||||||
|
1. **param.fade.post_duration_ms verification** (líneas 89, 1671)
|
||||||
|
2. **setRotateSpeed verification** (línea 797)
|
||||||
|
3. **TOTAL_DEMO_DATA - 200 magic number** (línea 1669)
|
||||||
|
4. **Comprehensive magic number search** - Buscar 100, 150, 200, 250, 300, 400, 500, 1000
|
||||||
|
|
||||||
|
### 4. **Velocidades y Aceleraciones**
|
||||||
|
- **Velocidades**: pixels/segundo
|
||||||
|
- **Aceleraciones**: pixels/segundo²
|
||||||
|
|
||||||
|
### 5. **Documentación de Conversiones**
|
||||||
|
- **Comentarios explicativos** en cambios críticos de timing
|
||||||
|
- Documentar conversiones frame→tiempo en el código
|
||||||
|
|
||||||
|
### 6. **Patrón de Constantes**
|
||||||
|
- Crear constantes para valores repetidos (evitar duplicación)
|
||||||
|
- Nombres descriptivos para constantes de tiempo
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Estado**: Directrices completas confirmadas
|
||||||
15
linux_utils/generate_compile_commands_json.sh
Executable file
@@ -0,0 +1,15 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# 🏁 Ruta base del proyecto
|
||||||
|
BASE_DIR="/home/sergio/gitea/coffee_crisis_arcade_edition"
|
||||||
|
|
||||||
|
# 📁 Ruta al build
|
||||||
|
BUILD_DIR="$BASE_DIR/build"
|
||||||
|
|
||||||
|
# 📄 Archivo de mapping personalizado
|
||||||
|
MAPPING_FILE="$BASE_DIR/linux_utils/sdl3_mapping.imp"
|
||||||
|
|
||||||
|
# 📦 Generar compile_commands.json
|
||||||
|
echo "🔧 Generando compile_commands.json..."
|
||||||
|
cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -S "$BASE_DIR" -B "$BUILD_DIR"
|
||||||
|
|
||||||
44
linux_utils/run_clang-tidy.sh
Executable file
@@ -0,0 +1,44 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Script para ejecutar clang-tidy en múltiples directorios
|
||||||
|
# Uso: ./run_clang-tidy.sh
|
||||||
|
|
||||||
|
# Lista de rutas donde ejecutar clang-tidy
|
||||||
|
PATHS=(
|
||||||
|
"/home/sergio/gitea/coffee_crisis_arcade_edition/source"
|
||||||
|
"/home/sergio/gitea/coffee_crisis_arcade_edition/source/sections"
|
||||||
|
"/home/sergio/gitea/coffee_crisis_arcade_edition/source/ui"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Ruta del directorio build (relativa desde donde se ejecuta el script)
|
||||||
|
BUILD_DIR="/home/sergio/gitea/coffee_crisis_arcade_edition/build/"
|
||||||
|
|
||||||
|
# Función para procesar un directorio
|
||||||
|
process_directory() {
|
||||||
|
local dir="$1"
|
||||||
|
|
||||||
|
echo "=== Procesando directorio: $dir ==="
|
||||||
|
|
||||||
|
# Verificar que el directorio existe
|
||||||
|
if [[ ! -d "$dir" ]]; then
|
||||||
|
echo "Error: El directorio $dir no existe"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Cambiar al directorio y ejecutar find con -maxdepth 1 para un solo nivel
|
||||||
|
cd "$dir" || return 1
|
||||||
|
|
||||||
|
# Buscar archivos .cpp, .h, .hpp solo en el nivel actual (no subdirectorios)
|
||||||
|
find . -maxdepth 1 \( -name '*.cpp' -o -name '*.h' -o -name '*.hpp' \) | \
|
||||||
|
xargs -P4 -I{} bash -c 'echo "Procesando: {}"; clang-tidy {} -p '"$BUILD_DIR"' --fix'
|
||||||
|
|
||||||
|
echo "=== Completado: $dir ==="
|
||||||
|
echo
|
||||||
|
}
|
||||||
|
|
||||||
|
# Procesar cada directorio en la lista
|
||||||
|
for path in "${PATHS[@]}"; do
|
||||||
|
process_directory "$path"
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "¡Proceso completado para todos los directorios!"
|
||||||
150
release/create_icons.py
Normal file
@@ -0,0 +1,150 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import shutil
|
||||||
|
import subprocess
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
|
def check_dependencies():
|
||||||
|
"""Verifica que ImageMagick esté instalado"""
|
||||||
|
try:
|
||||||
|
subprocess.run(['magick', '--version'], capture_output=True, check=True)
|
||||||
|
except (subprocess.CalledProcessError, FileNotFoundError):
|
||||||
|
print("Error: ImageMagick no está instalado o no se encuentra en el PATH")
|
||||||
|
print("Instala ImageMagick desde: https://imagemagick.org/script/download.php")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
# Verificar iconutil solo en macOS
|
||||||
|
if sys.platform == 'darwin':
|
||||||
|
try:
|
||||||
|
# iconutil no tiene --version, mejor usar which o probar con -h
|
||||||
|
result = subprocess.run(['which', 'iconutil'], capture_output=True, check=True)
|
||||||
|
if result.returncode == 0:
|
||||||
|
print("✓ iconutil disponible - se crearán archivos .ico e .icns")
|
||||||
|
except (subprocess.CalledProcessError, FileNotFoundError):
|
||||||
|
print("Error: iconutil no está disponible (solo funciona en macOS)")
|
||||||
|
print("Solo se creará el archivo .ico")
|
||||||
|
else:
|
||||||
|
print("ℹ️ Sistema no-macOS detectado - solo se creará archivo .ico")
|
||||||
|
|
||||||
|
|
||||||
|
def create_icons(input_file):
|
||||||
|
"""Crea archivos .icns e .ico a partir de un PNG"""
|
||||||
|
|
||||||
|
# Verificar que el archivo existe
|
||||||
|
if not os.path.isfile(input_file):
|
||||||
|
print(f"Error: El archivo {input_file} no existe.")
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Obtener información del archivo
|
||||||
|
file_path = Path(input_file)
|
||||||
|
file_dir = file_path.parent
|
||||||
|
file_name = file_path.stem # Nombre sin extensión
|
||||||
|
file_extension = file_path.suffix
|
||||||
|
|
||||||
|
if file_extension.lower() not in ['.png', '.jpg', '.jpeg', '.bmp', '.tiff']:
|
||||||
|
print(f"Advertencia: {file_extension} puede no ser compatible. Se recomienda usar PNG.")
|
||||||
|
|
||||||
|
# Crear archivo .ico usando el método simplificado
|
||||||
|
ico_output = file_dir / f"{file_name}.ico"
|
||||||
|
try:
|
||||||
|
print(f"Creando {ico_output}...")
|
||||||
|
subprocess.run([
|
||||||
|
'magick', str(input_file),
|
||||||
|
'-define', 'icon:auto-resize=256,128,64,48,32,16',
|
||||||
|
str(ico_output)
|
||||||
|
], check=True)
|
||||||
|
print(f"✓ Archivo .ico creado: {ico_output}")
|
||||||
|
except subprocess.CalledProcessError as e:
|
||||||
|
print(f"Error creando archivo .ico: {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Crear archivo .icns (solo en macOS)
|
||||||
|
if sys.platform == 'darwin':
|
||||||
|
try:
|
||||||
|
# Crear carpeta temporal para iconset
|
||||||
|
temp_folder = file_dir / "icon.iconset"
|
||||||
|
|
||||||
|
# Eliminar carpeta temporal si existe
|
||||||
|
if temp_folder.exists():
|
||||||
|
shutil.rmtree(temp_folder)
|
||||||
|
|
||||||
|
# Crear carpeta temporal
|
||||||
|
temp_folder.mkdir(parents=True)
|
||||||
|
|
||||||
|
# Definir los tamaños y nombres de archivo para .icns
|
||||||
|
icon_sizes = [
|
||||||
|
(16, "icon_16x16.png"),
|
||||||
|
(32, "icon_16x16@2x.png"),
|
||||||
|
(32, "icon_32x32.png"),
|
||||||
|
(64, "icon_32x32@2x.png"),
|
||||||
|
(128, "icon_128x128.png"),
|
||||||
|
(256, "icon_128x128@2x.png"),
|
||||||
|
(256, "icon_256x256.png"),
|
||||||
|
(512, "icon_256x256@2x.png"),
|
||||||
|
(512, "icon_512x512.png"),
|
||||||
|
(1024, "icon_512x512@2x.png")
|
||||||
|
]
|
||||||
|
|
||||||
|
print("Generando imágenes para .icns...")
|
||||||
|
# Crear cada tamaño de imagen
|
||||||
|
for size, output_name in icon_sizes:
|
||||||
|
output_path = temp_folder / output_name
|
||||||
|
subprocess.run([
|
||||||
|
'magick', str(input_file),
|
||||||
|
'-resize', f'{size}x{size}',
|
||||||
|
str(output_path)
|
||||||
|
], check=True)
|
||||||
|
|
||||||
|
# Crear archivo .icns usando iconutil
|
||||||
|
icns_output = file_dir / f"{file_name}.icns"
|
||||||
|
print(f"Creando {icns_output}...")
|
||||||
|
subprocess.run([
|
||||||
|
'iconutil', '-c', 'icns',
|
||||||
|
str(temp_folder),
|
||||||
|
'-o', str(icns_output)
|
||||||
|
], check=True)
|
||||||
|
|
||||||
|
# Limpiar carpeta temporal
|
||||||
|
if temp_folder.exists():
|
||||||
|
shutil.rmtree(temp_folder)
|
||||||
|
|
||||||
|
print(f"✓ Archivo .icns creado: {icns_output}")
|
||||||
|
|
||||||
|
except subprocess.CalledProcessError as e:
|
||||||
|
print(f"Error creando archivo .icns: {e}")
|
||||||
|
# Limpiar carpeta temporal en caso de error
|
||||||
|
if temp_folder.exists():
|
||||||
|
shutil.rmtree(temp_folder)
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
print("ℹ️ Archivo .icns no creado (solo disponible en macOS)")
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"""Función principal"""
|
||||||
|
# Verificar argumentos
|
||||||
|
if len(sys.argv) != 2:
|
||||||
|
print(f"Uso: {sys.argv[0]} ARCHIVO")
|
||||||
|
print("Ejemplo: python3 create_icons.py imagen.png")
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
input_file = sys.argv[1]
|
||||||
|
|
||||||
|
# Verificar dependencias
|
||||||
|
check_dependencies()
|
||||||
|
|
||||||
|
# Crear iconos
|
||||||
|
if create_icons(input_file):
|
||||||
|
print("\n✅ Proceso completado exitosamente")
|
||||||
|
else:
|
||||||
|
print("\n❌ El proceso falló")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
BIN
release/icon.ico
|
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 128 KiB |
BIN
release/icon.png
|
Before Width: | Height: | Size: 134 KiB After Width: | Height: | Size: 438 KiB |
@@ -9,22 +9,44 @@
|
|||||||
#include <stdexcept> // Para runtime_error
|
#include <stdexcept> // Para runtime_error
|
||||||
#include <utility> // Para pair
|
#include <utility> // Para pair
|
||||||
|
|
||||||
#include "texture.h" // Para Texture
|
#include "resource_helper.h" // Para ResourceHelper
|
||||||
#include "utils.h" // Para printWithDots
|
#include "texture.h" // Para Texture
|
||||||
|
#include "utils.h" // Para printWithDots
|
||||||
|
|
||||||
// Carga las animaciones en un vector(Animations) desde un fichero
|
// Carga las animaciones en un vector(Animations) desde un fichero
|
||||||
auto loadAnimationsFromFile(const std::string& file_path) -> AnimationsFileBuffer {
|
auto loadAnimationsFromFile(const std::string& file_path) -> AnimationsFileBuffer {
|
||||||
std::ifstream file(file_path);
|
// Intentar cargar desde ResourceHelper primero
|
||||||
if (!file) {
|
auto resource_data = ResourceHelper::loadFile(file_path);
|
||||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error: Fichero no encontrado %s", file_path.c_str());
|
std::istringstream stream;
|
||||||
throw std::runtime_error("Fichero no encontrado: " + file_path);
|
bool using_resource_data = false;
|
||||||
|
|
||||||
|
if (!resource_data.empty()) {
|
||||||
|
std::string content(resource_data.begin(), resource_data.end());
|
||||||
|
stream.str(content);
|
||||||
|
using_resource_data = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fallback a archivo directo
|
||||||
|
std::ifstream file;
|
||||||
|
if (!using_resource_data) {
|
||||||
|
file.open(file_path);
|
||||||
|
if (!file) {
|
||||||
|
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error: Fichero no encontrado %s", file_path.c_str());
|
||||||
|
throw std::runtime_error("Fichero no encontrado: " + file_path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::istream& input_stream = using_resource_data ? stream : static_cast<std::istream&>(file);
|
||||||
|
|
||||||
printWithDots("Animation : ", file_path.substr(file_path.find_last_of("\\/") + 1), "[ LOADED ]");
|
printWithDots("Animation : ", file_path.substr(file_path.find_last_of("\\/") + 1), "[ LOADED ]");
|
||||||
|
|
||||||
std::vector<std::string> buffer;
|
std::vector<std::string> buffer;
|
||||||
std::string line;
|
std::string line;
|
||||||
while (std::getline(file, line)) {
|
while (std::getline(input_stream, line)) {
|
||||||
|
// Eliminar caracteres de retorno de carro (\r) al final de la línea
|
||||||
|
if (!line.empty() && line.back() == '\r') {
|
||||||
|
line.pop_back();
|
||||||
|
}
|
||||||
if (!line.empty()) {
|
if (!line.empty()) {
|
||||||
buffer.push_back(line);
|
buffer.push_back(line);
|
||||||
}
|
}
|
||||||
@@ -35,7 +57,7 @@ auto loadAnimationsFromFile(const std::string& file_path) -> AnimationsFileBuffe
|
|||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
AnimatedSprite::AnimatedSprite(std::shared_ptr<Texture> texture, const std::string& file_path)
|
AnimatedSprite::AnimatedSprite(std::shared_ptr<Texture> texture, const std::string& file_path)
|
||||||
: MovingSprite(texture) {
|
: MovingSprite(std::move(texture)) {
|
||||||
// Carga las animaciones
|
// Carga las animaciones
|
||||||
if (!file_path.empty()) {
|
if (!file_path.empty()) {
|
||||||
auto buffer = loadAnimationsFromFile(file_path);
|
auto buffer = loadAnimationsFromFile(file_path);
|
||||||
@@ -45,14 +67,14 @@ AnimatedSprite::AnimatedSprite(std::shared_ptr<Texture> texture, const std::stri
|
|||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
AnimatedSprite::AnimatedSprite(std::shared_ptr<Texture> texture, const AnimationsFileBuffer& animations)
|
AnimatedSprite::AnimatedSprite(std::shared_ptr<Texture> texture, const AnimationsFileBuffer& animations)
|
||||||
: MovingSprite(texture) {
|
: MovingSprite(std::move(texture)) {
|
||||||
if (!animations.empty()) {
|
if (!animations.empty()) {
|
||||||
loadFromAnimationsFileBuffer(animations);
|
loadFromAnimationsFileBuffer(animations);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Obtiene el índice de la animación a partir del nombre
|
// Obtiene el índice de la animación a partir del nombre
|
||||||
auto AnimatedSprite::getIndex(const std::string& name) -> int {
|
auto AnimatedSprite::getAnimationIndex(const std::string& name) -> int {
|
||||||
auto iterator = animation_indices_.find(name);
|
auto iterator = animation_indices_.find(name);
|
||||||
if (iterator != animation_indices_.end()) {
|
if (iterator != animation_indices_.end()) {
|
||||||
// Si se encuentra la animación en el mapa, devuelve su índice
|
// Si se encuentra la animación en el mapa, devuelve su índice
|
||||||
@@ -64,33 +86,33 @@ auto AnimatedSprite::getIndex(const std::string& name) -> int {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calcula el frame correspondiente a la animación
|
// Calcula el frame correspondiente a la animación (time-based)
|
||||||
void AnimatedSprite::animate() {
|
void AnimatedSprite::animate(float deltaTime) {
|
||||||
if (animations_[current_animation_].speed == 0 || animations_[current_animation_].paused) {
|
if (animations_[current_animation_].speed == 0 || animations_[current_animation_].paused) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calcula el frame actual a partir del contador
|
// Acumular tiempo transcurrido
|
||||||
animations_[current_animation_].current_frame = animations_[current_animation_].counter / animations_[current_animation_].speed;
|
animations_[current_animation_].time_accumulator += deltaTime;
|
||||||
|
|
||||||
// Si alcanza el final de la animación, reinicia el contador de la animación
|
// Verificar si es momento de cambiar frame
|
||||||
// en función de la variable loop y coloca el nuevo frame
|
if (animations_[current_animation_].time_accumulator >= animations_[current_animation_].speed) {
|
||||||
if (animations_[current_animation_].current_frame >= animations_[current_animation_].frames.size()) {
|
animations_[current_animation_].time_accumulator -= animations_[current_animation_].speed;
|
||||||
if (animations_[current_animation_].loop == -1) { // Si no hay loop, deja el último frame
|
animations_[current_animation_].current_frame++;
|
||||||
animations_[current_animation_].current_frame = animations_[current_animation_].frames.size();
|
|
||||||
animations_[current_animation_].completed = true;
|
// Si alcanza el final de la animación
|
||||||
} else { // Si hay loop, vuelve al frame indicado
|
if (animations_[current_animation_].current_frame >= animations_[current_animation_].frames.size()) {
|
||||||
animations_[current_animation_].counter = 0;
|
if (animations_[current_animation_].loop == -1) { // Si no hay loop, deja el último frame
|
||||||
animations_[current_animation_].current_frame = animations_[current_animation_].loop;
|
animations_[current_animation_].current_frame = animations_[current_animation_].frames.size() - 1;
|
||||||
|
animations_[current_animation_].completed = true;
|
||||||
|
} else { // Si hay loop, vuelve al frame indicado
|
||||||
|
animations_[current_animation_].time_accumulator = 0.0f;
|
||||||
|
animations_[current_animation_].current_frame = animations_[current_animation_].loop;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
// En caso contrario
|
// Actualizar el sprite clip
|
||||||
else {
|
|
||||||
// Escoge el frame correspondiente de la animación
|
|
||||||
updateSpriteClip();
|
updateSpriteClip();
|
||||||
|
|
||||||
// Incrementa el contador de la animacion
|
|
||||||
animations_[current_animation_].counter++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,17 +123,17 @@ auto AnimatedSprite::animationIsCompleted() -> bool {
|
|||||||
|
|
||||||
// Establece la animacion actual
|
// Establece la animacion actual
|
||||||
void AnimatedSprite::setCurrentAnimation(const std::string& name, bool reset) {
|
void AnimatedSprite::setCurrentAnimation(const std::string& name, bool reset) {
|
||||||
const auto NEW_ANIMATION = getIndex(name);
|
const auto NEW_ANIMATION = getAnimationIndex(name);
|
||||||
if (current_animation_ != NEW_ANIMATION) {
|
if (current_animation_ != NEW_ANIMATION) {
|
||||||
const auto OLD_ANIMATION = current_animation_;
|
const auto OLD_ANIMATION = current_animation_;
|
||||||
current_animation_ = NEW_ANIMATION;
|
current_animation_ = NEW_ANIMATION;
|
||||||
if (reset) {
|
if (reset) {
|
||||||
animations_[current_animation_].current_frame = 0;
|
animations_[current_animation_].current_frame = 0;
|
||||||
animations_[current_animation_].counter = 0;
|
animations_[current_animation_].time_accumulator = 0.0f;
|
||||||
animations_[current_animation_].completed = false;
|
animations_[current_animation_].completed = false;
|
||||||
} else {
|
} else {
|
||||||
animations_[current_animation_].current_frame = std::min(animations_[OLD_ANIMATION].current_frame, animations_[current_animation_].frames.size() - 1);
|
animations_[current_animation_].current_frame = std::min(animations_[OLD_ANIMATION].current_frame, animations_[current_animation_].frames.size() - 1);
|
||||||
animations_[current_animation_].counter = animations_[OLD_ANIMATION].counter;
|
animations_[current_animation_].time_accumulator = animations_[OLD_ANIMATION].time_accumulator;
|
||||||
animations_[current_animation_].completed = animations_[OLD_ANIMATION].completed;
|
animations_[current_animation_].completed = animations_[OLD_ANIMATION].completed;
|
||||||
}
|
}
|
||||||
updateSpriteClip();
|
updateSpriteClip();
|
||||||
@@ -126,27 +148,27 @@ void AnimatedSprite::setCurrentAnimation(int index, bool reset) {
|
|||||||
current_animation_ = NEW_ANIMATION;
|
current_animation_ = NEW_ANIMATION;
|
||||||
if (reset) {
|
if (reset) {
|
||||||
animations_[current_animation_].current_frame = 0;
|
animations_[current_animation_].current_frame = 0;
|
||||||
animations_[current_animation_].counter = 0;
|
animations_[current_animation_].time_accumulator = 0.0f;
|
||||||
animations_[current_animation_].completed = false;
|
animations_[current_animation_].completed = false;
|
||||||
} else {
|
} else {
|
||||||
animations_[current_animation_].current_frame = std::min(animations_[OLD_ANIMATION].current_frame, animations_[current_animation_].frames.size());
|
animations_[current_animation_].current_frame = std::min(animations_[OLD_ANIMATION].current_frame, animations_[current_animation_].frames.size());
|
||||||
animations_[current_animation_].counter = animations_[OLD_ANIMATION].counter;
|
animations_[current_animation_].time_accumulator = animations_[OLD_ANIMATION].time_accumulator;
|
||||||
animations_[current_animation_].completed = animations_[OLD_ANIMATION].completed;
|
animations_[current_animation_].completed = animations_[OLD_ANIMATION].completed;
|
||||||
}
|
}
|
||||||
updateSpriteClip();
|
updateSpriteClip();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Actualiza las variables del objeto
|
// Actualiza las variables del objeto (time-based)
|
||||||
void AnimatedSprite::update() {
|
void AnimatedSprite::update(float deltaTime) {
|
||||||
animate();
|
animate(deltaTime);
|
||||||
MovingSprite::update();
|
MovingSprite::update(deltaTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reinicia la animación
|
// Reinicia la animación
|
||||||
void AnimatedSprite::resetAnimation() {
|
void AnimatedSprite::resetAnimation() {
|
||||||
animations_[current_animation_].current_frame = 0;
|
animations_[current_animation_].current_frame = 0;
|
||||||
animations_[current_animation_].counter = 0;
|
animations_[current_animation_].time_accumulator = 0.0f;
|
||||||
animations_[current_animation_].completed = false;
|
animations_[current_animation_].completed = false;
|
||||||
animations_[current_animation_].paused = false;
|
animations_[current_animation_].paused = false;
|
||||||
updateSpriteClip();
|
updateSpriteClip();
|
||||||
@@ -172,11 +194,17 @@ void AnimatedSprite::loadFromAnimationsFileBuffer(const AnimationsFileBuffer& so
|
|||||||
// Pone un valor por defecto
|
// Pone un valor por defecto
|
||||||
setWidth(config.frame_width);
|
setWidth(config.frame_width);
|
||||||
setHeight(config.frame_height);
|
setHeight(config.frame_height);
|
||||||
|
|
||||||
|
// Establece el primer frame inmediatamente si hay animaciones
|
||||||
|
if (!animations_.empty()) {
|
||||||
|
current_animation_ = 0;
|
||||||
|
updateSpriteClip();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Procesa una línea de configuración
|
// Procesa una línea de configuración
|
||||||
void AnimatedSprite::processConfigLine(const std::string& line, AnimationConfig& config) {
|
void AnimatedSprite::processConfigLine(const std::string& line, AnimationConfig& config) {
|
||||||
size_t pos = line.find("=");
|
size_t pos = line.find('=');
|
||||||
if (pos == std::string::npos) {
|
if (pos == std::string::npos) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -230,7 +258,7 @@ auto AnimatedSprite::processAnimationBlock(const AnimationsFileBuffer& source, s
|
|||||||
|
|
||||||
// Procesa un parámetro individual de animación
|
// Procesa un parámetro individual de animación
|
||||||
void AnimatedSprite::processAnimationParameter(const std::string& line, Animation& animation, const AnimationConfig& config) {
|
void AnimatedSprite::processAnimationParameter(const std::string& line, Animation& animation, const AnimationConfig& config) {
|
||||||
size_t pos = line.find("=");
|
size_t pos = line.find('=');
|
||||||
if (pos == std::string::npos) {
|
if (pos == std::string::npos) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -241,7 +269,7 @@ void AnimatedSprite::processAnimationParameter(const std::string& line, Animatio
|
|||||||
if (key == "name") {
|
if (key == "name") {
|
||||||
animation.name = value;
|
animation.name = value;
|
||||||
} else if (key == "speed") {
|
} else if (key == "speed") {
|
||||||
animation.speed = std::stoi(value);
|
animation.speed = std::stof(value);
|
||||||
} else if (key == "loop") {
|
} else if (key == "loop") {
|
||||||
animation.loop = std::stoi(value);
|
animation.loop = std::stoi(value);
|
||||||
} else if (key == "frames") {
|
} else if (key == "frames") {
|
||||||
@@ -268,7 +296,7 @@ void AnimatedSprite::parseFramesParameter(const std::string& frames_str, Animati
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Establece la velocidad de la animación
|
// Establece la velocidad de la animación
|
||||||
void AnimatedSprite::setAnimationSpeed(size_t value) {
|
void AnimatedSprite::setAnimationSpeed(float value) {
|
||||||
animations_[current_animation_].speed = value;
|
animations_[current_animation_].speed = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,24 +7,25 @@
|
|||||||
#include <memory> // Para allocator, shared_ptr
|
#include <memory> // Para allocator, shared_ptr
|
||||||
#include <string> // Para string, hash
|
#include <string> // Para string, hash
|
||||||
#include <unordered_map> // Para unordered_map
|
#include <unordered_map> // Para unordered_map
|
||||||
#include <vector> // Para vector
|
#include <utility>
|
||||||
|
#include <vector> // Para vector
|
||||||
|
|
||||||
#include "moving_sprite.h" // Para MovingSprite
|
#include "moving_sprite.h" // Para MovingSprite
|
||||||
|
|
||||||
// Declaración adelantada
|
// Declaración adelantada
|
||||||
class Texture;
|
class Texture;
|
||||||
|
|
||||||
// Estructura de Animación
|
// --- Estructuras ---
|
||||||
struct Animation {
|
struct Animation {
|
||||||
static constexpr int DEFAULT_SPEED = 5;
|
static constexpr float DEFAULT_SPEED = 80.0F;
|
||||||
|
|
||||||
std::string name; // Nombre de la animación
|
std::string name; // Nombre de la animación
|
||||||
std::vector<SDL_FRect> frames; // Frames que componen la animación
|
std::vector<SDL_FRect> frames; // Frames que componen la animación
|
||||||
int speed{DEFAULT_SPEED}; // Velocidad de reproducción
|
float speed{DEFAULT_SPEED}; // Velocidad de reproducción (ms entre frames)
|
||||||
int loop{0}; // Frame de vuelta al terminar (-1 para no repetir)
|
int loop{0}; // Frame de vuelta al terminar (-1 para no repetir)
|
||||||
bool completed{false}; // Indica si la animación ha finalizado
|
bool completed{false}; // Indica si la animación ha finalizado
|
||||||
size_t current_frame{0}; // Frame actual en reproducción
|
size_t current_frame{0}; // Frame actual en reproducción
|
||||||
int counter{0}; // Contador para la animación
|
float time_accumulator{0.0f}; // Acumulador de tiempo para animaciones time-based
|
||||||
bool paused{false}; // La animación no avanza
|
bool paused{false}; // La animación no avanza
|
||||||
|
|
||||||
Animation() = default;
|
Animation() = default;
|
||||||
@@ -37,47 +38,47 @@ struct AnimationConfig {
|
|||||||
int max_tiles = 1;
|
int max_tiles = 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Alias de tipo para buffer de animaciones
|
// --- Tipos ---
|
||||||
using AnimationsFileBuffer = std::vector<std::string>;
|
using AnimationsFileBuffer = std::vector<std::string>; // Buffer de animaciones
|
||||||
|
|
||||||
// Carga las animaciones desde un fichero en un vector de strings
|
// --- Funciones ---
|
||||||
auto loadAnimationsFromFile(const std::string& file_path) -> AnimationsFileBuffer;
|
auto loadAnimationsFromFile(const std::string& file_path) -> AnimationsFileBuffer; // Carga las animaciones desde un fichero
|
||||||
|
|
||||||
// Clase AnimatedSprite: Sprite animado que hereda de MovingSprite
|
// --- Clase AnimatedSprite: sprite animado que hereda de MovingSprite ---
|
||||||
class AnimatedSprite : public MovingSprite {
|
class AnimatedSprite : public MovingSprite {
|
||||||
public:
|
public:
|
||||||
// --- Constructores y destructor ---
|
// --- Constructores y destructor ---
|
||||||
AnimatedSprite(std::shared_ptr<Texture> texture, const std::string& file_path);
|
AnimatedSprite(std::shared_ptr<Texture> texture, const std::string& file_path);
|
||||||
AnimatedSprite(std::shared_ptr<Texture> texture, const AnimationsFileBuffer& animations);
|
AnimatedSprite(std::shared_ptr<Texture> texture, const AnimationsFileBuffer& animations);
|
||||||
explicit AnimatedSprite(std::shared_ptr<Texture> texture) : MovingSprite(texture) {}
|
explicit AnimatedSprite(std::shared_ptr<Texture> texture)
|
||||||
|
: MovingSprite(std::move(texture)) {}
|
||||||
~AnimatedSprite() override = default;
|
~AnimatedSprite() override = default;
|
||||||
|
|
||||||
// --- Métodos principales ---
|
// --- Métodos principales ---
|
||||||
void update() override; // Actualiza la animación
|
void update(float deltaTime) override; // Actualiza la animación (time-based)
|
||||||
|
|
||||||
// --- Control de animaciones ---
|
// --- Control de animaciones ---
|
||||||
void setCurrentAnimation(const std::string& name = "default", bool reset = true); // Establece la animación por nombre
|
void setCurrentAnimation(const std::string& name = "default", bool reset = true); // Establece la animación por nombre
|
||||||
void setCurrentAnimation(int index = 0, bool reset = true); // Establece la animación por índice
|
void setCurrentAnimation(int index = 0, bool reset = true); // Establece la animación por índice
|
||||||
void resetAnimation(); // Reinicia la animación actual
|
void resetAnimation(); // Reinicia la animación actual
|
||||||
void setAnimationSpeed(size_t value); // Establece la velocidad de la animación
|
void setAnimationSpeed(float value); // Establece la velocidad de la animación
|
||||||
auto getAnimationSpeed() const -> size_t { return animations_[current_animation_].speed; } // Obtiene la velocidad de la animación actual
|
auto getAnimationSpeed() const -> float { return animations_[current_animation_].speed; } // Obtiene la velocidad de la animación actual
|
||||||
void animtionPause() { animations_[current_animation_].paused = true; } // Detiene la animación
|
void animtionPause() { animations_[current_animation_].paused = true; } // Detiene la animación
|
||||||
void animationResume() { animations_[current_animation_].paused = false; } // Reanuda la animación
|
void animationResume() { animations_[current_animation_].paused = false; } // Reanuda la animación
|
||||||
|
auto getCurrentAnimationFrame() const -> size_t { return animations_[current_animation_].current_frame; } // Obtiene el numero de frame de la animación actual
|
||||||
|
|
||||||
// --- Consultas ---
|
// --- Consultas ---
|
||||||
auto animationIsCompleted() -> bool; // Comprueba si la animación ha terminado
|
auto animationIsCompleted() -> bool; // Comprueba si la animación ha terminado
|
||||||
auto getIndex(const std::string& name) -> int; // Obtiene el índice de una animación por nombre
|
auto getAnimationIndex(const std::string& name) -> int; // Obtiene el índice de una animación por nombre
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// --- Datos de animación ---
|
// --- Variables de estado ---
|
||||||
std::vector<Animation> animations_; // Vector de animaciones disponibles
|
std::vector<Animation> animations_; // Vector de animaciones disponibles
|
||||||
int current_animation_ = 0; // Índice de la animación activa
|
std::unordered_map<std::string, int> animation_indices_; // Mapa para búsqueda rápida por nombre
|
||||||
|
int current_animation_ = 0; // Índice de la animación activa
|
||||||
// --- Mapa para búsqueda rápida de animaciones por nombre ---
|
|
||||||
std::unordered_map<std::string, int> animation_indices_;
|
|
||||||
|
|
||||||
// --- Métodos internos ---
|
// --- Métodos internos ---
|
||||||
void animate(); // Calcula el frame correspondiente a la animación
|
void animate(float deltaTime); // Calcula el frame correspondiente a la animación (time-based)
|
||||||
void loadFromAnimationsFileBuffer(const AnimationsFileBuffer& source); // Carga la animación desde un vector de cadenas
|
void loadFromAnimationsFileBuffer(const AnimationsFileBuffer& source); // Carga la animación desde un vector de cadenas
|
||||||
void processConfigLine(const std::string& line, AnimationConfig& config); // Procesa una línea de configuración
|
void processConfigLine(const std::string& line, AnimationConfig& config); // Procesa una línea de configuración
|
||||||
void updateFrameCalculations(AnimationConfig& config); // Actualiza los cálculos basados en las dimensiones del frame
|
void updateFrameCalculations(AnimationConfig& config); // Actualiza los cálculos basados en las dimensiones del frame
|
||||||
|
|||||||
@@ -2,13 +2,16 @@
|
|||||||
|
|
||||||
#include <SDL3/SDL.h> // Para SDL_LogCategory, SDL_LogInfo, SDL_LogError, SDL_LogWarn
|
#include <SDL3/SDL.h> // Para SDL_LogCategory, SDL_LogInfo, SDL_LogError, SDL_LogWarn
|
||||||
|
|
||||||
#include <cstddef> // Para size_t
|
#include <algorithm> // Para std::sort
|
||||||
#include <exception> // Para exception
|
#include <cstddef> // Para size_t
|
||||||
#include <fstream> // Para basic_istream, basic_ifstream, ifstream, istringstream
|
#include <exception> // Para exception
|
||||||
#include <sstream> // Para basic_istringstream
|
#include <filesystem> // Para std::filesystem
|
||||||
#include <stdexcept> // Para runtime_error
|
#include <fstream> // Para basic_istream, basic_ifstream, ifstream, istringstream
|
||||||
|
#include <sstream> // Para basic_istringstream
|
||||||
|
#include <stdexcept> // Para runtime_error
|
||||||
|
|
||||||
#include "utils.h" // Para getFileName
|
#include "resource_helper.h" // Para ResourceHelper
|
||||||
|
#include "utils.h" // Para getFileName
|
||||||
|
|
||||||
// Singleton
|
// Singleton
|
||||||
Asset *Asset::instance = nullptr;
|
Asset *Asset::instance = nullptr;
|
||||||
@@ -92,7 +95,7 @@ void Asset::loadFromFile(const std::string &config_file_path, const std::string
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
std::string type_str = parts[0];
|
const std::string &type_str = parts[0];
|
||||||
std::string path = parts[1];
|
std::string path = parts[1];
|
||||||
|
|
||||||
// Valores por defecto
|
// Valores por defecto
|
||||||
@@ -139,6 +142,17 @@ auto Asset::get(const std::string &filename) const -> std::string {
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Carga datos del archivo usando ResourceHelper
|
||||||
|
auto Asset::loadData(const std::string &filename) const -> std::vector<uint8_t> {
|
||||||
|
auto it = file_list_.find(filename);
|
||||||
|
if (it != file_list_.end()) {
|
||||||
|
return ResourceHelper::loadFile(it->second.file);
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "Warning: file %s not found for data loading", filename.c_str());
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
// Verifica si un recurso existe
|
// Verifica si un recurso existe
|
||||||
auto Asset::exists(const std::string &filename) const -> bool {
|
auto Asset::exists(const std::string &filename) const -> bool {
|
||||||
return file_list_.find(filename) != file_list_.end();
|
return file_list_.find(filename) != file_list_.end();
|
||||||
@@ -193,18 +207,28 @@ auto Asset::check() const -> bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Comprueba que existe un fichero
|
// Comprueba que existe un fichero
|
||||||
auto Asset::checkFile(const std::string &path) -> bool {
|
auto Asset::checkFile(const std::string &path) const -> bool {
|
||||||
std::ifstream file(path);
|
// Construir ruta del pack usando executable_path_
|
||||||
bool success = file.good();
|
std::string pack_path = executable_path_ + "resources.pack";
|
||||||
file.close();
|
bool pack_exists = std::filesystem::exists(pack_path);
|
||||||
|
|
||||||
if (!success) {
|
if (pack_exists) {
|
||||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
// MODO PACK: Usar ResourceHelper (igual que la carga real)
|
||||||
"Checking file: %s [ ERROR ]",
|
auto data = ResourceHelper::loadFile(path);
|
||||||
getFileName(path).c_str());
|
return !data.empty();
|
||||||
|
} else {
|
||||||
|
// MODO FILESYSTEM: Verificación directa (modo desarrollo)
|
||||||
|
std::ifstream file(path);
|
||||||
|
bool success = file.good();
|
||||||
|
file.close();
|
||||||
|
|
||||||
|
if (!success) {
|
||||||
|
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
|
"Error: Could not open file: %s", path.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
return success;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parsea string a Type
|
// Parsea string a Type
|
||||||
@@ -276,6 +300,9 @@ auto Asset::getListByType(Type type) const -> std::vector<std::string> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ordenar alfabéticamente para garantizar orden consistente
|
||||||
|
std::sort(list.begin(), list.end());
|
||||||
|
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,25 +1,26 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <string>
|
#include <cstdint> // Para uint8_t
|
||||||
#include <unordered_map>
|
#include <string> // Para string
|
||||||
#include <utility>
|
#include <unordered_map> // Para unordered_map
|
||||||
#include <vector>
|
#include <utility> // Para move
|
||||||
|
#include <vector> // Para vector
|
||||||
|
|
||||||
// Clase Asset: gestor optimizado de recursos (singleton)
|
// --- Clase Asset: gestor optimizado de recursos (singleton) ---
|
||||||
class Asset {
|
class Asset {
|
||||||
public:
|
public:
|
||||||
// Tipos de recursos
|
// --- Enums ---
|
||||||
enum class Type : int {
|
enum class Type : int {
|
||||||
BITMAP,
|
BITMAP, // Imágenes
|
||||||
MUSIC,
|
MUSIC, // Música
|
||||||
SOUND,
|
SOUND, // Sonidos
|
||||||
FONT,
|
FONT, // Fuentes
|
||||||
LANG,
|
LANG, // Idiomas
|
||||||
DATA,
|
DATA, // Datos
|
||||||
DEMODATA,
|
DEMODATA, // Datos de demo
|
||||||
ANIMATION,
|
ANIMATION, // Animaciones
|
||||||
PALETTE,
|
PALETTE, // Paletas
|
||||||
SIZE,
|
SIZE, // Tamaño
|
||||||
};
|
};
|
||||||
|
|
||||||
// --- Métodos de singleton ---
|
// --- Métodos de singleton ---
|
||||||
@@ -33,37 +34,41 @@ class Asset {
|
|||||||
void add(const std::string &file_path, Type type, bool required = true, bool absolute = false);
|
void add(const std::string &file_path, Type type, bool required = true, bool absolute = false);
|
||||||
void loadFromFile(const std::string &config_file_path, const std::string &prefix = "", const std::string &system_folder = ""); // Con soporte para variables
|
void loadFromFile(const std::string &config_file_path, const std::string &prefix = "", const std::string &system_folder = ""); // Con soporte para variables
|
||||||
[[nodiscard]] auto get(const std::string &filename) const -> std::string; // Mantener nombre original
|
[[nodiscard]] auto get(const std::string &filename) const -> std::string; // Mantener nombre original
|
||||||
|
[[nodiscard]] auto loadData(const std::string &filename) const -> std::vector<uint8_t>; // Carga datos del archivo
|
||||||
[[nodiscard]] auto check() const -> bool;
|
[[nodiscard]] auto check() const -> bool;
|
||||||
[[nodiscard]] auto getListByType(Type type) const -> std::vector<std::string>;
|
[[nodiscard]] auto getListByType(Type type) const -> std::vector<std::string>;
|
||||||
[[nodiscard]] auto exists(const std::string &filename) const -> bool; // Nueva función para verificar existencia
|
[[nodiscard]] auto exists(const std::string &filename) const -> bool; // Nueva función para verificar existencia
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// --- Estructura interna para almacenar información de cada recurso ---
|
// --- Estructuras privadas ---
|
||||||
struct Item {
|
struct Item {
|
||||||
std::string file; // Ruta completa del archivo (mantener nombre original)
|
std::string file; // Ruta completa del archivo
|
||||||
Type type; // Tipo de recurso
|
Type type; // Tipo de recurso
|
||||||
bool required; // Indica si el archivo es obligatorio
|
bool required; // Indica si el archivo es obligatorio
|
||||||
|
|
||||||
Item(std::string path, Type asset_type, bool is_required)
|
Item(std::string path, Type asset_type, bool is_required)
|
||||||
: file(std::move(path)), type(asset_type), required(is_required) {}
|
: file(std::move(path)),
|
||||||
|
type(asset_type),
|
||||||
|
required(is_required) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
// --- Variables internas ---
|
// --- Variables internas ---
|
||||||
std::unordered_map<std::string, Item> file_list_; // Mapa para búsqueda O(1) (mantener nombre original)
|
std::unordered_map<std::string, Item> file_list_; // Mapa para búsqueda O(1)
|
||||||
std::string executable_path_; // Ruta del ejecutable
|
std::string executable_path_; // Ruta del ejecutable
|
||||||
|
|
||||||
// --- Métodos internos ---
|
// --- Métodos internos ---
|
||||||
[[nodiscard]] static auto checkFile(const std::string &path) -> bool;
|
[[nodiscard]] auto checkFile(const std::string &path) const -> bool; // Verifica si un archivo existe
|
||||||
[[nodiscard]] static auto getTypeName(Type type) -> std::string;
|
[[nodiscard]] static auto getTypeName(Type type) -> std::string; // Obtiene el nombre del tipo
|
||||||
[[nodiscard]] static auto parseAssetType(const std::string &type_str) -> Type;
|
[[nodiscard]] static auto parseAssetType(const std::string &type_str) -> Type; // Convierte string a tipo
|
||||||
void addToMap(const std::string &file_path, Type type, bool required, bool absolute);
|
void addToMap(const std::string &file_path, Type type, bool required, bool absolute); // Añade archivo al mapa
|
||||||
[[nodiscard]] static auto replaceVariables(const std::string &path, const std::string &prefix, const std::string &system_folder) -> std::string;
|
[[nodiscard]] static auto replaceVariables(const std::string &path, const std::string &prefix, const std::string &system_folder) -> std::string; // Reemplaza variables en la ruta
|
||||||
static auto parseOptions(const std::string &options, bool &required, bool &absolute) -> void;
|
static auto parseOptions(const std::string &options, bool &required, bool &absolute) -> void; // Parsea opciones
|
||||||
|
|
||||||
// --- Patrón Singleton ---
|
// --- Constructores y destructor privados (singleton) ---
|
||||||
explicit Asset(std::string executable_path)
|
explicit Asset(std::string executable_path) // Constructor privado
|
||||||
: executable_path_(std::move(executable_path)) {}
|
: executable_path_(std::move(executable_path)) {}
|
||||||
~Asset() = default;
|
~Asset() = default; // Destructor privado
|
||||||
|
|
||||||
static Asset *instance;
|
// --- Instancia singleton ---
|
||||||
|
static Asset *instance; // Instancia única de Asset
|
||||||
};
|
};
|
||||||
106
source/asset_integrated.cpp
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
#include "asset_integrated.h"
|
||||||
|
|
||||||
|
#include <filesystem>
|
||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
bool AssetIntegrated::resource_pack_enabled_ = false;
|
||||||
|
|
||||||
|
void AssetIntegrated::initWithResourcePack(const std::string &executable_path,
|
||||||
|
const std::string &resource_pack_path) {
|
||||||
|
// Inicializar Asset normal
|
||||||
|
Asset::init(executable_path);
|
||||||
|
|
||||||
|
// Inicializar ResourceLoader
|
||||||
|
auto &loader = ResourceLoader::getInstance();
|
||||||
|
if (loader.initialize(resource_pack_path, true)) {
|
||||||
|
resource_pack_enabled_ = true;
|
||||||
|
std::cout << "Asset system initialized with resource pack: " << resource_pack_path << std::endl;
|
||||||
|
} else {
|
||||||
|
resource_pack_enabled_ = false;
|
||||||
|
std::cout << "Asset system initialized in fallback mode (filesystem)" << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<uint8_t> AssetIntegrated::loadFile(const std::string &filename) {
|
||||||
|
if (shouldUseResourcePack(filename) && resource_pack_enabled_) {
|
||||||
|
// Intentar cargar del pack de recursos
|
||||||
|
auto &loader = ResourceLoader::getInstance();
|
||||||
|
|
||||||
|
// Convertir ruta completa a ruta relativa para el pack
|
||||||
|
std::string relativePath = filename;
|
||||||
|
|
||||||
|
// Si la ruta contiene "data/", extraer la parte relativa
|
||||||
|
size_t dataPos = filename.find("data/");
|
||||||
|
if (dataPos != std::string::npos) {
|
||||||
|
relativePath = filename.substr(dataPos + 5); // +5 para saltar "data/"
|
||||||
|
}
|
||||||
|
|
||||||
|
auto data = loader.loadResource(relativePath);
|
||||||
|
if (!data.empty()) {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback: cargar del filesystem
|
||||||
|
std::ifstream file(filename, std::ios::binary | std::ios::ate);
|
||||||
|
if (!file) {
|
||||||
|
std::cerr << "Error: Could not open file: " << filename << std::endl;
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::streamsize fileSize = file.tellg();
|
||||||
|
file.seekg(0, std::ios::beg);
|
||||||
|
|
||||||
|
std::vector<uint8_t> data(fileSize);
|
||||||
|
if (!file.read(reinterpret_cast<char *>(data.data()), fileSize)) {
|
||||||
|
std::cerr << "Error: Could not read file: " << filename << std::endl;
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AssetIntegrated::fileExists(const std::string &filename) const {
|
||||||
|
if (shouldUseResourcePack(filename) && resource_pack_enabled_) {
|
||||||
|
auto &loader = ResourceLoader::getInstance();
|
||||||
|
|
||||||
|
// Convertir ruta completa a ruta relativa para el pack
|
||||||
|
std::string relativePath = filename;
|
||||||
|
size_t dataPos = filename.find("data/");
|
||||||
|
if (dataPos != std::string::npos) {
|
||||||
|
relativePath = filename.substr(dataPos + 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (loader.resourceExists(relativePath)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verificar en filesystem
|
||||||
|
return std::filesystem::exists(filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string AssetIntegrated::getSystemPath(const std::string &filename) const {
|
||||||
|
// Los archivos de sistema/config siempre van al filesystem
|
||||||
|
return filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AssetIntegrated::shouldUseResourcePack(const std::string &filepath) const {
|
||||||
|
// Los archivos que NO van al pack:
|
||||||
|
// - Archivos de config/ (ahora están fuera de data/)
|
||||||
|
// - Archivos con absolute=true en assets.txt
|
||||||
|
// - Archivos de sistema (${SYSTEM_FOLDER})
|
||||||
|
|
||||||
|
if (filepath.find("/config/") != std::string::npos ||
|
||||||
|
filepath.find("config/") == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filepath.find("/data/") != std::string::npos ||
|
||||||
|
filepath.find("data/") == 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
29
source/asset_integrated.h
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include "asset.h"
|
||||||
|
#include "resource_loader.h"
|
||||||
|
|
||||||
|
// Extensión de Asset que integra ResourceLoader
|
||||||
|
class AssetIntegrated : public Asset {
|
||||||
|
public:
|
||||||
|
// Inicializa Asset con ResourceLoader
|
||||||
|
static void initWithResourcePack(const std::string &executable_path,
|
||||||
|
const std::string &resource_pack_path = "resources.pack");
|
||||||
|
|
||||||
|
// Carga un archivo usando ResourceLoader como primera opción
|
||||||
|
std::vector<uint8_t> loadFile(const std::string &filename);
|
||||||
|
|
||||||
|
// Verifica si un archivo existe (pack o filesystem)
|
||||||
|
bool fileExists(const std::string &filename) const;
|
||||||
|
|
||||||
|
// Obtiene la ruta completa para archivos del sistema/config
|
||||||
|
std::string getSystemPath(const std::string &filename) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static bool resource_pack_enabled_;
|
||||||
|
|
||||||
|
// Determina si un archivo debe cargarse del pack o del filesystem
|
||||||
|
bool shouldUseResourcePack(const std::string &filepath) const;
|
||||||
|
};
|
||||||
@@ -4,9 +4,7 @@
|
|||||||
|
|
||||||
#include <algorithm> // Para clamp
|
#include <algorithm> // Para clamp
|
||||||
|
|
||||||
#ifndef NO_AUDIO
|
|
||||||
#include "external/jail_audio.h" // Para JA_FadeOutMusic, JA_Init, JA_PauseM...
|
#include "external/jail_audio.h" // Para JA_FadeOutMusic, JA_Init, JA_PauseM...
|
||||||
#endif
|
|
||||||
#include "options.h" // Para AudioOptions, audio, MusicOptions
|
#include "options.h" // Para AudioOptions, audio, MusicOptions
|
||||||
#include "resource.h" // Para Resource
|
#include "resource.h" // Para Resource
|
||||||
|
|
||||||
@@ -27,9 +25,7 @@ Audio::Audio() { initSDLAudio(); }
|
|||||||
|
|
||||||
// Destructor
|
// Destructor
|
||||||
Audio::~Audio() {
|
Audio::~Audio() {
|
||||||
#ifndef NO_AUDIO
|
|
||||||
JA_Quit();
|
JA_Quit();
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Método principal
|
// Método principal
|
||||||
@@ -43,9 +39,7 @@ void Audio::playMusic(const std::string &name, const int loop) {
|
|||||||
music_.loop = (loop != 0);
|
music_.loop = (loop != 0);
|
||||||
|
|
||||||
if (music_enabled_ && music_.state != MusicState::PLAYING) {
|
if (music_enabled_ && music_.state != MusicState::PLAYING) {
|
||||||
#ifndef NO_AUDIO
|
|
||||||
JA_PlayMusic(Resource::get()->getMusic(name), loop);
|
JA_PlayMusic(Resource::get()->getMusic(name), loop);
|
||||||
#endif
|
|
||||||
music_.state = MusicState::PLAYING;
|
music_.state = MusicState::PLAYING;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -53,9 +47,7 @@ void Audio::playMusic(const std::string &name, const int loop) {
|
|||||||
// Pausa la música
|
// Pausa la música
|
||||||
void Audio::pauseMusic() {
|
void Audio::pauseMusic() {
|
||||||
if (music_enabled_ && music_.state == MusicState::PLAYING) {
|
if (music_enabled_ && music_.state == MusicState::PLAYING) {
|
||||||
#ifndef NO_AUDIO
|
|
||||||
JA_PauseMusic();
|
JA_PauseMusic();
|
||||||
#endif
|
|
||||||
music_.state = MusicState::PAUSED;
|
music_.state = MusicState::PAUSED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -63,9 +55,7 @@ void Audio::pauseMusic() {
|
|||||||
// Continua la música pausada
|
// Continua la música pausada
|
||||||
void Audio::resumeMusic() {
|
void Audio::resumeMusic() {
|
||||||
if (music_enabled_ && music_.state == MusicState::PAUSED) {
|
if (music_enabled_ && music_.state == MusicState::PAUSED) {
|
||||||
#ifndef NO_AUDIO
|
|
||||||
JA_ResumeMusic();
|
JA_ResumeMusic();
|
||||||
#endif
|
|
||||||
music_.state = MusicState::PLAYING;
|
music_.state = MusicState::PLAYING;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -73,9 +63,7 @@ void Audio::resumeMusic() {
|
|||||||
// Detiene la música
|
// Detiene la música
|
||||||
void Audio::stopMusic() {
|
void Audio::stopMusic() {
|
||||||
if (music_enabled_) {
|
if (music_enabled_) {
|
||||||
#ifndef NO_AUDIO
|
|
||||||
JA_StopMusic();
|
JA_StopMusic();
|
||||||
#endif
|
|
||||||
music_.state = MusicState::STOPPED;
|
music_.state = MusicState::STOPPED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -83,27 +71,37 @@ void Audio::stopMusic() {
|
|||||||
// Reproduce un sonido
|
// Reproduce un sonido
|
||||||
void Audio::playSound(const std::string &name, Group group) const {
|
void Audio::playSound(const std::string &name, Group group) const {
|
||||||
if (sound_enabled_) {
|
if (sound_enabled_) {
|
||||||
#ifndef NO_AUDIO
|
|
||||||
JA_PlaySound(Resource::get()->getSound(name), 0, static_cast<int>(group));
|
JA_PlaySound(Resource::get()->getSound(name), 0, static_cast<int>(group));
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Detiene todos los sonidos
|
// Detiene todos los sonidos
|
||||||
void Audio::stopAllSounds() const {
|
void Audio::stopAllSounds() const {
|
||||||
if (sound_enabled_) {
|
if (sound_enabled_) {
|
||||||
#ifndef NO_AUDIO
|
|
||||||
JA_StopChannel(-1);
|
JA_StopChannel(-1);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Realiza un fundido de salida de la música
|
// Realiza un fundido de salida de la música
|
||||||
void Audio::fadeOutMusic(int milliseconds) const {
|
void Audio::fadeOutMusic(int milliseconds) const {
|
||||||
if (music_enabled_) {
|
if (music_enabled_ && getRealMusicState() == MusicState::PLAYING) {
|
||||||
#ifndef NO_AUDIO
|
|
||||||
JA_FadeOutMusic(milliseconds);
|
JA_FadeOutMusic(milliseconds);
|
||||||
#endif
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Consulta directamente el estado real de la música en jailaudio
|
||||||
|
auto Audio::getRealMusicState() const -> MusicState {
|
||||||
|
JA_Music_state ja_state = JA_GetMusicState();
|
||||||
|
switch (ja_state) {
|
||||||
|
case JA_MUSIC_PLAYING:
|
||||||
|
return MusicState::PLAYING;
|
||||||
|
case JA_MUSIC_PAUSED:
|
||||||
|
return MusicState::PAUSED;
|
||||||
|
case JA_MUSIC_STOPPED:
|
||||||
|
case JA_MUSIC_INVALID:
|
||||||
|
case JA_MUSIC_DISABLED:
|
||||||
|
default:
|
||||||
|
return MusicState::STOPPED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -111,10 +109,8 @@ void Audio::fadeOutMusic(int milliseconds) const {
|
|||||||
void Audio::setSoundVolume(int sound_volume, Group group) const {
|
void Audio::setSoundVolume(int sound_volume, Group group) const {
|
||||||
if (sound_enabled_) {
|
if (sound_enabled_) {
|
||||||
sound_volume = std::clamp(sound_volume, MIN_VOLUME, MAX_VOLUME);
|
sound_volume = std::clamp(sound_volume, MIN_VOLUME, MAX_VOLUME);
|
||||||
#ifndef NO_AUDIO
|
|
||||||
const float CONVERTED_VOLUME = (sound_volume / 100.0F) * (Options::audio.volume / 100.0F);
|
const float CONVERTED_VOLUME = (sound_volume / 100.0F) * (Options::audio.volume / 100.0F);
|
||||||
JA_SetSoundVolume(CONVERTED_VOLUME, static_cast<int>(group));
|
JA_SetSoundVolume(CONVERTED_VOLUME, static_cast<int>(group));
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -122,10 +118,8 @@ void Audio::setSoundVolume(int sound_volume, Group group) const {
|
|||||||
void Audio::setMusicVolume(int music_volume) const {
|
void Audio::setMusicVolume(int music_volume) const {
|
||||||
if (music_enabled_) {
|
if (music_enabled_) {
|
||||||
music_volume = std::clamp(music_volume, MIN_VOLUME, MAX_VOLUME);
|
music_volume = std::clamp(music_volume, MIN_VOLUME, MAX_VOLUME);
|
||||||
#ifndef NO_AUDIO
|
|
||||||
const float CONVERTED_VOLUME = (music_volume / 100.0F) * (Options::audio.volume / 100.0F);
|
const float CONVERTED_VOLUME = (music_volume / 100.0F) * (Options::audio.volume / 100.0F);
|
||||||
JA_SetMusicVolume(CONVERTED_VOLUME);
|
JA_SetMusicVolume(CONVERTED_VOLUME);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,7 +138,6 @@ void Audio::enable(bool value) {
|
|||||||
|
|
||||||
// Inicializa SDL Audio
|
// Inicializa SDL Audio
|
||||||
void Audio::initSDLAudio() {
|
void Audio::initSDLAudio() {
|
||||||
#ifndef NO_AUDIO
|
|
||||||
if (!SDL_Init(SDL_INIT_AUDIO)) {
|
if (!SDL_Init(SDL_INIT_AUDIO)) {
|
||||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_AUDIO could not initialize! SDL Error: %s", SDL_GetError());
|
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_AUDIO could not initialize! SDL Error: %s", SDL_GetError());
|
||||||
} else {
|
} else {
|
||||||
@@ -153,7 +146,4 @@ void Audio::initSDLAudio() {
|
|||||||
|
|
||||||
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "** Audio system initialized successfully");
|
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "** Audio system initialized successfully");
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "** Audio system disabled");
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
@@ -3,19 +3,26 @@
|
|||||||
#include <string> // Para string
|
#include <string> // Para string
|
||||||
#include <utility> // Para move
|
#include <utility> // Para move
|
||||||
|
|
||||||
// Clase Audio: gestor de audio (singleton)
|
// --- Clase Audio: gestor de audio (singleton) ---
|
||||||
class Audio {
|
class Audio {
|
||||||
public:
|
public:
|
||||||
|
// --- Enums ---
|
||||||
enum class Group : int {
|
enum class Group : int {
|
||||||
ALL = -1,
|
ALL = -1, // Todos los grupos
|
||||||
GAME = 0,
|
GAME = 0, // Sonidos del juego
|
||||||
INTERFACE = 1
|
INTERFACE = 1 // Sonidos de la interfaz
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class MusicState {
|
||||||
|
PLAYING, // Reproduciendo música
|
||||||
|
PAUSED, // Música pausada
|
||||||
|
STOPPED, // Música detenida
|
||||||
};
|
};
|
||||||
|
|
||||||
// --- Constantes ---
|
// --- Constantes ---
|
||||||
static constexpr int MAX_VOLUME = 100;
|
static constexpr int MAX_VOLUME = 100; // Volumen máximo
|
||||||
static constexpr int MIN_VOLUME = 0;
|
static constexpr int MIN_VOLUME = 0; // Volumen mínimo
|
||||||
static constexpr int FREQUENCY = 48000;
|
static constexpr int FREQUENCY = 48000; // Frecuencia de audio
|
||||||
|
|
||||||
// --- Métodos de singleton ---
|
// --- Métodos de singleton ---
|
||||||
static void init(); // Inicializa el objeto Audio
|
static void init(); // Inicializa el objeto Audio
|
||||||
@@ -59,40 +66,46 @@ class Audio {
|
|||||||
void setSoundVolume(int volume, Group group = Group::ALL) const; // Ajustar volumen de efectos
|
void setSoundVolume(int volume, Group group = Group::ALL) const; // Ajustar volumen de efectos
|
||||||
void setMusicVolume(int volume) const; // Ajustar volumen de música
|
void setMusicVolume(int volume) const; // Ajustar volumen de música
|
||||||
|
|
||||||
private:
|
// --- Getters para debug ---
|
||||||
enum class MusicState {
|
bool isEnabled() const { return enabled_; }
|
||||||
PLAYING,
|
bool isSoundEnabled() const { return sound_enabled_; }
|
||||||
PAUSED,
|
bool isMusicEnabled() const { return music_enabled_; }
|
||||||
STOPPED,
|
MusicState getMusicState() const { return music_.state; }
|
||||||
};
|
MusicState getRealMusicState() const; // Consulta directamente a jailaudio
|
||||||
|
const std::string& getCurrentMusicName() const { return music_.name; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
// --- Estructuras privadas ---
|
||||||
struct Music {
|
struct Music {
|
||||||
MusicState state; // Estado actual de la música (reproduciendo, detenido, en pausa)
|
MusicState state; // Estado actual de la música (reproduciendo, detenido, en pausa)
|
||||||
std::string name; // Última pista de música reproducida
|
std::string name; // Última pista de música reproducida
|
||||||
bool loop; // Indica si la última pista de música se debe reproducir en bucle
|
bool loop; // Indica si la última pista de música se debe reproducir en bucle
|
||||||
|
|
||||||
// Constructor para inicializar la música con valores predeterminados
|
// Constructor para inicializar la música con valores predeterminados
|
||||||
Music() : state(MusicState::STOPPED), loop(false) {}
|
Music()
|
||||||
|
: state(MusicState::STOPPED),
|
||||||
|
loop(false) {}
|
||||||
|
|
||||||
// Constructor para inicializar con valores específicos
|
// Constructor para inicializar con valores específicos
|
||||||
Music(MusicState init_state, std::string init_name, bool init_loop)
|
Music(MusicState init_state, std::string init_name, bool init_loop)
|
||||||
: state(init_state), name(std::move(init_name)), loop(init_loop) {}
|
: state(init_state),
|
||||||
|
name(std::move(init_name)),
|
||||||
|
loop(init_loop) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
Music music_;
|
// --- Variables de estado ---
|
||||||
|
Music music_; // Estado de la música
|
||||||
// --- Variables de Estado ---
|
|
||||||
bool enabled_ = true; // Estado general del audio
|
bool enabled_ = true; // Estado general del audio
|
||||||
bool sound_enabled_ = true; // Estado de los efectos de sonido
|
bool sound_enabled_ = true; // Estado de los efectos de sonido
|
||||||
bool music_enabled_ = true; // Estado de la música
|
bool music_enabled_ = true; // Estado de la música
|
||||||
|
|
||||||
// --- Inicializa SDL Audio ---
|
// --- Métodos internos ---
|
||||||
void initSDLAudio();
|
void initSDLAudio(); // Inicializa SDL Audio
|
||||||
|
|
||||||
// --- Patrón Singleton ---
|
// --- Constructores y destructor privados (singleton) ---
|
||||||
Audio(); // Constructor privado
|
Audio(); // Constructor privado
|
||||||
~Audio(); // Destructor privado
|
~Audio(); // Destructor privado
|
||||||
|
|
||||||
// --- Singleton ---
|
// --- Instancia singleton ---
|
||||||
static Audio *instance;
|
static Audio *instance; // Instancia única de Audio
|
||||||
};
|
};
|
||||||
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
#include <algorithm> // Para clamp, max
|
#include <algorithm> // Para clamp, max
|
||||||
#include <cmath> // Para M_PI, cos, sin
|
#include <cmath> // Para M_PI, cos, sin
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
#include "moving_sprite.h" // Para MovingSprite
|
#include "moving_sprite.h" // Para MovingSprite
|
||||||
#include "param.h" // Para Param, ParamBackground, param
|
#include "param.h" // Para Param, ParamBackground, param
|
||||||
@@ -12,9 +13,10 @@
|
|||||||
#include "screen.h" // Para Screen
|
#include "screen.h" // Para Screen
|
||||||
#include "sprite.h" // Para Sprite
|
#include "sprite.h" // Para Sprite
|
||||||
#include "texture.h" // Para Texture
|
#include "texture.h" // Para Texture
|
||||||
|
#include "utils.h" // Para funciones de easing
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
Background::Background()
|
Background::Background(float total_progress_to_complete)
|
||||||
: renderer_(Screen::get()->getRenderer()),
|
: renderer_(Screen::get()->getRenderer()),
|
||||||
|
|
||||||
buildings_texture_(Resource::get()->getTexture("game_buildings.png")),
|
buildings_texture_(Resource::get()->getTexture("game_buildings.png")),
|
||||||
@@ -25,84 +27,24 @@ Background::Background()
|
|||||||
sun_texture_(Resource::get()->getTexture("game_sun.png")),
|
sun_texture_(Resource::get()->getTexture("game_sun.png")),
|
||||||
moon_texture_(Resource::get()->getTexture("game_moon.png")),
|
moon_texture_(Resource::get()->getTexture("game_moon.png")),
|
||||||
|
|
||||||
|
total_progress_to_complete_(total_progress_to_complete),
|
||||||
|
progress_per_stage_(total_progress_to_complete_ / STAGES),
|
||||||
|
sun_completion_progress_(total_progress_to_complete_ * SUN_COMPLETION_FACTOR),
|
||||||
|
minimum_completed_progress_(total_progress_to_complete_ * MINIMUM_COMPLETED_PROGRESS_PERCENTAGE),
|
||||||
|
|
||||||
rect_(SDL_FRect{0, 0, static_cast<float>(gradients_texture_->getWidth() / 2), static_cast<float>(gradients_texture_->getHeight() / 2)}),
|
rect_(SDL_FRect{0, 0, static_cast<float>(gradients_texture_->getWidth() / 2), static_cast<float>(gradients_texture_->getHeight() / 2)}),
|
||||||
src_rect_({0, 0, 320, 240}),
|
src_rect_({.x = 0, .y = 0, .w = 320, .h = 240}),
|
||||||
dst_rect_({0, 0, 320, 240}),
|
dst_rect_({.x = 0, .y = 0, .w = 320, .h = 240}),
|
||||||
base_(rect_.h),
|
|
||||||
attenuate_color_(Color(param.background.attenuate_color.r, param.background.attenuate_color.g, param.background.attenuate_color.b)),
|
attenuate_color_(Color(param.background.attenuate_color.r, param.background.attenuate_color.g, param.background.attenuate_color.b)),
|
||||||
alpha_color_text_(param.background.attenuate_color.a),
|
|
||||||
alpha_color_text_temp_(param.background.attenuate_color.a)
|
|
||||||
|
|
||||||
{
|
alpha_color_texture_(param.background.attenuate_color.a),
|
||||||
// Precalcula rutas
|
previous_alpha_color_texture_(param.background.attenuate_color.a),
|
||||||
createSunPath();
|
base_(rect_.h) {
|
||||||
createMoonPath();
|
initializePaths();
|
||||||
|
initializeRects();
|
||||||
// Inicializa variables
|
initializeSprites();
|
||||||
{
|
initializeSpriteProperties();
|
||||||
gradient_rect_[0] = {0, 0, rect_.w, rect_.h};
|
initializeTextures();
|
||||||
gradient_rect_[1] = {rect_.w, 0, rect_.w, rect_.h};
|
|
||||||
gradient_rect_[2] = {0, rect_.h, rect_.w, rect_.h};
|
|
||||||
gradient_rect_[3] = {rect_.w, rect_.h, rect_.w, rect_.h};
|
|
||||||
|
|
||||||
const float TOP_CLOUDS_TEXTURE_HEIGHT = top_clouds_texture_->getHeight() / 4;
|
|
||||||
const float BOTTOM_CLOUDS_TEXTURE_HEIGHT = bottom_clouds_texture_->getHeight() / 4;
|
|
||||||
for (int i = 0; i < 4; ++i) {
|
|
||||||
top_clouds_rect_[i] = {0, i * TOP_CLOUDS_TEXTURE_HEIGHT, static_cast<float>(top_clouds_texture_->getWidth()), TOP_CLOUDS_TEXTURE_HEIGHT};
|
|
||||||
bottom_clouds_rect_[i] = {0, i * BOTTOM_CLOUDS_TEXTURE_HEIGHT, static_cast<float>(bottom_clouds_texture_->getWidth()), BOTTOM_CLOUDS_TEXTURE_HEIGHT};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Crea los sprites
|
|
||||||
{
|
|
||||||
const float TOP_CLOUDS_Y = base_ - 165;
|
|
||||||
const float BOTTOM_CLOUDS_Y = base_ - 101;
|
|
||||||
|
|
||||||
top_clouds_sprite_a_ = std::make_unique<MovingSprite>(top_clouds_texture_, (SDL_FRect){0, TOP_CLOUDS_Y, rect_.w, static_cast<float>(top_clouds_texture_->getHeight())});
|
|
||||||
top_clouds_sprite_b_ = std::make_unique<MovingSprite>(top_clouds_texture_, (SDL_FRect){rect_.w, TOP_CLOUDS_Y, rect_.w, static_cast<float>(top_clouds_texture_->getHeight())});
|
|
||||||
|
|
||||||
bottom_clouds_sprite_a_ = std::make_unique<MovingSprite>(bottom_clouds_texture_, (SDL_FRect){0, BOTTOM_CLOUDS_Y, rect_.w, static_cast<float>(bottom_clouds_texture_->getHeight())});
|
|
||||||
bottom_clouds_sprite_b_ = std::make_unique<MovingSprite>(bottom_clouds_texture_, (SDL_FRect){rect_.w, BOTTOM_CLOUDS_Y, rect_.w, static_cast<float>(bottom_clouds_texture_->getHeight())});
|
|
||||||
|
|
||||||
buildings_sprite_ = std::make_unique<Sprite>(buildings_texture_);
|
|
||||||
gradient_sprite_ = std::make_unique<Sprite>(gradients_texture_, 0, 0, rect_.w, rect_.h);
|
|
||||||
grass_sprite_ = std::make_unique<Sprite>(grass_texture_, 0, 0, grass_texture_->getWidth(), grass_texture_->getHeight() / 2);
|
|
||||||
sun_sprite_ = std::make_unique<Sprite>(sun_texture_);
|
|
||||||
moon_sprite_ = std::make_unique<Sprite>(moon_texture_);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Inicializa objetos
|
|
||||||
{
|
|
||||||
constexpr float TOP_CLOUDS_SPEED = 0.1F;
|
|
||||||
constexpr float BOTTOM_CLOUDS_SPEED = 0.05F;
|
|
||||||
|
|
||||||
top_clouds_sprite_a_->setSpriteClip(0, 0, top_clouds_texture_->getWidth(), top_clouds_texture_->getHeight());
|
|
||||||
top_clouds_sprite_a_->setVelX(-TOP_CLOUDS_SPEED);
|
|
||||||
|
|
||||||
top_clouds_sprite_b_->setSpriteClip(0, 0, top_clouds_texture_->getWidth(), top_clouds_texture_->getHeight());
|
|
||||||
top_clouds_sprite_b_->setVelX(-TOP_CLOUDS_SPEED);
|
|
||||||
|
|
||||||
bottom_clouds_sprite_a_->setSpriteClip(0, 0, bottom_clouds_texture_->getWidth(), bottom_clouds_texture_->getHeight());
|
|
||||||
bottom_clouds_sprite_a_->setVelX(-BOTTOM_CLOUDS_SPEED);
|
|
||||||
|
|
||||||
bottom_clouds_sprite_b_->setSpriteClip(0, 0, bottom_clouds_texture_->getWidth(), bottom_clouds_texture_->getHeight());
|
|
||||||
bottom_clouds_sprite_b_->setVelX(-BOTTOM_CLOUDS_SPEED);
|
|
||||||
|
|
||||||
buildings_sprite_->setY(base_ - buildings_sprite_->getHeight());
|
|
||||||
grass_sprite_->setY(base_ - grass_sprite_->getHeight());
|
|
||||||
sun_sprite_->setPosition(sun_path_.front());
|
|
||||||
moon_sprite_->setPosition(moon_path_.front());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Crea la textura para componer el fondo
|
|
||||||
canvas_ = SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, rect_.w, rect_.h);
|
|
||||||
SDL_SetTextureBlendMode(canvas_, SDL_BLENDMODE_BLEND);
|
|
||||||
|
|
||||||
// Crea la textura para atenuar el fondo
|
|
||||||
color_texture_ = SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, rect_.w, rect_.h);
|
|
||||||
SDL_SetTextureBlendMode(color_texture_, SDL_BLENDMODE_BLEND);
|
|
||||||
setColor(attenuate_color_);
|
|
||||||
SDL_SetTextureAlphaMod(color_texture_, alpha_color_text_);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Destructor
|
// Destructor
|
||||||
@@ -111,31 +53,318 @@ Background::~Background() {
|
|||||||
SDL_DestroyTexture(color_texture_);
|
SDL_DestroyTexture(color_texture_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Inicializa las rutas del sol y la luna
|
||||||
|
void Background::initializePaths() {
|
||||||
|
createSunPath();
|
||||||
|
createMoonPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inicializa los rectángulos de gradientes y nubes
|
||||||
|
void Background::initializeRects() {
|
||||||
|
gradient_rect_[0] = {.x = 0, .y = 0, .w = rect_.w, .h = rect_.h};
|
||||||
|
gradient_rect_[1] = {.x = rect_.w, .y = 0, .w = rect_.w, .h = rect_.h};
|
||||||
|
gradient_rect_[2] = {.x = 0, .y = rect_.h, .w = rect_.w, .h = rect_.h};
|
||||||
|
gradient_rect_[3] = {.x = rect_.w, .y = rect_.h, .w = rect_.w, .h = rect_.h};
|
||||||
|
|
||||||
|
const float TOP_CLOUDS_TEXTURE_HEIGHT = top_clouds_texture_->getHeight() / 4;
|
||||||
|
const float BOTTOM_CLOUDS_TEXTURE_HEIGHT = bottom_clouds_texture_->getHeight() / 4;
|
||||||
|
|
||||||
|
for (int i = 0; i < 4; ++i) {
|
||||||
|
top_clouds_rect_[i] = {.x = 0, .y = i * TOP_CLOUDS_TEXTURE_HEIGHT, .w = static_cast<float>(top_clouds_texture_->getWidth()), .h = TOP_CLOUDS_TEXTURE_HEIGHT};
|
||||||
|
bottom_clouds_rect_[i] = {.x = 0, .y = i * BOTTOM_CLOUDS_TEXTURE_HEIGHT, .w = static_cast<float>(bottom_clouds_texture_->getWidth()), .h = BOTTOM_CLOUDS_TEXTURE_HEIGHT};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Crea los sprites
|
||||||
|
void Background::initializeSprites() {
|
||||||
|
const float TOP_CLOUDS_Y = base_ - 165;
|
||||||
|
const float BOTTOM_CLOUDS_Y = base_ - 101;
|
||||||
|
|
||||||
|
top_clouds_sprite_a_ = std::make_unique<MovingSprite>(top_clouds_texture_, (SDL_FRect){0, TOP_CLOUDS_Y, rect_.w, static_cast<float>(top_clouds_texture_->getHeight())});
|
||||||
|
top_clouds_sprite_b_ = std::make_unique<MovingSprite>(top_clouds_texture_, (SDL_FRect){rect_.w, TOP_CLOUDS_Y, rect_.w, static_cast<float>(top_clouds_texture_->getHeight())});
|
||||||
|
|
||||||
|
bottom_clouds_sprite_a_ = std::make_unique<MovingSprite>(bottom_clouds_texture_, (SDL_FRect){0, BOTTOM_CLOUDS_Y, rect_.w, static_cast<float>(bottom_clouds_texture_->getHeight())});
|
||||||
|
bottom_clouds_sprite_b_ = std::make_unique<MovingSprite>(bottom_clouds_texture_, (SDL_FRect){rect_.w, BOTTOM_CLOUDS_Y, rect_.w, static_cast<float>(bottom_clouds_texture_->getHeight())});
|
||||||
|
|
||||||
|
buildings_sprite_ = std::make_unique<Sprite>(buildings_texture_);
|
||||||
|
gradient_sprite_ = std::make_unique<Sprite>(gradients_texture_, 0, 0, rect_.w, rect_.h);
|
||||||
|
grass_sprite_ = std::make_unique<Sprite>(grass_texture_, 0, 0, grass_texture_->getWidth(), grass_texture_->getHeight() / 2);
|
||||||
|
sun_sprite_ = std::make_unique<Sprite>(sun_texture_);
|
||||||
|
moon_sprite_ = std::make_unique<Sprite>(moon_texture_);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configura las propiedades iniciales de los sprites
|
||||||
|
void Background::initializeSpriteProperties() {
|
||||||
|
// Velocidades iniciales que coinciden con updateCloudsSpeed() cuando progress=0
|
||||||
|
constexpr float INITIAL_TOP_CLOUDS_SPEED_PX_PER_S = 0.05F * 60.0F; // 3.0 píxeles/segundo (coincide con CLOUDS_INITIAL_SPEED)
|
||||||
|
constexpr float INITIAL_BOTTOM_CLOUDS_SPEED_PX_PER_S = 0.05F * 60.0F / 2.0F; // 1.5 píxeles/segundo (mitad de velocidad)
|
||||||
|
|
||||||
|
top_clouds_sprite_a_->setSpriteClip(0, 0, top_clouds_texture_->getWidth(), top_clouds_texture_->getHeight());
|
||||||
|
top_clouds_sprite_a_->setVelX(-INITIAL_TOP_CLOUDS_SPEED_PX_PER_S);
|
||||||
|
|
||||||
|
top_clouds_sprite_b_->setSpriteClip(0, 0, top_clouds_texture_->getWidth(), top_clouds_texture_->getHeight());
|
||||||
|
top_clouds_sprite_b_->setVelX(-INITIAL_TOP_CLOUDS_SPEED_PX_PER_S);
|
||||||
|
|
||||||
|
bottom_clouds_sprite_a_->setSpriteClip(0, 0, bottom_clouds_texture_->getWidth(), bottom_clouds_texture_->getHeight());
|
||||||
|
bottom_clouds_sprite_a_->setVelX(-INITIAL_BOTTOM_CLOUDS_SPEED_PX_PER_S);
|
||||||
|
|
||||||
|
bottom_clouds_sprite_b_->setSpriteClip(0, 0, bottom_clouds_texture_->getWidth(), bottom_clouds_texture_->getHeight());
|
||||||
|
bottom_clouds_sprite_b_->setVelX(-INITIAL_BOTTOM_CLOUDS_SPEED_PX_PER_S);
|
||||||
|
|
||||||
|
buildings_sprite_->setY(base_ - buildings_sprite_->getHeight());
|
||||||
|
grass_sprite_->setY(base_ - grass_sprite_->getHeight());
|
||||||
|
sun_sprite_->setPosition(sun_path_.front());
|
||||||
|
moon_sprite_->setPosition(moon_path_.front());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inicializa las texturas de renderizado
|
||||||
|
void Background::initializeTextures() {
|
||||||
|
canvas_ = SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, rect_.w, rect_.h);
|
||||||
|
SDL_SetTextureBlendMode(canvas_, SDL_BLENDMODE_BLEND);
|
||||||
|
|
||||||
|
color_texture_ = SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, rect_.w, rect_.h);
|
||||||
|
SDL_SetTextureBlendMode(color_texture_, SDL_BLENDMODE_BLEND);
|
||||||
|
setColor(attenuate_color_);
|
||||||
|
SDL_SetTextureAlphaMod(color_texture_, alpha_color_texture_);
|
||||||
|
}
|
||||||
|
|
||||||
// Actualiza la lógica del objeto
|
// Actualiza la lógica del objeto
|
||||||
void Background::update() {
|
void Background::update(float delta_time) {
|
||||||
// Actualiza el valor de alpha_
|
// Actualiza la progresión y calcula transiciones
|
||||||
|
if (!manual_mode_) {
|
||||||
|
updateProgression(delta_time);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Actualiza el valor de alpha
|
||||||
updateAlphaColorTexture();
|
updateAlphaColorTexture();
|
||||||
|
|
||||||
// Actualiza las nubes
|
// Actualiza las nubes
|
||||||
updateClouds();
|
updateClouds(delta_time);
|
||||||
|
|
||||||
// Calcula el frame de la hierba
|
// Actualiza timer de hierba
|
||||||
grass_sprite_->setSpriteClip(0, (10 * (counter_ / 20 % 2)), 320, 10);
|
grass_timer_ += delta_time;
|
||||||
|
|
||||||
// Calcula el valor de alpha_
|
// Calcula el frame de la hierba (alterna cada GRASS_FRAME_DURATION ms)
|
||||||
|
int grass_frame = static_cast<int>(grass_timer_ / GRASS_FRAME_DURATION) % 2;
|
||||||
|
grass_sprite_->setSpriteClip(0, (10 * grass_frame), 320, 10);
|
||||||
|
|
||||||
|
// Calcula el valor de alpha
|
||||||
alpha_ = std::max((255 - (int)(255 * transition_)), 0);
|
alpha_ = std::max((255 - (int)(255 * transition_)), 0);
|
||||||
|
|
||||||
// Mueve el sol
|
// Mueve el sol y la luna según la progresión
|
||||||
sun_sprite_->setPosition(sun_path_.at(sun_index_));
|
sun_sprite_->setPosition(sun_path_.at(sun_index_));
|
||||||
moon_sprite_->setPosition(moon_path_.at(moon_index_));
|
moon_sprite_->setPosition(moon_path_.at(moon_index_));
|
||||||
|
|
||||||
// Incrementa el contador
|
|
||||||
++counter_;
|
|
||||||
|
|
||||||
// Compone todos los elementos del fondo en la textura
|
// Compone todos los elementos del fondo en la textura
|
||||||
fillCanvas();
|
fillCanvas();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Incrementa la progresión interna
|
||||||
|
void Background::incrementProgress(float amount) {
|
||||||
|
if (state_ == State::NORMAL) {
|
||||||
|
float old_progress = progress_;
|
||||||
|
progress_ += amount;
|
||||||
|
progress_ = std::min(progress_, total_progress_to_complete_);
|
||||||
|
|
||||||
|
// Notifica el cambio si hay callback y el progreso cambió
|
||||||
|
if (progress_callback_ && progress_ != old_progress) {
|
||||||
|
progress_callback_(progress_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Establece la progresión absoluta
|
||||||
|
void Background::setProgress(float absolute_progress) {
|
||||||
|
float old_progress = progress_;
|
||||||
|
progress_ = std::clamp(absolute_progress, 0.0F, total_progress_to_complete_);
|
||||||
|
|
||||||
|
// Notifica el cambio si hay callback y el progreso cambió
|
||||||
|
if (progress_callback_ && progress_ != old_progress) {
|
||||||
|
progress_callback_(progress_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cambia el estado del fondo
|
||||||
|
void Background::setState(State new_state) {
|
||||||
|
// Si entra en estado completado, inicializar variables de transición
|
||||||
|
if (new_state == State::COMPLETED && state_ != State::COMPLETED) {
|
||||||
|
completion_initial_progress_ = progress_;
|
||||||
|
completion_transition_timer_ = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
state_ = new_state;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reinicia la progresión
|
||||||
|
void Background::reset() {
|
||||||
|
float old_progress = progress_;
|
||||||
|
progress_ = 0.0F;
|
||||||
|
state_ = State::NORMAL;
|
||||||
|
manual_mode_ = false;
|
||||||
|
gradient_number_ = 0;
|
||||||
|
transition_ = 0.0F;
|
||||||
|
sun_index_ = 0;
|
||||||
|
moon_index_ = 0;
|
||||||
|
|
||||||
|
// Resetear variables de transición de completado
|
||||||
|
completion_transition_timer_ = 0.0f;
|
||||||
|
completion_initial_progress_ = 0.0f;
|
||||||
|
|
||||||
|
// Notifica el cambio si hay callback
|
||||||
|
if (progress_callback_ && progress_ != old_progress) {
|
||||||
|
progress_callback_(progress_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Activa/desactiva el modo manual
|
||||||
|
void Background::setManualMode(bool manual) {
|
||||||
|
manual_mode_ = manual;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Establece callback para sincronización automática
|
||||||
|
void Background::setProgressCallback(ProgressCallback callback) {
|
||||||
|
progress_callback_ = std::move(callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Elimina el callback
|
||||||
|
void Background::removeProgressCallback() {
|
||||||
|
progress_callback_ = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ajusta la velocidad de las nubes
|
||||||
|
void Background::setCloudsSpeed(float value) {
|
||||||
|
clouds_speed_ = value;
|
||||||
|
|
||||||
|
// En modo manual, aplicar la velocidad directamente
|
||||||
|
// Las nubes inferiores van a la mitad de velocidad que las superiores
|
||||||
|
top_clouds_sprite_a_->setVelX(value);
|
||||||
|
top_clouds_sprite_b_->setVelX(value);
|
||||||
|
bottom_clouds_sprite_a_->setVelX(value / 2.0F);
|
||||||
|
bottom_clouds_sprite_b_->setVelX(value / 2.0F);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Establece el degradado de fondo
|
||||||
|
void Background::setGradientNumber(int value) {
|
||||||
|
gradient_number_ = value % STAGES;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ajusta la transición entre texturas
|
||||||
|
void Background::setTransition(float value) {
|
||||||
|
transition_ = std::clamp(value, 0.0F, 1.0F);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Establece la posición del sol
|
||||||
|
void Background::setSunProgression(float progress) {
|
||||||
|
progress = std::clamp(progress, 0.0F, 1.0F);
|
||||||
|
sun_index_ = static_cast<size_t>(progress * (sun_path_.size() - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Establece la posición de la luna
|
||||||
|
void Background::setMoonProgression(float progress) {
|
||||||
|
progress = std::clamp(progress, 0.0F, 1.0F);
|
||||||
|
moon_index_ = static_cast<size_t>(progress * (moon_path_.size() - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Actualiza la progresión y calcula las transiciones
|
||||||
|
void Background::updateProgression(float delta_time) {
|
||||||
|
// Si el juego está completado, hacer transición suave con easing
|
||||||
|
if (state_ == State::COMPLETED) {
|
||||||
|
completion_transition_timer_ += delta_time;
|
||||||
|
|
||||||
|
// Calcular progreso normalizado de la transición (0.0 a 1.0)
|
||||||
|
float t = std::min(completion_transition_timer_ / COMPLETION_TRANSITION_DURATION_S, 1.0f);
|
||||||
|
|
||||||
|
if (t < 1.0f) {
|
||||||
|
// Usar easeOutCubic para transición suave (rápido al inicio, lento al final)
|
||||||
|
float eased_t = easeOutCubic(static_cast<double>(t));
|
||||||
|
|
||||||
|
// Interpolación desde progreso inicial hasta mínimo
|
||||||
|
float progress_range = completion_initial_progress_ - minimum_completed_progress_;
|
||||||
|
progress_ = completion_initial_progress_ - (progress_range * eased_t);
|
||||||
|
} else {
|
||||||
|
// Transición completada, fijar al valor mínimo
|
||||||
|
progress_ = minimum_completed_progress_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calcula la transición de los diferentes fondos
|
||||||
|
const float GRADIENT_NUMBER_FLOAT = std::min(progress_ / progress_per_stage_, 3.0F);
|
||||||
|
const float PERCENT = GRADIENT_NUMBER_FLOAT - static_cast<int>(GRADIENT_NUMBER_FLOAT);
|
||||||
|
|
||||||
|
gradient_number_ = static_cast<size_t>(GRADIENT_NUMBER_FLOAT);
|
||||||
|
transition_ = PERCENT;
|
||||||
|
|
||||||
|
// Calcula la posición del sol
|
||||||
|
const float SUN_PROGRESSION = std::min(progress_ / sun_completion_progress_, 1.0F);
|
||||||
|
sun_index_ = static_cast<size_t>(SUN_PROGRESSION * (sun_path_.size() - 1));
|
||||||
|
|
||||||
|
// Calcula la posición de la luna
|
||||||
|
const float MOON_PROGRESSION = std::min(progress_ / total_progress_to_complete_, 1.0F);
|
||||||
|
moon_index_ = static_cast<size_t>(MOON_PROGRESSION * (moon_path_.size() - 1));
|
||||||
|
|
||||||
|
// Actualiza la velocidad de las nubes
|
||||||
|
updateCloudsSpeed();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Actualiza la velocidad de las nubes según el estado y progresión
|
||||||
|
void Background::updateCloudsSpeed() {
|
||||||
|
// Cálculo de velocidad según progreso (convertido de frame-based a time-based)
|
||||||
|
constexpr float CLOUDS_INITIAL_SPEED_PX_PER_S = 0.05F * 60.0F; // 3.0 píxeles/segundo (era 0.05 px/frame @ 60fps)
|
||||||
|
constexpr float CLOUDS_TOTAL_SPEED_PX_PER_S = 2.00F * 60.0F; // 120.0 píxeles/segundo (era 2.00 px/frame @ 60fps)
|
||||||
|
constexpr float CLOUDS_FINAL_SPEED_RANGE_PX_PER_S = CLOUDS_TOTAL_SPEED_PX_PER_S - CLOUDS_INITIAL_SPEED_PX_PER_S; // 117.0 píxeles/segundo
|
||||||
|
|
||||||
|
// Velocidad base según progreso (de -3.0 a -120.0 píxeles/segundo, igual que la versión original)
|
||||||
|
float base_clouds_speed = (-CLOUDS_INITIAL_SPEED_PX_PER_S) +
|
||||||
|
(-CLOUDS_FINAL_SPEED_RANGE_PX_PER_S * (progress_ / total_progress_to_complete_));
|
||||||
|
|
||||||
|
// En estado completado, las nubes se ralentizan gradualmente
|
||||||
|
if (state_ == State::COMPLETED) {
|
||||||
|
float completion_factor = (progress_ - minimum_completed_progress_) /
|
||||||
|
(total_progress_to_complete_ - minimum_completed_progress_);
|
||||||
|
completion_factor = std::max(0.1F, completion_factor);
|
||||||
|
base_clouds_speed *= completion_factor;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Aplicar velocidades diferentes para nubes superiores e inferiores
|
||||||
|
const float TOP_CLOUDS_SPEED = base_clouds_speed;
|
||||||
|
const float BOTTOM_CLOUDS_SPEED = base_clouds_speed / 2.0F;
|
||||||
|
|
||||||
|
// Aplicar las velocidades a los sprites correspondientes
|
||||||
|
top_clouds_sprite_a_->setVelX(TOP_CLOUDS_SPEED);
|
||||||
|
top_clouds_sprite_b_->setVelX(TOP_CLOUDS_SPEED);
|
||||||
|
bottom_clouds_sprite_a_->setVelX(BOTTOM_CLOUDS_SPEED);
|
||||||
|
bottom_clouds_sprite_b_->setVelX(BOTTOM_CLOUDS_SPEED);
|
||||||
|
|
||||||
|
// Guardar la velocidad principal
|
||||||
|
clouds_speed_ = TOP_CLOUDS_SPEED;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Actualiza las nubes
|
||||||
|
void Background::updateClouds(float deltaTime) {
|
||||||
|
// Mueve las nubes
|
||||||
|
top_clouds_sprite_a_->update(deltaTime);
|
||||||
|
top_clouds_sprite_b_->update(deltaTime);
|
||||||
|
bottom_clouds_sprite_a_->update(deltaTime);
|
||||||
|
bottom_clouds_sprite_b_->update(deltaTime);
|
||||||
|
|
||||||
|
// Calcula el offset de las nubes
|
||||||
|
if (top_clouds_sprite_a_->getPosX() < -top_clouds_sprite_a_->getWidth()) {
|
||||||
|
top_clouds_sprite_a_->setPosX(top_clouds_sprite_a_->getWidth());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (top_clouds_sprite_b_->getPosX() < -top_clouds_sprite_b_->getWidth()) {
|
||||||
|
top_clouds_sprite_b_->setPosX(top_clouds_sprite_b_->getWidth());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bottom_clouds_sprite_a_->getPosX() < -bottom_clouds_sprite_a_->getWidth()) {
|
||||||
|
bottom_clouds_sprite_a_->setPosX(bottom_clouds_sprite_a_->getWidth());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bottom_clouds_sprite_b_->getPosX() < -bottom_clouds_sprite_b_->getWidth()) {
|
||||||
|
bottom_clouds_sprite_b_->setPosX(bottom_clouds_sprite_b_->getWidth());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Dibuja el gradiente de fondo
|
// Dibuja el gradiente de fondo
|
||||||
void Background::renderGradient() {
|
void Background::renderGradient() {
|
||||||
// Dibuja el gradiente de detras
|
// Dibuja el gradiente de detras
|
||||||
@@ -221,21 +450,6 @@ void Background::render() {
|
|||||||
SDL_RenderTexture(renderer_, color_texture_, &src_rect_, &dst_rect_);
|
SDL_RenderTexture(renderer_, color_texture_, &src_rect_, &dst_rect_);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ajusta el valor de la variable
|
|
||||||
void Background::setCloudsSpeed(float value) {
|
|
||||||
clouds_speed_ = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ajusta el valor de la variable
|
|
||||||
void Background::setGradientNumber(int value) {
|
|
||||||
gradient_number_ = value % 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ajusta el valor de la variable
|
|
||||||
void Background::setTransition(float value) {
|
|
||||||
transition_ = std::clamp(value, 0.0F, 1.0F);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Establece la posición del objeto
|
// Establece la posición del objeto
|
||||||
void Background::setPos(SDL_FRect pos) {
|
void Background::setPos(SDL_FRect pos) {
|
||||||
dst_rect_ = pos;
|
dst_rect_ = pos;
|
||||||
@@ -247,7 +461,7 @@ void Background::setPos(SDL_FRect pos) {
|
|||||||
src_rect_.h = pos.h;
|
src_rect_.h = pos.h;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Establece el color_ de atenuación
|
// Establece el color de atenuación
|
||||||
void Background::setColor(Color color) {
|
void Background::setColor(Color color) {
|
||||||
attenuate_color_ = color;
|
attenuate_color_ = color;
|
||||||
|
|
||||||
@@ -264,52 +478,20 @@ void Background::setColor(Color color) {
|
|||||||
// Establece la transparencia de la atenuación
|
// Establece la transparencia de la atenuación
|
||||||
void Background::setAlpha(int alpha) {
|
void Background::setAlpha(int alpha) {
|
||||||
// Evita que se asignen valores fuera de rango
|
// Evita que se asignen valores fuera de rango
|
||||||
alpha_ = std::clamp(alpha, 0, 255);
|
alpha = std::clamp(alpha, 0, 255);
|
||||||
|
|
||||||
// Guarda el valor actual y establece el nuevo valor
|
// Guarda el valor actual y establece el nuevo valor
|
||||||
alpha_color_text_temp_ = alpha_color_text_;
|
previous_alpha_color_texture_ = alpha_color_texture_;
|
||||||
alpha_color_text_ = alpha_;
|
alpha_color_texture_ = alpha;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Actualiza el valor de alpha_
|
// Actualiza el valor de alpha
|
||||||
void Background::updateAlphaColorTexture() {
|
void Background::updateAlphaColorTexture() {
|
||||||
if (alpha_color_text_ == alpha_color_text_temp_) {
|
if (alpha_color_texture_ == previous_alpha_color_texture_) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
alpha_color_text_ > alpha_color_text_temp_ ? ++alpha_color_text_temp_ : --alpha_color_text_temp_;
|
alpha_color_texture_ > previous_alpha_color_texture_ ? ++previous_alpha_color_texture_ : --previous_alpha_color_texture_;
|
||||||
SDL_SetTextureAlphaMod(color_texture_, alpha_color_text_temp_);
|
SDL_SetTextureAlphaMod(color_texture_, previous_alpha_color_texture_);
|
||||||
}
|
|
||||||
|
|
||||||
// Actualiza las nubes
|
|
||||||
void Background::updateClouds() {
|
|
||||||
// Aplica la velocidad calculada a las nubes
|
|
||||||
top_clouds_sprite_a_->setVelX(clouds_speed_);
|
|
||||||
top_clouds_sprite_b_->setVelX(clouds_speed_);
|
|
||||||
bottom_clouds_sprite_a_->setVelX(clouds_speed_ / 2);
|
|
||||||
bottom_clouds_sprite_b_->setVelX(clouds_speed_ / 2);
|
|
||||||
|
|
||||||
// Mueve las nubes
|
|
||||||
top_clouds_sprite_a_->update();
|
|
||||||
top_clouds_sprite_b_->update();
|
|
||||||
bottom_clouds_sprite_a_->update();
|
|
||||||
bottom_clouds_sprite_b_->update();
|
|
||||||
|
|
||||||
// Calcula el offset de las nubes
|
|
||||||
if (top_clouds_sprite_a_->getPosX() < -top_clouds_sprite_a_->getWidth()) {
|
|
||||||
top_clouds_sprite_a_->setPosX(top_clouds_sprite_a_->getWidth());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (top_clouds_sprite_b_->getPosX() < -top_clouds_sprite_b_->getWidth()) {
|
|
||||||
top_clouds_sprite_b_->setPosX(top_clouds_sprite_b_->getWidth());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bottom_clouds_sprite_a_->getPosX() < -bottom_clouds_sprite_a_->getWidth()) {
|
|
||||||
bottom_clouds_sprite_a_->setPosX(bottom_clouds_sprite_a_->getWidth());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bottom_clouds_sprite_b_->getPosX() < -bottom_clouds_sprite_b_->getWidth()) {
|
|
||||||
bottom_clouds_sprite_b_->setPosX(bottom_clouds_sprite_b_->getWidth());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Precalcula el vector con el recorrido del sol
|
// Precalcula el vector con el recorrido del sol
|
||||||
@@ -323,7 +505,7 @@ void Background::createSunPath() {
|
|||||||
const int NUM_STEPS = static_cast<int>((M_PI - M_PI / 2) / STEP) + 1;
|
const int NUM_STEPS = static_cast<int>((M_PI - M_PI / 2) / STEP) + 1;
|
||||||
|
|
||||||
for (int i = 0; i < NUM_STEPS; ++i) {
|
for (int i = 0; i < NUM_STEPS; ++i) {
|
||||||
double theta = M_PI / 2 + i * STEP;
|
double theta = M_PI / 2 + (i * STEP);
|
||||||
float x = CENTER_X + (RADIUS * cos(theta));
|
float x = CENTER_X + (RADIUS * cos(theta));
|
||||||
float y = CENTER_Y - (RADIUS * sin(theta));
|
float y = CENTER_Y - (RADIUS * sin(theta));
|
||||||
sun_path_.push_back({x, y});
|
sun_path_.push_back({x, y});
|
||||||
@@ -343,26 +525,22 @@ void Background::createMoonPath() {
|
|||||||
const float CENTER_Y = base_ - 50;
|
const float CENTER_Y = base_ - 50;
|
||||||
constexpr float RADIUS = 140;
|
constexpr float RADIUS = 140;
|
||||||
|
|
||||||
// Generar puntos de la curva desde 0 a 90 grados
|
|
||||||
constexpr double STEP = 0.01;
|
constexpr double STEP = 0.01;
|
||||||
const int NUM_STEPS = static_cast<int>((M_PI / 2 - 0) / STEP) + 1;
|
const int NUM_STEPS = static_cast<int>((M_PI / 2) / STEP) + 1;
|
||||||
|
|
||||||
|
constexpr float FREEZE_PERCENTAGE = 0.2F; // Porcentaje final del recorrido que se mantiene fijo
|
||||||
|
|
||||||
|
const int FREEZE_START_INDEX = static_cast<int>(NUM_STEPS * (1.0F - FREEZE_PERCENTAGE));
|
||||||
|
|
||||||
for (int i = 0; i < NUM_STEPS; ++i) {
|
for (int i = 0; i < NUM_STEPS; ++i) {
|
||||||
double theta = 0 + i * STEP;
|
double theta = i * STEP;
|
||||||
float x = CENTER_X + (RADIUS * cos(theta));
|
float x = CENTER_X + (RADIUS * cos(theta));
|
||||||
float y = CENTER_Y - (RADIUS * sin(theta));
|
float y = CENTER_Y - (RADIUS * sin(theta));
|
||||||
moon_path_.push_back({x, y});
|
|
||||||
|
if (i >= FREEZE_START_INDEX && !moon_path_.empty()) {
|
||||||
|
moon_path_.push_back(moon_path_.back()); // Repite el último punto válido
|
||||||
|
} else {
|
||||||
|
moon_path_.push_back({x, y});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Establece la posición del sol
|
|
||||||
void Background::setSunProgression(float progress) {
|
|
||||||
progress = std::clamp(progress, 0.0F, 1.0F);
|
|
||||||
sun_index_ = static_cast<size_t>(progress * (sun_path_.size() - 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Establece la posición de la luna
|
|
||||||
void Background::setMoonProgression(float progress) {
|
|
||||||
progress = std::clamp(progress, 0.0F, 1.0F);
|
|
||||||
moon_index_ = static_cast<size_t>(progress * (moon_path_.size() - 1));
|
|
||||||
}
|
|
||||||
@@ -2,10 +2,11 @@
|
|||||||
|
|
||||||
#include <SDL3/SDL.h> // Para SDL_FRect, SDL_FPoint, SDL_Texture, SDL_Renderer
|
#include <SDL3/SDL.h> // Para SDL_FRect, SDL_FPoint, SDL_Texture, SDL_Renderer
|
||||||
|
|
||||||
#include <array> // Para array
|
#include <array> // Para array
|
||||||
#include <cstddef> // Para size_t
|
#include <cstddef> // Para size_t
|
||||||
#include <memory> // Para unique_ptr, shared_ptr
|
#include <functional> // Para function
|
||||||
#include <vector> // Para vector
|
#include <memory> // Para unique_ptr, shared_ptr
|
||||||
|
#include <vector> // Para vector
|
||||||
|
|
||||||
#include "color.h" // Para Color
|
#include "color.h" // Para Color
|
||||||
|
|
||||||
@@ -13,102 +14,128 @@ class MovingSprite;
|
|||||||
class Sprite;
|
class Sprite;
|
||||||
class Texture;
|
class Texture;
|
||||||
|
|
||||||
/*
|
// --- Clase Background: gestiona el fondo de la sección jugable ---
|
||||||
Esta clase gestiona el fondo que aparece en la sección jugable.
|
|
||||||
|
|
||||||
Usa una textura compuesta y una capa superior con un color sólido cuya opacidad es ajustable.
|
|
||||||
Su área total está definida por "rect", pero solo se pinta la región "srcRect" en la pantalla en "dstRect".
|
|
||||||
|
|
||||||
Métodos clave:
|
|
||||||
- setCloudsSpeed(float value) -> Define la velocidad de las nubes
|
|
||||||
- setGradientNumber(int value) -> Ajusta el índice del color de cielo
|
|
||||||
- setTransition(float value) -> Configura la transición entre texturas
|
|
||||||
- setColor(Color color) -> Aplica un color de atenuación
|
|
||||||
- setAlpha(int alpha) -> Ajusta la transparencia de la capa de atenuación
|
|
||||||
*/
|
|
||||||
|
|
||||||
class Background {
|
class Background {
|
||||||
public:
|
public:
|
||||||
// Constructor y Destructor
|
// --- Enums ---
|
||||||
Background();
|
enum class State {
|
||||||
~Background();
|
NORMAL, // Progresión normal del día
|
||||||
|
COMPLETED // Reducción gradual de la actividad
|
||||||
|
};
|
||||||
|
|
||||||
// Actualización y renderizado
|
// --- Tipos ---
|
||||||
void update(); // Actualiza la lógica del objeto
|
using ProgressCallback = std::function<void(float)>; // Callback para sincronización
|
||||||
void render(); // Dibuja el objeto
|
|
||||||
|
|
||||||
// Configuración de posición
|
// --- Constructor y destructor ---
|
||||||
void setPos(SDL_FRect pos); // Establece la posición del objeto
|
Background(float total_progress_to_complete = 6100.0F); // Constructor principal
|
||||||
|
~Background(); // Destructor
|
||||||
|
|
||||||
// Configuración de animaciones y efectos
|
// --- Métodos principales ---
|
||||||
void setCloudsSpeed(float value); // Ajusta la velocidad de desplazamiento de las nubes
|
void update(float delta_time); // Actualiza la lógica del objeto
|
||||||
void setGradientNumber(int value); // Establece el degradado de fondo a usar
|
void render(); // Dibuja el objeto
|
||||||
void setTransition(float value); // Ajusta la transición entre texturas de fondo
|
void reset(); // Reinicia la progresión
|
||||||
|
|
||||||
// Configuración de efectos visuales
|
// --- Configuración ---
|
||||||
void setColor(Color color); // Establece el color de atenuación
|
void setPos(SDL_FRect pos); // Establece la posición del objeto
|
||||||
void setAlpha(int alpha); // Ajusta la transparencia del fondo
|
void setState(State new_state); // Cambia el estado del fondo
|
||||||
|
void setProgressCallback(ProgressCallback callback); // Establece callback para sincronización
|
||||||
|
void removeProgressCallback(); // Elimina el callback
|
||||||
|
void setManualMode(bool manual); // Activa/desactiva el modo manual
|
||||||
|
void setCloudsSpeed(float value); // Ajusta la velocidad de las nubes
|
||||||
|
void setGradientNumber(int value); // Establece el degradado de fondo
|
||||||
|
void setTransition(float value); // Ajusta la transición entre texturas
|
||||||
|
void setSunProgression(float progress); // Establece la posición del sol
|
||||||
|
void setMoonProgression(float progress); // Establece la posición de la luna
|
||||||
|
void setColor(Color color); // Establece el color de atenuación
|
||||||
|
void setAlpha(int alpha); // Ajusta la transparencia del fondo
|
||||||
|
|
||||||
// Configuración del sol y la luna
|
// --- Control de progresión ---
|
||||||
void setSunProgression(float progress); // Establece la posición del sol
|
void incrementProgress(float amount = 1.0F); // Incrementa la progresión interna
|
||||||
void setMoonProgression(float progress); // Establece la posición de la luna
|
void setProgress(float absolute_progress); // Establece la progresión absoluta
|
||||||
|
|
||||||
|
// --- Getters ---
|
||||||
|
[[nodiscard]] auto getProgress() const -> float { return progress_; } // Obtiene el progreso actual
|
||||||
|
[[nodiscard]] auto getState() const -> State { return state_; } // Obtiene el estado actual
|
||||||
|
[[nodiscard]] auto getCurrentGradient() const -> int { return static_cast<int>(gradient_number_); } // Obtiene el gradiente actual
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Objetos y punteros
|
// --- Constantes ---
|
||||||
SDL_Renderer *renderer_; // Renderizador de la ventana
|
static constexpr size_t STAGES = 4; // Número de etapas
|
||||||
|
static constexpr float MINIMUM_COMPLETED_PROGRESS_PERCENTAGE = 0.05F; // Porcentaje mínimo completado (10%)
|
||||||
|
static constexpr float SUN_COMPLETION_FACTOR = 0.5F; // Factor de completado del sol
|
||||||
|
static constexpr float COMPLETION_TRANSITION_DURATION_S = 3.0F; // Duración de la transición de completado en segundos
|
||||||
|
|
||||||
// Texturas
|
// --- Objetos y punteros ---
|
||||||
std::shared_ptr<Texture> buildings_texture_;
|
SDL_Renderer *renderer_; // Renderizador de la ventana
|
||||||
std::shared_ptr<Texture> top_clouds_texture_;
|
SDL_Texture *canvas_; // Textura para componer el fondo
|
||||||
std::shared_ptr<Texture> bottom_clouds_texture_;
|
SDL_Texture *color_texture_; // Textura para atenuar el fondo
|
||||||
std::shared_ptr<Texture> grass_texture_;
|
std::shared_ptr<Texture> buildings_texture_; // Textura de edificios
|
||||||
std::shared_ptr<Texture> gradients_texture_;
|
std::shared_ptr<Texture> top_clouds_texture_; // Textura de nubes superiores
|
||||||
std::shared_ptr<Texture> sun_texture_;
|
std::shared_ptr<Texture> bottom_clouds_texture_; // Textura de nubes inferiores
|
||||||
std::shared_ptr<Texture> moon_texture_;
|
std::shared_ptr<Texture> grass_texture_; // Textura de hierba
|
||||||
|
std::shared_ptr<Texture> gradients_texture_; // Textura de gradientes
|
||||||
|
std::shared_ptr<Texture> sun_texture_; // Textura del sol
|
||||||
|
std::shared_ptr<Texture> moon_texture_; // Textura de la luna
|
||||||
|
std::unique_ptr<MovingSprite> top_clouds_sprite_a_; // Sprite de nubes superiores A
|
||||||
|
std::unique_ptr<MovingSprite> top_clouds_sprite_b_; // Sprite de nubes superiores B
|
||||||
|
std::unique_ptr<MovingSprite> bottom_clouds_sprite_a_; // Sprite de nubes inferiores A
|
||||||
|
std::unique_ptr<MovingSprite> bottom_clouds_sprite_b_; // Sprite de nubes inferiores B
|
||||||
|
std::unique_ptr<Sprite> buildings_sprite_; // Sprite de edificios
|
||||||
|
std::unique_ptr<Sprite> gradient_sprite_; // Sprite de gradiente
|
||||||
|
std::unique_ptr<Sprite> grass_sprite_; // Sprite de hierba
|
||||||
|
std::unique_ptr<Sprite> sun_sprite_; // Sprite del sol
|
||||||
|
std::unique_ptr<Sprite> moon_sprite_; // Sprite de la luna
|
||||||
|
|
||||||
// Sprites
|
// --- Variables de configuración ---
|
||||||
std::unique_ptr<MovingSprite> top_clouds_sprite_a_;
|
const float total_progress_to_complete_; // Progreso total para completar
|
||||||
std::unique_ptr<MovingSprite> top_clouds_sprite_b_;
|
const float progress_per_stage_; // Progreso por etapa
|
||||||
std::unique_ptr<MovingSprite> bottom_clouds_sprite_a_;
|
const float sun_completion_progress_; // Progreso de completado del sol
|
||||||
std::unique_ptr<MovingSprite> bottom_clouds_sprite_b_;
|
const float minimum_completed_progress_; // Progreso mínimo calculado dinámicamente
|
||||||
std::unique_ptr<Sprite> buildings_sprite_;
|
ProgressCallback progress_callback_; // Callback para notificar cambios de progreso
|
||||||
std::unique_ptr<Sprite> gradient_sprite_;
|
|
||||||
std::unique_ptr<Sprite> grass_sprite_;
|
|
||||||
std::unique_ptr<Sprite> sun_sprite_;
|
|
||||||
std::unique_ptr<Sprite> moon_sprite_;
|
|
||||||
|
|
||||||
// Buffers de renderizado
|
// --- Variables de estado ---
|
||||||
SDL_Texture *canvas_; // Textura para componer el fondo
|
std::vector<SDL_FPoint> sun_path_; // Recorrido del sol
|
||||||
SDL_Texture *color_texture_; // Textura para atenuar el fondo
|
std::vector<SDL_FPoint> moon_path_; // Recorrido de la luna
|
||||||
|
std::array<SDL_FRect, STAGES> gradient_rect_; // Fondos degradados
|
||||||
|
std::array<SDL_FRect, 4> top_clouds_rect_; // Nubes superiores
|
||||||
|
std::array<SDL_FRect, 4> bottom_clouds_rect_; // Nubes inferiores
|
||||||
|
SDL_FRect rect_; // Tamaño del objeto
|
||||||
|
SDL_FRect src_rect_; // Parte del objeto para copiar en pantalla
|
||||||
|
SDL_FRect dst_rect_; // Posición en pantalla donde se copia el objeto
|
||||||
|
Color attenuate_color_; // Color de atenuación
|
||||||
|
State state_ = State::NORMAL; // Estado actual
|
||||||
|
float progress_ = 0.0F; // Progresión interna
|
||||||
|
float clouds_speed_ = 0; // Velocidad de las nubes
|
||||||
|
float transition_ = 0; // Porcentaje de transición
|
||||||
|
size_t gradient_number_ = 0; // Índice de fondo degradado
|
||||||
|
float grass_timer_ = 0.0f; // Timer para animación de hierba (ms)
|
||||||
|
static constexpr float GRASS_FRAME_DURATION = 333.34f; // Duración por frame de hierba (20 frames * 16.67ms)
|
||||||
|
size_t alpha_color_texture_ = 0; // Transparencia de atenuación
|
||||||
|
size_t previous_alpha_color_texture_ = 0; // Transparencia anterior
|
||||||
|
size_t sun_index_ = 0; // Índice del recorrido del sol
|
||||||
|
size_t moon_index_ = 0; // Índice del recorrido de la luna
|
||||||
|
int base_ = 0; // Posición base del fondo
|
||||||
|
Uint8 alpha_ = 0; // Transparencia entre fases
|
||||||
|
bool manual_mode_ = false; // Si está en modo manual
|
||||||
|
|
||||||
// Variables de control
|
// --- Variables para transición suave de completado ---
|
||||||
std::array<SDL_FRect, 4> gradient_rect_;
|
float completion_transition_timer_ = 0.0f; // Timer para la transición de completado
|
||||||
std::array<SDL_FRect, 4> top_clouds_rect_;
|
float completion_initial_progress_ = 0.0f; // Progreso inicial al entrar en estado completado
|
||||||
std::array<SDL_FRect, 4> bottom_clouds_rect_;
|
|
||||||
int gradient_number_ = 0;
|
|
||||||
int alpha_ = 0;
|
|
||||||
float clouds_speed_ = 0;
|
|
||||||
float transition_ = 0;
|
|
||||||
int counter_ = 0;
|
|
||||||
SDL_FRect rect_;
|
|
||||||
SDL_FRect src_rect_;
|
|
||||||
SDL_FRect dst_rect_;
|
|
||||||
int base_;
|
|
||||||
Color attenuate_color_;
|
|
||||||
int alpha_color_text_;
|
|
||||||
int alpha_color_text_temp_;
|
|
||||||
std::vector<SDL_FPoint> sun_path_;
|
|
||||||
std::vector<SDL_FPoint> moon_path_;
|
|
||||||
size_t sun_index_ = 0;
|
|
||||||
size_t moon_index_ = 0;
|
|
||||||
|
|
||||||
// Métodos internos
|
// --- Métodos internos ---
|
||||||
void renderGradient(); // Dibuja el gradiente de fondo
|
void initializePaths(); // Inicializa las rutas del sol y la luna
|
||||||
void renderTopClouds(); // Dibuja las nubes superiores
|
void initializeRects(); // Inicializa los rectángulos de gradientes y nubes
|
||||||
void renderBottomClouds(); // Dibuja las nubes inferiores
|
void initializeSprites(); // Crea los sprites
|
||||||
void fillCanvas(); // Compone todos los elementos en la textura
|
void initializeSpriteProperties(); // Configura las propiedades iniciales de los sprites
|
||||||
void updateAlphaColorTexture(); // Actualiza el alpha de la textura de atenuación
|
void initializeTextures(); // Inicializa las texturas de renderizado
|
||||||
void updateClouds(); // Actualiza el movimiento de las nubes
|
void updateProgression(float delta_time); // Actualiza la progresión y calcula transiciones
|
||||||
void createSunPath(); // Precalcula el recorrido del sol
|
void updateCloudsSpeed(); // Actualiza la velocidad de las nubes según el estado
|
||||||
void createMoonPath(); // Precalcula el recorrido de la luna
|
void renderGradient(); // Dibuja el gradiente de fondo
|
||||||
};
|
void renderTopClouds(); // Dibuja las nubes superiores
|
||||||
|
void renderBottomClouds(); // Dibuja las nubes inferiores
|
||||||
|
void fillCanvas(); // Compone todos los elementos en la textura
|
||||||
|
void updateAlphaColorTexture(); // Actualiza el alpha de la textura de atenuación
|
||||||
|
void updateClouds(float deltaTime); // Actualiza el movimiento de las nubes (time-based)
|
||||||
|
void createSunPath(); // Precalcula el recorrido del sol
|
||||||
|
void createMoonPath(); // Precalcula el recorrido de la luna
|
||||||
|
};
|
||||||
@@ -11,24 +11,25 @@
|
|||||||
#include "texture.h" // Para Texture
|
#include "texture.h" // Para Texture
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
Balloon::Balloon(float x, float y, Type type, Size size, float vel_x, float speed, Uint16 creation_timer, SDL_FRect play_area, std::shared_ptr<Texture> texture, const std::vector<std::string> &animation)
|
Balloon::Balloon(const Config& config)
|
||||||
: sprite_(std::make_unique<AnimatedSprite>(texture, animation)),
|
: sprite_(std::make_unique<AnimatedSprite>(config.texture, config.animation)),
|
||||||
x_(x),
|
x_(config.x),
|
||||||
y_(y),
|
y_(config.y),
|
||||||
vx_(vel_x),
|
vx_(config.vel_x),
|
||||||
being_created_(creation_timer > 0),
|
being_created_(config.creation_counter > 0),
|
||||||
invulnerable_(creation_timer > 0),
|
invulnerable_(config.creation_counter > 0),
|
||||||
stopped_(creation_timer > 0),
|
stopped_(config.creation_counter > 0),
|
||||||
creation_counter_(creation_timer),
|
creation_counter_(config.creation_counter),
|
||||||
creation_counter_ini_(creation_timer),
|
creation_counter_ini_(config.creation_counter),
|
||||||
type_(type),
|
type_(config.type),
|
||||||
size_(size),
|
size_(config.size),
|
||||||
speed_(speed),
|
game_tempo_(config.game_tempo),
|
||||||
play_area_(play_area) {
|
play_area_(config.play_area),
|
||||||
|
sound_(config.sound) {
|
||||||
switch (type_) {
|
switch (type_) {
|
||||||
case Type::BALLOON: {
|
case Type::BALLOON: {
|
||||||
vy_ = 0;
|
vy_ = 0;
|
||||||
max_vy_ = 3.0F;
|
max_vy_ = 3.0F * 60.0F; // Convert from frames to seconds (180 pixels/s)
|
||||||
|
|
||||||
const int INDEX = static_cast<int>(size_);
|
const int INDEX = static_cast<int>(size_);
|
||||||
gravity_ = param.balloon.settings.at(INDEX).grav;
|
gravity_ = param.balloon.settings.at(INDEX).grav;
|
||||||
@@ -37,14 +38,13 @@ Balloon::Balloon(float x, float y, Type type, Size size, float vel_x, float spee
|
|||||||
power_ = POWER.at(INDEX);
|
power_ = POWER.at(INDEX);
|
||||||
menace_ = MENACE.at(INDEX);
|
menace_ = MENACE.at(INDEX);
|
||||||
score_ = SCORE.at(INDEX);
|
score_ = SCORE.at(INDEX);
|
||||||
bouncing_sound_ = BOUNCING_SOUND.at(INDEX);
|
sound_.bouncing_file = BOUNCING_SOUND.at(INDEX);
|
||||||
popping_sound_ = POPPING_SOUND.at(INDEX);
|
sound_.popping_file = POPPING_SOUND.at(INDEX);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case Type::FLOATER: {
|
case Type::FLOATER: {
|
||||||
default_vy_ = max_vy_ = vy_ = fabs(vx_ * 2.0F);
|
default_vy_ = max_vy_ = vy_ = std::fabs(vx_ * 2.0F);
|
||||||
gravity_ = 0.00F;
|
gravity_ = 0.00F;
|
||||||
|
|
||||||
const int INDEX = static_cast<int>(size_);
|
const int INDEX = static_cast<int>(size_);
|
||||||
@@ -52,27 +52,25 @@ Balloon::Balloon(float x, float y, Type type, Size size, float vel_x, float spee
|
|||||||
power_ = POWER.at(INDEX);
|
power_ = POWER.at(INDEX);
|
||||||
menace_ = MENACE.at(INDEX);
|
menace_ = MENACE.at(INDEX);
|
||||||
score_ = SCORE.at(INDEX);
|
score_ = SCORE.at(INDEX);
|
||||||
bouncing_sound_ = BOUNCING_SOUND.at(INDEX);
|
sound_.bouncing_file = BOUNCING_SOUND.at(INDEX);
|
||||||
popping_sound_ = POPPING_SOUND.at(INDEX);
|
sound_.popping_file = POPPING_SOUND.at(INDEX);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case Type::POWERBALL: {
|
case Type::POWERBALL: {
|
||||||
constexpr int INDEX = 3;
|
constexpr int INDEX = 3;
|
||||||
h_ = w_ = WIDTH.at(4);
|
h_ = w_ = WIDTH.at(4);
|
||||||
bouncing_sound_ = BOUNCING_SOUND.at(3);
|
sound_.bouncing_file = BOUNCING_SOUND.at(3);
|
||||||
popping_sound_ = "power_ball_explosion.wav";
|
sound_.popping_file = "power_ball_explosion.wav";
|
||||||
power_ = score_ = menace_ = 0;
|
power_ = score_ = menace_ = 0;
|
||||||
|
|
||||||
vy_ = 0;
|
vy_ = 0;
|
||||||
max_vy_ = 3.0F;
|
max_vy_ = 3.0F * 60.0F; // Convert from frames to seconds (180 pixels/s)
|
||||||
gravity_ = param.balloon.settings.at(INDEX).grav;
|
gravity_ = param.balloon.settings.at(INDEX).grav;
|
||||||
default_vy_ = param.balloon.settings.at(INDEX).vel;
|
default_vy_ = param.balloon.settings.at(INDEX).vel;
|
||||||
|
|
||||||
sprite_->setRotate(creation_timer <= 0);
|
sprite_->setRotate(config.creation_counter <= 0);
|
||||||
sprite_->setRotateAmount(vx_ > 0.0F ? 2.0 : -2.0);
|
sprite_->setRotateAmount(vx_ > 0.0F ? 120.0 : -120.0); // Convert from 2 degrees/frame to 120 degrees/second
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,14 +89,19 @@ Balloon::Balloon(float x, float y, Type type, Size size, float vel_x, float spee
|
|||||||
|
|
||||||
// Establece la animación a usar
|
// Establece la animación a usar
|
||||||
setAnimation();
|
setAnimation();
|
||||||
|
|
||||||
|
// Si no se está creando (creation_counter = 0), asegurar estado activo
|
||||||
|
if (!being_created_) {
|
||||||
|
start();
|
||||||
|
setInvulnerable(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Centra el globo en la posición X
|
// Centra el globo en la posición X
|
||||||
void Balloon::alignTo(int x) {
|
void Balloon::alignTo(int x) {
|
||||||
x_ = static_cast<float>(x - (w_ / 2));
|
const float MIN_X = play_area_.x;
|
||||||
const int MIN_X = play_area_.x;
|
const float MAX_X = play_area_.w - w_;
|
||||||
const int MAX_X = play_area_.w - w_;
|
x_ = std::clamp(x - (w_ / 2), MIN_X, MAX_X);
|
||||||
x_ = std::clamp(x_, static_cast<float>(MIN_X), static_cast<float>(MAX_X));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pinta el globo en la pantalla
|
// Pinta el globo en la pantalla
|
||||||
@@ -138,19 +141,20 @@ void Balloon::render() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Actualiza la posición y estados del globo
|
// Actualiza la posición y estados del globo (time-based)
|
||||||
void Balloon::move() {
|
void Balloon::move(float deltaTime) {
|
||||||
if (isStopped()) {
|
if (isStopped()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
handleHorizontalMovement();
|
handleHorizontalMovement(deltaTime);
|
||||||
handleVerticalMovement();
|
handleVerticalMovement(deltaTime);
|
||||||
applyGravity();
|
applyGravity(deltaTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Balloon::handleHorizontalMovement() {
|
void Balloon::handleHorizontalMovement(float deltaTime) {
|
||||||
x_ += vx_ * speed_;
|
// DeltaTime en segundos: velocidad (pixels/s) * tempo * tiempo (s)
|
||||||
|
x_ += vx_ * game_tempo_ * deltaTime;
|
||||||
|
|
||||||
const int CLIP = 2;
|
const int CLIP = 2;
|
||||||
const float MIN_X = play_area_.x - CLIP;
|
const float MIN_X = play_area_.x - CLIP;
|
||||||
@@ -161,8 +165,9 @@ void Balloon::handleHorizontalMovement() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Balloon::handleVerticalMovement() {
|
void Balloon::handleVerticalMovement(float deltaTime) {
|
||||||
y_ += vy_ * speed_;
|
// DeltaTime en segundos: velocidad (pixels/s) * tempo * tiempo (s)
|
||||||
|
y_ += vy_ * game_tempo_ * deltaTime;
|
||||||
|
|
||||||
if (shouldCheckTopCollision()) {
|
if (shouldCheckTopCollision()) {
|
||||||
handleTopCollision();
|
handleTopCollision();
|
||||||
@@ -217,41 +222,37 @@ void Balloon::handleBottomCollision() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Balloon::applyGravity() {
|
void Balloon::applyGravity(float deltaTime) {
|
||||||
/*
|
// DeltaTime en segundos: aceleración (pixels/s²) * tempo * tiempo (s)
|
||||||
Para aplicar la gravedad, el diseño original la aplicaba en cada iteración del bucle
|
vy_ += gravity_ * game_tempo_ * deltaTime;
|
||||||
Al añadir el modificador de velocidad se reduce la distancia que recorre el objeto y por
|
|
||||||
tanto recibe mas gravedad. Para solucionarlo se va a aplicar la gravedad cuando se haya
|
|
||||||
recorrido una distancia igual a la velocidad en Y, que era el cálculo inicial
|
|
||||||
*/
|
|
||||||
|
|
||||||
travel_y_ += speed_;
|
|
||||||
|
|
||||||
if (travel_y_ >= 1.0F) {
|
|
||||||
travel_y_ -= 1.0F;
|
|
||||||
vy_ += gravity_;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Balloon::playBouncingSound() {
|
void Balloon::playBouncingSound() {
|
||||||
if (bouncing_sound_enabled_) {
|
if (sound_.enabled && sound_.bouncing_enabled) {
|
||||||
playSound(bouncing_sound_);
|
Audio::get()->playSound(sound_.bouncing_file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Actualiza al globo a su posicion, animación y controla los contadores
|
void Balloon::playPoppingSound() {
|
||||||
void Balloon::update() {
|
if (sound_.enabled && sound_.poping_enabled) {
|
||||||
move();
|
Audio::get()->playSound(sound_.popping_file);
|
||||||
updateState();
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Actualiza al globo a su posicion, animación y controla los contadores (time-based)
|
||||||
|
void Balloon::update(float deltaTime) {
|
||||||
|
move(deltaTime);
|
||||||
|
updateState(deltaTime);
|
||||||
updateBounceEffect();
|
updateBounceEffect();
|
||||||
shiftSprite();
|
shiftSprite();
|
||||||
shiftColliders();
|
shiftColliders();
|
||||||
sprite_->update();
|
sprite_->update(deltaTime);
|
||||||
++counter_;
|
// Contador interno con deltaTime en segundos
|
||||||
|
counter_ += deltaTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Actualiza los estados del globo
|
// Actualiza los estados del globo (time-based)
|
||||||
void Balloon::updateState() {
|
void Balloon::updateState(float deltaTime) {
|
||||||
// Si se está creando
|
// Si se está creando
|
||||||
if (isBeingCreated()) {
|
if (isBeingCreated()) {
|
||||||
// Actualiza el valor de las variables
|
// Actualiza el valor de las variables
|
||||||
@@ -260,9 +261,14 @@ void Balloon::updateState() {
|
|||||||
|
|
||||||
if (creation_counter_ > 0) {
|
if (creation_counter_ > 0) {
|
||||||
// Desplaza lentamente el globo hacia abajo y hacia un lado
|
// Desplaza lentamente el globo hacia abajo y hacia un lado
|
||||||
if (creation_counter_ % 10 == 0) {
|
// Cada 10/60 segundos (equivalente a 10 frames a 60fps)
|
||||||
|
movement_accumulator_ += deltaTime;
|
||||||
|
|
||||||
|
constexpr float MOVEMENT_INTERVAL_S = 10.0f / 60.0f; // 10 frames = ~0.167s
|
||||||
|
if (movement_accumulator_ >= MOVEMENT_INTERVAL_S) {
|
||||||
|
movement_accumulator_ -= MOVEMENT_INTERVAL_S;
|
||||||
y_++;
|
y_++;
|
||||||
x_ += vx_;
|
x_ += vx_ / 60.0f; // Convierte de pixels/segundo a pixels/frame para movimiento discreto
|
||||||
|
|
||||||
// Comprueba no se salga por los laterales
|
// Comprueba no se salga por los laterales
|
||||||
const int MIN_X = play_area_.x;
|
const int MIN_X = play_area_.x;
|
||||||
@@ -270,11 +276,12 @@ void Balloon::updateState() {
|
|||||||
|
|
||||||
if (x_ < MIN_X || x_ > MAX_X) {
|
if (x_ < MIN_X || x_ > MAX_X) {
|
||||||
// Corrige y cambia el sentido de la velocidad
|
// Corrige y cambia el sentido de la velocidad
|
||||||
x_ -= vx_;
|
x_ -= vx_ / 60.0f;
|
||||||
vx_ = -vx_;
|
vx_ = -vx_;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
--creation_counter_;
|
creation_counter_ -= deltaTime;
|
||||||
|
if (creation_counter_ < 0) creation_counter_ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
else {
|
else {
|
||||||
@@ -308,11 +315,14 @@ void Balloon::setAnimation() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Establece el frame de animación
|
// Establece el frame de animación
|
||||||
|
std::string chosen_animation;
|
||||||
if (use_reversed_colors_) {
|
if (use_reversed_colors_) {
|
||||||
sprite_->setCurrentAnimation(creating_animation);
|
chosen_animation = creating_animation;
|
||||||
} else {
|
} else {
|
||||||
sprite_->setCurrentAnimation(isBeingCreated() ? creating_animation : normal_animation);
|
chosen_animation = isBeingCreated() ? creating_animation : normal_animation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sprite_->setCurrentAnimation(chosen_animation);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Detiene el globo
|
// Detiene el globo
|
||||||
@@ -369,23 +379,8 @@ void Balloon::useNormalColor() {
|
|||||||
setAnimation();
|
setAnimation();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reproduce sonido
|
|
||||||
void Balloon::playSound(const std::string &name) const {
|
|
||||||
if (!sound_enabled_) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
static auto *audio_ = Audio::get();
|
|
||||||
audio_->playSound(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Explota el globo
|
// Explota el globo
|
||||||
void Balloon::pop(bool should_sound) {
|
void Balloon::pop(bool should_sound) {
|
||||||
if (should_sound) {
|
if (should_sound) { playPoppingSound(); }
|
||||||
if (poping_sound_enabled_) {
|
|
||||||
playSound(popping_sound_);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
enabled_ = false;
|
enabled_ = false;
|
||||||
}
|
}
|
||||||
185
source/balloon.h
@@ -25,52 +25,75 @@ class Balloon {
|
|||||||
static constexpr std::array<int, 5> WIDTH = {10, 16, 26, 48, 49};
|
static constexpr std::array<int, 5> WIDTH = {10, 16, 26, 48, 49};
|
||||||
|
|
||||||
static constexpr std::array<std::string_view, 4> BOUNCING_SOUND = {
|
static constexpr std::array<std::string_view, 4> BOUNCING_SOUND = {
|
||||||
"balloon_bounce0.wav", "balloon_bounce1.wav", "balloon_bounce2.wav", "balloon_bounce3.wav"};
|
"balloon_bounce0.wav",
|
||||||
|
"balloon_bounce1.wav",
|
||||||
|
"balloon_bounce2.wav",
|
||||||
|
"balloon_bounce3.wav"};
|
||||||
|
|
||||||
static constexpr std::array<std::string_view, 4> POPPING_SOUND = {
|
static constexpr std::array<std::string_view, 4> POPPING_SOUND = {
|
||||||
"balloon_pop0.wav", "balloon_pop1.wav", "balloon_pop2.wav", "balloon_pop3.wav"};
|
"balloon_pop0.wav",
|
||||||
|
"balloon_pop1.wav",
|
||||||
|
"balloon_pop2.wav",
|
||||||
|
"balloon_pop3.wav"};
|
||||||
|
|
||||||
static constexpr float VELX_POSITIVE = 0.7F;
|
// Velocidades horizontales en pixels/segundo (convertidas desde 0.7 pixels/frame a 60fps)
|
||||||
static constexpr float VELX_NEGATIVE = -0.7F;
|
static constexpr float VELX_POSITIVE = 0.7F * 60.0F; // 42 pixels/segundo
|
||||||
|
static constexpr float VELX_NEGATIVE = -0.7F * 60.0F; // -42 pixels/segundo
|
||||||
|
|
||||||
static constexpr std::array<float, 5> SPEED = {0.60F, 0.70F, 0.80F, 0.90F, 1.00F};
|
// Multiplicadores de tempo del juego (sin cambios, son puros multiplicadores)
|
||||||
|
static constexpr std::array<float, 5> GAME_TEMPO = {0.60F, 0.70F, 0.80F, 0.90F, 1.00F};
|
||||||
|
|
||||||
static constexpr int POWERBALL_SCREENPOWER_MINIMUM = 10;
|
static constexpr int POWERBALL_SCREENPOWER_MINIMUM = 10;
|
||||||
static constexpr int POWERBALL_COUNTER = 8;
|
static constexpr int POWERBALL_COUNTER = 8;
|
||||||
|
|
||||||
|
// --- Enums ---
|
||||||
enum class Size : Uint8 {
|
enum class Size : Uint8 {
|
||||||
SMALL = 0,
|
SMALL = 0, // Tamaño pequeño
|
||||||
MEDIUM = 1,
|
MEDIUM = 1, // Tamaño mediano
|
||||||
LARGE = 2,
|
LARGE = 2, // Tamaño grande
|
||||||
EXTRALARGE = 3,
|
EXTRALARGE = 3, // Tamaño extra grande
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class Type : Uint8 {
|
enum class Type : Uint8 {
|
||||||
BALLOON = 0,
|
BALLOON = 0, // Globo normal
|
||||||
FLOATER = 1,
|
FLOATER = 1, // Globo flotante
|
||||||
POWERBALL = 2,
|
POWERBALL = 2, // Globo de poder
|
||||||
|
};
|
||||||
|
|
||||||
|
// --- Estructura para manejo de sonido ---
|
||||||
|
struct Sound {
|
||||||
|
std::string bouncing_file; // Archivo de sonido al rebotar
|
||||||
|
std::string popping_file; // Archivo de sonido al explotar
|
||||||
|
bool bouncing_enabled = false; // Si debe sonar el globo al rebotar
|
||||||
|
bool poping_enabled = true; // Si debe sonar el globo al explotar
|
||||||
|
bool enabled = true; // Indica si los globos deben hacer algun sonido
|
||||||
|
};
|
||||||
|
|
||||||
|
// --- Estructura de configuración para inicialización ---
|
||||||
|
struct Config {
|
||||||
|
float x = 0.0F;
|
||||||
|
float y = 0.0F;
|
||||||
|
Type type = Type::BALLOON;
|
||||||
|
Size size = Size::EXTRALARGE;
|
||||||
|
float vel_x = VELX_POSITIVE;
|
||||||
|
float game_tempo = GAME_TEMPO.at(0);
|
||||||
|
float creation_counter = 0.0f;
|
||||||
|
SDL_FRect play_area = {.x = 0.0F, .y = 0.0F, .w = 0.0F, .h = 0.0F};
|
||||||
|
std::shared_ptr<Texture> texture = nullptr;
|
||||||
|
std::vector<std::string> animation;
|
||||||
|
Sound sound;
|
||||||
};
|
};
|
||||||
|
|
||||||
// --- Constructores y destructor ---
|
// --- Constructores y destructor ---
|
||||||
Balloon(
|
Balloon(const Config& config);
|
||||||
float x,
|
|
||||||
float y,
|
|
||||||
Type type,
|
|
||||||
Size size,
|
|
||||||
float vel_x,
|
|
||||||
float speed,
|
|
||||||
Uint16 creation_timer,
|
|
||||||
SDL_FRect play_area,
|
|
||||||
std::shared_ptr<Texture> texture,
|
|
||||||
const std::vector<std::string>& animation);
|
|
||||||
~Balloon() = default;
|
~Balloon() = default;
|
||||||
|
|
||||||
// --- Métodos principales ---
|
// --- Métodos principales ---
|
||||||
void alignTo(int x); // Centra el globo en la posición X
|
void alignTo(int x); // Centra el globo en la posición X
|
||||||
void render(); // Pinta el globo en la pantalla
|
void render(); // Pinta el globo en la pantalla
|
||||||
void move(); // Actualiza la posición y estados del globo
|
void move(float deltaTime); // Actualiza la posición y estados del globo (time-based)
|
||||||
void update(); // Actualiza el globo (posición, animación, contadores)
|
void update(float deltaTime); // Actualiza el globo (posición, animación, contadores) (time-based)
|
||||||
void stop(); // Detiene el globo
|
void stop(); // Detiene el globo
|
||||||
void start(); // Pone el globo en movimiento
|
void start(); // Pone el globo en movimiento
|
||||||
void pop(bool should_sound = false); // Explota el globo
|
void pop(bool should_sound = false); // Explota el globo
|
||||||
|
|
||||||
@@ -99,11 +122,13 @@ class Balloon {
|
|||||||
|
|
||||||
// --- Setters ---
|
// --- Setters ---
|
||||||
void setVelY(float vel_y) { vy_ = vel_y; }
|
void setVelY(float vel_y) { vy_ = vel_y; }
|
||||||
void setSpeed(float speed) { speed_ = speed; }
|
void setVelX(float vel_x) { vx_ = vel_x; }
|
||||||
|
void alterVelX(float percent) {vx_ *= percent; }
|
||||||
|
void setGameTempo(float tempo) { game_tempo_ = tempo; }
|
||||||
void setInvulnerable(bool value) { invulnerable_ = value; }
|
void setInvulnerable(bool value) { invulnerable_ = value; }
|
||||||
void setBouncingSound(bool value) { bouncing_sound_enabled_ = value; }
|
void setBouncingSound(bool value) { sound_.bouncing_enabled = value; }
|
||||||
void setPoppingSound(bool value) { poping_sound_enabled_ = value; }
|
void setPoppingSound(bool value) { sound_.poping_enabled = value; }
|
||||||
void setSound(bool value) { sound_enabled_ = value; }
|
void setSound(bool value) { sound_.enabled = value; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// --- Estructura para el efecto de rebote ---
|
// --- Estructura para el efecto de rebote ---
|
||||||
@@ -113,10 +138,28 @@ class Balloon {
|
|||||||
|
|
||||||
// Tablas de valores predefinidos para el efecto de rebote
|
// Tablas de valores predefinidos para el efecto de rebote
|
||||||
static constexpr std::array<float, BOUNCE_FRAMES> HORIZONTAL_ZOOM_VALUES = {
|
static constexpr std::array<float, BOUNCE_FRAMES> HORIZONTAL_ZOOM_VALUES = {
|
||||||
1.10F, 1.05F, 1.00F, 0.95F, 0.90F, 0.95F, 1.00F, 1.02F, 1.05F, 1.02F};
|
1.10F,
|
||||||
|
1.05F,
|
||||||
|
1.00F,
|
||||||
|
0.95F,
|
||||||
|
0.90F,
|
||||||
|
0.95F,
|
||||||
|
1.00F,
|
||||||
|
1.02F,
|
||||||
|
1.05F,
|
||||||
|
1.02F};
|
||||||
|
|
||||||
static constexpr std::array<float, BOUNCE_FRAMES> VERTICAL_ZOOM_VALUES = {
|
static constexpr std::array<float, BOUNCE_FRAMES> VERTICAL_ZOOM_VALUES = {
|
||||||
0.90F, 0.95F, 1.00F, 1.05F, 1.10F, 1.05F, 1.00F, 0.98F, 0.95F, 0.98F};
|
0.90F,
|
||||||
|
0.95F,
|
||||||
|
1.00F,
|
||||||
|
1.05F,
|
||||||
|
1.10F,
|
||||||
|
1.05F,
|
||||||
|
1.00F,
|
||||||
|
0.98F,
|
||||||
|
0.95F,
|
||||||
|
0.98F};
|
||||||
|
|
||||||
// Estado del efecto
|
// Estado del efecto
|
||||||
bool enabled_ = false; // Si el efecto está activo
|
bool enabled_ = false; // Si el efecto está activo
|
||||||
@@ -202,52 +245,48 @@ class Balloon {
|
|||||||
std::unique_ptr<AnimatedSprite> sprite_; // Sprite del objeto globo
|
std::unique_ptr<AnimatedSprite> sprite_; // Sprite del objeto globo
|
||||||
|
|
||||||
// --- Variables de estado y físicas ---
|
// --- Variables de estado y físicas ---
|
||||||
float x_; // Posición X
|
float x_; // Posición X
|
||||||
float y_; // Posición Y
|
float y_; // Posición Y
|
||||||
float w_; // Ancho
|
float w_; // Ancho
|
||||||
float h_; // Alto
|
float h_; // Alto
|
||||||
float vx_; // Velocidad X
|
float vx_; // Velocidad X
|
||||||
float vy_; // Velocidad Y
|
float vy_; // Velocidad Y
|
||||||
float gravity_; // Aceleración en Y
|
float gravity_; // Aceleración en Y
|
||||||
float default_vy_; // Velocidad inicial al rebotar
|
float default_vy_; // Velocidad inicial al rebotar
|
||||||
float max_vy_; // Máxima velocidad en Y
|
float max_vy_; // Máxima velocidad en Y
|
||||||
bool being_created_; // Si el globo se está creando
|
bool being_created_; // Si el globo se está creando
|
||||||
bool enabled_ = true; // Si el globo está activo
|
bool enabled_ = true; // Si el globo está activo
|
||||||
bool invulnerable_; // Si el globo es invulnerable
|
bool invulnerable_; // Si el globo es invulnerable
|
||||||
bool stopped_; // Si el globo está parado
|
bool stopped_; // Si el globo está parado
|
||||||
bool use_reversed_colors_ = false; // Si se usa el color alternativo
|
bool use_reversed_colors_ = false; // Si se usa el color alternativo
|
||||||
Circle collider_; // Círculo de colisión
|
Circle collider_; // Círculo de colisión
|
||||||
Uint16 creation_counter_; // Temporizador de creación
|
float creation_counter_; // Temporizador de creación
|
||||||
Uint16 creation_counter_ini_; // Valor inicial del temporizador de creación
|
float creation_counter_ini_; // Valor inicial del temporizador de creación
|
||||||
Uint16 score_; // Puntos al destruir el globo
|
Uint16 score_; // Puntos al destruir el globo
|
||||||
Type type_; // Tipo de globo
|
Type type_; // Tipo de globo
|
||||||
Size size_; // Tamaño de globo
|
Size size_; // Tamaño de globo
|
||||||
Uint8 menace_; // Amenaza que genera el globo
|
Uint8 menace_; // Amenaza que genera el globo
|
||||||
Uint32 counter_ = 0; // Contador interno
|
Uint32 counter_ = 0; // Contador interno
|
||||||
float travel_y_ = 1.0F; // Distancia a recorrer en Y antes de aplicar gravedad
|
float game_tempo_; // Multiplicador de tempo del juego
|
||||||
float speed_; // Velocidad del globo
|
float movement_accumulator_ = 0.0f; // Acumulador para movimiento durante creación (deltaTime)
|
||||||
Uint8 power_; // Poder que alberga el globo
|
Uint8 power_; // Poder que alberga el globo
|
||||||
SDL_FRect play_area_; // Zona de movimiento del globo
|
SDL_FRect play_area_; // Zona de movimiento del globo
|
||||||
std::string bouncing_sound_; // Archivo de sonido al rebotar
|
Sound sound_; // Configuración de sonido del globo
|
||||||
std::string popping_sound_; // Archivo de sonido al explotar
|
BounceEffect bounce_effect_; // Efecto de rebote
|
||||||
bool bouncing_sound_enabled_ = false; // Si debe sonar el globo al rebotar
|
|
||||||
bool poping_sound_enabled_ = true; // Si debe sonar el globo al explotar
|
|
||||||
bool sound_enabled_ = true; // Indica si los globos deben hacer algun sonido
|
|
||||||
BounceEffect bounce_effect_; // Efecto de rebote
|
|
||||||
|
|
||||||
// --- Posicionamiento y transformación ---
|
// --- Posicionamiento y transformación ---
|
||||||
void shiftColliders(); // Alinea el círculo de colisión con el sprite
|
void shiftColliders(); // Alinea el círculo de colisión con el sprite
|
||||||
void shiftSprite(); // Alinea el sprite en pantalla
|
void shiftSprite(); // Alinea el sprite en pantalla
|
||||||
|
|
||||||
// --- Animación y sonido ---
|
// --- Animación y sonido ---
|
||||||
void setAnimation(); // Establece la animación correspondiente
|
void setAnimation(); // Establece la animación correspondiente
|
||||||
void playSound(const std::string& name) const; // Reproduce un sonido por nombre
|
void playBouncingSound(); // Reproduce el sonido de rebote
|
||||||
void playBouncingSound(); // Reproduce el sonido de rebote
|
void playPoppingSound(); // Reproduce el sonido de reventar
|
||||||
|
|
||||||
// --- Movimiento y física ---
|
// --- Movimiento y física ---
|
||||||
void handleHorizontalMovement(); // Maneja el movimiento horizontal
|
void handleHorizontalMovement(float deltaTime); // Maneja el movimiento horizontal (time-based)
|
||||||
void handleVerticalMovement(); // Maneja el movimiento vertical
|
void handleVerticalMovement(float deltaTime); // Maneja el movimiento vertical (time-based)
|
||||||
void applyGravity(); // Aplica la gravedad al objeto
|
void applyGravity(float deltaTime); // Aplica la gravedad al objeto (time-based)
|
||||||
|
|
||||||
// --- Rebote ---
|
// --- Rebote ---
|
||||||
void enableBounceEffect(); // Activa el efecto de rebote
|
void enableBounceEffect(); // Activa el efecto de rebote
|
||||||
@@ -262,5 +301,5 @@ class Balloon {
|
|||||||
void handleBottomCollision(); // Maneja la colisión inferior
|
void handleBottomCollision(); // Maneja la colisión inferior
|
||||||
|
|
||||||
// --- Lógica de estado ---
|
// --- Lógica de estado ---
|
||||||
void updateState(); // Actualiza los estados del globo
|
void updateState(float deltaTime); // Actualiza los estados del globo (time-based)
|
||||||
};
|
};
|
||||||
@@ -155,7 +155,7 @@ auto BalloonFormations::parseBalloonLine(const std::string& line, const std::map
|
|||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
int creation_time = DEFAULT_CREATION_TIME + evaluateExpression(tokens.at(6), variables);
|
float creation_time = CREATION_TIME + evaluateExpression(tokens.at(6), variables); // Base time + offset from formations.txt
|
||||||
|
|
||||||
return SpawnParams(x + offset, y, vel_x, type, size, creation_time);
|
return SpawnParams(x + offset, y, vel_x, type, size, creation_time);
|
||||||
} catch (const std::exception&) {
|
} catch (const std::exception&) {
|
||||||
@@ -168,7 +168,7 @@ auto BalloonFormations::evaluateExpression(const std::string& expr, const std::m
|
|||||||
|
|
||||||
// Si es un número directo
|
// Si es un número directo
|
||||||
if ((std::isdigit(trimmed_expr.at(0)) != 0) || (trimmed_expr.at(0) == '-' && trimmed_expr.length() > 1)) {
|
if ((std::isdigit(trimmed_expr.at(0)) != 0) || (trimmed_expr.at(0) == '-' && trimmed_expr.length() > 1)) {
|
||||||
return std::stoi(trimmed_expr);
|
return std::stof(trimmed_expr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Si es una variable simple
|
// Si es una variable simple
|
||||||
@@ -205,7 +205,7 @@ auto BalloonFormations::evaluateSimpleExpression(const std::string& expr, const
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Si no se encuentra operador, intentar como variable o número
|
// Si no se encuentra operador, intentar como variable o número
|
||||||
return variables.find(expr) != variables.end() ? variables.at(expr) : std::stoi(expr);
|
return variables.find(expr) != variables.end() ? variables.at(expr) : std::stof(expr);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto BalloonFormations::trim(const std::string& str) -> std::string {
|
auto BalloonFormations::trim(const std::string& str) -> std::string {
|
||||||
@@ -235,10 +235,10 @@ void BalloonFormations::createFloaterVariants() {
|
|||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
void BalloonFormations::addTestFormation() {
|
void BalloonFormations::addTestFormation() {
|
||||||
std::vector<SpawnParams> test_params = {
|
std::vector<SpawnParams> test_params = {
|
||||||
{10, -BLOCK, 0, Balloon::Type::FLOATER, Balloon::Size::SMALL, 200},
|
{10, -BLOCK, 0, Balloon::Type::FLOATER, Balloon::Size::SMALL, 3.334f}, // 200 frames ÷ 60fps = 3.334s
|
||||||
{50, -BLOCK, 0, Balloon::Type::FLOATER, Balloon::Size::MEDIUM, 200},
|
{50, -BLOCK, 0, Balloon::Type::FLOATER, Balloon::Size::MEDIUM, 3.334f}, // 200 frames ÷ 60fps = 3.334s
|
||||||
{90, -BLOCK, 0, Balloon::Type::FLOATER, Balloon::Size::LARGE, 200},
|
{90, -BLOCK, 0, Balloon::Type::FLOATER, Balloon::Size::LARGE, 3.334f}, // 200 frames ÷ 60fps = 3.334s
|
||||||
{140, -BLOCK, 0, Balloon::Type::FLOATER, Balloon::Size::EXTRALARGE, 200}};
|
{140, -BLOCK, 0, Balloon::Type::FLOATER, Balloon::Size::EXTRALARGE, 3.334f}}; // 200 frames ÷ 60fps = 3.334s
|
||||||
|
|
||||||
formations_.at(99) = Formation(test_params);
|
formations_.at(99) = Formation(test_params);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,21 +13,26 @@
|
|||||||
// --- Clase BalloonFormations ---
|
// --- Clase BalloonFormations ---
|
||||||
class BalloonFormations {
|
class BalloonFormations {
|
||||||
public:
|
public:
|
||||||
// --- Estructuras de datos ---
|
// --- Estructuras ---
|
||||||
struct SpawnParams {
|
struct SpawnParams {
|
||||||
int x = 0; // Posición en el eje X donde crear el globo
|
float x = 0; // Posición en el eje X donde crear el globo
|
||||||
int y = 0; // Posición en el eje Y donde crear el globo
|
float y = 0; // Posición en el eje Y donde crear el globo
|
||||||
float vel_x = 0.0F; // Velocidad inicial en el eje X
|
float vel_x = 0.0F; // Velocidad inicial en el eje X
|
||||||
Balloon::Type type = Balloon::Type::BALLOON; // Tipo de globo
|
Balloon::Type type = Balloon::Type::BALLOON; // Tipo de globo
|
||||||
Balloon::Size size = Balloon::Size::SMALL; // Tamaño de globo
|
Balloon::Size size = Balloon::Size::SMALL; // Tamaño de globo
|
||||||
int creation_counter = 0; // Temporizador para la creación del globo
|
float creation_counter = 0.0f; // Temporizador para la creación del globo
|
||||||
|
|
||||||
// Constructor por defecto
|
// Constructor por defecto
|
||||||
SpawnParams() = default;
|
SpawnParams() = default;
|
||||||
|
|
||||||
// Constructor con parámetros
|
// Constructor con parámetros
|
||||||
SpawnParams(int x, int y, float vel_x, Balloon::Type type, Balloon::Size size, int creation_counter)
|
SpawnParams(float x, float y, float vel_x, Balloon::Type type, Balloon::Size size, float creation_counter)
|
||||||
: x(x), y(y), vel_x(vel_x), type(type), size(size), creation_counter(creation_counter) {}
|
: x(x),
|
||||||
|
y(y),
|
||||||
|
vel_x(vel_x),
|
||||||
|
type(type),
|
||||||
|
size(size),
|
||||||
|
creation_counter(creation_counter) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Formation {
|
struct Formation {
|
||||||
@@ -41,8 +46,8 @@ class BalloonFormations {
|
|||||||
Formation() = default;
|
Formation() = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Vector de índices a formaciones
|
// --- Types ---
|
||||||
using Pool = std::vector<int>;
|
using Pool = std::vector<int>; // Vector de índices a formaciones
|
||||||
|
|
||||||
// --- Constructor y destructor ---
|
// --- Constructor y destructor ---
|
||||||
BalloonFormations() {
|
BalloonFormations() {
|
||||||
@@ -77,30 +82,23 @@ class BalloonFormations {
|
|||||||
private:
|
private:
|
||||||
// --- Constantes ---
|
// --- Constantes ---
|
||||||
static constexpr int BALLOON_SPAWN_HEIGHT = 208; // Altura desde el suelo en la que aparecen los globos
|
static constexpr int BALLOON_SPAWN_HEIGHT = 208; // Altura desde el suelo en la que aparecen los globos
|
||||||
static constexpr int DEFAULT_CREATION_TIME = 200; // Tiempo base de creación de los globos para las formaciones
|
static constexpr float CREATION_TIME = 5.0f; // Tiempo base de creación de los globos en segundos (300 frames ÷ 60fps = 5.0s)
|
||||||
|
static constexpr float DEFAULT_CREATION_TIME = 3.334f; // Tiempo base de creación de los globos en segundos (200 frames ÷ 60fps = 3.334s)
|
||||||
|
|
||||||
// --- Datos ---
|
// --- Variables ---
|
||||||
std::vector<Formation> formations_; // Vector con todas las formaciones disponibles
|
std::vector<Formation> formations_; // Vector con todas las formaciones disponibles
|
||||||
std::vector<Pool> pools_; // Vector de pools, cada pool contiene índices a formaciones
|
std::vector<Pool> pools_; // Vector de pools, cada pool contiene índices a formaciones
|
||||||
|
|
||||||
// --- Inicialización de formaciones ---
|
// --- Métodos internos ---
|
||||||
void initFormations(); // Inicializa la lista principal de formaciones de globos disponibles
|
void initFormations(); // Inicializa la lista principal de formaciones de globos disponibles
|
||||||
void initFormationPools(); // Carga los pools desde archivo de configuración
|
void initFormationPools(); // Carga los pools desde archivo de configuración
|
||||||
|
|
||||||
// --- Carga y análisis de datos ---
|
|
||||||
auto loadFormationsFromFile(const std::string& filename, const std::map<std::string, float>& variables) -> bool;
|
auto loadFormationsFromFile(const std::string& filename, const std::map<std::string, float>& variables) -> bool;
|
||||||
auto parseBalloonLine(const std::string& line, const std::map<std::string, float>& variables) -> std::optional<SpawnParams>;
|
auto parseBalloonLine(const std::string& line, const std::map<std::string, float>& variables) -> std::optional<SpawnParams>;
|
||||||
auto loadPoolsFromFile(const std::string& filename) -> bool; // Nueva función para cargar pools
|
auto loadPoolsFromFile(const std::string& filename) -> bool; // Nueva función para cargar pools
|
||||||
auto parsePoolLine(const std::string& line) -> std::optional<std::pair<int, std::vector<int>>>; // Nueva función para parsear líneas de pools
|
auto parsePoolLine(const std::string& line) -> std::optional<std::pair<int, std::vector<int>>>; // Nueva función para parsear líneas de pools
|
||||||
|
|
||||||
// --- Evaluación de expresiones ---
|
|
||||||
auto evaluateExpression(const std::string& expr, const std::map<std::string, float>& variables) -> float;
|
auto evaluateExpression(const std::string& expr, const std::map<std::string, float>& variables) -> float;
|
||||||
auto evaluateSimpleExpression(const std::string& expr, const std::map<std::string, float>& variables) -> float;
|
auto evaluateSimpleExpression(const std::string& expr, const std::map<std::string, float>& variables) -> float;
|
||||||
|
|
||||||
// --- Utilidades ---
|
|
||||||
static auto trim(const std::string& str) -> std::string;
|
static auto trim(const std::string& str) -> std::string;
|
||||||
|
|
||||||
// --- Generación de variantes ---
|
|
||||||
void createFloaterVariants();
|
void createFloaterVariants();
|
||||||
void loadDefaultFormations();
|
void loadDefaultFormations();
|
||||||
void loadDefaultPools(); // Nueva función para pools por defecto
|
void loadDefaultPools(); // Nueva función para pools por defecto
|
||||||
|
|||||||
@@ -12,13 +12,14 @@
|
|||||||
#include "param.h" // Para Param, ParamGame, param
|
#include "param.h" // Para Param, ParamGame, param
|
||||||
#include "resource.h" // Para Resource
|
#include "resource.h" // Para Resource
|
||||||
#include "screen.h" // Para Screen
|
#include "screen.h" // Para Screen
|
||||||
#include "stage.h" // Para addPower
|
#include "stage_interface.h" // Para IStageInfo
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
BalloonManager::BalloonManager()
|
BalloonManager::BalloonManager(IStageInfo* stage_info)
|
||||||
: explosions_(std::make_unique<Explosions>()),
|
: explosions_(std::make_unique<Explosions>()),
|
||||||
balloon_formations_(std::make_unique<BalloonFormations>()) { init(); }
|
balloon_formations_(std::make_unique<BalloonFormations>()),
|
||||||
|
stage_info_(stage_info) { init(); }
|
||||||
|
|
||||||
// Inicializa
|
// Inicializa
|
||||||
void BalloonManager::init() {
|
void BalloonManager::init() {
|
||||||
@@ -61,18 +62,18 @@ void BalloonManager::init() {
|
|||||||
explosions_->addTexture(3, explosions_textures_.at(3), explosions_animations_.at(3));
|
explosions_->addTexture(3, explosions_textures_.at(3), explosions_animations_.at(3));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Actualiza
|
// Actualiza (time-based)
|
||||||
void BalloonManager::update() {
|
void BalloonManager::update(float deltaTime) {
|
||||||
for (auto balloon : balloons_) {
|
for (const auto& balloon : balloons_) {
|
||||||
balloon->update();
|
balloon->update(deltaTime);
|
||||||
}
|
}
|
||||||
updateBalloonDeployCounter();
|
updateBalloonDeployCounter(deltaTime);
|
||||||
explosions_->update();
|
explosions_->update(deltaTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Renderiza los objetos
|
// Renderiza los objetos
|
||||||
void BalloonManager::render() {
|
void BalloonManager::render() {
|
||||||
for (auto &balloon : balloons_) {
|
for (auto& balloon : balloons_) {
|
||||||
balloon->render();
|
balloon->render();
|
||||||
}
|
}
|
||||||
explosions_->render();
|
explosions_->render();
|
||||||
@@ -80,12 +81,12 @@ void BalloonManager::render() {
|
|||||||
|
|
||||||
// Crea una formación de globos
|
// Crea una formación de globos
|
||||||
void BalloonManager::deployRandomFormation(int stage) {
|
void BalloonManager::deployRandomFormation(int stage) {
|
||||||
// Solo despliega una formación enemiga si ha pasado cierto tiempo desde la última
|
// Solo despliega una formación enemiga si el timer ha llegado a cero
|
||||||
if (balloon_deploy_counter_ == 0) {
|
if (balloon_deploy_counter_ <= 0.0f) {
|
||||||
// En este punto se decide entre crear una powerball o una formación enemiga
|
// En este punto se decide entre crear una powerball o una formación enemiga
|
||||||
if ((rand() % 100 < 15) && (canPowerBallBeCreated())) {
|
if ((rand() % 100 < 15) && (canPowerBallBeCreated())) {
|
||||||
createPowerBall(); // Crea una powerball
|
createPowerBall(); // Crea una powerball
|
||||||
balloon_deploy_counter_ = 10; // Da un poco de margen para que se creen mas globos
|
balloon_deploy_counter_ = POWERBALL_DEPLOY_DELAY; // Resetea con pequeño retraso
|
||||||
} else {
|
} else {
|
||||||
// Decrementa el contador de despliegues de globos necesarios para la siguiente PowerBall
|
// Decrementa el contador de despliegues de globos necesarios para la siguiente PowerBall
|
||||||
if (power_ball_counter_ > 0) {
|
if (power_ball_counter_ > 0) {
|
||||||
@@ -106,11 +107,19 @@ void BalloonManager::deployRandomFormation(int stage) {
|
|||||||
// Crea los globos de la formación
|
// Crea los globos de la formación
|
||||||
const auto BALLOONS = balloon_formations_->getFormationFromPool(stage, formation_id).balloons;
|
const auto BALLOONS = balloon_formations_->getFormationFromPool(stage, formation_id).balloons;
|
||||||
for (auto balloon : BALLOONS) {
|
for (auto balloon : BALLOONS) {
|
||||||
createBalloon(balloon.x, balloon.y, balloon.type, balloon.size, balloon.vel_x, balloon_speed_, (creation_time_enabled_) ? balloon.creation_counter : 0);
|
Balloon::Config config = {
|
||||||
|
.x = balloon.x,
|
||||||
|
.y = balloon.y,
|
||||||
|
.type = balloon.type,
|
||||||
|
.size = balloon.size,
|
||||||
|
.vel_x = balloon.vel_x,
|
||||||
|
.game_tempo = balloon_speed_,
|
||||||
|
.creation_counter = creation_time_enabled_ ? balloon.creation_counter : 0.0f};
|
||||||
|
createBalloon(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reinicia el contador para el próximo despliegue
|
// Reinicia el timer para el próximo despliegue
|
||||||
balloon_deploy_counter_ = 300;
|
balloon_deploy_counter_ = DEFAULT_BALLOON_DEPLOY_DELAY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -119,29 +128,44 @@ void BalloonManager::deployRandomFormation(int stage) {
|
|||||||
void BalloonManager::deployFormation(int formation_id) {
|
void BalloonManager::deployFormation(int formation_id) {
|
||||||
const auto BALLOONS = balloon_formations_->getFormation(formation_id).balloons;
|
const auto BALLOONS = balloon_formations_->getFormation(formation_id).balloons;
|
||||||
for (auto balloon : BALLOONS) {
|
for (auto balloon : BALLOONS) {
|
||||||
createBalloon(balloon.x, balloon.y, balloon.type, balloon.size, balloon.vel_x, balloon_speed_, balloon.creation_counter);
|
Balloon::Config config = {
|
||||||
|
.x = balloon.x,
|
||||||
|
.y = balloon.y,
|
||||||
|
.type = balloon.type,
|
||||||
|
.size = balloon.size,
|
||||||
|
.vel_x = balloon.vel_x,
|
||||||
|
.game_tempo = balloon_speed_,
|
||||||
|
.creation_counter = balloon.creation_counter};
|
||||||
|
createBalloon(config);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Crea una formación de globos específica a una altura determinada
|
// Crea una formación de globos específica a una altura determinada
|
||||||
void BalloonManager::deployFormation(int formation_id, int y) {
|
void BalloonManager::deployFormation(int formation_id, float y) {
|
||||||
const auto BALLOONS = balloon_formations_->getFormation(formation_id).balloons;
|
const auto BALLOONS = balloon_formations_->getFormation(formation_id).balloons;
|
||||||
for (auto balloon : BALLOONS) {
|
for (auto balloon : BALLOONS) {
|
||||||
createBalloon(balloon.x, y, balloon.type, balloon.size, balloon.vel_x, balloon_speed_, balloon.creation_counter);
|
Balloon::Config config = {
|
||||||
|
.x = balloon.x,
|
||||||
|
.y = y,
|
||||||
|
.type = balloon.type,
|
||||||
|
.size = balloon.size,
|
||||||
|
.vel_x = balloon.vel_x,
|
||||||
|
.game_tempo = balloon_speed_,
|
||||||
|
.creation_counter = balloon.creation_counter};
|
||||||
|
createBalloon(config);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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() {
|
||||||
auto it = std::remove_if(balloons_.begin(), balloons_.end(), [](const auto &balloon) { return !balloon->isEnabled(); });
|
auto result = std::ranges::remove_if(balloons_, [](const auto& balloon) { return !balloon->isEnabled(); });
|
||||||
balloons_.erase(it, balloons_.end());
|
balloons_.erase(result.begin(), balloons_.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Actualiza la variable enemyDeployCounter
|
// Actualiza el timer de despliegue de globos (time-based)
|
||||||
void BalloonManager::updateBalloonDeployCounter() {
|
void BalloonManager::updateBalloonDeployCounter(float deltaTime) {
|
||||||
if (balloon_deploy_counter_ > 0) {
|
// DeltaTime en segundos - timer decrementa hasta llegar a cero
|
||||||
--balloon_deploy_counter_;
|
balloon_deploy_counter_ -= deltaTime;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Indica si se puede crear una powerball
|
// Indica si se puede crear una powerball
|
||||||
@@ -149,17 +173,20 @@ auto BalloonManager::canPowerBallBeCreated() -> bool { return (!power_ball_enabl
|
|||||||
|
|
||||||
// Calcula el poder actual de los globos en pantalla
|
// Calcula el poder actual de los globos en pantalla
|
||||||
auto BalloonManager::calculateScreenPower() -> int {
|
auto BalloonManager::calculateScreenPower() -> int {
|
||||||
return std::accumulate(balloons_.begin(), balloons_.end(), 0, [](int sum, const auto &balloon) { return sum + (balloon->isEnabled() ? balloon->getPower() : 0); });
|
return std::accumulate(balloons_.begin(), balloons_.end(), 0, [](int sum, const auto& balloon) { return sum + (balloon->isEnabled() ? balloon->getPower() : 0); });
|
||||||
}
|
}
|
||||||
|
|
||||||
// Crea un globo nuevo en el vector de globos
|
// Crea un globo nuevo en el vector de globos
|
||||||
auto BalloonManager::createBalloon(float x, int y, Balloon::Type type, Balloon::Size size, float velx, float speed, int creation_timer) -> std::shared_ptr<Balloon> {
|
auto BalloonManager::createBalloon(Balloon::Config config) -> std::shared_ptr<Balloon> {
|
||||||
if (can_deploy_balloons_) {
|
if (can_deploy_balloons_) {
|
||||||
const int INDEX = static_cast<int>(size);
|
const int INDEX = static_cast<int>(config.size);
|
||||||
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)));
|
config.play_area = play_area_;
|
||||||
balloons_.back()->setSound(sound_enabled_);
|
config.texture = balloon_textures_.at(INDEX);
|
||||||
balloons_.back()->setBouncingSound(bouncing_sound_enabled_);
|
config.animation = balloon_animations_.at(INDEX);
|
||||||
balloons_.back()->setPoppingSound(poping_sound_enabled_);
|
config.sound.enabled = sound_enabled_;
|
||||||
|
config.sound.bouncing_enabled = bouncing_sound_enabled_;
|
||||||
|
config.sound.poping_enabled = poping_sound_enabled_;
|
||||||
|
balloons_.emplace_back(std::make_shared<Balloon>(config));
|
||||||
return balloons_.back();
|
return balloons_.back();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -167,30 +194,49 @@ auto BalloonManager::createBalloon(float x, int y, Balloon::Type type, Balloon::
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Crea un globo a partir de otro globo
|
// Crea un globo a partir de otro globo
|
||||||
void BalloonManager::createChildBalloon(const std::shared_ptr<Balloon> &balloon, const std::string &direction) {
|
void BalloonManager::createChildBalloon(const std::shared_ptr<Balloon>& balloon, const std::string& direction) {
|
||||||
if (can_deploy_balloons_) {
|
if (can_deploy_balloons_) {
|
||||||
// Calcula parametros
|
// Calcula parametros
|
||||||
const float VX = direction == "LEFT" ? Balloon::VELX_NEGATIVE : Balloon::VELX_POSITIVE;
|
|
||||||
const auto SIZE = static_cast<Balloon::Size>(static_cast<int>(balloon->getSize()) - 1);
|
|
||||||
const int PARENT_HEIGHT = balloon->getHeight();
|
const int PARENT_HEIGHT = balloon->getHeight();
|
||||||
const int CHILD_HEIGHT = Balloon::WIDTH.at(static_cast<int>(balloon->getSize()) - 1);
|
const int CHILD_HEIGHT = Balloon::WIDTH.at(static_cast<int>(balloon->getSize()) - 1);
|
||||||
const int Y = balloon->getPosY() + (PARENT_HEIGHT - CHILD_HEIGHT) / 2;
|
const int CHILD_WIDTH = CHILD_HEIGHT;
|
||||||
const int X = direction == "LEFT" ? balloon->getPosX() + (balloon->getWidth() / 3) : balloon->getPosX() + 2 * (balloon->getWidth() / 3);
|
|
||||||
|
const float X = direction == "LEFT" ? balloon->getPosX() + (balloon->getWidth() / 3) : balloon->getPosX() + (2 * (balloon->getWidth() / 3));
|
||||||
|
const float MIN_X = play_area_.x;
|
||||||
|
const float MAX_X = play_area_.w - CHILD_WIDTH;
|
||||||
|
|
||||||
|
Balloon::Config config = {
|
||||||
|
.x = std::clamp(X - (CHILD_WIDTH / 2), MIN_X, MAX_X),
|
||||||
|
.y = balloon->getPosY() + ((PARENT_HEIGHT - CHILD_HEIGHT) / 2),
|
||||||
|
.type = balloon->getType(),
|
||||||
|
.size = static_cast<Balloon::Size>(static_cast<int>(balloon->getSize()) - 1),
|
||||||
|
.vel_x = direction == "LEFT" ? Balloon::VELX_NEGATIVE : Balloon::VELX_POSITIVE,
|
||||||
|
.game_tempo = balloon_speed_,
|
||||||
|
.creation_counter = 0};
|
||||||
|
|
||||||
// Crea el globo
|
// Crea el globo
|
||||||
auto b = createBalloon(0, Y, balloon->getType(), SIZE, VX, balloon_speed_, 0);
|
auto b = createBalloon(config);
|
||||||
|
|
||||||
// Establece parametros
|
// Establece parametros
|
||||||
b->alignTo(X);
|
constexpr float VEL_Y_BALLOON_PER_S = -150.0F;
|
||||||
b->setVelY(b->getType() == Balloon::Type::BALLOON ? -2.50F : Balloon::VELX_NEGATIVE * 2.0F);
|
switch (b->getType()) {
|
||||||
|
case Balloon::Type::BALLOON: {
|
||||||
|
b->setVelY(VEL_Y_BALLOON_PER_S);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Balloon::Type::FLOATER: {
|
||||||
|
const float MODIFIER = (rand() % 2 == 0) ? 1.0F : 1.0F;
|
||||||
|
b->setVelY(Balloon::VELX_NEGATIVE * 2.0F * MODIFIER);
|
||||||
|
(rand() % 2 == 0) ? b->alterVelX(1.0F) : b->alterVelX(1.0F);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// Herencia de estados
|
// Herencia de estados
|
||||||
if (balloon->isStopped()) {
|
if (balloon->isStopped()) { b->stop(); }
|
||||||
b->stop();
|
if (balloon->isUsingReversedColor()) { b->useReverseColor(); }
|
||||||
}
|
|
||||||
if (balloon->isUsingReversedColor()) {
|
|
||||||
b->useReverseColor();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -198,18 +244,32 @@ void BalloonManager::createChildBalloon(const std::shared_ptr<Balloon> &balloon,
|
|||||||
void BalloonManager::createPowerBall() {
|
void BalloonManager::createPowerBall() {
|
||||||
if (can_deploy_balloons_) {
|
if (can_deploy_balloons_) {
|
||||||
constexpr int VALUES = 6;
|
constexpr int VALUES = 6;
|
||||||
constexpr float POS_Y = -Balloon::WIDTH.at(4);
|
const int LUCK = rand() % VALUES;
|
||||||
constexpr int CREATION_TIME = 0;
|
|
||||||
|
|
||||||
const float LEFT = param.game.play_area.rect.x;
|
const float LEFT = param.game.play_area.rect.x;
|
||||||
const float CENTER = param.game.play_area.center_x - (Balloon::WIDTH.at(4) / 2);
|
const float CENTER = param.game.play_area.center_x - (Balloon::WIDTH.at(4) / 2);
|
||||||
const float RIGHT = param.game.play_area.rect.w - Balloon::WIDTH.at(4);
|
const float RIGHT = param.game.play_area.rect.w - Balloon::WIDTH.at(4);
|
||||||
|
|
||||||
const int LUCK = rand() % VALUES;
|
|
||||||
const std::array<float, VALUES> POS_X = {LEFT, LEFT, CENTER, CENTER, RIGHT, RIGHT};
|
const std::array<float, VALUES> POS_X = {LEFT, LEFT, CENTER, CENTER, RIGHT, RIGHT};
|
||||||
const std::array<float, VALUES> VEL_X = {Balloon::VELX_POSITIVE, Balloon::VELX_POSITIVE, Balloon::VELX_POSITIVE, Balloon::VELX_NEGATIVE, Balloon::VELX_NEGATIVE, Balloon::VELX_NEGATIVE};
|
const std::array<float, VALUES> VEL_X = {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>(POS_X[LUCK], POS_Y, Balloon::Type::POWERBALL, Balloon::Size::EXTRALARGE, VEL_X[LUCK], balloon_speed_, CREATION_TIME, play_area_, balloon_textures_[4], balloon_animations_[4]));
|
Balloon::Config config = {
|
||||||
|
.x = POS_X.at(LUCK),
|
||||||
|
.y = -Balloon::WIDTH.at(4),
|
||||||
|
.type = Balloon::Type::POWERBALL,
|
||||||
|
.size = Balloon::Size::EXTRALARGE,
|
||||||
|
.vel_x = VEL_X.at(LUCK),
|
||||||
|
.game_tempo = balloon_speed_,
|
||||||
|
.creation_counter = 0,
|
||||||
|
.play_area = play_area_,
|
||||||
|
.texture = balloon_textures_.at(4),
|
||||||
|
.animation = balloon_animations_.at(4),
|
||||||
|
.sound = {
|
||||||
|
.bouncing_enabled = bouncing_sound_enabled_,
|
||||||
|
.poping_enabled = poping_sound_enabled_,
|
||||||
|
.enabled = sound_enabled_}};
|
||||||
|
|
||||||
|
balloons_.emplace_back(std::make_unique<Balloon>(config));
|
||||||
balloons_.back()->setInvulnerable(true);
|
balloons_.back()->setInvulnerable(true);
|
||||||
|
|
||||||
power_ball_enabled_ = true;
|
power_ball_enabled_ = true;
|
||||||
@@ -220,21 +280,21 @@ void BalloonManager::createPowerBall() {
|
|||||||
// Establece la velocidad de los globos
|
// Establece la velocidad de los globos
|
||||||
void BalloonManager::setBalloonSpeed(float speed) {
|
void BalloonManager::setBalloonSpeed(float speed) {
|
||||||
balloon_speed_ = speed;
|
balloon_speed_ = speed;
|
||||||
for (auto &balloon : balloons_) {
|
for (auto& balloon : balloons_) {
|
||||||
balloon->setSpeed(speed);
|
balloon->setGameTempo(speed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Explosiona un globo. Lo destruye y crea otros dos si es el caso
|
// Explosiona un globo. Lo destruye y crea otros dos si es el caso
|
||||||
auto BalloonManager::popBalloon(std::shared_ptr<Balloon> balloon) -> int {
|
auto BalloonManager::popBalloon(const std::shared_ptr<Balloon>& balloon) -> int {
|
||||||
Stage::addPower(1);
|
stage_info_->addPower(1);
|
||||||
int score = 0;
|
int score = 0;
|
||||||
|
|
||||||
if (balloon->getType() == Balloon::Type::POWERBALL) {
|
if (balloon->getType() == Balloon::Type::POWERBALL) {
|
||||||
balloon->pop(true);
|
balloon->pop(true);
|
||||||
score = destroyAllBalloons();
|
score = destroyAllBalloons();
|
||||||
power_ball_enabled_ = false;
|
power_ball_enabled_ = false;
|
||||||
balloon_deploy_counter_ = 20;
|
balloon_deploy_counter_ = BALLOON_POP_DELAY; // Resetea con retraso
|
||||||
} else {
|
} else {
|
||||||
score = balloon->getScore();
|
score = balloon->getScore();
|
||||||
if (balloon->getSize() != Balloon::Size::SMALL) {
|
if (balloon->getSize() != Balloon::Size::SMALL) {
|
||||||
@@ -251,7 +311,7 @@ auto BalloonManager::popBalloon(std::shared_ptr<Balloon> balloon) -> int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Explosiona un globo. Lo destruye = no crea otros globos
|
// Explosiona un globo. Lo destruye = no crea otros globos
|
||||||
auto BalloonManager::destroyBalloon(std::shared_ptr<Balloon> &balloon) -> int {
|
auto BalloonManager::destroyBalloon(std::shared_ptr<Balloon>& balloon) -> int {
|
||||||
int score = 0;
|
int score = 0;
|
||||||
|
|
||||||
// Calcula la puntuación y el poder que generaria el globo en caso de romperlo a él y a sus hijos
|
// Calcula la puntuación y el poder que generaria el globo en caso de romperlo a él y a sus hijos
|
||||||
@@ -274,7 +334,7 @@ auto BalloonManager::destroyBalloon(std::shared_ptr<Balloon> &balloon) -> int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Aumenta el poder de la fase
|
// Aumenta el poder de la fase
|
||||||
Stage::addPower(balloon->getPower());
|
stage_info_->addPower(balloon->getPower());
|
||||||
|
|
||||||
// Destruye el globo
|
// Destruye el globo
|
||||||
explosions_->add(balloon->getPosX(), balloon->getPosY(), static_cast<int>(balloon->getSize()));
|
explosions_->add(balloon->getPosX(), balloon->getPosY(), static_cast<int>(balloon->getSize()));
|
||||||
@@ -286,12 +346,12 @@ auto BalloonManager::destroyBalloon(std::shared_ptr<Balloon> &balloon) -> int {
|
|||||||
// Destruye todos los globos
|
// Destruye todos los globos
|
||||||
auto BalloonManager::destroyAllBalloons() -> int {
|
auto BalloonManager::destroyAllBalloons() -> int {
|
||||||
int score = 0;
|
int score = 0;
|
||||||
for (auto &balloon : balloons_) {
|
for (auto& balloon : balloons_) {
|
||||||
score += destroyBalloon(balloon);
|
score += destroyBalloon(balloon);
|
||||||
}
|
}
|
||||||
|
|
||||||
balloon_deploy_counter_ = 300;
|
balloon_deploy_counter_ = DEFAULT_BALLOON_DEPLOY_DELAY;
|
||||||
Screen::get()->flash(FLASH_COLOR, 3);
|
Screen::get()->flash(Colors::FLASH, 0.05F);
|
||||||
Screen::get()->shake();
|
Screen::get()->shake();
|
||||||
|
|
||||||
return score;
|
return score;
|
||||||
@@ -299,14 +359,16 @@ auto BalloonManager::destroyAllBalloons() -> int {
|
|||||||
|
|
||||||
// Detiene todos los globos
|
// Detiene todos los globos
|
||||||
void BalloonManager::stopAllBalloons() {
|
void BalloonManager::stopAllBalloons() {
|
||||||
for (auto &balloon : balloons_) {
|
for (auto& balloon : balloons_) {
|
||||||
balloon->stop();
|
if (!balloon->isBeingCreated()) {
|
||||||
|
balloon->stop();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pone en marcha todos los globos
|
// Pone en marcha todos los globos
|
||||||
void BalloonManager::startAllBalloons() {
|
void BalloonManager::startAllBalloons() {
|
||||||
for (auto &balloon : balloons_) {
|
for (auto& balloon : balloons_) {
|
||||||
if (!balloon->isBeingCreated()) {
|
if (!balloon->isBeingCreated()) {
|
||||||
balloon->start();
|
balloon->start();
|
||||||
}
|
}
|
||||||
@@ -315,7 +377,7 @@ void BalloonManager::startAllBalloons() {
|
|||||||
|
|
||||||
// Cambia el color de todos los globos
|
// Cambia el color de todos los globos
|
||||||
void BalloonManager::reverseColorsToAllBalloons() {
|
void BalloonManager::reverseColorsToAllBalloons() {
|
||||||
for (auto &balloon : balloons_) {
|
for (auto& balloon : balloons_) {
|
||||||
if (balloon->isStopped()) {
|
if (balloon->isStopped()) {
|
||||||
balloon->useReverseColor();
|
balloon->useReverseColor();
|
||||||
}
|
}
|
||||||
@@ -324,7 +386,7 @@ void BalloonManager::reverseColorsToAllBalloons() {
|
|||||||
|
|
||||||
// Cambia el color de todos los globos
|
// Cambia el color de todos los globos
|
||||||
void BalloonManager::normalColorsToAllBalloons() {
|
void BalloonManager::normalColorsToAllBalloons() {
|
||||||
for (auto &balloon : balloons_) {
|
for (auto& balloon : balloons_) {
|
||||||
balloon->useNormalColor();
|
balloon->useNormalColor();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -334,28 +396,15 @@ void BalloonManager::createTwoBigBalloons() {
|
|||||||
deployFormation(1);
|
deployFormation(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Crea una disposición de globos aleatoria
|
|
||||||
void BalloonManager::createRandomBalloons() {
|
|
||||||
const int NUM_BALLOONS = 2 + rand() % 4;
|
|
||||||
for (int i = 0; i < NUM_BALLOONS; ++i) {
|
|
||||||
const float X = param.game.game_area.rect.x + (rand() % static_cast<int>(param.game.game_area.rect.w)) - Balloon::WIDTH.at(3);
|
|
||||||
const int Y = param.game.game_area.rect.y + (rand() % 50);
|
|
||||||
const auto SIZE = static_cast<Balloon::Size>(rand() % 4);
|
|
||||||
const float VEL_X = (rand() % 2 == 0) ? Balloon::VELX_POSITIVE : Balloon::VELX_NEGATIVE;
|
|
||||||
const int CREATION_COUNTER = 0;
|
|
||||||
createBalloon(X, Y, Balloon::Type::BALLOON, SIZE, VEL_X, balloon_speed_, CREATION_COUNTER);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Obtiene el nivel de ameza actual generado por los globos
|
// Obtiene el nivel de ameza actual generado por los globos
|
||||||
auto BalloonManager::getMenace() -> int {
|
auto BalloonManager::getMenace() -> int {
|
||||||
return std::accumulate(balloons_.begin(), balloons_.end(), 0, [](int sum, const auto &balloon) { return sum + (balloon->isEnabled() ? balloon->getMenace() : 0); });
|
return std::accumulate(balloons_.begin(), balloons_.end(), 0, [](int sum, const auto& balloon) { return sum + (balloon->isEnabled() ? balloon->getMenace() : 0); });
|
||||||
}
|
}
|
||||||
|
|
||||||
// Establece el sonido de los globos
|
// Establece el sonido de los globos
|
||||||
void BalloonManager::setSounds(bool value) {
|
void BalloonManager::setSounds(bool value) {
|
||||||
sound_enabled_ = value;
|
sound_enabled_ = value;
|
||||||
for (auto &balloon : balloons_) {
|
for (auto& balloon : balloons_) {
|
||||||
balloon->setSound(value);
|
balloon->setSound(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -363,14 +412,14 @@ void BalloonManager::setSounds(bool value) {
|
|||||||
// Activa o desactiva los sonidos de rebote los globos
|
// Activa o desactiva los sonidos de rebote los globos
|
||||||
void BalloonManager::setBouncingSounds(bool value) {
|
void BalloonManager::setBouncingSounds(bool value) {
|
||||||
bouncing_sound_enabled_ = value;
|
bouncing_sound_enabled_ = value;
|
||||||
for (auto &balloon : balloons_) {
|
for (auto& balloon : balloons_) {
|
||||||
balloon->setBouncingSound(value);
|
balloon->setBouncingSound(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Activa o desactiva los sonidos de los globos al explotar
|
// Activa o desactiva los sonidos de los globos al explotar
|
||||||
void BalloonManager::setPoppingSounds(bool value) {
|
void BalloonManager::setPoppingSounds(bool value) {
|
||||||
poping_sound_enabled_ = value;
|
poping_sound_enabled_ = value;
|
||||||
for (auto &balloon : balloons_) {
|
for (auto& balloon : balloons_) {
|
||||||
balloon->setPoppingSound(value);
|
balloon->setPoppingSound(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -12,98 +12,104 @@
|
|||||||
#include "balloon_formations.h" // Para BalloonFormations
|
#include "balloon_formations.h" // Para BalloonFormations
|
||||||
#include "explosions.h" // Para Explosions
|
#include "explosions.h" // Para Explosions
|
||||||
#include "param.h" // Para Param, ParamGame, param
|
#include "param.h" // Para Param, ParamGame, param
|
||||||
|
#include "stage_interface.h" // Para IStageInfo
|
||||||
#include "utils.h" // Para Zone
|
#include "utils.h" // Para Zone
|
||||||
|
|
||||||
class Texture;
|
class Texture;
|
||||||
|
|
||||||
|
// --- Types ---
|
||||||
using Balloons = std::vector<std::shared_ptr<Balloon>>;
|
using Balloons = std::vector<std::shared_ptr<Balloon>>;
|
||||||
|
|
||||||
// Clase BalloonManager
|
// --- Clase BalloonManager: gestiona todos los globos del juego ---
|
||||||
class BalloonManager {
|
class BalloonManager {
|
||||||
public:
|
public:
|
||||||
// Constructor y Destructor
|
// --- Constructor y destructor ---
|
||||||
BalloonManager();
|
BalloonManager(IStageInfo *stage_info);
|
||||||
~BalloonManager() = default;
|
~BalloonManager() = default;
|
||||||
|
|
||||||
// Actualización y Renderizado
|
// --- Métodos principales ---
|
||||||
void update(); // Actualiza el estado de los globos
|
void update(float deltaTime); // Actualiza el estado de los globos (time-based)
|
||||||
void render(); // Renderiza los globos en pantalla
|
void render(); // Renderiza los globos en pantalla
|
||||||
|
|
||||||
// Gestión de globos
|
// --- Gestión de globos ---
|
||||||
void freeBalloons(); // Libera globos que ya no sirven
|
void freeBalloons(); // Libera globos que ya no sirven
|
||||||
|
|
||||||
// Creación de formaciones enemigas
|
// --- Creación de formaciones enemigas ---
|
||||||
void deployRandomFormation(int stage); // Crea una formación de globos aleatoria
|
void deployRandomFormation(int stage); // Crea una formación de globos aleatoria
|
||||||
void deployFormation(int formation_id); // Crea una formación específica
|
void deployFormation(int formation_id); // Crea una formación específica
|
||||||
void deployFormation(int formation_id, int y); // Crea una formación específica con coordenadas
|
void deployFormation(int formation_id, float y); // Crea una formación específica con coordenadas
|
||||||
|
|
||||||
// Creación de globos
|
// --- Creación de globos ---
|
||||||
auto createBalloon(float x, int y, Balloon::Type type, Balloon::Size size, float velx, float speed, int creation_timer) -> std::shared_ptr<Balloon>; // Crea un nuevo globo
|
auto createBalloon(Balloon::Config config) -> std::shared_ptr<Balloon>; // Crea un nuevo globo
|
||||||
void createChildBalloon(const std::shared_ptr<Balloon> &balloon, const std::string &direction); // Crea un globo a partir de otro
|
void createChildBalloon(const std::shared_ptr<Balloon> &balloon, const std::string &direction); // Crea un globo a partir de otro
|
||||||
void createPowerBall(); // Crea una PowerBall
|
void createPowerBall(); // Crea una PowerBall
|
||||||
void createTwoBigBalloons(); // Crea dos globos grandes
|
void createTwoBigBalloons(); // Crea dos globos grandes
|
||||||
void createRandomBalloons(); // Crea una disposición aleatoria de globos
|
|
||||||
|
|
||||||
// Control de velocidad y despliegue
|
// --- Control de velocidad y despliegue ---
|
||||||
void setBalloonSpeed(float speed); // Ajusta la velocidad de los globos
|
void setBalloonSpeed(float speed); // Ajusta la velocidad de los globos
|
||||||
void setDefaultBalloonSpeed(float speed) { default_balloon_speed_ = speed; }; // Establece la velocidad base
|
void setDefaultBalloonSpeed(float speed) { default_balloon_speed_ = speed; }; // Establece la velocidad base
|
||||||
void resetBalloonSpeed() { setBalloonSpeed(default_balloon_speed_); }; // Restablece la velocidad de los globos
|
void resetBalloonSpeed() { setBalloonSpeed(default_balloon_speed_); }; // Restablece la velocidad de los globos
|
||||||
void updateBalloonDeployCounter(); // Actualiza el contador de despliegue
|
void updateBalloonDeployCounter(float deltaTime); // Actualiza el contador de despliegue (time-based)
|
||||||
auto canPowerBallBeCreated() -> bool; // Indica si se puede crear una PowerBall
|
auto canPowerBallBeCreated() -> bool; // Indica si se puede crear una PowerBall
|
||||||
auto calculateScreenPower() -> int; // Calcula el poder de los globos en pantalla
|
auto calculateScreenPower() -> int; // Calcula el poder de los globos en pantalla
|
||||||
|
|
||||||
// Manipulación de globos existentes
|
// --- Manipulación de globos existentes ---
|
||||||
auto popBalloon(std::shared_ptr<Balloon> balloon) -> int; // Explosiona un globo, creando otros si aplica
|
auto popBalloon(const std::shared_ptr<Balloon> &balloon) -> int; // Explosiona un globo, creando otros si aplica
|
||||||
auto destroyBalloon(std::shared_ptr<Balloon> &balloon) -> int; // Explosiona un globo sin crear otros
|
auto destroyBalloon(std::shared_ptr<Balloon> &balloon) -> int; // Explosiona un globo sin crear otros
|
||||||
auto destroyAllBalloons() -> int; // Destruye todos los globos
|
auto destroyAllBalloons() -> int; // Destruye todos los globos
|
||||||
void stopAllBalloons(); // Detiene el movimiento de los globos
|
void stopAllBalloons(); // Detiene el movimiento de los globos
|
||||||
void startAllBalloons(); // Reactiva el movimiento de los globos
|
void startAllBalloons(); // Reactiva el movimiento de los globos
|
||||||
|
|
||||||
// Cambios de apariencia
|
// --- Cambios de apariencia ---
|
||||||
void reverseColorsToAllBalloons(); // Invierte los colores de los globos
|
void reverseColorsToAllBalloons(); // Invierte los colores de los globos
|
||||||
void normalColorsToAllBalloons(); // Restaura los colores originales
|
void normalColorsToAllBalloons(); // Restaura los colores originales
|
||||||
|
|
||||||
// Configuración de sonido
|
// --- Configuración de sonido ---
|
||||||
void setSounds(bool value); // Activa o desactiva los sonidos de los globos
|
void setSounds(bool value); // Activa o desactiva los sonidos de los globos
|
||||||
void setBouncingSounds(bool value); // Activa o desactiva los sonidos de rebote los globos
|
void setBouncingSounds(bool value); // Activa o desactiva los sonidos de rebote los globos
|
||||||
void setPoppingSounds(bool value); // Activa o desactiva los sonidos de los globos al explotar
|
void setPoppingSounds(bool value); // Activa o desactiva los sonidos de los globos al explotar
|
||||||
|
|
||||||
// Configuración de juego
|
// --- Configuración de juego ---
|
||||||
void setPlayArea(SDL_FRect play_area) { play_area_ = play_area; }; // Define el área de juego
|
void setPlayArea(SDL_FRect play_area) { play_area_ = play_area; }; // Define el área de juego
|
||||||
void setCreationTimeEnabled(bool value) { creation_time_enabled_ = value; }; // Activa o desactiva el tiempo de creación de globos
|
void setCreationTimeEnabled(bool value) { creation_time_enabled_ = value; }; // Activa o desactiva el tiempo de creación de globos
|
||||||
void enableBalloonDeployment(bool value) { can_deploy_balloons_ = value; }; // Activa o desactiva la generación de globos
|
void enableBalloonDeployment(bool value) { can_deploy_balloons_ = value; }; // Activa o desactiva la generación de globos
|
||||||
|
|
||||||
// Obtención de información
|
// --- Getters ---
|
||||||
auto getMenace() -> int; // Obtiene el nivel de amenaza generado por los globos
|
auto getMenace() -> int; // Obtiene el nivel de amenaza generado por los globos
|
||||||
[[nodiscard]] auto getBalloonSpeed() const -> float { return balloon_speed_; }
|
[[nodiscard]] auto getBalloonSpeed() const -> float { return balloon_speed_; }
|
||||||
auto getBalloons() -> Balloons & { return balloons_; }
|
auto getBalloons() -> Balloons & { return balloons_; }
|
||||||
[[nodiscard]] auto getNumBalloons() const -> int { return balloons_.size(); }
|
[[nodiscard]] auto getNumBalloons() const -> int { return balloons_.size(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Balloons balloons_; // Vector con los globos activos
|
// --- Constantes ---
|
||||||
std::unique_ptr<Explosions> explosions_; // Objeto para gestionar explosiones
|
static constexpr float DEFAULT_BALLOON_DEPLOY_DELAY = 5.0f; // 300 frames = 5 segundos
|
||||||
std::unique_ptr<BalloonFormations> balloon_formations_; // Objeto para manejar formaciones enemigas
|
static constexpr float POWERBALL_DEPLOY_DELAY = 0.167f; // 10 frames = 0.167 segundos
|
||||||
|
static constexpr float BALLOON_POP_DELAY = 0.333f; // 20 frames = 0.333 segundos
|
||||||
std::vector<std::shared_ptr<Texture>> balloon_textures_; // Texturas de los globos
|
|
||||||
std::vector<std::shared_ptr<Texture>> explosions_textures_; // Texturas de explosiones
|
|
||||||
|
|
||||||
|
// --- Objetos y punteros ---
|
||||||
|
Balloons balloons_; // Vector con los globos activos
|
||||||
|
std::unique_ptr<Explosions> explosions_; // Objeto para gestionar explosiones
|
||||||
|
std::unique_ptr<BalloonFormations> balloon_formations_; // Objeto para manejar formaciones enemigas
|
||||||
|
std::vector<std::shared_ptr<Texture>> balloon_textures_; // Texturas de los globos
|
||||||
|
std::vector<std::shared_ptr<Texture>> explosions_textures_; // Texturas de explosiones
|
||||||
std::vector<std::vector<std::string>> balloon_animations_; // Animaciones de los globos
|
std::vector<std::vector<std::string>> balloon_animations_; // Animaciones de los globos
|
||||||
std::vector<std::vector<std::string>> explosions_animations_; // Animaciones de las explosiones
|
std::vector<std::vector<std::string>> explosions_animations_; // Animaciones de las explosiones
|
||||||
|
IStageInfo *stage_info_; // Informacion de la pantalla actual
|
||||||
|
|
||||||
// Variables de control de globos
|
// --- Variables de estado ---
|
||||||
float balloon_speed_ = Balloon::SPEED.at(0);
|
SDL_FRect play_area_ = param.game.play_area.rect;
|
||||||
float default_balloon_speed_ = Balloon::SPEED.at(0);
|
float balloon_speed_ = Balloon::GAME_TEMPO.at(0);
|
||||||
int balloon_deploy_counter_ = 0;
|
float default_balloon_speed_ = Balloon::GAME_TEMPO.at(0);
|
||||||
bool power_ball_enabled_ = false;
|
float balloon_deploy_counter_ = 0;
|
||||||
int power_ball_counter_ = 0;
|
int power_ball_counter_ = 0;
|
||||||
int last_balloon_deploy_ = 0;
|
int last_balloon_deploy_ = 0;
|
||||||
SDL_FRect play_area_ = param.game.play_area.rect;
|
bool power_ball_enabled_ = false;
|
||||||
bool creation_time_enabled_ = true;
|
bool creation_time_enabled_ = true;
|
||||||
bool can_deploy_balloons_ = true;
|
bool can_deploy_balloons_ = true;
|
||||||
bool bouncing_sound_enabled_ = false; // Si debe sonar el globo al rebotar
|
bool bouncing_sound_enabled_ = false; // Si debe sonar el globo al rebotar
|
||||||
bool poping_sound_enabled_ = true; // Si debe sonar el globo al explotar
|
bool poping_sound_enabled_ = true; // Si debe sonar el globo al explotar
|
||||||
bool sound_enabled_ = true; // Indica si los globos deben hacer algun sonido
|
bool sound_enabled_ = true; // Indica si los globos deben hacer algun sonido
|
||||||
|
|
||||||
// Metodos privados
|
// --- Métodos internos ---
|
||||||
void init();
|
void init();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -4,46 +4,64 @@
|
|||||||
#include <string> // Para char_traits, basic_string, operator+, string
|
#include <string> // Para char_traits, basic_string, operator+, string
|
||||||
|
|
||||||
#include "param.h" // Para Param, ParamGame, param
|
#include "param.h" // Para Param, ParamGame, param
|
||||||
|
#include "player.h" // Para Player::Id
|
||||||
#include "resource.h" // Para Resource
|
#include "resource.h" // Para Resource
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
Bullet::Bullet(float x, float y, BulletType bullet_type, bool powered, Player::Id owner)
|
Bullet::Bullet(float x, float y, Type type, Color color, int owner)
|
||||||
: sprite_(std::make_unique<AnimatedSprite>(Resource::get()->getTexture("bullet.png"), Resource::get()->getAnimation("bullet.ani"))),
|
: sprite_(std::make_unique<AnimatedSprite>(Resource::get()->getTexture("bullet.png"), Resource::get()->getAnimation("bullet.ani"))),
|
||||||
|
type_(type),
|
||||||
|
owner_(owner),
|
||||||
pos_x_(x),
|
pos_x_(x),
|
||||||
pos_y_(y),
|
pos_y_(y) {
|
||||||
bullet_type_(bullet_type),
|
vel_x_ = calculateVelocity(type_);
|
||||||
owner_(owner) {
|
sprite_->setCurrentAnimation(buildAnimationString(type_, color));
|
||||||
vel_x_ = calculateVelocity(bullet_type_);
|
|
||||||
sprite_->setCurrentAnimation(buildAnimationString(bullet_type_, powered));
|
|
||||||
|
|
||||||
collider_.r = WIDTH / 2;
|
collider_.r = WIDTH / 2;
|
||||||
shiftColliders();
|
shiftColliders();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calcula la velocidad horizontal de la bala basada en su tipo
|
// Calcula la velocidad horizontal de la bala basada en su tipo
|
||||||
auto Bullet::calculateVelocity(BulletType bullet_type) -> float {
|
auto Bullet::calculateVelocity(Type type) -> float {
|
||||||
switch (bullet_type) {
|
switch (type) {
|
||||||
case BulletType::LEFT:
|
case Type::LEFT:
|
||||||
return VEL_X_LEFT;
|
return VEL_X_LEFT;
|
||||||
case BulletType::RIGHT:
|
case Type::RIGHT:
|
||||||
return VEL_X_RIGHT;
|
return VEL_X_RIGHT;
|
||||||
default:
|
default:
|
||||||
return VEL_X_CENTER;
|
return VEL_X_CENTER;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Construye el string de animación basado en el tipo de bala y si está potenciada
|
// Construye el string de animación basado en el tipo de bala y color específico
|
||||||
auto Bullet::buildAnimationString(BulletType bullet_type, bool powered) -> std::string {
|
auto Bullet::buildAnimationString(Type type, Color color) -> std::string {
|
||||||
std::string animation_string = powered ? "powered_" : "normal_";
|
std::string animation_string;
|
||||||
|
|
||||||
switch (bullet_type) {
|
// Mapear color a string específico
|
||||||
case BulletType::UP:
|
switch (color) {
|
||||||
|
case Color::YELLOW:
|
||||||
|
animation_string = "yellow_";
|
||||||
|
break;
|
||||||
|
case Color::GREEN:
|
||||||
|
animation_string = "green_";
|
||||||
|
break;
|
||||||
|
case Color::RED:
|
||||||
|
animation_string = "red_";
|
||||||
|
break;
|
||||||
|
case Color::PURPLE:
|
||||||
|
animation_string = "purple_";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Añadir dirección
|
||||||
|
switch (type) {
|
||||||
|
case Type::UP:
|
||||||
animation_string += "up";
|
animation_string += "up";
|
||||||
break;
|
break;
|
||||||
case BulletType::LEFT:
|
case Type::LEFT:
|
||||||
animation_string += "left";
|
animation_string += "left";
|
||||||
break;
|
break;
|
||||||
case BulletType::RIGHT:
|
case Type::RIGHT:
|
||||||
animation_string += "right";
|
animation_string += "right";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -53,48 +71,48 @@ auto Bullet::buildAnimationString(BulletType bullet_type, bool powered) -> std::
|
|||||||
return animation_string;
|
return animation_string;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implementación de render (llama al render del sprite_)
|
// Implementación de render
|
||||||
void Bullet::render() {
|
void Bullet::render() {
|
||||||
if (bullet_type_ != BulletType::NONE) {
|
if (type_ != Type::NONE) {
|
||||||
sprite_->render();
|
sprite_->render();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Actualiza el estado del objeto
|
// Actualiza el estado del objeto
|
||||||
auto Bullet::update() -> BulletMoveStatus {
|
auto Bullet::update(float deltaTime) -> MoveStatus {
|
||||||
sprite_->update();
|
sprite_->update(deltaTime);
|
||||||
return move();
|
return move(deltaTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implementación del movimiento usando BulletMoveStatus
|
// Implementación del movimiento usando MoveStatus
|
||||||
auto Bullet::move() -> BulletMoveStatus {
|
auto Bullet::move(float deltaTime) -> MoveStatus {
|
||||||
pos_x_ += vel_x_;
|
pos_x_ += vel_x_ * deltaTime;
|
||||||
if (pos_x_ < param.game.play_area.rect.x - WIDTH || pos_x_ > param.game.play_area.rect.w) {
|
if (pos_x_ < param.game.play_area.rect.x - WIDTH || pos_x_ > param.game.play_area.rect.w) {
|
||||||
disable();
|
disable();
|
||||||
return BulletMoveStatus::OUT;
|
return MoveStatus::OUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
pos_y_ += VEL_Y;
|
pos_y_ += VEL_Y * deltaTime;
|
||||||
if (pos_y_ < param.game.play_area.rect.y - HEIGHT) {
|
if (pos_y_ < param.game.play_area.rect.y - HEIGHT) {
|
||||||
disable();
|
disable();
|
||||||
return BulletMoveStatus::OUT;
|
return MoveStatus::OUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
shiftSprite();
|
shiftSprite();
|
||||||
shiftColliders();
|
shiftColliders();
|
||||||
|
|
||||||
return BulletMoveStatus::OK;
|
return MoveStatus::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Bullet::isEnabled() const -> bool {
|
auto Bullet::isEnabled() const -> bool {
|
||||||
return bullet_type_ != BulletType::NONE;
|
return type_ != Type::NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Bullet::disable() {
|
void Bullet::disable() {
|
||||||
bullet_type_ = BulletType::NONE;
|
type_ = Type::NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Bullet::getOwner() const -> Player::Id {
|
auto Bullet::getOwner() const -> int {
|
||||||
return owner_;
|
return owner_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
103
source/bullet.h
@@ -6,68 +6,71 @@
|
|||||||
#include <string> // Para string
|
#include <string> // Para string
|
||||||
|
|
||||||
#include "animated_sprite.h" // Para AnimatedSprite
|
#include "animated_sprite.h" // Para AnimatedSprite
|
||||||
#include "player.h" // Para Player
|
|
||||||
#include "utils.h" // Para Circle
|
#include "utils.h" // Para Circle
|
||||||
|
|
||||||
// Tipos de balas
|
// --- Clase Bullet: representa una bala del jugador ---
|
||||||
enum class BulletType : Uint8 {
|
|
||||||
UP,
|
|
||||||
LEFT,
|
|
||||||
RIGHT,
|
|
||||||
NONE
|
|
||||||
};
|
|
||||||
|
|
||||||
// Resultado del movimiento de la bala
|
|
||||||
enum class BulletMoveStatus : Uint8 {
|
|
||||||
OK = 0,
|
|
||||||
OUT = 1
|
|
||||||
};
|
|
||||||
|
|
||||||
// Clase Bullet
|
|
||||||
class Bullet {
|
class Bullet {
|
||||||
public:
|
public:
|
||||||
// Constantes
|
// --- Constantes ---
|
||||||
static constexpr float WIDTH = 12.0F;
|
static constexpr float WIDTH = 12.0F; // Anchura de la bala
|
||||||
static constexpr float HEIGHT = 12.0F;
|
static constexpr float HEIGHT = 12.0F; // Altura de la bala
|
||||||
|
|
||||||
// Constructor y Destructor
|
// --- Enums ---
|
||||||
Bullet(float x, float y, BulletType bullet_type, bool powered, Player::Id owner);
|
enum class Type : Uint8 {
|
||||||
~Bullet() = default;
|
UP, // Bala hacia arriba
|
||||||
|
LEFT, // Bala hacia la izquierda
|
||||||
|
RIGHT, // Bala hacia la derecha
|
||||||
|
NONE // Sin bala
|
||||||
|
};
|
||||||
|
|
||||||
// Métodos principales
|
enum class MoveStatus : Uint8 {
|
||||||
void render(); // Dibuja la bala en pantalla
|
OK = 0, // Movimiento normal
|
||||||
auto update() -> BulletMoveStatus; // Actualiza el estado del objeto
|
OUT = 1 // Fuera de los límites
|
||||||
|
};
|
||||||
|
|
||||||
// Estado de la bala
|
enum class Color : Uint8 {
|
||||||
|
YELLOW,
|
||||||
|
GREEN,
|
||||||
|
RED,
|
||||||
|
PURPLE
|
||||||
|
};
|
||||||
|
|
||||||
|
// --- Constructor y destructor ---
|
||||||
|
Bullet(float x, float y, Type type, Color color, int owner); // Constructor principal
|
||||||
|
~Bullet() = default; // Destructor
|
||||||
|
|
||||||
|
// --- Métodos principales ---
|
||||||
|
void render(); // Dibuja la bala en pantalla
|
||||||
|
auto update(float deltaTime) -> MoveStatus; // Actualiza el estado del objeto (time-based)
|
||||||
|
void disable(); // Desactiva la bala
|
||||||
|
|
||||||
|
// --- Getters ---
|
||||||
[[nodiscard]] auto isEnabled() const -> bool; // Comprueba si está activa
|
[[nodiscard]] auto isEnabled() const -> bool; // Comprueba si está activa
|
||||||
void disable(); // Desactiva la bala
|
[[nodiscard]] auto getOwner() const -> int; // Devuelve el identificador del dueño
|
||||||
|
auto getCollider() -> Circle&; // Devuelve el círculo de colisión
|
||||||
// Getters
|
|
||||||
[[nodiscard]] auto getOwner() const -> Player::Id; // Devuelve el identificador del dueño
|
|
||||||
auto getCollider() -> Circle &; // Devuelve el círculo de colisión
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Constantes
|
// --- Constantes ---
|
||||||
static constexpr float VEL_Y = -3.0F;
|
static constexpr float VEL_Y = -180.0F; // Velocidad vertical (pixels/segundo) - era -0.18F pixels/ms
|
||||||
static constexpr float VEL_X_LEFT = -2.0F;
|
static constexpr float VEL_X_LEFT = -120.0F; // Velocidad izquierda (pixels/segundo) - era -0.12F pixels/ms
|
||||||
static constexpr float VEL_X_RIGHT = 2.0F;
|
static constexpr float VEL_X_RIGHT = 120.0F; // Velocidad derecha (pixels/segundo) - era 0.12F pixels/ms
|
||||||
static constexpr float VEL_X_CENTER = 0.0F;
|
static constexpr float VEL_X_CENTER = 0.0F; // Velocidad central
|
||||||
|
|
||||||
// Propiedades
|
// --- Objetos y punteros ---
|
||||||
std::unique_ptr<AnimatedSprite> sprite_; // Sprite con los gráficos
|
std::unique_ptr<AnimatedSprite> sprite_; // Sprite con los gráficos
|
||||||
|
|
||||||
float pos_x_; // Posición en el eje X
|
// --- Variables de estado ---
|
||||||
float pos_y_; // Posición en el eje Y
|
Circle collider_; // Círculo de colisión
|
||||||
float vel_x_; // Velocidad en el eje X
|
Type type_; // Tipo de bala
|
||||||
|
int owner_; // Identificador del jugador
|
||||||
|
float pos_x_; // Posición en el eje X
|
||||||
|
float pos_y_; // Posición en el eje Y
|
||||||
|
float vel_x_; // Velocidad en el eje X
|
||||||
|
|
||||||
BulletType bullet_type_; // Tipo de bala
|
// --- Métodos internos ---
|
||||||
Player::Id owner_; // Identificador del dueño
|
void shiftColliders(); // Ajusta el círculo de colisión
|
||||||
Circle collider_; // Círculo de colisión
|
void shiftSprite(); // Ajusta el sprite
|
||||||
|
auto move(float deltaTime) -> MoveStatus; // Mueve la bala y devuelve su estado (time-based)
|
||||||
// Métodos internos
|
static auto calculateVelocity(Type type) -> float; // Calcula la velocidad horizontal de la bala
|
||||||
void shiftColliders(); // Ajusta el círculo de colisión
|
static auto buildAnimationString(Type type, Color color) -> std::string; // Construye el string de animación
|
||||||
void shiftSprite(); // Ajusta el sprite
|
|
||||||
auto move() -> BulletMoveStatus; // Mueve la bala y devuelve su estado
|
|
||||||
static auto calculateVelocity(BulletType bullet_type) -> float; // Calcula la velocidad horizontal de la bala basada en su tipo
|
|
||||||
static auto buildAnimationString(BulletType bullet_type, bool powered) -> std::string; // Construye el string de animación basado en el tipo de bala y si está potenciada
|
|
||||||
};
|
};
|
||||||
|
|||||||