This commit is contained in:
2025-10-19 22:01:31 +02:00
parent 16306f2325
commit 2b4523d644
101 changed files with 2058 additions and 1564 deletions

61
TODO.md
View File

@@ -1,61 +0,0 @@
# 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"

553
linux_utils/iwyu_tool.py Executable file
View File

@@ -0,0 +1,553 @@
#!/usr/bin/env python3
##===--- iwyu_tool.py -----------------------------------------------------===##
#
# The LLVM Compiler Infrastructure
#
# This file is distributed under the University of Illinois Open Source
# License. See LICENSE.TXT for details.
#
##===----------------------------------------------------------------------===##
""" Driver to consume a Clang compilation database and invoke IWYU.
Example usage with CMake:
# Unix systems
$ mkdir build && cd build
$ CC="clang" CXX="clang++" cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON ...
$ iwyu_tool.py -p .
# Windows systems
$ mkdir build && cd build
$ cmake -DCMAKE_CXX_COMPILER="%VCINSTALLDIR%/bin/cl.exe" \
-DCMAKE_C_COMPILER="%VCINSTALLDIR%/VC/bin/cl.exe" \
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
-G Ninja ...
$ python3 iwyu_tool.py -p .
See iwyu_tool.py -h for more details on command-line arguments.
"""
from __future__ import print_function
import os
import re
import sys
import json
import time
import shlex
import shutil
import argparse
import tempfile
import subprocess
CORRECT_RE = re.compile(r'^\((.*?) has correct #includes/fwd-decls\)$')
SHOULD_ADD_RE = re.compile(r'^(.*?) should add these lines:$')
ADD_RE = re.compile('^(.*?) +// (.*)$')
SHOULD_REMOVE_RE = re.compile(r'^(.*?) should remove these lines:$')
FULL_LIST_RE = re.compile(r'The full include-list for (.*?):$')
END_RE = re.compile(r'^---$')
LINES_RE = re.compile(r'^- (.*?) // lines ([0-9]+)-[0-9]+$')
GENERAL, ADD, REMOVE, LIST = range(4)
def clang_formatter(output, style):
""" Process iwyu's output into something clang-like. """
formatted = []
state = (GENERAL, None)
for line in output.splitlines():
match = CORRECT_RE.match(line)
if match:
# See PR#1806 for more info
continue
match = SHOULD_ADD_RE.match(line)
if match:
state = (ADD, match.group(1))
continue
match = SHOULD_REMOVE_RE.match(line)
if match:
state = (REMOVE, match.group(1))
continue
match = FULL_LIST_RE.match(line)
if match:
state = (LIST, match.group(1))
elif END_RE.match(line):
state = (GENERAL, None)
elif not line.strip():
continue
elif state[0] == GENERAL:
formatted.append(line)
elif state[0] == ADD:
match = ADD_RE.match(line)
if match:
formatted.append("%s:1:1: %s: add '%s' (%s)" %
(state[1],
style,
match.group(1),
match.group(2)))
else:
formatted.append("%s:1:1: %s: add '%s'" %
(state[1], style, line))
elif state[0] == REMOVE:
match = LINES_RE.match(line)
line_no = match.group(2) if match else '1'
formatted.append("%s:%s:1: %s: superfluous '%s'" %
(state[1], line_no, style, match.group(1)))
return os.linesep.join(formatted)
DEFAULT_FORMAT = 'iwyu'
FORMATTERS = {
'iwyu': lambda output: output,
'clang': lambda output: clang_formatter(output, style="error"),
'clang-warning': lambda output: clang_formatter(output, style="warning"),
}
if sys.platform.startswith('win'):
# Case-insensitive match on Windows
def normcase(s):
return s.lower()
else:
def normcase(s):
return s
def is_subpath_of(path, parent):
""" Return True if path is equal to or fully contained within parent.
Assumes both paths are canonicalized with os.path.realpath.
"""
parent = normcase(parent)
path = normcase(path)
if path == parent:
return True
if not path.startswith(parent):
return False
# Now we know parent is a prefix of path, but they only share lineage if the
# difference between them starts with a path separator, e.g. /a/b/c/file
# is not a parent of /a/b/c/file.cpp, but /a/b/c and /a/b/c/ are.
parent = parent.rstrip(os.path.sep)
suffix = path[len(parent):]
return suffix.startswith(os.path.sep)
def is_msvc_driver(compile_command):
""" Return True if compile_command matches an MSVC CL-style driver. """
compile_command = normcase(compile_command)
if compile_command.endswith('cl.exe'):
# Native MSVC compiler or clang-cl.exe
return True
if compile_command.endswith('clang-cl'):
# Cross clang-cl on non-Windows
return True
return False
def win_split(cmdline):
""" Minimal implementation of shlex.split for Windows following
https://msdn.microsoft.com/en-us/library/windows/desktop/17w5ykft.aspx.
"""
def split_iter(cmdline):
in_quotes = False
backslashes = 0
arg = ''
for c in cmdline:
if c == '\\':
# MSDN: Backslashes are interpreted literally, unless they
# immediately precede a double quotation mark.
# Buffer them until we know what comes next.
backslashes += 1
elif c == '"':
# Quotes can either be an escaped quote or the start of a quoted
# string. Paraphrasing MSDN:
# Before quotes, place one backslash in the arg for every pair
# of leading backslashes. If the number of backslashes is odd,
# retain the double quotation mark, otherwise interpret it as a
# string delimiter and switch state.
arg += '\\' * (backslashes // 2)
if backslashes % 2 == 1:
arg += c
else:
in_quotes = not in_quotes
backslashes = 0
elif c in (' ', '\t') and not in_quotes:
# MSDN: Arguments are delimited by white space, which is either
# a space or a tab [but only outside of a string].
# Flush any buffered backslashes and yield arg, unless empty.
arg += '\\' * backslashes
if arg:
yield arg
arg = ''
backslashes = 0
else:
# Flush buffered backslashes and append.
arg += '\\' * backslashes
arg += c
backslashes = 0
if arg:
arg += '\\' * backslashes
yield arg
return list(split_iter(cmdline))
def split_command(cmdstr):
""" Split a command string into a list, respecting shell quoting. """
if sys.platform.startswith('win'):
# shlex.split does not work for Windows command-lines, so special-case
# to our own implementation.
cmd = win_split(cmdstr)
else:
cmd = shlex.split(cmdstr)
return cmd
def find_include_what_you_use():
""" Find IWYU executable and return its full pathname. """
env_iwyu_path = os.environ.get('IWYU_BINARY')
if env_iwyu_path:
return os.path.realpath(env_iwyu_path)
# Search in same dir as this script.
iwyu_path = shutil.which('include-what-you-use',
path=os.path.dirname(__file__))
if iwyu_path:
return os.path.realpath(iwyu_path)
# Search the system PATH.
iwyu_path = shutil.which('include-what-you-use')
if iwyu_path:
return os.path.realpath(iwyu_path)
return None
IWYU_EXECUTABLE = find_include_what_you_use()
class Process(object):
""" Manages an IWYU process in flight """
def __init__(self, proc, outfile):
self.proc = proc
self.outfile = outfile
self.output = None
def poll(self):
""" Return the exit code if the process has completed, None otherwise.
"""
return self.proc.poll()
@property
def returncode(self):
return self.proc.returncode
def get_output(self):
""" Return stdout+stderr output of the process.
This call blocks until the process is complete, then returns the output.
"""
if not self.output:
self.proc.wait()
self.outfile.seek(0)
self.output = self.outfile.read().decode("utf-8")
self.outfile.close()
return self.output
@classmethod
def start(cls, invocation):
""" Start a Process for the invocation and capture stdout+stderr. """
outfile = tempfile.TemporaryFile(prefix='iwyu')
process = subprocess.Popen(
invocation.command,
cwd=invocation.cwd,
stdout=outfile,
stderr=subprocess.STDOUT)
return cls(process, outfile)
KNOWN_COMPILER_WRAPPERS=frozenset([
"ccache"
])
class Invocation(object):
""" Holds arguments of an IWYU invocation. """
def __init__(self, command, cwd):
self.command = command
self.cwd = cwd
def __str__(self):
return ' '.join(self.command)
@classmethod
def from_compile_command(cls, entry, extra_args):
""" Parse a JSON compilation database entry into new Invocation. """
if 'arguments' in entry:
# arguments is a command-line in list form.
command = entry['arguments']
elif 'command' in entry:
# command is a command-line in string form, split to list.
command = split_command(entry['command'])
else:
raise ValueError('Invalid compilation database entry: %s' % entry)
if command[0] in KNOWN_COMPILER_WRAPPERS:
# Remove the compiler wrapper from the command.
command = command[1:]
# Rewrite the compile command for IWYU
compile_command, compile_args = command[0], command[1:]
if is_msvc_driver(compile_command):
# If the compiler is cl-compatible, let IWYU be cl-compatible.
extra_args = ['--driver-mode=cl'] + extra_args
command = [IWYU_EXECUTABLE] + extra_args + compile_args
return cls(command, entry['directory'])
def start(self, verbose):
""" Run invocation and collect output. """
if verbose:
print('# %s' % self, file=sys.stderr)
return Process.start(self)
def fixup_compilation_db(compilation_db):
""" Canonicalize paths in JSON compilation database. """
for entry in compilation_db:
# Convert relative paths to absolute ones if possible, based on the entry's directory.
if 'directory' in entry and not os.path.isabs(entry['file']):
entry['file'] = os.path.join(entry['directory'], entry['file'])
# Expand relative paths and symlinks
entry['file'] = os.path.realpath(entry['file'])
return compilation_db
def select_compilation_db(compilation_db, selection):
""" Return a new compilation database reduced to the paths in selection. """
if not selection:
return compilation_db
# Canonicalize selection paths to match compilation database.
selection = [os.path.realpath(p) for p in selection]
new_db = []
for path in selection:
if not os.path.exists(path):
print('warning: \'%s\' not found on disk.' % path, file=sys.stderr)
continue
found = [e for e in compilation_db if is_subpath_of(e['file'], path)]
if not found:
print('warning: \'%s\' not found in compilation database.' % path,
file=sys.stderr)
continue
new_db.extend(found)
return new_db
def slice_compilation_db(compilation_db, selection, exclude):
""" Return a new compilation database with filtered entries. """
new_db = select_compilation_db(compilation_db, selection)
# Canonicalize selection paths to match compilation database.
exclude = [os.path.realpath(p) for p in exclude]
for path in exclude:
if not os.path.exists(path):
print('warning: excluded path \'%s\' not found on disk.' % path,
file=sys.stderr)
continue
new_db = [e for e in new_db if not is_subpath_of(e['file'], path)]
return new_db
def worst_exit_code(worst, cur):
"""Return the most extreme exit code of two.
Negative exit codes occur if the program exits due to a signal (Unix) or
structured exception (Windows). If we've seen a negative one before, keep
it, as it usually indicates a critical error.
Otherwise return the biggest positive exit code.
"""
if cur < 0:
# Negative results take precedence, return the minimum
return min(worst, cur)
elif worst < 0:
# We know cur is non-negative, negative worst must be minimum
return worst
else:
# We know neither are negative, return the maximum
return max(worst, cur)
def execute(invocations, verbose, formatter, jobs, max_load_average=0):
""" Launch processes described by invocations. """
exit_code = 0
if jobs == 1:
for invocation in invocations:
proc = invocation.start(verbose)
print(formatter(proc.get_output()))
exit_code = worst_exit_code(exit_code, proc.returncode)
return exit_code
pending = []
while invocations or pending:
# Collect completed IWYU processes and print results.
complete = [proc for proc in pending if proc.poll() is not None]
for proc in complete:
pending.remove(proc)
print(formatter(proc.get_output()))
exit_code = worst_exit_code(exit_code, proc.returncode)
# Schedule new processes if there's room.
capacity = jobs - len(pending)
if max_load_average > 0:
one_min_load_average, _, _ = os.getloadavg()
load_capacity = max_load_average - one_min_load_average
if load_capacity < 0:
load_capacity = 0
if load_capacity < capacity:
capacity = int(load_capacity)
if not capacity and not pending:
# Ensure there is at least one job running.
capacity = 1
pending.extend(i.start(verbose) for i in invocations[:capacity])
invocations = invocations[capacity:]
# Yield CPU.
time.sleep(0.0001)
return exit_code
def main(compilation_db_path, source_files, exclude, verbose, formatter, jobs,
max_load_average, extra_args):
""" Entry point. """
if not IWYU_EXECUTABLE:
print('error: include-what-you-use executable not found',
file=sys.stderr)
return 1
try:
if os.path.isdir(compilation_db_path):
compilation_db_path = os.path.join(compilation_db_path,
'compile_commands.json')
# Read compilation db from disk.
compilation_db_path = os.path.realpath(compilation_db_path)
with open(compilation_db_path, 'r') as fileobj:
compilation_db = json.load(fileobj)
except IOError as why:
print('error: failed to parse compilation database: %s' % why,
file=sys.stderr)
return 1
compilation_db = fixup_compilation_db(compilation_db)
compilation_db = slice_compilation_db(compilation_db, source_files, exclude)
# Transform compilation db entries into a list of IWYU invocations.
invocations = [
Invocation.from_compile_command(e, extra_args) for e in compilation_db
]
return execute(invocations, verbose, formatter, jobs, max_load_average)
def _bootstrap(sys_argv):
""" Parse arguments and dispatch to main(). """
# This hackery is necessary to add the forwarded IWYU args to the
# usage and help strings.
def customize_usage(parser):
""" Rewrite the parser's format_usage. """
original_format_usage = parser.format_usage
parser.format_usage = lambda: original_format_usage().rstrip() + \
' -- [<IWYU args>]' + os.linesep
def customize_help(parser):
""" Rewrite the parser's format_help. """
original_format_help = parser.format_help
def custom_help():
""" Customized help string, calls the adjusted format_usage. """
helpmsg = original_format_help()
helplines = helpmsg.splitlines()
helplines[0] = parser.format_usage().rstrip()
return os.linesep.join(helplines) + os.linesep
parser.format_help = custom_help
# Parse arguments.
parser = argparse.ArgumentParser(
description='Include-what-you-use compilation database driver.',
epilog='Assumes include-what-you-use is available on the PATH.')
customize_usage(parser)
customize_help(parser)
parser.add_argument('-v', '--verbose', action='store_true',
help='Print IWYU commands')
parser.add_argument('-o', '--output-format', type=str,
choices=FORMATTERS.keys(), default=DEFAULT_FORMAT,
help='Output format (default: %s)' % DEFAULT_FORMAT)
parser.add_argument('-j', '--jobs', type=int, default=1,
nargs='?', const=0,
help=('Number of concurrent subprocesses. If zero, '
'will try to match the logical cores of the '
'system.'))
parser.add_argument('-l', '--load', type=float, default=0,
help=('Do not start new jobs if the 1min load average '
'is greater than the provided value'))
parser.add_argument('-p', metavar='<build-path>', required=True,
help='Compilation database path', dest='dbpath')
parser.add_argument('-e', '--exclude', action='append', default=[],
help=('Do not run IWYU on source files (or directories) '
'below this path.'))
parser.add_argument('source', nargs='*',
help=('Zero or more source files (or directories) to '
'run IWYU on. Defaults to all in compilation '
'database.'))
def partition_args(argv):
""" Split around '--' into driver args and IWYU args. """
try:
double_dash = argv.index('--')
return argv[:double_dash], argv[double_dash+1:]
except ValueError:
return argv, []
argv, extra_args = partition_args(sys_argv[1:])
args = parser.parse_args(argv)
jobs = args.jobs
if jobs == 0:
jobs = os.cpu_count() or 1
return main(args.dbpath, args.source, args.exclude, args.verbose,
FORMATTERS[args.output_format], jobs, args.load, extra_args)
if __name__ == '__main__':
sys.exit(_bootstrap(sys.argv))

View File

@@ -6,6 +6,8 @@
# Lista de rutas donde ejecutar clang-tidy # Lista de rutas donde ejecutar clang-tidy
PATHS=( PATHS=(
"/home/sergio/gitea/coffee_crisis_arcade_edition/source" "/home/sergio/gitea/coffee_crisis_arcade_edition/source"
"/home/sergio/gitea/coffee_crisis_arcade_edition/source/rendering"
"/home/sergio/gitea/coffee_crisis_arcade_edition/source/rendering/opengl"
"/home/sergio/gitea/coffee_crisis_arcade_edition/source/sections" "/home/sergio/gitea/coffee_crisis_arcade_edition/source/sections"
"/home/sergio/gitea/coffee_crisis_arcade_edition/source/ui" "/home/sergio/gitea/coffee_crisis_arcade_edition/source/ui"
) )

View File

@@ -15,8 +15,8 @@ cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -S "$BASE_DIR" -B "$BUILD_DIR"
# 🛠️ Ejecutar IWYU con fix_includes.py # 🛠️ Ejecutar IWYU con fix_includes.py
echo "🚀 Ejecutando IWYU..." echo "🚀 Ejecutando IWYU..."
iwyu_tool.py -p "$BUILD_DIR" -- -Xiwyu --mapping_file="$MAPPING_FILE" -Xiwyu --verbose=3 \ ./iwyu_tool.py -p "$BUILD_DIR" -- -Xiwyu --mapping_file="$MAPPING_FILE" -Xiwyu --verbose=3 \
| python3 /usr/bin/fix_includes.py --update_comments --reorder --nosafe_headers | fix_include --update_comments --reorder --nosafe_headers
# 🧹 Reemplazar // for por // Para en líneas de #include # 🧹 Reemplazar // for por // Para en líneas de #include
echo "✍️ Corrigiendo comentarios en includes..." echo "✍️ Corrigiendo comentarios en includes..."

View File

@@ -2,17 +2,16 @@
#include <SDL3/SDL.h> // Para SDL_LogWarn, SDL_LogCategory, SDL_LogError, SDL_FRect #include <SDL3/SDL.h> // Para SDL_LogWarn, SDL_LogCategory, SDL_LogError, SDL_FRect
#include <algorithm> // Para min, max #include <algorithm> // Para min
#include <cstddef> // Para size_t #include <cstddef> // Para size_t
#include <fstream> // Para basic_istream, basic_ifstream, basic_ios, ifstream, stringstream #include <fstream> // Para basic_istream, basic_ifstream, istream, basic_ios, ifstream, istringstream, stringstream
#include <sstream> // Para basic_stringstream #include <sstream> // Para basic_istringstream, basic_stringstream
#include <stdexcept> // Para runtime_error #include <stdexcept> // Para runtime_error
#include <utility> // Para pair #include <utility> // Para move, pair
#include "resource_helper.hpp" // Para ResourceHelper #include "resource_helper.hpp" // Para loadFile
#include "texture.hpp" // Para Texture #include "texture.hpp" // Para Texture
#include "utils.hpp" // Para printWithDots #include "ui/logger.hpp" // Para dots
#include "ui/logger.hpp"
// 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 {
@@ -88,13 +87,13 @@ auto AnimatedSprite::getAnimationIndex(const std::string& name) -> int {
} }
// Calcula el frame correspondiente a la animación (time-based) // Calcula el frame correspondiente a la animación (time-based)
void AnimatedSprite::animate(float deltaTime) { void AnimatedSprite::animate(float delta_time) {
if (animations_[current_animation_].speed == 0 || animations_[current_animation_].paused) { if (animations_[current_animation_].speed == 0 || animations_[current_animation_].paused) {
return; return;
} }
// Acumular tiempo transcurrido // Acumular tiempo transcurrido
animations_[current_animation_].time_accumulator += deltaTime; animations_[current_animation_].time_accumulator += delta_time;
// Verificar si es momento de cambiar frame // Verificar si es momento de cambiar frame
if (animations_[current_animation_].time_accumulator >= animations_[current_animation_].speed) { if (animations_[current_animation_].time_accumulator >= animations_[current_animation_].speed) {
@@ -107,7 +106,7 @@ void AnimatedSprite::animate(float deltaTime) {
animations_[current_animation_].current_frame = animations_[current_animation_].frames.size() - 1; animations_[current_animation_].current_frame = animations_[current_animation_].frames.size() - 1;
animations_[current_animation_].completed = true; animations_[current_animation_].completed = true;
} else { // Si hay loop, vuelve al frame indicado } else { // Si hay loop, vuelve al frame indicado
animations_[current_animation_].time_accumulator = 0.0f; animations_[current_animation_].time_accumulator = 0.0F;
animations_[current_animation_].current_frame = animations_[current_animation_].loop; animations_[current_animation_].current_frame = animations_[current_animation_].loop;
} }
} }
@@ -130,7 +129,7 @@ void AnimatedSprite::setCurrentAnimation(const std::string& name, 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_].time_accumulator = 0.0f; 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);
@@ -149,7 +148,7 @@ 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_].time_accumulator = 0.0f; 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());
@@ -161,15 +160,15 @@ void AnimatedSprite::setCurrentAnimation(int index, bool reset) {
} }
// Actualiza las variables del objeto (time-based) // Actualiza las variables del objeto (time-based)
void AnimatedSprite::update(float deltaTime) { void AnimatedSprite::update(float delta_time) {
animate(deltaTime); animate(delta_time);
MovingSprite::update(deltaTime); MovingSprite::update(delta_time);
} }
// 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_].time_accumulator = 0.0f; 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();

View File

@@ -2,15 +2,14 @@
#include <SDL3/SDL.h> // Para SDL_FRect #include <SDL3/SDL.h> // Para SDL_FRect
#include <algorithm> // Para max
#include <cstddef> // Para size_t #include <cstddef> // Para size_t
#include <memory> // Para allocator, shared_ptr #include <memory> // Para shared_ptr
#include <string> // Para string, hash #include <string> // Para basic_string, string, hash
#include <unordered_map> // Para unordered_map #include <unordered_map> // Para unordered_map
#include <utility> #include <utility> // Para move
#include <vector> // Para vector #include <vector> // Para vector
#include "moving_sprite.hpp" // Para MovingSprite #include "moving_sprite.hpp" // for MovingSprite
// Declaración adelantada // Declaración adelantada
class Texture; class Texture;
@@ -25,7 +24,7 @@ struct Animation {
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
float time_accumulator{0.0f}; // Acumulador de tiempo para animaciones time-based 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;
@@ -55,7 +54,7 @@ class AnimatedSprite : public MovingSprite {
~AnimatedSprite() override = default; ~AnimatedSprite() override = default;
// --- Métodos principales --- // --- Métodos principales ---
void update(float deltaTime) override; // Actualiza la animación (time-based) void update(float delta_time) 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
@@ -78,7 +77,7 @@ class AnimatedSprite : public MovingSprite {
int current_animation_ = 0; // Índice de la animación activa int current_animation_ = 0; // Índice de la animación activa
// --- Métodos internos --- // --- Métodos internos ---
void animate(float deltaTime); // Calcula el frame correspondiente a la animación (time-based) void animate(float delta_time); // 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

View File

@@ -1,17 +1,18 @@
#include "asset.hpp" #include "asset.hpp"
#include <SDL3/SDL.h> // Para SDL_LogCategory, SDL_LogInfo, SDL_LogError, SDL_LogWarn #include <SDL3/SDL.h> // Para SDL_LogWarn, SDL_LogCategory, SDL_LogError
#include <algorithm> // Para std::sort #include <algorithm> // Para sort
#include <cstddef> // Para size_t #include <cstddef> // Para size_t
#include <exception> // Para exception #include <exception> // Para exception
#include <filesystem> // Para std::filesystem #include <filesystem> // Para exists, path
#include <fstream> // Para basic_istream, basic_ifstream, ifstream, istringstream #include <fstream> // Para basic_ifstream, basic_istream, basic_ostream, operator<<, ifstream, istringstream, endl
#include <iostream> // Para cout
#include <sstream> // Para basic_istringstream #include <sstream> // Para basic_istringstream
#include <stdexcept> // Para runtime_error #include <stdexcept> // Para runtime_error
#include "resource_helper.hpp" // Para ResourceHelper #include "resource_helper.hpp" // Para loadFile
#include "ui/logger.hpp" // Pâra Logger #include "ui/logger.hpp" // Para info, section, CYAN
#include "utils.hpp" // Para getFileName #include "utils.hpp" // Para getFileName
// Singleton // Singleton
@@ -124,7 +125,7 @@ void Asset::loadFromFile(const std::string& config_file_path, const std::string&
} }
} }
std::cout << "Loaded " << file_list_.size() << " assets from config file" << std::endl; std::cout << "Loaded " << file_list_.size() << " assets from config file" << '\n';
file.close(); file.close();
} }
@@ -204,20 +205,18 @@ auto Asset::checkFile(const std::string& path) const -> bool {
// MODO PACK: Usar ResourceHelper (igual que la carga real) // MODO PACK: Usar ResourceHelper (igual que la carga real)
auto data = ResourceHelper::loadFile(path); auto data = ResourceHelper::loadFile(path);
return !data.empty(); return !data.empty();
} else { } // MODO FILESYSTEM: Verificación directa (modo desarrollo)
// MODO FILESYSTEM: Verificación directa (modo desarrollo) std::ifstream file(path);
std::ifstream file(path); bool success = file.good();
bool success = file.good(); file.close();
file.close();
if (!success) { if (!success) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"Error: Could not open file: %s", "Error: Could not open file: %s",
path.c_str()); path.c_str());
}
return success;
} }
return success;
} }
// Parsea string a Type // Parsea string a Type
@@ -290,7 +289,7 @@ auto Asset::getListByType(Type type) const -> std::vector<std::string> {
} }
// Ordenar alfabéticamente para garantizar orden consistente // Ordenar alfabéticamente para garantizar orden consistente
std::sort(list.begin(), list.end()); std::ranges::sort(list);
return list; return list;
} }

View File

@@ -13,17 +13,17 @@ class AssetIntegrated : public Asset {
const std::string& resource_pack_path = "resources.pack"); const std::string& resource_pack_path = "resources.pack");
// Carga un archivo usando ResourceLoader como primera opción // Carga un archivo usando ResourceLoader como primera opción
std::vector<uint8_t> loadFile(const std::string& filename); auto loadFile(const std::string& filename) -> std::vector<uint8_t>;
// Verifica si un archivo existe (pack o filesystem) // Verifica si un archivo existe (pack o filesystem)
bool fileExists(const std::string& filename) const; auto fileExists(const std::string& filename) const -> bool;
// Obtiene la ruta completa para archivos del sistema/config // Obtiene la ruta completa para archivos del sistema/config
std::string getSystemPath(const std::string& filename) const; auto getSystemPath(const std::string& filename) const -> std::string;
private: private:
static bool resource_pack_enabled_; static bool resource_pack_enabled;
// Determina si un archivo debe cargarse del pack o del filesystem // Determina si un archivo debe cargarse del pack o del filesystem
bool shouldUseResourcePack(const std::string& filepath) const; auto shouldUseResourcePack(const std::string& filepath) const -> bool;
}; };

View File

@@ -7,7 +7,7 @@
#include "external/jail_audio.h" // Para JA_FadeOutMusic, JA_Init, JA_PauseM... #include "external/jail_audio.h" // Para JA_FadeOutMusic, JA_Init, JA_PauseM...
#include "options.hpp" // Para AudioOptions, audio, MusicOptions #include "options.hpp" // Para AudioOptions, audio, MusicOptions
#include "resource.hpp" // Para Resource #include "resource.hpp" // Para Resource
#include "ui/logger.hpp" // Para logger #include "ui/logger.hpp" // Para logger
// Singleton // Singleton
Audio* Audio::instance = nullptr; Audio* Audio::instance = nullptr;
@@ -91,7 +91,7 @@ void Audio::fadeOutMusic(int milliseconds) const {
} }
// Consulta directamente el estado real de la música en jailaudio // Consulta directamente el estado real de la música en jailaudio
auto Audio::getRealMusicState() const -> MusicState { auto Audio::getRealMusicState() -> MusicState {
JA_Music_state ja_state = JA_GetMusicState(); JA_Music_state ja_state = JA_GetMusicState();
switch (ja_state) { switch (ja_state) {
case JA_MUSIC_PLAYING: case JA_MUSIC_PLAYING:

View File

@@ -67,12 +67,12 @@ class Audio {
void setMusicVolume(int volume) const; // Ajustar volumen de música void setMusicVolume(int volume) const; // Ajustar volumen de música
// --- Getters para debug --- // --- Getters para debug ---
bool isEnabled() const { return enabled_; } [[nodiscard]] auto isEnabled() const -> bool { return enabled_; }
bool isSoundEnabled() const { return sound_enabled_; } [[nodiscard]] auto isSoundEnabled() const -> bool { return sound_enabled_; }
bool isMusicEnabled() const { return music_enabled_; } [[nodiscard]] auto isMusicEnabled() const -> bool { return music_enabled_; }
MusicState getMusicState() const { return music_.state; } [[nodiscard]] auto getMusicState() const -> MusicState { return music_.state; }
MusicState getRealMusicState() const; // Consulta directamente a jailaudio [[nodiscard]] static auto getRealMusicState() -> MusicState; // Consulta directamente a jailaudio
const std::string& getCurrentMusicName() const { return music_.name; } [[nodiscard]] auto getCurrentMusicName() const -> const std::string& { return music_.name; }
private: private:
// --- Estructuras privadas --- // --- Estructuras privadas ---

View File

@@ -3,18 +3,19 @@
#include <SDL3/SDL.h> // Para SDL_FRect, SDL_SetRenderTarget, SDL_CreateTexture, SDL_DestroyTexture, SDL_GetRenderTarget, SDL_RenderTexture, SDL_SetTextureAlphaMod, SDL_SetTextureBlendMode, SDL_BLENDMODE_BLEND, SDL_PixelFormat, SDL_RenderClear, SDL_SetRenderDrawColor, SDL_TextureAccess, SDL_FPoint #include <SDL3/SDL.h> // Para SDL_FRect, SDL_SetRenderTarget, SDL_CreateTexture, SDL_DestroyTexture, SDL_GetRenderTarget, SDL_RenderTexture, SDL_SetTextureAlphaMod, SDL_SetTextureBlendMode, SDL_BLENDMODE_BLEND, SDL_PixelFormat, SDL_RenderClear, SDL_SetRenderDrawColor, SDL_TextureAccess, SDL_FPoint
#include <algorithm> // Para clamp, max #include <algorithm> // Para clamp, min, max
#include <cmath> // Para M_PI, cos, sin #include <cmath> // Para M_PI, cos, sin
#include <utility> #include <string> // Para basic_string
#include <utility> // Para move
#include "animated_sprite.hpp" // Para MovingSprite #include "animated_sprite.hpp" // Para AnimatedSprite
#include "moving_sprite.hpp" // Para MovingSprite #include "moving_sprite.hpp" // Para MovingSprite
#include "param.hpp" // Para Param, ParamBackground, param #include "param.hpp" // Para Param, ParamBackground, param
#include "resource.hpp" // Para Resource #include "resource.hpp" // Para Resource
#include "screen.hpp" // Para Screen #include "screen.hpp" // Para Screen
#include "sprite.hpp" // Para Sprite #include "sprite.hpp" // Para Sprite
#include "texture.hpp" // Para Texture #include "texture.hpp" // Para Texture
#include "utils.hpp" // Para funciones de easing #include "utils.hpp" // Para easeOutCubic
// Constructor // Constructor
Background::Background(float total_progress_to_complete) Background::Background(float total_progress_to_complete)
@@ -191,7 +192,7 @@ void Background::setState(State new_state) {
// Si entra en estado completado, inicializar variables de transición // Si entra en estado completado, inicializar variables de transición
if (new_state == State::COMPLETED && state_ != State::COMPLETED) { if (new_state == State::COMPLETED && state_ != State::COMPLETED) {
completion_initial_progress_ = progress_; completion_initial_progress_ = progress_;
completion_transition_timer_ = 0.0f; completion_transition_timer_ = 0.0F;
} }
state_ = new_state; state_ = new_state;
@@ -209,8 +210,8 @@ void Background::reset() {
moon_index_ = 0; moon_index_ = 0;
// Resetear variables de transición de completado // Resetear variables de transición de completado
completion_transition_timer_ = 0.0f; completion_transition_timer_ = 0.0F;
completion_initial_progress_ = 0.0f; completion_initial_progress_ = 0.0F;
// Notifica el cambio si hay callback // Notifica el cambio si hay callback
if (progress_callback_ && progress_ != old_progress) { if (progress_callback_ && progress_ != old_progress) {
@@ -274,9 +275,9 @@ void Background::updateProgression(float delta_time) {
completion_transition_timer_ += delta_time; completion_transition_timer_ += delta_time;
// Calcular progreso normalizado de la transición (0.0 a 1.0) // 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); float t = std::min(completion_transition_timer_ / COMPLETION_TRANSITION_DURATION_S, 1.0F);
if (t < 1.0f) { if (t < 1.0F) {
// Usar easeOutCubic para transición suave (rápido al inicio, lento al final) // Usar easeOutCubic para transición suave (rápido al inicio, lento al final)
float eased_t = easeOutCubic(static_cast<double>(t)); float eased_t = easeOutCubic(static_cast<double>(t));
@@ -342,12 +343,12 @@ void Background::updateCloudsSpeed() {
} }
// Actualiza las nubes // Actualiza las nubes
void Background::updateClouds(float deltaTime) { void Background::updateClouds(float delta_time) {
// Mueve las nubes // Mueve las nubes
top_clouds_sprite_a_->update(deltaTime); top_clouds_sprite_a_->update(delta_time);
top_clouds_sprite_b_->update(deltaTime); top_clouds_sprite_b_->update(delta_time);
bottom_clouds_sprite_a_->update(deltaTime); bottom_clouds_sprite_a_->update(delta_time);
bottom_clouds_sprite_b_->update(deltaTime); bottom_clouds_sprite_b_->update(delta_time);
// Calcula el offset de las nubes // Calcula el offset de las nubes
if (top_clouds_sprite_a_->getPosX() < -top_clouds_sprite_a_->getWidth()) { if (top_clouds_sprite_a_->getPosX() < -top_clouds_sprite_a_->getWidth()) {

View File

@@ -117,8 +117,8 @@ class Background {
bool manual_mode_ = false; // Si está en modo manual bool manual_mode_ = false; // Si está en modo manual
// --- Variables para transición suave de completado --- // --- Variables para transición suave de completado ---
float completion_transition_timer_ = 0.0f; // Timer para la transición de completado float completion_transition_timer_ = 0.0F; // Timer para la transición de completado
float completion_initial_progress_ = 0.0f; // Progreso inicial al entrar en estado completado float completion_initial_progress_ = 0.0F; // Progreso inicial al entrar en estado completado
// --- Métodos internos --- // --- Métodos internos ---
void initializePaths(); // Inicializa las rutas del sol y la luna void initializePaths(); // Inicializa las rutas del sol y la luna
@@ -133,7 +133,7 @@ class Background {
void renderBottomClouds(); // Dibuja las nubes inferiores void renderBottomClouds(); // Dibuja las nubes inferiores
void fillCanvas(); // Compone todos los elementos en la textura void fillCanvas(); // Compone todos los elementos en la textura
void updateAlphaColorTexture(); // Actualiza el alpha de la textura de atenuación void updateAlphaColorTexture(); // Actualiza el alpha de la textura de atenuación
void updateClouds(float deltaTime); // Actualiza el movimiento de las nubes (time-based) void updateClouds(float delta_time); // Actualiza el movimiento de las nubes (time-based)
void createSunPath(); // Precalcula el recorrido del sol void createSunPath(); // Precalcula el recorrido del sol
void createMoonPath(); // Precalcula el recorrido de la luna void createMoonPath(); // Precalcula el recorrido de la luna
}; };

View File

@@ -131,7 +131,7 @@ void Balloon::render() {
// Renderizado para el resto de globos // Renderizado para el resto de globos
if (isBeingCreated()) { if (isBeingCreated()) {
// Renderizado con transparencia // Renderizado con transparencia
sprite_->getTexture()->setAlpha(255 - (int)((float)creation_counter_ * (255.0F / (float)creation_counter_ini_))); sprite_->getTexture()->setAlpha(255 - (int)(creation_counter_ * (255.0F / creation_counter_ini_)));
sprite_->render(); sprite_->render();
sprite_->getTexture()->setAlpha(255); sprite_->getTexture()->setAlpha(255);
} else { } else {
@@ -142,19 +142,19 @@ void Balloon::render() {
} }
// Actualiza la posición y estados del globo (time-based) // Actualiza la posición y estados del globo (time-based)
void Balloon::move(float deltaTime) { void Balloon::move(float delta_time) {
if (isStopped()) { if (isStopped()) {
return; return;
} }
handleHorizontalMovement(deltaTime); handleHorizontalMovement(delta_time);
handleVerticalMovement(deltaTime); handleVerticalMovement(delta_time);
applyGravity(deltaTime); applyGravity(delta_time);
} }
void Balloon::handleHorizontalMovement(float deltaTime) { void Balloon::handleHorizontalMovement(float delta_time) {
// DeltaTime en segundos: velocidad (pixels/s) * tempo * tiempo (s) // DeltaTime en segundos: velocidad (pixels/s) * tempo * tiempo (s)
x_ += vx_ * game_tempo_ * deltaTime; x_ += vx_ * game_tempo_ * delta_time;
const int CLIP = 2; const int CLIP = 2;
const float MIN_X = play_area_.x - CLIP; const float MIN_X = play_area_.x - CLIP;
@@ -165,9 +165,9 @@ void Balloon::handleHorizontalMovement(float deltaTime) {
} }
} }
void Balloon::handleVerticalMovement(float deltaTime) { void Balloon::handleVerticalMovement(float delta_time) {
// DeltaTime en segundos: velocidad (pixels/s) * tempo * tiempo (s) // DeltaTime en segundos: velocidad (pixels/s) * tempo * tiempo (s)
y_ += vy_ * game_tempo_ * deltaTime; y_ += vy_ * game_tempo_ * delta_time;
if (shouldCheckTopCollision()) { if (shouldCheckTopCollision()) {
handleTopCollision(); handleTopCollision();
@@ -222,37 +222,37 @@ void Balloon::handleBottomCollision() {
} }
} }
void Balloon::applyGravity(float deltaTime) { void Balloon::applyGravity(float delta_time) {
// DeltaTime en segundos: aceleración (pixels/s²) * tempo * tiempo (s) // DeltaTime en segundos: aceleración (pixels/s²) * tempo * tiempo (s)
vy_ += gravity_ * game_tempo_ * deltaTime; vy_ += gravity_ * game_tempo_ * delta_time;
} }
void Balloon::playBouncingSound() { void Balloon::playBouncingSound() const {
if (sound_.enabled && sound_.bouncing_enabled) { if (sound_.enabled && sound_.bouncing_enabled) {
Audio::get()->playSound(sound_.bouncing_file); Audio::get()->playSound(sound_.bouncing_file);
} }
} }
void Balloon::playPoppingSound() { void Balloon::playPoppingSound() const {
if (sound_.enabled && sound_.poping_enabled) { if (sound_.enabled && sound_.poping_enabled) {
Audio::get()->playSound(sound_.popping_file); Audio::get()->playSound(sound_.popping_file);
} }
} }
// Actualiza al globo a su posicion, animación y controla los contadores (time-based) // Actualiza al globo a su posicion, animación y controla los contadores (time-based)
void Balloon::update(float deltaTime) { void Balloon::update(float delta_time) {
move(deltaTime); move(delta_time);
updateState(deltaTime); updateState(delta_time);
updateBounceEffect(); updateBounceEffect();
shiftSprite(); shiftSprite();
shiftColliders(); shiftColliders();
sprite_->update(deltaTime); sprite_->update(delta_time);
// Contador interno con deltaTime en segundos // Contador interno con deltaTime en segundos
counter_ += deltaTime; counter_ += delta_time;
} }
// Actualiza los estados del globo (time-based) // Actualiza los estados del globo (time-based)
void Balloon::updateState(float deltaTime) { void Balloon::updateState(float delta_time) {
// Si se está creando // Si se está creando
if (isBeingCreated()) { if (isBeingCreated()) {
// Actualiza el valor de las variables // Actualiza el valor de las variables
@@ -262,13 +262,13 @@ void Balloon::updateState(float deltaTime) {
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
// Cada 10/60 segundos (equivalente a 10 frames a 60fps) // Cada 10/60 segundos (equivalente a 10 frames a 60fps)
movement_accumulator_ += deltaTime; movement_accumulator_ += delta_time;
constexpr float MOVEMENT_INTERVAL_S = 10.0f / 60.0f; // 10 frames = ~0.167s constexpr float MOVEMENT_INTERVAL_S = 10.0F / 60.0F; // 10 frames = ~0.167s
if (movement_accumulator_ >= MOVEMENT_INTERVAL_S) { if (movement_accumulator_ >= MOVEMENT_INTERVAL_S) {
movement_accumulator_ -= MOVEMENT_INTERVAL_S; movement_accumulator_ -= MOVEMENT_INTERVAL_S;
y_++; y_++;
x_ += vx_ / 60.0f; // Convierte de pixels/segundo a pixels/frame para movimiento discreto 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;
@@ -276,12 +276,12 @@ void Balloon::updateState(float deltaTime) {
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_ / 60.0f; x_ -= vx_ / 60.0F;
vx_ = -vx_; vx_ = -vx_;
} }
} }
creation_counter_ -= deltaTime; creation_counter_ -= delta_time;
if (creation_counter_ < 0) creation_counter_ = 0; creation_counter_ = std::max<float>(creation_counter_, 0);
} }
else { else {

View File

@@ -77,7 +77,7 @@ class Balloon {
Size size = Size::EXTRALARGE; Size size = Size::EXTRALARGE;
float vel_x = VELX_POSITIVE; float vel_x = VELX_POSITIVE;
float game_tempo = GAME_TEMPO.at(0); float game_tempo = GAME_TEMPO.at(0);
float creation_counter = 0.0f; float creation_counter = 0.0F;
SDL_FRect play_area = {.x = 0.0F, .y = 0.0F, .w = 0.0F, .h = 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::shared_ptr<Texture> texture = nullptr;
std::vector<std::string> animation; std::vector<std::string> animation;
@@ -91,8 +91,8 @@ class Balloon {
// --- 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(float deltaTime); // Actualiza la posición y estados del globo (time-based) void move(float delta_time); // Actualiza la posición y estados del globo (time-based)
void update(float deltaTime); // Actualiza el globo (posición, animación, contadores) (time-based) void update(float delta_time); // 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
@@ -268,7 +268,7 @@ class Balloon {
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 game_tempo_; // Multiplicador de tempo del juego float game_tempo_; // Multiplicador de tempo del juego
float movement_accumulator_ = 0.0f; // Acumulador para movimiento durante creación (deltaTime) 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
Sound sound_; // Configuración de sonido del globo Sound sound_; // Configuración de sonido del globo
@@ -279,14 +279,14 @@ class Balloon {
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 playBouncingSound(); // Reproduce el sonido de rebote void playBouncingSound() const; // Reproduce el sonido de rebote
void playPoppingSound(); // Reproduce el sonido de reventar void playPoppingSound() const; // Reproduce el sonido de reventar
// --- Movimiento y física --- // --- Movimiento y física ---
void handleHorizontalMovement(float deltaTime); // Maneja el movimiento horizontal (time-based) void handleHorizontalMovement(float delta_time); // Maneja el movimiento horizontal (time-based)
void handleVerticalMovement(float deltaTime); // Maneja el movimiento vertical (time-based) void handleVerticalMovement(float delta_time); // Maneja el movimiento vertical (time-based)
void applyGravity(float deltaTime); // Aplica la gravedad al objeto (time-based) void applyGravity(float delta_time); // Aplica la gravedad al objeto (time-based)
// --- Rebote --- // --- Rebote ---
void enableBounceEffect(); // Activa el efecto de rebote void enableBounceEffect(); // Activa el efecto de rebote
@@ -301,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(float deltaTime); // Actualiza los estados del globo (time-based) void updateState(float delta_time); // Actualiza los estados del globo (time-based)
}; };

View File

@@ -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, 3.334f}, // 200 frames ÷ 60fps = 3.334s {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, 3.334f}, // 200 frames ÷ 60fps = 3.334s {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, 3.334f}, // 200 frames ÷ 60fps = 3.334s {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, 3.334f}}; // 200 frames ÷ 60fps = 3.334s {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);
} }

View File

@@ -1,14 +1,14 @@
#pragma once #pragma once
#include <algorithm> // Para copy, max #include <cstddef> // Para size_t
#include <cstddef> // Para size_t #include <iterator> // Para pair
#include <map> // Para map #include <map> // Para map
#include <optional> // Para optional #include <optional> // Para optional
#include <string> // Para string #include <string> // Para string
#include <utility> // Para pair #include <utility> // Para pair
#include <vector> // Para vector #include <vector> // Para vector
#include "balloon.hpp" // Para Balloon #include "balloon.hpp" // for Balloon
// --- Clase BalloonFormations --- // --- Clase BalloonFormations ---
class BalloonFormations { class BalloonFormations {
@@ -20,7 +20,7 @@ class BalloonFormations {
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
float creation_counter = 0.0f; // 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;
@@ -82,8 +82,8 @@ 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 float CREATION_TIME = 5.0f; // Tiempo base de creación de los globos en segundos (300 frames ÷ 60fps = 5.0s) 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) static constexpr float DEFAULT_CREATION_TIME = 3.334F; // Tiempo base de creación de los globos en segundos (200 frames ÷ 60fps = 3.334s)
// --- Variables --- // --- Variables ---
std::vector<Formation> formations_; // Vector con todas las formaciones disponibles std::vector<Formation> formations_; // Vector con todas las formaciones disponibles

View File

@@ -63,12 +63,12 @@ void BalloonManager::init() {
} }
// Actualiza (time-based) // Actualiza (time-based)
void BalloonManager::update(float deltaTime) { void BalloonManager::update(float delta_time) {
for (const auto& balloon : balloons_) { for (const auto& balloon : balloons_) {
balloon->update(deltaTime); balloon->update(delta_time);
} }
updateBalloonDeployCounter(deltaTime); updateBalloonDeployCounter(delta_time);
explosions_->update(deltaTime); explosions_->update(delta_time);
} }
// Renderiza los objetos // Renderiza los objetos
@@ -82,7 +82,7 @@ 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 el timer ha llegado a cero // Solo despliega una formación enemiga si el timer ha llegado a cero
if (balloon_deploy_counter_ <= 0.0f) { 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
@@ -114,7 +114,7 @@ void BalloonManager::deployRandomFormation(int stage) {
.size = balloon.size, .size = balloon.size,
.vel_x = balloon.vel_x, .vel_x = balloon.vel_x,
.game_tempo = balloon_speed_, .game_tempo = balloon_speed_,
.creation_counter = creation_time_enabled_ ? balloon.creation_counter : 0.0f}; .creation_counter = creation_time_enabled_ ? balloon.creation_counter : 0.0F};
createBalloon(config); createBalloon(config);
} }
@@ -163,9 +163,9 @@ void BalloonManager::freeBalloons() {
} }
// Actualiza el timer de despliegue de globos (time-based) // Actualiza el timer de despliegue de globos (time-based)
void BalloonManager::updateBalloonDeployCounter(float deltaTime) { void BalloonManager::updateBalloonDeployCounter(float delta_time) {
// DeltaTime en segundos - timer decrementa hasta llegar a cero // DeltaTime en segundos - timer decrementa hasta llegar a cero
balloon_deploy_counter_ -= deltaTime; balloon_deploy_counter_ -= delta_time;
} }
// Indica si se puede crear una powerball // Indica si se puede crear una powerball

View File

@@ -2,19 +2,18 @@
#include <SDL3/SDL.h> // Para SDL_FRect #include <SDL3/SDL.h> // Para SDL_FRect
#include <algorithm> // Para max #include <array> // Para array
#include <array> // Para array #include <memory> // Para shared_ptr, unique_ptr
#include <memory> // Para shared_ptr, unique_ptr #include <string> // Para basic_string, string
#include <string> // Para string #include <vector> // Para vector
#include <vector> // Para vector
#include "balloon.hpp" // Para BALLOON_SPEED, Balloon, Balloon::Size (ptr only), Balloon::Type (ptr only) #include "balloon.hpp" // for Balloon
#include "balloon_formations.hpp" // Para BalloonFormations #include "balloon_formations.hpp" // for BalloonFormations
#include "explosions.hpp" // Para Explosions #include "explosions.hpp" // for Explosions
#include "param.hpp" // Para Param, ParamGame, param #include "param.hpp" // for Param, ParamGame, param
#include "stage_interface.hpp" // Para IStageInfo #include "utils.hpp" // for Zone
#include "utils.hpp" // Para Zone
class IStageInfo;
class Texture; class Texture;
// --- Types --- // --- Types ---
@@ -28,8 +27,8 @@ class BalloonManager {
~BalloonManager() = default; ~BalloonManager() = default;
// --- Métodos principales --- // --- Métodos principales ---
void update(float deltaTime); // Actualiza el estado de los globos (time-based) void update(float delta_time); // 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
@@ -49,7 +48,7 @@ class BalloonManager {
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(float deltaTime); // Actualiza el contador de despliegue (time-based) void updateBalloonDeployCounter(float delta_time); // 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
@@ -82,9 +81,9 @@ class BalloonManager {
private: private:
// --- Constantes --- // --- Constantes ---
static constexpr float DEFAULT_BALLOON_DEPLOY_DELAY = 5.0f; // 300 frames = 5 segundos static constexpr float DEFAULT_BALLOON_DEPLOY_DELAY = 5.0F; // 300 frames = 5 segundos
static constexpr float POWERBALL_DEPLOY_DELAY = 0.167f; // 10 frames = 0.167 segundos 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 static constexpr float BALLOON_POP_DELAY = 0.333F; // 20 frames = 0.333 segundos
// --- Objetos y punteros --- // --- Objetos y punteros ---
Balloons balloons_; // Vector con los globos activos Balloons balloons_; // Vector con los globos activos

View File

@@ -1,10 +1,9 @@
#include "bullet.hpp" #include "bullet.hpp"
#include <memory> // Para allocator, unique_ptr, make_unique #include <memory> // Para unique_ptr, make_unique
#include <string> // Para char_traits, basic_string, operator+, string #include <string> // Para basic_string, string
#include "param.hpp" // Para Param, ParamGame, param #include "param.hpp" // Para Param, ParamGame, param
#include "player.hpp" // Para Player::Id
#include "resource.hpp" // Para Resource #include "resource.hpp" // Para Resource
// Constructor // Constructor
@@ -79,20 +78,20 @@ void Bullet::render() {
} }
// Actualiza el estado del objeto // Actualiza el estado del objeto
auto Bullet::update(float deltaTime) -> MoveStatus { auto Bullet::update(float delta_time) -> MoveStatus {
sprite_->update(deltaTime); sprite_->update(delta_time);
return move(deltaTime); return move(delta_time);
} }
// Implementación del movimiento usando MoveStatus // Implementación del movimiento usando MoveStatus
auto Bullet::move(float deltaTime) -> MoveStatus { auto Bullet::move(float delta_time) -> MoveStatus {
pos_x_ += vel_x_ * deltaTime; pos_x_ += vel_x_ * delta_time;
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 MoveStatus::OUT; return MoveStatus::OUT;
} }
pos_y_ += VEL_Y * deltaTime; pos_y_ += VEL_Y * delta_time;
if (pos_y_ < param.game.play_area.rect.y - HEIGHT) { if (pos_y_ < param.game.play_area.rect.y - HEIGHT) {
disable(); disable();
return MoveStatus::OUT; return MoveStatus::OUT;

View File

@@ -40,9 +40,9 @@ class Bullet {
~Bullet() = default; // Destructor ~Bullet() = default; // Destructor
// --- Métodos principales --- // --- Métodos principales ---
void render(); // Dibuja la bala en pantalla void render(); // Dibuja la bala en pantalla
auto update(float deltaTime) -> MoveStatus; // Actualiza el estado del objeto (time-based) auto update(float delta_time) -> MoveStatus; // Actualiza el estado del objeto (time-based)
void disable(); // Desactiva la bala void disable(); // Desactiva la bala
// --- Getters --- // --- Getters ---
[[nodiscard]] auto isEnabled() const -> bool; // Comprueba si está activa [[nodiscard]] auto isEnabled() const -> bool; // Comprueba si está activa
@@ -70,7 +70,7 @@ class Bullet {
// --- Métodos internos --- // --- Métodos internos ---
void shiftColliders(); // Ajusta el círculo de colisión void shiftColliders(); // Ajusta el círculo de colisión
void shiftSprite(); // Ajusta el sprite void shiftSprite(); // Ajusta el sprite
auto move(float deltaTime) -> MoveStatus; // Mueve la bala y devuelve su estado (time-based) auto move(float delta_time) -> MoveStatus; // Mueve la bala y devuelve su estado (time-based)
static auto calculateVelocity(Type type) -> float; // Calcula la velocidad horizontal de la bala static auto calculateVelocity(Type type) -> float; // Calcula la velocidad horizontal de la bala
static auto buildAnimationString(Type type, Color color) -> std::string; // Construye el string de animación static auto buildAnimationString(Type type, Color color) -> std::string; // Construye el string de animación
}; };

View File

@@ -1,10 +1,11 @@
#include "bullet_manager.hpp" #include "bullet_manager.hpp"
#include <algorithm> // Para remove_if #include <algorithm> // Para remove_if
#include <utility>
#include "bullet.hpp" // Para Bullet #include "bullet.hpp" // Para Bullet
#include "param.hpp" // Para param #include "param.hpp" // Para Param, ParamGame, param
#include "player.hpp" // Para Player #include "utils.hpp" // Para Circle, Zone
// Constructor // Constructor
BulletManager::BulletManager() BulletManager::BulletManager()
@@ -12,10 +13,10 @@ BulletManager::BulletManager()
} }
// Actualiza el estado de todas las balas // Actualiza el estado de todas las balas
void BulletManager::update(float deltaTime) { void BulletManager::update(float delta_time) {
for (auto& bullet : bullets_) { for (auto& bullet : bullets_) {
if (bullet->isEnabled()) { if (bullet->isEnabled()) {
processBulletUpdate(bullet, deltaTime); processBulletUpdate(bullet, delta_time);
} }
} }
} }
@@ -36,14 +37,9 @@ void BulletManager::createBullet(int x, int y, Bullet::Type type, Bullet::Color
// Libera balas que ya no están habilitadas // Libera balas que ya no están habilitadas
void BulletManager::freeBullets() { void BulletManager::freeBullets() {
if (!bullets_.empty()) { std::erase_if(bullets_, [](const std::shared_ptr<Bullet>& bullet) {
// Elimina las balas deshabilitadas del vector return !bullet->isEnabled();
bullets_.erase( });
std::remove_if(bullets_.begin(), bullets_.end(), [](const std::shared_ptr<Bullet>& bullet) {
return !bullet->isEnabled();
}),
bullets_.end());
}
} }
// Elimina todas las balas // Elimina todas las balas
@@ -72,24 +68,24 @@ void BulletManager::checkCollisions() {
// Establece el callback para colisión con Tabe // Establece el callback para colisión con Tabe
void BulletManager::setTabeCollisionCallback(CollisionCallback callback) { void BulletManager::setTabeCollisionCallback(CollisionCallback callback) {
tabe_collision_callback_ = callback; tabe_collision_callback_ = std::move(callback);
} }
// Establece el callback para colisión con globos // Establece el callback para colisión con globos
void BulletManager::setBalloonCollisionCallback(CollisionCallback callback) { void BulletManager::setBalloonCollisionCallback(CollisionCallback callback) {
balloon_collision_callback_ = callback; balloon_collision_callback_ = std::move(callback);
} }
// Establece el callback para balas fuera de límites // Establece el callback para balas fuera de límites
void BulletManager::setOutOfBoundsCallback(OutOfBoundsCallback callback) { void BulletManager::setOutOfBoundsCallback(OutOfBoundsCallback callback) {
out_of_bounds_callback_ = callback; out_of_bounds_callback_ = std::move(callback);
} }
// --- Métodos privados --- // --- Métodos privados ---
// Procesa la actualización individual de una bala // Procesa la actualización individual de una bala
void BulletManager::processBulletUpdate(const std::shared_ptr<Bullet>& bullet, float deltaTime) { void BulletManager::processBulletUpdate(const std::shared_ptr<Bullet>& bullet, float delta_time) {
auto status = bullet->update(deltaTime); auto status = bullet->update(delta_time);
// Si la bala salió de los límites, llama al callback // Si la bala salió de los límites, llama al callback
if (status == Bullet::MoveStatus::OUT && out_of_bounds_callback_) { if (status == Bullet::MoveStatus::OUT && out_of_bounds_callback_) {
@@ -98,7 +94,7 @@ void BulletManager::processBulletUpdate(const std::shared_ptr<Bullet>& bullet, f
} }
// Verifica si la bala está fuera de los límites del área de juego // Verifica si la bala está fuera de los límites del área de juego
auto BulletManager::isBulletOutOfBounds(const std::shared_ptr<Bullet>& bullet) -> bool { auto BulletManager::isBulletOutOfBounds(const std::shared_ptr<Bullet>& bullet) const -> bool {
auto collider = bullet->getCollider(); auto collider = bullet->getCollider();
return (collider.x < play_area_.x || return (collider.x < play_area_.x ||

View File

@@ -3,18 +3,14 @@
#include <SDL3/SDL.h> // Para SDL_FRect #include <SDL3/SDL.h> // Para SDL_FRect
#include <functional> // Para function #include <functional> // Para function
#include <memory> // Para shared_ptr, unique_ptr #include <memory> // Para shared_ptr
#include <vector> // Para vector #include <vector> // Para vector
#include "bullet.hpp" // Para Bullet #include "bullet.hpp" // for Bullet
#include "utils.hpp" // Para Circle
// --- Types --- // --- Types ---
using Bullets = std::vector<std::shared_ptr<Bullet>>; using Bullets = std::vector<std::shared_ptr<Bullet>>;
// --- Forward declarations ---
class Player;
// --- Clase BulletManager: gestiona todas las balas del juego --- // --- Clase BulletManager: gestiona todas las balas del juego ---
// //
// Esta clase se encarga de la gestión completa de las balas del juego, // Esta clase se encarga de la gestión completa de las balas del juego,
@@ -40,8 +36,8 @@ class BulletManager {
~BulletManager() = default; ~BulletManager() = default;
// --- Métodos principales --- // --- Métodos principales ---
void update(float deltaTime); // Actualiza el estado de las balas (time-based) void update(float delta_time); // Actualiza el estado de las balas (time-based)
void render(); // Renderiza las balas en pantalla void render(); // Renderiza las balas en pantalla
// --- Gestión de balas --- // --- Gestión de balas ---
void createBullet(int x, int y, Bullet::Type type, Bullet::Color color, int owner); // Crea una nueva bala void createBullet(int x, int y, Bullet::Type type, Bullet::Color color, int owner); // Crea una nueva bala
@@ -74,6 +70,6 @@ class BulletManager {
OutOfBoundsCallback out_of_bounds_callback_; // Callback para balas fuera de límites OutOfBoundsCallback out_of_bounds_callback_; // Callback para balas fuera de límites
// --- Métodos internos --- // --- Métodos internos ---
void processBulletUpdate(const std::shared_ptr<Bullet>& bullet, float deltaTime); // Procesa actualización individual void processBulletUpdate(const std::shared_ptr<Bullet>& bullet, float delta_time); // Procesa actualización individual
auto isBulletOutOfBounds(const std::shared_ptr<Bullet>& bullet) -> bool; // Verifica si la bala está fuera de límites auto isBulletOutOfBounds(const std::shared_ptr<Bullet>& bullet) const -> bool; // Verifica si la bala está fuera de límites
}; };

View File

@@ -43,7 +43,7 @@ auto Color::fromHex(const std::string& hex_str) -> Color {
} }
// Implementaciones de métodos estáticos de Color // Implementaciones de métodos estáticos de Color
constexpr auto Color::rgbToHsv(Color color) -> HSV { constexpr auto Color::RGB_TO_HSV(Color color) -> HSV {
float r = color.r / 255.0F; float r = color.r / 255.0F;
float g = color.g / 255.0F; float g = color.g / 255.0F;
float b = color.b / 255.0F; float b = color.b / 255.0F;
@@ -73,7 +73,7 @@ constexpr auto Color::rgbToHsv(Color color) -> HSV {
return {.h = h, .s = s, .v = v}; return {.h = h, .s = s, .v = v};
} }
constexpr auto Color::hsvToRgb(HSV hsv) -> Color { constexpr auto Color::HSV_TO_RGB(HSV hsv) -> Color {
float c = hsv.v * hsv.s; float c = hsv.v * hsv.s;
float x = c * (1 - std::abs(std::fmod(hsv.h / 60.0F, 2) - 1)); float x = c * (1 - std::abs(std::fmod(hsv.h / 60.0F, 2) - 1));
float m = hsv.v - c; float m = hsv.v - c;
@@ -133,7 +133,7 @@ auto getColorLikeKnightRider(const std::vector<Color>& colors, int counter) -> C
auto generateMirroredCycle(Color base, ColorCycleStyle style) -> Cycle { auto generateMirroredCycle(Color base, ColorCycleStyle style) -> Cycle {
Cycle result{}; Cycle result{};
HSV base_hsv = Color::rgbToHsv(base); HSV base_hsv = Color::RGB_TO_HSV(base);
for (size_t i = 0; i < CYCLE_SIZE; ++i) { for (size_t i = 0; i < CYCLE_SIZE; ++i) {
float t = static_cast<float>(i) / (CYCLE_SIZE - 1); // 0 → 1 float t = static_cast<float>(i) / (CYCLE_SIZE - 1); // 0 → 1
@@ -176,7 +176,7 @@ auto generateMirroredCycle(Color base, ColorCycleStyle style) -> Cycle {
.s = fminf(1.0F, fmaxf(0.0F, base_hsv.s + sat_shift)), .s = fminf(1.0F, fmaxf(0.0F, base_hsv.s + sat_shift)),
.v = fminf(1.0F, fmaxf(0.0F, base_hsv.v + val_shift))}; .v = fminf(1.0F, fmaxf(0.0F, base_hsv.v + val_shift))};
Color c = Color::hsvToRgb(adjusted); Color c = Color::HSV_TO_RGB(adjusted);
result[i] = c; result[i] = c;
result[(2 * CYCLE_SIZE) - 1 - i] = c; // espejo result[(2 * CYCLE_SIZE) - 1 - i] = c; // espejo
} }

View File

@@ -72,8 +72,8 @@ struct Color {
static auto fromHex(const std::string& hex_str) -> Color; static auto fromHex(const std::string& hex_str) -> Color;
// Conversiones de formato de color // Conversiones de formato de color
[[nodiscard]] constexpr static auto rgbToHsv(Color color) -> HSV; [[nodiscard]] constexpr static auto RGB_TO_HSV(Color color) -> HSV;
[[nodiscard]] constexpr static auto hsvToRgb(HSV hsv) -> Color; [[nodiscard]] constexpr static auto HSV_TO_RGB(HSV hsv) -> Color;
[[nodiscard]] constexpr auto IS_EQUAL_TO(const Color& other) const -> bool { [[nodiscard]] constexpr auto IS_EQUAL_TO(const Color& other) const -> bool {
return r == other.r && g == other.g && b == other.b && a == other.a; return r == other.r && g == other.g && b == other.b && a == other.a;
@@ -98,11 +98,11 @@ struct Color {
// Interpolación lineal hacia otro color (t=0.0: this, t=1.0: target) // Interpolación lineal hacia otro color (t=0.0: this, t=1.0: target)
[[nodiscard]] constexpr auto LERP(const Color& target, float t) const -> Color { [[nodiscard]] constexpr auto LERP(const Color& target, float t) const -> Color {
// Asegurar que t esté en el rango [0.0, 1.0] // Asegurar que t esté en el rango [0.0, 1.0]
t = std::clamp(t, 0.0f, 1.0f); t = std::clamp(t, 0.0F, 1.0F);
// Interpolación lineal para cada componente // Interpolación lineal para cada componente
auto lerp_component = [t](Uint8 start, Uint8 end) -> Uint8 { auto lerp_component = [t](Uint8 start, Uint8 end) -> Uint8 {
return static_cast<Uint8>(start + (end - start) * t); return static_cast<Uint8>(start + ((end - start) * t));
}; };
return Color( return Color(

View File

@@ -1,15 +1,13 @@
#include "define_buttons.hpp" #include "define_buttons.hpp"
#include <algorithm> // Para __all_of_fn, all_of #include <algorithm> // Para __all_of_fn, all_of
#include <functional> // Para identity #include <memory> // Para unique_ptr, allocator, shared_ptr, operator==, make_unique
#include <memory> // Para allocator, unique_ptr, shared_ptr, make_unique, operator==
#include "color.hpp" // Para Color
#include "input.hpp" // Para Input #include "input.hpp" // Para Input
#include "input_types.hpp" // Para InputAction #include "input_types.hpp" // Para InputAction
#include "lang.hpp" // Para getText #include "lang.hpp" // Para getText
#include "options.hpp" // Para Gamepad #include "options.hpp" // Para Gamepad
#include "param.hpp" // Para Param, ParamGame, param #include "param.hpp" // Para Param, param, ParamGame, ParamServiceMenu
#include "resource.hpp" // Para Resource #include "resource.hpp" // Para Resource
#include "ui/window_message.hpp" // Para WindowMessage #include "ui/window_message.hpp" // Para WindowMessage
#include "utils.hpp" // Para Zone #include "utils.hpp" // Para Zone
@@ -234,7 +232,7 @@ void DefineButtons::checkEnd() {
// Solo marcar que ya mostramos el mensaje // Solo marcar que ya mostramos el mensaje
message_shown_ = true; message_shown_ = true;
message_timer_ = 0.0f; message_timer_ = 0.0F;
} }
} }

View File

@@ -48,7 +48,7 @@ class DefineButtons {
private: private:
// --- Constantes --- // --- Constantes ---
static constexpr float MESSAGE_DISPLAY_DURATION_S = 2.0f; // Cuánto tiempo mostrar el mensaje en segundos static constexpr float MESSAGE_DISPLAY_DURATION_S = 2.0F; // Cuánto tiempo mostrar el mensaje en segundos
// --- Objetos y punteros --- // --- Objetos y punteros ---
Input* input_ = nullptr; // Entrada del usuario Input* input_ = nullptr; // Entrada del usuario
@@ -59,7 +59,7 @@ class DefineButtons {
std::vector<Button> buttons_; // Lista de botones std::vector<Button> buttons_; // Lista de botones
std::vector<std::string> controller_names_; // Nombres de los controladores std::vector<std::string> controller_names_; // Nombres de los controladores
size_t index_button_ = 0; // Índice del botón seleccionado size_t index_button_ = 0; // Índice del botón seleccionado
float message_timer_ = 0.0f; // Timer en segundos para el mensaje float message_timer_ = 0.0F; // Timer en segundos para el mensaje
bool enabled_ = false; // Flag para indicar si está activo bool enabled_ = false; // Flag para indicar si está activo
bool finished_ = false; // Flag para indicar si ha terminado bool finished_ = false; // Flag para indicar si ha terminado
bool closing_ = false; // Flag para indicar que está cerrando bool closing_ = false; // Flag para indicar que está cerrando

View File

@@ -5,8 +5,8 @@
#include <stdexcept> // Para runtime_error #include <stdexcept> // Para runtime_error
#include "resource_helper.hpp" // Para ResourceHelper #include "resource_helper.hpp" // Para ResourceHelper
#include "utils.hpp" // Para printWithDots, getFileName
#include "ui/logger.hpp" #include "ui/logger.hpp"
#include "utils.hpp" // Para printWithDots, getFileName
// Carga el fichero de datos para la demo // Carga el fichero de datos para la demo
auto loadDemoDataFromFile(const std::string& file_path) -> DemoData { auto loadDemoDataFromFile(const std::string& file_path) -> DemoData {

View File

@@ -1,26 +1,27 @@
// IWYU pragma: no_include <bits/chrono.h> // IWYU pragma: no_include <bits/chrono.h>
#include "director.hpp" #include "director.hpp"
#include <SDL3/SDL.h> // Para SDL_LogInfo, SDL_LogCategory, SDL_SetLogPriority, SDL_LogPriority, SDL_Quit #include <SDL3/SDL.h> // Para SDL_SetLogPriority, SDL_LogCategory, SDL_LogPriority, SDL_Quit
#include <cstdlib> // Para srand, exit, rand, EXIT_FAILURE #include <cstdlib> // Para srand, exit, rand, EXIT_FAILURE
#include <ctime> // Para time #include <ctime> // Para time
#include <iostream> // Para basic_ostream, operator<<, cerr, endl #include <filesystem> // Para path, absolute
#include <memory> // Para make_unique, unique_ptr #include <iostream> // Para basic_ostream, operator<<, cerr
#include <span> // Para span #include <memory> // Para make_unique, unique_ptr
#include <stdexcept> // Para runtime_error #include <span> // Para span
#include <string> // Para allocator, char_traits, operator==, string, basic_string, operator+ #include <stdexcept> // Para runtime_error
#include <string> // Para allocator, basic_string, char_traits, operator+, string, operator==
#include "asset.hpp" // Para Asset #include "asset.hpp" // Para Asset
#include "audio.hpp" // Para Audio #include "audio.hpp" // Para Audio
#include "input.hpp" // Para Input #include "input.hpp" // Para Input
#include "lang.hpp" // Para setLanguage #include "lang.hpp" // Para setLanguage
#include "manage_hiscore_table.hpp" // Para ManageHiScoreTable #include "manage_hiscore_table.hpp" // Para ManageHiScoreTable
#include "options.hpp" // Para loadFromFile, saveToFile, Settings, settings, setConfigFile, setControllersFile #include "options.hpp" // Para Settings, loadFromFile, saveToFile, settings, setConfigFile, setControllersFile
#include "param.hpp" // Para loadParamsFromFile #include "param.hpp" // Para loadParamsFromFile
#include "player.hpp" // Para Player #include "player.hpp" // Para Player
#include "resource.hpp" // Para Resource #include "resource.hpp" // Para Resource
#include "resource_helper.hpp" // Para ResourceHelper #include "resource_helper.hpp" // Para initializeResourceSystem
#include "screen.hpp" // Para Screen #include "screen.hpp" // Para Screen
#include "section.hpp" // Para Name, Options, name, options, AttractMode, attract_mode #include "section.hpp" // Para Name, Options, name, options, AttractMode, attract_mode
#include "sections/credits.hpp" // Para Credits #include "sections/credits.hpp" // Para Credits
@@ -32,10 +33,10 @@
#include "sections/title.hpp" // Para Title #include "sections/title.hpp" // Para Title
#include "shutdown.hpp" // Para resultToString, shutdownSystem, ShutdownResult #include "shutdown.hpp" // Para resultToString, shutdownSystem, ShutdownResult
#include "system_utils.hpp" // Para createApplicationFolder, resultToString, Result #include "system_utils.hpp" // Para createApplicationFolder, resultToString, Result
#include "ui/logger.hpp" // Para section, put
#include "ui/notifier.hpp" // Para Notifier #include "ui/notifier.hpp" // Para Notifier
#include "ui/service_menu.hpp" // Para ServiceMenu #include "ui/service_menu.hpp" // Para ServiceMenu
#include "utils.hpp" // Para Overrides, overrides, getPath #include "utils.hpp" // Para Overrides, overrides
#include "ui/logger.hpp"
// Constructor // Constructor
Director::Director(int argc, std::span<char*> argv) { Director::Director(int argc, std::span<char*> argv) {
@@ -85,28 +86,27 @@ void Director::init() {
#else #else
ResourceHelper::initializeResourceSystem(executable_path_ + "resources.pack"); ResourceHelper::initializeResourceSystem(executable_path_ + "resources.pack");
#endif #endif
loadAssets(); // Crea el índice de archivos loadAssets(); // Crea el índice de archivos
Logger::section("INIT INPUT"); Logger::section("INIT INPUT");
Input::init(Asset::get()->get("gamecontrollerdb.txt"), Asset::get()->get("controllers.json")); // Carga configuración de controles Input::init(Asset::get()->get("gamecontrollerdb.txt"), Asset::get()->get("controllers.json")); // Carga configuración de controles
Logger::section("INIT CONFIG"); Logger::section("INIT CONFIG");
Options::setConfigFile(Asset::get()->get("config_v2.txt")); // Establece el fichero de configuración Options::setConfigFile(Asset::get()->get("config_v2.txt")); // Establece el fichero de configuración
Options::setControllersFile(Asset::get()->get("controllers.json")); // Establece el fichero de configuración de mandos Options::setControllersFile(Asset::get()->get("controllers.json")); // Establece el fichero de configuración de mandos
Options::loadFromFile(); // Carga el archivo de configuración Options::loadFromFile(); // Carga el archivo de configuración
loadParams(); // Carga los parámetros del programa loadParams(); // Carga los parámetros del programa
loadScoreFile(); // Carga el archivo de puntuaciones loadScoreFile(); // Carga el archivo de puntuaciones
// Inicialización de subsistemas principales // Inicialización de subsistemas principales
Lang::setLanguage(Options::settings.language); // Carga el archivo de idioma Lang::setLanguage(Options::settings.language); // Carga el archivo de idioma
Logger::section("INIT VIDEO"); Logger::section("INIT VIDEO");
Screen::init(); // Inicializa la pantalla y el sistema de renderizado Screen::init(); // Inicializa la pantalla y el sistema de renderizado
Logger::section("INIT AUDIO"); Logger::section("INIT AUDIO");
Audio::init(); // Activa el sistema de audio Audio::init(); // Activa el sistema de audio
Logger::section("INIT RESOURCES"); Logger::section("INIT RESOURCES");
#ifdef _DEBUG #ifdef _DEBUG
Resource::init(Resource::LoadingMode::PRELOAD); // Inicializa el sistema de gestión de recursos Resource::init(Resource::LoadingMode::PRELOAD); // Inicializa el sistema de gestión de recursos

View File

@@ -6,8 +6,7 @@
// Constructor // Constructor
EnterName::EnterName() EnterName::EnterName()
: character_list_("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789."), : character_list_("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.") {}
selected_index_(0) {}
// Inicializa el objeto // Inicializa el objeto
void EnterName::init(const std::string& name) { void EnterName::init(const std::string& name) {

View File

@@ -1,15 +1,13 @@
#include "explosions.hpp" #include "explosions.hpp"
#include <algorithm> // Para max
#include "animated_sprite.hpp" // Para AnimatedSprite #include "animated_sprite.hpp" // Para AnimatedSprite
class Texture; // lines 4-4 class Texture; // lines 4-4
// Actualiza la lógica de la clase (time-based) // Actualiza la lógica de la clase (time-based)
void Explosions::update(float deltaTime) { void Explosions::update(float delta_time) {
for (auto& explosion : explosions_) { for (auto& explosion : explosions_) {
explosion->update(deltaTime); explosion->update(delta_time);
} }
// Vacia el vector de elementos finalizados // Vacia el vector de elementos finalizados

View File

@@ -29,8 +29,8 @@ class Explosions {
~Explosions() = default; // Destructor por defecto ~Explosions() = default; // Destructor por defecto
// --- Métodos principales --- // --- Métodos principales ---
void update(float deltaTime); // Actualiza la lógica de la clase (time-based) void update(float delta_time); // Actualiza la lógica de la clase (time-based)
void render(); // Dibuja el objeto en pantalla void render(); // Dibuja el objeto en pantalla
// --- Configuración --- // --- Configuración ---
void addTexture(int size, const std::shared_ptr<Texture>& texture, const std::vector<std::string>& animation); // Añade texturas al objeto void addTexture(int size, const std::shared_ptr<Texture>& texture, const std::vector<std::string>& animation); // Añade texturas al objeto

View File

@@ -366,7 +366,7 @@ void Fade::activateDiagonal(int diagonal_index, Uint32 current_time) {
// Verificar que y está dentro de los límites // Verificar que y está dentro de los límites
if (y >= 0 && y < num_squares_height_) { if (y >= 0 && y < num_squares_height_) {
// Convertir coordenadas (x,y) a índice en el vector // Convertir coordenadas (x,y) a índice en el vector
int index = y * num_squares_width_ + x; int index = (y * num_squares_width_) + x;
if (index >= 0 && index < static_cast<int>(square_age_.size())) { if (index >= 0 && index < static_cast<int>(square_age_.size())) {
if (square_age_[index] == -1) { if (square_age_[index] == -1) {
@@ -405,12 +405,12 @@ void Fade::drawDiagonal() {
} else { } else {
// Cuadrado activado - calculamos progreso // Cuadrado activado - calculamos progreso
Uint32 square_elapsed = current_time - square_age_[i]; Uint32 square_elapsed = current_time - square_age_[i];
float progress = std::min(static_cast<float>(square_elapsed) / square_transition_duration_, 1.0f); float progress = std::min(static_cast<float>(square_elapsed) / square_transition_duration_, 1.0F);
if (mode_ == Mode::OUT) { if (mode_ == Mode::OUT) {
current_alpha = static_cast<Uint8>(progress * a_); // 0 → 255 current_alpha = static_cast<Uint8>(progress * a_); // 0 → 255
} else { } else {
current_alpha = static_cast<Uint8>((1.0f - progress) * a_); // 255 → 0 current_alpha = static_cast<Uint8>((1.0F - progress) * a_); // 255 → 0
} }
} }
@@ -470,12 +470,12 @@ void Fade::drawRandomSquares2() {
} else { } else {
// Cuadrado activado - calculamos progreso // Cuadrado activado - calculamos progreso
Uint32 square_elapsed = current_time - square_age_[i]; Uint32 square_elapsed = current_time - square_age_[i];
float progress = std::min(static_cast<float>(square_elapsed) / square_transition_duration_, 1.0f); float progress = std::min(static_cast<float>(square_elapsed) / square_transition_duration_, 1.0F);
if (mode_ == Mode::OUT) { if (mode_ == Mode::OUT) {
current_alpha = static_cast<Uint8>(progress * a_); // 0 → 255 current_alpha = static_cast<Uint8>(progress * a_); // 0 → 255
} else { } else {
current_alpha = static_cast<Uint8>((1.0f - progress) * a_); // 255 → 0 current_alpha = static_cast<Uint8>((1.0F - progress) * a_); // 255 → 0
} }
} }

View File

@@ -3,6 +3,7 @@
#include <SDL3/SDL.h> // Para SDL_SetTextureScaleMode, SDL_FlipMode, SDL_ScaleMode #include <SDL3/SDL.h> // Para SDL_SetTextureScaleMode, SDL_FlipMode, SDL_ScaleMode
#include <algorithm> // Para max #include <algorithm> // Para max
#include <string> // Para basic_string
#include "animated_sprite.hpp" // Para AnimatedSprite #include "animated_sprite.hpp" // Para AnimatedSprite
#include "audio.hpp" // Para Audio #include "audio.hpp" // Para Audio
@@ -15,8 +16,8 @@
#include "texture.hpp" // Para Texture #include "texture.hpp" // Para Texture
constexpr int ZOOM_FACTOR = 5; constexpr int ZOOM_FACTOR = 5;
constexpr float FLASH_DELAY_S = 0.05f; // 3 frames → 0.05s constexpr float FLASH_DELAY_S = 0.05F; // 3 frames → 0.05s
constexpr float FLASH_DURATION_S = 0.1f; // 6 frames → 0.1s (3 + 3) constexpr float FLASH_DURATION_S = 0.1F; // 6 frames → 0.1s (3 + 3)
constexpr Color FLASH_COLOR = Color(0xFF, 0xFF, 0xFF); // Color blanco para el flash constexpr Color FLASH_COLOR = Color(0xFF, 0xFF, 0xFF); // Color blanco para el flash
// Constructor // Constructor
@@ -46,7 +47,7 @@ void GameLogo::init() {
arcade_edition_status_ = Status::DISABLED; arcade_edition_status_ = Status::DISABLED;
shake_.init(1, 2, 8, XP); shake_.init(1, 2, 8, XP);
zoom_ = 3.0F * ZOOM_FACTOR; zoom_ = 3.0F * ZOOM_FACTOR;
post_finished_timer_ = 0.0f; post_finished_timer_ = 0.0F;
// Inicializa el bitmap de 'Coffee' // Inicializa el bitmap de 'Coffee'
coffee_sprite_->setPosX(XP); coffee_sprite_->setPosX(XP);
@@ -59,7 +60,7 @@ void GameLogo::init() {
coffee_sprite_->setAccelY(COFFEE_ACCEL_Y); coffee_sprite_->setAccelY(COFFEE_ACCEL_Y);
coffee_sprite_->setSpriteClip(0, 0, coffee_texture_->getWidth(), coffee_texture_->getHeight()); coffee_sprite_->setSpriteClip(0, 0, coffee_texture_->getWidth(), coffee_texture_->getHeight());
coffee_sprite_->setEnabled(true); coffee_sprite_->setEnabled(true);
coffee_sprite_->setFinishedDelay(0.0f); coffee_sprite_->setFinishedDelay(0.0F);
coffee_sprite_->setDestX(XP); coffee_sprite_->setDestX(XP);
coffee_sprite_->setDestY(y_ - coffee_texture_->getHeight()); coffee_sprite_->setDestY(y_ - coffee_texture_->getHeight());
@@ -74,7 +75,7 @@ void GameLogo::init() {
crisis_sprite_->setAccelY(CRISIS_ACCEL_Y); crisis_sprite_->setAccelY(CRISIS_ACCEL_Y);
crisis_sprite_->setSpriteClip(0, 0, crisis_texture_->getWidth(), crisis_texture_->getHeight()); crisis_sprite_->setSpriteClip(0, 0, crisis_texture_->getWidth(), crisis_texture_->getHeight());
crisis_sprite_->setEnabled(true); crisis_sprite_->setEnabled(true);
crisis_sprite_->setFinishedDelay(0.0f); crisis_sprite_->setFinishedDelay(0.0F);
crisis_sprite_->setDestX(XP + CRISIS_OFFSET_X); crisis_sprite_->setDestX(XP + CRISIS_OFFSET_X);
crisis_sprite_->setDestY(y_); crisis_sprite_->setDestY(y_);
@@ -115,44 +116,44 @@ void GameLogo::render() {
} }
// Actualiza la lógica de la clase (time-based) // Actualiza la lógica de la clase (time-based)
void GameLogo::update(float deltaTime) { void GameLogo::update(float delta_time) {
updateCoffeeCrisis(deltaTime); updateCoffeeCrisis(delta_time);
updateArcadeEdition(deltaTime); updateArcadeEdition(delta_time);
updatePostFinishedCounter(deltaTime); updatePostFinishedCounter(delta_time);
} }
void GameLogo::updateCoffeeCrisis(float deltaTime) { void GameLogo::updateCoffeeCrisis(float delta_time) {
switch (coffee_crisis_status_) { switch (coffee_crisis_status_) {
case Status::MOVING: case Status::MOVING:
handleCoffeeCrisisMoving(deltaTime); handleCoffeeCrisisMoving(delta_time);
break; break;
case Status::SHAKING: case Status::SHAKING:
handleCoffeeCrisisShaking(deltaTime); handleCoffeeCrisisShaking(delta_time);
break; break;
case Status::FINISHED: case Status::FINISHED:
handleCoffeeCrisisFinished(deltaTime); handleCoffeeCrisisFinished(delta_time);
break; break;
default: default:
break; break;
} }
} }
void GameLogo::updateArcadeEdition(float deltaTime) { void GameLogo::updateArcadeEdition(float delta_time) {
switch (arcade_edition_status_) { switch (arcade_edition_status_) {
case Status::MOVING: case Status::MOVING:
handleArcadeEditionMoving(deltaTime); handleArcadeEditionMoving(delta_time);
break; break;
case Status::SHAKING: case Status::SHAKING:
handleArcadeEditionShaking(deltaTime); handleArcadeEditionShaking(delta_time);
break; break;
default: default:
break; break;
} }
} }
void GameLogo::handleCoffeeCrisisMoving(float deltaTime) { void GameLogo::handleCoffeeCrisisMoving(float delta_time) {
coffee_sprite_->update(deltaTime); coffee_sprite_->update(delta_time);
crisis_sprite_->update(deltaTime); crisis_sprite_->update(delta_time);
if (coffee_sprite_->hasFinished() && crisis_sprite_->hasFinished()) { if (coffee_sprite_->hasFinished() && crisis_sprite_->hasFinished()) {
coffee_crisis_status_ = Status::SHAKING; coffee_crisis_status_ = Status::SHAKING;
@@ -160,23 +161,23 @@ void GameLogo::handleCoffeeCrisisMoving(float deltaTime) {
} }
} }
void GameLogo::handleCoffeeCrisisShaking(float deltaTime) { void GameLogo::handleCoffeeCrisisShaking(float delta_time) {
if (shake_.remaining > 0) { if (shake_.remaining > 0) {
processShakeEffect(coffee_sprite_.get(), crisis_sprite_.get(), deltaTime); processShakeEffect(coffee_sprite_.get(), crisis_sprite_.get(), delta_time);
} else { } else {
finishCoffeeCrisisShaking(); finishCoffeeCrisisShaking();
} }
updateDustSprites(deltaTime); updateDustSprites(delta_time);
} }
void GameLogo::handleCoffeeCrisisFinished(float deltaTime) { void GameLogo::handleCoffeeCrisisFinished(float delta_time) {
updateDustSprites(deltaTime); updateDustSprites(delta_time);
} }
void GameLogo::handleArcadeEditionMoving(float deltaTime) { void GameLogo::handleArcadeEditionMoving(float delta_time) {
// DeltaTime en segundos: decremento por segundo // DeltaTime en segundos: decremento por segundo
zoom_ -= (ZOOM_DECREMENT_PER_S * ZOOM_FACTOR) * deltaTime; zoom_ -= (ZOOM_DECREMENT_PER_S * ZOOM_FACTOR) * delta_time;
arcade_edition_sprite_->setZoom(zoom_); arcade_edition_sprite_->setZoom(zoom_);
if (zoom_ <= 1.0F) { if (zoom_ <= 1.0F) {
@@ -184,17 +185,17 @@ void GameLogo::handleArcadeEditionMoving(float deltaTime) {
} }
} }
void GameLogo::handleArcadeEditionShaking(float deltaTime) { void GameLogo::handleArcadeEditionShaking(float delta_time) {
if (shake_.remaining > 0) { if (shake_.remaining > 0) {
processArcadeEditionShake(deltaTime); processArcadeEditionShake(delta_time);
} else { } else {
arcade_edition_sprite_->setX(shake_.origin); arcade_edition_sprite_->setX(shake_.origin);
arcade_edition_status_ = Status::FINISHED; arcade_edition_status_ = Status::FINISHED;
} }
} }
void GameLogo::processShakeEffect(SmartSprite* primary_sprite, SmartSprite* secondary_sprite, float deltaTime) { void GameLogo::processShakeEffect(SmartSprite* primary_sprite, SmartSprite* secondary_sprite, float delta_time) {
shake_.time_accumulator += deltaTime; shake_.time_accumulator += delta_time;
if (shake_.time_accumulator >= SHAKE_DELAY_S) { if (shake_.time_accumulator >= SHAKE_DELAY_S) {
shake_.time_accumulator -= SHAKE_DELAY_S; shake_.time_accumulator -= SHAKE_DELAY_S;
@@ -207,14 +208,14 @@ void GameLogo::processShakeEffect(SmartSprite* primary_sprite, SmartSprite* seco
} }
} }
void GameLogo::processArcadeEditionShake(float deltaTime) { void GameLogo::processArcadeEditionShake(float delta_time) {
// Delay fijo en segundos (shake_.delay era frames, ahora usamos constante) // Delay fijo en segundos (shake_.delay era frames, ahora usamos constante)
float delayTime = SHAKE_DELAY_S; float delay_time = SHAKE_DELAY_S;
shake_.time_accumulator += deltaTime; shake_.time_accumulator += delta_time;
if (shake_.time_accumulator >= delayTime) { if (shake_.time_accumulator >= delay_time) {
shake_.time_accumulator -= delayTime; shake_.time_accumulator -= delay_time;
const auto DISPLACEMENT = calculateShakeDisplacement(); const auto DISPLACEMENT = calculateShakeDisplacement();
arcade_edition_sprite_->setX(shake_.origin + DISPLACEMENT); arcade_edition_sprite_->setX(shake_.origin + DISPLACEMENT);
shake_.remaining--; shake_.remaining--;
@@ -246,15 +247,15 @@ void GameLogo::playTitleEffects() {
Screen::get()->shake(); Screen::get()->shake();
} }
void GameLogo::updateDustSprites(float deltaTime) { void GameLogo::updateDustSprites(float delta_time) {
dust_right_sprite_->update(deltaTime); dust_right_sprite_->update(delta_time);
dust_left_sprite_->update(deltaTime); dust_left_sprite_->update(delta_time);
} }
void GameLogo::updatePostFinishedCounter(float deltaTime) { void GameLogo::updatePostFinishedCounter(float delta_time) {
if (coffee_crisis_status_ == Status::FINISHED && if (coffee_crisis_status_ == Status::FINISHED &&
arcade_edition_status_ == Status::FINISHED) { arcade_edition_status_ == Status::FINISHED) {
post_finished_timer_ += deltaTime; post_finished_timer_ += delta_time;
} }
} }

View File

@@ -27,9 +27,9 @@ class GameLogo {
~GameLogo() = default; ~GameLogo() = default;
// --- Métodos principales --- // --- Métodos principales ---
void render(); // Pinta la clase en pantalla void render(); // Pinta la clase en pantalla
void update(float deltaTime); // Actualiza la lógica de la clase (time-based) void update(float delta_time); // Actualiza la lógica de la clase (time-based)
void enable(); // Activa la clase void enable(); // Activa la clase
// --- Getters --- // --- Getters ---
[[nodiscard]] auto hasFinished() const -> bool; // Indica si ha terminado la animación [[nodiscard]] auto hasFinished() const -> bool; // Indica si ha terminado la animación
@@ -50,7 +50,7 @@ class GameLogo {
int length = 8; // Cantidad de desplazamientos a realizar int length = 8; // Cantidad de desplazamientos a realizar
int remaining = length; // Cantidad de desplazamientos pendientes a realizar int remaining = length; // Cantidad de desplazamientos pendientes a realizar
int counter = delay; // Contador para el retraso (frame-based) int counter = delay; // Contador para el retraso (frame-based)
float time_accumulator = 0.0f; // Acumulador de tiempo para deltaTime float time_accumulator = 0.0F; // Acumulador de tiempo para deltaTime
int origin = 0; // Valor inicial de la pantalla para dejarla igual tras el desplazamiento int origin = 0; // Valor inicial de la pantalla para dejarla igual tras el desplazamiento
Shake() = default; Shake() = default;
@@ -68,7 +68,7 @@ class GameLogo {
length = l; length = l;
remaining = l; remaining = l;
counter = de; counter = de;
time_accumulator = 0.0f; time_accumulator = 0.0F;
origin = o; origin = o;
} }
}; };
@@ -93,33 +93,33 @@ class GameLogo {
float y_; // Posición Y del logo float y_; // Posición Y del logo
float zoom_ = 1.0F; // Zoom aplicado al texto "ARCADE EDITION" float zoom_ = 1.0F; // Zoom aplicado al texto "ARCADE EDITION"
float post_finished_delay_s_ = POST_FINISHED_FRAME_TIME_S; // Retraso final tras animaciones (s) float post_finished_delay_s_ = POST_FINISHED_FRAME_TIME_S; // Retraso final tras animaciones (s)
float post_finished_timer_ = 0.0f; // Timer acumulado para retraso final (s) float post_finished_timer_ = 0.0F; // Timer acumulado para retraso final (s)
// --- Inicialización --- // --- Inicialización ---
void init(); // Inicializa las variables void init(); // Inicializa las variables
[[nodiscard]] auto getInitialVerticalDesp() const -> int; // Calcula el desplazamiento vertical inicial [[nodiscard]] auto getInitialVerticalDesp() const -> int; // Calcula el desplazamiento vertical inicial
// --- Actualización de estados específicos --- // --- Actualización de estados específicos ---
void updateCoffeeCrisis(float deltaTime); // Actualiza el estado de "Coffee Crisis" (time-based) void updateCoffeeCrisis(float delta_time); // Actualiza el estado de "Coffee Crisis" (time-based)
void updateArcadeEdition(float deltaTime); // Actualiza el estado de "Arcade Edition" (time-based) void updateArcadeEdition(float delta_time); // Actualiza el estado de "Arcade Edition" (time-based)
void updatePostFinishedCounter(float deltaTime); // Actualiza el contador tras finalizar una animación (time-based) void updatePostFinishedCounter(float delta_time); // Actualiza el contador tras finalizar una animación (time-based)
// --- Efectos visuales: movimiento y sacudidas --- // --- Efectos visuales: movimiento y sacudidas ---
void handleCoffeeCrisisMoving(float deltaTime); // Maneja el movimiento de "Coffee Crisis" (time-based) void handleCoffeeCrisisMoving(float delta_time); // Maneja el movimiento de "Coffee Crisis" (time-based)
void handleCoffeeCrisisShaking(float deltaTime); // Maneja la sacudida de "Coffee Crisis" (time-based) void handleCoffeeCrisisShaking(float delta_time); // Maneja la sacudida de "Coffee Crisis" (time-based)
void handleArcadeEditionMoving(float deltaTime); // Maneja el movimiento de "Arcade Edition" (time-based) void handleArcadeEditionMoving(float delta_time); // Maneja el movimiento de "Arcade Edition" (time-based)
void handleArcadeEditionShaking(float deltaTime); // Maneja la sacudida de "Arcade Edition" (time-based) void handleArcadeEditionShaking(float delta_time); // Maneja la sacudida de "Arcade Edition" (time-based)
void processShakeEffect(SmartSprite* primary_sprite, SmartSprite* secondary_sprite = nullptr); // Procesa el efecto de sacudida en sprites (frame-based) void processShakeEffect(SmartSprite* primary_sprite, SmartSprite* secondary_sprite = nullptr); // Procesa el efecto de sacudida en sprites (frame-based)
void processShakeEffect(SmartSprite* primary_sprite, SmartSprite* secondary_sprite, float deltaTime); // Procesa el efecto de sacudida en sprites (time-based) void processShakeEffect(SmartSprite* primary_sprite, SmartSprite* secondary_sprite, float delta_time); // Procesa el efecto de sacudida en sprites (time-based)
void processArcadeEditionShake(float deltaTime); // Procesa la sacudida específica de "Arcade Edition" (time-based) void processArcadeEditionShake(float delta_time); // Procesa la sacudida específica de "Arcade Edition" (time-based)
[[nodiscard]] auto calculateShakeDisplacement() const -> int; // Calcula el desplazamiento de la sacudida [[nodiscard]] auto calculateShakeDisplacement() const -> int; // Calcula el desplazamiento de la sacudida
// --- Gestión de finalización de efectos --- // --- Gestión de finalización de efectos ---
void handleCoffeeCrisisFinished(float deltaTime); // Maneja el final de la animación "Coffee Crisis" (time-based) void handleCoffeeCrisisFinished(float delta_time); // Maneja el final de la animación "Coffee Crisis" (time-based)
void finishCoffeeCrisisShaking(); // Finaliza la sacudida de "Coffee Crisis" void finishCoffeeCrisisShaking(); // Finaliza la sacudida de "Coffee Crisis"
void finishArcadeEditionMoving(); // Finaliza el movimiento de "Arcade Edition" void finishArcadeEditionMoving(); // Finaliza el movimiento de "Arcade Edition"
// --- Utilidades --- // --- Utilidades ---
static void playTitleEffects(); // Reproduce efectos visuales/sonoros del título static void playTitleEffects(); // Reproduce efectos visuales/sonoros del título
void updateDustSprites(float deltaTime); // Actualiza los sprites de polvo (time-based) void updateDustSprites(float delta_time); // Actualiza los sprites de polvo (time-based)
}; };

View File

@@ -1,9 +1,9 @@
#include "global_inputs.hpp" #include "global_inputs.hpp"
#include <algorithm> // Para std::ranges::any_of #include <algorithm> // Para __any_of_fn, any_of
#include <functional> // Para function #include <functional> // Para function
#include <memory> // Para allocator, shared_ptr #include <iterator> // Para pair
#include <string> // Para operator+, char_traits, string, to_string #include <string> // Para basic_string, operator+, allocator, char_traits, string, to_string
#include <utility> // Para pair #include <utility> // Para pair
#include <vector> // Para vector #include <vector> // Para vector

View File

@@ -1,13 +1,14 @@
#include "input.hpp" #include "input.hpp"
#include <SDL3/SDL.h> // Para SDL_GamepadButton, SDL_GetGamepadAxis, SDL_GetError, SDL_GamepadAxis, SDL_JoystickID, SDL_AddGamepadMappingsFromFile, SDL_Event, SDL_EventType, SDL_GetGamepadButton, SDL_GetKeyboardState, SDL_INIT_GAMEPAD, SDL_InitSubSystem, SDL_LogCategory, SDL_LogError, SDL_LogInfo, SDL_OpenGamepad, SDL_PollEvent, SDL_WasInit, SDL_Gamepad, SDL_Scancode #include <SDL3/SDL.h> // Para SDL_GetGamepadAxis, SDL_GamepadAxis, SDL_GamepadButton, SDL_GetError, SDL_JoystickID, SDL_AddGamepadMappingsFromFile, SDL_Event, SDL_EventType, SDL_GetGamepadButton, SDL_GetKeyboardState, SDL_INIT_GAMEPAD, SDL_InitSubSystem, SDL_LogError, SDL_OpenGamepad, SDL_PollEvent, SDL_WasInit, Sint16, SDL_Gamepad, SDL_LogCategory, SDL_Scancode
#include <algorithm> // Para find_if, remove_if #include <iostream> // Para basic_ostream, operator<<, cout, cerr
#include <iostream> // Para basic_ostream, operator<<, endl, cout, cerr
#include <memory> // Para shared_ptr, __shared_ptr_access, allocator, operator==, make_shared #include <memory> // Para shared_ptr, __shared_ptr_access, allocator, operator==, make_shared
#include <unordered_map> // Para unordered_map, operator==, _Node_iterator_base, _Node_iterator, _Node_const_iterator #include <ranges> // Para __find_if_fn, find_if
#include <unordered_map> // Para unordered_map, _Node_iterator, operator==, _Node_iterator_base, _Node_const_iterator
#include <utility> // Para pair, move #include <utility> // Para pair, move
#include "ui/logger.hpp"
#include "ui/logger.hpp" // Para info
// Singleton // Singleton
Input* Input::instance = nullptr; Input* Input::instance = nullptr;

View File

@@ -1,15 +1,16 @@
#pragma once #pragma once
#include <SDL3/SDL.h> // Para SDL_Scancode, SDL_GamepadButton, SDL_JoystickID, SDL_CloseGamepad, SDL_Gamepad, SDL_GetGamepadJoystick, SDL_GetGamepadName, SDL_GetGamepadPath, SDL_GetJoystickID, Uint8, SDL_Event, Sint16 #include <SDL3/SDL.h> // Para SDL_Scancode, SDL_GamepadButton, SDL_JoystickID, SDL_CloseGamepad, SDL_Gamepad, SDL_GetGamepadJoystick, SDL_GetGamepadName, SDL_GetGamepadPath, SDL_GetJoystickID, Sint16, Uint8, SDL_Event
#include <array> // Para array #include <array> // Para array
#include <memory> // Para shared_ptr, allocator #include <memory> // Para shared_ptr
#include <string> // Para string #include <string> // Para string, basic_string
#include <unordered_map> // Para unordered_map #include <unordered_map> // Para unordered_map
#include <utility> // Para pair
#include <vector> // Para vector #include <vector> // Para vector
#include "gamepad_config_manager.hpp" // Para GamepadConfig (ptr only), GamepadConfigs #include "gamepad_config_manager.hpp" // for GamepadConfig (ptr only), GamepadConfigs
#include "input_types.hpp" // Para InputAction #include "input_types.hpp" // for InputAction
// --- Clase Input: gestiona la entrada de teclado y mandos (singleton) --- // --- Clase Input: gestiona la entrada de teclado y mandos (singleton) ---
class Input { class Input {

View File

@@ -1,5 +1,7 @@
#include "input_types.hpp" #include "input_types.hpp"
#include <utility> // Para pair
// Definición de los mapas // Definición de los mapas
const std::unordered_map<InputAction, std::string> ACTION_TO_STRING = { const std::unordered_map<InputAction, std::string> ACTION_TO_STRING = {
{InputAction::FIRE_LEFT, "FIRE_LEFT"}, {InputAction::FIRE_LEFT, "FIRE_LEFT"},

View File

@@ -29,14 +29,14 @@ Item::Item(ItemType type, float x, float y, SDL_FRect& play_area, const std::sha
pos_x_ = x; pos_x_ = x;
pos_y_ = y; pos_y_ = y;
// 6 velocidades: 3 negativas (-1.0, -0.66, -0.33) y 3 positivas (0.33, 0.66, 1.0) // 6 velocidades: 3 negativas (-1.0, -0.66, -0.33) y 3 positivas (0.33, 0.66, 1.0)
const int direction = rand() % 6; const int DIRECTION = rand() % 6;
if (direction < 3) { if (DIRECTION < 3) {
// Velocidades negativas: -1.0, -0.66, -0.33 // Velocidades negativas: -1.0, -0.66, -0.33
vel_x_ = -ITEM_VEL_X_BASE + (direction * ITEM_VEL_X_STEP); vel_x_ = -ITEM_VEL_X_BASE + (DIRECTION * ITEM_VEL_X_STEP);
rotate_speed_ = -720.0F; rotate_speed_ = -720.0F;
} else { } else {
// Velocidades positivas: 0.33, 0.66, 1.0 // Velocidades positivas: 0.33, 0.66, 1.0
vel_x_ = ITEM_VEL_X_STEP + ((direction - 3) * ITEM_VEL_X_STEP); vel_x_ = ITEM_VEL_X_STEP + ((DIRECTION - 3) * ITEM_VEL_X_STEP);
rotate_speed_ = 720.0F; rotate_speed_ = 720.0F;
} }
vel_y_ = ITEM_VEL_Y; vel_y_ = ITEM_VEL_Y;
@@ -71,33 +71,33 @@ void Item::alignTo(int x) {
void Item::render() { void Item::render() {
if (enabled_) { if (enabled_) {
// Muestra normalmente hasta los últimos ~3.3 segundos // Muestra normalmente hasta los últimos ~3.3 segundos
constexpr float BLINK_START_S = LIFETIME_DURATION_S - 3.33f; constexpr float BLINK_START_S = LIFETIME_DURATION_S - 3.33F;
if (lifetime_timer_ < BLINK_START_S) { if (lifetime_timer_ < BLINK_START_S) {
sprite_->render(); sprite_->render();
} else { } else {
// Efecto de parpadeo en los últimos segundos (cada ~0.33 segundos) // Efecto de parpadeo en los últimos segundos (cada ~0.33 segundos)
constexpr float BLINK_INTERVAL_S = 0.33f; constexpr float BLINK_INTERVAL_S = 0.33F;
const float phase = fmod(lifetime_timer_, BLINK_INTERVAL_S); const float PHASE = std::fmod(lifetime_timer_, BLINK_INTERVAL_S);
const float half_interval = BLINK_INTERVAL_S / 2.0f; const float HALF_INTERVAL = BLINK_INTERVAL_S / 2.0F;
if (phase < half_interval) { if (PHASE < HALF_INTERVAL) {
sprite_->render(); sprite_->render();
} }
} }
} }
} }
void Item::move(float deltaTime) { void Item::move(float delta_time) {
floor_collision_ = false; floor_collision_ = false;
// Calcula la nueva posición usando deltaTime (velocidad en pixels/segundo) // Calcula la nueva posición usando deltaTime (velocidad en pixels/segundo)
pos_x_ += vel_x_ * deltaTime; pos_x_ += vel_x_ * delta_time;
pos_y_ += vel_y_ * deltaTime; pos_y_ += vel_y_ * delta_time;
// Aplica las aceleraciones a la velocidad usando deltaTime (aceleración en pixels/segundo²) // Aplica las aceleraciones a la velocidad usando deltaTime (aceleración en pixels/segundo²)
vel_x_ += accel_x_ * deltaTime; vel_x_ += accel_x_ * delta_time;
vel_y_ += accel_y_ * deltaTime; vel_y_ += accel_y_ * delta_time;
// Comprueba los laterales de la zona de juego // Comprueba los laterales de la zona de juego
const float MIN_X = param.game.play_area.rect.x; const float MIN_X = param.game.play_area.rect.x;
@@ -160,14 +160,14 @@ void Item::move(float deltaTime) {
void Item::disable() { enabled_ = false; } void Item::disable() { enabled_ = false; }
void Item::update(float deltaTime) { void Item::update(float delta_time) {
move(deltaTime); move(delta_time);
sprite_->update(deltaTime); sprite_->update(delta_time);
updateTimeToLive(deltaTime); updateTimeToLive(delta_time);
} }
void Item::updateTimeToLive(float deltaTime) { void Item::updateTimeToLive(float delta_time) {
lifetime_timer_ += deltaTime; lifetime_timer_ += delta_time;
if (lifetime_timer_ >= LIFETIME_DURATION_S) { if (lifetime_timer_ >= LIFETIME_DURATION_S) {
disable(); disable();
} }

View File

@@ -31,7 +31,7 @@ class Item {
static constexpr float HEIGHT = 20.0F; // ALtura del item static constexpr float HEIGHT = 20.0F; // ALtura del item
static constexpr int COFFEE_MACHINE_WIDTH = 30; // Anchura de la máquina de café static constexpr int COFFEE_MACHINE_WIDTH = 30; // Anchura de la máquina de café
static constexpr int COFFEE_MACHINE_HEIGHT = 39; // Altura de la máquina de café static constexpr int COFFEE_MACHINE_HEIGHT = 39; // Altura de la máquina de café
static constexpr float LIFETIME_DURATION_S = 10.0f; // Duración de vida del ítem en segundos static constexpr float LIFETIME_DURATION_S = 10.0F; // Duración de vida del ítem en segundos
// Velocidades base (pixels/segundo) - Coffee Machine // Velocidades base (pixels/segundo) - Coffee Machine
static constexpr float COFFEE_MACHINE_VEL_X_FACTOR = 30.0F; // Factor para velocidad X de máquina de café (0.5*60fps) static constexpr float COFFEE_MACHINE_VEL_X_FACTOR = 30.0F; // Factor para velocidad X de máquina de café (0.5*60fps)
@@ -55,10 +55,10 @@ class Item {
~Item() = default; // Destructor ~Item() = default; // Destructor
// --- Métodos principales --- // --- Métodos principales ---
void alignTo(int x); // Centra el objeto en la posición X indicada void alignTo(int x); // Centra el objeto en la posición X indicada
void render(); // Renderiza el objeto en pantalla void render(); // Renderiza el objeto en pantalla
void disable(); // Desactiva el objeto void disable(); // Desactiva el objeto
void update(float deltaTime); // Actualiza la posición, animación y contadores (time-based) void update(float delta_time); // Actualiza la posición, animación y contadores (time-based)
// --- Getters --- // --- Getters ---
[[nodiscard]] auto getPosX() const -> float { return pos_x_; } // Obtiene la posición X [[nodiscard]] auto getPosX() const -> float { return pos_x_; } // Obtiene la posición X
@@ -87,14 +87,14 @@ class Item {
float width_ = WIDTH; // Ancho del objeto float width_ = WIDTH; // Ancho del objeto
float height_ = HEIGHT; // Alto del objeto float height_ = HEIGHT; // Alto del objeto
float rotate_speed_ = 0.0F; // Velocidad de rotacion float rotate_speed_ = 0.0F; // Velocidad de rotacion
float lifetime_timer_ = 0.0f; // Acumulador de tiempo de vida del ítem (segundos) float lifetime_timer_ = 0.0F; // Acumulador de tiempo de vida del ítem (segundos)
bool floor_collision_ = false; // Indica si el objeto colisiona con el suelo bool floor_collision_ = false; // Indica si el objeto colisiona con el suelo
bool enabled_ = true; // Indica si el objeto está habilitado bool enabled_ = true; // Indica si el objeto está habilitado
// --- Métodos internos --- // --- Métodos internos ---
void shiftColliders(); // Alinea el círculo de colisión con la posición del objeto void shiftColliders(); // Alinea el círculo de colisión con la posición del objeto
void shiftSprite(); // Coloca el sprite en la posición del objeto void shiftSprite(); // Coloca el sprite en la posición del objeto
void move(float deltaTime); // Actualiza la posición y estados del objeto (time-based) void move(float delta_time); // Actualiza la posición y estados del objeto (time-based)
void updateTimeToLive(float deltaTime); // Actualiza el contador de tiempo de vida (time-based) void updateTimeToLive(float delta_time); // Actualiza el contador de tiempo de vida (time-based)
static auto getCoffeeMachineSpawn(int player_x, int item_width, int area_width, int margin = 2) -> int; // Calcula la zona de aparición de la máquina de café static auto getCoffeeMachineSpawn(int player_x, int item_width, int area_width, int margin = 2) -> int; // Calcula la zona de aparición de la máquina de café
}; };

View File

@@ -1,12 +1,15 @@
#include "manage_hiscore_table.hpp" #include "manage_hiscore_table.hpp"
#include <SDL3/SDL.h> // Para SDL_ReadIO, SDL_WriteIO, SDL_CloseIO, SDL_GetError, SDL_IOFromFile, SDL_LogCategory, SDL_LogError, SDL_LogInfo #include <SDL3/SDL.h> // Para SDL_ReadIO, SDL_WriteIO, SDL_CloseIO, SDL_GetError, SDL_IOFromFile, SDL_LogError, SDL_LogCategory, SDL_LogInfo
#include <algorithm> // Para find_if, sort #include <algorithm> // Para __sort_fn, sort
#include <iterator> // Para distance #include <functional> // Para identity
#include <iterator> // Para distance
#include <ranges> // Para __find_if_fn, find_if
#include <utility> // Para move
#include "utils.hpp" // Para getFileName #include "ui/logger.hpp" // Para info
#include "ui/logger.hpp" #include "utils.hpp" // Para getFileName
// Resetea la tabla a los valores por defecto // Resetea la tabla a los valores por defecto
void ManageHiScoreTable::clear() { void ManageHiScoreTable::clear() {
@@ -170,7 +173,7 @@ auto ManageHiScoreTable::saveToFile(const std::string& file_path) -> bool {
SDL_WriteIO(file, &occ_value, sizeof(int)); SDL_WriteIO(file, &occ_value, sizeof(int));
} }
//SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Writing file: %s", getFileName(file_path).c_str()); // SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Writing file: %s", getFileName(file_path).c_str());
Logger::info("Writing file: " + getFileName(file_path)); Logger::info("Writing file: " + getFileName(file_path));
SDL_CloseIO(file); SDL_CloseIO(file);
} else { } else {

View File

@@ -55,23 +55,23 @@ void MovingSprite::stop() {
} }
// Mueve el sprite (time-based) // Mueve el sprite (time-based)
void MovingSprite::move(float deltaTime) { void MovingSprite::move(float delta_time) {
// DeltaTime puro: velocidad (pixels/ms) * tiempo (ms) // DeltaTime puro: velocidad (pixels/ms) * tiempo (ms)
x_ += vx_ * deltaTime; x_ += vx_ * delta_time;
y_ += vy_ * deltaTime; y_ += vy_ * delta_time;
// Aceleración (pixels/ms²) * tiempo (ms) // Aceleración (pixels/ms²) * tiempo (ms)
vx_ += ax_ * deltaTime; vx_ += ax_ * delta_time;
vy_ += ay_ * deltaTime; vy_ += ay_ * delta_time;
pos_.x = static_cast<int>(x_); pos_.x = static_cast<int>(x_);
pos_.y = static_cast<int>(y_); pos_.y = static_cast<int>(y_);
} }
// Actualiza las variables internas del objeto (time-based) // Actualiza las variables internas del objeto (time-based)
void MovingSprite::update(float deltaTime) { void MovingSprite::update(float delta_time) {
move(deltaTime); move(delta_time);
rotate(deltaTime); rotate(delta_time);
} }
// Muestra el sprite por pantalla // Muestra el sprite por pantalla
@@ -80,9 +80,9 @@ void MovingSprite::render() {
} }
// Establece la rotacion (time-based) // Establece la rotacion (time-based)
void MovingSprite::rotate(float deltaTime) { void MovingSprite::rotate(float delta_time) {
if (rotate_.enabled) { if (rotate_.enabled) {
rotate_.angle += rotate_.amount * deltaTime; rotate_.angle += rotate_.amount * delta_time;
} }
} }

View File

@@ -2,10 +2,9 @@
#include <SDL3/SDL.h> // Para SDL_FlipMode, SDL_FPoint, SDL_FRect #include <SDL3/SDL.h> // Para SDL_FlipMode, SDL_FPoint, SDL_FRect
#include <algorithm> // Para max #include <memory> // Para shared_ptr
#include <memory> // Para shared_ptr
#include "sprite.hpp" // Para Sprite #include "sprite.hpp" // for Sprite
class Texture; class Texture;
@@ -27,10 +26,10 @@ class MovingSprite : public Sprite {
~MovingSprite() override = default; ~MovingSprite() override = default;
// --- Métodos principales --- // --- Métodos principales ---
virtual void update(float deltaTime); // Actualiza las variables internas del objeto (time-based) virtual void update(float delta_time); // Actualiza las variables internas del objeto (time-based)
void clear() override; // Reinicia todas las variables a cero void clear() override; // Reinicia todas las variables a cero
void stop(); // Elimina el movimiento del sprite void stop(); // Elimina el movimiento del sprite
void render() override; // Muestra el sprite por pantalla void render() override; // Muestra el sprite por pantalla
// --- Configuración --- // --- Configuración ---
void setPos(SDL_FRect rect); // Establece la posición y el tamaño del objeto void setPos(SDL_FRect rect); // Establece la posición y el tamaño del objeto
@@ -79,6 +78,6 @@ class MovingSprite : public Sprite {
// --- Métodos internos --- // --- Métodos internos ---
void updateAngle() { rotate_.angle += rotate_.amount; } // Incrementa el valor del ángulo void updateAngle() { rotate_.angle += rotate_.amount; } // Incrementa el valor del ángulo
void move(float deltaTime); // Mueve el sprite según velocidad y aceleración (time-based) void move(float delta_time); // Mueve el sprite según velocidad y aceleración (time-based)
void rotate(float deltaTime); // Rota el sprite según los parámetros de rotación (time-based) void rotate(float delta_time); // Rota el sprite según los parámetros de rotación (time-based)
}; };

View File

@@ -1,24 +1,23 @@
#include "options.hpp" #include "options.hpp"
#include <SDL3/SDL.h> // Para SDL_ScaleMode, SDL_GamepadButton, SDL_LogCategory, SDL_LogInfo, SDL_LogError, SDL_LogWarn #include <SDL3/SDL.h> // Para SDL_ScaleMode, SDL_LogCategory, SDL_LogError, SDL_LogInfo, SDL_LogWarn
#include <algorithm> // Para clamp, max #include <algorithm> // Para clamp, __any_of_fn, any_of
#include <cstddef> // Para size_t #include <cstddef> // Para size_t
#include <fstream> // Para basic_ostream, operator<<, basic_ostream::operator<<, basic_ofstream, basic_istream, basic_ifstream, ifstream, ofstream #include <fstream> // Para basic_ostream, operator<<, basic_ofstream, basic_ostream::operator<<, basic_istream, basic_ifstream, ifstream, istringstream, ofstream
#include <functional> // Para function #include <functional> // Para function
#include <map> // Para map, operator==, _Rb_tree_const_iterator #include <map> // Para map, operator==, _Rb_tree_const_iterator
#include <ranges> // Para std::ranges::any_of #include <sstream> // Para basic_istringstream
#include <sstream> // Para istringstream
#include <stdexcept> // Para invalid_argument, out_of_range #include <stdexcept> // Para invalid_argument, out_of_range
#include <string> // Para char_traits, stoi, operator==, operator<<, allocator, string, basic_string, operator<=>, getline #include <string> // Para char_traits, basic_string, stoi, string, operator<<, operator+, operator==, operator>>, getline, operator<=>, to_string
#include <utility> // Para swap, pair #include <utility> // Para pair
#include <vector> // Para vector #include <vector> // Para vector
#include "difficulty.hpp" // Para Code, init #include "difficulty.hpp" // Para Code, init
#include "input.hpp" // Para InputDevice #include "input.hpp" // Para Input
#include "lang.hpp" // Para Code #include "lang.hpp" // Para getText, Code
#include "ui/logger.hpp" // Para Logger #include "ui/logger.hpp" // Para info
#include "utils.hpp" // Para boolToString, stringToBool, getFileName #include "utils.hpp" // Para stringToBool, boolToString, getFileName
namespace Options { namespace Options {
// --- Variables globales --- // --- Variables globales ---
@@ -116,7 +115,7 @@ auto saveToFile() -> bool {
return false; return false;
} }
//SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Writing file: %s", getFileName(settings.config_file).c_str()); // SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Writing file: %s", getFileName(settings.config_file).c_str());
Logger::info("Writing file: " + getFileName(settings.config_file)); Logger::info("Writing file: " + getFileName(settings.config_file));
applyPendingChanges(); applyPendingChanges();

View File

@@ -2,24 +2,23 @@
#include <SDL3/SDL.h> // Para SDL_ScaleMode #include <SDL3/SDL.h> // Para SDL_ScaleMode
#include <algorithm> // Para copy
#include <array> // Para array #include <array> // Para array
#include <cstddef> // Para size_t #include <cstddef> // Para size_t
#include <exception> // Para exception #include <exception> // Para exception
#include <fstream> // Para basic_ostream, operator<<, basic_ofstream, basic_ostream::operator<<, ofstream #include <fstream> // Para basic_ostream, operator<<, basic_ofstream, basic_ostream::operator<<, ofstream
#include <memory> // Para shared_ptr, swap #include <memory> // Para shared_ptr, __shared_ptr_access, swap
#include <stdexcept> // Para out_of_range, invalid_argument #include <stdexcept> // Para out_of_range, invalid_argument
#include <string> // Para char_traits, string, allocator, operator==, swap, operator<<, basic_string, stoi #include <string> // Para char_traits, basic_string, string, operator==, operator<<, swap, stoi
#include <string_view> // Para string_view #include <string_view> // Para string_view
#include <utility> // Para swap #include <utility> // Para move
#include <vector> // Para vector #include <vector> // Para vector
#include "defaults.hpp" // Para GameDefaults #include "defaults.hpp" // for AUDIO_ENABLED, AUDIO_VOLUME, MUSIC_ENABLED, MUSIC_VOLUME, PARAMS_FILE, SETTINGS_AUTOFIRE, SETTINGS_SHUTDOWN_ENABLED, SOUND_ENABLED, SOUND_VOLUME, VIDEO_FULLSCREEN, VIDEO_INTEGER_SCALE, VIDEO_SCALE_MODE, VIDEO_SHADERS, VIDEO_VSYNC, WINDOW_CAPTION, WINDOW_MAX_ZOOM, WINDOW_ZOOM
#include "difficulty.hpp" // Para Code #include "difficulty.hpp" // for Code
#include "input.hpp" // Para Input #include "input.hpp" // for Input
#include "lang.hpp" // Para Code #include "lang.hpp" // for Code
#include "manage_hiscore_table.hpp" // Para ManageHiScoreTable, Table #include "manage_hiscore_table.hpp" // for ManageHiScoreTable, Table
#include "player.hpp" // Para Player #include "player.hpp" // for Player
// --- Namespace Options: gestión de configuración y opciones del juego --- // --- Namespace Options: gestión de configuración y opciones del juego ---
namespace Options { namespace Options {

View File

@@ -1,18 +1,19 @@
#include "param.hpp" #include "param.hpp"
#include <SDL3/SDL.h> // Para SDL_LogCategory, SDL_LogError, SDL_LogInfo #include <SDL3/SDL.h> // Para SDL_LogWarn, SDL_LogCategory, SDL_LogError
#include <fstream> // Para basic_istream, basic_ifstream, ifstream #include <fstream> // Para basic_istream, basic_ifstream, ifstream, istringstream
#include <functional> #include <functional> // Para function
#include <sstream> // Para basic_istringstream #include <sstream> // Para basic_istringstream
#include <stdexcept> // Para runtime_error #include <stdexcept> // Para runtime_error
#include <string> // Para operator==, stoi, char_traits, string, ope... #include <string> // Para string, basic_string, stoi, stof, hash, allocator, operator==, char_traits, operator+, operator>>, getline
#include <unordered_map> #include <unordered_map> // Para unordered_map, operator==, _Node_iterator_base
#include <utility> // Para pair
#include "color.hpp" #include "color.hpp" // Para Color
#include "ui/notifier.hpp" // Para Notifier::Position #include "ui/logger.hpp" // Para info, YELLOW
#include "utils.hpp" #include "ui/notifier.hpp" // Para Notifier
#include "ui/logger.hpp" // Para Logger #include "utils.hpp" // Para Zone, stringToBool, getFileName
// Variable global - ahora se inicializa automáticamente con valores por defecto // Variable global - ahora se inicializa automáticamente con valores por defecto
Param param; Param param;
@@ -53,7 +54,7 @@ void loadParamsFromFile(const std::string& file_path) {
throw std::runtime_error("No se pudo abrir el archivo: " + file_path); throw std::runtime_error("No se pudo abrir el archivo: " + file_path);
} }
//SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "\nReading file: %s", getFileName(file_path).c_str()); // SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "\nReading file: %s", getFileName(file_path).c_str());
Logger::info("Reading file: " + getFileName(file_path)); Logger::info("Reading file: " + getFileName(file_path));
std::string line; std::string line;
@@ -202,37 +203,37 @@ auto setParams(const std::string& var, const std::string& value) -> bool {
{"red", true}, {"red", true},
{"green", true}}; {"green", true}};
auto validateBalloonColor = [](const std::string& color) -> bool { auto validate_balloon_color = [](const std::string& color) -> bool {
return VALID_BALLOON_COLORS.find(color) != VALID_BALLOON_COLORS.end(); return VALID_BALLOON_COLORS.find(color) != VALID_BALLOON_COLORS.end();
}; };
static const std::unordered_map<std::string, std::function<void(const std::string&)>> STRING_PARAMS = { static const std::unordered_map<std::string, std::function<void(const std::string&)>> STRING_PARAMS = {
{"balloon.color[0]", [validateBalloonColor](const std::string& v) { {"balloon.color[0]", [validate_balloon_color](const std::string& v) {
if (!validateBalloonColor(v)) { if (!validate_balloon_color(v)) {
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "Color de globo inválido '%s'. Usando 'blue' por defecto.", v.c_str()); SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "Color de globo inválido '%s'. Usando 'blue' por defecto.", v.c_str());
param.balloon.color.at(0) = "blue"; param.balloon.color.at(0) = "blue";
} else { } else {
param.balloon.color.at(0) = v; param.balloon.color.at(0) = v;
} }
}}, }},
{"balloon.color[1]", [validateBalloonColor](const std::string& v) { {"balloon.color[1]", [validate_balloon_color](const std::string& v) {
if (!validateBalloonColor(v)) { if (!validate_balloon_color(v)) {
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "Color de globo inválido '%s'. Usando 'orange' por defecto.", v.c_str()); SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "Color de globo inválido '%s'. Usando 'orange' por defecto.", v.c_str());
param.balloon.color.at(1) = "orange"; param.balloon.color.at(1) = "orange";
} else { } else {
param.balloon.color.at(1) = v; param.balloon.color.at(1) = v;
} }
}}, }},
{"balloon.color[2]", [validateBalloonColor](const std::string& v) { {"balloon.color[2]", [validate_balloon_color](const std::string& v) {
if (!validateBalloonColor(v)) { if (!validate_balloon_color(v)) {
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "Color de globo inválido '%s'. Usando 'red' por defecto.", v.c_str()); SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "Color de globo inválido '%s'. Usando 'red' por defecto.", v.c_str());
param.balloon.color.at(2) = "red"; param.balloon.color.at(2) = "red";
} else { } else {
param.balloon.color.at(2) = v; param.balloon.color.at(2) = v;
} }
}}, }},
{"balloon.color[3]", [validateBalloonColor](const std::string& v) { {"balloon.color[3]", [validate_balloon_color](const std::string& v) {
if (!validateBalloonColor(v)) { if (!validate_balloon_color(v)) {
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "Color de globo inválido '%s'. Usando 'green' por defecto.", v.c_str()); SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "Color de globo inválido '%s'. Usando 'green' por defecto.", v.c_str());
param.balloon.color.at(3) = "green"; param.balloon.color.at(3) = "green";
} else { } else {

View File

@@ -1,6 +1,7 @@
// IWYU pragma: no_include <bits/std_abs.h> // IWYU pragma: no_include <bits/std_abs.h>
#include "path_sprite.hpp" #include "path_sprite.hpp"
#include <cmath> // Para abs
#include <functional> // Para function #include <functional> // Para function
#include <utility> // Para move #include <utility> // Para move
@@ -75,32 +76,32 @@ void PathSprite::addPath(Path path, bool centered) {
switch (path_centered) { switch (path_centered) {
case PathCentered::ON_X: { case PathCentered::ON_X: {
// Centrar en el eje X (para paths Verticales) // Centrar en el eje X (para paths Verticales)
const float X_offset = pos_.w / 2.0f; // Asume que pos_.w está inicializado por el constructor de Sprite const float X_OFFSET = pos_.w / 2.0F; // Asume que pos_.w está inicializado por el constructor de Sprite
if (path.is_point_path) { if (path.is_point_path) {
const float X_base = !path.spots.empty() ? path.spots.front().x : 0.0f; const float X_BASE = !path.spots.empty() ? path.spots.front().x : 0.0F;
const float X = X_base - X_offset; const float X = X_BASE - X_OFFSET;
for (auto& spot : path.spots) { for (auto& spot : path.spots) {
spot.x = X; spot.x = X;
} }
} else { } else {
// Es un path generado, ajustamos la posición fija (que es X) // Es un path generado, ajustamos la posición fija (que es X)
path.fixed_pos -= X_offset; path.fixed_pos -= X_OFFSET;
} }
paths_.emplace_back(std::move(path)); // Usamos std::move paths_.emplace_back(std::move(path)); // Usamos std::move
break; break;
} }
case PathCentered::ON_Y: { case PathCentered::ON_Y: {
// Centrar en el eje Y (para paths Horizontales) // Centrar en el eje Y (para paths Horizontales)
const float Y_offset = pos_.h / 2.0f; // Asume que pos_.h está inicializado const float Y_OFFSET = pos_.h / 2.0F; // Asume que pos_.h está inicializado
if (path.is_point_path) { if (path.is_point_path) {
const float Y_base = !path.spots.empty() ? path.spots.front().y : 0.0f; const float Y_BASE = !path.spots.empty() ? path.spots.front().y : 0.0F;
const float Y = Y_base - Y_offset; const float Y = Y_BASE - Y_OFFSET;
for (auto& spot : path.spots) { for (auto& spot : path.spots) {
spot.y = Y; spot.y = Y;
} }
} else { } else {
// Es un path generado, ajustamos la posición fija (que es Y) // Es un path generado, ajustamos la posición fija (que es Y)
path.fixed_pos -= Y_offset; path.fixed_pos -= Y_OFFSET;
} }
paths_.emplace_back(std::move(path)); // Usamos std::move paths_.emplace_back(std::move(path)); // Usamos std::move
break; break;
@@ -139,9 +140,9 @@ void PathSprite::enable() {
// Para paths generados, establecer posición inicial // Para paths generados, establecer posición inicial
SDL_FPoint initial_pos; SDL_FPoint initial_pos;
if (path.type == PathType::HORIZONTAL) { if (path.type == PathType::HORIZONTAL) {
initial_pos = {path.start_pos, path.fixed_pos}; initial_pos = {.x = path.start_pos, .y = path.fixed_pos};
} else { } else {
initial_pos = {path.fixed_pos, path.start_pos}; initial_pos = {.x = path.fixed_pos, .y = path.start_pos};
} }
setPosition(initial_pos); setPosition(initial_pos);
} }
@@ -177,8 +178,8 @@ void PathSprite::moveThroughCurrentPath(float delta_time) {
// Calcular progreso (0.0 a 1.0) // Calcular progreso (0.0 a 1.0)
float progress = path.elapsed_time / path.duration_s; float progress = path.elapsed_time / path.duration_s;
if (progress >= 1.0f) { if (progress >= 1.0F) {
progress = 1.0f; progress = 1.0F;
path.on_destination = true; path.on_destination = true;
} }
@@ -186,14 +187,14 @@ void PathSprite::moveThroughCurrentPath(float delta_time) {
double eased_progress = path.easing_function(progress); double eased_progress = path.easing_function(progress);
// Calcular posición actual // Calcular posición actual
float current_pos = path.start_pos + (path.end_pos - path.start_pos) * static_cast<float>(eased_progress); float current_pos = path.start_pos + ((path.end_pos - path.start_pos) * static_cast<float>(eased_progress));
// Establecer posición según el tipo // Establecer posición según el tipo
SDL_FPoint position; SDL_FPoint position;
if (path.type == PathType::HORIZONTAL) { if (path.type == PathType::HORIZONTAL) {
position = {current_pos, path.fixed_pos}; position = {.x = current_pos, .y = path.fixed_pos};
} else { } else {
position = {path.fixed_pos, current_pos}; position = {.x = path.fixed_pos, .y = current_pos};
} }
setPosition(position); setPosition(position);
} else { } else {

View File

@@ -32,8 +32,8 @@ struct Path { // Define un recorrido p
float duration_s; // Duración de la animación en segundos float duration_s; // Duración de la animación en segundos
float waiting_time_s; // Tiempo de espera una vez en el destino float waiting_time_s; // Tiempo de espera una vez en el destino
std::function<double(double)> easing_function; // Función de easing std::function<double(double)> easing_function; // Función de easing
float elapsed_time = 0.0f; // Tiempo transcurrido float elapsed_time = 0.0F; // Tiempo transcurrido
float waiting_elapsed = 0.0f; // Tiempo de espera transcurrido float waiting_elapsed = 0.0F; // Tiempo de espera transcurrido
bool on_destination = false; // Indica si ha llegado al destino bool on_destination = false; // Indica si ha llegado al destino
bool finished = false; // Indica si ha terminado de esperarse bool finished = false; // Indica si ha terminado de esperarse
@@ -73,8 +73,8 @@ class PathSprite : public Sprite {
// --- Gestión de recorridos --- // --- Gestión de recorridos ---
void addPath(Path path, bool centered = false); // Añade un recorrido (Path) void addPath(Path path, bool centered = false); // Añade un recorrido (Path)
void addPath(const std::vector<SDL_FPoint>& spots, float waiting_time_s = 0.0f); // Añade un recorrido a partir de puntos void addPath(const std::vector<SDL_FPoint>& spots, float waiting_time_s = 0.0F); // Añade un recorrido a partir de puntos
void addPath(float start, float end, PathType type, float fixed_pos, float duration_s, const std::function<double(double)>& easing_function, float waiting_time_s = 0.0f); // Añade un recorrido generado void addPath(float start, float end, PathType type, float fixed_pos, float duration_s, const std::function<double(double)>& easing_function, float waiting_time_s = 0.0F); // Añade un recorrido generado
// --- Estado y control --- // --- Estado y control ---
void enable(); // Habilita el objeto void enable(); // Habilita el objeto

View File

@@ -1,6 +1,6 @@
#include "player.hpp" #include "player.hpp"
#include <SDL3/SDL.h> // Para SDL_GetTicks, SDL_FlipMode #include <SDL3/SDL.h> // Para SDL_FlipMode
#include <algorithm> // Para clamp, max, min #include <algorithm> // Para clamp, max, min
#include <cmath> // Para fmod #include <cmath> // Para fmod
@@ -14,12 +14,8 @@
#include "manage_hiscore_table.hpp" // Para ManageHiScoreTable, HiScoreEntry #include "manage_hiscore_table.hpp" // Para ManageHiScoreTable, HiScoreEntry
#include "param.hpp" // Para Param, ParamGame, param #include "param.hpp" // Para Param, ParamGame, param
#include "scoreboard.hpp" // Para Scoreboard #include "scoreboard.hpp" // Para Scoreboard
#include "stage.hpp" // Para power_can_be_added
#include "stage_interface.hpp" // Para IStageInfo #include "stage_interface.hpp" // Para IStageInfo
#include "texture.hpp" // Para Texture #include "texture.hpp" // Para Texture
#ifdef _DEBUG
#include <iostream>
#endif
// Constructor // Constructor
Player::Player(const Config& config) Player::Player(const Config& config)
@@ -61,8 +57,8 @@ void Player::init() {
extra_hit_ = false; extra_hit_ = false;
coffees_ = 0; coffees_ = 0;
continue_counter_ = 10; continue_counter_ = 10;
name_entry_idle_time_accumulator_ = 0.0f; name_entry_idle_time_accumulator_ = 0.0F;
name_entry_total_time_accumulator_ = 0.0f; name_entry_total_time_accumulator_ = 0.0F;
shiftColliders(); shiftColliders();
vel_x_ = 0; vel_x_ = 0;
vel_y_ = 0; vel_y_ = 0;
@@ -146,37 +142,37 @@ void Player::setInputEnteringName(Input::Action action) {
default: default:
break; break;
} }
name_entry_idle_time_accumulator_ = 0.0f; name_entry_idle_time_accumulator_ = 0.0F;
} }
// Sistema de movimiento // Sistema de movimiento
void Player::move(float deltaTime) { void Player::move(float delta_time) {
switch (playing_state_) { switch (playing_state_) {
case State::PLAYING: case State::PLAYING:
handlePlayingMovement(deltaTime); handlePlayingMovement(delta_time);
break; break;
case State::ROLLING: case State::ROLLING:
handleRollingMovement(); handleRollingMovement();
break; break;
case State::TITLE_ANIMATION: case State::TITLE_ANIMATION:
handleTitleAnimation(deltaTime); handleTitleAnimation(delta_time);
break; break;
case State::CONTINUE_TIME_OUT: case State::CONTINUE_TIME_OUT:
handleContinueTimeOut(); handleContinueTimeOut();
break; break;
case State::LEAVING_SCREEN: case State::LEAVING_SCREEN:
updateStepCounter(deltaTime); updateStepCounter(delta_time);
handleLeavingScreen(deltaTime); handleLeavingScreen(delta_time);
break; break;
case State::ENTERING_SCREEN: case State::ENTERING_SCREEN:
updateStepCounter(deltaTime); updateStepCounter(delta_time);
handleEnteringScreen(deltaTime); handleEnteringScreen(delta_time);
break; break;
case State::CREDITS: case State::CREDITS:
handleCreditsMovement(deltaTime); handleCreditsMovement(delta_time);
break; break;
case State::WAITING: case State::WAITING:
handleWaitingMovement(deltaTime); handleWaitingMovement(delta_time);
break; break;
case State::RECOVER: case State::RECOVER:
handleRecoverMovement(); handleRecoverMovement();
@@ -187,9 +183,9 @@ void Player::move(float deltaTime) {
} }
// Movimiento time-based durante el juego // Movimiento time-based durante el juego
void Player::handlePlayingMovement(float deltaTime) { void Player::handlePlayingMovement(float delta_time) {
// Mueve el jugador a derecha o izquierda (time-based en segundos) // Mueve el jugador a derecha o izquierda (time-based en segundos)
pos_x_ += vel_x_ * deltaTime; pos_x_ += vel_x_ * delta_time;
// Si el jugador abandona el area de juego por los laterales, restaura su posición // Si el jugador abandona el area de juego por los laterales, restaura su posición
const float MIN_X = play_area_.x - 5; const float MIN_X = play_area_.x - 5;
@@ -253,10 +249,10 @@ void Player::handleRollingBounce() {
playSound("jump.wav"); playSound("jump.wav");
} }
void Player::handleTitleAnimation(float deltaTime) { void Player::handleTitleAnimation(float delta_time) {
setInputBasedOnPlayerId(); setInputBasedOnPlayerId();
pos_x_ += (vel_x_ * 2.0F) * deltaTime; pos_x_ += (vel_x_ * 2.0F) * delta_time;
const float MIN_X = -WIDTH; const float MIN_X = -WIDTH;
const float MAX_X = play_area_.w; const float MAX_X = play_area_.w;
pos_x_ = std::clamp(pos_x_, MIN_X, MAX_X); pos_x_ = std::clamp(pos_x_, MIN_X, MAX_X);
@@ -275,11 +271,11 @@ void Player::handleContinueTimeOut() {
} }
} }
void Player::handleLeavingScreen(float deltaTime) { void Player::handleLeavingScreen(float delta_time) {
// updateStepCounter se llama desde move() con deltaTime // updateStepCounter se llama desde move() con deltaTime
setInputBasedOnPlayerId(); setInputBasedOnPlayerId();
pos_x_ += vel_x_ * deltaTime; pos_x_ += vel_x_ * delta_time;
const float MIN_X = -WIDTH; const float MIN_X = -WIDTH;
const float MAX_X = play_area_.w; const float MAX_X = play_area_.w;
pos_x_ = std::clamp(pos_x_, MIN_X, MAX_X); pos_x_ = std::clamp(pos_x_, MIN_X, MAX_X);
@@ -290,15 +286,15 @@ void Player::handleLeavingScreen(float deltaTime) {
} }
} }
void Player::handleEnteringScreen(float deltaTime) { void Player::handleEnteringScreen(float delta_time) {
// updateStepCounter se llama desde move() con deltaTime // updateStepCounter se llama desde move() con deltaTime
switch (id_) { switch (id_) {
case Id::PLAYER1: case Id::PLAYER1:
handlePlayer1Entering(deltaTime); handlePlayer1Entering(delta_time);
break; break;
case Id::PLAYER2: case Id::PLAYER2:
handlePlayer2Entering(deltaTime); handlePlayer2Entering(delta_time);
break; break;
default: default:
break; break;
@@ -307,18 +303,18 @@ void Player::handleEnteringScreen(float deltaTime) {
shiftSprite(); shiftSprite();
} }
void Player::handlePlayer1Entering(float deltaTime) { void Player::handlePlayer1Entering(float delta_time) {
setInputPlaying(Input::Action::RIGHT); setInputPlaying(Input::Action::RIGHT);
pos_x_ += vel_x_ * deltaTime; pos_x_ += vel_x_ * delta_time;
if (pos_x_ > default_pos_x_) { if (pos_x_ > default_pos_x_) {
pos_x_ = default_pos_x_; pos_x_ = default_pos_x_;
setPlayingState(State::PLAYING); setPlayingState(State::PLAYING);
} }
} }
void Player::handlePlayer2Entering(float deltaTime) { void Player::handlePlayer2Entering(float delta_time) {
setInputPlaying(Input::Action::LEFT); setInputPlaying(Input::Action::LEFT);
pos_x_ += vel_x_ * deltaTime; pos_x_ += vel_x_ * delta_time;
if (pos_x_ < default_pos_x_) { if (pos_x_ < default_pos_x_) {
pos_x_ = default_pos_x_; pos_x_ = default_pos_x_;
setPlayingState(State::PLAYING); setPlayingState(State::PLAYING);
@@ -326,8 +322,8 @@ void Player::handlePlayer2Entering(float deltaTime) {
} }
// Movimiento general en la pantalla de créditos (time-based) // Movimiento general en la pantalla de créditos (time-based)
void Player::handleCreditsMovement(float deltaTime) { void Player::handleCreditsMovement(float delta_time) {
pos_x_ += (vel_x_ / 2.0F) * deltaTime; pos_x_ += (vel_x_ / 2.0F) * delta_time;
if (vel_x_ > 0) { if (vel_x_ > 0) {
handleCreditsRightMovement(); handleCreditsRightMovement();
@@ -354,11 +350,11 @@ void Player::handleCreditsLeftMovement() {
} }
// Controla la animación del jugador saludando (time-based) // Controla la animación del jugador saludando (time-based)
void Player::handleWaitingMovement(float deltaTime) { void Player::handleWaitingMovement(float delta_time) {
waiting_time_accumulator_ += deltaTime; waiting_time_accumulator_ += delta_time;
const float WAITING_DURATION_S = static_cast<float>(WAITING_COUNTER) / 60.0f; // Convert frames to seconds const float WAITING_DURATION_S = static_cast<float>(WAITING_COUNTER) / 60.0F; // Convert frames to seconds
if (waiting_time_accumulator_ >= WAITING_DURATION_S) { if (waiting_time_accumulator_ >= WAITING_DURATION_S) {
waiting_time_accumulator_ = 0.0f; waiting_time_accumulator_ = 0.0F;
player_sprite_->resetAnimation(); player_sprite_->resetAnimation();
} }
} }
@@ -385,11 +381,11 @@ void Player::setInputBasedOnPlayerId() {
} }
// Incrementa o ajusta el contador de pasos (time-based) // Incrementa o ajusta el contador de pasos (time-based)
void Player::updateStepCounter(float deltaTime) { void Player::updateStepCounter(float delta_time) {
step_time_accumulator_ += deltaTime; step_time_accumulator_ += delta_time;
const float STEP_INTERVAL_S = 10.0f / 60.0f; // 10 frames converted to seconds const float STEP_INTERVAL_S = 10.0F / 60.0F; // 10 frames converted to seconds
if (step_time_accumulator_ >= STEP_INTERVAL_S) { if (step_time_accumulator_ >= STEP_INTERVAL_S) {
step_time_accumulator_ = 0.0f; step_time_accumulator_ = 0.0F;
playSound("walk.wav"); playSound("walk.wav");
} }
} }
@@ -460,7 +456,7 @@ auto Player::computeAnimation() const -> std::pair<std::string, SDL_FlipMode> {
} }
// Establece la animación correspondiente al estado // Establece la animación correspondiente al estado
void Player::setAnimation(float deltaTime) { void Player::setAnimation(float delta_time) {
switch (playing_state_) { switch (playing_state_) {
case State::PLAYING: case State::PLAYING:
case State::ENTERING_SCREEN: case State::ENTERING_SCREEN:
@@ -497,22 +493,22 @@ void Player::setAnimation(float deltaTime) {
} }
// La diferencia clave: usa deltaTime para las animaciones // La diferencia clave: usa deltaTime para las animaciones
player_sprite_->update(deltaTime); player_sprite_->update(delta_time);
power_sprite_->update(deltaTime); power_sprite_->update(delta_time);
} }
// Actualiza al jugador con deltaTime (time-based) // Actualiza al jugador con deltaTime (time-based)
void Player::update(float deltaTime) { void Player::update(float delta_time) {
move(deltaTime); // Sistema de movimiento time-based move(delta_time); // Sistema de movimiento time-based
setAnimation(deltaTime); // Animaciones time-based setAnimation(delta_time); // Animaciones time-based
shiftColliders(); // Sin cambios (posicional) shiftColliders(); // Sin cambios (posicional)
updateFireSystem(deltaTime); // Sistema de disparo de dos líneas updateFireSystem(delta_time); // Sistema de disparo de dos líneas
updatePowerUp(deltaTime); // Sistema de power-up time-based updatePowerUp(delta_time); // Sistema de power-up time-based
updateInvulnerable(deltaTime); // Sistema de invulnerabilidad time-based updateInvulnerable(delta_time); // Sistema de invulnerabilidad time-based
updateScoreboard(); // Sin cambios (no temporal) updateScoreboard(); // Sin cambios (no temporal)
updateContinueCounter(deltaTime); // Sistema de continue time-based updateContinueCounter(delta_time); // Sistema de continue time-based
updateEnterNameCounter(deltaTime); // Sistema de name entry time-based updateEnterNameCounter(delta_time); // Sistema de name entry time-based
updateShowingName(deltaTime); // Sistema de showing name time-based updateShowingName(delta_time); // Sistema de showing name time-based
} }
void Player::passShowingName() { void Player::passShowingName() {
@@ -584,7 +580,7 @@ void Player::setPlayingState(State state) {
case State::CONTINUE: { case State::CONTINUE: {
// Inicializa el contador de continuar // Inicializa el contador de continuar
continue_counter_ = 9; continue_counter_ = 9;
continue_time_accumulator_ = 0.0f; // Initialize time accumulator continue_time_accumulator_ = 0.0F; // Initialize time accumulator
playSound("continue_clock.wav"); playSound("continue_clock.wav");
setScoreboardMode(Scoreboard::Mode::CONTINUE); setScoreboardMode(Scoreboard::Mode::CONTINUE);
break; break;
@@ -603,7 +599,7 @@ void Player::setPlayingState(State state) {
} }
pos_y_ = default_pos_y_; pos_y_ = default_pos_y_;
waiting_counter_ = 0; waiting_counter_ = 0;
waiting_time_accumulator_ = 0.0f; // Initialize time accumulator waiting_time_accumulator_ = 0.0F; // Initialize time accumulator
shiftSprite(); shiftSprite();
player_sprite_->setCurrentAnimation("hello"); player_sprite_->setCurrentAnimation("hello");
player_sprite_->animtionPause(); player_sprite_->animtionPause();
@@ -615,7 +611,7 @@ void Player::setPlayingState(State state) {
break; break;
} }
case State::SHOWING_NAME: { case State::SHOWING_NAME: {
showing_name_time_accumulator_ = 0.0f; // Inicializar acumulador time-based showing_name_time_accumulator_ = 0.0F; // Inicializar acumulador time-based
setScoreboardMode(Scoreboard::Mode::ENTER_TO_SHOW_NAME); // Iniciar animación de transición setScoreboardMode(Scoreboard::Mode::ENTER_TO_SHOW_NAME); // Iniciar animación de transición
Scoreboard::get()->setEnterName(scoreboard_panel_, last_enter_name_); Scoreboard::get()->setEnterName(scoreboard_panel_, last_enter_name_);
addScoreToScoreBoard(); addScoreToScoreBoard();
@@ -624,7 +620,7 @@ void Player::setPlayingState(State state) {
case State::ROLLING: { case State::ROLLING: {
// Activa la animación de rodar dando botes // Activa la animación de rodar dando botes
player_sprite_->setCurrentAnimation("rolling"); player_sprite_->setCurrentAnimation("rolling");
player_sprite_->setAnimationSpeed(4.0f / 60.0f); // 4 frames convertido a segundos player_sprite_->setAnimationSpeed(4.0F / 60.0F); // 4 frames convertido a segundos
player_sprite_->setVelY(-396.0F); // Velocidad inicial (6.6 * 60 = 396 pixels/s) player_sprite_->setVelY(-396.0F); // Velocidad inicial (6.6 * 60 = 396 pixels/s)
player_sprite_->setAccelY(720.0F); // Gravedad (0.2 * 60² = 720 pixels/s²) player_sprite_->setAccelY(720.0F); // Gravedad (0.2 * 60² = 720 pixels/s²)
player_sprite_->setPosY(pos_y_ - 2); // Para "sacarlo" del suelo, ya que está hundido un pixel para ocultar el outline de los pies player_sprite_->setPosY(pos_y_ - 2); // Para "sacarlo" del suelo, ya que está hundido un pixel para ocultar el outline de los pies
@@ -648,7 +644,7 @@ void Player::setPlayingState(State state) {
player_sprite_->setVelY(-240.0F); // -4.0 * 60 = -240 pixels/s player_sprite_->setVelY(-240.0F); // -4.0 * 60 = -240 pixels/s
player_sprite_->setVelX(0.0F); player_sprite_->setVelX(0.0F);
player_sprite_->setCurrentAnimation("rolling"); player_sprite_->setCurrentAnimation("rolling");
player_sprite_->setAnimationSpeed(5.0f / 60.0f); // 5 frames convertido a segundos player_sprite_->setAnimationSpeed(5.0F / 60.0F); // 5 frames convertido a segundos
setScoreboardMode(Scoreboard::Mode::GAME_OVER); setScoreboardMode(Scoreboard::Mode::GAME_OVER);
playSound("voice_aw_aw_aw.wav"); playSound("voice_aw_aw_aw.wav");
playSound("jump.wav"); playSound("jump.wav");
@@ -671,14 +667,14 @@ void Player::setPlayingState(State state) {
} }
case State::LEAVING_SCREEN: { case State::LEAVING_SCREEN: {
step_counter_ = 0; step_counter_ = 0;
step_time_accumulator_ = 0.0f; // Initialize time accumulator step_time_accumulator_ = 0.0F; // Initialize time accumulator
setScoreboardMode(Scoreboard::Mode::GAME_COMPLETED); setScoreboardMode(Scoreboard::Mode::GAME_COMPLETED);
break; break;
} }
case State::ENTERING_SCREEN: { case State::ENTERING_SCREEN: {
init(); init();
step_counter_ = 0; step_counter_ = 0;
step_time_accumulator_ = 0.0f; // Initialize time accumulator step_time_accumulator_ = 0.0F; // Initialize time accumulator
setScoreboardMode(Scoreboard::Mode::SCORE); setScoreboardMode(Scoreboard::Mode::SCORE);
switch (id_) { switch (id_) {
case Id::PLAYER1: case Id::PLAYER1:
@@ -719,25 +715,25 @@ void Player::decScoreMultiplier() {
void Player::setInvulnerable(bool value) { void Player::setInvulnerable(bool value) {
invulnerable_ = value; invulnerable_ = value;
invulnerable_counter_ = invulnerable_ ? INVULNERABLE_COUNTER : 0; invulnerable_counter_ = invulnerable_ ? INVULNERABLE_COUNTER : 0;
invulnerable_time_accumulator_ = invulnerable_ ? static_cast<float>(INVULNERABLE_COUNTER) / 60.0f : 0.0f; // Convert frames to seconds invulnerable_time_accumulator_ = invulnerable_ ? static_cast<float>(INVULNERABLE_COUNTER) / 60.0F : 0.0F; // Convert frames to seconds
} }
// Monitoriza el estado (time-based) // Monitoriza el estado (time-based)
void Player::updateInvulnerable(float deltaTime) { void Player::updateInvulnerable(float delta_time) {
if (playing_state_ == State::PLAYING && invulnerable_) { if (playing_state_ == State::PLAYING && invulnerable_) {
if (invulnerable_time_accumulator_ > 0) { if (invulnerable_time_accumulator_ > 0) {
invulnerable_time_accumulator_ -= deltaTime; invulnerable_time_accumulator_ -= delta_time;
// Frecuencia fija de parpadeo adaptada a deltaTime (en segundos) // Frecuencia fija de parpadeo adaptada a deltaTime (en segundos)
constexpr float BLINK_PERIOD_S = 8.0f / 60.0f; // 8 frames convertidos a segundos constexpr float BLINK_PERIOD_S = 8.0F / 60.0F; // 8 frames convertidos a segundos
// Calcula proporción decreciente basada en tiempo restante // Calcula proporción decreciente basada en tiempo restante
const float TOTAL_INVULNERABLE_TIME_S = static_cast<float>(INVULNERABLE_COUNTER) / 60.0f; const float TOTAL_INVULNERABLE_TIME_S = static_cast<float>(INVULNERABLE_COUNTER) / 60.0F;
float progress = 1.0f - (invulnerable_time_accumulator_ / TOTAL_INVULNERABLE_TIME_S); float progress = 1.0F - (invulnerable_time_accumulator_ / TOTAL_INVULNERABLE_TIME_S);
float white_proportion = 0.5f - progress * 0.2f; // Menos blanco hacia el final float white_proportion = 0.5F - (progress * 0.2F); // Menos blanco hacia el final
// Calcula si debe mostrar textura de invulnerabilidad basado en el ciclo temporal // Calcula si debe mostrar textura de invulnerabilidad basado en el ciclo temporal
float cycle_position = fmod(invulnerable_time_accumulator_, BLINK_PERIOD_S) / BLINK_PERIOD_S; float cycle_position = std::fmod(invulnerable_time_accumulator_, BLINK_PERIOD_S) / BLINK_PERIOD_S;
bool should_show_invulnerable = cycle_position < white_proportion; bool should_show_invulnerable = cycle_position < white_proportion;
size_t target_texture = should_show_invulnerable ? INVULNERABLE_TEXTURE : coffees_; size_t target_texture = should_show_invulnerable ? INVULNERABLE_TEXTURE : coffees_;
@@ -758,17 +754,17 @@ void Player::updateInvulnerable(float deltaTime) {
void Player::setPowerUp() { void Player::setPowerUp() {
power_up_ = true; power_up_ = true;
power_up_counter_ = POWERUP_COUNTER; power_up_counter_ = POWERUP_COUNTER;
power_up_time_accumulator_ = static_cast<float>(POWERUP_COUNTER) / 60.0f; // Convert frames to seconds power_up_time_accumulator_ = static_cast<float>(POWERUP_COUNTER) / 60.0F; // Convert frames to seconds
power_sprite_visible_ = true; // Inicialmente visible cuando se activa el power-up power_sprite_visible_ = true; // Inicialmente visible cuando se activa el power-up
in_power_up_ending_phase_ = false; // Empezar en fase normal in_power_up_ending_phase_ = false; // Empezar en fase normal
bullet_color_toggle_ = false; // Resetear toggle bullet_color_toggle_ = false; // Resetear toggle
} }
// Actualiza el valor de la variable (time-based) // Actualiza el valor de la variable (time-based)
void Player::updatePowerUp(float deltaTime) { void Player::updatePowerUp(float delta_time) {
if (playing_state_ == State::PLAYING) { if (playing_state_ == State::PLAYING) {
if (power_up_) { if (power_up_) {
power_up_time_accumulator_ -= deltaTime; power_up_time_accumulator_ -= delta_time;
power_up_ = power_up_time_accumulator_ > 0; power_up_ = power_up_time_accumulator_ > 0;
if (!power_up_) { if (!power_up_) {
power_up_time_accumulator_ = 0; power_up_time_accumulator_ = 0;
@@ -778,8 +774,8 @@ void Player::updatePowerUp(float deltaTime) {
// Los colores ahora se manejan dinámicamente en getNextBulletColor() // Los colores ahora se manejan dinámicamente en getNextBulletColor()
} else { } else {
// Calcular visibilidad del power sprite // Calcular visibilidad del power sprite
const float TOTAL_POWERUP_TIME_S = static_cast<float>(POWERUP_COUNTER) / 60.0f; const float TOTAL_POWERUP_TIME_S = static_cast<float>(POWERUP_COUNTER) / 60.0F;
const float QUARTER_TIME_S = TOTAL_POWERUP_TIME_S / 4.0f; const float QUARTER_TIME_S = TOTAL_POWERUP_TIME_S / 4.0F;
if (power_up_time_accumulator_ > QUARTER_TIME_S) { if (power_up_time_accumulator_ > QUARTER_TIME_S) {
// En los primeros 75% del tiempo, siempre visible // En los primeros 75% del tiempo, siempre visible
@@ -787,10 +783,10 @@ void Player::updatePowerUp(float deltaTime) {
in_power_up_ending_phase_ = false; in_power_up_ending_phase_ = false;
} else { } else {
// En el último 25%, parpadea cada 20 frames (≈0.333s) // En el último 25%, parpadea cada 20 frames (≈0.333s)
constexpr float BLINK_PERIOD_S = 20.0f / 60.0f; constexpr float BLINK_PERIOD_S = 20.0F / 60.0F;
constexpr float VISIBLE_PROPORTION = 4.0f / 20.0f; constexpr float VISIBLE_PROPORTION = 4.0F / 20.0F;
float cycle_position = fmod(power_up_time_accumulator_, BLINK_PERIOD_S) / BLINK_PERIOD_S; float cycle_position = std::fmod(power_up_time_accumulator_, BLINK_PERIOD_S) / BLINK_PERIOD_S;
power_sprite_visible_ = cycle_position >= VISIBLE_PROPORTION; power_sprite_visible_ = cycle_position >= VISIBLE_PROPORTION;
in_power_up_ending_phase_ = true; // Activar modo alternancia de colores de balas in_power_up_ending_phase_ = true; // Activar modo alternancia de colores de balas
} }
@@ -836,10 +832,10 @@ void Player::setPlayerTextures(const std::vector<std::shared_ptr<Texture>>& text
} }
// Actualiza el contador de continue (time-based) // Actualiza el contador de continue (time-based)
void Player::updateContinueCounter(float deltaTime) { void Player::updateContinueCounter(float delta_time) {
if (playing_state_ == State::CONTINUE) { if (playing_state_ == State::CONTINUE) {
continue_time_accumulator_ += deltaTime; continue_time_accumulator_ += delta_time;
constexpr float CONTINUE_INTERVAL_S = 1.0f; // 1 segundo constexpr float CONTINUE_INTERVAL_S = 1.0F; // 1 segundo
if (continue_time_accumulator_ >= CONTINUE_INTERVAL_S) { if (continue_time_accumulator_ >= CONTINUE_INTERVAL_S) {
continue_time_accumulator_ -= CONTINUE_INTERVAL_S; continue_time_accumulator_ -= CONTINUE_INTERVAL_S;
decContinueCounter(); decContinueCounter();
@@ -848,10 +844,10 @@ void Player::updateContinueCounter(float deltaTime) {
} }
// Actualiza el contador de entrar nombre (time-based) // Actualiza el contador de entrar nombre (time-based)
void Player::updateEnterNameCounter(float deltaTime) { void Player::updateEnterNameCounter(float delta_time) {
if (playing_state_ == State::ENTERING_NAME || playing_state_ == State::ENTERING_NAME_GAME_COMPLETED) { if (playing_state_ == State::ENTERING_NAME || playing_state_ == State::ENTERING_NAME_GAME_COMPLETED) {
name_entry_time_accumulator_ += deltaTime; name_entry_time_accumulator_ += delta_time;
constexpr float NAME_ENTRY_INTERVAL_S = 1.0f; // 1 segundo constexpr float NAME_ENTRY_INTERVAL_S = 1.0F; // 1 segundo
if (name_entry_time_accumulator_ >= NAME_ENTRY_INTERVAL_S) { if (name_entry_time_accumulator_ >= NAME_ENTRY_INTERVAL_S) {
name_entry_time_accumulator_ -= NAME_ENTRY_INTERVAL_S; name_entry_time_accumulator_ -= NAME_ENTRY_INTERVAL_S;
decNameEntryCounter(); decNameEntryCounter();
@@ -860,10 +856,10 @@ void Player::updateEnterNameCounter(float deltaTime) {
} }
// Actualiza el estado de SHOWING_NAME (time-based) // Actualiza el estado de SHOWING_NAME (time-based)
void Player::updateShowingName(float deltaTime) { void Player::updateShowingName(float delta_time) {
if (playing_state_ == State::SHOWING_NAME) { if (playing_state_ == State::SHOWING_NAME) {
showing_name_time_accumulator_ += deltaTime; showing_name_time_accumulator_ += delta_time;
constexpr float SHOWING_NAME_DURATION_S = 5.0f; // 5 segundos constexpr float SHOWING_NAME_DURATION_S = 5.0F; // 5 segundos
if (showing_name_time_accumulator_ >= SHOWING_NAME_DURATION_S) { if (showing_name_time_accumulator_ >= SHOWING_NAME_DURATION_S) {
game_completed_ ? setPlayingState(State::LEAVING_SCREEN) : setPlayingState(State::CONTINUE); game_completed_ ? setPlayingState(State::LEAVING_SCREEN) : setPlayingState(State::CONTINUE);
} }
@@ -872,7 +868,7 @@ void Player::updateShowingName(float deltaTime) {
// Decrementa el contador de continuar // Decrementa el contador de continuar
void Player::decContinueCounter() { void Player::decContinueCounter() {
continue_time_accumulator_ = 0.0f; // Reset time accumulator continue_time_accumulator_ = 0.0F; // Reset time accumulator
--continue_counter_; --continue_counter_;
if (continue_counter_ < 0) { if (continue_counter_ < 0) {
setPlayingState(State::CONTINUE_TIME_OUT); setPlayingState(State::CONTINUE_TIME_OUT);
@@ -883,16 +879,16 @@ void Player::decContinueCounter() {
// Decrementa el contador de entrar nombre // Decrementa el contador de entrar nombre
void Player::decNameEntryCounter() { void Player::decNameEntryCounter() {
name_entry_time_accumulator_ = 0.0f; // Reset time accumulator name_entry_time_accumulator_ = 0.0F; // Reset time accumulator
// Incrementa acumuladores de tiempo (1 segundo) // Incrementa acumuladores de tiempo (1 segundo)
name_entry_idle_time_accumulator_ += 1.0f; name_entry_idle_time_accumulator_ += 1.0F;
name_entry_total_time_accumulator_ += 1.0f; name_entry_total_time_accumulator_ += 1.0F;
if ((name_entry_total_time_accumulator_ >= param.game.name_entry_total_time) || if ((name_entry_total_time_accumulator_ >= param.game.name_entry_total_time) ||
(name_entry_idle_time_accumulator_ >= param.game.name_entry_idle_time)) { (name_entry_idle_time_accumulator_ >= param.game.name_entry_idle_time)) {
name_entry_total_time_accumulator_ = 0.0f; name_entry_total_time_accumulator_ = 0.0F;
name_entry_idle_time_accumulator_ = 0.0f; name_entry_idle_time_accumulator_ = 0.0F;
if (playing_state_ == State::ENTERING_NAME) { if (playing_state_ == State::ENTERING_NAME) {
last_enter_name_ = getRecordName(); last_enter_name_ = getRecordName();
setPlayingState(State::SHOWING_NAME); setPlayingState(State::SHOWING_NAME);
@@ -977,15 +973,15 @@ void Player::addCredit() {
// ======================================== // ========================================
// Método principal del sistema de disparo // Método principal del sistema de disparo
void Player::updateFireSystem(float deltaTime) { void Player::updateFireSystem(float delta_time) {
updateFunctionalLine(deltaTime); // Línea 1: CanFire updateFunctionalLine(delta_time); // Línea 1: CanFire
updateVisualLine(deltaTime); // Línea 2: Animaciones updateVisualLine(delta_time); // Línea 2: Animaciones
} }
// LÍNEA 1: Sistema Funcional (CanFire) // LÍNEA 1: Sistema Funcional (CanFire)
void Player::updateFunctionalLine(float deltaTime) { void Player::updateFunctionalLine(float delta_time) {
if (fire_cooldown_timer_ > 0) { if (fire_cooldown_timer_ > 0) {
fire_cooldown_timer_ -= deltaTime; fire_cooldown_timer_ -= delta_time;
can_fire_new_system_ = false; can_fire_new_system_ = false;
} else { } else {
fire_cooldown_timer_ = 0; // Evitar valores negativos fire_cooldown_timer_ = 0; // Evitar valores negativos
@@ -994,12 +990,12 @@ void Player::updateFunctionalLine(float deltaTime) {
} }
// LÍNEA 2: Sistema Visual (Animaciones) // LÍNEA 2: Sistema Visual (Animaciones)
void Player::updateVisualLine(float deltaTime) { void Player::updateVisualLine(float delta_time) {
if (visual_fire_state_ == VisualFireState::NORMAL) { if (visual_fire_state_ == VisualFireState::NORMAL) {
return; // No hay temporizador activo en estado NORMAL return; // No hay temporizador activo en estado NORMAL
} }
visual_state_timer_ -= deltaTime; visual_state_timer_ -= delta_time;
switch (visual_fire_state_) { switch (visual_fire_state_) {
case VisualFireState::AIMING: case VisualFireState::AIMING:
@@ -1029,7 +1025,7 @@ void Player::updateVisualLine(float deltaTime) {
// Inicia un disparo en ambas líneas // Inicia un disparo en ambas líneas
void Player::startFiringSystem(int cooldown_frames) { void Player::startFiringSystem(int cooldown_frames) {
// LÍNEA 1: Inicia cooldown funcional // LÍNEA 1: Inicia cooldown funcional
fire_cooldown_timer_ = static_cast<float>(cooldown_frames) / 60.0f; // Convertir frames a segundos fire_cooldown_timer_ = static_cast<float>(cooldown_frames) / 60.0F; // Convertir frames a segundos
can_fire_new_system_ = false; can_fire_new_system_ = false;
// LÍNEA 2: Resetea completamente el estado visual // LÍNEA 2: Resetea completamente el estado visual

View File

@@ -1,21 +1,23 @@
#pragma once #pragma once
#include <SDL3/SDL.h> // Para Uint32, SDL_FRect, SDL_FlipMode #include <SDL3/SDL.h> // Para SDL_FRect, SDL_FlipMode
#include <memory> // Para shared_ptr, allocator, unique_ptr #include <cstddef> // Para size_t
#include <string> // Para string #include <iterator> // Para pair
#include <utility> // Para pair #include <memory> // Para shared_ptr, unique_ptr
#include <vector> // Para vector #include <string> // Para basic_string, string
#include <utility> // Para move, pair
#include <vector> // Para vector
#include "animated_sprite.hpp" // Para AnimatedSprite #include "animated_sprite.hpp" // for AnimatedSprite
#include "bullet.hpp" // Para Bullet #include "bullet.hpp" // for Bullet
#include "enter_name.hpp" // Para EnterName #include "enter_name.hpp" // for EnterName
#include "input.hpp" // Para Input #include "input.hpp" // for Input
#include "manage_hiscore_table.hpp" // Para Table #include "manage_hiscore_table.hpp" // for Table
#include "scoreboard.hpp" // Para Scoreboard #include "scoreboard.hpp" // for Scoreboard
#include "stage_interface.hpp" // Para IStageInfo #include "utils.hpp" // for Circle
#include "utils.hpp" // Para Circle
class IStageInfo;
class Texture; class Texture;
// --- Clase Player: jugador principal del juego --- // --- Clase Player: jugador principal del juego ---
@@ -115,9 +117,9 @@ class Player {
~Player() = default; ~Player() = default;
// --- Inicialización y ciclo de vida --- // --- Inicialización y ciclo de vida ---
void init(); // Inicializa el jugador void init(); // Inicializa el jugador
void update(float deltaTime); // Actualiza estado, animación y contadores (time-based) void update(float delta_time); // Actualiza estado, animación y contadores (time-based)
void render(); // Dibuja el jugador en pantalla void render(); // Dibuja el jugador en pantalla
// --- Entrada y control --- // --- Entrada y control ---
void setInput(Input::Action action); // Procesa entrada general void setInput(Input::Action action); // Procesa entrada general
@@ -125,8 +127,8 @@ class Player {
void setInputEnteringName(Input::Action action); // Procesa entrada al introducir nombre void setInputEnteringName(Input::Action action); // Procesa entrada al introducir nombre
// --- Movimiento y animación --- // --- Movimiento y animación ---
void move(float deltaTime); // Mueve el jugador (time-based) void move(float delta_time); // Mueve el jugador (time-based)
void setAnimation(float deltaTime); // Establece la animación según el estado (time-based) void setAnimation(float delta_time); // Establece la animación según el estado (time-based)
// --- Texturas y animaciones --- // --- Texturas y animaciones ---
void setPlayerTextures(const std::vector<std::shared_ptr<Texture>>& texture); // Cambia las texturas del jugador void setPlayerTextures(const std::vector<std::shared_ptr<Texture>>& texture); // Cambia las texturas del jugador
@@ -140,7 +142,7 @@ class Player {
void setPlayingState(State state); // Cambia el estado de juego void setPlayingState(State state); // Cambia el estado de juego
void setInvulnerable(bool value); // Establece el valor del estado de invulnerabilidad void setInvulnerable(bool value); // Establece el valor del estado de invulnerabilidad
void setPowerUp(); // Activa el modo PowerUp void setPowerUp(); // Activa el modo PowerUp
void updatePowerUp(float deltaTime); // Actualiza el valor de PowerUp void updatePowerUp(float delta_time); // Actualiza el valor de PowerUp
void giveExtraHit(); // Concede un toque extra al jugador void giveExtraHit(); // Concede un toque extra al jugador
void removeExtraHit(); // Quita el toque extra al jugador void removeExtraHit(); // Quita el toque extra al jugador
void decContinueCounter(); // Decrementa el contador de continuar void decContinueCounter(); // Decrementa el contador de continuar
@@ -221,7 +223,7 @@ class Player {
private: private:
// --- Constantes de física y movimiento --- // --- Constantes de física y movimiento ---
static constexpr float BASE_SPEED = 90.0f; // Velocidad base del jugador (pixels/segundo) static constexpr float BASE_SPEED = 90.0F; // Velocidad base del jugador (pixels/segundo)
// --- Constantes de power-ups y estados especiales --- // --- Constantes de power-ups y estados especiales ---
static constexpr int POWERUP_COUNTER = 1500; // Duración del estado PowerUp (frames) static constexpr int POWERUP_COUNTER = 1500; // Duración del estado PowerUp (frames)
@@ -236,10 +238,10 @@ class Player {
static constexpr int WAITING_COUNTER = 1000; // Tiempo de espera en estado de espera static constexpr int WAITING_COUNTER = 1000; // Tiempo de espera en estado de espera
// --- Constantes del nuevo sistema de disparo de dos líneas --- // --- Constantes del nuevo sistema de disparo de dos líneas ---
static constexpr float AIMING_DURATION_FACTOR = 0.5f; // 50% del cooldown funcional static constexpr float AIMING_DURATION_FACTOR = 0.5F; // 50% del cooldown funcional
static constexpr float RECOILING_DURATION_MULTIPLIER = 4.0f; // 4 veces la duración de aiming static constexpr float RECOILING_DURATION_MULTIPLIER = 4.0F; // 4 veces la duración de aiming
static constexpr float THREAT_POSE_DURATION = 50.0f / 60.0f; // 50 frames = ~0.833s (duración base) static constexpr float THREAT_POSE_DURATION = 50.0F / 60.0F; // 50 frames = ~0.833s (duración base)
static constexpr float MIN_THREAT_POSE_DURATION = 6.0f / 60.0f; // 6 frames = ~0.1s (duración mínima) static constexpr float MIN_THREAT_POSE_DURATION = 6.0F / 60.0F; // 6 frames = ~0.1s (duración mínima)
// --- Objetos y punteros --- // --- Objetos y punteros ---
std::unique_ptr<AnimatedSprite> player_sprite_; // Sprite para dibujar el jugador std::unique_ptr<AnimatedSprite> player_sprite_; // Sprite para dibujar el jugador
@@ -251,17 +253,17 @@ class Player {
IStageInfo* stage_info_; // Informacion de la pantalla actual IStageInfo* stage_info_; // Informacion de la pantalla actual
// --- Variables de estado --- // --- Variables de estado ---
SDL_FRect play_area_; // Rectángulo con la zona de juego SDL_FRect play_area_; // Rectángulo con la zona de juego
Circle collider_ = Circle(0, 0, 9); // Círculo de colisión del jugador Circle collider_ = Circle(0, 0, 9); // Círculo de colisión del jugador
std::string name_; // Nombre del jugador std::string name_; // Nombre del jugador
std::string last_enter_name_; // Último nombre introducido en la tabla de puntuaciones std::string last_enter_name_; // Último nombre introducido en la tabla de puntuaciones
Scoreboard::Id scoreboard_panel_ = Scoreboard::Id::LEFT; // Panel del marcador asociado al jugador Scoreboard::Id scoreboard_panel_ = Scoreboard::Id::LEFT; // Panel del marcador asociado al jugador
Id id_; // Identificador para el jugador Id id_; // Identificador para el jugador
State walking_state_ = State::WALKING_STOP; // Estado del jugador al moverse State walking_state_ = State::WALKING_STOP; // Estado del jugador al moverse
State firing_state_ = State::FIRING_NONE; // Estado del jugador al disparar State firing_state_ = State::FIRING_NONE; // Estado del jugador al disparar
State playing_state_ = State::WAITING; // Estado del jugador en el juego State playing_state_ = State::WAITING; // Estado del jugador en el juego
BulletColorPair bullet_colors_ = {Bullet::Color::YELLOW, Bullet::Color::GREEN}; // Par de colores de balas para este jugador BulletColorPair bullet_colors_ = {.normal_color = Bullet::Color::YELLOW, .powered_color = Bullet::Color::GREEN}; // Par de colores de balas para este jugador
std::string bullet_sound_file_ = "bullet1p.wav"; // Archivo de sonido de bala para este jugador std::string bullet_sound_file_ = "bullet1p.wav"; // Archivo de sonido de bala para este jugador
float pos_x_ = 0.0F; // Posición en el eje X float pos_x_ = 0.0F; // Posición en el eje X
float default_pos_x_; // Posición inicial para el jugador float default_pos_x_; // Posición inicial para el jugador
@@ -270,20 +272,20 @@ class Player {
int pos_y_ = 0; // Posición en el eje Y int pos_y_ = 0; // Posición en el eje Y
int default_pos_y_; // Posición inicial para el jugador int default_pos_y_; // Posición inicial para el jugador
int vel_y_ = 0; // Cantidad de píxeles a desplazarse en el eje Y int vel_y_ = 0; // Cantidad de píxeles a desplazarse en el eje Y
float invulnerable_time_accumulator_ = 0.0f; // Acumulador de tiempo para invulnerabilidad (time-based) float invulnerable_time_accumulator_ = 0.0F; // Acumulador de tiempo para invulnerabilidad (time-based)
float power_up_time_accumulator_ = 0.0f; // Acumulador de tiempo para power-up (time-based) float power_up_time_accumulator_ = 0.0F; // Acumulador de tiempo para power-up (time-based)
float continue_time_accumulator_ = 0.0f; // Acumulador de tiempo para continue counter (time-based) float continue_time_accumulator_ = 0.0F; // Acumulador de tiempo para continue counter (time-based)
float name_entry_time_accumulator_ = 0.0f; // Acumulador de tiempo para name entry counter (time-based) float name_entry_time_accumulator_ = 0.0F; // Acumulador de tiempo para name entry counter (time-based)
float showing_name_time_accumulator_ = 0.0f; // Acumulador de tiempo para showing name (time-based) float showing_name_time_accumulator_ = 0.0F; // Acumulador de tiempo para showing name (time-based)
float waiting_time_accumulator_ = 0.0f; // Acumulador de tiempo para waiting movement (time-based) float waiting_time_accumulator_ = 0.0F; // Acumulador de tiempo para waiting movement (time-based)
float step_time_accumulator_ = 0.0f; // Acumulador de tiempo para step counter (time-based) float step_time_accumulator_ = 0.0F; // Acumulador de tiempo para step counter (time-based)
// ======================================== // ========================================
// NUEVO SISTEMA DE DISPARO DE DOS LÍNEAS // NUEVO SISTEMA DE DISPARO DE DOS LÍNEAS
// ======================================== // ========================================
// LÍNEA 1: SISTEMA FUNCIONAL (CanFire) // LÍNEA 1: SISTEMA FUNCIONAL (CanFire)
float fire_cooldown_timer_ = 0.0f; // Tiempo restante hasta poder disparar otra vez float fire_cooldown_timer_ = 0.0F; // Tiempo restante hasta poder disparar otra vez
bool can_fire_new_system_ = true; // true si puede disparar ahora mismo bool can_fire_new_system_ = true; // true si puede disparar ahora mismo
// LÍNEA 2: SISTEMA VISUAL (Animaciones) // LÍNEA 2: SISTEMA VISUAL (Animaciones)
@@ -295,9 +297,9 @@ class Player {
}; };
VisualFireState visual_fire_state_ = VisualFireState::NORMAL; VisualFireState visual_fire_state_ = VisualFireState::NORMAL;
float visual_state_timer_ = 0.0f; // Tiempo en el estado visual actual float visual_state_timer_ = 0.0F; // Tiempo en el estado visual actual
float aiming_duration_ = 0.0f; // Duración del estado AIMING float aiming_duration_ = 0.0F; // Duración del estado AIMING
float recoiling_duration_ = 0.0f; // Duración del estado RECOILING float recoiling_duration_ = 0.0F; // Duración del estado RECOILING
int invulnerable_counter_ = INVULNERABLE_COUNTER; // Contador para la invulnerabilidad int invulnerable_counter_ = INVULNERABLE_COUNTER; // Contador para la invulnerabilidad
int score_ = 0; // Puntos del jugador int score_ = 0; // Puntos del jugador
@@ -307,8 +309,8 @@ class Player {
int continue_counter_ = 10; // Contador para poder continuar int continue_counter_ = 10; // Contador para poder continuar
int controller_index_ = 0; // Índice del array de mandos que utilizará para moverse int controller_index_ = 0; // Índice del array de mandos que utilizará para moverse
size_t demo_file_ = 0; // Indice del fichero de datos para el modo demo size_t demo_file_ = 0; // Indice del fichero de datos para el modo demo
float name_entry_idle_time_accumulator_ = 0.0f; // Tiempo idle acumulado para poner nombre (milisegundos) float name_entry_idle_time_accumulator_ = 0.0F; // Tiempo idle acumulado para poner nombre (milisegundos)
float name_entry_total_time_accumulator_ = 0.0f; // Tiempo total acumulado poniendo nombre (milisegundos) float name_entry_total_time_accumulator_ = 0.0F; // Tiempo total acumulado poniendo nombre (milisegundos)
int step_counter_ = 0; // Cuenta los pasos para los estados en los que camina automáticamente int step_counter_ = 0; // Cuenta los pasos para los estados en los que camina automáticamente
int credits_used_ = 0; // Indica el número de veces que ha continuado int credits_used_ = 0; // Indica el número de veces que ha continuado
int waiting_counter_ = 0; // Contador para el estado de espera int waiting_counter_ = 0; // Contador para el estado de espera
@@ -336,11 +338,11 @@ class Player {
void setScoreMultiplier(float value) { score_multiplier_ = value; } void setScoreMultiplier(float value) { score_multiplier_ = value; }
// --- Actualizadores de estado (time-based) --- // --- Actualizadores de estado (time-based) ---
void updateInvulnerable(float deltaTime); // Monitoriza el estado de invulnerabilidad void updateInvulnerable(float delta_time); // Monitoriza el estado de invulnerabilidad
void updateContinueCounter(float deltaTime); // Actualiza el contador de continue void updateContinueCounter(float delta_time); // Actualiza el contador de continue
void updateEnterNameCounter(float deltaTime); // Actualiza el contador de entrar nombre void updateEnterNameCounter(float delta_time); // Actualiza el contador de entrar nombre
void updateShowingName(float deltaTime); // Actualiza el estado SHOWING_NAME void updateShowingName(float delta_time); // Actualiza el estado SHOWING_NAME
void decNameEntryCounter(); // Decrementa el contador de entrar nombre void decNameEntryCounter(); // Decrementa el contador de entrar nombre
// --- Utilidades generales --- // --- Utilidades generales ---
void updateScoreboard(); // Actualiza el panel del marcador void updateScoreboard(); // Actualiza el panel del marcador
@@ -350,19 +352,19 @@ class Player {
void addScoreToScoreBoard() const; // Añade una puntuación a la tabla de records void addScoreToScoreBoard() const; // Añade una puntuación a la tabla de records
// --- Sistema de disparo (nuevo - dos líneas) --- // --- Sistema de disparo (nuevo - dos líneas) ---
void updateFireSystem(float deltaTime); // Método principal del nuevo sistema de disparo void updateFireSystem(float delta_time); // Método principal del nuevo sistema de disparo
void updateFunctionalLine(float deltaTime); // Actualiza la línea funcional (CanFire) void updateFunctionalLine(float delta_time); // Actualiza la línea funcional (CanFire)
void updateVisualLine(float deltaTime); // Actualiza la línea visual (Animaciones) void updateVisualLine(float delta_time); // Actualiza la línea visual (Animaciones)
void updateFiringStateFromVisual(); // Sincroniza firing_state_ con visual_fire_state_ void updateFiringStateFromVisual(); // Sincroniza firing_state_ con visual_fire_state_
void transitionToRecoilingNew(); // Transición AIMING → RECOILING void transitionToRecoilingNew(); // Transición AIMING → RECOILING
void transitionToThreatPose(); // Transición RECOILING → THREAT_POSE void transitionToThreatPose(); // Transición RECOILING → THREAT_POSE
void transitionToNormalNew(); // Transición THREAT_POSE → NORMAL void transitionToNormalNew(); // Transición THREAT_POSE → NORMAL
// --- Manejadores de movimiento --- // --- Manejadores de movimiento ---
void handlePlayingMovement(float deltaTime); // Gestiona el movimiento durante el juego void handlePlayingMovement(float delta_time); // Gestiona el movimiento durante el juego
void handleRecoverMovement(); // Comprueba si ha acabado la animación de recuperación void handleRecoverMovement(); // Comprueba si ha acabado la animación de recuperación
void updateStepCounter(float deltaTime); // Incrementa o ajusta el contador de pasos void updateStepCounter(float delta_time); // Incrementa o ajusta el contador de pasos
void setInputBasedOnPlayerId(); // Asocia las entradas de control según el jugador void setInputBasedOnPlayerId(); // Asocia las entradas de control según el jugador
// --- Manejadores de estados especiales --- // --- Manejadores de estados especiales ---
void handleRollingMovement(); // Actualiza la lógica de movimiento de "rodar" void handleRollingMovement(); // Actualiza la lógica de movimiento de "rodar"
@@ -373,18 +375,18 @@ class Player {
void handleContinueTimeOut(); // Gestiona tiempo de espera en pantalla "Continuar" void handleContinueTimeOut(); // Gestiona tiempo de espera en pantalla "Continuar"
// --- Manejadores de transiciones de pantalla --- // --- Manejadores de transiciones de pantalla ---
void handleTitleAnimation(float deltaTime); // Ejecuta animación del título void handleTitleAnimation(float delta_time); // Ejecuta animación del título
void handleLeavingScreen(float deltaTime); // Lógica para salir de pantalla void handleLeavingScreen(float delta_time); // Lógica para salir de pantalla
void handleEnteringScreen(float deltaTime); // Lógica para entrar en pantalla void handleEnteringScreen(float delta_time); // Lógica para entrar en pantalla
void handlePlayer1Entering(float deltaTime); // Entrada del Jugador 1 void handlePlayer1Entering(float delta_time); // Entrada del Jugador 1
void handlePlayer2Entering(float deltaTime); // Entrada del Jugador 2 void handlePlayer2Entering(float delta_time); // Entrada del Jugador 2
// --- Manejadores de pantallas especiales --- // --- Manejadores de pantallas especiales ---
void handleCreditsMovement(float deltaTime); // Movimiento en pantalla de créditos void handleCreditsMovement(float delta_time); // Movimiento en pantalla de créditos
void handleCreditsRightMovement(); // Movimiento hacia la derecha en créditos void handleCreditsRightMovement(); // Movimiento hacia la derecha en créditos
void handleCreditsLeftMovement(); // Movimiento hacia la izquierda en créditos void handleCreditsLeftMovement(); // Movimiento hacia la izquierda en créditos
void handleWaitingMovement(float deltaTime); // Animación del jugador saludando void handleWaitingMovement(float delta_time); // Animación del jugador saludando
void updateWalkingStateForCredits(); // Actualiza estado de caminata en créditos void updateWalkingStateForCredits(); // Actualiza estado de caminata en créditos
// --- Utilidades de animación --- // --- Utilidades de animación ---
[[nodiscard]] auto computeAnimation() const -> std::pair<std::string, SDL_FlipMode>; // Calcula animación de movimiento y disparo [[nodiscard]] auto computeAnimation() const -> std::pair<std::string, SDL_FlipMode>; // Calcula animación de movimiento y disparo

View File

@@ -24,10 +24,10 @@ class ShaderBackend {
* @param fragment_source Código fuente del fragment shader * @param fragment_source Código fuente del fragment shader
* @return true si la inicialización fue exitosa * @return true si la inicialización fue exitosa
*/ */
virtual bool init(SDL_Window* window, virtual auto init(SDL_Window* window,
SDL_Texture* texture, SDL_Texture* texture,
const std::string& vertex_source, const std::string& vertex_source,
const std::string& fragment_source) = 0; const std::string& fragment_source) -> bool = 0;
/** /**
* @brief Renderiza la textura con los shaders aplicados * @brief Renderiza la textura con los shaders aplicados
@@ -50,7 +50,7 @@ class ShaderBackend {
* @brief Verifica si el backend está usando aceleración por hardware * @brief Verifica si el backend está usando aceleración por hardware
* @return true si usa aceleración (OpenGL/Metal/Vulkan) * @return true si usa aceleración (OpenGL/Metal/Vulkan)
*/ */
virtual bool isHardwareAccelerated() const = 0; [[nodiscard]] virtual auto isHardwareAccelerated() const -> bool = 0;
}; };
} // namespace Rendering } // namespace Rendering

View File

@@ -2,31 +2,33 @@
#include <SDL3/SDL.h> // Para SDL_LogInfo, SDL_LogCategory, SDL_LogError, SDL_SetRenderDrawColor, SDL_EventType, SDL_PollEvent, SDL_RenderFillRect, SDL_RenderRect, SDLK_ESCAPE, SDL_Event #include <SDL3/SDL.h> // Para SDL_LogInfo, SDL_LogCategory, SDL_LogError, SDL_SetRenderDrawColor, SDL_EventType, SDL_PollEvent, SDL_RenderFillRect, SDL_RenderRect, SDLK_ESCAPE, SDL_Event
#include <algorithm> // Para find_if, max, find
#include <array> // Para array #include <array> // Para array
#include <cstdlib> // Para exit, getenv #include <cstdlib> // Para exit
#include <filesystem> // Para filesystem::remove, filesystem::exists #include <exception> // Para exception
#include <fstream> // Para ofstream #include <filesystem> // Para exists, path, remove
#include <fstream> // Para basic_ofstream, basic_ios, basic_ostream::write, ios, ofstream
#include <ranges> // Para __find_if_fn, find_if, __find_fn, find
#include <stdexcept> // Para runtime_error #include <stdexcept> // Para runtime_error
#include <utility> // Para move #include <utility> // Para move
#include "asset.hpp" // Para Asset #include "asset.hpp" // Para Asset
#include "color.hpp" // Para Color #include "color.hpp" // Para Color, NO_COLOR_MOD
#include "external/jail_audio.h" // Para JA_LoadMusic, JA_LoadSound, JA_DeleteMusic, JA_DeleteSound #include "external/jail_audio.h" // Para JA_LoadMusic, JA_LoadSound, JA_DeleteMusic, JA_DeleteSound
#include "lang.hpp" // Para getText #include "lang.hpp" // Para getText
#include "param.hpp" // Para Param, param, ParamResource, ParamGame #include "param.hpp" // Para Param, param, ParamPlayer, ParamResource, ParamGame
#include "resource_helper.hpp" // Para ResourceHelper #include "resource_helper.hpp" // Para loadFile
#include "screen.hpp" // Para Screen #include "screen.hpp" // Para Screen
#include "text.hpp" // Para Text #include "text.hpp" // Para Text
#include "version.h" // Para Version::APP_NAME y Version::GIT_HASH #include "ui/logger.hpp" // Para info, CR, dots
#include "ui/logger.hpp" // Para Logger #include "utils.hpp" // Para getFileName
#include "version.h" // Para APP_NAME, GIT_HASH
struct JA_Music_t; // lines 11-11 struct JA_Music_t; // lines 11-11
struct JA_Sound_t; // lines 12-12 struct JA_Sound_t; // lines 12-12
// Helper para cargar archivos de audio desde pack o filesystem // Helper para cargar archivos de audio desde pack o filesystem
namespace { namespace {
std::string createTempAudioFile(const std::string& file_path, std::vector<std::string>& temp_files_tracker) { auto createTempAudioFile(const std::string& file_path, std::vector<std::string>& temp_files_tracker) -> std::string {
auto resource_data = ResourceHelper::loadFile(file_path); auto resource_data = ResourceHelper::loadFile(file_path);
if (!resource_data.empty()) { if (!resource_data.empty()) {
// Crear archivo temporal // Crear archivo temporal
@@ -319,8 +321,8 @@ auto Resource::getAnimation(const std::string& name) -> AnimationsFileBuffer& {
auto Resource::getDemoData(int index) -> DemoData& { auto Resource::getDemoData(int index) -> DemoData& {
if (index < 0 || index >= static_cast<int>(demos_.size())) { if (index < 0 || index >= static_cast<int>(demos_.size())) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Index %d out of range for demo data (size: %d)", index, static_cast<int>(demos_.size())); SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Index %d out of range for demo data (size: %d)", index, static_cast<int>(demos_.size()));
static DemoData empty_demo; static DemoData empty_demo_;
return empty_demo; return empty_demo_;
} }
return demos_.at(index); return demos_.at(index);
} }
@@ -446,7 +448,7 @@ void Resource::load() {
auto vsync = Screen::getVSync(); auto vsync = Screen::getVSync();
screen->setVSync(false); screen->setVSync(false);
//SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "\n** LOADING RESOURCES"); // SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "\n** LOADING RESOURCES");
loadSounds(); // Carga sonidos loadSounds(); // Carga sonidos
loadMusics(); // Carga músicas loadMusics(); // Carga músicas
loadTextures(); // Carga texturas loadTextures(); // Carga texturas
@@ -456,7 +458,7 @@ void Resource::load() {
createText(); // Crea objetos de texto createText(); // Crea objetos de texto
createTextTextures(); // Crea texturas a partir de texto createTextTextures(); // Crea texturas a partir de texto
createPlayerTextures(); // Crea las texturas de jugadores con todas sus variantes de paleta createPlayerTextures(); // Crea las texturas de jugadores con todas sus variantes de paleta
//SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "\n** RESOURCES LOADED"); // SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "\n** RESOURCES LOADED");
// Restablece el sincronismo vertical a su valor original // Restablece el sincronismo vertical a su valor original
screen->setVSync(vsync); screen->setVSync(vsync);
@@ -489,7 +491,7 @@ void Resource::loadSounds() {
// Carga las músicas del juego // Carga las músicas del juego
void Resource::loadMusics() { void Resource::loadMusics() {
Logger::CR(); Logger::cr();
Logger::info("MUSIC FILES"); Logger::info("MUSIC FILES");
auto list = Asset::get()->getListByType(Asset::Type::MUSIC); auto list = Asset::get()->getListByType(Asset::Type::MUSIC);
musics_.clear(); musics_.clear();
@@ -505,7 +507,7 @@ void Resource::loadMusics() {
// Carga las texturas del juego // Carga las texturas del juego
void Resource::loadTextures() { void Resource::loadTextures() {
Logger::CR(); Logger::cr();
Logger::info("TEXTURES"); Logger::info("TEXTURES");
auto list = Asset::get()->getListByType(Asset::Type::BITMAP); auto list = Asset::get()->getListByType(Asset::Type::BITMAP);
textures_.clear(); textures_.clear();
@@ -519,7 +521,7 @@ void Resource::loadTextures() {
// Carga los ficheros de texto del juego // Carga los ficheros de texto del juego
void Resource::loadTextFiles() { void Resource::loadTextFiles() {
Logger::CR(); Logger::cr();
Logger::info("TEXT FILES"); Logger::info("TEXT FILES");
auto list = Asset::get()->getListByType(Asset::Type::FONT); auto list = Asset::get()->getListByType(Asset::Type::FONT);
text_files_.clear(); text_files_.clear();
@@ -533,7 +535,7 @@ void Resource::loadTextFiles() {
// Carga las animaciones del juego // Carga las animaciones del juego
void Resource::loadAnimations() { void Resource::loadAnimations() {
Logger::CR(); Logger::cr();
Logger::info("ANIMATIONS"); Logger::info("ANIMATIONS");
auto list = Asset::get()->getListByType(Asset::Type::ANIMATION); auto list = Asset::get()->getListByType(Asset::Type::ANIMATION);
animations_.clear(); animations_.clear();
@@ -547,7 +549,7 @@ void Resource::loadAnimations() {
// Carga los datos para el modo demostración // Carga los datos para el modo demostración
void Resource::loadDemoData() { void Resource::loadDemoData() {
Logger::CR(); Logger::cr();
Logger::info("DEMO FILES"); Logger::info("DEMO FILES");
auto list = Asset::get()->getListByType(Asset::Type::DEMODATA); auto list = Asset::get()->getListByType(Asset::Type::DEMODATA);
demos_.clear(); demos_.clear();
@@ -561,7 +563,7 @@ void Resource::loadDemoData() {
// Crea las texturas de jugadores con todas sus variantes de paleta // Crea las texturas de jugadores con todas sus variantes de paleta
void Resource::createPlayerTextures() { void Resource::createPlayerTextures() {
Logger::CR(); Logger::cr();
Logger::info("CREATING PLAYER TEXTURES"); Logger::info("CREATING PLAYER TEXTURES");
// Configuración de jugadores y sus paletas // Configuración de jugadores y sus paletas
@@ -650,7 +652,7 @@ void Resource::createTextTextures() {
text(std::move(text_init)) {} text(std::move(text_init)) {}
}; };
Logger::CR(); Logger::cr();
Logger::info("CREATING TEXTURES"); Logger::info("CREATING TEXTURES");
// Texturas de tamaño normal con outline // Texturas de tamaño normal con outline
@@ -700,7 +702,7 @@ void Resource::createText() {
white_texture_file(std::move(w_file)) {} white_texture_file(std::move(w_file)) {}
}; };
Logger::CR(); Logger::cr();
Logger::info("CREATING TEXT OBJECTS"); Logger::info("CREATING TEXT OBJECTS");
std::vector<ResourceInfo> resources = { std::vector<ResourceInfo> resources = {
@@ -890,7 +892,7 @@ void Resource::cleanupTempAudioFiles() {
try { try {
if (std::filesystem::exists(temp_path)) { if (std::filesystem::exists(temp_path)) {
std::filesystem::remove(temp_path); std::filesystem::remove(temp_path);
//SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Removed temp audio file: %s", temp_path.c_str()); // SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Removed temp audio file: %s", temp_path.c_str());
} }
} catch (const std::exception& e) { } catch (const std::exception& e) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to remove temp audio file %s: %s", temp_path.c_str(), e.what()); SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to remove temp audio file %s: %s", temp_path.c_str(), e.what());

View File

@@ -1,21 +1,23 @@
#include "resource_helper.hpp" #include "resource_helper.hpp"
#include <algorithm> #include <algorithm> // Para replace
#include <filesystem> #include <cstddef> // Para size_t
#include <fstream> #include <fstream> // Para basic_ifstream, basic_ostream, basic_ios, operator<<, ios, basic_istream, endl, operator|, basic_istream::read, basic_istream::seekg, basic_istream::tellg, ifstream, streamsize
#include <iostream> #include <iostream> // Para cout
#include "resource_loader.hpp" // Para ResourceLoader
namespace ResourceHelper { namespace ResourceHelper {
static bool resource_system_initialized = false; static bool resource_system_initialized = false;
bool initializeResourceSystem(const std::string& pack_file) { auto initializeResourceSystem(const std::string& pack_file) -> bool {
auto& loader = ResourceLoader::getInstance(); auto& loader = ResourceLoader::getInstance();
resource_system_initialized = loader.initialize(pack_file, true); resource_system_initialized = loader.initialize(pack_file, true);
if (resource_system_initialized) { if (resource_system_initialized) {
std::cout << "Resource system initialized with pack: " << pack_file << std::endl; std::cout << "Resource system initialized with pack: " << pack_file << '\n';
} else { } else {
std::cout << "Resource system using fallback mode (filesystem only)" << std::endl; std::cout << "Resource system using fallback mode (filesystem only)" << '\n';
} }
return true; // Always return true as fallback is acceptable return true; // Always return true as fallback is acceptable
@@ -28,7 +30,7 @@ void shutdownResourceSystem() {
} }
} }
std::vector<uint8_t> loadFile(const std::string& filepath) { auto loadFile(const std::string& filepath) -> std::vector<uint8_t> {
if (resource_system_initialized && shouldUseResourcePack(filepath)) { if (resource_system_initialized && shouldUseResourcePack(filepath)) {
auto& loader = ResourceLoader::getInstance(); auto& loader = ResourceLoader::getInstance();
std::string pack_path = getPackPath(filepath); std::string pack_path = getPackPath(filepath);
@@ -45,18 +47,18 @@ std::vector<uint8_t> loadFile(const std::string& filepath) {
return {}; return {};
} }
std::streamsize fileSize = file.tellg(); std::streamsize file_size = file.tellg();
file.seekg(0, std::ios::beg); file.seekg(0, std::ios::beg);
std::vector<uint8_t> data(fileSize); std::vector<uint8_t> data(file_size);
if (!file.read(reinterpret_cast<char*>(data.data()), fileSize)) { if (!file.read(reinterpret_cast<char*>(data.data()), file_size)) {
return {}; return {};
} }
return data; return data;
} }
bool shouldUseResourcePack(const std::string& filepath) { auto shouldUseResourcePack(const std::string& filepath) -> bool {
// Archivos que NO van al pack: // Archivos que NO van al pack:
// - config/ (ahora está fuera de data/) // - config/ (ahora está fuera de data/)
// - archivos absolutos del sistema // - archivos absolutos del sistema
@@ -73,11 +75,11 @@ bool shouldUseResourcePack(const std::string& filepath) {
return false; return false;
} }
std::string getPackPath(const std::string& asset_path) { auto getPackPath(const std::string& asset_path) -> std::string {
std::string pack_path = asset_path; std::string pack_path = asset_path;
// Normalizar separadores de path a '/' // Normalizar separadores de path a '/'
std::replace(pack_path.begin(), pack_path.end(), '\\', '/'); std::ranges::replace(pack_path, '\\', '/');
// Remover prefijo "data/" si existe // Remover prefijo "data/" si existe
size_t data_pos = pack_path.find("data/"); size_t data_pos = pack_path.find("data/");

View File

@@ -1,33 +1,31 @@
#pragma once #pragma once
#include <filesystem> #include <cstdint> // Para uint8_t
#include <fstream> #include <filesystem> // Para remove, path
#include <memory> #include <fstream> // Para basic_ofstream, basic_ios, basic_ostream::write, ios, ofstream
#include <string> #include <string> // Para string, basic_string, hash, operator+, to_string, __str_hash_base
#include <vector> #include <vector> // Para vector
#include "resource_loader.hpp"
// Helper functions para integrar ResourceLoader con el sistema existente // Helper functions para integrar ResourceLoader con el sistema existente
namespace ResourceHelper { namespace ResourceHelper {
// Inicializa ResourceLoader (llamar al inicio del programa) // Inicializa ResourceLoader (llamar al inicio del programa)
bool initializeResourceSystem(const std::string& pack_file = "resources.pack"); auto initializeResourceSystem(const std::string& pack_file = "resources.pack") -> bool;
// Cierra ResourceLoader // Cierra ResourceLoader
void shutdownResourceSystem(); void shutdownResourceSystem();
// Carga un archivo usando ResourceLoader o fallback a filesystem // Carga un archivo usando ResourceLoader o fallback a filesystem
std::vector<uint8_t> loadFile(const std::string& filepath); auto loadFile(const std::string& filepath) -> std::vector<uint8_t>;
// Verifica si un archivo debería cargarse del pack vs filesystem // Verifica si un archivo debería cargarse del pack vs filesystem
bool shouldUseResourcePack(const std::string& filepath); auto shouldUseResourcePack(const std::string& filepath) -> bool;
// Convierte ruta Asset a ruta relativa para ResourceLoader // Convierte ruta Asset a ruta relativa para ResourceLoader
std::string getPackPath(const std::string& asset_path); auto getPackPath(const std::string& asset_path) -> std::string;
// Wrappea la carga de archivos para mantener compatibilidad // Wrappea la carga de archivos para mantener compatibilidad
template <typename T> template <typename T>
T* loadResourceFile(const std::string& asset_path, T* (*loader_func)(const char*)) { auto loadResourceFile(const std::string& asset_path, T* (*loader_func)(const char*)) -> T* {
auto data = loadFile(asset_path); auto data = loadFile(asset_path);
if (data.empty()) { if (data.empty()) {
return loader_func(asset_path.c_str()); return loader_func(asset_path.c_str());

View File

@@ -1,17 +1,19 @@
#include "resource_loader.hpp" #include "resource_loader.hpp"
#include <algorithm> #include <algorithm> // Para replace
#include <filesystem> #include <filesystem> // Para exists, path, recursive_directory_iterator, directory_entry, relative
#include <fstream> #include <fstream> // Para basic_ostream, basic_ifstream, operator<<, basic_ios, endl, ios, basic_istream, operator|, basic_istream::read, basic_istream::seekg, basic_istream::tellg, ifstream, streamsize
#include <iostream> #include <iostream> // Para cerr, cout
#include "resource_pack.hpp" // Para ResourcePack
std::unique_ptr<ResourceLoader> ResourceLoader::instance = nullptr; std::unique_ptr<ResourceLoader> ResourceLoader::instance = nullptr;
ResourceLoader::ResourceLoader() ResourceLoader::ResourceLoader()
: resourcePack(nullptr), : resource_pack_(nullptr),
fallbackToFiles(true) {} fallback_to_files_(true) {}
ResourceLoader& ResourceLoader::getInstance() { auto ResourceLoader::getInstance() -> ResourceLoader& {
if (!instance) { if (!instance) {
instance = std::unique_ptr<ResourceLoader>(new ResourceLoader()); instance = std::unique_ptr<ResourceLoader>(new ResourceLoader());
} }
@@ -22,110 +24,109 @@ ResourceLoader::~ResourceLoader() {
shutdown(); shutdown();
} }
bool ResourceLoader::initialize(const std::string& packFile, bool enableFallback) { auto ResourceLoader::initialize(const std::string& packFile, bool enable_fallback) -> bool {
shutdown(); shutdown();
fallbackToFiles = enableFallback; fallback_to_files_ = enable_fallback;
packPath = packFile; pack_path_ = packFile;
if (std::filesystem::exists(packFile)) { if (std::filesystem::exists(packFile)) {
resourcePack = new ResourcePack(); resource_pack_ = new ResourcePack();
if (resourcePack->loadPack(packFile)) { if (resource_pack_->loadPack(packFile)) {
std::cout << "Resource pack loaded successfully: " << packFile << std::endl; std::cout << "Resource pack loaded successfully: " << packFile << '\n';
std::cout << "Resources available: " << resourcePack->getResourceCount() << std::endl; std::cout << "Resources available: " << resource_pack_->getResourceCount() << '\n';
return true; return true;
} else {
delete resourcePack;
resourcePack = nullptr;
std::cerr << "Failed to load resource pack: " << packFile << std::endl;
} }
delete resource_pack_;
resource_pack_ = nullptr;
std::cerr << "Failed to load resource pack: " << packFile << std::endl;
} }
if (fallbackToFiles) { if (fallback_to_files_) {
std::cout << "Using fallback mode: loading resources from data/ directory" << std::endl; std::cout << "Using fallback mode: loading resources from data/ directory" << '\n';
return true; return true;
} }
std::cerr << "Resource pack not found and fallback disabled: " << packFile << std::endl; std::cerr << "Resource pack not found and fallback disabled: " << packFile << '\n';
return false; return false;
} }
void ResourceLoader::shutdown() { void ResourceLoader::shutdown() {
if (resourcePack) { if (resource_pack_ != nullptr) {
delete resourcePack; delete resource_pack_;
resourcePack = nullptr; resource_pack_ = nullptr;
} }
} }
std::vector<uint8_t> ResourceLoader::loadResource(const std::string& filename) { auto ResourceLoader::loadResource(const std::string& filename) -> std::vector<uint8_t> {
if (resourcePack && resourcePack->hasResource(filename)) { if ((resource_pack_ != nullptr) && resource_pack_->hasResource(filename)) {
return resourcePack->getResource(filename); return resource_pack_->getResource(filename);
} }
if (fallbackToFiles) { if (fallback_to_files_) {
return loadFromFile(filename); return loadFromFile(filename);
} }
std::cerr << "Resource not found: " << filename << std::endl; std::cerr << "Resource not found: " << filename << '\n';
return {}; return {};
} }
bool ResourceLoader::resourceExists(const std::string& filename) { auto ResourceLoader::resourceExists(const std::string& filename) -> bool {
if (resourcePack && resourcePack->hasResource(filename)) { if ((resource_pack_ != nullptr) && resource_pack_->hasResource(filename)) {
return true; return true;
} }
if (fallbackToFiles) { if (fallback_to_files_) {
std::string fullPath = getDataPath(filename); std::string full_path = getDataPath(filename);
return std::filesystem::exists(fullPath); return std::filesystem::exists(full_path);
} }
return false; return false;
} }
std::vector<uint8_t> ResourceLoader::loadFromFile(const std::string& filename) { auto ResourceLoader::loadFromFile(const std::string& filename) -> std::vector<uint8_t> {
std::string fullPath = getDataPath(filename); std::string full_path = getDataPath(filename);
std::ifstream file(fullPath, std::ios::binary | std::ios::ate); std::ifstream file(full_path, std::ios::binary | std::ios::ate);
if (!file) { if (!file) {
std::cerr << "Error: Could not open file: " << fullPath << std::endl; std::cerr << "Error: Could not open file: " << full_path << '\n';
return {}; return {};
} }
std::streamsize fileSize = file.tellg(); std::streamsize file_size = file.tellg();
file.seekg(0, std::ios::beg); file.seekg(0, std::ios::beg);
std::vector<uint8_t> data(fileSize); std::vector<uint8_t> data(file_size);
if (!file.read(reinterpret_cast<char*>(data.data()), fileSize)) { if (!file.read(reinterpret_cast<char*>(data.data()), file_size)) {
std::cerr << "Error: Could not read file: " << fullPath << std::endl; std::cerr << "Error: Could not read file: " << full_path << '\n';
return {}; return {};
} }
return data; return data;
} }
std::string ResourceLoader::getDataPath(const std::string& filename) { auto ResourceLoader::getDataPath(const std::string& filename) -> std::string {
return "data/" + filename; return "data/" + filename;
} }
size_t ResourceLoader::getLoadedResourceCount() const { auto ResourceLoader::getLoadedResourceCount() const -> size_t {
if (resourcePack) { if (resource_pack_ != nullptr) {
return resourcePack->getResourceCount(); return resource_pack_->getResourceCount();
} }
return 0; return 0;
} }
std::vector<std::string> ResourceLoader::getAvailableResources() const { auto ResourceLoader::getAvailableResources() const -> std::vector<std::string> {
if (resourcePack) { if (resource_pack_ != nullptr) {
return resourcePack->getResourceList(); return resource_pack_->getResourceList();
} }
std::vector<std::string> result; std::vector<std::string> result;
if (fallbackToFiles && std::filesystem::exists("data")) { if (fallback_to_files_ && std::filesystem::exists("data")) {
for (const auto& entry : std::filesystem::recursive_directory_iterator("data")) { for (const auto& entry : std::filesystem::recursive_directory_iterator("data")) {
if (entry.is_regular_file()) { if (entry.is_regular_file()) {
std::string filename = std::filesystem::relative(entry.path(), "data").string(); std::string filename = std::filesystem::relative(entry.path(), "data").string();
std::replace(filename.begin(), filename.end(), '\\', '/'); std::ranges::replace(filename, '\\', '/');
result.push_back(filename); result.push_back(filename);
} }
} }

View File

@@ -1,38 +1,39 @@
#ifndef RESOURCE_LOADER_H #pragma once
#define RESOURCE_LOADER_H
#include <memory> #include <cstddef> // Para size_t
#include <cstdint> // Para uint8_t
#include <memory> // Para unique_ptr
#include <string> // Para string, basic_string
#include <vector> // Para vector
#include "resource_pack.hpp" class ResourcePack;
class ResourceLoader { class ResourceLoader {
private: private:
static std::unique_ptr<ResourceLoader> instance; static std::unique_ptr<ResourceLoader> instance;
ResourcePack* resourcePack; ResourcePack* resource_pack_;
std::string packPath; std::string pack_path_;
bool fallbackToFiles; bool fallback_to_files_;
ResourceLoader(); ResourceLoader();
public: public:
static ResourceLoader& getInstance(); static auto getInstance() -> ResourceLoader&;
~ResourceLoader(); ~ResourceLoader();
bool initialize(const std::string& packFile, bool enableFallback = true); auto initialize(const std::string& pack_file, bool enable_fallback = true) -> bool;
void shutdown(); void shutdown();
std::vector<uint8_t> loadResource(const std::string& filename); auto loadResource(const std::string& filename) -> std::vector<uint8_t>;
bool resourceExists(const std::string& filename); auto resourceExists(const std::string& filename) -> bool;
void setFallbackToFiles(bool enable) { fallbackToFiles = enable; } void setFallbackToFiles(bool enable) { fallback_to_files_ = enable; }
bool getFallbackToFiles() const { return fallbackToFiles; } [[nodiscard]] auto getFallbackToFiles() const -> bool { return fallback_to_files_; }
size_t getLoadedResourceCount() const; [[nodiscard]] auto getLoadedResourceCount() const -> size_t;
std::vector<std::string> getAvailableResources() const; [[nodiscard]] auto getAvailableResources() const -> std::vector<std::string>;
private: private:
std::vector<uint8_t> loadFromFile(const std::string& filename); auto loadFromFile(const std::string& filename) -> std::vector<uint8_t>;
std::string getDataPath(const std::string& filename); static auto getDataPath(const std::string& filename) -> std::string;
}; };
#endif

View File

@@ -1,29 +1,32 @@
#include "resource_pack.hpp" #include "resource_pack.hpp"
#include <algorithm> #include <algorithm> // Para replace
#include <filesystem> #include <filesystem> // Para path, recursive_directory_iterator, directory_entry, exists, relative
#include <fstream> #include <fstream> // Para basic_ifstream, basic_ostream, basic_ofstream, operator<<, basic_ios, basic_istream::read, basic_ostream::write, endl, ios, basic_istream, ifstream, operator|, basic_istream::seekg, basic_istream::tellg, ofstream, streamsize
#include <iostream> #include <iostream> // Para cerr
#include <utility> // Para pair
const std::string ResourcePack::DEFAULT_ENCRYPT_KEY = "CCAE_RESOURCES_2024"; const std::string ResourcePack::DEFAULT_ENCRYPT_KEY = "CCAE_RESOURCES__2024";
ResourcePack::ResourcePack() ResourcePack::ResourcePack()
: loaded(false) {} : loaded_(false) {}
ResourcePack::~ResourcePack() { ResourcePack::~ResourcePack() {
clear(); clear();
} }
uint32_t ResourcePack::calculateChecksum(const std::vector<uint8_t>& data) { auto ResourcePack::calculateChecksum(const std::vector<uint8_t>& data) -> uint32_t {
uint32_t checksum = 0x12345678; uint32_t checksum = 0x12345678;
for (size_t i = 0; i < data.size(); ++i) { for (unsigned char i : data) {
checksum = ((checksum << 5) + checksum) + data[i]; checksum = ((checksum << 5) + checksum) + i;
} }
return checksum; return checksum;
} }
void ResourcePack::encryptData(std::vector<uint8_t>& data, const std::string& key) { void ResourcePack::encryptData(std::vector<uint8_t>& data, const std::string& key) {
if (key.empty()) return; if (key.empty()) {
return;
}
for (size_t i = 0; i < data.size(); ++i) { for (size_t i = 0; i < data.size(); ++i) {
data[i] ^= key[i % key.length()]; data[i] ^= key[i % key.length()];
@@ -34,39 +37,39 @@ void ResourcePack::decryptData(std::vector<uint8_t>& data, const std::string& ke
encryptData(data, key); encryptData(data, key);
} }
bool ResourcePack::loadPack(const std::string& packFile) { auto ResourcePack::loadPack(const std::string& pack_file) -> bool {
std::ifstream file(packFile, std::ios::binary); std::ifstream file(pack_file, std::ios::binary);
if (!file) { if (!file) {
std::cerr << "Error: Could not open pack file: " << packFile << std::endl; std::cerr << "Error: Could not open pack file: " << pack_file << '\n';
return false; return false;
} }
char header[4]; char header[4];
file.read(header, 4); file.read(header, 4);
if (std::string(header, 4) != "CCAE") { if (std::string(header, 4) != "CCAE") {
std::cerr << "Error: Invalid pack file format" << std::endl; std::cerr << "Error: Invalid pack file format" << '\n';
return false; return false;
} }
uint32_t version; uint32_t version;
file.read(reinterpret_cast<char*>(&version), sizeof(version)); file.read(reinterpret_cast<char*>(&version), sizeof(version));
if (version != 1) { if (version != 1) {
std::cerr << "Error: Unsupported pack version: " << version << std::endl; std::cerr << "Error: Unsupported pack version: " << version << '\n';
return false; return false;
} }
uint32_t resourceCount; uint32_t resource_count;
file.read(reinterpret_cast<char*>(&resourceCount), sizeof(resourceCount)); file.read(reinterpret_cast<char*>(&resource_count), sizeof(resource_count));
resources.clear(); resources_.clear();
resources.reserve(resourceCount); resources_.reserve(resource_count);
for (uint32_t i = 0; i < resourceCount; ++i) { for (uint32_t i = 0; i < resource_count; ++i) {
uint32_t filenameLength; uint32_t filename_length;
file.read(reinterpret_cast<char*>(&filenameLength), sizeof(filenameLength)); file.read(reinterpret_cast<char*>(&filename_length), sizeof(filename_length));
std::string filename(filenameLength, '\0'); std::string filename(filename_length, '\0');
file.read(&filename[0], filenameLength); file.read(filename.data(), filename_length);
ResourceEntry entry; ResourceEntry entry;
entry.filename = filename; entry.filename = filename;
@@ -74,25 +77,25 @@ bool ResourcePack::loadPack(const std::string& packFile) {
file.read(reinterpret_cast<char*>(&entry.size), sizeof(entry.size)); file.read(reinterpret_cast<char*>(&entry.size), sizeof(entry.size));
file.read(reinterpret_cast<char*>(&entry.checksum), sizeof(entry.checksum)); file.read(reinterpret_cast<char*>(&entry.checksum), sizeof(entry.checksum));
resources[filename] = entry; resources_[filename] = entry;
} }
uint64_t dataSize; uint64_t data_size;
file.read(reinterpret_cast<char*>(&dataSize), sizeof(dataSize)); file.read(reinterpret_cast<char*>(&data_size), sizeof(data_size));
data.resize(dataSize); data_.resize(data_size);
file.read(reinterpret_cast<char*>(data.data()), dataSize); file.read(reinterpret_cast<char*>(data_.data()), data_size);
decryptData(data, DEFAULT_ENCRYPT_KEY); decryptData(data_, DEFAULT_ENCRYPT_KEY);
loaded = true; loaded_ = true;
return true; return true;
} }
bool ResourcePack::savePack(const std::string& packFile) { auto ResourcePack::savePack(const std::string& pack_file) -> bool {
std::ofstream file(packFile, std::ios::binary); std::ofstream file(pack_file, std::ios::binary);
if (!file) { if (!file) {
std::cerr << "Error: Could not create pack file: " << packFile << std::endl; std::cerr << "Error: Could not create pack file: " << pack_file << '\n';
return false; return false;
} }
@@ -101,60 +104,60 @@ bool ResourcePack::savePack(const std::string& packFile) {
uint32_t version = 1; uint32_t version = 1;
file.write(reinterpret_cast<const char*>(&version), sizeof(version)); file.write(reinterpret_cast<const char*>(&version), sizeof(version));
uint32_t resourceCount = static_cast<uint32_t>(resources.size()); auto resource_count = static_cast<uint32_t>(resources_.size());
file.write(reinterpret_cast<const char*>(&resourceCount), sizeof(resourceCount)); file.write(reinterpret_cast<const char*>(&resource_count), sizeof(resource_count));
for (const auto& [filename, entry] : resources) { for (const auto& [filename, entry] : resources_) {
uint32_t filenameLength = static_cast<uint32_t>(filename.length()); auto filename_length = static_cast<uint32_t>(filename.length());
file.write(reinterpret_cast<const char*>(&filenameLength), sizeof(filenameLength)); file.write(reinterpret_cast<const char*>(&filename_length), sizeof(filename_length));
file.write(filename.c_str(), filenameLength); file.write(filename.c_str(), filename_length);
file.write(reinterpret_cast<const char*>(&entry.offset), sizeof(entry.offset)); file.write(reinterpret_cast<const char*>(&entry.offset), sizeof(entry.offset));
file.write(reinterpret_cast<const char*>(&entry.size), sizeof(entry.size)); file.write(reinterpret_cast<const char*>(&entry.size), sizeof(entry.size));
file.write(reinterpret_cast<const char*>(&entry.checksum), sizeof(entry.checksum)); file.write(reinterpret_cast<const char*>(&entry.checksum), sizeof(entry.checksum));
} }
std::vector<uint8_t> encryptedData = data; std::vector<uint8_t> encrypted_data = data_;
encryptData(encryptedData, DEFAULT_ENCRYPT_KEY); encryptData(encrypted_data, DEFAULT_ENCRYPT_KEY);
uint64_t dataSize = encryptedData.size(); uint64_t data_size = encrypted_data.size();
file.write(reinterpret_cast<const char*>(&dataSize), sizeof(dataSize)); file.write(reinterpret_cast<const char*>(&data_size), sizeof(data_size));
file.write(reinterpret_cast<const char*>(encryptedData.data()), dataSize); file.write(reinterpret_cast<const char*>(encrypted_data.data()), data_size);
return true; return true;
} }
bool ResourcePack::addFile(const std::string& filename, const std::string& filepath) { auto ResourcePack::addFile(const std::string& filename, const std::string& filepath) -> bool {
std::ifstream file(filepath, std::ios::binary | std::ios::ate); std::ifstream file(filepath, std::ios::binary | std::ios::ate);
if (!file) { if (!file) {
std::cerr << "Error: Could not open file: " << filepath << std::endl; std::cerr << "Error: Could not open file: " << filepath << '\n';
return false; return false;
} }
std::streamsize fileSize = file.tellg(); std::streamsize file_size = file.tellg();
file.seekg(0, std::ios::beg); file.seekg(0, std::ios::beg);
std::vector<uint8_t> fileData(fileSize); std::vector<uint8_t> file_data(file_size);
if (!file.read(reinterpret_cast<char*>(fileData.data()), fileSize)) { if (!file.read(reinterpret_cast<char*>(file_data.data()), file_size)) {
std::cerr << "Error: Could not read file: " << filepath << std::endl; std::cerr << "Error: Could not read file: " << filepath << '\n';
return false; return false;
} }
ResourceEntry entry; ResourceEntry entry;
entry.filename = filename; entry.filename = filename;
entry.offset = data.size(); entry.offset = data_.size();
entry.size = fileData.size(); entry.size = file_data.size();
entry.checksum = calculateChecksum(fileData); entry.checksum = calculateChecksum(file_data);
data.insert(data.end(), fileData.begin(), fileData.end()); data_.insert(data_.end(), file_data.begin(), file_data.end());
resources[filename] = entry; resources_[filename] = entry;
return true; return true;
} }
bool ResourcePack::addDirectory(const std::string& directory) { auto ResourcePack::addDirectory(const std::string& directory) -> bool {
if (!std::filesystem::exists(directory)) { if (!std::filesystem::exists(directory)) {
std::cerr << "Error: Directory does not exist: " << directory << std::endl; std::cerr << "Error: Directory does not exist: " << directory << '\n';
return false; return false;
} }
@@ -163,7 +166,7 @@ bool ResourcePack::addDirectory(const std::string& directory) {
std::string filepath = entry.path().string(); std::string filepath = entry.path().string();
std::string filename = std::filesystem::relative(entry.path(), directory).string(); std::string filename = std::filesystem::relative(entry.path(), directory).string();
std::replace(filename.begin(), filename.end(), '\\', '/'); std::ranges::replace(filename, '\\', '/');
if (!addFile(filename, filepath)) { if (!addFile(filename, filepath)) {
return false; return false;
@@ -174,49 +177,49 @@ bool ResourcePack::addDirectory(const std::string& directory) {
return true; return true;
} }
std::vector<uint8_t> ResourcePack::getResource(const std::string& filename) { auto ResourcePack::getResource(const std::string& filename) -> std::vector<uint8_t> {
auto it = resources.find(filename); auto it = resources_.find(filename);
if (it == resources.end()) { if (it == resources_.end()) {
std::cerr << "Error: Resource not found: " << filename << std::endl; std::cerr << "Error: Resource not found: " << filename << '\n';
return {}; return {};
} }
const ResourceEntry& entry = it->second; const ResourceEntry& entry = it->second;
if (entry.offset + entry.size > data.size()) { if (entry.offset + entry.size > data_.size()) {
std::cerr << "Error: Invalid resource data: " << filename << std::endl; std::cerr << "Error: Invalid resource data: " << filename << '\n';
return {}; return {};
} }
std::vector<uint8_t> result(data.begin() + entry.offset, std::vector<uint8_t> result(data_.begin() + entry.offset,
data.begin() + entry.offset + entry.size); data_.begin() + entry.offset + entry.size);
uint32_t checksum = calculateChecksum(result); uint32_t checksum = calculateChecksum(result);
if (checksum != entry.checksum) { if (checksum != entry.checksum) {
std::cerr << "Warning: Checksum mismatch for resource: " << filename << std::endl; std::cerr << "Warning: Checksum mismatch for resource: " << filename << '\n';
} }
return result; return result;
} }
bool ResourcePack::hasResource(const std::string& filename) const { auto ResourcePack::hasResource(const std::string& filename) const -> bool {
return resources.find(filename) != resources.end(); return resources_.find(filename) != resources_.end();
} }
void ResourcePack::clear() { void ResourcePack::clear() {
resources.clear(); resources_.clear();
data.clear(); data_.clear();
loaded = false; loaded_ = false;
} }
size_t ResourcePack::getResourceCount() const { auto ResourcePack::getResourceCount() const -> size_t {
return resources.size(); return resources_.size();
} }
std::vector<std::string> ResourcePack::getResourceList() const { auto ResourcePack::getResourceList() const -> std::vector<std::string> {
std::vector<std::string> result; std::vector<std::string> result;
result.reserve(resources.size()); result.reserve(resources_.size());
for (const auto& [filename, entry] : resources) { for (const auto& [filename, entry] : resources_) {
result.push_back(filename); result.push_back(filename);
} }

View File

@@ -1,10 +1,11 @@
#ifndef RESOURCE_PACK_H #ifndef RESOURCE_PACK_H
#define RESOURCE_PACK_H #define RESOURCE_PACK_H
#include <cstdint> #include <cstddef> // Para size_t
#include <string> #include <cstdint> // Para uint8_t, uint32_t, uint64_t
#include <unordered_map> #include <string> // Para string, basic_string, hash
#include <vector> #include <unordered_map> // Para unordered_map
#include <vector> // Para vector
struct ResourceEntry { struct ResourceEntry {
std::string filename; std::string filename;
@@ -15,30 +16,30 @@ struct ResourceEntry {
class ResourcePack { class ResourcePack {
private: private:
std::unordered_map<std::string, ResourceEntry> resources; std::unordered_map<std::string, ResourceEntry> resources_;
std::vector<uint8_t> data; std::vector<uint8_t> data_;
bool loaded; bool loaded_;
uint32_t calculateChecksum(const std::vector<uint8_t>& data); static auto calculateChecksum(const std::vector<uint8_t>& data) -> uint32_t;
void encryptData(std::vector<uint8_t>& data, const std::string& key); static void encryptData(std::vector<uint8_t>& data, const std::string& key);
void decryptData(std::vector<uint8_t>& data, const std::string& key); void decryptData(std::vector<uint8_t>& data, const std::string& key);
public: public:
ResourcePack(); ResourcePack();
~ResourcePack(); ~ResourcePack();
bool loadPack(const std::string& packFile); auto loadPack(const std::string& pack_file) -> bool;
bool savePack(const std::string& packFile); auto savePack(const std::string& pack_file) -> bool;
bool addFile(const std::string& filename, const std::string& filepath); auto addFile(const std::string& filename, const std::string& filepath) -> bool;
bool addDirectory(const std::string& directory); auto addDirectory(const std::string& directory) -> bool;
std::vector<uint8_t> getResource(const std::string& filename); auto getResource(const std::string& filename) -> std::vector<uint8_t>;
bool hasResource(const std::string& filename) const; auto hasResource(const std::string& filename) const -> bool;
void clear(); void clear();
size_t getResourceCount() const; auto getResourceCount() const -> size_t;
std::vector<std::string> getResourceList() const; auto getResourceList() const -> std::vector<std::string>;
static const std::string DEFAULT_ENCRYPT_KEY; static const std::string DEFAULT_ENCRYPT_KEY;
}; };

View File

@@ -52,7 +52,7 @@ Scoreboard::Scoreboard()
continue_counter_.at(i) = 0; continue_counter_.at(i) = 0;
carousel_prev_index_.at(i) = -1; // Inicializar a -1 para detectar primera inicialización carousel_prev_index_.at(i) = -1; // Inicializar a -1 para detectar primera inicialización
enter_name_ref_.at(i) = nullptr; enter_name_ref_.at(i) = nullptr;
text_slide_offset_.at(i) = 0.0f; text_slide_offset_.at(i) = 0.0F;
} }
panel_.at(static_cast<size_t>(Id::LEFT)).mode = Mode::SCORE; panel_.at(static_cast<size_t>(Id::LEFT)).mode = Mode::SCORE;
@@ -96,12 +96,12 @@ Scoreboard::~Scoreboard() {
// Configura la animación del carrusel // Configura la animación del carrusel
void Scoreboard::setCarouselAnimation(Id id, int selected_index, EnterName* enter_name_ptr) { void Scoreboard::setCarouselAnimation(Id id, int selected_index, EnterName* enter_name_ptr) {
size_t idx = static_cast<size_t>(id); auto idx = static_cast<size_t>(id);
// Guardar referencia a EnterName // Guardar referencia a EnterName
enter_name_ref_.at(idx) = enter_name_ptr; enter_name_ref_.at(idx) = enter_name_ptr;
if (!enter_name_ptr || selected_index < 0) { if ((enter_name_ptr == nullptr) || selected_index < 0) {
return; return;
} }
@@ -144,7 +144,7 @@ void Scoreboard::setCarouselAnimation(Id id, int selected_index, EnterName* ente
// Establece el modo del panel y gestiona transiciones // Establece el modo del panel y gestiona transiciones
void Scoreboard::setMode(Id id, Mode mode) { void Scoreboard::setMode(Id id, Mode mode) {
size_t idx = static_cast<size_t>(id); auto idx = static_cast<size_t>(id);
// Cambiar el modo // Cambiar el modo
panel_.at(idx).mode = mode; panel_.at(idx).mode = mode;
@@ -153,7 +153,7 @@ void Scoreboard::setMode(Id id, Mode mode) {
switch (mode) { switch (mode) {
case Mode::SCORE_TO_ENTER_NAME: case Mode::SCORE_TO_ENTER_NAME:
// Iniciar animación de transición SCORE → ENTER_NAME // Iniciar animación de transición SCORE → ENTER_NAME
text_slide_offset_.at(idx) = 0.0f; text_slide_offset_.at(idx) = 0.0F;
// Resetear carrusel para que se inicialice correctamente en ENTER_NAME // Resetear carrusel para que se inicialice correctamente en ENTER_NAME
if (carousel_prev_index_.at(idx) != -1) { if (carousel_prev_index_.at(idx) != -1) {
carousel_prev_index_.at(idx) = -1; carousel_prev_index_.at(idx) = -1;
@@ -166,17 +166,17 @@ void Scoreboard::setMode(Id id, Mode mode) {
if (carousel_prev_index_.at(idx) != -1) { if (carousel_prev_index_.at(idx) != -1) {
carousel_prev_index_.at(idx) = -1; carousel_prev_index_.at(idx) = -1;
} }
text_slide_offset_.at(idx) = 0.0f; text_slide_offset_.at(idx) = 0.0F;
break; break;
case Mode::ENTER_TO_SHOW_NAME: case Mode::ENTER_TO_SHOW_NAME:
// Iniciar animación de transición ENTER_NAME → SHOW_NAME // Iniciar animación de transición ENTER_NAME → SHOW_NAME
text_slide_offset_.at(idx) = 0.0f; text_slide_offset_.at(idx) = 0.0F;
break; break;
case Mode::SHOW_NAME: case Mode::SHOW_NAME:
// Asegurar que la animación está completa // Asegurar que la animación está completa
text_slide_offset_.at(idx) = 1.0f; text_slide_offset_.at(idx) = 1.0F;
break; break;
// Otros modos no requieren inicialización especial // Otros modos no requieren inicialización especial
@@ -216,17 +216,17 @@ void Scoreboard::updateNameColorIndex() {
} }
// Actualiza la animación del carrusel // Actualiza la animación del carrusel
void Scoreboard::updateCarouselAnimation(float deltaTime) { void Scoreboard::updateCarouselAnimation(float delta_time) {
constexpr float CAROUSEL_SPEED = 8.0f; // Posiciones por segundo constexpr float CAROUSEL_SPEED = 8.0F; // Posiciones por segundo
for (size_t i = 0; i < carousel_position_.size(); ++i) { for (size_t i = 0; i < carousel_position_.size(); ++i) {
// Solo animar si no hemos llegado al target // Solo animar si no hemos llegado al target
if (std::abs(carousel_position_.at(i) - carousel_target_.at(i)) > 0.01f) { if (std::abs(carousel_position_.at(i) - carousel_target_.at(i)) > 0.01F) {
// Determinar dirección // Determinar dirección
float direction = (carousel_target_.at(i) > carousel_position_.at(i)) ? 1.0f : -1.0f; float direction = (carousel_target_.at(i) > carousel_position_.at(i)) ? 1.0F : -1.0F;
// Calcular movimiento // Calcular movimiento
float movement = CAROUSEL_SPEED * deltaTime * direction; float movement = CAROUSEL_SPEED * delta_time * direction;
// Mover, pero no sobrepasar el target // Mover, pero no sobrepasar el target
float new_position = carousel_position_.at(i) + movement; float new_position = carousel_position_.at(i) + movement;
@@ -245,24 +245,24 @@ void Scoreboard::updateCarouselAnimation(float deltaTime) {
} }
// Actualiza las animaciones de deslizamiento de texto // Actualiza las animaciones de deslizamiento de texto
void Scoreboard::updateTextSlideAnimation(float deltaTime) { void Scoreboard::updateTextSlideAnimation(float delta_time) {
for (size_t i = 0; i < static_cast<size_t>(Id::SIZE); ++i) { for (size_t i = 0; i < static_cast<size_t>(Id::SIZE); ++i) {
Mode current_mode = panel_.at(i).mode; Mode current_mode = panel_.at(i).mode;
if (current_mode == Mode::SCORE_TO_ENTER_NAME) { if (current_mode == Mode::SCORE_TO_ENTER_NAME) {
// Incrementar progreso de animación SCORE → ENTER_NAME (0.0 a 1.0) // Incrementar progreso de animación SCORE → ENTER_NAME (0.0 a 1.0)
text_slide_offset_.at(i) += deltaTime / TEXT_SLIDE_DURATION; text_slide_offset_.at(i) += delta_time / TEXT_SLIDE_DURATION;
// Terminar animación y cambiar a ENTER_NAME cuando se complete // Terminar animación y cambiar a ENTER_NAME cuando se complete
if (text_slide_offset_.at(i) >= 1.0f) { if (text_slide_offset_.at(i) >= 1.0F) {
setMode(static_cast<Id>(i), Mode::ENTER_NAME); setMode(static_cast<Id>(i), Mode::ENTER_NAME);
} }
} else if (current_mode == Mode::ENTER_TO_SHOW_NAME) { } else if (current_mode == Mode::ENTER_TO_SHOW_NAME) {
// Incrementar progreso de animación ENTER_NAME → SHOW_NAME (0.0 a 1.0) // Incrementar progreso de animación ENTER_NAME → SHOW_NAME (0.0 a 1.0)
text_slide_offset_.at(i) += deltaTime / TEXT_SLIDE_DURATION; text_slide_offset_.at(i) += delta_time / TEXT_SLIDE_DURATION;
// Terminar animación y cambiar a SHOW_NAME cuando se complete // Terminar animación y cambiar a SHOW_NAME cuando se complete
if (text_slide_offset_.at(i) >= 1.0f) { if (text_slide_offset_.at(i) >= 1.0F) {
setMode(static_cast<Id>(i), Mode::SHOW_NAME); setMode(static_cast<Id>(i), Mode::SHOW_NAME);
} }
} }
@@ -270,11 +270,11 @@ void Scoreboard::updateTextSlideAnimation(float deltaTime) {
} }
// Actualiza la lógica del marcador // Actualiza la lógica del marcador
void Scoreboard::update(float deltaTime) { void Scoreboard::update(float delta_time) {
updateTimeCounter(); updateTimeCounter();
updateNameColorIndex(); updateNameColorIndex();
updateCarouselAnimation(deltaTime); updateCarouselAnimation(delta_time);
updateTextSlideAnimation(deltaTime); updateTextSlideAnimation(delta_time);
fillBackgroundTexture(); // Renderizar DESPUÉS de actualizar fillBackgroundTexture(); // Renderizar DESPUÉS de actualizar
} }
@@ -438,30 +438,30 @@ void Scoreboard::renderContinueMode(size_t panel_index) {
void Scoreboard::renderScoreToEnterNameMode(size_t panel_index) { void Scoreboard::renderScoreToEnterNameMode(size_t panel_index) {
// Calcular progreso suavizado de la animación (0.0 a 1.0) // Calcular progreso suavizado de la animación (0.0 a 1.0)
const float t = static_cast<float>(easeInOutSine(text_slide_offset_.at(panel_index))); const auto T = static_cast<float>(easeInOutSine(text_slide_offset_.at(panel_index)));
// Calcular desplazamientos reales entre slots (no son exactamente ROW_SIZE) // Calcular desplazamientos reales entre slots (no son exactamente ROW_SIZE)
const float delta_1_to_2 = slot4_2_.y - slot4_1_.y; // Diferencia real entre ROW1 y ROW2 const float DELTA_1_TO_2 = slot4_2_.y - slot4_1_.y; // Diferencia real entre ROW1 y ROW2
const float delta_2_to_3 = slot4_3_.y - slot4_2_.y; // Diferencia real entre ROW2 y ROW3 const float DELTA_2_TO_3 = slot4_3_.y - slot4_2_.y; // Diferencia real entre ROW2 y ROW3
const float delta_3_to_4 = slot4_4_.y - slot4_3_.y; // Diferencia real entre ROW3 y ROW4 const float DELTA_3_TO_4 = slot4_4_.y - slot4_3_.y; // Diferencia real entre ROW3 y ROW4
// ========== Texto que SALE hacia arriba ========== // ========== Texto que SALE hacia arriba ==========
// name_ (sale desde ROW1 hacia arriba) // name_ (sale desde ROW1 hacia arriba)
text_->writeDX(Text::CENTER | Text::COLOR, slot4_1_.x, slot4_1_.y - t * delta_1_to_2, name_.at(panel_index), 1, text_color1_); text_->writeDX(Text::CENTER | Text::COLOR, slot4_1_.x, slot4_1_.y - (T * DELTA_1_TO_2), name_.at(panel_index), 1, text_color1_);
// ========== Textos que SE MUEVEN hacia arriba ========== // ========== Textos que SE MUEVEN hacia arriba ==========
// score_ (se mueve de ROW2 a ROW1) // score_ (se mueve de ROW2 a ROW1)
text_->writeDX(Text::CENTER | Text::COLOR, slot4_2_.x, slot4_2_.y - t * delta_1_to_2, updateScoreText(score_.at(panel_index)), 1, text_color2_); text_->writeDX(Text::CENTER | Text::COLOR, slot4_2_.x, slot4_2_.y - (T * DELTA_1_TO_2), updateScoreText(score_.at(panel_index)), 1, text_color2_);
// "ENTER NAME" (se mueve de ROW3 a ROW2) // "ENTER NAME" (se mueve de ROW3 a ROW2)
text_->writeDX(Text::CENTER | Text::COLOR, slot4_3_.x, slot4_3_.y - t * delta_2_to_3, Lang::getText("[SCOREBOARD] 11"), 1, text_color1_); text_->writeDX(Text::CENTER | Text::COLOR, slot4_3_.x, slot4_3_.y - (T * DELTA_2_TO_3), Lang::getText("[SCOREBOARD] 11"), 1, text_color1_);
// enter_name_ (se mueve de ROW4 a ROW3) // enter_name_ (se mueve de ROW4 a ROW3)
text_->writeDX(Text::CENTER | Text::COLOR, slot4_4_.x, slot4_4_.y - t * delta_3_to_4, enter_name_.at(panel_index), 1, text_color2_); text_->writeDX(Text::CENTER | Text::COLOR, slot4_4_.x, slot4_4_.y - (T * DELTA_3_TO_4), enter_name_.at(panel_index), 1, text_color2_);
// ========== Elemento que ENTRA desde abajo ========== // ========== Elemento que ENTRA desde abajo ==========
// CARRUSEL (entra desde debajo de ROW4 hacia ROW4) // CARRUSEL (entra desde debajo de ROW4 hacia ROW4)
renderCarousel(panel_index, slot4_4_.x, static_cast<int>(slot4_4_.y + delta_3_to_4 - t * delta_3_to_4)); renderCarousel(panel_index, slot4_4_.x, static_cast<int>(slot4_4_.y + DELTA_3_TO_4 - (T * DELTA_3_TO_4)));
} }
void Scoreboard::renderEnterNameMode(size_t panel_index) { void Scoreboard::renderEnterNameMode(size_t panel_index) {
@@ -491,31 +491,31 @@ void Scoreboard::renderEnterNameMode(size_t panel_index) {
void Scoreboard::renderEnterToShowNameMode(size_t panel_index) { void Scoreboard::renderEnterToShowNameMode(size_t panel_index) {
// Calcular progreso suavizado de la animación (0.0 a 1.0) // Calcular progreso suavizado de la animación (0.0 a 1.0)
const float t = static_cast<float>(easeInOutSine(text_slide_offset_.at(panel_index))); const auto T = static_cast<float>(easeInOutSine(text_slide_offset_.at(panel_index)));
// Calcular desplazamientos reales entre slots (no son exactamente ROW_SIZE) // Calcular desplazamientos reales entre slots (no son exactamente ROW_SIZE)
const float delta_1_to_2 = slot4_2_.y - slot4_1_.y; // Diferencia real entre ROW1 y ROW2 const float DELTA_1_TO_2 = slot4_2_.y - slot4_1_.y; // Diferencia real entre ROW1 y ROW2
const float delta_2_to_3 = slot4_3_.y - slot4_2_.y; // Diferencia real entre ROW2 y ROW3 const float DELTA_2_TO_3 = slot4_3_.y - slot4_2_.y; // Diferencia real entre ROW2 y ROW3
const float delta_3_to_4 = slot4_4_.y - slot4_3_.y; // Diferencia real entre ROW3 y ROW4 const float DELTA_3_TO_4 = slot4_4_.y - slot4_3_.y; // Diferencia real entre ROW3 y ROW4
// ========== Texto que ENTRA desde arriba ========== // ========== Texto que ENTRA desde arriba ==========
// name_ (entra desde arriba hacia ROW1) // name_ (entra desde arriba hacia ROW1)
// Debe venir desde donde estaría ROW0, que está a delta_1_to_2 píxeles arriba de ROW1 // Debe venir desde donde estaría ROW0, que está a delta_1_to_2 píxeles arriba de ROW1
text_->writeDX(Text::CENTER | Text::COLOR, slot4_1_.x, slot4_1_.y + t * delta_1_to_2 - delta_1_to_2, name_.at(panel_index), 1, text_color1_); text_->writeDX(Text::CENTER | Text::COLOR, slot4_1_.x, slot4_1_.y + (T * DELTA_1_TO_2) - DELTA_1_TO_2, name_.at(panel_index), 1, text_color1_);
// ========== Textos que SE MUEVEN (renderizar UNA sola vez) ========== // ========== Textos que SE MUEVEN (renderizar UNA sola vez) ==========
// SCORE (se mueve de ROW1 a ROW2) // SCORE (se mueve de ROW1 a ROW2)
text_->writeDX(Text::CENTER | Text::COLOR, slot4_1_.x, slot4_1_.y + t * delta_1_to_2, updateScoreText(score_.at(panel_index)), 1, text_color2_); text_->writeDX(Text::CENTER | Text::COLOR, slot4_1_.x, slot4_1_.y + (T * DELTA_1_TO_2), updateScoreText(score_.at(panel_index)), 1, text_color2_);
// "ENTER NAME" (se mueve de ROW2 a ROW3) // "ENTER NAME" (se mueve de ROW2 a ROW3)
text_->writeDX(Text::CENTER | Text::COLOR, slot4_2_.x, slot4_2_.y + t * delta_2_to_3, Lang::getText("[SCOREBOARD] 11"), 1, text_color1_); text_->writeDX(Text::CENTER | Text::COLOR, slot4_2_.x, slot4_2_.y + (T * DELTA_2_TO_3), Lang::getText("[SCOREBOARD] 11"), 1, text_color1_);
// enter_name_ (se mueve de ROW3 a ROW4) // enter_name_ (se mueve de ROW3 a ROW4)
text_->writeDX(Text::CENTER | Text::COLOR, slot4_3_.x, slot4_3_.y + t * delta_3_to_4, enter_name_.at(panel_index), 1, text_color2_); text_->writeDX(Text::CENTER | Text::COLOR, slot4_3_.x, slot4_3_.y + (T * DELTA_3_TO_4), enter_name_.at(panel_index), 1, text_color2_);
// ========== Elemento que SALE hacia abajo ========== // ========== Elemento que SALE hacia abajo ==========
// CARRUSEL (sale desde ROW4 hacia abajo, fuera de pantalla) // CARRUSEL (sale desde ROW4 hacia abajo, fuera de pantalla)
renderCarousel(panel_index, slot4_4_.x, static_cast<int>(slot4_4_.y + t * delta_3_to_4)); renderCarousel(panel_index, slot4_4_.x, static_cast<int>(slot4_4_.y + (T * DELTA_3_TO_4)));
} }
void Scoreboard::renderShowNameMode(size_t panel_index) { void Scoreboard::renderShowNameMode(size_t panel_index) {
@@ -652,7 +652,7 @@ void Scoreboard::renderSeparator() {
void Scoreboard::renderCarousel(size_t panel_index, int center_x, int y) { void Scoreboard::renderCarousel(size_t panel_index, int center_x, int y) {
// Obtener referencia a EnterName // Obtener referencia a EnterName
EnterName* enter_name = enter_name_ref_.at(panel_index); EnterName* enter_name = enter_name_ref_.at(panel_index);
if (!enter_name) { if (enter_name == nullptr) {
return; return;
} }
@@ -669,7 +669,7 @@ void Scoreboard::renderCarousel(size_t panel_index, int center_x, int y) {
constexpr int HALF_VISIBLE = CAROUSEL_VISIBLE_LETTERS / 2; // 4 constexpr int HALF_VISIBLE = CAROUSEL_VISIBLE_LETTERS / 2; // 4
// Posición flotante actual del carrusel (índice en character_list_) // Posición flotante actual del carrusel (índice en character_list_)
const float carousel_pos = carousel_position_.at(panel_index); const float CAROUSEL_POS = carousel_position_.at(panel_index);
// Calcular ancho promedio de una letra (asumimos ancho uniforme) // Calcular ancho promedio de una letra (asumimos ancho uniforme)
std::string sample_char(1, char_list[0]); std::string sample_char(1, char_list[0]);
@@ -677,58 +677,58 @@ void Scoreboard::renderCarousel(size_t panel_index, int center_x, int y) {
const int CHAR_STEP = AVG_CHAR_WIDTH + EXTRA_SPACING; const int CHAR_STEP = AVG_CHAR_WIDTH + EXTRA_SPACING;
// Calcular offset de píxeles basado en la parte fraccionaria de carousel_pos // Calcular offset de píxeles basado en la parte fraccionaria de carousel_pos
const float fractional_offset = carousel_pos - std::floor(carousel_pos); const float FRACTIONAL_OFFSET = CAROUSEL_POS - std::floor(CAROUSEL_POS);
const int pixel_offset = static_cast<int>(fractional_offset * CHAR_STEP); const int PIXEL_OFFSET = static_cast<int>(FRACTIONAL_OFFSET * CHAR_STEP);
// Índice base en character_list_ (centro del carrusel) // Índice base en character_list_ (centro del carrusel)
const int base_index = static_cast<int>(std::floor(carousel_pos)); const int BASE_INDEX = static_cast<int>(std::floor(CAROUSEL_POS));
const int char_list_size = static_cast<int>(char_list.size()); const int CHAR_LIST_SIZE = static_cast<int>(char_list.size());
// Calcular posición X inicial (centrar el conjunto de 9 letras) // Calcular posición X inicial (centrar el conjunto de 9 letras)
int start_x = center_x - (HALF_VISIBLE * CHAR_STEP) - (AVG_CHAR_WIDTH / 2) - pixel_offset; int start_x = center_x - (HALF_VISIBLE * CHAR_STEP) - (AVG_CHAR_WIDTH / 2) - PIXEL_OFFSET;
// Renderizar las 9 letras visibles // Renderizar las 9 letras visibles
for (int i = -HALF_VISIBLE; i <= HALF_VISIBLE; ++i) { for (int i = -HALF_VISIBLE; i <= HALF_VISIBLE; ++i) {
// Índice real en character_list_ (con wrap-around circular) // Índice real en character_list_ (con wrap-around circular)
int char_index = base_index + i; int char_index = BASE_INDEX + i;
// Wrap-around circular // Wrap-around circular
char_index = char_index % char_list_size; char_index = char_index % CHAR_LIST_SIZE;
if (char_index < 0) { if (char_index < 0) {
char_index += char_list_size; char_index += CHAR_LIST_SIZE;
} }
// Obtener el carácter directamente de character_list_ // Obtener el carácter directamente de character_list_
std::string single_char(1, char_list[char_index]); std::string single_char(1, char_list[char_index]);
// Calcular distancia flotante al centro visual basada en posición real del carácter // Calcular distancia flotante al centro visual basada en posición real del carácter
float distance_from_center = std::abs(static_cast<float>(char_index) - carousel_pos); float distance_from_center = std::abs(static_cast<float>(char_index) - CAROUSEL_POS);
// Manejar wrap-around circular: elegir el camino más corto // Manejar wrap-around circular: elegir el camino más corto
if (distance_from_center > static_cast<float>(char_list_size) / 2.0f) { if (distance_from_center > static_cast<float>(CHAR_LIST_SIZE) / 2.0F) {
distance_from_center = static_cast<float>(char_list_size) - distance_from_center; distance_from_center = static_cast<float>(CHAR_LIST_SIZE) - distance_from_center;
} }
// Calcular color con LERP dinámico continuo // Calcular color con LERP dinámico continuo
Color letter_color; Color letter_color;
if (distance_from_center < 0.5f) { if (distance_from_center < 0.5F) {
// Letra cerca del centro: LERP hacia animated_color_ // Letra cerca del centro: LERP hacia animated_color_
// distance_from_center va de 0.0 (centro exacto) a 0.5 (borde) // distance_from_center va de 0.0 (centro exacto) a 0.5 (borde)
float lerp_to_animated = distance_from_center / 0.5f; // 0.0 a 1.0 float lerp_to_animated = distance_from_center / 0.5F; // 0.0 a 1.0
letter_color = animated_color_.LERP(text_color1_, lerp_to_animated); letter_color = animated_color_.LERP(text_color1_, lerp_to_animated);
} else { } else {
// Letras alejadas: LERP hacia color_ (fade out) // Letras alejadas: LERP hacia color_ (fade out)
float base_lerp = (distance_from_center - 0.5f) / (HALF_VISIBLE - 0.5f); float base_lerp = (distance_from_center - 0.5F) / (HALF_VISIBLE - 0.5F);
base_lerp = std::min(base_lerp, 1.0f); base_lerp = std::min(base_lerp, 1.0F);
const float LERP_FACTOR = base_lerp * 0.85f; const float LERP_FACTOR = base_lerp * 0.85F;
letter_color = text_color1_.LERP(color_, LERP_FACTOR); letter_color = text_color1_.LERP(color_, LERP_FACTOR);
} }
// Calcular posición X de esta letra // Calcular posición X de esta letra
const int letter_x = start_x + (i + HALF_VISIBLE) * CHAR_STEP; const int LETTER_X = start_x + ((i + HALF_VISIBLE) * CHAR_STEP);
// Pintar la letra // Pintar la letra
text_->writeDX(Text::COLOR, letter_x, y, single_char, 1, letter_color); text_->writeDX(Text::COLOR, LETTER_X, y, single_char, 1, letter_color);
} }
} }

View File

@@ -55,8 +55,8 @@ class Scoreboard {
static auto get() -> Scoreboard*; // Obtiene el puntero al objeto Scoreboard static auto get() -> Scoreboard*; // Obtiene el puntero al objeto Scoreboard
// --- Métodos principales --- // --- Métodos principales ---
void update(float deltaTime); // Actualiza la lógica del marcador void update(float delta_time); // Actualiza la lógica del marcador
void render(); // Pinta el marcador void render(); // Pinta el marcador
// --- Setters --- // --- Setters ---
void setColor(Color color); // Establece el color del marcador void setColor(Color color); // Establece el color del marcador
@@ -113,7 +113,7 @@ class Scoreboard {
// --- Constantes --- // --- Constantes ---
static constexpr int CAROUSEL_VISIBLE_LETTERS = 9; static constexpr int CAROUSEL_VISIBLE_LETTERS = 9;
static constexpr float TEXT_SLIDE_DURATION = 0.3f; // Duración de la animación de deslizamiento en segundos static constexpr float TEXT_SLIDE_DURATION = 0.3F; // Duración de la animación de deslizamiento en segundos
// --- Variables de aspecto --- // --- Variables de aspecto ---
Color text_color1_, text_color2_; // Colores para los marcadores del texto; Color text_color1_, text_color2_; // Colores para los marcadores del texto;
@@ -131,8 +131,8 @@ class Scoreboard {
void fillBackgroundTexture(); // Rellena la textura de fondo void fillBackgroundTexture(); // Rellena la textura de fondo
void updateTimeCounter(); // Actualiza el contador void updateTimeCounter(); // Actualiza el contador
void updateNameColorIndex(); // Actualiza el índice del color animado del nombre void updateNameColorIndex(); // Actualiza el índice del color animado del nombre
void updateCarouselAnimation(float deltaTime); // Actualiza la animación del carrusel void updateCarouselAnimation(float delta_time); // Actualiza la animación del carrusel
void updateTextSlideAnimation(float deltaTime); // Actualiza la animación de deslizamiento de texto void updateTextSlideAnimation(float delta_time); // Actualiza la animación de deslizamiento de texto
void renderSeparator(); // Dibuja la línea que separa la zona de juego del marcador void renderSeparator(); // Dibuja la línea que separa la zona de juego del marcador
void renderPanelContent(size_t panel_index); void renderPanelContent(size_t panel_index);
void renderScoreMode(size_t panel_index); void renderScoreMode(size_t panel_index);

View File

@@ -1,24 +1,23 @@
#include "screen.hpp" #include "screen.hpp"
#include <SDL3/SDL.h> // Para SDL_SetRenderTarget, SDL_LogCategory, SDL_LogInfo, SDL_RenderTexture, SDL_SetRenderDrawColor, SDL_SetRenderVSync, SDL_GetError, SDL_LogError, SDL_RendererLogicalPresentation, SDL_SetRenderLogicalPresentation, SDL_CreateTexture, SDL_DestroyTexture, SDL_DestroyWindow, SDL_GetTicks, SDL_Quit, SDL_RENDERER_VSYNC_DISABLED, SDL_RenderClear, SDL_CreateRenderer, SDL_CreateWindow, SDL_DestroyRenderer, SDL_DisplayID, SDL_FRect, SDL_GetCurrentDisplayMode, SDL_GetDisplayName, SDL_GetDisplays, SDL_GetRenderTarget, SDL_GetWindowPosition, SDL_GetWindowSize, SDL_Init, SDL_LogWarn, SDL_PixelFormat, SDL_RenderFillRect, SDL_RenderPresent, SDL_SetHint, SDL_SetRenderDrawBlendMode, SDL_SetTextureScaleMode, SDL_SetWindowFullscreen, SDL_SetWindowPosition, SDL_SetWindowSize, SDL_TextureAccess, SDL_free, SDL_BLENDMODE_BLEND, SDL_HINT_RENDER_DRIVER, SDL_INIT_VIDEO, SDL_PRIu32, SDL_ScaleMode, SDL_WINDOW_FULLSCREEN, SDL_WINDOW_OPENGL, SDL_WindowFlags #include <SDL3/SDL.h> // Para SDL_SetRenderTarget, SDL_RenderTexture, SDL_SetRenderDrawColor, SDL_SetRenderVSync, SDL_LogCategory, SDL_GetError, SDL_LogError, SDL_LogInfo, SDL_RendererLogicalPresentation, SDL_SetRenderLogicalPresentation, SDL_CreateTexture, SDL_DestroyTexture, SDL_DestroyWindow, SDL_GetDisplayName, SDL_GetTicks, SDL_Quit, SDL_RENDERER_VSYNC_DISABLED, SDL_RenderClear, SDL_CreateRenderer, SDL_CreateWindow, SDL_DestroyRenderer, SDL_DisplayID, SDL_FRect, SDL_GetCurrentDisplayMode, SDL_GetDisplays, SDL_GetRenderTarget, SDL_GetWindowPosition, SDL_GetWindowSize, SDL_Init, SDL_LogWarn, SDL_PixelFormat, SDL_RenderFillRect, SDL_RenderPresent, SDL_SetHint, SDL_SetRenderDrawBlendMode, SDL_SetTextureScaleMode, SDL_SetWindowFullscreen, SDL_SetWindowPosition, SDL_SetWindowSize, SDL_TextureAccess, SDL_free, SDL_BLENDMODE_BLEND, SDL_HINT_RENDER_DRIVER, SDL_INIT_VIDEO, SDL_ScaleMode, SDL_WINDOW_FULLSCREEN, SDL_WINDOW_OPENGL, SDL_WindowFlags
#include <algorithm> // Para min, max #include <algorithm> // Para min, max
#include <fstream> // Para basic_ifstream, ifstream #include <memory> // Para allocator, shared_ptr, unique_ptr, __shared_ptr_access, make_shared, make_unique
#include <iterator> // Para istreambuf_iterator, operator== #include <string> // Para basic_string, operator+, char_traits, to_string, string
#include <memory> // Para allocator, shared_ptr, make_shared, __shared_ptr_access #include <vector> // Para vector
#include <string> // Para operator+, char_traits, to_string, string
#include "asset.hpp" // Para Asset #include "asset.hpp" // Para Asset
#include "mouse.hpp" // Para updateCursorVisibility #include "mouse.hpp" // Para updateCursorVisibility
#include "options.hpp" // Para VideoOptions, video, WindowOptions, window #include "options.hpp" // Para Video, video, Window, window
#include "param.hpp" // Para Param, param, ParamGame, ParamDebug #include "param.hpp" // Para Param, param, ParamGame, ParamDebug
#include "rendering/opengl/opengl_shader.hpp" // Para OpenGLShader #include "rendering/opengl/opengl_shader.hpp" // Para OpenGLShader
#include "text.hpp" // Para Text, Text::COLOR, Text::STROKE #include "shader_backend.hpp" // Para ShaderBackend
#include "text.hpp" // Para Text
#include "texture.hpp" // Para Texture #include "texture.hpp" // Para Texture
#include "ui/logger.hpp" // Para Logger #include "ui/logger.hpp" // Para info
#include "ui/notifier.hpp" // Para Notifier #include "ui/notifier.hpp" // Para Notifier
#include "ui/service_menu.hpp" // Para ServiceMenu #include "ui/service_menu.hpp" // Para ServiceMenu
#include "utils.hpp" // Para Zone
// Singleton // Singleton
Screen* Screen::instance = nullptr; Screen* Screen::instance = nullptr;
@@ -232,13 +231,13 @@ void Screen::loadShaders() {
if (vertex_shader_source_.empty()) { if (vertex_shader_source_.empty()) {
// Detectar si necesitamos OpenGL ES (Raspberry Pi) // Detectar si necesitamos OpenGL ES (Raspberry Pi)
// Intentar cargar versión ES primero si existe // Intentar cargar versión ES primero si existe
std::string VERTEX_FILE = "crtpi_vertex_es.glsl"; std::string vertex_file = "crtpi_vertex_es.glsl";
auto data = Asset::get()->loadData(VERTEX_FILE); auto data = Asset::get()->loadData(vertex_file);
if (data.empty()) { if (data.empty()) {
// Si no existe versión ES, usar versión Desktop // Si no existe versión ES, usar versión Desktop
VERTEX_FILE = "crtpi_vertex.glsl"; vertex_file = "crtpi_vertex.glsl";
data = Asset::get()->loadData(VERTEX_FILE); data = Asset::get()->loadData(vertex_file);
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
"Usando shaders OpenGL Desktop 3.3"); "Usando shaders OpenGL Desktop 3.3");
} else { } else {
@@ -252,13 +251,13 @@ void Screen::loadShaders() {
} }
if (fragment_shader_source_.empty()) { if (fragment_shader_source_.empty()) {
// Intentar cargar versión ES primero si existe // Intentar cargar versión ES primero si existe
std::string FRAGMENT_FILE = "crtpi_fragment_es.glsl"; std::string fragment_file = "crtpi_fragment_es.glsl";
auto data = Asset::get()->loadData(FRAGMENT_FILE); auto data = Asset::get()->loadData(fragment_file);
if (data.empty()) { if (data.empty()) {
// Si no existe versión ES, usar versión Desktop // Si no existe versión ES, usar versión Desktop
FRAGMENT_FILE = "crtpi_fragment.glsl"; fragment_file = "crtpi_fragment.glsl";
data = Asset::get()->loadData(FRAGMENT_FILE); data = Asset::get()->loadData(fragment_file);
} }
if (!data.empty()) { if (!data.empty()) {
@@ -450,8 +449,6 @@ void Screen::getDisplayInfo() {
// SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Window resolution: %dx%d x%d", static_cast<int>(param.game.width), static_cast<int>(param.game.height), Options::window.zoom); // SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Window resolution: %dx%d x%d", static_cast<int>(param.game.width), static_cast<int>(param.game.height), Options::window.zoom);
Logger::info("Window resolution: " + std::to_string(static_cast<int>(param.game.width)) + "x" + std::to_string(static_cast<int>(param.game.height)) + "x" + std::to_string(Options::window.zoom)); Logger::info("Window resolution: " + std::to_string(static_cast<int>(param.game.width)) + "x" + std::to_string(static_cast<int>(param.game.height)) + "x" + std::to_string(Options::window.zoom));
// Calcula el máximo factor de zoom que se puede aplicar a la pantalla // Calcula el máximo factor de zoom que se puede aplicar a la pantalla
const int MAX_ZOOM = std::min(dm->w / param.game.width, (dm->h - WINDOWS_DECORATIONS) / param.game.height); const int MAX_ZOOM = std::min(dm->w / param.game.width, (dm->h - WINDOWS_DECORATIONS) / param.game.height);

View File

@@ -43,8 +43,8 @@ class Screen {
void initShaders(); // Inicializa los shaders void initShaders(); // Inicializa los shaders
// --- Efectos visuales --- // --- Efectos visuales ---
void shake(int desp = 2, float delay_s = 0.05f, float duration_s = 0.133f) { shake_effect_.enable(src_rect_, dst_rect_, desp, delay_s, duration_s); } // Agita la pantalla (tiempo en segundos) void shake(int desp = 2, float delay_s = 0.05F, float duration_s = 0.133F) { shake_effect_.enable(src_rect_, dst_rect_, desp, delay_s, duration_s); } // Agita la pantalla (tiempo en segundos)
void flash(Color color, float duration_s = 0.167f, float delay_s = 0.0f) { flash_effect_ = FlashEffect(true, duration_s, delay_s, color); } // Pone la pantalla de color (tiempo en segundos) void flash(Color color, float duration_s = 0.167F, float delay_s = 0.0F) { flash_effect_ = FlashEffect(true, duration_s, delay_s, color); } // Pone la pantalla de color (tiempo en segundos)
void toggleShaders(); // Alterna entre activar y desactivar los shaders void toggleShaders(); // Alterna entre activar y desactivar los shaders
void toggleIntegerScale(); // Alterna entre activar y desactivar el escalado entero void toggleIntegerScale(); // Alterna entre activar y desactivar el escalado entero
void toggleVSync(); // Alterna entre activar y desactivar el V-Sync void toggleVSync(); // Alterna entre activar y desactivar el V-Sync
@@ -107,7 +107,7 @@ class Screen {
float timer_s; // Timer en segundos (contador decreciente) float timer_s; // Timer en segundos (contador decreciente)
Color color; // Color del flash Color color; // Color del flash
explicit FlashEffect(bool enabled = false, float duration_s = 0.0f, float delay_s = 0.0f, Color color = Color(0xFF, 0xFF, 0xFF)) explicit FlashEffect(bool enabled = false, float duration_s = 0.0F, float delay_s = 0.0F, Color color = Color(0xFF, 0xFF, 0xFF))
: enabled(enabled), : enabled(enabled),
duration_s(duration_s), duration_s(duration_s),
delay_s(delay_s), delay_s(delay_s),
@@ -115,9 +115,9 @@ class Screen {
color(color) {} color(color) {}
void update(float delta_time) { void update(float delta_time) {
if (enabled && timer_s > 0.0f) { if (enabled && timer_s > 0.0F) {
timer_s -= delta_time; timer_s -= delta_time;
if (timer_s <= 0.0f) { if (timer_s <= 0.0F) {
enabled = false; enabled = false;
} }
} }
@@ -136,7 +136,7 @@ class Screen {
int original_width; // Ancho original de la imagen int original_width; // Ancho original de la imagen
bool enabled; // Indica si el efecto está activo bool enabled; // Indica si el efecto está activo
explicit ShakeEffect(bool en = false, int dp = 2, float dl_s = 0.05f, float cnt_s = 0.0f, float len_s = 0.133f, float rem_s = 0.0f, int orig_pos = 0, int orig_width = 800) explicit ShakeEffect(bool en = false, int dp = 2, float dl_s = 0.05F, float cnt_s = 0.0F, float len_s = 0.133F, float rem_s = 0.0F, int orig_pos = 0, int orig_width = 800)
: desp(dp), : desp(dp),
delay_s(dl_s), delay_s(dl_s),
counter_s(cnt_s), counter_s(cnt_s),
@@ -147,7 +147,7 @@ class Screen {
enabled(en) {} enabled(en) {}
// Activa el efecto de sacudida y guarda la posición y tamaño originales // Activa el efecto de sacudida y guarda la posición y tamaño originales
void enable(SDL_FRect& src_rect, SDL_FRect& dst_rect, int new_desp = -1, float new_delay_s = -1.0f, float new_duration_s = -1.0f) { void enable(SDL_FRect& src_rect, SDL_FRect& dst_rect, int new_desp = -1, float new_delay_s = -1.0F, float new_duration_s = -1.0F) {
if (!enabled) { if (!enabled) {
enabled = true; enabled = true;
original_pos = src_rect.x; original_pos = src_rect.x;
@@ -157,10 +157,10 @@ class Screen {
if (new_desp != -1) { if (new_desp != -1) {
desp = new_desp; desp = new_desp;
} }
if (new_delay_s >= 0.0f) { if (new_delay_s >= 0.0F) {
delay_s = new_delay_s; delay_s = new_delay_s;
} }
if (new_duration_s >= 0.0f) { if (new_duration_s >= 0.0F) {
duration_s = new_duration_s; duration_s = new_duration_s;
} }
@@ -175,17 +175,17 @@ class Screen {
void update(SDL_FRect& src_rect, SDL_FRect& dst_rect, float delta_time) { void update(SDL_FRect& src_rect, SDL_FRect& dst_rect, float delta_time) {
if (enabled) { if (enabled) {
counter_s -= delta_time; counter_s -= delta_time;
if (counter_s <= 0.0f) { if (counter_s <= 0.0F) {
counter_s = delay_s; counter_s = delay_s;
// Alternar desplazamiento basado en tiempo restante // Alternar desplazamiento basado en tiempo restante
const bool SHAKE_LEFT = static_cast<int>(remaining_s * 30.0f) % 2 == 0; // ~30 cambios por segundo const bool SHAKE_LEFT = static_cast<int>(remaining_s * 30.0F) % 2 == 0; // ~30 cambios por segundo
const auto SRC_DESP = SHAKE_LEFT ? 0 : desp; const auto SRC_DESP = SHAKE_LEFT ? 0 : desp;
const auto DST_DESP = SHAKE_LEFT ? desp : 0; const auto DST_DESP = SHAKE_LEFT ? desp : 0;
src_rect.x = original_pos + SRC_DESP; src_rect.x = original_pos + SRC_DESP;
dst_rect.x = original_pos + DST_DESP; dst_rect.x = original_pos + DST_DESP;
remaining_s -= delay_s; remaining_s -= delay_s;
if (remaining_s <= 0.0f) { if (remaining_s <= 0.0F) {
enabled = false; enabled = false;
src_rect.x = original_pos; src_rect.x = original_pos;
src_rect.w = original_width; src_rect.w = original_width;

View File

@@ -1,10 +1,11 @@
// IWYU pragma: no_include <bits/std_abs.h> // IWYU pragma: no_include <bits/std_abs.h>
#include "credits.hpp" #include "credits.hpp"
#include <SDL3/SDL.h> // Para SDL_RenderFillRect, SDL_RenderTexture, SDL_SetRenderTarget, SDL_SetRenderDrawColor, SDL_CreateTexture, SDL_DestroyTexture, SDL_GetTicks, SDL_GetRenderTarget, SDL_PixelFormat, SDL_PollEvent, SDL_RenderClear, SDL_RenderRect, SDL_SetTextureBlendMode, SDL_TextureAccess, SDL_BLENDMODE_BLEND, SDL_Event #include <SDL3/SDL.h> // Para SDL_RenderFillRect, SDL_RenderTexture, SDL_SetRenderTarget, SDL_SetRenderDrawColor, SDL_CreateTexture, SDL_DestroyTexture, SDL_GetTicks, SDL_GetRenderTarget, SDL_PixelFormat, SDL_PollEvent, SDL_RenderClear, SDL_RenderRect, SDL_SetTextureBlendMode, SDL_TextureAccess, SDL_BLENDMODE_BLEND, SDL_Event, Uint64
#include <algorithm> // Para max, min, clamp #include <algorithm> // Para max, min, clamp
#include <array> // Para array #include <array> // Para array
#include <cmath> // Para abs
#include <stdexcept> // Para runtime_error #include <stdexcept> // Para runtime_error
#include <string> // Para basic_string, string #include <string> // Para basic_string, string
#include <string_view> // Para string_view #include <string_view> // Para string_view
@@ -12,23 +13,23 @@
#include "audio.hpp" // Para Audio #include "audio.hpp" // Para Audio
#include "balloon_manager.hpp" // Para BalloonManager #include "balloon_manager.hpp" // Para BalloonManager
#include "color.hpp" // Para Zone, Colors::SHADOW_TEXT, Colors::NO_COLOR_MOD, Color #include "color.hpp" // Para Color, SHADOW_TEXT, NO_COLOR_MOD
#include "fade.hpp" // Para Fade, FadeType, FadeMode #include "fade.hpp" // Para Fade
#include "global_events.hpp" // Para check #include "global_events.hpp" // Para handle
#include "global_inputs.hpp" // Para check #include "global_inputs.hpp" // Para check
#include "input.hpp" // Para Input, Input::ALLOW_REPEAT #include "input.hpp" // Para Input
#include "lang.hpp" // Para getText #include "lang.hpp" // Para getText
#include "param.hpp" // Para Param, param, ParamGame, ParamFade #include "param.hpp" // Para Param, param, ParamGame, ParamFade
#include "player.hpp" // Para Player, PlayerState #include "player.hpp" // Para Player
#include "resource.hpp" // Para Resource #include "resource.hpp" // Para Resource
#include "screen.hpp" // Para Screen #include "screen.hpp" // Para Screen
#include "section.hpp" // Para Name, name #include "section.hpp" // Para Name, name
#include "sprite.hpp" // Para Sprite #include "sprite.hpp" // Para Sprite
#include "text.hpp" // Para Text, Text::CENTER, Text::SHADOW #include "text.hpp" // Para Text
#include "texture.hpp" // Para Texture #include "texture.hpp" // Para Texture
#include "tiled_bg.hpp" // Para TiledBG, TiledBGMode #include "tiled_bg.hpp" // Para TiledBG, TiledBGMode
#include "ui/service_menu.hpp" // Para ServiceMenu #include "ui/service_menu.hpp" // Para ServiceMenu
#include "utils.hpp" #include "utils.hpp" // Para Zone
// Textos // Textos
constexpr std::string_view TEXT_COPYRIGHT = "@2020,2025 JailDesigner"; constexpr std::string_view TEXT_COPYRIGHT = "@2020,2025 JailDesigner";
@@ -81,10 +82,10 @@ Credits::~Credits() {
// Calcula el deltatime // Calcula el deltatime
auto Credits::calculateDeltaTime() -> float { auto Credits::calculateDeltaTime() -> float {
const Uint64 current_time = SDL_GetTicks(); const Uint64 CURRENT_TIME = SDL_GetTicks();
const float delta_time = static_cast<float>(current_time - last_time_) / 1000.0f; // Convertir ms a segundos const float DELTA_TIME = static_cast<float>(CURRENT_TIME - last_time_) / 1000.0F; // Convertir ms a segundos
last_time_ = current_time; last_time_ = CURRENT_TIME;
return delta_time; return DELTA_TIME;
} }
// Bucle principal // Bucle principal
@@ -93,33 +94,33 @@ void Credits::run() {
while (Section::name == Section::Name::CREDITS) { while (Section::name == Section::Name::CREDITS) {
checkInput(); checkInput();
const float delta_time = calculateDeltaTime(); const float DELTA_TIME = calculateDeltaTime();
update(delta_time); update(DELTA_TIME);
checkEvents(); // Tiene que ir antes del render checkEvents(); // Tiene que ir antes del render
render(); render();
} }
} }
// Actualiza las variables (time-based) // Actualiza las variables (time-based)
void Credits::update(float deltaTime) { void Credits::update(float delta_time) {
const float multiplier = want_to_pass_ ? 4.0f : 1.0f; const float MULTIPLIER = want_to_pass_ ? 4.0F : 1.0F;
const float adjusted_delta_time = deltaTime * multiplier; const float ADJUSTED_DELTA_TIME = delta_time * MULTIPLIER;
static auto* const SCREEN = Screen::get(); static auto* const SCREEN = Screen::get();
SCREEN->update(deltaTime); // Actualiza el objeto screen SCREEN->update(delta_time); // Actualiza el objeto screen
Audio::update(); // Actualiza el objeto audio Audio::update(); // Actualiza el objeto audio
tiled_bg_->update(adjusted_delta_time); tiled_bg_->update(ADJUSTED_DELTA_TIME);
cycleColors(); cycleColors();
balloon_manager_->update(adjusted_delta_time); balloon_manager_->update(ADJUSTED_DELTA_TIME);
updateTextureDstRects(adjusted_delta_time); updateTextureDstRects(ADJUSTED_DELTA_TIME);
throwBalloons(adjusted_delta_time); throwBalloons(ADJUSTED_DELTA_TIME);
updatePlayers(adjusted_delta_time); updatePlayers(ADJUSTED_DELTA_TIME);
updateAllFades(adjusted_delta_time); updateAllFades(ADJUSTED_DELTA_TIME);
// Convertir deltaTime a equivalente de frames (60fps) // Convertir deltaTime a equivalente de frames (60fps)
const float frameFactor = adjusted_delta_time * 60.0f; const float FRAME_FACTOR = ADJUSTED_DELTA_TIME * 60.0F;
counter_ += frameFactor; counter_ += FRAME_FACTOR;
fillCanvas(); fillCanvas();
} }
@@ -291,9 +292,9 @@ void Credits::fillCanvas() {
} }
// Actualiza el destino de los rectangulos de las texturas (time-based) // Actualiza el destino de los rectangulos de las texturas (time-based)
void Credits::updateTextureDstRects(float deltaTime) { void Credits::updateTextureDstRects(float delta_time) {
constexpr float TEXTURE_UPDATE_INTERVAL_S = 10.0f / 60.0f; // ~0.167s (cada 10 frames) constexpr float TEXTURE_UPDATE_INTERVAL_S = 10.0F / 60.0F; // ~0.167s (cada 10 frames)
credits_state_.texture_accumulator += deltaTime; credits_state_.texture_accumulator += delta_time;
if (credits_state_.texture_accumulator >= TEXTURE_UPDATE_INTERVAL_S) { if (credits_state_.texture_accumulator >= TEXTURE_UPDATE_INTERVAL_S) {
credits_state_.texture_accumulator -= TEXTURE_UPDATE_INTERVAL_S; credits_state_.texture_accumulator -= TEXTURE_UPDATE_INTERVAL_S;
@@ -325,18 +326,18 @@ void Credits::updateTextureDstRects(float deltaTime) {
} }
// Tira globos al escenario (time-based) // Tira globos al escenario (time-based)
void Credits::throwBalloons(float deltaTime) { void Credits::throwBalloons(float delta_time) {
constexpr int SPEED = 200; constexpr int SPEED = 200;
const std::vector<int> SETS = {0, 63, 25, 67, 17, 75, 13, 50}; const std::vector<int> SETS = {0, 63, 25, 67, 17, 75, 13, 50};
constexpr float BALLOON_INTERVAL_S = SPEED / 60.0f; // ~3.33s (cada 200 frames) constexpr float BALLOON_INTERVAL_S = SPEED / 60.0F; // ~3.33s (cada 200 frames)
constexpr float POWERBALL_INTERVAL_S = (SPEED * 4) / 60.0f; // ~13.33s (cada 800 frames) constexpr float POWERBALL_INTERVAL_S = (SPEED * 4) / 60.0F; // ~13.33s (cada 800 frames)
if (counter_ > ((SETS.size() - 1) * SPEED) * 3) { if (counter_ > ((SETS.size() - 1) * SPEED) * 3) {
return; return;
} }
credits_state_.balloon_accumulator += deltaTime; credits_state_.balloon_accumulator += delta_time;
credits_state_.powerball_accumulator += deltaTime; credits_state_.powerball_accumulator += delta_time;
if (credits_state_.balloon_accumulator >= BALLOON_INTERVAL_S) { if (credits_state_.balloon_accumulator >= BALLOON_INTERVAL_S) {
credits_state_.balloon_accumulator -= BALLOON_INTERVAL_S; credits_state_.balloon_accumulator -= BALLOON_INTERVAL_S;
@@ -418,12 +419,12 @@ void Credits::initPlayers() {
} }
// Actualiza los rectangulos negros (time-based) // Actualiza los rectangulos negros (time-based)
void Credits::updateBlackRects(float deltaTime) { void Credits::updateBlackRects(float delta_time) {
static float current_step_ = static_cast<float>(steps_); static auto current_step_ = static_cast<float>(steps_);
constexpr float BLACK_RECT_INTERVAL_S = 4.0f / 60.0f; // ~0.067s (cada 4 frames) constexpr float BLACK_RECT_INTERVAL_S = 4.0F / 60.0F; // ~0.067s (cada 4 frames)
if (top_black_rect_.h != param.game.game_area.center_y - 1 && bottom_black_rect_.y != param.game.game_area.center_y + 1) { if (top_black_rect_.h != param.game.game_area.center_y - 1 && bottom_black_rect_.y != param.game.game_area.center_y + 1) {
// Si los rectangulos superior e inferior no han llegado al centro // Si los rectangulos superior e inferior no han llegado al centro
credits_state_.black_rect_accumulator += deltaTime; credits_state_.black_rect_accumulator += delta_time;
if (credits_state_.black_rect_accumulator >= BLACK_RECT_INTERVAL_S) { if (credits_state_.black_rect_accumulator >= BLACK_RECT_INTERVAL_S) {
credits_state_.black_rect_accumulator -= BLACK_RECT_INTERVAL_S; credits_state_.black_rect_accumulator -= BLACK_RECT_INTERVAL_S;
@@ -459,8 +460,8 @@ void Credits::updateBlackRects(float deltaTime) {
fade_out_->activate(); fade_out_->activate();
} else { } else {
// Convertir deltaTime a equivalente de frames // Convertir deltaTime a equivalente de frames
const float frameFactor = deltaTime * 60.0f; const float FRAME_FACTOR = delta_time * 60.0F;
counter_pre_fade_ += frameFactor; counter_pre_fade_ += FRAME_FACTOR;
} }
} }
} }
@@ -475,9 +476,9 @@ void Credits::updateRedRect() {
} }
// Actualiza el estado de fade (time-based) // Actualiza el estado de fade (time-based)
void Credits::updateAllFades(float deltaTime) { void Credits::updateAllFades(float delta_time) {
if (fading_) { if (fading_) {
updateBlackRects(deltaTime); updateBlackRects(delta_time);
updateRedRect(); updateRedRect();
} }
@@ -510,7 +511,7 @@ void Credits::cycleColors() {
constexpr int LOWER_LIMIT = 30; // Límite inferior constexpr int LOWER_LIMIT = 30; // Límite inferior
// Inicializar valores RGB si es la primera vez // Inicializar valores RGB si es la primera vez
if (credits_state_.r == 255.0f && credits_state_.g == 0.0f && credits_state_.b == 0.0f && credits_state_.step_r == -0.5f) { if (credits_state_.r == 255.0F && credits_state_.g == 0.0F && credits_state_.b == 0.0F && credits_state_.step_r == -0.5F) {
credits_state_.r = static_cast<float>(UPPER_LIMIT); credits_state_.r = static_cast<float>(UPPER_LIMIT);
credits_state_.g = static_cast<float>(LOWER_LIMIT); credits_state_.g = static_cast<float>(LOWER_LIMIT);
credits_state_.b = static_cast<float>(LOWER_LIMIT); credits_state_.b = static_cast<float>(LOWER_LIMIT);
@@ -540,9 +541,9 @@ void Credits::cycleColors() {
} }
// Actualza los jugadores (time-based) // Actualza los jugadores (time-based)
void Credits::updatePlayers(float deltaTime) { void Credits::updatePlayers(float delta_time) {
for (auto& player : players_) { for (auto& player : players_) {
player->update(deltaTime); player->update(delta_time);
} }
} }

View File

@@ -27,10 +27,9 @@ class Credits {
private: private:
// --- Métodos del bucle principal --- // --- Métodos del bucle principal ---
void update(float deltaTime); // Actualización principal de la lógica (time-based) void update(float delta_time); // Actualización principal de la lógica (time-based)
auto calculateDeltaTime() -> float; // Calcula el deltatime auto calculateDeltaTime() -> float; // Calcula el deltatime
private:
// --- Constantes de clase --- // --- Constantes de clase ---
static constexpr int PLAY_AREA_HEIGHT = 200; static constexpr int PLAY_AREA_HEIGHT = 200;
@@ -67,16 +66,16 @@ class Credits {
// --- Estado de acumuladores para animaciones --- // --- Estado de acumuladores para animaciones ---
struct CreditsState { struct CreditsState {
float texture_accumulator = 0.0f; float texture_accumulator = 0.0F;
float balloon_accumulator = 0.0f; float balloon_accumulator = 0.0F;
float powerball_accumulator = 0.0f; float powerball_accumulator = 0.0F;
float black_rect_accumulator = 0.0f; float black_rect_accumulator = 0.0F;
float r = 255.0f; // UPPER_LIMIT float r = 255.0F; // UPPER_LIMIT
float g = 0.0f; // LOWER_LIMIT float g = 0.0F; // LOWER_LIMIT
float b = 0.0f; // LOWER_LIMIT float b = 0.0F; // LOWER_LIMIT
float step_r = -0.5f; float step_r = -0.5F;
float step_g = 0.3f; float step_g = 0.3F;
float step_b = 0.1f; float step_b = 0.1F;
} credits_state_; } credits_state_;
// --- Rectángulos de renderizado --- // --- Rectángulos de renderizado ---
@@ -130,20 +129,20 @@ class Credits {
void renderPlayers(); // Renderiza los jugadores void renderPlayers(); // Renderiza los jugadores
// --- Métodos de lógica del juego --- // --- Métodos de lógica del juego ---
void throwBalloons(); // Lanzar globos al escenario (frame-based) void throwBalloons(); // Lanzar globos al escenario (frame-based)
void throwBalloons(float deltaTime); // Lanzar globos al escenario (time-based) void throwBalloons(float delta_time); // Lanzar globos al escenario (time-based)
void initPlayers(); // Inicializar jugadores void initPlayers(); // Inicializar jugadores
void updateAllFades(); // Actualizar estados de fade (frame-based) void updateAllFades(); // Actualizar estados de fade (frame-based)
void updateAllFades(float deltaTime); // Actualizar estados de fade (time-based) void updateAllFades(float delta_time); // Actualizar estados de fade (time-based)
void cycleColors(); // Cambiar colores de fondo void cycleColors(); // Cambiar colores de fondo
void updatePlayers(float deltaTime); // Actualza los jugadores (time-based) void updatePlayers(float delta_time); // Actualza los jugadores (time-based)
// --- Métodos de interfaz --- // --- Métodos de interfaz ---
void updateBlackRects(); // Actualizar rectángulos negros (letterbox) (frame-based) void updateBlackRects(); // Actualizar rectángulos negros (letterbox) (frame-based)
void updateBlackRects(float deltaTime); // Actualizar rectángulos negros (letterbox) (time-based) void updateBlackRects(float delta_time); // Actualizar rectángulos negros (letterbox) (time-based)
void updateRedRect(); // Actualizar rectángulo rojo (borde) void updateRedRect(); // Actualizar rectángulo rojo (borde)
void updateTextureDstRects(); // Actualizar destinos de texturas (frame-based) void updateTextureDstRects(); // Actualizar destinos de texturas (frame-based)
void updateTextureDstRects(float deltaTime); // Actualizar destinos de texturas (time-based) void updateTextureDstRects(float delta_time); // Actualizar destinos de texturas (time-based)
// --- Métodos de audio --- // --- Métodos de audio ---
static void setVolume(int amount); // Establecer volumen static void setVolume(int amount); // Establecer volumen

View File

@@ -1,14 +1,16 @@
#include "game.hpp" #include "game.hpp"
#include <SDL3/SDL.h> // Para SDL_GetTicks, SDL_SetRenderTarget, SDL_CreateTexture, SDL_Delay, SDL_DestroyTexture, SDL_EventType, SDL_GetRenderTarget, SDL_PollEvent, SDL_RenderTexture, SDL_SetTextureBlendMode, SDL_BLENDMODE_BLEND, SDL_Event, SDL_PixelFormat, SDL_Point, SDL_TextureAccess #include <SDL3/SDL.h> // Para SDL_GetTicks, SDL_SetRenderTarget, SDL_EventType, SDL_CreateTexture, SDL_Delay, SDL_DestroyTexture, SDL_Event, SDL_GetRenderTarget, SDL_PollEvent, SDL_RenderTexture, SDL_SetTextureBlendMode, SDLK_1, SDLK_2, SDLK_3, SDLK_4, SDLK_5, SDLK_6, SDLK_7, SDLK_8, SDLK_9, SDLK_KP_MINUS, SDLK_KP_PLUS, SDL_BLENDMODE_BLEND, SDL_PixelFormat, SDL_Point, SDL_TextureAccess, Uint64
#include <algorithm> // Para find, clamp, find_if, min, std::shuffle, std::iota #include <algorithm> // Para find, clamp, find_if, min, shuffle
#include <array> // Para array #include <array> // Para array
#include <cstdlib> // Para rand, size_t #include <cstdlib> // Para rand, size_t
#include <functional> // Para function #include <functional> // Para function
#include <iterator> // Para size #include <iterator> // Para size
#include <memory> // Para shared_ptr, unique_ptr, __shared_ptr_access, allocator, make_unique, operator==, make_shared #include <memory> // Para shared_ptr, unique_ptr, __shared_ptr_access, make_unique, allocator, operator==
#include <random> // std::random_device, std::default_random_engine #include <numeric> // Para iota
#include <optional> // Para optional
#include <random> // Para random_device, default_random_engine
#include <utility> // Para move #include <utility> // Para move
#include "asset.hpp" // Para Asset #include "asset.hpp" // Para Asset
@@ -16,12 +18,12 @@
#include "background.hpp" // Para Background #include "background.hpp" // Para Background
#include "balloon.hpp" // Para Balloon #include "balloon.hpp" // Para Balloon
#include "balloon_manager.hpp" // Para BalloonManager #include "balloon_manager.hpp" // Para BalloonManager
#include "bullet.hpp" // Para Bullet, Bullet::Type, BulletMoveStatus #include "bullet.hpp" // Para Bullet
#include "bullet_manager.hpp" // Para BulletManager #include "bullet_manager.hpp" // Para BulletManager
#include "color.hpp" // Para Color, Colors::FLASH #include "color.hpp" // Para Color, FLASH, NO_COLOR_MOD
#include "difficulty.hpp" // Para Code #include "difficulty.hpp" // Para Code
#include "fade.hpp" // Para Fade, FadeType, FadeMode #include "fade.hpp" // Para Fade
#include "global_events.hpp" // Para check #include "global_events.hpp" // Para handle
#include "global_inputs.hpp" // Para check #include "global_inputs.hpp" // Para check
#include "hit.hpp" // Para Hit #include "hit.hpp" // Para Hit
#include "input.hpp" // Para Input #include "input.hpp" // Para Input
@@ -30,7 +32,7 @@
#include "lang.hpp" // Para getText #include "lang.hpp" // Para getText
#include "manage_hiscore_table.hpp" // Para HiScoreEntry, ManageHiScoreTable #include "manage_hiscore_table.hpp" // Para HiScoreEntry, ManageHiScoreTable
#include "param.hpp" // Para Param, param, ParamGame, ParamScoreboard, ParamFade, ParamBalloon #include "param.hpp" // Para Param, param, ParamGame, ParamScoreboard, ParamFade, ParamBalloon
#include "path_sprite.hpp" // Para Path, PathSprite, createPath, PathType #include "path_sprite.hpp" // Para Path, PathSprite, PathType
#include "pause_manager.hpp" // Para PauseManager #include "pause_manager.hpp" // Para PauseManager
#include "player.hpp" // Para Player #include "player.hpp" // Para Player
#include "resource.hpp" // Para Resource #include "resource.hpp" // Para Resource
@@ -38,13 +40,14 @@
#include "screen.hpp" // Para Screen #include "screen.hpp" // Para Screen
#include "section.hpp" // Para Name, name, AttractMode, Options, attract_mode, options #include "section.hpp" // Para Name, name, AttractMode, Options, attract_mode, options
#include "smart_sprite.hpp" // Para SmartSprite #include "smart_sprite.hpp" // Para SmartSprite
#include "stage.hpp" // Para number, Stage, get, total_power, power, init, power_can_be_added, stages #include "stage.hpp" // Para StageManager, StageData
#include "tabe.hpp" // Para Tabe #include "tabe.hpp" // Para Tabe
#include "text.hpp" // Para Text #include "text.hpp" // Para Text
#include "texture.hpp" // Para Texture #include "texture.hpp" // Para Texture
#include "ui/service_menu.hpp" // Para ServiceMenu #include "ui/service_menu.hpp" // Para ServiceMenu
#include "utils.hpp" // Para Zone, checkCollision, easeInQuint, easeOutQuint, boolToString
#ifdef _DEBUG #ifdef _DEBUG
#include <iostream> // Para std::cout #include <iostream> // Para basic_ostream, basic_ostream::operator<<, operator<<, cout
#include "ui/notifier.hpp" // Para Notifier #include "ui/notifier.hpp" // Para Notifier
#endif #endif
@@ -240,9 +243,9 @@ void Game::updateHiScore() {
} }
// Actualiza las variables del jugador // Actualiza las variables del jugador
void Game::updatePlayers(float deltaTime) { void Game::updatePlayers(float delta_time) {
for (auto& player : players_) { for (auto& player : players_) {
player->update(deltaTime); player->update(delta_time);
if (player->isPlaying()) { if (player->isPlaying()) {
// Comprueba la colisión entre el jugador y los globos // Comprueba la colisión entre el jugador y los globos
@@ -341,29 +344,29 @@ void Game::updateStage() {
} }
// Actualiza las variables y sistemas durante el estado de fin de partida // Actualiza las variables y sistemas durante el estado de fin de partida
void Game::updateGameStateGameOver(float deltaTime) { void Game::updateGameStateGameOver(float delta_time) {
fade_out_->update(); fade_out_->update();
updatePlayers(deltaTime); updatePlayers(delta_time);
updateScoreboard(deltaTime); updateScoreboard(delta_time);
updateBackground(deltaTime); updateBackground(delta_time);
balloon_manager_->update(deltaTime); balloon_manager_->update(delta_time);
tabe_->update(deltaTime); tabe_->update(delta_time);
bullet_manager_->update(deltaTime); bullet_manager_->update(delta_time);
updateItems(deltaTime); updateItems(delta_time);
updateSmartSprites(deltaTime); updateSmartSprites(delta_time);
updatePathSprites(deltaTime); updatePathSprites(delta_time);
updateTimeStopped(deltaTime); updateTimeStopped(delta_time);
bullet_manager_->checkCollisions(); bullet_manager_->checkCollisions();
cleanVectors(); cleanVectors();
if (game_over_timer_ < GAME_OVER_DURATION_S) { if (game_over_timer_ < GAME_OVER_DURATION_S) {
game_over_timer_ += deltaTime; // Incremento time-based primero game_over_timer_ += delta_time; // Incremento time-based primero
handleGameOverEvents(); // Maneja eventos después del incremento handleGameOverEvents(); // Maneja eventos después del incremento
} }
if (Options::audio.enabled) { if (Options::audio.enabled) {
const float progress = std::min(game_over_timer_ / GAME_OVER_DURATION_S, 1.0f); const float PROGRESS = std::min(game_over_timer_ / GAME_OVER_DURATION_S, 1.0F);
const float VOL = 64.0f * (1.0f - progress); const float VOL = 64.0F * (1.0F - PROGRESS);
Audio::get()->setSoundVolume(static_cast<int>(VOL), Audio::Group::GAME); Audio::get()->setSoundVolume(static_cast<int>(VOL), Audio::Group::GAME);
} }
@@ -378,16 +381,16 @@ void Game::updateGameStateGameOver(float deltaTime) {
} }
// Gestiona eventos para el estado del final del juego // Gestiona eventos para el estado del final del juego
void Game::updateGameStateCompleted(float deltaTime) { void Game::updateGameStateCompleted(float delta_time) {
updatePlayers(deltaTime); updatePlayers(delta_time);
updateScoreboard(deltaTime); updateScoreboard(delta_time);
updateBackground(deltaTime); updateBackground(delta_time);
balloon_manager_->update(deltaTime); balloon_manager_->update(delta_time);
tabe_->update(deltaTime); tabe_->update(delta_time);
bullet_manager_->update(deltaTime); bullet_manager_->update(delta_time);
updateItems(deltaTime); updateItems(delta_time);
updateSmartSprites(deltaTime); updateSmartSprites(delta_time);
updatePathSprites(deltaTime); updatePathSprites(delta_time);
cleanVectors(); cleanVectors();
// Maneja eventos del juego completado // Maneja eventos del juego completado
@@ -399,7 +402,7 @@ void Game::updateGameStateCompleted(float deltaTime) {
} }
// Incrementa el acumulador al final // Incrementa el acumulador al final
game_completed_timer_ += deltaTime; game_completed_timer_ += delta_time;
} }
// Comprueba el estado del juego // Comprueba el estado del juego
@@ -589,9 +592,9 @@ void Game::handleItemDrop(const std::shared_ptr<Balloon>& balloon, const std::sh
} }
// Maneja la destrucción del globo y puntuación // Maneja la destrucción del globo y puntuación
void Game::handleBalloonDestruction(std::shared_ptr<Balloon> balloon, const std::shared_ptr<Player>& player) { void Game::handleBalloonDestruction(const std::shared_ptr<Balloon>& balloon, const std::shared_ptr<Player>& player) {
if (player->isPlaying()) { if (player->isPlaying()) {
auto const SCORE = balloon_manager_->popBalloon(std::move(balloon)) * player->getScoreMultiplier() * difficulty_score_multiplier_; auto const SCORE = balloon_manager_->popBalloon(balloon) * player->getScoreMultiplier() * difficulty_score_multiplier_;
player->addScore(SCORE, Options::settings.hi_score_table.back().score); player->addScore(SCORE, Options::settings.hi_score_table.back().score);
player->incScoreMultiplier(); player->incScoreMultiplier();
} }
@@ -600,13 +603,13 @@ void Game::handleBalloonDestruction(std::shared_ptr<Balloon> balloon, const std:
} }
// Actualiza los items // Actualiza los items
void Game::updateItems(float deltaTime) { void Game::updateItems(float delta_time) {
for (auto& item : items_) { for (auto& item : items_) {
if (item->isEnabled()) { if (item->isEnabled()) {
item->update(deltaTime); item->update(delta_time);
if (item->isOnFloor()) { if (item->isOnFloor()) {
playSound("title.wav"); playSound("title.wav");
screen_->shake(1, 0.033f, 0.067f); // desp=1, delay=0.033s, length=0.067s screen_->shake(1, 0.033F, 0.067F); // desp=1, delay=0.033s, length=0.067s
} }
} }
} }
@@ -711,8 +714,8 @@ void Game::createItemText(int x, const std::shared_ptr<Texture>& texture) {
path_sprites_.back()->setWidth(W); path_sprites_.back()->setWidth(W);
path_sprites_.back()->setHeight(H); path_sprites_.back()->setHeight(H);
path_sprites_.back()->setSpriteClip({0, 0, static_cast<float>(W), static_cast<float>(H)}); path_sprites_.back()->setSpriteClip({0, 0, static_cast<float>(W), static_cast<float>(H)});
path_sprites_.back()->addPath(Y0, Y1, PathType::VERTICAL, x, 1.667f, easeOutQuint, 0); // 100 frames → 1.667s path_sprites_.back()->addPath(Y0, Y1, PathType::VERTICAL, x, 1.667F, easeOutQuint, 0); // 100 frames → 1.667s
path_sprites_.back()->addPath(Y1, Y2, PathType::VERTICAL, x, 1.333f, easeInQuint, 0); // 80 frames → 1.333s path_sprites_.back()->addPath(Y1, Y2, PathType::VERTICAL, x, 1.333F, easeInQuint, 0); // 80 frames → 1.333s
path_sprites_.back()->enable(); path_sprites_.back()->enable();
} }
@@ -757,10 +760,10 @@ void Game::throwCoffee(int x, int y) {
smart_sprites_.back()->setPosY(y - 8); smart_sprites_.back()->setPosY(y - 8);
smart_sprites_.back()->setWidth(Item::WIDTH); smart_sprites_.back()->setWidth(Item::WIDTH);
smart_sprites_.back()->setHeight(Item::HEIGHT); smart_sprites_.back()->setHeight(Item::HEIGHT);
smart_sprites_.back()->setVelX((-1.0F + ((rand() % 5) * 0.5F)) * 60.0f); // Convertir a pixels/segundo smart_sprites_.back()->setVelX((-1.0F + ((rand() % 5) * 0.5F)) * 60.0F); // Convertir a pixels/segundo
smart_sprites_.back()->setVelY(-4.0F * 60.0f); // Convertir a pixels/segundo smart_sprites_.back()->setVelY(-4.0F * 60.0F); // Convertir a pixels/segundo
smart_sprites_.back()->setAccelX(0.0F); smart_sprites_.back()->setAccelX(0.0F);
smart_sprites_.back()->setAccelY(0.2F * 60.0f * 60.0f); // Convertir a pixels/segundo² (0.2 × 60²) smart_sprites_.back()->setAccelY(0.2F * 60.0F * 60.0F); // Convertir a pixels/segundo² (0.2 × 60²)
smart_sprites_.back()->setDestX(x + (smart_sprites_.back()->getVelX() * 50)); smart_sprites_.back()->setDestX(x + (smart_sprites_.back()->getVelX() * 50));
smart_sprites_.back()->setDestY(param.game.height + 1); smart_sprites_.back()->setDestY(param.game.height + 1);
smart_sprites_.back()->setEnabled(true); smart_sprites_.back()->setEnabled(true);
@@ -772,9 +775,9 @@ void Game::throwCoffee(int x, int y) {
} }
// Actualiza los SmartSprites // Actualiza los SmartSprites
void Game::updateSmartSprites(float deltaTime) { void Game::updateSmartSprites(float delta_time) {
for (auto& sprite : smart_sprites_) { for (auto& sprite : smart_sprites_) {
sprite->update(deltaTime); sprite->update(delta_time);
} }
} }
@@ -786,9 +789,9 @@ void Game::renderSmartSprites() {
} }
// Actualiza los PathSprites // Actualiza los PathSprites
void Game::updatePathSprites(float deltaTime) { void Game::updatePathSprites(float delta_time) {
for (auto& sprite : path_sprites_) { for (auto& sprite : path_sprites_) {
sprite->update(deltaTime); sprite->update(delta_time);
} }
} }
@@ -831,44 +834,44 @@ void Game::handlePlayerCollision(std::shared_ptr<Player>& player, std::shared_pt
} }
// Actualiza el estado del tiempo detenido // Actualiza el estado del tiempo detenido
void Game::updateTimeStopped(float deltaTime) { void Game::updateTimeStopped(float delta_time) {
static constexpr float WARNING_THRESHOLD_S = 2.0f; // 120 frames a 60fps → segundos static constexpr float WARNING_THRESHOLD_S = 2.0F; // 120 frames a 60fps → segundos
static constexpr float CLOCK_SOUND_INTERVAL_S = 0.5f; // 30 frames a 60fps → segundos static constexpr float CLOCK_SOUND_INTERVAL_S = 0.5F; // 30 frames a 60fps → segundos
static constexpr float COLOR_FLASH_INTERVAL_S = 0.25f; // 15 frames a 60fps → segundos static constexpr float COLOR_FLASH_INTERVAL_S = 0.25F; // 15 frames a 60fps → segundos
if (time_stopped_timer_ > 0) { if (time_stopped_timer_ > 0) {
time_stopped_timer_ -= deltaTime; time_stopped_timer_ -= delta_time;
// Fase de advertencia (últimos 2 segundos) // Fase de advertencia (últimos 2 segundos)
if (time_stopped_timer_ <= WARNING_THRESHOLD_S) { if (time_stopped_timer_ <= WARNING_THRESHOLD_S) {
static float last_sound_time = 0.0f; static float last_sound_time_ = 0.0F;
// CLAC al entrar en fase de advertencia // CLAC al entrar en fase de advertencia
if (!time_stopped_flags_.warning_phase_started) { if (!time_stopped_flags_.warning_phase_started) {
playSound("clock.wav"); playSound("clock.wav");
time_stopped_flags_.warning_phase_started = true; time_stopped_flags_.warning_phase_started = true;
last_sound_time = 0.0f; // Reset para empezar el ciclo rápido last_sound_time_ = 0.0F; // Reset para empezar el ciclo rápido
} }
last_sound_time += deltaTime; last_sound_time_ += delta_time;
if (last_sound_time >= CLOCK_SOUND_INTERVAL_S) { if (last_sound_time_ >= CLOCK_SOUND_INTERVAL_S) {
balloon_manager_->normalColorsToAllBalloons(); balloon_manager_->normalColorsToAllBalloons();
playSound("clock.wav"); playSound("clock.wav");
last_sound_time = 0.0f; last_sound_time_ = 0.0F;
time_stopped_flags_.color_flash_sound_played = false; // Reset flag para el próximo intervalo time_stopped_flags_.color_flash_sound_played = false; // Reset flag para el próximo intervalo
} else if (last_sound_time >= COLOR_FLASH_INTERVAL_S && !time_stopped_flags_.color_flash_sound_played) { } else if (last_sound_time_ >= COLOR_FLASH_INTERVAL_S && !time_stopped_flags_.color_flash_sound_played) {
balloon_manager_->reverseColorsToAllBalloons(); balloon_manager_->reverseColorsToAllBalloons();
playSound("clock.wav"); playSound("clock.wav");
time_stopped_flags_.color_flash_sound_played = true; // Evita que suene múltiples veces time_stopped_flags_.color_flash_sound_played = true; // Evita que suene múltiples veces
} }
} else { } else {
// Fase normal - solo sonido ocasional // Fase normal - solo sonido ocasional
static float sound_timer = 0.0f; static float sound_timer_ = 0.0F;
sound_timer += deltaTime; sound_timer_ += delta_time;
if (sound_timer >= CLOCK_SOUND_INTERVAL_S) { if (sound_timer_ >= CLOCK_SOUND_INTERVAL_S) {
playSound("clock.wav"); playSound("clock.wav");
sound_timer = 0.0f; sound_timer_ = 0.0F;
} }
} }
@@ -881,15 +884,15 @@ void Game::updateTimeStopped(float deltaTime) {
} }
// Actualiza toda la lógica del juego // Actualiza toda la lógica del juego
void Game::update(float deltaTime) { void Game::update(float delta_time) {
screen_->update(deltaTime); // Actualiza el objeto screen screen_->update(delta_time); // Actualiza el objeto screen
Audio::update(); // Actualiza el objeto audio Audio::update(); // Actualiza el objeto audio
updateDemo(deltaTime); updateDemo(delta_time);
#ifdef RECORDING #ifdef RECORDING
updateRecording(deltaTime); updateRecording(deltaTime);
#endif #endif
updateGameStates(deltaTime); updateGameStates(delta_time);
fillCanvas(); fillCanvas();
} }
@@ -909,26 +912,26 @@ void Game::render() {
} }
// Actualiza los estados del juego // Actualiza los estados del juego
void Game::updateGameStates(float deltaTime) { void Game::updateGameStates(float delta_time) {
if (!pause_manager_->isPaused()) { if (!pause_manager_->isPaused()) {
switch (state_) { switch (state_) {
case State::FADE_IN: case State::FADE_IN:
updateGameStateFadeIn(deltaTime); updateGameStateFadeIn(delta_time);
break; break;
case State::ENTERING_PLAYER: case State::ENTERING_PLAYER:
updateGameStateEnteringPlayer(deltaTime); updateGameStateEnteringPlayer(delta_time);
break; break;
case State::SHOWING_GET_READY_MESSAGE: case State::SHOWING_GET_READY_MESSAGE:
updateGameStateShowingGetReadyMessage(deltaTime); updateGameStateShowingGetReadyMessage(delta_time);
break; break;
case State::PLAYING: case State::PLAYING:
updateGameStatePlaying(deltaTime); updateGameStatePlaying(delta_time);
break; break;
case State::COMPLETED: case State::COMPLETED:
updateGameStateCompleted(deltaTime); updateGameStateCompleted(delta_time);
break; break;
case State::GAME_OVER: case State::GAME_OVER:
updateGameStateGameOver(deltaTime); updateGameStateGameOver(delta_time);
break; break;
default: default:
break; break;
@@ -937,8 +940,8 @@ void Game::updateGameStates(float deltaTime) {
} }
// Actualiza el fondo // Actualiza el fondo
void Game::updateBackground(float deltaTime) { void Game::updateBackground(float delta_time) {
background_->update(deltaTime); background_->update(delta_time);
} }
// Dibuja los elementos de la zona de juego en su textura // Dibuja los elementos de la zona de juego en su textura
@@ -980,10 +983,10 @@ void Game::disableTimeStopItem() {
// Calcula el deltatime en segundos // Calcula el deltatime en segundos
auto Game::calculateDeltaTime() -> float { auto Game::calculateDeltaTime() -> float {
const Uint64 current_time = SDL_GetTicks(); const Uint64 CURRENT_TIME = SDL_GetTicks();
const float delta_time_ms = static_cast<float>(current_time - last_time_); const auto DELTA_TIME_MS = static_cast<float>(CURRENT_TIME - last_time_);
last_time_ = current_time; last_time_ = CURRENT_TIME;
return delta_time_ms / 1000.0f; // Convertir de milisegundos a segundos return DELTA_TIME_MS / 1000.0F; // Convertir de milisegundos a segundos
} }
// Bucle para el juego // Bucle para el juego
@@ -991,9 +994,9 @@ void Game::run() {
last_time_ = SDL_GetTicks(); last_time_ = SDL_GetTicks();
while (Section::name == Section::Name::GAME) { while (Section::name == Section::Name::GAME) {
const float delta_time = calculateDeltaTime(); const float DELTA_TIME = calculateDeltaTime();
checkInput(); checkInput();
update(delta_time); update(DELTA_TIME);
handleEvents(); // Tiene que ir antes del render handleEvents(); // Tiene que ir antes del render
render(); render();
} }
@@ -1003,7 +1006,7 @@ void Game::run() {
void Game::initPaths() { void Game::initPaths() {
// --- Duración estándar para 80 frames --- // --- Duración estándar para 80 frames ---
// (Basado en tu ejemplo: 80 frames → 1.333s) // (Basado en tu ejemplo: 80 frames → 1.333s)
const float DURATION_80F_S = 1.333f; const float DURATION_80F_S = 1.333F;
// Recorrido para el texto de "Get Ready!" (0,1) // Recorrido para el texto de "Get Ready!" (0,1)
{ {
@@ -1013,9 +1016,9 @@ void Game::initPaths() {
const int X1 = param.game.play_area.center_x - (W / 2); const int X1 = param.game.play_area.center_x - (W / 2);
const int X2 = param.game.play_area.rect.w; const int X2 = param.game.play_area.rect.w;
// Y_base es la LÍNEA CENTRAL. addPath(true) restará H/2 // Y_base es la LÍNEA CENTRAL. addPath(true) restará H/2
const int Y_base = param.game.play_area.center_y; const int Y_BASE = param.game.play_area.center_y;
paths_.emplace_back(X0, X1, PathType::HORIZONTAL, Y_base, DURATION_80F_S, 0.5f, easeOutQuint); paths_.emplace_back(X0, X1, PathType::HORIZONTAL, Y_BASE, DURATION_80F_S, 0.5F, easeOutQuint);
paths_.emplace_back(X1, X2, PathType::HORIZONTAL, Y_base, DURATION_80F_S, 0.0f, easeInQuint); paths_.emplace_back(X1, X2, PathType::HORIZONTAL, Y_BASE, DURATION_80F_S, 0.0F, easeInQuint);
} }
// Recorrido para el texto de "Last Stage!" o de "X stages left" (2,3) // Recorrido para el texto de "Last Stage!" o de "X stages left" (2,3)
@@ -1026,9 +1029,9 @@ void Game::initPaths() {
const int Y1 = param.game.play_area.center_y - (H / 2); const int Y1 = param.game.play_area.center_y - (H / 2);
const int Y2 = -H; const int Y2 = -H;
// X_base es la LÍNEA CENTRAL. addPath(true) restará W/2 // X_base es la LÍNEA CENTRAL. addPath(true) restará W/2
const int X_base = param.game.play_area.center_x; const int X_BASE = param.game.play_area.center_x;
paths_.emplace_back(Y0, Y1, PathType::VERTICAL, X_base, DURATION_80F_S, 0.5f, easeOutQuint); paths_.emplace_back(Y0, Y1, PathType::VERTICAL, X_BASE, DURATION_80F_S, 0.5F, easeOutQuint);
paths_.emplace_back(Y1, Y2, PathType::VERTICAL, X_base, DURATION_80F_S, 0.0f, easeInQuint); paths_.emplace_back(Y1, Y2, PathType::VERTICAL, X_BASE, DURATION_80F_S, 0.0F, easeInQuint);
} }
// Recorrido para el texto de "Congratulations!!" (4,5) // Recorrido para el texto de "Congratulations!!" (4,5)
@@ -1040,9 +1043,9 @@ void Game::initPaths() {
const int X1 = param.game.play_area.center_x - (W / 2); const int X1 = param.game.play_area.center_x - (W / 2);
const int X2 = param.game.play_area.rect.w; const int X2 = param.game.play_area.rect.w;
// Y_base es la LÍNEA CENTRAL. addPath(true) restará H/2 // Y_base es la LÍNEA CENTRAL. addPath(true) restará H/2
const int Y_base = param.game.play_area.center_y - (H / 2); const int Y_BASE = param.game.play_area.center_y - (H / 2);
paths_.emplace_back(X0, X1, PathType::HORIZONTAL, Y_base, DURATION_80F_S, 7.0f, easeOutQuint); paths_.emplace_back(X0, X1, PathType::HORIZONTAL, Y_BASE, DURATION_80F_S, 7.0F, easeOutQuint);
paths_.emplace_back(X1, X2, PathType::HORIZONTAL, Y_base, DURATION_80F_S, 0.0f, easeInQuint); paths_.emplace_back(X1, X2, PathType::HORIZONTAL, Y_BASE, DURATION_80F_S, 0.0F, easeInQuint);
} }
// Recorrido para el texto de "1.000.000 points!" (6,7) // Recorrido para el texto de "1.000.000 points!" (6,7)
@@ -1054,9 +1057,9 @@ void Game::initPaths() {
const int X1 = param.game.play_area.center_x - (W / 2); const int X1 = param.game.play_area.center_x - (W / 2);
const int X2 = -W; const int X2 = -W;
// Y_base es la LÍNEA CENTRAL (desplazada PREV_H hacia abajo). addPath(true) restará H/2 // Y_base es la LÍNEA CENTRAL (desplazada PREV_H hacia abajo). addPath(true) restará H/2
const int Y_base = param.game.play_area.center_y + (H / 2); const int Y_BASE = param.game.play_area.center_y + (H / 2);
paths_.emplace_back(X0, X1, PathType::HORIZONTAL, Y_base, DURATION_80F_S, 7.0f, easeOutQuint); paths_.emplace_back(X0, X1, PathType::HORIZONTAL, Y_BASE, DURATION_80F_S, 7.0F, easeOutQuint);
paths_.emplace_back(X1, X2, PathType::HORIZONTAL, Y_base, DURATION_80F_S, 0.0f, easeInQuint); paths_.emplace_back(X1, X2, PathType::HORIZONTAL, Y_BASE, DURATION_80F_S, 0.0F, easeInQuint);
} }
// Recorrido para el texto de "New Record!" (8,9) // Recorrido para el texto de "New Record!" (8,9)
@@ -1068,9 +1071,9 @@ void Game::initPaths() {
const int X1 = param.game.play_area.center_x - (W / 2); // Destino (no-fijo), está bien const int X1 = param.game.play_area.center_x - (W / 2); // Destino (no-fijo), está bien
const int X2 = param.game.play_area.rect.w; const int X2 = param.game.play_area.rect.w;
// Y_base es la LÍNEA CENTRAL (desplazada 2*H hacia arriba). addPath(true) restará H/2 // Y_base es la LÍNEA CENTRAL (desplazada 2*H hacia arriba). addPath(true) restará H/2
const int Y_base = param.game.play_area.center_y - (H * 2); const int Y_BASE = param.game.play_area.center_y - (H * 2);
paths_.emplace_back(X0, X1, PathType::HORIZONTAL, Y_base, DURATION_80F_S, 1.0f, easeOutQuint); paths_.emplace_back(X0, X1, PathType::HORIZONTAL, Y_BASE, DURATION_80F_S, 1.0F, easeOutQuint);
paths_.emplace_back(X1, X2, PathType::HORIZONTAL, Y_base, DURATION_80F_S, 0.0f, easeInQuint); paths_.emplace_back(X1, X2, PathType::HORIZONTAL, Y_BASE, DURATION_80F_S, 0.0F, easeInQuint);
} }
// Recorrido para el texto de "Game Over" (10,11) // Recorrido para el texto de "Game Over" (10,11)
@@ -1081,9 +1084,9 @@ void Game::initPaths() {
const int Y1 = param.game.play_area.center_y - (H / 2); // Destino (no-fijo), está bien const int Y1 = param.game.play_area.center_y - (H / 2); // Destino (no-fijo), está bien
const int Y2 = -H; const int Y2 = -H;
// X_base es la LÍNEA CENTRAL. addPath(true) restará W/2 // X_base es la LÍNEA CENTRAL. addPath(true) restará W/2
const int X_base = param.game.play_area.center_x; const int X_BASE = param.game.play_area.center_x;
paths_.emplace_back(Y0, Y1, PathType::VERTICAL, X_base, DURATION_80F_S, 2.0f, easeOutQuint); paths_.emplace_back(Y0, Y1, PathType::VERTICAL, X_BASE, DURATION_80F_S, 2.0F, easeOutQuint);
paths_.emplace_back(Y1, Y2, PathType::VERTICAL, X_base, DURATION_80F_S, 0.0f, easeInQuint); paths_.emplace_back(Y1, Y2, PathType::VERTICAL, X_BASE, DURATION_80F_S, 0.0F, easeInQuint);
} }
} }
@@ -1159,7 +1162,7 @@ void Game::handleEvents() {
} }
// Actualiza el marcador // Actualiza el marcador
void Game::updateScoreboard(float deltaTime) { void Game::updateScoreboard(float delta_time) {
for (const auto& player : players_) { for (const auto& player : players_) {
scoreboard_->setScore(player->getScoreBoardPanel(), player->getScore()); scoreboard_->setScore(player->getScoreBoardPanel(), player->getScore());
scoreboard_->setMult(player->getScoreBoardPanel(), player->getScoreMultiplier()); scoreboard_->setMult(player->getScoreBoardPanel(), player->getScoreMultiplier());
@@ -1171,7 +1174,7 @@ void Game::updateScoreboard(float deltaTime) {
scoreboard_->setHiScore(hi_score_.score); scoreboard_->setHiScore(hi_score_.score);
scoreboard_->setHiScoreName(hi_score_.name); scoreboard_->setHiScoreName(hi_score_.name);
scoreboard_->update(deltaTime); scoreboard_->update(delta_time);
} }
// Pone en el marcador el nombre del primer jugador de la tabla // Pone en el marcador el nombre del primer jugador de la tabla
@@ -1207,7 +1210,7 @@ void Game::checkPlayersStatusPlaying() {
// Obtiene un jugador a partir de su "id" // Obtiene un jugador a partir de su "id"
auto Game::getPlayer(Player::Id id) -> std::shared_ptr<Player> { auto Game::getPlayer(Player::Id id) -> std::shared_ptr<Player> {
auto it = std::find_if(players_.begin(), players_.end(), [id](const auto& player) { return player->getId() == id; }); auto it = std::ranges::find_if(players_, [id](const auto& player) { return player->getId() == id; });
if (it != players_.end()) { if (it != players_.end()) {
return *it; return *it;
@@ -1699,7 +1702,7 @@ void Game::stopMusic() const {
} }
// Actualiza las variables durante el modo demo // Actualiza las variables durante el modo demo
void Game::updateDemo(float deltaTime) { void Game::updateDemo(float delta_time) {
if (demo_.enabled) { if (demo_.enabled) {
balloon_manager_->setCreationTimeEnabled(balloon_manager_->getNumBalloons() != 0); balloon_manager_->setCreationTimeEnabled(balloon_manager_->getNumBalloons() != 0);
@@ -1708,7 +1711,7 @@ void Game::updateDemo(float deltaTime) {
fade_out_->update(); fade_out_->update();
// Actualiza el contador de tiempo y el índice // Actualiza el contador de tiempo y el índice
demo_.elapsed_s += deltaTime; demo_.elapsed_s += delta_time;
demo_.index = static_cast<int>(demo_.elapsed_s * 60.0F); demo_.index = static_cast<int>(demo_.elapsed_s * 60.0F);
// Activa el fundido antes de acabar con los datos de la demo // Activa el fundido antes de acabar con los datos de la demo
@@ -1755,10 +1758,10 @@ void Game::updateRecording(float deltaTime) {
#endif #endif
// Actualiza las variables durante dicho estado // Actualiza las variables durante dicho estado
void Game::updateGameStateFadeIn(float deltaTime) { void Game::updateGameStateFadeIn(float delta_time) {
fade_in_->update(); fade_in_->update();
updateScoreboard(deltaTime); updateScoreboard(delta_time);
updateBackground(deltaTime); updateBackground(delta_time);
if (fade_in_->hasEnded()) { if (fade_in_->hasEnded()) {
setState(State::ENTERING_PLAYER); setState(State::ENTERING_PLAYER);
balloon_manager_->createTwoBigBalloons(); balloon_manager_->createTwoBigBalloons();
@@ -1767,11 +1770,11 @@ void Game::updateGameStateFadeIn(float deltaTime) {
} }
// Actualiza las variables durante dicho estado // Actualiza las variables durante dicho estado
void Game::updateGameStateEnteringPlayer(float deltaTime) { void Game::updateGameStateEnteringPlayer(float delta_time) {
balloon_manager_->update(deltaTime); balloon_manager_->update(delta_time);
updatePlayers(deltaTime); updatePlayers(delta_time);
updateScoreboard(deltaTime); updateScoreboard(delta_time);
updateBackground(deltaTime); updateBackground(delta_time);
for (const auto& player : players_) { for (const auto& player : players_) {
if (player->isPlaying()) { if (player->isPlaying()) {
setState(State::SHOWING_GET_READY_MESSAGE); setState(State::SHOWING_GET_READY_MESSAGE);
@@ -1782,38 +1785,38 @@ void Game::updateGameStateEnteringPlayer(float deltaTime) {
} }
// Actualiza las variables durante dicho estado // Actualiza las variables durante dicho estado
void Game::updateGameStateShowingGetReadyMessage(float deltaTime) { void Game::updateGameStateShowingGetReadyMessage(float delta_time) {
updateGameStatePlaying(deltaTime); updateGameStatePlaying(delta_time);
constexpr float MUSIC_START_S = 1.67F; constexpr float MUSIC_START_S = 1.67F;
static float music_timer = 0.0f; static float music_timer_ = 0.0F;
music_timer += deltaTime; music_timer_ += delta_time;
if (music_timer >= MUSIC_START_S) { if (music_timer_ >= MUSIC_START_S) {
playMusic("playing.ogg"); playMusic("playing.ogg");
music_timer = 0.0F; music_timer_ = 0.0F;
setState(State::PLAYING); setState(State::PLAYING);
} }
} }
// Actualiza las variables durante el transcurso normal del juego // Actualiza las variables durante el transcurso normal del juego
void Game::updateGameStatePlaying(float deltaTime) { void Game::updateGameStatePlaying(float delta_time) {
#ifdef _DEBUG #ifdef _DEBUG
if (auto_pop_balloons_) { if (auto_pop_balloons_) {
stage_manager_->addPower(2); stage_manager_->addPower(2);
} }
#endif #endif
updatePlayers(deltaTime); updatePlayers(delta_time);
checkPlayersStatusPlaying(); checkPlayersStatusPlaying();
updateScoreboard(deltaTime); updateScoreboard(delta_time);
updateBackground(deltaTime); updateBackground(delta_time);
balloon_manager_->update(deltaTime); balloon_manager_->update(delta_time);
tabe_->update(deltaTime); tabe_->update(delta_time);
bullet_manager_->update(deltaTime); bullet_manager_->update(delta_time);
updateItems(deltaTime); updateItems(delta_time);
updateStage(); updateStage();
updateSmartSprites(deltaTime); updateSmartSprites(delta_time);
updatePathSprites(deltaTime); updatePathSprites(delta_time);
updateTimeStopped(deltaTime); updateTimeStopped(delta_time);
updateHelper(); updateHelper();
bullet_manager_->checkCollisions(); bullet_manager_->checkCollisions();
updateMenace(); updateMenace();
@@ -1916,9 +1919,9 @@ void Game::sortPlayersByZOrder() {
// Procesar jugadores que van al fondo (se dibujan primero) // Procesar jugadores que van al fondo (se dibujan primero)
if (!players_to_put_at_back_.empty()) { if (!players_to_put_at_back_.empty()) {
for (auto& player : players_to_put_at_back_) { for (auto& player : players_to_put_at_back_) {
auto it = std::find(players_.begin(), players_.end(), player); auto it = std::ranges::find(players_, player);
if (it != players_.end() && it != players_.begin()) { if (it != players_.end() && it != players_.begin()) {
std::shared_ptr<Player> dying_player = *it; const std::shared_ptr<Player>& dying_player = *it;
players_.erase(it); players_.erase(it);
players_.insert(players_.begin(), dying_player); players_.insert(players_.begin(), dying_player);
} }
@@ -1929,9 +1932,9 @@ void Game::sortPlayersByZOrder() {
// Procesar jugadores que van al frente (se dibujan últimos) // Procesar jugadores que van al frente (se dibujan últimos)
if (!players_to_put_at_front_.empty()) { if (!players_to_put_at_front_.empty()) {
for (auto& player : players_to_put_at_front_) { for (auto& player : players_to_put_at_front_) {
auto it = std::find(players_.begin(), players_.end(), player); auto it = std::ranges::find(players_, player);
if (it != players_.end() && it != players_.end() - 1) { if (it != players_.end() && it != players_.end() - 1) {
std::shared_ptr<Player> front_player = *it; const std::shared_ptr<Player>& front_player = *it;
players_.erase(it); players_.erase(it);
players_.push_back(front_player); players_.push_back(front_player);
} }
@@ -1957,8 +1960,8 @@ void Game::onPauseStateChanged(bool is_paused) {
// Maneja eventos del juego completado usando flags para triggers únicos // Maneja eventos del juego completado usando flags para triggers únicos
void Game::handleGameCompletedEvents() { void Game::handleGameCompletedEvents() {
constexpr float START_CELEBRATIONS_S = 6.0f; constexpr float START_CELEBRATIONS_S = 6.0F;
constexpr float END_CELEBRATIONS_S = 14.0f; constexpr float END_CELEBRATIONS_S = 14.0F;
// Inicio de celebraciones // Inicio de celebraciones
if (!game_completed_flags_.start_celebrations_triggered && game_completed_timer_ >= START_CELEBRATIONS_S) { if (!game_completed_flags_.start_celebrations_triggered && game_completed_timer_ >= START_CELEBRATIONS_S) {
@@ -1992,8 +1995,8 @@ void Game::handleGameCompletedEvents() {
// Maneja eventos discretos basados en tiempo durante el estado game over // Maneja eventos discretos basados en tiempo durante el estado game over
void Game::handleGameOverEvents() { void Game::handleGameOverEvents() {
constexpr float MESSAGE_TRIGGER_S = 1.5f; constexpr float MESSAGE_TRIGGER_S = 1.5F;
constexpr float FADE_TRIGGER_S = GAME_OVER_DURATION_S - 2.5f; constexpr float FADE_TRIGGER_S = GAME_OVER_DURATION_S - 2.5F;
// Trigger inicial: fade out de música y sonidos de globos // Trigger inicial: fade out de música y sonidos de globos
if (!game_over_flags_.music_fade_triggered) { if (!game_over_flags_.music_fade_triggered) {

View File

@@ -1,23 +1,18 @@
#pragma once #pragma once
#include <SDL3/SDL.h> // Para SDL_Renderer, SDL_Texture, Uint64, Uint8 #include <SDL3/SDL.h> // Para SDL_Event, SDL_Renderer, SDL_Texture, Uint64
#include <memory> // Para shared_ptr, unique_ptr #include <memory> // Para shared_ptr, unique_ptr
#include <string> // Para string #include <string> // Para string
#include <vector> // Para vector #include <vector> // Para vector
#include "bullet.hpp" // Para Bullet #include "bullet.hpp" // for Bullet
#include "bullet_manager.hpp" // Para BulletManager #include "demo.hpp" // for Demo
#include "demo.hpp" // Para Demo #include "hit.hpp" // for Hit
#include "hit.hpp" // Para Hit #include "item.hpp" // for Item (ptr only), ItemType
#include "item.hpp" // Para Item, ItemType #include "manage_hiscore_table.hpp" // for HiScoreEntry
#include "manage_hiscore_table.hpp" // Para HiScoreEntry #include "options.hpp" // for Settings, settings
#include "options.hpp" // Para Settings, settings #include "player.hpp" // for Player
#include "path_sprite.hpp" // Para PathSprite, Path
#include "player.hpp" // Para Player
#include "smart_sprite.hpp" // Para SmartSprite
#include "stage.hpp" // Para StageManager
#include "utils.hpp" // Para otras utilidades
class Background; class Background;
class Balloon; class Balloon;
@@ -25,11 +20,15 @@ class BalloonManager;
class BulletManager; class BulletManager;
class Fade; class Fade;
class Input; class Input;
class PathSprite;
class PauseManager; class PauseManager;
class Scoreboard; class Scoreboard;
class Screen; class Screen;
class SmartSprite;
class StageManager;
class Tabe; class Tabe;
class Texture; class Texture;
struct Path;
namespace Difficulty { namespace Difficulty {
enum class Code; enum class Code;
@@ -76,12 +75,12 @@ class Game {
}; };
// --- Constantes de tiempo (en segundos) --- // --- Constantes de tiempo (en segundos) ---
static constexpr float HELP_COUNTER_S = 16.667f; // Contador de ayuda (1000 frames a 60fps → segundos) static constexpr float HELP_COUNTER_S = 16.667F; // Contador de ayuda (1000 frames a 60fps → segundos)
static constexpr float GAME_COMPLETED_START_FADE_S = 8.333f; // Inicio del fade al completar (500 frames → segundos) static constexpr float GAME_COMPLETED_START_FADE_S = 8.333F; // Inicio del fade al completar (500 frames → segundos)
static constexpr float GAME_COMPLETED_END_S = 11.667f; // Fin del juego completado (700 frames → segundos) static constexpr float GAME_COMPLETED_END_S = 11.667F; // Fin del juego completado (700 frames → segundos)
static constexpr float GAME_OVER_DURATION_S = 8.5f; static constexpr float GAME_OVER_DURATION_S = 8.5F;
static constexpr float TIME_STOPPED_DURATION_S = 6.0f; static constexpr float TIME_STOPPED_DURATION_S = 6.0F;
static constexpr float DEMO_FADE_PRE_DURATION_S = 0.5f; static constexpr float DEMO_FADE_PRE_DURATION_S = 0.5F;
static constexpr int ITEM_POINTS_1_DISK_ODDS = 10; static constexpr int ITEM_POINTS_1_DISK_ODDS = 10;
static constexpr int ITEM_POINTS_2_GAVINA_ODDS = 6; static constexpr int ITEM_POINTS_2_GAVINA_ODDS = 6;
static constexpr int ITEM_POINTS_3_PACMAR_ODDS = 3; static constexpr int ITEM_POINTS_3_PACMAR_ODDS = 3;
@@ -155,11 +154,11 @@ class Game {
Uint64 last_time_ = 0; // Último tiempo registrado para deltaTime Uint64 last_time_ = 0; // Último tiempo registrado para deltaTime
bool coffee_machine_enabled_ = false; // Indica si hay una máquina de café en el terreno de juego bool coffee_machine_enabled_ = false; // Indica si hay una máquina de café en el terreno de juego
bool hi_score_achieved_ = false; // Indica si se ha superado la puntuación máxima bool hi_score_achieved_ = false; // Indica si se ha superado la puntuación máxima
float difficulty_score_multiplier_ = 1.0f; // Multiplicador de puntos en función de la dificultad float difficulty_score_multiplier_ = 1.0F; // Multiplicador de puntos en función de la dificultad
float counter_ = 0.0f; // Contador para el juego float counter_ = 0.0F; // Contador para el juego
float game_completed_timer_ = 0.0f; // Acumulador de tiempo para el tramo final (milisegundos) float game_completed_timer_ = 0.0F; // Acumulador de tiempo para el tramo final (milisegundos)
float game_over_timer_ = 0.0f; // Timer para el estado de fin de partida (milisegundos) float game_over_timer_ = 0.0F; // Timer para el estado de fin de partida (milisegundos)
float time_stopped_timer_ = 0.0f; // Temporizador para llevar la cuenta del tiempo detenido float time_stopped_timer_ = 0.0F; // Temporizador para llevar la cuenta del tiempo detenido
int menace_ = 0; // Nivel de amenaza actual int menace_ = 0; // Nivel de amenaza actual
int menace_threshold_ = 0; // Umbral del nivel de amenaza. Si el nivel de amenaza cae por debajo del umbral, se generan más globos. Si el umbral aumenta, aumenta el número de globos int menace_threshold_ = 0; // Umbral del nivel de amenaza. Si el nivel de amenaza cae por debajo del umbral, se generan más globos. Si el umbral aumenta, aumenta el número de globos
State state_ = State::FADE_IN; // Estado State state_ = State::FADE_IN; // Estado
@@ -205,7 +204,7 @@ class Game {
#endif #endif
// --- Ciclo principal del juego --- // --- Ciclo principal del juego ---
void update(float deltaTime); // Actualiza la lógica principal del juego void update(float delta_time); // Actualiza la lógica principal del juego
auto calculateDeltaTime() -> float; // Calcula el deltatime auto calculateDeltaTime() -> float; // Calcula el deltatime
void render(); // Renderiza todos los elementos del juego void render(); // Renderiza todos los elementos del juego
void handleEvents(); // Procesa los eventos del sistema en cola void handleEvents(); // Procesa los eventos del sistema en cola
@@ -214,17 +213,17 @@ class Game {
void cleanVectors(); // Limpia vectores de elementos deshabilitados void cleanVectors(); // Limpia vectores de elementos deshabilitados
// --- Gestión de estados del juego --- // --- Gestión de estados del juego ---
void updateGameStates(float deltaTime); // Actualiza todos los estados del juego void updateGameStates(float delta_time); // Actualiza todos los estados del juego
void updateGameStateFadeIn(float deltaTime); // Gestiona el estado de transición de entrada (time-based) void updateGameStateFadeIn(float delta_time); // Gestiona el estado de transición de entrada (time-based)
void updateGameStateEnteringPlayer(float deltaTime); // Gestiona el estado de entrada de jugador void updateGameStateEnteringPlayer(float delta_time); // Gestiona el estado de entrada de jugador
void updateGameStateShowingGetReadyMessage(float deltaTime); // Gestiona el estado de mensaje "preparado" void updateGameStateShowingGetReadyMessage(float delta_time); // Gestiona el estado de mensaje "preparado"
void updateGameStatePlaying(float deltaTime); // Gestiona el estado de juego activo void updateGameStatePlaying(float delta_time); // Gestiona el estado de juego activo
void updateGameStateCompleted(float deltaTime); // Gestiona el estado de juego completado void updateGameStateCompleted(float delta_time); // Gestiona el estado de juego completado
void updateGameStateGameOver(float deltaTime); // Gestiona las actualizaciones continuas del estado de fin de partida void updateGameStateGameOver(float delta_time); // Gestiona las actualizaciones continuas del estado de fin de partida
// --- Gestión de jugadores --- // --- Gestión de jugadores ---
void initPlayers(Player::Id player_id); // Inicializa los datos de los jugadores void initPlayers(Player::Id player_id); // Inicializa los datos de los jugadores
void updatePlayers(float deltaTime); // Actualiza las variables y estados de los jugadores void updatePlayers(float delta_time); // Actualiza las variables y estados de los jugadores
void renderPlayers(); // Renderiza todos los jugadores en pantalla void renderPlayers(); // Renderiza todos los jugadores en pantalla
void sortPlayersByZOrder(); // Reorganiza el orden de dibujado de jugadores void sortPlayersByZOrder(); // Reorganiza el orden de dibujado de jugadores
auto getPlayer(Player::Id id) -> std::shared_ptr<Player>; // Obtiene un jugador por su identificador auto getPlayer(Player::Id id) -> std::shared_ptr<Player>; // Obtiene un jugador por su identificador
@@ -269,7 +268,7 @@ class Game {
void processBalloonHit(const std::shared_ptr<Bullet>& bullet, const std::shared_ptr<Balloon>& balloon); // Procesa impacto en globo void processBalloonHit(const std::shared_ptr<Bullet>& bullet, const std::shared_ptr<Balloon>& balloon); // Procesa impacto en globo
// --- Sistema de ítems y power-ups --- // --- Sistema de ítems y power-ups ---
void updateItems(float deltaTime); // Actualiza posición y estado de todos los ítems void updateItems(float delta_time); // Actualiza posición y estado de todos los ítems
void renderItems(); // Renderiza todos los ítems activos void renderItems(); // Renderiza todos los ítems activos
auto dropItem() -> ItemType; // Determina aleatoriamente qué ítem soltar auto dropItem() -> ItemType; // Determina aleatoriamente qué ítem soltar
void createItem(ItemType type, float x, float y); // Crea un nuevo ítem en posición específica void createItem(ItemType type, float x, float y); // Crea un nuevo ítem en posición específica
@@ -277,35 +276,35 @@ class Game {
void destroyAllItems(); // Elimina todos los ítems activos de la pantalla void destroyAllItems(); // Elimina todos los ítems activos de la pantalla
// --- ítems especiales --- // --- ítems especiales ---
void enableTimeStopItem(); // Activa el efecto de detener el tiempo void enableTimeStopItem(); // Activa el efecto de detener el tiempo
void disableTimeStopItem(); // Desactiva el efecto de detener el tiempo void disableTimeStopItem(); // Desactiva el efecto de detener el tiempo
void updateTimeStopped(float deltaTime); // Actualiza el estado del tiempo detenido void updateTimeStopped(float delta_time); // Actualiza el estado del tiempo detenido
void handleGameCompletedEvents(); // Maneja eventos del juego completado void handleGameCompletedEvents(); // Maneja eventos del juego completado
void handleGameOverEvents(); // Maneja eventos discretos basados en tiempo durante game over void handleGameOverEvents(); // Maneja eventos discretos basados en tiempo durante game over
void throwCoffee(int x, int y); // Crea efecto de café arrojado al ser golpeado void throwCoffee(int x, int y); // Crea efecto de café arrojado al ser golpeado
// --- Gestión de caída de ítems --- // --- Gestión de caída de ítems ---
void handleItemDrop(const std::shared_ptr<Balloon>& balloon, const std::shared_ptr<Player>& player); // Gestiona caída de ítem desde globo void handleItemDrop(const std::shared_ptr<Balloon>& balloon, const std::shared_ptr<Player>& player); // Gestiona caída de ítem desde globo
// --- Sprites inteligentes (smartsprites) --- // --- Sprites inteligentes (smartsprites) ---
void updateSmartSprites(float deltaTime); // Actualiza todos los sprites con lógica propia (time-based) void updateSmartSprites(float delta_time); // Actualiza todos los sprites con lógica propia (time-based)
void renderSmartSprites(); // Renderiza todos los sprites inteligentes void renderSmartSprites(); // Renderiza todos los sprites inteligentes
void freeSmartSprites(); // Libera memoria de sprites inteligentes void freeSmartSprites(); // Libera memoria de sprites inteligentes
// --- Sprites por ruta (pathsprites) --- // --- Sprites por ruta (pathsprites) ---
void updatePathSprites(float deltaTime); // Actualiza sprites que siguen rutas predefinidas void updatePathSprites(float delta_time); // Actualiza sprites que siguen rutas predefinidas
void renderPathSprites(); // Renderiza sprites animados por ruta void renderPathSprites(); // Renderiza sprites animados por ruta
void freePathSprites(); // Libera memoria de sprites por ruta void freePathSprites(); // Libera memoria de sprites por ruta
void initPaths(); // Inicializa rutas predefinidas para animaciones void initPaths(); // Inicializa rutas predefinidas para animaciones
// --- Creación de sprites especiales --- // --- Creación de sprites especiales ---
void createItemText(int x, const std::shared_ptr<Texture>& texture); // Crea texto animado para ítems void createItemText(int x, const std::shared_ptr<Texture>& texture); // Crea texto animado para ítems
void createMessage(const std::vector<Path>& paths, const std::shared_ptr<Texture>& texture); // Crea mensaje con animación por ruta void createMessage(const std::vector<Path>& paths, const std::shared_ptr<Texture>& texture); // Crea mensaje con animación por ruta
// --- Sistema de globos y enemigos --- // --- Sistema de globos y enemigos ---
void handleBalloonDestruction(std::shared_ptr<Balloon> balloon, const std::shared_ptr<Player>& player); // Procesa destrucción de globo void handleBalloonDestruction(const std::shared_ptr<Balloon>& balloon, const std::shared_ptr<Player>& player); // Procesa destrucción de globo
void handleTabeHitEffects(); // Gestiona efectos al golpear a Tabe void handleTabeHitEffects(); // Gestiona efectos al golpear a Tabe
void checkAndUpdateBalloonSpeed(); // Ajusta velocidad de globos según progreso void checkAndUpdateBalloonSpeed(); // Ajusta velocidad de globos según progreso
// --- Gestión de fases y progresión --- // --- Gestión de fases y progresión ---
void updateStage(); // Verifica y actualiza cambio de fase void updateStage(); // Verifica y actualiza cambio de fase
@@ -316,20 +315,20 @@ class Game {
void setMenace(); // Calcula y establece amenaza según globos activos void setMenace(); // Calcula y establece amenaza según globos activos
// --- Puntuación y marcador --- // --- Puntuación y marcador ---
void updateHiScore(); // Actualiza el récord máximo si es necesario void updateHiScore(); // Actualiza el récord máximo si es necesario
void updateScoreboard(float deltaTime); // Actualiza la visualización del marcador void updateScoreboard(float delta_time); // Actualiza la visualización del marcador
void updateHiScoreName(); // Pone en el marcador el nombre del primer jugador de la tabla void updateHiScoreName(); // Pone en el marcador el nombre del primer jugador de la tabla
void initScoreboard(); // Inicializa el sistema de puntuación void initScoreboard(); // Inicializa el sistema de puntuación
// --- Modo demostración --- // --- Modo demostración ---
void initDemo(Player::Id player_id); // Inicializa variables para el modo demostración void initDemo(Player::Id player_id); // Inicializa variables para el modo demostración
void updateDemo(float deltaTime); // Actualiza lógica específica del modo demo void updateDemo(float delta_time); // Actualiza lógica específica del modo demo
// --- Recursos y renderizado --- // --- Recursos y renderizado ---
void setResources(); // Asigna texturas y animaciones a los objetos void setResources(); // Asigna texturas y animaciones a los objetos
void updateBackground(float deltaTime); // Actualiza elementos del fondo (time-based) void updateBackground(float delta_time); // Actualiza elementos del fondo (time-based)
void fillCanvas(); // Renderiza elementos del área de juego en su textura void fillCanvas(); // Renderiza elementos del área de juego en su textura
void updateHelper(); // Actualiza variables auxiliares de renderizado void updateHelper(); // Actualiza variables auxiliares de renderizado
// --- Sistema de audio --- // --- Sistema de audio ---
static void playMusic(const std::string& music_file, int loop = -1); // Reproduce la música de fondo static void playMusic(const std::string& music_file, int loop = -1); // Reproduce la música de fondo

View File

@@ -33,7 +33,7 @@ HiScoreTable::HiScoreTable()
backbuffer_(SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, param.game.width, param.game.height)), backbuffer_(SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, param.game.width, param.game.height)),
fade_(std::make_unique<Fade>()), fade_(std::make_unique<Fade>()),
background_(std::make_unique<Background>()), background_(std::make_unique<Background>()),
last_time_(0),
view_area_(SDL_FRect{0, 0, param.game.width, param.game.height}), view_area_(SDL_FRect{0, 0, param.game.width, param.game.height}),
fade_mode_(Fade::Mode::IN), fade_mode_(Fade::Mode::IN),
background_fade_color_(Color(0, 0, 0)) { background_fade_color_(Color(0, 0, 0)) {
@@ -75,7 +75,7 @@ void HiScoreTable::render() {
SCREEN->clean(); // Limpia la pantalla SCREEN->clean(); // Limpia la pantalla
background_->render(); // Pinta el fondo background_->render(); // Pinta el fondo
float counter_equivalent = elapsed_time_ * 60.0f; // Convertir tiempo a equivalente frame para UI float counter_equivalent = elapsed_time_ * 60.0F; // Convertir tiempo a equivalente frame para UI
view_area_.y = std::max(0.0F, param.game.height - counter_equivalent + 100); // Establece la ventana del backbuffer view_area_.y = std::max(0.0F, param.game.height - counter_equivalent + 100); // Establece la ventana del backbuffer
SDL_RenderTexture(renderer_, backbuffer_, nullptr, &view_area_); // Copia el backbuffer al renderizador SDL_RenderTexture(renderer_, backbuffer_, nullptr, &view_area_); // Copia el backbuffer al renderizador
fade_->render(); // Renderiza el fade fade_->render(); // Renderiza el fade
@@ -118,11 +118,11 @@ void HiScoreTable::checkInput() {
} }
// Calcula el tiempo transcurrido desde el último frame // Calcula el tiempo transcurrido desde el último frame
float HiScoreTable::calculateDeltaTime() { auto HiScoreTable::calculateDeltaTime() -> float {
const Uint64 current_time = SDL_GetTicks(); const Uint64 CURRENT_TIME = SDL_GetTicks();
const float delta_time = static_cast<float>(current_time - last_time_) / 1000.0f; // Convertir ms a segundos const float DELTA_TIME = static_cast<float>(CURRENT_TIME - last_time_) / 1000.0F; // Convertir ms a segundos
last_time_ = current_time; last_time_ = CURRENT_TIME;
return delta_time; return DELTA_TIME;
} }
// Bucle para la pantalla de instrucciones // Bucle para la pantalla de instrucciones
@@ -131,10 +131,10 @@ void HiScoreTable::run() {
Audio::get()->playMusic("title.ogg"); Audio::get()->playMusic("title.ogg");
while (Section::name == Section::Name::HI_SCORE_TABLE) { while (Section::name == Section::Name::HI_SCORE_TABLE) {
const float delta_time = calculateDeltaTime(); const float DELTA_TIME = calculateDeltaTime();
checkInput(); checkInput();
update(delta_time); update(DELTA_TIME);
checkEvents(); // Tiene que ir antes del render checkEvents(); // Tiene que ir antes del render
render(); render();
} }
@@ -262,12 +262,12 @@ void HiScoreTable::createSprites() {
// Actualiza las posiciones de los sprites de texto // Actualiza las posiciones de los sprites de texto
void HiScoreTable::updateSprites(float delta_time) { void HiScoreTable::updateSprites(float delta_time) {
if (elapsed_time_ >= INIT_DELAY_S) { if (elapsed_time_ >= INIT_DELAY_S) {
const float elapsed_since_init = elapsed_time_ - INIT_DELAY_S; const float ELAPSED_SINCE_INIT = elapsed_time_ - INIT_DELAY_S;
int index = static_cast<int>(elapsed_since_init / ENTRY_DELAY_S); int index = static_cast<int>(ELAPSED_SINCE_INIT / ENTRY_DELAY_S);
if (index < static_cast<int>(entry_names_.size()) && index >= 0) { if (index < static_cast<int>(entry_names_.size()) && index >= 0) {
// Verificar si este índice debe activarse ahora // Verificar si este índice debe activarse ahora
float expected_time = index * ENTRY_DELAY_S; float expected_time = index * ENTRY_DELAY_S;
if (elapsed_since_init >= expected_time && elapsed_since_init < expected_time + delta_time) { if (ELAPSED_SINCE_INIT >= expected_time && ELAPSED_SINCE_INIT < expected_time + delta_time) {
entry_names_.at(index)->enable(); entry_names_.at(index)->enable();
} }
} }
@@ -357,7 +357,7 @@ void HiScoreTable::iniEntryColors() {
// Hace brillar los nombres de la tabla de records // Hace brillar los nombres de la tabla de records
void HiScoreTable::glowEntryNames() { void HiScoreTable::glowEntryNames() {
int color_counter = static_cast<int>(elapsed_time_ * 60.0f / 5.0f); // Convertir tiempo a equivalente frame int color_counter = static_cast<int>(elapsed_time_ * 60.0F / 5.0F); // Convertir tiempo a equivalente frame
const Color ENTRY_COLOR = getEntryColor(color_counter); const Color ENTRY_COLOR = getEntryColor(color_counter);
for (const auto& entry_index : Options::settings.glowing_entries) { for (const auto& entry_index : Options::settings.glowing_entries) {
if (entry_index != -1) { if (entry_index != -1) {

View File

@@ -1,17 +1,18 @@
#pragma once #pragma once
#include <SDL3/SDL.h> // Para Uint16, SDL_FRect, SDL_Renderer, SDL_Texture, Uint64, Uint8 #include <SDL3/SDL.h> // Para SDL_FRect, SDL_Renderer, SDL_Texture, Uint64
#include <memory> // Para unique_ptr, shared_ptr #include <memory> // Para unique_ptr, shared_ptr
#include <string> // Para string #include <string> // Para string
#include <vector> // Para vector #include <vector> // Para vector
#include "color.hpp" // Para Color #include "color.hpp" // for Color
#include "fade.hpp" // Para Fade #include "fade.hpp" // for Fade
#include "path_sprite.hpp" // Para Path, PathSprite (ptr only)
class Background; class Background;
class PathSprite;
class Sprite; class Sprite;
struct Path;
// --- Clase HiScoreTable: muestra la tabla de puntuaciones más altas --- // --- Clase HiScoreTable: muestra la tabla de puntuaciones más altas ---
// Esta clase gestiona un estado del programa. Se encarga de mostrar la tabla con las puntuaciones // Esta clase gestiona un estado del programa. Se encarga de mostrar la tabla con las puntuaciones
@@ -31,12 +32,12 @@ class HiScoreTable {
private: private:
// --- Constantes (en segundos) --- // --- Constantes (en segundos) ---
static constexpr float COUNTER_END_S = 800.0f / 60.0f; // Tiempo final (≈13.33s) static constexpr float COUNTER_END_S = 800.0F / 60.0F; // Tiempo final (≈13.33s)
static constexpr float INIT_DELAY_S = 190.0f / 60.0f; // Retraso inicial (≈3.17s) static constexpr float INIT_DELAY_S = 190.0F / 60.0F; // Retraso inicial (≈3.17s)
static constexpr float ENTRY_DELAY_S = 16.0f / 60.0f; // Retraso entre entradas (≈0.27s) static constexpr float ENTRY_DELAY_S = 16.0F / 60.0F; // Retraso entre entradas (≈0.27s)
static constexpr float BACKGROUND_CHANGE_S = 150.0f / 60.0f; // Tiempo cambio fondo (≈2.5s) static constexpr float BACKGROUND_CHANGE_S = 150.0F / 60.0F; // Tiempo cambio fondo (≈2.5s)
static constexpr float ANIM_DURATION_S = 80.0f / 60.0f; // Duración animación (≈1.33s) static constexpr float ANIM_DURATION_S = 80.0F / 60.0F; // Duración animación (≈1.33s)
static constexpr float CLOUDS_SPEED = -6.0f; // Velocidad nubes (pixels/s) static constexpr float CLOUDS_SPEED = -6.0F; // Velocidad nubes (pixels/s)
// --- Objetos y punteros --- // --- Objetos y punteros ---
SDL_Renderer* renderer_; // El renderizador de la ventana SDL_Renderer* renderer_; // El renderizador de la ventana
@@ -49,7 +50,7 @@ class HiScoreTable {
std::vector<Path> paths_; // Vector con los recorridos precalculados std::vector<Path> paths_; // Vector con los recorridos precalculados
// --- Variables --- // --- Variables ---
float elapsed_time_ = 0.0f; // Tiempo transcurrido (segundos) float elapsed_time_ = 0.0F; // Tiempo transcurrido (segundos)
Uint64 last_time_ = 0; // Último timestamp para calcular delta-time Uint64 last_time_ = 0; // Último timestamp para calcular delta-time
SDL_FRect view_area_; // Parte de la textura que se muestra en pantalla SDL_FRect view_area_; // Parte de la textura que se muestra en pantalla
Fade::Mode fade_mode_; // Modo de fade a utilizar Fade::Mode fade_mode_; // Modo de fade a utilizar
@@ -83,5 +84,5 @@ class HiScoreTable {
void iniEntryColors(); // Inicializa los colores de las entradas void iniEntryColors(); // Inicializa los colores de las entradas
void glowEntryNames(); // Hace brillar los nombres de la tabla de records void glowEntryNames(); // Hace brillar los nombres de la tabla de records
void updateCounter(); // Gestiona el contador void updateCounter(); // Gestiona el contador
float calculateDeltaTime(); // Calcula el tiempo transcurrido desde el último frame auto calculateDeltaTime() -> float; // Calcula el tiempo transcurrido desde el último frame
}; };

View File

@@ -90,19 +90,19 @@ void Instructions::updateSprites() {
SDL_FRect src_rect = {0, 0, Item::WIDTH, Item::HEIGHT}; SDL_FRect src_rect = {0, 0, Item::WIDTH, Item::HEIGHT};
// Disquito (desplazamiento 12/60 = 0.2s) // Disquito (desplazamiento 12/60 = 0.2s)
src_rect.y = Item::HEIGHT * (static_cast<int>((elapsed_time_ + 0.2f) / SPRITE_ANIMATION_CYCLE_S) % 2); src_rect.y = Item::HEIGHT * (static_cast<int>((elapsed_time_ + 0.2F) / SPRITE_ANIMATION_CYCLE_S) % 2);
sprites_[0]->setSpriteClip(src_rect); sprites_[0]->setSpriteClip(src_rect);
// Gavina (desplazamiento 9/60 = 0.15s) // Gavina (desplazamiento 9/60 = 0.15s)
src_rect.y = Item::HEIGHT * (static_cast<int>((elapsed_time_ + 0.15f) / SPRITE_ANIMATION_CYCLE_S) % 2); src_rect.y = Item::HEIGHT * (static_cast<int>((elapsed_time_ + 0.15F) / SPRITE_ANIMATION_CYCLE_S) % 2);
sprites_[1]->setSpriteClip(src_rect); sprites_[1]->setSpriteClip(src_rect);
// Pacmar (desplazamiento 6/60 = 0.1s) // Pacmar (desplazamiento 6/60 = 0.1s)
src_rect.y = Item::HEIGHT * (static_cast<int>((elapsed_time_ + 0.1f) / SPRITE_ANIMATION_CYCLE_S) % 2); src_rect.y = Item::HEIGHT * (static_cast<int>((elapsed_time_ + 0.1F) / SPRITE_ANIMATION_CYCLE_S) % 2);
sprites_[2]->setSpriteClip(src_rect); sprites_[2]->setSpriteClip(src_rect);
// Time Stopper (desplazamiento 3/60 = 0.05s) // Time Stopper (desplazamiento 3/60 = 0.05s)
src_rect.y = Item::HEIGHT * (static_cast<int>((elapsed_time_ + 0.05f) / SPRITE_ANIMATION_CYCLE_S) % 2); src_rect.y = Item::HEIGHT * (static_cast<int>((elapsed_time_ + 0.05F) / SPRITE_ANIMATION_CYCLE_S) % 2);
sprites_[3]->setSpriteClip(src_rect); sprites_[3]->setSpriteClip(src_rect);
// Coffee (sin desplazamiento) // Coffee (sin desplazamiento)
@@ -255,11 +255,11 @@ void Instructions::checkInput() {
} }
// Calcula el tiempo transcurrido desde el último frame // Calcula el tiempo transcurrido desde el último frame
float Instructions::calculateDeltaTime() { auto Instructions::calculateDeltaTime() -> float {
const Uint64 current_time = SDL_GetTicks(); const Uint64 CURRENT_TIME = SDL_GetTicks();
const float delta_time = static_cast<float>(current_time - last_time_) / 1000.0f; // Convertir ms a segundos const float DELTA_TIME = static_cast<float>(CURRENT_TIME - last_time_) / 1000.0F; // Convertir ms a segundos
last_time_ = current_time; last_time_ = CURRENT_TIME;
return delta_time; return DELTA_TIME;
} }
// Bucle para la pantalla de instrucciones // Bucle para la pantalla de instrucciones
@@ -268,10 +268,10 @@ void Instructions::run() {
Audio::get()->playMusic("title.ogg"); Audio::get()->playMusic("title.ogg");
while (Section::name == Section::Name::INSTRUCTIONS) { while (Section::name == Section::Name::INSTRUCTIONS) {
const float delta_time = calculateDeltaTime(); const float DELTA_TIME = calculateDeltaTime();
checkInput(); checkInput();
update(delta_time); update(DELTA_TIME);
checkEvents(); // Tiene que ir antes del render checkEvents(); // Tiene que ir antes del render
render(); render();
} }
@@ -328,7 +328,7 @@ void Instructions::renderLines(SDL_Renderer* renderer, SDL_Texture* texture, con
// Gestiona la textura con los graficos // Gestiona la textura con los graficos
void Instructions::updateBackbuffer(float delta_time) { void Instructions::updateBackbuffer(float delta_time) {
// Establece la ventana del backbuffer (convertir elapsed_time_ a equivalente de counter) // Establece la ventana del backbuffer (convertir elapsed_time_ a equivalente de counter)
float counter_equivalent = elapsed_time_ * 60.0f; // Convertir segundos a equivalente frame para UI float counter_equivalent = elapsed_time_ * 60.0F; // Convertir segundos a equivalente frame para UI
view_.y = std::max(0.0F, param.game.height - counter_equivalent + 100); view_.y = std::max(0.0F, param.game.height - counter_equivalent + 100);
// Verifica si view_.y == 0 y gestiona el temporizador // Verifica si view_.y == 0 y gestiona el temporizador
@@ -336,7 +336,7 @@ void Instructions::updateBackbuffer(float delta_time) {
if (!start_delay_triggered_) { if (!start_delay_triggered_) {
// Activa el temporizador si no ha sido activado // Activa el temporizador si no ha sido activado
start_delay_triggered_ = true; start_delay_triggered_ = true;
start_delay_timer_ = 0.0f; start_delay_timer_ = 0.0F;
} else { } else {
start_delay_timer_ += delta_time; start_delay_timer_ += delta_time;
if (start_delay_timer_ >= START_DELAY_S) { if (start_delay_timer_ >= START_DELAY_S) {

View File

@@ -1,13 +1,12 @@
#pragma once #pragma once
#include <SDL3/SDL.h> // Para SDL_Texture, Uint32, SDL_Renderer, SDL_FPoint, SDL_FRect, Uint64 #include <SDL3/SDL.h> // Para SDL_Texture, SDL_Renderer, Uint32, SDL_FPoint, SDL_FRect, Uint64
#include <memory> // Para unique_ptr, shared_ptr #include <memory> // Para unique_ptr, shared_ptr
#include <vector> // Para vector #include <vector> // Para vector
#include "sprite.hpp" // Para Sprite
class Fade; class Fade;
class Sprite;
class Text; class Text;
class Texture; class Texture;
class TiledBG; class TiledBG;
@@ -51,10 +50,10 @@ class Instructions {
private: private:
// --- Constantes de tiempo (en segundos) --- // --- Constantes de tiempo (en segundos) ---
static constexpr float SPRITE_ANIMATION_CYCLE_S = 36.0f / 60.0f; // Ciclo de animación sprites (≈0.6s) static constexpr float SPRITE_ANIMATION_CYCLE_S = 36.0F / 60.0F; // Ciclo de animación sprites (≈0.6s)
static constexpr float START_DELAY_S = 4.0f; // Retraso antes de mover líneas (4s) static constexpr float START_DELAY_S = 4.0F; // Retraso antes de mover líneas (4s)
static constexpr float LINE_MOVE_DURATION_S = 1.0f; // Duración movimiento líneas (1s) static constexpr float LINE_MOVE_DURATION_S = 1.0F; // Duración movimiento líneas (1s)
static constexpr float LINE_START_DELAY_MS = 5.0f; // Retraso entre líneas (5ms) static constexpr float LINE_START_DELAY_MS = 5.0F; // Retraso entre líneas (5ms)
// --- Objetos y punteros --- // --- Objetos y punteros ---
SDL_Renderer* renderer_; // El renderizador de la ventana SDL_Renderer* renderer_; // El renderizador de la ventana
@@ -68,14 +67,14 @@ class Instructions {
std::unique_ptr<Fade> fade_; // Objeto para renderizar fades std::unique_ptr<Fade> fade_; // Objeto para renderizar fades
// --- Variables --- // --- Variables ---
float elapsed_time_ = 0.0f; // Tiempo transcurrido (segundos) float elapsed_time_ = 0.0F; // Tiempo transcurrido (segundos)
Uint64 last_time_ = 0; // Último timestamp para calcular delta-time Uint64 last_time_ = 0; // Último timestamp para calcular delta-time
SDL_FRect view_; // Vista del backbuffer que se va a mostrar por pantalla SDL_FRect view_; // Vista del backbuffer que se va a mostrar por pantalla
SDL_FPoint sprite_pos_ = {0, 0}; // Posición del primer sprite en la lista SDL_FPoint sprite_pos_ = {0, 0}; // Posición del primer sprite en la lista
float item_space_ = 2.0; // Espacio entre los items en pantalla float item_space_ = 2.0; // Espacio entre los items en pantalla
std::vector<Line> lines_; // Vector que contiene las líneas animadas en la pantalla std::vector<Line> lines_; // Vector que contiene las líneas animadas en la pantalla
bool all_lines_off_screen_ = false; // Indica si todas las líneas han salido de la pantalla bool all_lines_off_screen_ = false; // Indica si todas las líneas han salido de la pantalla
float start_delay_timer_ = 0.0f; // Timer para retraso antes de mover líneas (segundos) float start_delay_timer_ = 0.0F; // Timer para retraso antes de mover líneas (segundos)
bool start_delay_triggered_ = false; // Bandera para determinar si el retraso ha comenzado bool start_delay_triggered_ = false; // Bandera para determinar si el retraso ha comenzado
// --- Métodos internos --- // --- Métodos internos ---
@@ -91,5 +90,5 @@ class Instructions {
static auto moveLines(std::vector<Line>& lines, int width, float duration, Uint32 start_delay) -> bool; // Mueve las líneas (ya usa tiempo real) static auto moveLines(std::vector<Line>& lines, int width, float duration, Uint32 start_delay) -> bool; // Mueve las líneas (ya usa tiempo real)
static void renderLines(SDL_Renderer* renderer, SDL_Texture* texture, const std::vector<Line>& lines); // Renderiza las líneas static void renderLines(SDL_Renderer* renderer, SDL_Texture* texture, const std::vector<Line>& lines); // Renderiza las líneas
void updateBackbuffer(float delta_time); // Gestiona la textura con los gráficos void updateBackbuffer(float delta_time); // Gestiona la textura con los gráficos
float calculateDeltaTime(); // Calcula el tiempo transcurrido desde el último frame auto calculateDeltaTime() -> float; // Calcula el tiempo transcurrido desde el último frame
}; };

View File

@@ -1,8 +1,7 @@
#include "intro.hpp" #include "intro.hpp"
#include <SDL3/SDL.h> // Para SDL_GetTicks, SDL_SetRenderDrawColor, SDL_FRect, SDL_RenderFillRect, SDL_GetRenderTarget, SDL_RenderClear, SDL_RenderRect, SDL_SetRenderTarget, SDL_BLENDMODE_BLEND, SDL_PixelFormat, SDL_PollEvent, SDL_RenderTexture, SDL_TextureAccess, SDL_Event, Uint32 #include <SDL3/SDL.h> // Para SDL_GetTicks, SDL_SetRenderDrawColor, SDL_FRect, SDL_RenderFillRect, SDL_GetRenderTarget, SDL_RenderClear, SDL_RenderRect, SDL_SetRenderTarget, SDL_BLENDMODE_BLEND, SDL_PixelFormat, SDL_PollEvent, SDL_RenderTexture, SDL_TextureAccess, SDL_Event, Uint64
#include <algorithm> // Para max
#include <array> // Para array #include <array> // Para array
#include <functional> // Para function #include <functional> // Para function
#include <string> // Para basic_string, string #include <string> // Para basic_string, string
@@ -10,7 +9,7 @@
#include "audio.hpp" // Para Audio #include "audio.hpp" // Para Audio
#include "color.hpp" // Para Color #include "color.hpp" // Para Color
#include "global_events.hpp" // Para check #include "global_events.hpp" // Para handle
#include "global_inputs.hpp" // Para check #include "global_inputs.hpp" // Para check
#include "input.hpp" // Para Input #include "input.hpp" // Para Input
#include "lang.hpp" // Para getText #include "lang.hpp" // Para getText
@@ -191,7 +190,7 @@ void Intro::updateScene5() {
// Acaba la ultima imagen // Acaba la ultima imagen
if (card_sprites_.at(5)->hasFinished() && texts_.at(8)->hasFinished()) { if (card_sprites_.at(5)->hasFinished() && texts_.at(8)->hasFinished()) {
state_ = State::POST; state_ = State::POST;
state_start_time_ = SDL_GetTicks() / 1000.0f; state_start_time_ = SDL_GetTicks() / 1000.0F;
} }
} }
@@ -251,11 +250,11 @@ void Intro::render() {
} }
// Calcula el tiempo transcurrido desde el último frame // Calcula el tiempo transcurrido desde el último frame
float Intro::calculateDeltaTime() { auto Intro::calculateDeltaTime() -> float {
const Uint64 current_time = SDL_GetTicks(); const Uint64 CURRENT_TIME = SDL_GetTicks();
const float delta_time = static_cast<float>(current_time - last_time_) / 1000.0f; // Convertir ms a segundos const float DELTA_TIME = static_cast<float>(CURRENT_TIME - last_time_) / 1000.0F; // Convertir ms a segundos
last_time_ = current_time; last_time_ = CURRENT_TIME;
return delta_time; return DELTA_TIME;
} }
// Bucle principal // Bucle principal
@@ -264,10 +263,10 @@ void Intro::run() {
Audio::get()->playMusic("intro.ogg", 0); Audio::get()->playMusic("intro.ogg", 0);
while (Section::name == Section::Name::INTRO) { while (Section::name == Section::Name::INTRO) {
const float delta_time = calculateDeltaTime(); const float DELTA_TIME = calculateDeltaTime();
checkInput(); checkInput();
update(delta_time); update(DELTA_TIME);
checkEvents(); // Tiene que ir antes del render checkEvents(); // Tiene que ir antes del render
render(); render();
} }
@@ -338,13 +337,13 @@ void Intro::initSprites() {
const float X_DEST = param.game.game_area.center_x - (CARD_WIDTH / 2); const float X_DEST = param.game.game_area.center_x - (CARD_WIDTH / 2);
const float Y_DEST = param.game.game_area.first_quarter_y - (CARD_HEIGHT / 4); const float Y_DEST = param.game.game_area.first_quarter_y - (CARD_HEIGHT / 4);
card_sprites_.at(0)->addPath(-CARD_WIDTH - CARD_OFFSET_MARGIN, X_DEST, PathType::HORIZONTAL, Y_DEST, CARD_ANIM_DURATION_NORMAL, easeInOutExpo, 0.0f); card_sprites_.at(0)->addPath(-CARD_WIDTH - CARD_OFFSET_MARGIN, X_DEST, PathType::HORIZONTAL, Y_DEST, CARD_ANIM_DURATION_NORMAL, easeInOutExpo, 0.0F);
card_sprites_.at(1)->addPath(param.game.width, X_DEST, PathType::HORIZONTAL, Y_DEST, CARD_ANIM_DURATION_NORMAL, easeOutBounce, 0.0f); card_sprites_.at(1)->addPath(param.game.width, X_DEST, PathType::HORIZONTAL, Y_DEST, CARD_ANIM_DURATION_NORMAL, easeOutBounce, 0.0F);
card_sprites_.at(2)->addPath(-CARD_HEIGHT, Y_DEST, PathType::VERTICAL, X_DEST, CARD_ANIM_DURATION_FAST, easeOutQuint, 0.0f); card_sprites_.at(2)->addPath(-CARD_HEIGHT, Y_DEST, PathType::VERTICAL, X_DEST, CARD_ANIM_DURATION_FAST, easeOutQuint, 0.0F);
card_sprites_.at(3)->addPath(param.game.height, Y_DEST, PathType::VERTICAL, X_DEST, CARD_ANIM_DURATION_VERY_SLOW, easeInOutExpo, 0.0f); card_sprites_.at(3)->addPath(param.game.height, Y_DEST, PathType::VERTICAL, X_DEST, CARD_ANIM_DURATION_VERY_SLOW, easeInOutExpo, 0.0F);
card_sprites_.at(4)->addPath(-CARD_HEIGHT, Y_DEST, PathType::VERTICAL, X_DEST, CARD_ANIM_DURATION_MEDIUM, easeOutElastic, 0.0f); card_sprites_.at(4)->addPath(-CARD_HEIGHT, Y_DEST, PathType::VERTICAL, X_DEST, CARD_ANIM_DURATION_MEDIUM, easeOutElastic, 0.0F);
card_sprites_.at(5)->addPath(-CARD_HEIGHT, Y_DEST, PathType::VERTICAL, X_DEST, CARD_ANIM_DURATION_SLOW, easeOutQuad, CARD_ANIM_DELAY_LONG_S); card_sprites_.at(5)->addPath(-CARD_HEIGHT, Y_DEST, PathType::VERTICAL, X_DEST, CARD_ANIM_DURATION_SLOW, easeOutQuad, CARD_ANIM_DELAY_LONG_S);
card_sprites_.at(5)->addPath(X_DEST, -CARD_WIDTH, PathType::HORIZONTAL, Y_DEST, CARD_ANIM_DURATION_SHORT, easeInElastic, 0.0f); card_sprites_.at(5)->addPath(X_DEST, -CARD_WIDTH, PathType::HORIZONTAL, Y_DEST, CARD_ANIM_DURATION_SHORT, easeInElastic, 0.0F);
// Constantes // Constantes
const float DESP = SHADOW_OFFSET; const float DESP = SHADOW_OFFSET;
@@ -389,13 +388,13 @@ void Intro::initSprites() {
const float S_X_DEST = X_DEST + DESP; const float S_X_DEST = X_DEST + DESP;
const float S_Y_DEST = Y_DEST + DESP; const float S_Y_DEST = Y_DEST + DESP;
shadow_sprites_.at(0)->addPath(param.game.height + CARD_OFFSET_MARGIN, S_Y_DEST, PathType::VERTICAL, S_X_DEST, CARD_ANIM_DURATION_NORMAL, easeInOutExpo, 0.0f); shadow_sprites_.at(0)->addPath(param.game.height + CARD_OFFSET_MARGIN, S_Y_DEST, PathType::VERTICAL, S_X_DEST, CARD_ANIM_DURATION_NORMAL, easeInOutExpo, 0.0F);
shadow_sprites_.at(1)->addPath(-SHADOW_SPRITE_HEIGHT, S_Y_DEST, PathType::VERTICAL, S_X_DEST, CARD_ANIM_DURATION_NORMAL, easeOutBounce, 0.0f); shadow_sprites_.at(1)->addPath(-SHADOW_SPRITE_HEIGHT, S_Y_DEST, PathType::VERTICAL, S_X_DEST, CARD_ANIM_DURATION_NORMAL, easeOutBounce, 0.0F);
shadow_sprites_.at(2)->addPath(-SHADOW_SPRITE_WIDTH, S_X_DEST, PathType::HORIZONTAL, S_Y_DEST, CARD_ANIM_DURATION_FAST, easeOutQuint, 0.0f); shadow_sprites_.at(2)->addPath(-SHADOW_SPRITE_WIDTH, S_X_DEST, PathType::HORIZONTAL, S_Y_DEST, CARD_ANIM_DURATION_FAST, easeOutQuint, 0.0F);
shadow_sprites_.at(3)->addPath(-SHADOW_SPRITE_HEIGHT, S_Y_DEST, PathType::VERTICAL, S_X_DEST, CARD_ANIM_DURATION_VERY_SLOW, easeInOutExpo, 0.0f); shadow_sprites_.at(3)->addPath(-SHADOW_SPRITE_HEIGHT, S_Y_DEST, PathType::VERTICAL, S_X_DEST, CARD_ANIM_DURATION_VERY_SLOW, easeInOutExpo, 0.0F);
shadow_sprites_.at(4)->addPath(param.game.height, S_Y_DEST, PathType::VERTICAL, S_X_DEST, CARD_ANIM_DURATION_MEDIUM, easeOutElastic, 0.0f); shadow_sprites_.at(4)->addPath(param.game.height, S_Y_DEST, PathType::VERTICAL, S_X_DEST, CARD_ANIM_DURATION_MEDIUM, easeOutElastic, 0.0F);
shadow_sprites_.at(5)->addPath(param.game.width, S_X_DEST, PathType::HORIZONTAL, S_Y_DEST, CARD_ANIM_DURATION_SLOW, easeOutQuad, CARD_ANIM_DELAY_LONG_S); shadow_sprites_.at(5)->addPath(param.game.width, S_X_DEST, PathType::HORIZONTAL, S_Y_DEST, CARD_ANIM_DURATION_SLOW, easeOutQuad, CARD_ANIM_DELAY_LONG_S);
shadow_sprites_.at(5)->addPath(S_X_DEST, param.game.width, PathType::HORIZONTAL, S_Y_DEST, CARD_ANIM_DURATION_SHORT, easeInElastic, 0.0f); shadow_sprites_.at(5)->addPath(S_X_DEST, param.game.width, PathType::HORIZONTAL, S_Y_DEST, CARD_ANIM_DURATION_SHORT, easeInElastic, 0.0F);
} }
// Inicializa los textos // Inicializa los textos
@@ -485,7 +484,7 @@ void Intro::renderTexts() {
// Actualiza el estado POST // Actualiza el estado POST
void Intro::updatePostState() { void Intro::updatePostState() {
const float ELAPSED_TIME = (SDL_GetTicks() / 1000.0f) - state_start_time_; const float ELAPSED_TIME = (SDL_GetTicks() / 1000.0F) - state_start_time_;
switch (post_state_) { switch (post_state_) {
case PostState::STOP_BG: case PostState::STOP_BG:
@@ -503,7 +502,7 @@ void Intro::updatePostState() {
// Cambia de estado si el fondo se ha detenido y recuperado el color // Cambia de estado si el fondo se ha detenido y recuperado el color
if (tiled_bg_->isStopped() && bg_color_.IS_EQUAL_TO(param.title.bg_color)) { if (tiled_bg_->isStopped() && bg_color_.IS_EQUAL_TO(param.title.bg_color)) {
post_state_ = PostState::END; post_state_ = PostState::END;
state_start_time_ = SDL_GetTicks() / 1000.0f; state_start_time_ = SDL_GetTicks() / 1000.0F;
} }
break; break;

View File

@@ -38,32 +38,32 @@ class Intro {
private: private:
// --- Constantes de tiempo (en segundos) --- // --- Constantes de tiempo (en segundos) ---
static constexpr float TEXT_DISPLAY_DURATION_S = 3.0f; // Duración de visualización de texto (180 frames a 60fps) static constexpr float TEXT_DISPLAY_DURATION_S = 3.0F; // Duración de visualización de texto (180 frames a 60fps)
static constexpr float POST_BG_STOP_DELAY_S = 1.0f; // Retraso antes de detener el fondo static constexpr float POST_BG_STOP_DELAY_S = 1.0F; // Retraso antes de detener el fondo
static constexpr float POST_END_DELAY_S = 1.0f; // Retraso antes de finalizar intro static constexpr float POST_END_DELAY_S = 1.0F; // Retraso antes de finalizar intro
// --- Constantes de layout --- // --- Constantes de layout ---
static constexpr float CARD_BORDER_SIZE = 2.0f; // Tamaño del borde de tarjetas static constexpr float CARD_BORDER_SIZE = 2.0F; // Tamaño del borde de tarjetas
static constexpr float SHADOW_OFFSET = 8.0f; // Desplazamiento de sombra static constexpr float SHADOW_OFFSET = 8.0F; // Desplazamiento de sombra
static constexpr float TILED_BG_SPEED = 18.0f; // Velocidad del fondo mosaico (pixels/segundo) static constexpr float TILED_BG_SPEED = 18.0F; // Velocidad del fondo mosaico (pixels/segundo)
static constexpr int TEXT_KERNING = -2; // Espaciado entre caracteres static constexpr int TEXT_KERNING = -2; // Espaciado entre caracteres
// --- Constantes de velocidades de texto (segundos entre caracteres) --- // --- Constantes de velocidades de texto (segundos entre caracteres) ---
static constexpr float TEXT_SPEED_NORMAL = 0.133f; // Velocidad normal (8 frames * 16.67ms = 133ms) static constexpr float TEXT_SPEED_NORMAL = 0.133F; // Velocidad normal (8 frames * 16.67ms = 133ms)
static constexpr float TEXT_SPEED_FAST = 0.2f; // Velocidad rápida (12 frames * 16.67ms = 200ms) static constexpr float TEXT_SPEED_FAST = 0.2F; // Velocidad rápida (12 frames * 16.67ms = 200ms)
static constexpr float TEXT_SPEED_VERY_SLOW = 0.0167f; // Velocidad muy lenta (1 frame * 16.67ms = 16.7ms) static constexpr float TEXT_SPEED_VERY_SLOW = 0.0167F; // Velocidad muy lenta (1 frame * 16.67ms = 16.7ms)
static constexpr float TEXT_SPEED_VERY_FAST = 0.267f; // Velocidad muy rápida (16 frames * 16.67ms = 267ms) static constexpr float TEXT_SPEED_VERY_FAST = 0.267F; // Velocidad muy rápida (16 frames * 16.67ms = 267ms)
static constexpr float TEXT_SPEED_SLOW = 0.033f; // Velocidad lenta (2 frames * 16.67ms = 33ms) static constexpr float TEXT_SPEED_SLOW = 0.033F; // Velocidad lenta (2 frames * 16.67ms = 33ms)
static constexpr float TEXT_SPEED_MEDIUM_SLOW = 0.05f; // Velocidad medio-lenta (3 frames * 16.67ms = 50ms) static constexpr float TEXT_SPEED_MEDIUM_SLOW = 0.05F; // Velocidad medio-lenta (3 frames * 16.67ms = 50ms)
static constexpr float TEXT_SPEED_ULTRA_FAST = 0.333f; // Velocidad ultra rápida (20 frames * 16.67ms = 333ms) static constexpr float TEXT_SPEED_ULTRA_FAST = 0.333F; // Velocidad ultra rápida (20 frames * 16.67ms = 333ms)
// --- Constantes de animaciones de tarjetas (duraciones en segundos) --- // --- Constantes de animaciones de tarjetas (duraciones en segundos) ---
static constexpr float CARD_ANIM_DURATION_NORMAL = 100.0f / 60.0f; // ≈ 1.6667 s static constexpr float CARD_ANIM_DURATION_NORMAL = 100.0F / 60.0F; // ≈ 1.6667 s
static constexpr float CARD_ANIM_DURATION_FAST = 40.0f / 60.0f; // ≈ 0.6667 s static constexpr float CARD_ANIM_DURATION_FAST = 40.0F / 60.0F; // ≈ 0.6667 s
static constexpr float CARD_ANIM_DURATION_MEDIUM = 70.0f / 60.0f; // ≈ 1.1667 s static constexpr float CARD_ANIM_DURATION_MEDIUM = 70.0F / 60.0F; // ≈ 1.1667 s
static constexpr float CARD_ANIM_DURATION_SHORT = 80.0f / 60.0f; // ≈ 1.3333 s static constexpr float CARD_ANIM_DURATION_SHORT = 80.0F / 60.0F; // ≈ 1.3333 s
static constexpr float CARD_ANIM_DURATION_SLOW = 250.0f / 60.0f; // ≈ 4.1667 s static constexpr float CARD_ANIM_DURATION_SLOW = 250.0F / 60.0F; // ≈ 4.1667 s
static constexpr float CARD_ANIM_DURATION_VERY_SLOW = 300.0f / 60.0f; // ≈ 5.0000 s static constexpr float CARD_ANIM_DURATION_VERY_SLOW = 300.0F / 60.0F; // ≈ 5.0000 s
static constexpr float CARD_ANIM_DELAY_LONG_S = 7.5F; // Retraso largo antes de animación static constexpr float CARD_ANIM_DELAY_LONG_S = 7.5F; // Retraso largo antes de animación
static constexpr float CARD_OFFSET_MARGIN = 10.0F; // Margen fuera de pantalla static constexpr float CARD_OFFSET_MARGIN = 10.0F; // Margen fuera de pantalla
@@ -107,7 +107,7 @@ class Intro {
void renderTexts(); // Dibuja los textos void renderTexts(); // Dibuja los textos
static void renderTextRect(); // Dibuja el rectangulo de fondo del texto; static void renderTextRect(); // Dibuja el rectangulo de fondo del texto;
void updatePostState(); // Actualiza el estado POST void updatePostState(); // Actualiza el estado POST
float calculateDeltaTime(); // Calcula el tiempo transcurrido desde el último frame auto calculateDeltaTime() -> float; // Calcula el tiempo transcurrido desde el último frame
// --- Métodos para manejar cada escena individualmente --- // --- Métodos para manejar cada escena individualmente ---
void updateScene0(); void updateScene0();

View File

@@ -1,12 +1,14 @@
#include "logo.hpp" #include "logo.hpp"
#include <SDL3/SDL.h> // Para SDL_GetTicks, SDL_PollEvent, SDL_Event, SDL_FRect #include <SDL3/SDL.h> // Para SDL_GetTicks, SDL_PollEvent, SDL_Event, SDL_FRect, Uint64
#include <cstddef> // Para size_t
#include <string> // Para basic_string
#include <utility> // Para move #include <utility> // Para move
#include "audio.hpp" // Para Audio #include "audio.hpp" // Para Audio
#include "color.hpp" // Para Color #include "color.hpp" // Para Color
#include "global_events.hpp" // Para check #include "global_events.hpp" // Para handle
#include "global_inputs.hpp" // Para check #include "global_inputs.hpp" // Para check
#include "input.hpp" // Para Input #include "input.hpp" // Para Input
#include "param.hpp" // Para Param, ParamGame, param #include "param.hpp" // Para Param, ParamGame, param
@@ -118,16 +120,16 @@ void Logo::updateJAILGAMES(float delta_time) {
void Logo::updateTextureColors(float delta_time) { void Logo::updateTextureColors(float delta_time) {
// Manejo de 'sinceTexture' // Manejo de 'sinceTexture'
for (int i = 0; i <= MAX_SINCE_COLOR_INDEX; ++i) { for (int i = 0; i <= MAX_SINCE_COLOR_INDEX; ++i) {
const float target_time = SHOW_SINCE_SPRITE_TIME_S + COLOR_CHANGE_INTERVAL_S * i; const float TARGET_TIME = SHOW_SINCE_SPRITE_TIME_S + (COLOR_CHANGE_INTERVAL_S * i);
if (elapsed_time_s_ >= target_time && elapsed_time_s_ - delta_time < target_time) { if (elapsed_time_s_ >= TARGET_TIME && elapsed_time_s_ - delta_time < TARGET_TIME) {
since_texture_->setColor(color_[i].r, color_[i].g, color_[i].b); since_texture_->setColor(color_[i].r, color_[i].g, color_[i].b);
} }
} }
// Manejo de 'jailTexture' y 'sinceTexture' en el fade // Manejo de 'jailTexture' y 'sinceTexture' en el fade
for (int i = 0; i <= MAX_FADE_COLOR_INDEX; ++i) { for (int i = 0; i <= MAX_FADE_COLOR_INDEX; ++i) {
const float target_time = INIT_FADE_TIME_S + COLOR_CHANGE_INTERVAL_S * i; const float TARGET_TIME = INIT_FADE_TIME_S + (COLOR_CHANGE_INTERVAL_S * i);
if (elapsed_time_s_ >= target_time && elapsed_time_s_ - delta_time < target_time) { if (elapsed_time_s_ >= TARGET_TIME && elapsed_time_s_ - delta_time < TARGET_TIME) {
jail_texture_->setColor(color_[MAX_FADE_COLOR_INDEX - i].r, color_[MAX_FADE_COLOR_INDEX - i].g, color_[MAX_FADE_COLOR_INDEX - i].b); jail_texture_->setColor(color_[MAX_FADE_COLOR_INDEX - i].r, color_[MAX_FADE_COLOR_INDEX - i].g, color_[MAX_FADE_COLOR_INDEX - i].b);
since_texture_->setColor(color_[MAX_FADE_COLOR_INDEX - i].r, color_[MAX_FADE_COLOR_INDEX - i].g, color_[MAX_FADE_COLOR_INDEX - i].b); since_texture_->setColor(color_[MAX_FADE_COLOR_INDEX - i].r, color_[MAX_FADE_COLOR_INDEX - i].g, color_[MAX_FADE_COLOR_INDEX - i].b);
} }
@@ -160,11 +162,11 @@ void Logo::render() {
} }
// Calcula el tiempo transcurrido desde el último frame // Calcula el tiempo transcurrido desde el último frame
float Logo::calculateDeltaTime() { auto Logo::calculateDeltaTime() -> float {
const Uint64 current_time = SDL_GetTicks(); const Uint64 CURRENT_TIME = SDL_GetTicks();
const float delta_time = static_cast<float>(current_time - last_time_) / 1000.0f; // Convertir ms a segundos const float DELTA_TIME = static_cast<float>(CURRENT_TIME - last_time_) / 1000.0F; // Convertir ms a segundos
last_time_ = current_time; last_time_ = CURRENT_TIME;
return delta_time; return DELTA_TIME;
} }
// Bucle para el logo del juego // Bucle para el logo del juego
@@ -172,10 +174,10 @@ void Logo::run() {
last_time_ = SDL_GetTicks(); last_time_ = SDL_GetTicks();
while (Section::name == Section::Name::LOGO) { while (Section::name == Section::Name::LOGO) {
const float delta_time = calculateDeltaTime(); const float DELTA_TIME = calculateDeltaTime();
checkInput(); checkInput();
update(delta_time); update(DELTA_TIME);
checkEvents(); // Tiene que ir antes del render checkEvents(); // Tiene que ir antes del render
render(); render();
} }

View File

@@ -2,12 +2,12 @@
#include <SDL3/SDL.h> // Para SDL_FPoint, Uint64 #include <SDL3/SDL.h> // Para SDL_FPoint, Uint64
#include <memory> // Para unique_ptr, shared_ptr #include <memory> // Para shared_ptr, unique_ptr
#include <vector> // Para vector #include <vector> // Para vector
#include "color.hpp" // Para Color #include "color.hpp" // for Color
#include "sprite.hpp" // Para Sprite
class Sprite;
class Texture; class Texture;
// --- Clase Logo: pantalla de presentación de JAILGAMES con efectos retro --- // --- Clase Logo: pantalla de presentación de JAILGAMES con efectos retro ---
@@ -36,13 +36,13 @@ class Logo {
private: private:
// --- Constantes de tiempo (en segundos) --- // --- Constantes de tiempo (en segundos) ---
static constexpr float SOUND_TRIGGER_TIME_S = 0.5f; // Tiempo para activar el sonido del logo static constexpr float SOUND_TRIGGER_TIME_S = 0.5F; // Tiempo para activar el sonido del logo
static constexpr float SHOW_SINCE_SPRITE_TIME_S = 1.167f; // Tiempo para mostrar el sprite "SINCE 1998" static constexpr float SHOW_SINCE_SPRITE_TIME_S = 1.167F; // Tiempo para mostrar el sprite "SINCE 1998"
static constexpr float INIT_FADE_TIME_S = 5.0f; // Tiempo de inicio del fade a negro static constexpr float INIT_FADE_TIME_S = 5.0F; // Tiempo de inicio del fade a negro
static constexpr float END_LOGO_TIME_S = 6.668f; // Tiempo de finalización del logo static constexpr float END_LOGO_TIME_S = 6.668F; // Tiempo de finalización del logo
static constexpr float POST_LOGO_DURATION_S = 0.333f; // Duración adicional después del fade static constexpr float POST_LOGO_DURATION_S = 0.333F; // Duración adicional después del fade
static constexpr float LOGO_SPEED_PX_PER_S = 480.0f; // Velocidad de desplazamiento (píxeles por segundo) - 8.0f/16.67f*1000 static constexpr float LOGO_SPEED_PX_PER_S = 480.0F; // Velocidad de desplazamiento (píxeles por segundo) - 8.0f/16.67f*1000
static constexpr float COLOR_CHANGE_INTERVAL_S = 0.0667f; // Intervalo entre cambios de color (~4 frames a 60fps) static constexpr float COLOR_CHANGE_INTERVAL_S = 0.0667F; // Intervalo entre cambios de color (~4 frames a 60fps)
// --- Constantes de layout --- // --- Constantes de layout ---
static constexpr int SINCE_SPRITE_Y_OFFSET = 83; // Posición Y base del sprite "Since 1998" static constexpr int SINCE_SPRITE_Y_OFFSET = 83; // Posición Y base del sprite "Since 1998"
@@ -73,7 +73,7 @@ class Logo {
// --- Variables --- // --- Variables ---
std::vector<Color> color_; // Vector con los colores para el fade std::vector<Color> color_; // Vector con los colores para el fade
float elapsed_time_s_ = 0.0f; // Tiempo transcurrido en segundos float elapsed_time_s_ = 0.0F; // Tiempo transcurrido en segundos
Uint64 last_time_ = 0; // Último timestamp para calcular delta-time Uint64 last_time_ = 0; // Último timestamp para calcular delta-time
SDL_FPoint dest_; // Posición donde dibujar el logo SDL_FPoint dest_; // Posición donde dibujar el logo
bool sound_triggered_ = false; // Indica si el sonido del logo ya se reprodujo bool sound_triggered_ = false; // Indica si el sonido del logo ya se reprodujo
@@ -87,5 +87,5 @@ class Logo {
void renderJAILGAMES(); // Renderiza el logo de JAILGAMES void renderJAILGAMES(); // Renderiza el logo de JAILGAMES
void updateTextureColors(float delta_time); // Gestiona el color de las texturas void updateTextureColors(float delta_time); // Gestiona el color de las texturas
void handleSound(); // Maneja la reproducción del sonido del logo void handleSound(); // Maneja la reproducción del sonido del logo
float calculateDeltaTime(); // Calcula el tiempo transcurrido desde el último frame auto calculateDeltaTime() -> float; // Calcula el tiempo transcurrido desde el último frame
}; };

View File

@@ -1,16 +1,16 @@
#include "title.hpp" #include "title.hpp"
#include <SDL3/SDL.h> // Para SDL_GetTicks, Uint32, SDL_Event, SDL_PollEvent, SDL_EventType #include <SDL3/SDL.h> // Para SDL_GetTicks, SDL_Event, SDL_Keycode, SDL_PollEvent, SDLK_A, SDLK_C, SDLK_D, SDLK_F, SDLK_S, SDLK_V, SDLK_X, SDLK_Z, SDL_EventType, Uint64
#include <algorithm> // Para max, find_if #include <ranges> // Para __find_if_fn, find_if
#include <string> // Para operator+, char_traits, to_string, string, basic_string #include <string> // Para basic_string, char_traits, operator+, to_string, string
#include <vector> // Para vector #include <vector> // Para vector
#include "audio.hpp" // Para Audio #include "audio.hpp" // Para Audio
#include "color.hpp" // Para Colors::NO_COLOR_MOD, Colors::TITLE_SHADOW_TEXT #include "color.hpp" // Para Color, NO_COLOR_MOD, TITLE_SHADOW_TEXT
#include "fade.hpp" // Para Fade, FadeType #include "fade.hpp" // Para Fade
#include "game_logo.hpp" // Para GameLogo #include "game_logo.hpp" // Para GameLogo
#include "global_events.hpp" // Para check #include "global_events.hpp" // Para handle
#include "global_inputs.hpp" // Para check #include "global_inputs.hpp" // Para check
#include "input.hpp" // Para Input #include "input.hpp" // Para Input
#include "input_types.hpp" // Para InputAction #include "input_types.hpp" // Para InputAction
@@ -31,8 +31,8 @@
class Texture; class Texture;
#ifdef _DEBUG #ifdef _DEBUG
#include <iomanip> // Para operator<<, setfill, setw #include <iomanip> // Para operator<<, setfill, setw
#include <iostream> #include <iostream> // Para basic_ostream, basic_ostream::operator<<, operator<<, cout, hex
#endif #endif
// Constructor // Constructor
@@ -84,23 +84,23 @@ Title::~Title() {
} }
// Actualiza las variables del objeto // Actualiza las variables del objeto
void Title::update(float deltaTime) { void Title::update(float delta_time) {
static auto* const SCREEN = Screen::get(); static auto* const SCREEN = Screen::get();
SCREEN->update(deltaTime); // Actualiza el objeto screen SCREEN->update(delta_time); // Actualiza el objeto screen
Audio::update(); // Actualiza el objeto audio Audio::update(); // Actualiza el objeto audio
updateFade(); updateFade();
updateState(deltaTime); updateState(delta_time);
updateStartPrompt(deltaTime); updateStartPrompt(delta_time);
updatePlayers(deltaTime); updatePlayers(delta_time);
} }
// Calcula el tiempo transcurrido desde el último frame // Calcula el tiempo transcurrido desde el último frame
float Title::calculateDeltaTime() { auto Title::calculateDeltaTime() -> float {
const Uint64 current_time = SDL_GetTicks(); const Uint64 CURRENT_TIME = SDL_GetTicks();
const float delta_time = static_cast<float>(current_time - last_time_) / 1000.0f; // Convert ms to seconds const float DELTA_TIME = static_cast<float>(CURRENT_TIME - last_time_) / 1000.0F; // Convert ms to seconds
last_time_ = current_time; last_time_ = CURRENT_TIME;
return delta_time; return DELTA_TIME;
} }
// Dibuja el objeto en pantalla // Dibuja el objeto en pantalla
@@ -145,7 +145,7 @@ void Title::handleKeyDownEvent(const SDL_Event& event) {
void Title::handleDebugColorKeys(SDL_Keycode key) { void Title::handleDebugColorKeys(SDL_Keycode key) {
adjustColorComponent(key, debug_color_); adjustColorComponent(key, debug_color_);
counter_time_ = 0.0f; counter_time_ = 0.0F;
tiled_bg_->setColor(debug_color_); tiled_bg_->setColor(debug_color_);
printColorValue(debug_color_); printColorValue(debug_color_);
} }
@@ -299,7 +299,7 @@ void Title::processPlayer2Start() {
void Title::activatePlayerAndSetState(Player::Id player_id) { void Title::activatePlayerAndSetState(Player::Id player_id) {
getPlayer(player_id)->setPlayingState(Player::State::TITLE_ANIMATION); getPlayer(player_id)->setPlayingState(Player::State::TITLE_ANIMATION);
setState(State::START_HAS_BEEN_PRESSED); setState(State::START_HAS_BEEN_PRESSED);
counter_time_ = 0.0f; counter_time_ = 0.0F;
} }
// Bucle para el titulo del juego // Bucle para el titulo del juego
@@ -307,17 +307,17 @@ void Title::run() {
last_time_ = SDL_GetTicks(); last_time_ = SDL_GetTicks();
while (Section::name == Section::Name::TITLE) { while (Section::name == Section::Name::TITLE) {
const float delta_time = calculateDeltaTime(); const float DELTA_TIME = calculateDeltaTime();
checkInput(); checkInput();
update(delta_time); update(DELTA_TIME);
checkEvents(); // Tiene que ir antes del render checkEvents(); // Tiene que ir antes del render
render(); render();
} }
} }
// Reinicia el contador interno // Reinicia el contador interno
void Title::resetCounter() { counter_time_ = 0.0f; } void Title::resetCounter() { counter_time_ = 0.0F; }
// Intercambia la asignación de mandos a los jugadores // Intercambia la asignación de mandos a los jugadores
void Title::swapControllers() { void Title::swapControllers() {
@@ -379,9 +379,9 @@ void Title::updateFade() {
} }
// Actualiza el estado // Actualiza el estado
void Title::updateState(float deltaTime) { void Title::updateState(float delta_time) {
game_logo_->update(deltaTime); game_logo_->update(delta_time);
tiled_bg_->update(deltaTime); tiled_bg_->update(delta_time);
// Establece la lógica según el estado // Establece la lógica según el estado
switch (state_) { switch (state_) {
@@ -392,7 +392,7 @@ void Title::updateState(float deltaTime) {
break; break;
} }
case State::LOGO_FINISHED: { case State::LOGO_FINISHED: {
counter_time_ += deltaTime; counter_time_ += delta_time;
if (counter_time_ >= param.title.title_duration) { if (counter_time_ >= param.title.title_duration) {
// El menu ha hecho time out // El menu ha hecho time out
@@ -403,7 +403,7 @@ void Title::updateState(float deltaTime) {
break; break;
} }
case State::START_HAS_BEEN_PRESSED: { case State::START_HAS_BEEN_PRESSED: {
counter_time_ += deltaTime; counter_time_ += delta_time;
if (counter_time_ >= START_PRESSED_DELAY_S) { if (counter_time_ >= START_PRESSED_DELAY_S) {
fade_->activate(); fade_->activate();
@@ -416,12 +416,12 @@ void Title::updateState(float deltaTime) {
} }
} }
void Title::updateStartPrompt(float deltaTime) { void Title::updateStartPrompt(float delta_time) {
blink_accumulator_ += deltaTime; blink_accumulator_ += delta_time;
bool condition_met = false; bool condition_met = false;
float period = 0.0f; float period = 0.0F;
float on_time = 0.0f; float on_time = 0.0F;
switch (state_) { switch (state_) {
case State::LOGO_FINISHED: case State::LOGO_FINISHED:
@@ -438,7 +438,7 @@ void Title::updateStartPrompt(float deltaTime) {
break; break;
} }
if (period > 0.0f) { if (period > 0.0F) {
// Reset accumulator when it exceeds the period // Reset accumulator when it exceeds the period
if (blink_accumulator_ >= period) { if (blink_accumulator_ >= period) {
blink_accumulator_ -= period; blink_accumulator_ -= period;
@@ -494,11 +494,11 @@ void Title::setState(State state) {
case State::LOGO_FINISHED: case State::LOGO_FINISHED:
Audio::get()->playMusic("title.ogg"); Audio::get()->playMusic("title.ogg");
tiled_bg_->changeSpeedTo(60.0F, 0.5F); tiled_bg_->changeSpeedTo(60.0F, 0.5F);
blink_accumulator_ = 0.0f; // Resetea el timer para empezar el parpadeo desde el inicio blink_accumulator_ = 0.0F; // Resetea el timer para empezar el parpadeo desde el inicio
break; break;
case State::START_HAS_BEEN_PRESSED: case State::START_HAS_BEEN_PRESSED:
Audio::get()->fadeOutMusic(MUSIC_FADE_OUT_LONG_MS); Audio::get()->fadeOutMusic(MUSIC_FADE_OUT_LONG_MS);
blink_accumulator_ = 0.0f; // Resetea el timer para empezar el parpadeo desde el inicio blink_accumulator_ = 0.0F; // Resetea el timer para empezar el parpadeo desde el inicio
break; break;
} }
} }
@@ -568,9 +568,9 @@ void Title::initPlayers() {
} }
// Actualiza los jugadores // Actualiza los jugadores
void Title::updatePlayers(float deltaTime) { void Title::updatePlayers(float delta_time) {
for (auto& player : players_) { for (auto& player : players_) {
player->update(deltaTime); player->update(delta_time);
} }
} }

View File

@@ -1,13 +1,15 @@
#pragma once #pragma once
#include <SDL3/SDL.h> // Para SDL_Event, Uint64 #include <SDL3/SDL.h> // Para SDL_Keycode, SDL_Event, Uint64
#include <cstdint> // Para uint8_t
#include <memory> // Para shared_ptr, unique_ptr #include <memory> // Para shared_ptr, unique_ptr
#include <string_view> // Para string_view #include <string_view> // Para string_view
#include <vector> // Para vector #include <vector> // Para vector
#include "player.hpp" // Para Player #include "color.hpp" // for Color
#include "section.hpp" // Para Options, Name (ptr only) #include "player.hpp" // for Player
#include "section.hpp" // for Options, Name (ptr only)
class Fade; class Fade;
class GameLogo; class GameLogo;
@@ -46,15 +48,15 @@ class Title {
private: private:
// --- Constantes de tiempo (en segundos) --- // --- Constantes de tiempo (en segundos) ---
static constexpr float START_PRESSED_DELAY_S = 1666.67f / 1000.0f; // Tiempo antes de fade tras pulsar start (100 frames a 60fps) static constexpr float START_PRESSED_DELAY_S = 1666.67F / 1000.0F; // Tiempo antes de fade tras pulsar start (100 frames a 60fps)
static constexpr int MUSIC_FADE_OUT_LONG_MS = 1500; // Fade out largo de música static constexpr int MUSIC_FADE_OUT_LONG_MS = 1500; // Fade out largo de música
static constexpr int MUSIC_FADE_OUT_SHORT_MS = 300; // Fade out corto de música static constexpr int MUSIC_FADE_OUT_SHORT_MS = 300; // Fade out corto de música
// --- Constantes de parpadeo (en segundos) --- // --- Constantes de parpadeo (en segundos) ---
static constexpr float LOGO_BLINK_PERIOD_S = 833.0f / 1000.0f; // Período de parpadeo del logo (833ms) static constexpr float LOGO_BLINK_PERIOD_S = 833.0F / 1000.0F; // Período de parpadeo del logo (833ms)
static constexpr float LOGO_BLINK_ON_TIME_S = 583.0f / 1000.0f; // Tiempo encendido del logo (583ms) static constexpr float LOGO_BLINK_ON_TIME_S = 583.0F / 1000.0F; // Tiempo encendido del logo (583ms)
static constexpr float START_BLINK_PERIOD_S = 167.0f / 1000.0f; // Período de parpadeo del start (167ms) static constexpr float START_BLINK_PERIOD_S = 167.0F / 1000.0F; // Período de parpadeo del start (167ms)
static constexpr float START_BLINK_ON_TIME_S = 83.0f / 1000.0f; // Tiempo encendido del start (83ms) static constexpr float START_BLINK_ON_TIME_S = 83.0F / 1000.0F; // Tiempo encendido del start (83ms)
// --- Constantes de layout --- // --- Constantes de layout ---
static constexpr int MINI_LOGO_Y_DIVISOR = 5; // Divisor para posición Y del mini logo static constexpr int MINI_LOGO_Y_DIVISOR = 5; // Divisor para posición Y del mini logo
@@ -92,8 +94,8 @@ class Title {
Section::Options selection_ = Section::Options::TITLE_TIME_OUT; // Opción elegida en el título Section::Options selection_ = Section::Options::TITLE_TIME_OUT; // Opción elegida en el título
State state_; // Estado actual de la sección State state_; // Estado actual de la sección
Uint64 last_time_ = 0; // Último timestamp para calcular delta-time Uint64 last_time_ = 0; // Último timestamp para calcular delta-time
float counter_time_ = 0.0f; // Temporizador para la pantalla de título (en segundos) float counter_time_ = 0.0F; // Temporizador para la pantalla de título (en segundos)
float blink_accumulator_ = 0.0f; // Acumulador para el parpadeo (en segundos) float blink_accumulator_ = 0.0F; // Acumulador para el parpadeo (en segundos)
int num_controllers_; // Número de mandos conectados int num_controllers_; // Número de mandos conectados
bool should_render_start_prompt_ = false; // Indica si se muestra el texto de PRESS START BUTTON TO PLAY bool should_render_start_prompt_ = false; // Indica si se muestra el texto de PRESS START BUTTON TO PLAY
bool player1_start_pressed_ = false; // Indica si se ha pulsado el botón de empezar para el jugador 1 bool player1_start_pressed_ = false; // Indica si se ha pulsado el botón de empezar para el jugador 1
@@ -104,11 +106,11 @@ class Title {
#endif #endif
// --- Ciclo de vida del título --- // --- Ciclo de vida del título ---
void update(float deltaTime); // Actualiza las variables del objeto void update(float delta_time); // Actualiza las variables del objeto
float calculateDeltaTime(); // Calcula el tiempo transcurrido desde el último frame auto calculateDeltaTime() -> float; // Calcula el tiempo transcurrido desde el último frame
void updateState(float deltaTime); // Actualiza el estado actual del título void updateState(float delta_time); // Actualiza el estado actual del título
void setState(State state); // Cambia el estado del título void setState(State state); // Cambia el estado del título
void resetCounter(); // Reinicia el contador interno void resetCounter(); // Reinicia el contador interno
// --- Entrada de usuario --- // --- Entrada de usuario ---
void checkEvents(); // Comprueba los eventos void checkEvents(); // Comprueba los eventos
@@ -125,16 +127,16 @@ class Title {
// --- Gestión de jugadores --- // --- Gestión de jugadores ---
void initPlayers(); // Inicializa los jugadores void initPlayers(); // Inicializa los jugadores
void updatePlayers(float deltaTime); // Actualiza los jugadores void updatePlayers(float delta_time); // Actualiza los jugadores
void renderPlayers(); // Renderiza los jugadores void renderPlayers(); // Renderiza los jugadores
auto getPlayer(Player::Id id) -> std::shared_ptr<Player>; // Obtiene un jugador a partir de su "id" auto getPlayer(Player::Id id) -> std::shared_ptr<Player>; // Obtiene un jugador a partir de su "id"
// --- Visualización / Renderizado --- // --- Visualización / Renderizado ---
void render(); // Dibuja el objeto en pantalla void render(); // Dibuja el objeto en pantalla
void updateFade(); // Actualiza el efecto de fundido (fade in/out) void updateFade(); // Actualiza el efecto de fundido (fade in/out)
void updateStartPrompt(float deltaTime); // Actualiza el mensaje de "Pulsa Start" void updateStartPrompt(float delta_time); // Actualiza el mensaje de "Pulsa Start"
void renderStartPrompt(); // Dibuja el mensaje de "Pulsa Start" en pantalla void renderStartPrompt(); // Dibuja el mensaje de "Pulsa Start" en pantalla
void renderCopyright(); // Dibuja el aviso de copyright void renderCopyright(); // Dibuja el aviso de copyright
// --- Utilidades estáticas --- // --- Utilidades estáticas ---
static void swapControllers(); // Intercambia la asignación de mandos a los jugadores static void swapControllers(); // Intercambia la asignación de mandos a los jugadores

View File

@@ -1,16 +1,16 @@
#include "shutdown.hpp" #include "shutdown.hpp"
#include <array> #include <sys/types.h> // Para pid_t
#include <iostream>
#include <vector> #include <cstdlib> // Para WEXITSTATUS
#include <iostream> // Para char_traits, basic_ostream, operator<<, cerr
#include <vector> // Para vector
#ifdef _WIN32 #ifdef _WIN32
#include <windows.h> #include <windows.h>
#else #else
#include <sys/wait.h> #include <sys/wait.h> // Para waitpid
#include <unistd.h> #include <unistd.h> // Para _exit, execvp, fork
#include <string>
#endif #endif
namespace SystemShutdown { namespace SystemShutdown {

View File

@@ -3,11 +3,11 @@
#include "moving_sprite.hpp" // Para MovingSprite #include "moving_sprite.hpp" // Para MovingSprite
// Actualiza la posición y comprueba si ha llegado a su destino (time-based) // Actualiza la posición y comprueba si ha llegado a su destino (time-based)
void SmartSprite::update(float deltaTime) { void SmartSprite::update(float delta_time) {
if (enabled_) { if (enabled_) {
MovingSprite::update(deltaTime); MovingSprite::update(delta_time);
checkMove(); checkMove();
checkFinished(deltaTime); checkFinished(delta_time);
} }
} }
@@ -72,15 +72,15 @@ void SmartSprite::checkMove() {
} }
// Comprueba si ha terminado (time-based) // Comprueba si ha terminado (time-based)
void SmartSprite::checkFinished(float deltaTime) { void SmartSprite::checkFinished(float delta_time) {
// Comprueba si ha llegado a su destino // Comprueba si ha llegado a su destino
on_destination_ = (getPosX() == dest_x_ && getPosY() == dest_y_); on_destination_ = (getPosX() == dest_x_ && getPosY() == dest_y_);
if (on_destination_) { if (on_destination_) {
if (finished_delay_ms_ == 0.0f) { if (finished_delay_ms_ == 0.0F) {
finished_ = true; finished_ = true;
} else { } else {
finished_timer_ += deltaTime; finished_timer_ += delta_time;
if (finished_timer_ >= finished_delay_ms_) { if (finished_timer_ >= finished_delay_ms_) {
finished_ = true; finished_ = true;
} }

View File

@@ -16,8 +16,8 @@ class SmartSprite : public AnimatedSprite {
~SmartSprite() override = default; ~SmartSprite() override = default;
// --- Métodos principales --- // --- Métodos principales ---
void update(float deltaTime) override; // Actualiza la posición y comprueba si ha llegado a su destino (time-based) void update(float delta_time) override; // Actualiza la posición y comprueba si ha llegado a su destino (time-based)
void render() override; // Dibuja el sprite void render() override; // Dibuja el sprite
// --- Getters --- // --- Getters ---
auto getDestX() const -> int { return dest_x_; } // Obtiene la posición de destino en X auto getDestX() const -> int { return dest_x_; } // Obtiene la posición de destino en X
@@ -35,13 +35,13 @@ class SmartSprite : public AnimatedSprite {
// --- Variables de estado --- // --- Variables de estado ---
int dest_x_ = 0; // Posición de destino en el eje X int dest_x_ = 0; // Posición de destino en el eje X
int dest_y_ = 0; // Posición de destino en el eje Y int dest_y_ = 0; // Posición de destino en el eje Y
float finished_delay_ms_ = 0.0f; // Retraso para deshabilitarlo (ms) float finished_delay_ms_ = 0.0F; // Retraso para deshabilitarlo (ms)
float finished_timer_ = 0.0f; // Timer acumulado (ms) float finished_timer_ = 0.0F; // Timer acumulado (ms)
bool on_destination_ = false; // Indica si está en el destino bool on_destination_ = false; // Indica si está en el destino
bool finished_ = false; // Indica si ya ha terminado bool finished_ = false; // Indica si ya ha terminado
bool enabled_ = false; // Indica si el objeto está habilitado bool enabled_ = false; // Indica si el objeto está habilitado
// --- Métodos internos --- // --- Métodos internos ---
void checkFinished(float deltaTime); // Comprueba si ha terminado (time-based) void checkFinished(float delta_time); // Comprueba si ha terminado (time-based)
void checkMove(); // Comprueba el movimiento void checkMove(); // Comprueba el movimiento
}; };

View File

@@ -1,9 +1,10 @@
#include "stage.hpp" #include "stage.hpp"
#include <algorithm> #include <algorithm> // Para max, min
#include <fstream> #include <exception> // Para exception
#include <sstream> #include <fstream> // Para basic_istream, basic_ifstream, ifstream, stringstream
#include <utility> #include <sstream> // Para basic_stringstream
#include <utility> // Para move
// Implementación de StageData // Implementación de StageData
StageData::StageData(int power_to_complete, int min_menace, int max_menace, std::string name) StageData::StageData(int power_to_complete, int min_menace, int max_menace, std::string name)

View File

@@ -1,11 +1,12 @@
#pragma once #pragma once
#include <cstddef> // Para size_t
#include <functional> // Para function #include <functional> // Para function
#include <optional> // Para optional #include <optional> // Para optional
#include <string> // Para string #include <string> // Para basic_string, string
#include <vector> // Para vector #include <vector> // Para vector
#include "stage_interface.hpp" // Para IStageInfo #include "stage_interface.hpp" // for IStageInfo
// --- Enums --- // --- Enums ---
enum class PowerCollectionState { enum class PowerCollectionState {

View File

@@ -1,10 +1,9 @@
#include "system_utils.hpp" #include "system_utils.hpp"
#include <sys/stat.h> #include <sys/stat.h> // Para stat, mkdir, S_ISDIR
#include <cerrno> #include <cerrno> // Para EACCES, EEXIST, ENAMETOOLONG, errno
#include <cstdlib> #include <cstdlib> // Para getenv, size_t
#include <iostream>
#ifdef _WIN32 #ifdef _WIN32
#include <direct.h> #include <direct.h>
@@ -15,8 +14,8 @@
#undef ERROR_ALREADY_EXISTS #undef ERROR_ALREADY_EXISTS
#endif #endif
#else #else
#include <pwd.h> #include <pwd.h> // Para getpwuid, passwd
#include <unistd.h> #include <unistd.h> // Para getuid
#endif #endif
namespace SystemUtils { namespace SystemUtils {

View File

@@ -6,9 +6,10 @@
#include <algorithm> // Para max #include <algorithm> // Para max
#include <array> // Para array #include <array> // Para array
#include <cstdlib> // Para rand, abs #include <cstdlib> // Para rand, abs
#include <string> // Para basic_string
#include "audio.hpp" // Para Audio #include "audio.hpp" // Para Audio
#include "param.hpp" // Para Param, ParamGame, param #include "param.hpp" // Para Param, param, ParamGame, ParamTabe
#include "resource.hpp" // Para Resource #include "resource.hpp" // Para Resource
#include "utils.hpp" // Para Zone #include "utils.hpp" // Para Zone
@@ -18,11 +19,11 @@ Tabe::Tabe()
timer_(Timer(param.tabe.min_spawn_time, param.tabe.max_spawn_time)) {} timer_(Timer(param.tabe.min_spawn_time, param.tabe.max_spawn_time)) {}
// Actualiza la lógica (time-based) // Actualiza la lógica (time-based)
void Tabe::update(float deltaTime) { void Tabe::update(float delta_time) {
if (enabled_ && !timer_.is_paused) { if (enabled_ && !timer_.is_paused) {
sprite_->update(deltaTime); sprite_->update(delta_time);
move(deltaTime); move(delta_time);
updateState(deltaTime); updateState(delta_time);
} }
timer_.update(); timer_.update();
@@ -39,10 +40,10 @@ void Tabe::render() {
} }
// Mueve el objeto (time-based) // Mueve el objeto (time-based)
void Tabe::move(float deltaTime) { void Tabe::move(float delta_time) {
const int X = static_cast<int>(x_); const int X = static_cast<int>(x_);
speed_ += accel_ * deltaTime; speed_ += accel_ * delta_time;
x_ += speed_ * deltaTime; x_ += speed_ * delta_time;
fly_distance_ -= std::abs(X - static_cast<int>(x_)); fly_distance_ -= std::abs(X - static_cast<int>(x_));
// Comprueba si sale por los bordes // Comprueba si sale por los bordes
@@ -77,8 +78,8 @@ void Tabe::move(float deltaTime) {
if (fly_distance_ <= 0) { if (fly_distance_ <= 0) {
if (waiting_counter_ > 0) { if (waiting_counter_ > 0) {
accel_ = speed_ = 0.0F; accel_ = speed_ = 0.0F;
waiting_counter_ -= deltaTime; waiting_counter_ -= delta_time;
if (waiting_counter_ < 0) waiting_counter_ = 0; waiting_counter_ = std::max<float>(waiting_counter_, 0);
} else { } else {
constexpr int CHOICES = 4; constexpr int CHOICES = 4;
const std::array<Direction, CHOICES> LEFT = { const std::array<Direction, CHOICES> LEFT = {
@@ -129,22 +130,22 @@ void Tabe::enable() {
void Tabe::setRandomFlyPath(Direction direction, int length) { void Tabe::setRandomFlyPath(Direction direction, int length) {
direction_ = direction; direction_ = direction;
fly_distance_ = length; fly_distance_ = length;
waiting_counter_ = 0.083f + (rand() % 15) * 0.0167f; // 5-20 frames converted to seconds (5/60 to 20/60) waiting_counter_ = 0.083F + (rand() % 15) * 0.0167F; // 5-20 frames converted to seconds (5/60 to 20/60)
Audio::get()->playSound("tabe.wav"); Audio::get()->playSound("tabe.wav");
constexpr float SPEED = 120.0f; // 2 pixels/frame * 60fps = 120 pixels/second constexpr float SPEED = 120.0F; // 2 pixels/frame * 60fps = 120 pixels/second
switch (direction) { switch (direction) {
case Direction::TO_THE_LEFT: { case Direction::TO_THE_LEFT: {
speed_ = -1.0F * SPEED; speed_ = -1.0F * SPEED;
accel_ = -1.0F * (1 + rand() % 10) * 2.0f; // Converted from frame-based to seconds accel_ = -1.0F * (1 + rand() % 10) * 2.0F; // Converted from frame-based to seconds
sprite_->setFlip(SDL_FLIP_NONE); sprite_->setFlip(SDL_FLIP_NONE);
break; break;
} }
case Direction::TO_THE_RIGHT: { case Direction::TO_THE_RIGHT: {
speed_ = SPEED; speed_ = SPEED;
accel_ = (1 + rand() % 10) * 2.0f; // Converted from frame-based to seconds accel_ = (1 + rand() % 10) * 2.0F; // Converted from frame-based to seconds
sprite_->setFlip(SDL_FLIP_HORIZONTAL); sprite_->setFlip(SDL_FLIP_HORIZONTAL);
break; break;
} }
@@ -166,7 +167,7 @@ void Tabe::setState(State state) {
case State::HIT: case State::HIT:
sprite_->setCurrentAnimation("hit"); sprite_->setCurrentAnimation("hit");
hit_counter_ = 0.083f; // 5 frames converted to seconds (5/60) hit_counter_ = 0.083F; // 5 frames converted to seconds (5/60)
++number_of_hits_; ++number_of_hits_;
break; break;
@@ -177,9 +178,9 @@ void Tabe::setState(State state) {
} }
// Actualiza el estado (time-based) // Actualiza el estado (time-based)
void Tabe::updateState(float deltaTime) { void Tabe::updateState(float delta_time) {
if (state_ == State::HIT) { if (state_ == State::HIT) {
hit_counter_ -= deltaTime; hit_counter_ -= delta_time;
if (hit_counter_ <= 0) { if (hit_counter_ <= 0) {
setState(State::FLY); setState(State::FLY);
} }

View File

@@ -26,14 +26,14 @@ class Tabe {
~Tabe() = default; ~Tabe() = default;
// --- Métodos principales --- // --- Métodos principales ---
void update(float deltaTime); // Actualiza la lógica (time-based) void update(float delta_time); // Actualiza la lógica (time-based)
void render(); // Dibuja el objeto void render(); // Dibuja el objeto
void enable(); // Habilita el objeto void enable(); // Habilita el objeto
void setState(State state); // Establece el estado void setState(State state); // Establece el estado
auto tryToGetBonus() -> bool; // Intenta obtener el bonus auto tryToGetBonus() -> bool; // Intenta obtener el bonus
void pauseTimer(bool value); // Detiene/activa el timer void pauseTimer(bool value); // Detiene/activa el timer
void disableSpawning(); // Deshabilita el spawning permanentemente void disableSpawning(); // Deshabilita el spawning permanentemente
void enableSpawning(); // Habilita el spawning nuevamente void enableSpawning(); // Habilita el spawning nuevamente
// --- Getters --- // --- Getters ---
auto getCollider() -> SDL_FRect& { return sprite_->getRect(); } // Obtiene el área de colisión auto getCollider() -> SDL_FRect& { return sprite_->getRect(); } // Obtiene el área de colisión
@@ -141,10 +141,10 @@ class Tabe {
Timer timer_; // Temporizador para gestionar la aparición Timer timer_; // Temporizador para gestionar la aparición
// --- Métodos internos --- // --- Métodos internos ---
void move(float deltaTime); // Mueve el objeto (time-based) void move(float delta_time); // Mueve el objeto (time-based)
void shiftSprite() { sprite_->setPos(x_, y_); } // Actualiza la posición del sprite void shiftSprite() { sprite_->setPos(x_, y_); } // Actualiza la posición del sprite
void setRandomFlyPath(Direction direction, int length); // Establece un vuelo aleatorio void setRandomFlyPath(Direction direction, int length); // Establece un vuelo aleatorio
void updateState(float deltaTime); // Actualiza el estado (time-based) void updateState(float delta_time); // Actualiza el estado (time-based)
void updateTimer(); // Actualiza el temporizador void updateTimer(); // Actualiza el temporizador
void disable(); // Deshabilita el objeto void disable(); // Deshabilita el objeto
}; };

View File

@@ -1,20 +1,21 @@
#include "text.hpp" #include "text.hpp"
#include <SDL3/SDL.h> // Para Uint8, SDL_GetRenderTarget, SDL_RenderClear, SDL_SetRenderDrawColor, SDL_SetRenderTarget, SDL_FRect, SDL_BLENDMODE_BLEND, SDL_PixelFormat, SDL_TextureAccess #include <SDL3/SDL.h> // Para SDL_FRect, Uint8, SDL_GetRenderTarget, SDL_RenderClear, SDL_SetRenderDrawColor, SDL_SetRenderTarget, SDL_BLENDMODE_BLEND, SDL_PixelFormat, SDL_TextureAccess, SDL_GetTextureAlphaMod
#include <fstream> // Para basic_ifstream, basic_istream, basic_ostream, operator<<, endl, ifstream #include <fstream> // Para basic_ifstream, basic_istream, basic_ostream, operator<<, istream, ifstream, istringstream
#include <iostream> // Para cerr #include <iostream> // Para cerr
#include <sstream> // Para istringstream #include <sstream> // Para basic_istringstream
#include <stdexcept> // Para runtime_error #include <stdexcept> // Para runtime_error
#include <string_view> // Para string_view #include <string_view> // Para string_view
#include <vector> // Para vector
#include "color.hpp" // Para Color #include "color.hpp" // Para Color
#include "resource_helper.hpp" // Para ResourceHelper #include "resource_helper.hpp" // Para loadFile
#include "screen.hpp" // Para Screen #include "screen.hpp" // Para Screen
#include "sprite.hpp" // Para Sprite #include "sprite.hpp" // Para Sprite
#include "texture.hpp" // Para Texture #include "texture.hpp" // Para Texture
#include "utils.hpp" // Para getFileName, printWithDots #include "ui/logger.hpp" // Para dots
#include "ui/logger.hpp" #include "utils.hpp" // Para getFileName
// Constructor // Constructor
Text::Text(const std::shared_ptr<Texture>& texture, const std::string& text_file) { Text::Text(const std::shared_ptr<Texture>& texture, const std::string& text_file) {

View File

@@ -16,8 +16,8 @@
#include "external/gif.hpp" // Para Gif #include "external/gif.hpp" // Para Gif
#include "resource_helper.hpp" // Para ResourceHelper #include "resource_helper.hpp" // Para ResourceHelper
#include "stb_image.h" // Para stbi_image_free, stbi_load, STBI_rgb_alpha #include "stb_image.h" // Para stbi_image_free, stbi_load, STBI_rgb_alpha
#include "utils.hpp"
#include "ui/logger.hpp" #include "ui/logger.hpp"
#include "utils.hpp"
// Constructor // Constructor
Texture::Texture(SDL_Renderer* renderer, std::string path) Texture::Texture(SDL_Renderer* renderer, std::string path)

View File

@@ -2,11 +2,12 @@
#include <SDL3/SDL.h> // Para SDL_SetRenderTarget, SDL_CreateTexture, SDL_DestroyTexture, SDL_FRect, SDL_GetRenderTarget, SDL_RenderTexture, SDL_PixelFormat, SDL_TextureAccess #include <SDL3/SDL.h> // Para SDL_SetRenderTarget, SDL_CreateTexture, SDL_DestroyTexture, SDL_FRect, SDL_GetRenderTarget, SDL_RenderTexture, SDL_PixelFormat, SDL_TextureAccess
#include <algorithm> #include <algorithm> // Para max
#include <cmath> // Para sin, pow #include <cmath> // Para cos, pow, sin
#include <cstdlib> // Para rand #include <cstdlib> // Para rand
#include <memory> // Para allocator, unique_ptr, make_unique #include <memory> // Para unique_ptr, make_unique
#include <numbers> // Para pi #include <numbers> // Para pi
#include <string> // Para basic_string
#include "resource.hpp" // Para Resource #include "resource.hpp" // Para Resource
#include "screen.hpp" // Para Screen #include "screen.hpp" // Para Screen
@@ -92,10 +93,10 @@ void TiledBG::update(float delta_time) {
} }
case TiledBGMode::CIRCLE: { case TiledBGMode::CIRCLE: {
// El tileado de fondo se desplaza en circulo // El tileado de fondo se desplaza en circulo
const float angle_rad = (desp_ * std::numbers::pi / 180.0F); const float ANGLE_RAD = (desp_ * std::numbers::pi / 180.0F);
window_.x = 128 + static_cast<int>(std::cos(angle_rad) * 128); window_.x = 128 + static_cast<int>(std::cos(ANGLE_RAD) * 128);
window_.y = 128 + static_cast<int>(std::sin(-angle_rad) * 96); window_.y = 128 + static_cast<int>(std::sin(-ANGLE_RAD) * 96);
break; break;
} }
default: default:
@@ -129,7 +130,7 @@ void TiledBG::updateStop(float delta_time) {
// Cambia la velocidad gradualmente en X segundos // Cambia la velocidad gradualmente en X segundos
void TiledBG::changeSpeedTo(float target_speed, float duration_s) { void TiledBG::changeSpeedTo(float target_speed, float duration_s) {
if (duration_s <= 0.0f) { if (duration_s <= 0.0F) {
// Si la duración es 0 o negativa, cambia inmediatamente // Si la duración es 0 o negativa, cambia inmediatamente
speed_ = target_speed; speed_ = target_speed;
changing_speed_ = false; changing_speed_ = false;
@@ -141,7 +142,7 @@ void TiledBG::changeSpeedTo(float target_speed, float duration_s) {
initial_speed_ = speed_; initial_speed_ = speed_;
target_speed_ = target_speed; target_speed_ = target_speed;
change_duration_s_ = duration_s; change_duration_s_ = duration_s;
change_timer_s_ = 0.0f; change_timer_s_ = 0.0F;
} }
// Actualiza el cambio gradual de velocidad (time-based) // Actualiza el cambio gradual de velocidad (time-based)

View File

@@ -39,9 +39,9 @@ class TiledBG {
// --- Constantes --- // --- Constantes ---
static constexpr int TILE_WIDTH = 64; // Ancho del tile static constexpr int TILE_WIDTH = 64; // Ancho del tile
static constexpr int TILE_HEIGHT = 64; // Alto del tile static constexpr int TILE_HEIGHT = 64; // Alto del tile
static constexpr float STOP_THRESHOLD_FACTOR = 20.0f; // Factor para umbral de parada static constexpr float STOP_THRESHOLD_FACTOR = 20.0F; // Factor para umbral de parada
static constexpr float DECELERATION_FACTOR = 1.05f; // Factor de desaceleración static constexpr float DECELERATION_FACTOR = 1.05F; // Factor de desaceleración
static constexpr float MIN_SPEED = 0.1f; // Velocidad mínima static constexpr float MIN_SPEED = 0.1F; // Velocidad mínima
// --- Objetos y punteros --- // --- Objetos y punteros ---
SDL_Renderer* renderer_; // El renderizador de la ventana SDL_Renderer* renderer_; // El renderizador de la ventana

View File

@@ -44,7 +44,7 @@ inline void error(const std::string& msg) {
} }
// CR // CR
inline void CR() { inline void cr() {
std::cout << "\n"; std::cout << "\n";
} }
@@ -52,7 +52,7 @@ inline void CR() {
inline void dots(const std::string& prefix, inline void dots(const std::string& prefix,
const std::string& middle, const std::string& middle,
const std::string& suffix, const std::string& suffix,
const std::string& suffixColor = GREEN) { const std::string& suffix_color = GREEN) {
size_t field_width = TOTAL_WIDTH > (prefix.size() + suffix.size()) size_t field_width = TOTAL_WIDTH > (prefix.size() + suffix.size())
? TOTAL_WIDTH - prefix.size() - suffix.size() ? TOTAL_WIDTH - prefix.size() - suffix.size()
: 0; : 0;
@@ -65,7 +65,7 @@ inline void dots(const std::string& prefix,
} }
std::cout << " " << prefix << field_text std::cout << " " << prefix << field_text
<< suffixColor << suffix << RESET << suffix_color << suffix << RESET
<< "\n"; << "\n";
} }

View File

@@ -1,8 +1,8 @@
#include "menu_option.hpp" #include "menu_option.hpp"
#include <algorithm> // Para find #include <algorithm> // Para max
#include <iterator> // Para distance #include <iterator> // Para distance
#include <memory> // Para allocator #include <ranges> // Para __find_fn, find
#include "text.hpp" // Para Text #include "text.hpp" // Para Text

View File

@@ -69,7 +69,7 @@ void Notifier::processNotification(int index, float delta_time) {
void Notifier::playNotificationSoundIfNeeded(const Notification& notification) { void Notifier::playNotificationSoundIfNeeded(const Notification& notification) {
// Hace sonar la notificación al inicio // Hace sonar la notificación al inicio
if (notification.timer <= 0.016f && if (notification.timer <= 0.016F &&
param.notification.sound && param.notification.sound &&
notification.state == State::RISING) { notification.state == State::RISING) {
Audio::get()->playSound("notify.wav", Audio::Group::INTERFACE); Audio::get()->playSound("notify.wav", Audio::Group::INTERFACE);
@@ -99,7 +99,7 @@ void Notifier::handleRisingState(int index, float delta_time) {
const float PIXELS_TO_MOVE = ANIMATION_SPEED_PX_PER_S * delta_time; const float PIXELS_TO_MOVE = ANIMATION_SPEED_PX_PER_S * delta_time;
const float PROGRESS = notification.timer * ANIMATION_SPEED_PX_PER_S / notification.travel_dist; const float PROGRESS = notification.timer * ANIMATION_SPEED_PX_PER_S / notification.travel_dist;
const int ALPHA = static_cast<int>(255 * std::min(PROGRESS, 1.0f)); const int ALPHA = static_cast<int>(255 * std::min(PROGRESS, 1.0F));
moveNotificationVertically(notification, param.notification.pos_v == Position::TOP ? PIXELS_TO_MOVE : -PIXELS_TO_MOVE); moveNotificationVertically(notification, param.notification.pos_v == Position::TOP ? PIXELS_TO_MOVE : -PIXELS_TO_MOVE);
notification.texture->setAlpha(ALPHA); notification.texture->setAlpha(ALPHA);
@@ -115,7 +115,7 @@ void Notifier::handleStayState(int index) {
if (notification.timer >= STAY_DURATION_S) { if (notification.timer >= STAY_DURATION_S) {
notification.state = State::VANISHING; notification.state = State::VANISHING;
notification.timer = 0.0f; notification.timer = 0.0F;
} }
} }
@@ -124,12 +124,12 @@ void Notifier::handleVanishingState(int index, float delta_time) {
const float PIXELS_TO_MOVE = ANIMATION_SPEED_PX_PER_S * delta_time; const float PIXELS_TO_MOVE = ANIMATION_SPEED_PX_PER_S * delta_time;
const float PROGRESS = notification.timer * ANIMATION_SPEED_PX_PER_S / notification.travel_dist; const float PROGRESS = notification.timer * ANIMATION_SPEED_PX_PER_S / notification.travel_dist;
const int ALPHA = static_cast<int>(255 * (1 - std::min(PROGRESS, 1.0f))); const int ALPHA = static_cast<int>(255 * (1 - std::min(PROGRESS, 1.0F)));
moveNotificationVertically(notification, param.notification.pos_v == Position::TOP ? -PIXELS_TO_MOVE : PIXELS_TO_MOVE); moveNotificationVertically(notification, param.notification.pos_v == Position::TOP ? -PIXELS_TO_MOVE : PIXELS_TO_MOVE);
notification.texture->setAlpha(ALPHA); notification.texture->setAlpha(ALPHA);
if (PROGRESS >= 1.0f) { if (PROGRESS >= 1.0F) {
notification.state = State::FINISHED; notification.state = State::FINISHED;
} }
} }
@@ -143,7 +143,7 @@ void Notifier::transitionToStayState(int index) {
notification.state = State::STAY; notification.state = State::STAY;
notification.texture->setAlpha(255); notification.texture->setAlpha(255);
notification.rect.y = static_cast<float>(notification.y); // Asegurar posición exacta notification.rect.y = static_cast<float>(notification.y); // Asegurar posición exacta
notification.timer = 0.0f; notification.timer = 0.0F;
} }
// Elimina las notificaciones finalizadas // Elimina las notificaciones finalizadas

View File

@@ -42,8 +42,8 @@ class Notifier {
private: private:
// --- Constantes de tiempo (en segundos) --- // --- Constantes de tiempo (en segundos) ---
static constexpr float STAY_DURATION_S = 2.5f; // Tiempo que se ve la notificación (150 frames @ 60fps) static constexpr float STAY_DURATION_S = 2.5F; // Tiempo que se ve la notificación (150 frames @ 60fps)
static constexpr float ANIMATION_SPEED_PX_PER_S = 60.0f; // Velocidad de animación (1 pixel/frame @ 60fps) static constexpr float ANIMATION_SPEED_PX_PER_S = 60.0F; // Velocidad de animación (1 pixel/frame @ 60fps)
// --- Enums privados --- // --- Enums privados ---
enum class State { enum class State {
@@ -67,7 +67,7 @@ class Notifier {
std::string code; // Código identificador de la notificación std::string code; // Código identificador de la notificación
State state{State::RISING}; // Estado de la notificación State state{State::RISING}; // Estado de la notificación
Shape shape{Shape::SQUARED}; // Forma de la notificación Shape shape{Shape::SQUARED}; // Forma de la notificación
float timer{0.0f}; // Timer en segundos float timer{0.0F}; // Timer en segundos
int y{0}; // Posición vertical int y{0}; // Posición vertical
int travel_dist{0}; // Distancia a recorrer int travel_dist{0}; // Distancia a recorrer

View File

@@ -4,13 +4,14 @@
#include <cstddef> // Para size_t #include <cstddef> // Para size_t
#include <functional> // Para function #include <functional> // Para function
#include <iterator> // Para pair
#include <memory> // Para unique_ptr #include <memory> // Para unique_ptr
#include <string> // Para string #include <string> // Para basic_string, string
#include <utility> // Para pair #include <utility> // Para pair
#include <vector> // Para vector #include <vector> // Para vector
#include "define_buttons.hpp" // Para DefineButtons #include "define_buttons.hpp" // for DefineButtons
#include "ui_message.hpp" // Para UIMessage #include "ui_message.hpp" // for UIMessage
class MenuOption; class MenuOption;
class MenuRenderer; class MenuRenderer;

View File

@@ -1,5 +1,6 @@
#include "ui_message.hpp" #include "ui_message.hpp"
#include <algorithm>
#include <cmath> // Para pow #include <cmath> // Para pow
#include <utility> #include <utility>
@@ -20,7 +21,7 @@ void UIMessage::show() {
start_y_ = DESP; // Empieza 8 píxeles arriba de la posición base start_y_ = DESP; // Empieza 8 píxeles arriba de la posición base
target_y_ = 0.0F; // La posición final es la base target_y_ = 0.0F; // La posición final es la base
y_offset_ = start_y_; y_offset_ = start_y_;
animation_timer_ = 0.0f; animation_timer_ = 0.0F;
animating_ = true; animating_ = true;
visible_ = true; visible_ = true;
} }
@@ -33,7 +34,7 @@ void UIMessage::hide() {
start_y_ = y_offset_; // Comienza desde la posición actual start_y_ = y_offset_; // Comienza desde la posición actual
target_y_ = DESP; // Termina 8 píxeles arriba de la base target_y_ = DESP; // Termina 8 píxeles arriba de la base
animation_timer_ = 0.0f; animation_timer_ = 0.0F;
animating_ = true; animating_ = true;
} }
@@ -50,9 +51,7 @@ void UIMessage::updateAnimation(float delta_time) {
float t = animation_timer_ / ANIMATION_DURATION_S; float t = animation_timer_ / ANIMATION_DURATION_S;
// Clamp t entre 0 y 1 // Clamp t entre 0 y 1
if (t > 1.0f) { t = std::min(t, 1.0f);
t = 1.0f;
}
if (target_y_ > start_y_) { if (target_y_ > start_y_) {
// Animación de entrada (ease out cubic) // Animación de entrada (ease out cubic)
@@ -67,7 +66,7 @@ void UIMessage::updateAnimation(float delta_time) {
if (animation_timer_ >= ANIMATION_DURATION_S) { if (animation_timer_ >= ANIMATION_DURATION_S) {
y_offset_ = target_y_; y_offset_ = target_y_;
animating_ = false; animating_ = false;
animation_timer_ = 0.0f; // Reset timer animation_timer_ = 0.0F; // Reset timer
if (target_y_ < 0.0F) { if (target_y_ < 0.0F) {
visible_ = false; visible_ = false;
} }

View File

@@ -48,7 +48,7 @@ class UIMessage {
float start_y_ = 0.0F; // Posición Y inicial de la animación float start_y_ = 0.0F; // Posición Y inicial de la animación
float target_y_ = 0.0F; // Posición Y objetivo de la animación float target_y_ = 0.0F; // Posición Y objetivo de la animación
float animation_timer_ = 0.0F; // Timer actual de la animación en segundos float animation_timer_ = 0.0F; // Timer actual de la animación en segundos
static constexpr float ANIMATION_DURATION_S = 0.133f; // Duración total de la animación (8 frames @ 60fps) static constexpr float ANIMATION_DURATION_S = 0.133F; // Duración total de la animación (8 frames @ 60fps)
static constexpr float DESP = -8.0F; // Distancia a desplazarse static constexpr float DESP = -8.0F; // Distancia a desplazarse
// Actualiza la interpolación de la animación (ease out/in cubic) // Actualiza la interpolación de la animación (ease out/in cubic)

View File

@@ -1,19 +1,17 @@
#define _USE_MATH_DEFINES #define _USE_MATH_DEFINES
#include "utils.hpp" #include "utils.hpp"
#include <SDL3/SDL.h> // Para SDL_RenderPoint, SDL_FRect, SDL_FPoint, SDL_CloseIO, SDL_IOFromFile, SDL_LogCategory, SDL_LogError, SDL_LogInfo, SDL_ReadIO, SDL_Renderer #include <SDL3/SDL.h> // Para SDL_RenderPoint, SDL_FRect, SDL_FPoint, SDL_Renderer
#include <algorithm> // Para clamp, find_if_not, find, transform #include <algorithm> // Para clamp, __transform_fn, transform
#include <cctype> // Para tolower, isspace #include <cctype> // Para tolower, isspace
#include <cmath> // Para pow, sin, M_PI, cos, sqrt #include <cmath> // Para pow, sin, M_PI, cos, sqrt
#include <compare> // Para operator<, __synth3way_t #include <compare> // Para operator<
#include <filesystem> // Para path #include <filesystem> // Para path
#include <ranges> #include <ranges> // Para __find_if_not_fn, find_if_not, reverse_view, __find_fn, find, ref_view
#include <stdexcept> // Para runtime_error #include <string> // Para basic_string, string, allocator, char_traits, operator==, operator+
#include <string> // Para basic_string, allocator, string, operator==, operator+, char_traits
#include "lang.hpp" // Para getText #include "lang.hpp" // Para getText
#include "resource_helper.hpp" // Para ResourceHelper
// Variables // Variables
Overrides overrides = Overrides(); Overrides overrides = Overrides();

View File

@@ -83,8 +83,8 @@ auto easeOutCubic(double time) -> double;
auto easeInCubic(double time) -> double; auto easeInCubic(double time) -> double;
// Utilidades varias // Utilidades varias
auto stringInVector(const std::vector<std::string>& vec, const std::string& str) -> bool; // Comprueba si un vector contiene una cadena auto stringInVector(const std::vector<std::string>& vec, const std::string& str) -> bool; // Comprueba si un vector contiene una cadena
auto truncateWithEllipsis(const std::string& input, size_t length) -> std::string; // Trunca un string y le añade puntos suspensivos auto truncateWithEllipsis(const std::string& input, size_t length) -> std::string; // Trunca un string y le añade puntos suspensivos
// Ficheros y rutas // Ficheros y rutas
auto getFileName(const std::string& path) -> std::string; // Obtiene el nombre de un fichero a partir de una ruta auto getFileName(const std::string& path) -> std::string; // Obtiene el nombre de un fichero a partir de una ruta

View File

@@ -10,7 +10,7 @@ void Writer::update(float delta_time) {
writing_timer_ += delta_time; writing_timer_ += delta_time;
if (writing_timer_ >= speed_interval_) { if (writing_timer_ >= speed_interval_) {
index_++; index_++;
writing_timer_ = 0.0f; writing_timer_ = 0.0F;
} }
if (index_ == length_) { if (index_ == length_) {
@@ -27,7 +27,7 @@ void Writer::update(float delta_time) {
// Actualiza el objeto (delta_time en segundos) // Actualiza el objeto (delta_time en segundos)
void Writer::updateS(float delta_time) { void Writer::updateS(float delta_time) {
// Convierte segundos a milisegundos y usa la lógica normal // Convierte segundos a milisegundos y usa la lógica normal
update(delta_time * 1000.0f); update(delta_time * 1000.0F);
} }
// Dibuja el objeto en pantalla // Dibuja el objeto en pantalla
@@ -61,16 +61,16 @@ void Writer::setCaption(const std::string& text) {
// Establece el valor de la variable (frames) // Establece el valor de la variable (frames)
void Writer::setSpeed(int value) { void Writer::setSpeed(int value) {
// Convierte frames a milisegundos (frames * 16.67ms) // Convierte frames a milisegundos (frames * 16.67ms)
constexpr float FRAME_TIME_MS = 16.67f; constexpr float FRAME_TIME_MS = 16.67F;
speed_interval_ = static_cast<float>(value) * FRAME_TIME_MS; speed_interval_ = static_cast<float>(value) * FRAME_TIME_MS;
writing_timer_ = 0.0f; writing_timer_ = 0.0F;
} }
// Establece la velocidad en segundos entre caracteres // Establece la velocidad en segundos entre caracteres
void Writer::setSpeedS(float value) { void Writer::setSpeedS(float value) {
// Convierte segundos a milisegundos para consistencia interna // Convierte segundos a milisegundos para consistencia interna
speed_interval_ = value * 1000.0f; speed_interval_ = value * 1000.0F;
writing_timer_ = 0.0f; writing_timer_ = 0.0F;
} }
// Establece el valor de la variable // Establece el valor de la variable
@@ -86,13 +86,13 @@ auto Writer::isEnabled() const -> bool {
// Establece el temporizador para deshabilitar el objeto (en milisegundos) // Establece el temporizador para deshabilitar el objeto (en milisegundos)
void Writer::setFinishedTimerMs(float time_ms) { void Writer::setFinishedTimerMs(float time_ms) {
enabled_timer_target_ = time_ms; enabled_timer_target_ = time_ms;
enabled_timer_ = 0.0f; enabled_timer_ = 0.0F;
} }
// Establece el temporizador para deshabilitar el objeto (en segundos) // Establece el temporizador para deshabilitar el objeto (en segundos)
void Writer::setFinishedTimerS(float time_s) { void Writer::setFinishedTimerS(float time_s) {
enabled_timer_target_ = time_s * 1000.0f; // Convertir segundos a milisegundos enabled_timer_target_ = time_s * 1000.0F; // Convertir segundos a milisegundos
enabled_timer_ = 0.0f; enabled_timer_ = 0.0F;
} }
// Centra la cadena de texto a un punto X // Centra la cadena de texto a un punto X

Some files were not shown because too many files have changed in this diff Show More