32 Commits

Author SHA1 Message Date
4e525642a0 v1.09 2025-03-01 09:15:08 +01:00
c7db6aeaa3 canvi de pc 2025-03-01 08:11:00 +01:00
5ff04daf20 gonna fer un commit per si reventa algo: estic a meitat implementar surfaces 2025-02-28 22:58:01 +01:00
5bb2b5e7c4 fix: les notificacions ja no embruten la pantalla de càrrega 2025-02-28 14:00:59 +01:00
7a685c0cc8 fix: no pintava el efecte de carrega del borde en LoadingScreen 2025-02-28 13:40:30 +01:00
07e83fc811 Tornada a posar la musica de Title i el attract mode 2025-02-28 13:25:21 +01:00
3167251eae Eliminat el alpha de les notificacions 2025-02-28 13:13:36 +01:00
4efbb61fbc Arreglat aixina sense massa ganes Scoreboard::render() 2025-02-28 13:11:02 +01:00
3992fc08bf Afegides comprobacions de valors per al fitxer de configuració 2025-02-28 11:34:51 +01:00
366fe404ca Modes de video aclarits (sembla)
La finestra manté la posició al canviar de tamany o activar el borde
La finestra ja pot creixer mentres donde de si el escriptori
2025-02-28 09:46:55 +01:00
217781c621 lo mateix 2025-02-27 23:18:16 +01:00
212b2b481c Treballant en els modes de video 2025-02-27 21:05:01 +01:00
59e766f5c3 Nou engine de notificacions 2025-02-27 19:03:57 +01:00
2e11fec2cb canvi de pc 2025-02-27 16:51:20 +01:00
0d7ab830c9 Modificada la barra de progres de carrega de recursos per a que s'actualitze cada 5 items. Aixina ja va rapidet encara que estiga el vsync 2025-02-27 14:21:53 +01:00
0cec9f8556 Solventat bug amb el punter a ScoreboardData 2025-02-27 14:17:00 +01:00
c6474cb2da canvi de pc 2025-02-27 07:37:39 +01:00
e6fd4225a2 Ja torna a deixar jugar
Encara queden bugs per corregir
Trencat el sistema de triar la paleta, de moment
2025-02-26 20:37:29 +01:00
85ab5ea03f Singleton de ItemTracker
Arreglos menors
2025-02-26 13:07:41 +01:00
2457517f2b Afegida barra de progres en la càrrega de recursos 2025-02-26 10:05:52 +01:00
64880a427e Metodes per mostrar o amagar la finestra 2025-02-26 08:58:17 +01:00
a8e5517a77 Arreglada la cárrega de opcions i recursos
Modificats els parametros dels fitxers .ani a snake_case
2025-02-26 08:50:12 +01:00
a07a08adb7 De moment ja compila i executa, encara que no troba alguns fitxers 2025-02-25 23:03:16 +01:00
32c31a8cb6 commit de moure a un Linux a gastar eines de home 2025-02-25 19:37:08 +01:00
c9da5135b2 canvi de pc enmig de la enfangà 2025-02-25 13:18:56 +01:00
817140825a canvi de pc 2025-02-25 07:38:34 +01:00
e6f101ece6 Afegint smart pointers
Actualitzat Resources
Actualitzades les classes Sprite i derivades
Afegida nova tipografia
Actualitzat Asset
Actualitzat Text
2025-02-24 14:09:29 +01:00
48971cd5d1 canvi de pc 2025-02-24 08:52:11 +01:00
5bb5be9c33 Afinada un poc mes la classe Options 2025-02-23 20:02:55 +01:00
2ee0c70319 Reestructurant la classe Options 2025-02-23 18:12:02 +01:00
3ba4293e8a Afegit globalEvents 2025-02-23 09:53:06 +01:00
8ae686a70b globalInputs implementat en totes les seccions excepte Title i Game 2025-02-23 08:57:01 +01:00
142 changed files with 7038 additions and 7877 deletions

View File

@@ -1,5 +1,5 @@
frameWidth=8 frame_width=8
frameHeight=8 frame_height=8
[animation] [animation]
name=default name=default

View File

@@ -1,5 +1,5 @@
frameWidth=8 frame_width=8
frameHeight=16 frame_height=16
[animation] [animation]
name=default name=default

View File

@@ -1,5 +1,5 @@
frameWidth=16 frame_width=16
frameHeight=16 frame_height=16
[animation] [animation]
name=default name=default

View File

@@ -1,5 +1,5 @@
frameWidth=8 frame_width=8
frameHeight=8 frame_height=8
[animation] [animation]
name=default name=default

View File

@@ -1,5 +1,5 @@
frameWidth=16 frame_width=16
frameHeight=16 frame_height=16
[animation] [animation]
name=default name=default

View File

@@ -1,5 +1,5 @@
frameWidth=16 frame_width=16
frameHeight=16 frame_height=16
[animation] [animation]
name=default name=default

View File

@@ -1,5 +1,5 @@
frameWidth=9 frame_width=9
frameHeight=7 frame_height=7
[animation] [animation]
name=default name=default

View File

@@ -1,5 +1,5 @@
frameWidth=8 frame_width=8
frameHeight=16 frame_height=16
[animation] [animation]
name=default name=default

View File

@@ -1,5 +1,5 @@
frameWidth=16 frame_width=16
frameHeight=16 frame_height=16
[animation] [animation]
name=default name=default

View File

@@ -1,5 +1,5 @@
frameWidth=16 frame_width=16
frameHeight=16 frame_height=16
[animation] [animation]
name=default name=default

View File

@@ -1,5 +1,5 @@
frameWidth=16 frame_width=16
frameHeight=16 frame_height=16
[animation] [animation]
name=default name=default

View File

@@ -1,5 +1,5 @@
frameWidth=16 frame_width=16
frameHeight=8 frame_height=8
[animation] [animation]
name=default name=default

View File

@@ -1,5 +1,5 @@
frameWidth=16 frame_width=16
frameHeight=16 frame_height=16
[animation] [animation]
name=default name=default

View File

@@ -1,5 +1,5 @@
frameWidth=24 frame_width=24
frameHeight=32 frame_height=32
[animation] [animation]
name=default name=default

View File

@@ -1,5 +1,5 @@
frameWidth=10 frame_width=10
frameHeight=16 frame_height=16
[animation] [animation]
name=default name=default

View File

@@ -1,5 +1,5 @@
frameWidth=8 frame_width=8
frameHeight=16 frame_height=16
[animation] [animation]
name=default name=default

View File

@@ -1,5 +1,5 @@
frameWidth=16 frame_width=16
frameHeight=16 frame_height=16
[animation] [animation]
name=default name=default

View File

@@ -1,5 +1,5 @@
frameWidth=8 frame_width=8
frameHeight=16 frame_height=16
[animation] [animation]
name=default name=default

View File

@@ -1,5 +1,5 @@
frameWidth=16 frame_width=16
frameHeight=16 frame_height=16
[animation] [animation]
name=default name=default

View File

@@ -1,5 +1,5 @@
frameWidth=16 frame_width=16
frameHeight=16 frame_height=16
[animation] [animation]
name=default name=default

View File

@@ -1,5 +1,5 @@
frameWidth=16 frame_width=16
frameHeight=16 frame_height=16
[animation] [animation]
name=default name=default

View File

@@ -1,5 +1,5 @@
frameWidth=22 frame_width=22
frameHeight=16 frame_height=16
[animation] [animation]
name=default name=default

View File

@@ -1,5 +1,5 @@
frameWidth=16 frame_width=16
frameHeight=16 frame_height=16
[animation] [animation]
name=default name=default

View File

@@ -1,5 +1,5 @@
frameWidth=16 frame_width=16
frameHeight=16 frame_height=16
[animation] [animation]
name=default name=default

View File

@@ -1,5 +1,5 @@
frameWidth=7 frame_width=7
frameHeight=7 frame_height=7
[animation] [animation]
name=default name=default

View File

@@ -1,5 +1,5 @@
frameWidth=16 frame_width=16
frameHeight=16 frame_height=16
[animation] [animation]
name=default name=default

View File

@@ -1,5 +1,5 @@
frameWidth=16 frame_width=16
frameHeight=16 frame_height=16
[animation] [animation]
name=default name=default

View File

@@ -1,5 +1,5 @@
frameWidth=13 frame_width=13
frameHeight=15 frame_height=15
[animation] [animation]
name=default name=default

View File

@@ -1,5 +1,5 @@
frameWidth=11 frame_width=11
frameHeight=13 frame_height=13
[animation] [animation]
name=default name=default

View File

@@ -1,5 +1,5 @@
frameWidth=16 frame_width=16
frameHeight=16 frame_height=16
[animation] [animation]
name=default name=default

View File

@@ -1,5 +1,5 @@
frameWidth=16 frame_width=16
frameHeight=16 frame_height=16
[animation] [animation]
name=default name=default

View File

@@ -1,5 +1,5 @@
frameWidth=16 frame_width=16
frameHeight=16 frame_height=16
[animation] [animation]
name=default name=default

View File

@@ -1,5 +1,5 @@
frameWidth=8 frame_width=8
frameHeight=16 frame_height=16
[animation] [animation]
name=default name=default

View File

@@ -1,5 +1,5 @@
frameWidth=16 frame_width=16
frameHeight=16 frame_height=16
[animation] [animation]
name=default name=default

View File

@@ -1,5 +1,5 @@
frameWidth=16 frame_width=16
frameHeight=16 frame_height=16
[animation] [animation]
name=default name=default

View File

@@ -1,5 +1,5 @@
frameWidth=16 frame_width=16
frameHeight=16 frame_height=16
[animation] [animation]
name=default name=default

View File

@@ -1,5 +1,5 @@
frameWidth=8 frame_width=8
frameHeight=16 frame_height=16
[animation] [animation]
name=default name=default

View File

@@ -1,5 +1,5 @@
frameWidth=16 frame_width=16
frameHeight=16 frame_height=16
[animation] [animation]
name=default name=default

View File

@@ -1,5 +1,5 @@
frameWidth=16 frame_width=16
frameHeight=16 frame_height=16
[animation] [animation]
name=default name=default

View File

@@ -1,5 +1,5 @@
frameWidth=16 frame_width=16
frameHeight=32 frame_height=32
[animation] [animation]
name=default name=default

View File

@@ -1,5 +1,5 @@
frameWidth=16 frame_width=16
frameHeight=16 frame_height=16
[animation] [animation]
name=default name=default

View File

@@ -1,5 +1,5 @@
frameWidth=8 frame_width=8
frameHeight=8 frame_height=8
[animation] [animation]
name=default name=default

View File

@@ -1,5 +1,5 @@
frameWidth=16 frame_width=16
frameHeight=16 frame_height=16
[animation] [animation]
name=default name=default

View File

@@ -1,5 +1,5 @@
frameWidth=8 frame_width=8
frameHeight=16 frame_height=16
[animation] [animation]
name=default name=default

View File

@@ -1,5 +1,5 @@
frameWidth=43 frame_width=43
frameHeight=44 frame_height=44
[animation] [animation]
name=default name=default

View File

@@ -1,5 +1,5 @@
frameWidth=79 frame_width=79
frameHeight=90 frame_height=90
[animation] [animation]
name=default name=default

View File

@@ -1,5 +1,5 @@
frameWidth=62 frame_width=62
frameHeight=47 frame_height=47
[animation] [animation]
name=default name=default

View File

@@ -1,5 +1,5 @@
frameWidth=64 frame_width=64
frameHeight=64 frame_height=64
[animation] [animation]
name=default name=default

View File

@@ -1,5 +1,5 @@
frameWidth=8 frame_width=8
frameHeight=8 frame_height=8
[animation] [animation]
name=default name=default

View File

@@ -1,5 +1,5 @@
frameWidth=7 frame_width=7
frameHeight=8 frame_height=8
[animation] [animation]
name=default name=default

View File

@@ -1,5 +1,5 @@
frameWidth=16 frame_width=16
frameHeight=16 frame_height=16
[animation] [animation]
name=default name=default

View File

@@ -1,5 +1,5 @@
frameWidth=16 frame_width=16
frameHeight=16 frame_height=16
[animation] [animation]
name=default name=default

View File

@@ -1,5 +1,5 @@
frameWidth=16 frame_width=16
frameHeight=18 frame_height=18
[animation] [animation]
name=default name=default

View File

@@ -1,5 +1,5 @@
frameWidth=24 frame_width=24
frameHeight=16 frame_height=16
[animation] [animation]
name=default name=default

View File

@@ -1,5 +1,5 @@
frameWidth=8 frame_width=8
frameHeight=16 frame_height=16
[animation] [animation]
name=default name=default

View File

@@ -1,5 +1,5 @@
frameWidth=5 frame_width=5
frameHeight=8 frame_height=8
[animation] [animation]
name=default name=default

View File

@@ -1,5 +1,5 @@
frameWidth=8 frame_width=8
frameHeight=8 frame_height=8
[animation] [animation]
name=default name=default

View File

@@ -1,5 +1,5 @@
frameWidth=16 frame_width=16
frameHeight=32 frame_height=32
[animation] [animation]
name=default name=default

BIN
data/font/8bithud.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

194
data/font/8bithud.txt Normal file
View File

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

View File

@@ -1,5 +1,5 @@
frameWidth=8 frame_width=8
frameHeight=16 frame_height=16
[animation] [animation]
name=stand name=stand

View File

@@ -1,5 +1,5 @@
frameWidth=8 frame_width=8
frameHeight=16 frame_height=16
[animation] [animation]
name=stand name=stand

View File

@@ -1,5 +1,5 @@
frameWidth=19 frame_width=19
frameHeight=18 frame_height=18
[animation] [animation]
name=default name=default

BIN
data/test.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 630 B

269
source/animated_sprite.cpp Normal file
View File

@@ -0,0 +1,269 @@
#include "animated_sprite.h"
#include <stddef.h> // Para size_t
#include <fstream> // Para basic_ostream, basic_istream, operator<<, basic...
#include <iostream> // Para cout, cerr
#include <sstream> // Para basic_stringstream
#include <stdexcept> // Para runtime_error
#include "texture.h" // Para Texture
#include "utils.h" // Para printWithDots
// Carga las animaciones en un vector(Animations) desde un fichero
Animations loadAnimationsFromFile(const std::string &file_path)
{
std::ifstream file(file_path);
if (!file)
{
std::cerr << "Error: Fichero no encontrado " << file_path << std::endl;
throw std::runtime_error("Fichero no encontrado: " + file_path);
}
printWithDots("Animation : ", file_path.substr(file_path.find_last_of("\\/") + 1), "[ LOADED ]");
std::vector<std::string> buffer;
std::string line;
while (std::getline(file, line))
{
if (!line.empty())
buffer.push_back(line);
}
return buffer;
}
// Constructor
AnimatedSprite::AnimatedSprite(std::shared_ptr<Texture> texture, const std::string &file_path)
: MovingSprite(texture)
{
// Carga las animaciones
if (!file_path.empty())
{
Animations v = loadAnimationsFromFile(file_path);
setAnimations(v);
}
}
// Constructor
AnimatedSprite::AnimatedSprite(std::shared_ptr<Texture> texture, const Animations &animations)
: MovingSprite(texture)
{
if (!animations.empty())
{
setAnimations(animations);
}
}
// Obtiene el indice de la animación a partir del nombre
int AnimatedSprite::getIndex(const std::string &name)
{
auto index = -1;
for (const auto &a : animations_)
{
index++;
if (a.name == name)
{
return index;
}
}
std::cout << "** Warning: could not find \"" << name.c_str() << "\" animation" << std::endl;
return -1;
}
// Calcula el frame correspondiente a la animación
void AnimatedSprite::animate()
{
if (animations_[current_animation_].speed == 0)
{
return;
}
// Calcula el frame actual a partir del contador
animations_[current_animation_].current_frame = animations_[current_animation_].counter / animations_[current_animation_].speed;
// Si alcanza el final de la animación, reinicia el contador de la animación
// en función de la variable loop y coloca el nuevo frame
if (animations_[current_animation_].current_frame >= static_cast<int>(animations_[current_animation_].frames.size()))
{
if (animations_[current_animation_].loop == -1)
{ // Si no hay loop, deja el último frame
animations_[current_animation_].current_frame = animations_[current_animation_].frames.size();
animations_[current_animation_].completed = true;
}
else
{ // Si hay loop, vuelve al frame indicado
animations_[current_animation_].counter = 0;
animations_[current_animation_].current_frame = animations_[current_animation_].loop;
}
}
// En caso contrario
else
{
// Escoge el frame correspondiente de la animación
setClip(animations_[current_animation_].frames[animations_[current_animation_].current_frame]);
// Incrementa el contador de la animacion
animations_[current_animation_].counter++;
}
}
// Comprueba si ha terminado la animación
bool AnimatedSprite::animationIsCompleted()
{
return animations_[current_animation_].completed;
}
// Establece la animacion actual
void AnimatedSprite::setCurrentAnimation(const std::string &name)
{
const auto new_animation = getIndex(name);
if (current_animation_ != new_animation)
{
current_animation_ = new_animation;
animations_[current_animation_].current_frame = 0;
animations_[current_animation_].counter = 0;
animations_[current_animation_].completed = false;
setClip(animations_[current_animation_].frames[animations_[current_animation_].current_frame]);
}
}
// Establece la animacion actual
void AnimatedSprite::setCurrentAnimation(int index)
{
const auto new_animation = index;
if (current_animation_ != new_animation)
{
current_animation_ = new_animation;
animations_[current_animation_].current_frame = 0;
animations_[current_animation_].counter = 0;
animations_[current_animation_].completed = false;
setClip(animations_[current_animation_].frames[animations_[current_animation_].current_frame]);
}
}
// Actualiza las variables del objeto
void AnimatedSprite::update()
{
animate();
MovingSprite::update();
}
// Reinicia la animación
void AnimatedSprite::resetAnimation()
{
animations_[current_animation_].current_frame = 0;
animations_[current_animation_].counter = 0;
animations_[current_animation_].completed = false;
}
// Carga la animación desde un vector de cadenas
void AnimatedSprite::setAnimations(const Animations &animations)
{
int frame_width = 1;
int frame_height = 1;
int frames_per_row = 1;
int max_tiles = 1;
size_t index = 0;
while (index < animations.size())
{
std::string line = animations.at(index);
// Parsea el fichero para buscar variables y valores
if (line != "[animation]")
{
// Encuentra la posición del caracter '='
size_t pos = line.find("=");
// Procesa las dos subcadenas
if (pos != std::string::npos)
{
std::string key = line.substr(0, pos);
int value = std::stoi(line.substr(pos + 1));
if (key == "frame_width")
frame_width = value;
else if (key == "frame_height")
frame_height = value;
else
std::cout << "Warning: unknown parameter " << key << std::endl;
frames_per_row = texture_->getWidth() / frame_width;
const int w = texture_->getWidth() / frame_width;
const int h = texture_->getHeight() / frame_height;
max_tiles = w * h;
}
}
// Si la linea contiene el texto [animation] se realiza el proceso de carga de una animación
if (line == "[animation]")
{
AnimationData animation;
do
{
index++;
line = animations.at(index);
size_t pos = line.find("=");
if (pos != std::string::npos)
{
std::string key = line.substr(0, pos);
std::string value = line.substr(pos + 1);
if (key == "name")
animation.name = value;
else if (key == "speed")
animation.speed = std::stoi(value);
else if (key == "loop")
animation.loop = std::stoi(value);
else if (key == "frames")
{
// Se introducen los valores separados por comas en un vector
std::stringstream ss(value);
std::string tmp;
SDL_Rect rect = {0, 0, frame_width, frame_height};
while (getline(ss, tmp, ','))
{
// Comprueba que el tile no sea mayor que el maximo indice permitido
const int num_tile = std::stoi(tmp);
if (num_tile <= max_tiles)
{
rect.x = (num_tile % frames_per_row) * frame_width;
rect.y = (num_tile / frames_per_row) * frame_height;
animation.frames.emplace_back(rect);
}
}
}
else
std::cout << "Warning: unknown parameter " << key << std::endl;
}
} while (line != "[/animation]");
// Añade la animación al vector de animaciones
animations_.emplace_back(animation);
}
// Una vez procesada la linea, aumenta el indice para pasar a la siguiente
index++;
}
// Pone un valor por defecto
setWidth(frame_width);
setHeight(frame_height);
}
// Establece el frame actual de la animación
void AnimatedSprite::setCurrentAnimationFrame(int num)
{
// Descarta valores fuera de rango
if (num < 0 || num >= static_cast<int>(animations_[current_animation_].frames.size()))
{
num = 0;
}
// Cambia el valor de la variable
animations_[current_animation_].current_frame = num;
animations_[current_animation_].counter = 0;
// Escoge el frame correspondiente de la animación
setClip(animations_[current_animation_].frames[animations_[current_animation_].current_frame]);
}

72
source/animated_sprite.h Normal file
View File

@@ -0,0 +1,72 @@
#pragma once
#include <SDL2/SDL_rect.h> // Para SDL_Rect
#include <memory> // Para shared_ptr
#include <string> // Para string
#include <vector> // Para vector
#include "moving_sprite.h" // Para MovingSprite
class Texture; // lines 9-9
struct AnimationData
{
std::string name; // Nombre de la animacion
std::vector<SDL_Rect> frames; // Cada uno de los frames que componen la animación
int speed; // Velocidad de la animación
int loop; // Indica a que frame vuelve la animación al terminar. -1 para que no vuelva
bool completed; // Indica si ha finalizado la animación
int current_frame; // Frame actual
int counter; // Contador para las animaciones
AnimationData() : name(std::string()), speed(5), loop(0), completed(false), current_frame(0), counter(0) {}
};
using Animations = std::vector<std::string>;
// Carga las animaciones en un vector(Animations) desde un fichero
Animations loadAnimationsFromFile(const std::string &file_path);
class AnimatedSprite : public MovingSprite
{
protected:
// Variables
std::vector<AnimationData> animations_; // Vector con las diferentes animaciones
int current_animation_ = 0; // Animacion activa
// Calcula el frame correspondiente a la animación actual
void animate();
// Carga la animación desde un vector de cadenas
void setAnimations(const Animations &animations);
public:
// Constructor
AnimatedSprite(std::shared_ptr<Texture> texture, const std::string &file_path);
AnimatedSprite(std::shared_ptr<Texture> texture, const Animations &animations);
explicit AnimatedSprite(std::shared_ptr<Texture> texture)
: MovingSprite(texture) {}
// Destructor
virtual ~AnimatedSprite() = default;
// Actualiza las variables del objeto
void update() override;
// Comprueba si ha terminado la animación
bool animationIsCompleted();
// Obtiene el indice de la animación a partir del nombre
int getIndex(const std::string &name);
// Establece la animacion actual
void setCurrentAnimation(const std::string &name = "default");
void setCurrentAnimation(int index = 0);
// Reinicia la animación
void resetAnimation();
// Establece el frame actual de la animación
void setCurrentAnimationFrame(int num);
// Obtiene el numero de frames de la animación actual
int getCurrentAnimationSize() { return static_cast<int>(animations_[current_animation_].frames.size()); }
};

View File

@@ -1,538 +0,0 @@
#include "animatedsprite.h"
#include <fstream> // Para basic_ostream, operator<<, basic_istream, basic...
#include <iostream> // Para cout
#include <sstream> // Para basic_stringstream
#include "texture.h" // Para Texture
// Carga la animación desde un fichero
animatedSprite_t loadAnimationFromFile(Texture *texture, std::string filePath, bool verbose)
{
// Inicializa variables
animatedSprite_t as;
as.texture = texture;
int framesPerRow = 0;
int frameWidth = 0;
int frameHeight = 0;
int maxTiles = 0;
const std::string filename = filePath.substr(filePath.find_last_of("\\/") + 1);
std::ifstream file(filePath);
std::string line;
// El fichero se puede abrir
if (file.good())
{
// Procesa el fichero linea a linea
if (verbose)
{
std::cout << "Animation loaded: " << filename << std::endl;
}
while (std::getline(file, line))
{
// Si la linea contiene el texto [animation] se realiza el proceso de carga de una animación
if (line == "[animation]")
{
animation_t buffer;
buffer.counter = 0;
buffer.currentFrame = 0;
buffer.completed = false;
do
{
std::getline(file, line);
// Encuentra la posición del caracter '='
int pos = line.find("=");
// Procesa las dos subcadenas
if (pos != (int)line.npos)
{
if (line.substr(0, pos) == "name")
{
buffer.name = line.substr(pos + 1, line.length());
}
else if (line.substr(0, pos) == "speed")
{
buffer.speed = std::stoi(line.substr(pos + 1, line.length()));
}
else if (line.substr(0, pos) == "loop")
{
buffer.loop = std::stoi(line.substr(pos + 1, line.length()));
}
else if (line.substr(0, pos) == "frames")
{
// Se introducen los valores separados por comas en un vector
std::stringstream ss(line.substr(pos + 1, line.length()));
std::string tmp;
SDL_Rect rect = {0, 0, frameWidth, frameHeight};
while (getline(ss, tmp, ','))
{
// Comprueba que el tile no sea mayor que el maximo indice permitido
const int numTile = std::stoi(tmp) > maxTiles ? 0 : std::stoi(tmp);
rect.x = (numTile % framesPerRow) * frameWidth;
rect.y = (numTile / framesPerRow) * frameHeight;
buffer.frames.push_back(rect);
}
}
else
{
std::cout << "Warning: file " << filename.c_str() << "\n, unknown parameter \"" << line.substr(0, pos).c_str() << "\"" << std::endl;
}
}
} while (line != "[/animation]");
// Añade la animación al vector de animaciones
as.animations.push_back(buffer);
}
// En caso contrario se parsea el fichero para buscar las variables y los valores
else
{
// Encuentra la posición del caracter '='
int pos = line.find("=");
// Procesa las dos subcadenas
if (pos != (int)line.npos)
{
if (line.substr(0, pos) == "framesPerRow")
{
framesPerRow = std::stoi(line.substr(pos + 1, line.length()));
}
else if (line.substr(0, pos) == "frameWidth")
{
frameWidth = std::stoi(line.substr(pos + 1, line.length()));
}
else if (line.substr(0, pos) == "frameHeight")
{
frameHeight = std::stoi(line.substr(pos + 1, line.length()));
}
else
{
std::cout << "Warning: file " << filename.c_str() << "\n, unknown parameter \"" << line.substr(0, pos).c_str() << "\"" << std::endl;
}
// Normaliza valores
if (framesPerRow == 0 && frameWidth > 0)
{
framesPerRow = texture->getWidth() / frameWidth;
}
if (maxTiles == 0 && frameWidth > 0 && frameHeight > 0)
{
const int w = texture->getWidth() / frameWidth;
const int h = texture->getHeight() / frameHeight;
maxTiles = w * h;
}
}
}
}
// Cierra el fichero
file.close();
}
// El fichero no se puede abrir
else
{
if (verbose)
{
std::cout << "Warning: Unable to open " << filename.c_str() << " file" << std::endl;
}
}
return as;
}
// Constructor
AnimatedSprite::AnimatedSprite(Texture *texture, SDL_Renderer *renderer, std::string file, std::vector<std::string> *buffer)
{
// Copia los punteros
setTexture(texture);
setRenderer(renderer);
// Carga las animaciones
if (file != "")
{
animatedSprite_t as = loadAnimationFromFile(texture, file);
// Copia los datos de las animaciones
for (auto animation : as.animations)
{
this->animation.push_back(animation);
}
}
else if (buffer)
{
loadFromVector(buffer);
}
// Inicializa variables
currentAnimation = 0;
}
// Constructor
AnimatedSprite::AnimatedSprite(SDL_Renderer *renderer, animatedSprite_t *animation)
{
// Copia los punteros
setTexture(animation->texture);
setRenderer(renderer);
// Inicializa variables
currentAnimation = 0;
// Copia los datos de las animaciones
for (auto a : animation->animations)
{
this->animation.push_back(a);
}
}
// Destructor
AnimatedSprite::~AnimatedSprite()
{
for (auto &a : animation)
{
a.frames.clear();
}
animation.clear();
}
// Obtiene el indice de la animación a partir del nombre
int AnimatedSprite::getIndex(std::string name)
{
int index = -1;
for (auto a : animation)
{
index++;
if (a.name == name)
{
return index;
}
}
std::cout << "** Warning: could not find \"" << name.c_str() << "\" animation" << std::endl;
return -1;
}
// Calcula el frame correspondiente a la animación
void AnimatedSprite::animate()
{
if (!enabled || animation[currentAnimation].speed == 0)
{
return;
}
// Calcula el frame actual a partir del contador
animation[currentAnimation].currentFrame = animation[currentAnimation].counter / animation[currentAnimation].speed;
// Si alcanza el final de la animación, reinicia el contador de la animación
// en función de la variable loop y coloca el nuevo frame
if (animation[currentAnimation].currentFrame >= (int)animation[currentAnimation].frames.size())
{
if (animation[currentAnimation].loop == -1)
{ // Si no hay loop, deja el último frame
animation[currentAnimation].currentFrame = animation[currentAnimation].frames.size();
animation[currentAnimation].completed = true;
}
else
{ // Si hay loop, vuelve al frame indicado
animation[currentAnimation].counter = 0;
animation[currentAnimation].currentFrame = animation[currentAnimation].loop;
}
}
// En caso contrario
else
{
// Escoge el frame correspondiente de la animación
setSpriteClip(animation[currentAnimation].frames[animation[currentAnimation].currentFrame]);
// Incrementa el contador de la animacion
animation[currentAnimation].counter++;
}
}
// Obtiene el numero de frames de la animación actual
int AnimatedSprite::getNumFrames()
{
return (int)animation[currentAnimation].frames.size();
}
// Establece el frame actual de la animación
void AnimatedSprite::setCurrentFrame(int num)
{
// Descarta valores fuera de rango
if (num >= (int)animation[currentAnimation].frames.size())
{
num = 0;
}
// Cambia el valor de la variable
animation[currentAnimation].currentFrame = num;
animation[currentAnimation].counter = 0;
// Escoge el frame correspondiente de la animación
setSpriteClip(animation[currentAnimation].frames[animation[currentAnimation].currentFrame]);
}
// Establece el valor del contador
void AnimatedSprite::setAnimationCounter(std::string name, int num)
{
animation[getIndex(name)].counter = num;
}
// Establece la velocidad de una animación
void AnimatedSprite::setAnimationSpeed(std::string name, int speed)
{
animation[getIndex(name)].counter = speed;
}
// Establece la velocidad de una animación
void AnimatedSprite::setAnimationSpeed(int index, int speed)
{
animation[index].counter = speed;
}
// Establece si la animación se reproduce en bucle
void AnimatedSprite::setAnimationLoop(std::string name, int loop)
{
animation[getIndex(name)].loop = loop;
}
// Establece si la animación se reproduce en bucle
void AnimatedSprite::setAnimationLoop(int index, int loop)
{
animation[index].loop = loop;
}
// Establece el valor de la variable
void AnimatedSprite::setAnimationCompleted(std::string name, bool value)
{
animation[getIndex(name)].completed = value;
}
// OLD - Establece el valor de la variable
void AnimatedSprite::setAnimationCompleted(int index, bool value)
{
animation[index].completed = value;
}
// Comprueba si ha terminado la animación
bool AnimatedSprite::animationIsCompleted()
{
return animation[currentAnimation].completed;
}
// Devuelve el rectangulo de una animación y frame concreto
SDL_Rect AnimatedSprite::getAnimationClip(std::string name, Uint8 index)
{
return animation[getIndex(name)].frames[index];
}
// Devuelve el rectangulo de una animación y frame concreto
SDL_Rect AnimatedSprite::getAnimationClip(int indexA, Uint8 indexF)
{
return animation[indexA].frames[indexF];
}
// Carga la animación desde un vector
bool AnimatedSprite::loadFromVector(std::vector<std::string> *source)
{
// Inicializa variables
int framesPerRow = 0;
int frameWidth = 0;
int frameHeight = 0;
int maxTiles = 0;
// Indicador de éxito en el proceso
bool success = true;
std::string line;
// Recorre todo el vector
int index = 0;
while (index < (int)source->size())
{
// Lee desde el vector
line = source->at(index);
// Si la linea contiene el texto [animation] se realiza el proceso de carga de una animación
if (line == "[animation]")
{
animation_t buffer;
buffer.counter = 0;
buffer.currentFrame = 0;
buffer.completed = false;
do
{
// Aumenta el indice para leer la siguiente linea
index++;
line = source->at(index);
// Encuentra la posición del caracter '='
int pos = line.find("=");
// Procesa las dos subcadenas
if (pos != (int)line.npos)
{
if (line.substr(0, pos) == "name")
{
buffer.name = line.substr(pos + 1, line.length());
}
else if (line.substr(0, pos) == "speed")
{
buffer.speed = std::stoi(line.substr(pos + 1, line.length()));
}
else if (line.substr(0, pos) == "loop")
{
buffer.loop = std::stoi(line.substr(pos + 1, line.length()));
}
else if (line.substr(0, pos) == "frames")
{
// Se introducen los valores separados por comas en un vector
std::stringstream ss(line.substr(pos + 1, line.length()));
std::string tmp;
SDL_Rect rect = {0, 0, frameWidth, frameHeight};
while (getline(ss, tmp, ','))
{
// Comprueba que el tile no sea mayor que el maximo indice permitido
const int numTile = std::stoi(tmp) > maxTiles ? 0 : std::stoi(tmp);
rect.x = (numTile % framesPerRow) * frameWidth;
rect.y = (numTile / framesPerRow) * frameHeight;
buffer.frames.push_back(rect);
}
}
else
{
std::cout << "Warning: unknown parameter " << line.substr(0, pos).c_str() << std::endl;
success = false;
}
}
} while (line != "[/animation]");
// Añade la animación al vector de animaciones
animation.push_back(buffer);
}
// En caso contrario se parsea el fichero para buscar las variables y los valores
else
{
// Encuentra la posición del caracter '='
int pos = line.find("=");
// Procesa las dos subcadenas
if (pos != (int)line.npos)
{
if (line.substr(0, pos) == "framesPerRow")
{
framesPerRow = std::stoi(line.substr(pos + 1, line.length()));
}
else if (line.substr(0, pos) == "frameWidth")
{
frameWidth = std::stoi(line.substr(pos + 1, line.length()));
}
else if (line.substr(0, pos) == "frameHeight")
{
frameHeight = std::stoi(line.substr(pos + 1, line.length()));
}
else
{
std::cout << "Warning: unknown parameter " << line.substr(0, pos).c_str() << std::endl;
success = false;
}
// Normaliza valores
if (framesPerRow == 0 && frameWidth > 0)
{
framesPerRow = texture->getWidth() / frameWidth;
}
if (maxTiles == 0 && frameWidth > 0 && frameHeight > 0)
{
const int w = texture->getWidth() / frameWidth;
const int h = texture->getHeight() / frameHeight;
maxTiles = w * h;
}
}
}
// Una vez procesada la linea, aumenta el indice para pasar a la siguiente
index++;
}
// Pone un valor por defecto
setRect({0, 0, frameWidth, frameHeight});
return success;
}
// Establece la animacion actual
void AnimatedSprite::setCurrentAnimation(std::string name)
{
const int newAnimation = getIndex(name);
if (currentAnimation != newAnimation)
{
currentAnimation = newAnimation;
animation[currentAnimation].currentFrame = 0;
animation[currentAnimation].counter = 0;
animation[currentAnimation].completed = false;
}
}
// Establece la animacion actual
void AnimatedSprite::setCurrentAnimation(int index)
{
const int newAnimation = index;
if (currentAnimation != newAnimation)
{
currentAnimation = newAnimation;
animation[currentAnimation].currentFrame = 0;
animation[currentAnimation].counter = 0;
animation[currentAnimation].completed = false;
}
}
// Actualiza las variables del objeto
void AnimatedSprite::update()
{
animate();
MovingSprite::update();
}
// Establece el rectangulo para un frame de una animación
void AnimatedSprite::setAnimationFrames(Uint8 index_animation, Uint8 index_frame, int x, int y, int w, int h)
{
animation[index_animation].frames.push_back({x, y, w, h});
}
// OLD - Establece el contador para todas las animaciones
void AnimatedSprite::setAnimationCounter(int value)
{
for (auto &a : animation)
{
a.counter = value;
}
}
// Reinicia la animación
void AnimatedSprite::resetAnimation()
{
animation[currentAnimation].currentFrame = 0;
animation[currentAnimation].counter = 0;
animation[currentAnimation].completed = false;
}

View File

@@ -1,98 +0,0 @@
#pragma once
#include <SDL2/SDL_rect.h> // Para SDL_Rect
#include <SDL2/SDL_render.h> // Para SDL_Renderer
#include <SDL2/SDL_stdinc.h> // Para Uint8
#include <string> // Para string
#include <vector> // Para vector
#include "movingsprite.h" // Para MovingSprite
class Texture;
struct animation_t
{
std::string name; // Nombre de la animacion
std::vector<SDL_Rect> frames; // Cada uno de los frames que componen la animación
int speed; // Velocidad de la animación
int loop; // Indica a que frame vuelve la animación al terminar. -1 para que no vuelva
bool completed; // Indica si ha finalizado la animación
int currentFrame; // Frame actual
int counter; // Contador para las animaciones
};
struct animatedSprite_t
{
std::vector<animation_t> animations; // Vector con las diferentes animaciones
Texture *texture; // Textura con los graficos para el sprite
};
// Carga la animación desde un fichero
animatedSprite_t loadAnimationFromFile(Texture *texture, std::string filePath, bool verbose = false);
class AnimatedSprite : public MovingSprite
{
private:
// Variables
std::vector<animation_t> animation; // Vector con las diferentes animaciones
int currentAnimation; // Animacion activa
public:
// Constructor
AnimatedSprite(Texture *texture = nullptr, SDL_Renderer *renderer = nullptr, std::string file = "", std::vector<std::string> *buffer = nullptr);
AnimatedSprite(SDL_Renderer *renderer, animatedSprite_t *animation);
// Destructor
~AnimatedSprite();
// Calcula el frame correspondiente a la animación actual
void animate();
// Obtiene el numero de frames de la animación actual
int getNumFrames();
// Establece el frame actual de la animación
void setCurrentFrame(int num);
// Establece el valor del contador
void setAnimationCounter(std::string name, int num);
// Establece la velocidad de una animación
void setAnimationSpeed(std::string name, int speed);
void setAnimationSpeed(int index, int speed);
// Establece el frame al que vuelve la animación al finalizar
void setAnimationLoop(std::string name, int loop);
void setAnimationLoop(int index, int loop);
// Establece el valor de la variable
void setAnimationCompleted(std::string name, bool value);
void setAnimationCompleted(int index, bool value);
// Comprueba si ha terminado la animación
bool animationIsCompleted();
// Devuelve el rectangulo de una animación y frame concreto
SDL_Rect getAnimationClip(std::string name = "default", Uint8 index = 0);
SDL_Rect getAnimationClip(int indexA = 0, Uint8 indexF = 0);
// Obtiene el indice de la animación a partir del nombre
int getIndex(std::string name);
// Carga la animación desde un vector
bool loadFromVector(std::vector<std::string> *source);
// Establece la animacion actual
void setCurrentAnimation(std::string name = "default");
void setCurrentAnimation(int index = 0);
// Actualiza las variables del objeto
void update();
// OLD - Establece el rectangulo para un frame de una animación
void setAnimationFrames(Uint8 index_animation, Uint8 index_frame, int x, int y, int w, int h);
// OLD - Establece el contador para todas las animaciones
void setAnimationCounter(int value);
// Reinicia la animación
void resetAnimation();
};

View File

@@ -1,86 +1,77 @@
#include "asset.h" #include "asset.h"
#include <SDL2/SDL_rwops.h> // Para SDL_RWFromFile, SDL_RWclose, SDL_RWops #include <algorithm> // Para find_if, max
#include <SDL2/SDL_stdinc.h> // Para SDL_max #include <fstream> // Para basic_ostream, operator<<, basic_ifstream, endl
#include <stddef.h> // Para size_t #include <iostream> // Para cout
#include <iostream> // Para basic_ostream, operator<<, cout, endl #include <string> // Para allocator, char_traits, string, operator+, oper...
#include "utils.h" // Para getFileName, printWithDots
// [SINGLETON] Hay que definir las variables estáticas, desde el .h sólo la hemos declarado // [SINGLETON] Hay que definir las variables estáticas, desde el .h sólo la hemos declarado
Asset *Asset::asset_ = nullptr; Asset *Asset::asset_ = nullptr;
// [SINGLETON] Crearemos el objeto con esta función estática // [SINGLETON] Crearemos el objeto asset con esta función estática
void Asset::init(const std::string &executable_path) void Asset::init(const std::string &executable_path)
{ {
Asset::asset_ = new Asset(executable_path); Asset::asset_ = new Asset(executable_path);
} }
// [SINGLETON] Destruiremos el objeto con esta función estática // [SINGLETON] Destruiremos el objeto asset con esta función estática
void Asset::destroy() void Asset::destroy()
{ {
delete Asset::asset_; delete Asset::asset_;
} }
// [SINGLETON] Con este método obtenemos el objeto y podemos trabajar con él // [SINGLETON] Con este método obtenemos el objeto asset y podemos trabajar con él
Asset *Asset::get() Asset *Asset::get()
{ {
return Asset::asset_; return Asset::asset_;
} }
// Añade un elemento a la lista // Añade un elemento a la lista
void Asset::add(std::string file, enum assetType type, bool required, bool absolute) void Asset::add(const std::string &file, AssetType type, bool required, bool absolute)
{ {
item_t temp; file_list_.emplace_back(absolute ? file : executable_path_ + file, type, required);
temp.file = absolute ? file : executable_path_ + file; longest_name_ = std::max(longest_name_, static_cast<int>(file_list_.back().file.size()));
temp.type = type;
temp.required = required;
fileList.push_back(temp);
const std::string filename = file.substr(file.find_last_of("\\/") + 1);
longest_name_ = SDL_max(longest_name_, filename.size());
} }
// Devuelve el fichero de un elemento de la lista a partir de una cadena // Devuelve la ruta completa a un fichero a partir de una cadena
std::string Asset::get(std::string text) std::string Asset::get(const std::string &text) const
{ {
for (auto f : fileList) auto it = std::find_if(file_list_.begin(), file_list_.end(),
{ [&text](const auto &f)
const size_t lastIndex = f.file.find_last_of("/") + 1; {
const std::string file = f.file.substr(lastIndex, std::string::npos); return getFileName(f.file) == text;
});
if (file == text) if (it != file_list_.end())
{
return f.file;
}
}
if (verbose_)
{ {
std::cout << "Warning: file " << text.c_str() << " not found" << std::endl; return it->file;
}
else
{
std::cout << "Warning: file " << text << " not found" << std::endl;
return "";
} }
return "";
} }
// Comprueba que existen todos los elementos // Comprueba que existen todos los elementos
bool Asset::check() bool Asset::check() const
{ {
bool success = true; bool success = true;
if (verbose_) std::cout << "\n** CHECKING FILES" << std::endl;
{
std::cout << "\n** Checking files" << std::endl;
std::cout << "Executable path is: " << executable_path_ << std::endl; // std::cout << "Executable path is: " << executable_path_ << std::endl;
std::cout << "Sample filepath: " << fileList.back().file << std::endl; // std::cout << "Sample filepath: " << file_list_.back().file << std::endl;
}
// Comprueba la lista de ficheros clasificandolos por tipo // Comprueba la lista de ficheros clasificandolos por tipo
for (int type = 0; type < t_maxAssetType; ++type) for (int type = 0; type < static_cast<int>(AssetType::MAX_ASSET_TYPE); ++type)
{ {
// Comprueba si hay ficheros de ese tipo // Comprueba si hay ficheros de ese tipo
bool any = false; bool any = false;
for (auto f : fileList) for (const auto &f : file_list_)
{ {
if ((f.required) && (f.type == type)) if (f.required && f.type == static_cast<AssetType>(type))
{ {
any = true; any = true;
} }
@@ -89,108 +80,74 @@ bool Asset::check()
// Si hay ficheros de ese tipo, comprueba si existen // Si hay ficheros de ese tipo, comprueba si existen
if (any) if (any)
{ {
if (verbose_) std::cout << "\n>> " << getTypeName(static_cast<AssetType>(type)).c_str() << " FILES" << std::endl;
{
std::cout << "\n>> " << getTypeName(type).c_str() << " FILES" << std::endl;
}
for (auto f : fileList) for (const auto &f : file_list_)
{ {
if ((f.required) && (f.type == type)) if (f.required && f.type == static_cast<AssetType>(type))
{ {
success &= checkFile(f.file); success &= checkFile(f.file);
} }
} }
if (success)
std::cout << " All files are OK." << std::endl;
} }
} }
// Resultado // Resultado
if (verbose_) std::cout << (success ? "\n** CHECKING FILES COMPLETED.\n" : "\n** CHECKING FILES FAILED.\n") << std::endl;
{
if (success)
{
std::cout << "\n** All files OK.\n"
<< std::endl;
}
else
{
std::cout << "\n** A file is missing. Exiting.\n"
<< std::endl;
}
}
return success; return success;
} }
// Comprueba que existe un fichero // Comprueba que existe un fichero
bool Asset::checkFile(std::string path) bool Asset::checkFile(const std::string &path) const
{ {
bool success = false; std::ifstream file(path);
std::string result = "ERROR"; bool success = file.good();
file.close();
// Comprueba si existe el fichero if (!success)
const std::string filename = path.substr(path.find_last_of("\\/") + 1); printWithDots("Checking file : ", getFileName(path), "[ ERROR ]");
SDL_RWops *file = SDL_RWFromFile(path.c_str(), "rb");
if (file != nullptr)
{
result = "OK";
success = true;
SDL_RWclose(file);
}
if (verbose_)
{
std::cout.setf(std::ios::left, std::ios::adjustfield);
std::cout << "Checking file: ";
std::cout.width(longest_name_ + 2);
std::cout.fill('.');
std::cout << filename + " ";
std::cout << " [" + result + "]" << std::endl;
}
return success; return success;
} }
// Devuelve el nombre del tipo de recurso // Devuelve el nombre del tipo de recurso
std::string Asset::getTypeName(int type) std::string Asset::getTypeName(AssetType type) const
{ {
switch (type) switch (type)
{ {
case t_bitmap: case AssetType::DATA:
return "BITMAP";
break;
case t_music:
return "MUSIC";
break;
case t_sound:
return "SOUND";
break;
case t_font:
return "FONT";
break;
case t_lang:
return "LANG";
break;
case t_data:
return "DATA"; return "DATA";
break; break;
case t_room: case AssetType::BITMAP:
return "BITMAP";
break;
case AssetType::ANIMATION:
return "ANIMATION";
break;
case AssetType::MUSIC:
return "MUSIC";
break;
case AssetType::SOUND:
return "SOUND";
break;
case AssetType::FONT:
return "FONT";
break;
case AssetType::ROOM:
return "ROOM"; return "ROOM";
break; break;
case t_enemy: case AssetType::TILEMAP:
return "ENEMY"; return "TILEMAP";
break;
case t_item:
return "ITEM";
break; break;
default: default:
@@ -199,8 +156,18 @@ std::string Asset::getTypeName(int type)
} }
} }
// Establece si ha de mostrar texto por pantalla // Devuelve la lista de recursos de un tipo
void Asset::setVerbose(bool value) std::vector<std::string> Asset::getListByType(AssetType type) const
{ {
verbose_ = value; std::vector<std::string> list;
for (auto f : file_list_)
{
if (f.type == type)
{
list.push_back(f.file);
}
}
return list;
} }

View File

@@ -1,49 +1,51 @@
#pragma once #pragma once
#include <string> // Para string #include <string> // para string, basic_string
#include <vector> // Para vector #include <vector> // para vector
#include "utils.h" #include "utils.h"
enum assetType enum class AssetType : int
{ {
t_bitmap, DATA,
t_music, BITMAP,
t_sound, ANIMATION,
t_font, MUSIC,
t_lang, SOUND,
t_data, FONT,
t_room, ROOM,
t_enemy, TILEMAP,
t_item, MAX_ASSET_TYPE
t_maxAssetType
}; };
// Clase Asset // Clase Asset
class Asset class Asset
{ {
private: private:
// [SINGLETON] Objeto asset privado // [SINGLETON] Objeto asset privado para Don Melitón
static Asset *asset_; static Asset *asset_;
// Estructura para definir un item // Estructura para definir un item
struct item_t struct AssetItem
{ {
std::string file; // Ruta del fichero desde la raiz del directorio std::string file; // Ruta del fichero desde la raíz del directorio
enum assetType type; // Indica el tipo de recurso AssetType type; // Indica el tipo de recurso
bool required; // Indica si es un fichero que debe de existir bool required; // Indica si es un fichero que debe de existir
// Constructor
AssetItem(const std::string &filePath, AssetType assetType, bool isRequired)
: file(filePath), type(assetType), required(isRequired) {}
}; };
// Variables // Variables
int longest_name_ = 0; // Contiene la longitud del nombre de fichero mas largo int longest_name_ = 0; // Contiene la longitud del nombre de fichero mas largo
std::vector<item_t> fileList; // Listado con todas las rutas a los ficheros std::vector<AssetItem> file_list_; // Listado con todas las rutas a los ficheros
std::string executable_path_; // Ruta al ejecutable std::string executable_path_; // Ruta al ejecutable
bool verbose_ = true; // Indica si ha de mostrar información por pantalla
// Comprueba que existe un fichero // Comprueba que existe un fichero
bool checkFile(std::string executablePath); bool checkFile(const std::string &path) const;
// Devuelve el nombre del tipo de recurso // Devuelve el nombre del tipo de recurso
std::string getTypeName(int type); std::string getTypeName(AssetType type) const;
// Constructor // Constructor
explicit Asset(const std::string &executable_path) explicit Asset(const std::string &executable_path)
@@ -63,14 +65,14 @@ public:
static Asset *get(); static Asset *get();
// Añade un elemento a la lista // Añade un elemento a la lista
void add(std::string file, enum assetType type, bool required = true, bool absolute = false); void add(const std::string &file, AssetType type, bool required = true, bool absolute = false);
// Devuelve un elemento de la lista a partir de una cadena // Devuelve la ruta completa a un fichero a partir de una cadena
std::string get(std::string text); std::string get(const std::string &text) const;
// Comprueba que existen todos los elementos // Comprueba que existen todos los elementos
bool check(); bool check() const;
// Establece si ha de mostrar texto por pantalla // Devuelve la lista de recursos de un tipo
void setVerbose(bool value); std::vector<std::string> getListByType(AssetType type) const;
}; };

View File

@@ -1,12 +1,11 @@
#include "cheevos.h" #include "cheevos.h"
#include <SDL2/SDL_error.h> // Para SDL_GetError #include <SDL2/SDL_error.h> // for SDL_GetError
#include <SDL2/SDL_rwops.h> // Para SDL_RWFromFile, SDL_RWclose, SDL_RWwrite #include <SDL2/SDL_rwops.h> // for SDL_RWFromFile, SDL_RWclose, SDL_RWwrite
#include <stddef.h> // Para NULL #include <stddef.h> // for NULL
#include <iostream> // Para basic_ostream, operator<<, cout, endl #include <fstream> // for basic_ostream, operator<<, basic_ofstream
#include "notifier.h" // Para Screen #include <iostream> // for cout, cerr
#include "utils.h" // Para options_t #include "notifier.h" // for Notifier
#include "options.h" #include "options.h" // for Options, options
#include <fstream> // Para fstream
// [SINGLETON] // [SINGLETON]
Cheevos *Cheevos::cheevos_ = nullptr; Cheevos *Cheevos::cheevos_ = nullptr;
@@ -89,7 +88,7 @@ void Cheevos::unlock(int id)
// Marcar el logro como completado // Marcar el logro como completado
cheevos_list_.at(index).completed = true; cheevos_list_.at(index).completed = true;
// Mostrar notificación en la pantalla // Mostrar notificación en la pantalla
Notifier::get()->show("ACHIEVEMENT UNLOCKED!", cheevos_list_.at(index).caption, cheevos_list_.at(index).icon); Notifier::get()->show({"ACHIEVEMENT UNLOCKED!", cheevos_list_.at(index).caption}, NotificationText::LEFT, cheevos_list_.at(index).icon);
// Guardar el estado de los logros // Guardar el estado de los logros
saveToFile(); saveToFile();
} }
@@ -109,24 +108,24 @@ void Cheevos::invalidate(int id)
// Carga el estado de los logros desde un fichero // Carga el estado de los logros desde un fichero
void Cheevos::loadFromFile() void Cheevos::loadFromFile()
{ {
std::ifstream file(this->file_, std::ios::binary); std::ifstream file(file_, std::ios::binary);
// El fichero no existe // El fichero no existe
if (!file) if (!file)
{ {
if (options.console) if (options.console)
{ {
std::cout << "Warning: Unable to open file! Creating new file..." << std::endl; std::cout << "Warning: Unable to open " << file_ << "! Creating new file..." << std::endl;
} }
// Crea el fichero en modo escritura (binario) // Crea el fichero en modo escritura (binario)
std::ofstream newFile(this->file_, std::ios::binary); std::ofstream newFile(file_, std::ios::binary);
if (newFile) if (newFile)
{ {
if (options.console) if (options.console)
{ {
std::cout << "New file created!" << std::endl; std::cout << "New " << file_ << " created!" << std::endl;
} }
// Guarda la información // Guarda la información
@@ -139,7 +138,7 @@ void Cheevos::loadFromFile()
{ {
if (options.console) if (options.console)
{ {
std::cerr << "Error: Unable to create file!" << std::endl; std::cerr << "Error: Unable to create " << file_ << "!" << std::endl;
} }
} }
} }
@@ -148,7 +147,7 @@ void Cheevos::loadFromFile()
{ {
if (options.console) if (options.console)
{ {
std::cout << "Reading file...!" << std::endl; std::cout << "Reading " << file_ << std::endl;
} }
// Carga los datos // Carga los datos

View File

@@ -1,8 +1,7 @@
#pragma once #pragma once
#include <string> // Para string
#include <vector> // Para vector #include <string> // for string
class Screen; #include <vector> // for vector
struct options_t;
// Struct para los logros // Struct para los logros
struct Achievement struct Achievement

View File

@@ -1,20 +1,22 @@
#include "credits.h" #include "credits.h"
#include <SDL2/SDL_blendmode.h> // Para SDL_BLENDMODE_BLEND #include <SDL2/SDL_blendmode.h> // for SDL_BLENDMODE_BLEND
#include <SDL2/SDL_error.h> // Para SDL_GetError #include <SDL2/SDL_error.h> // for SDL_GetError
#include <SDL2/SDL_pixels.h> // Para SDL_PIXELFORMAT_RGBA8888 #include <SDL2/SDL_events.h> // for SDL_PollEvent, SDL_Event
#include <SDL2/SDL_rect.h> // Para SDL_Rect #include <SDL2/SDL_pixels.h> // for SDL_PIXELFORMAT_RGBA8888
#include <SDL2/SDL_timer.h> // Para SDL_GetTicks #include <SDL2/SDL_rect.h> // for SDL_Rect
#include <algorithm> // Para min #include <SDL2/SDL_timer.h> // for SDL_GetTicks
#include <iostream> // Para char_traits, basic_ostream, operator<< #include <algorithm> // for min
#include "animatedsprite.h" // Para AnimatedSprite #include <iostream> // for basic_ostream, operator<<, cout, endl
#include "const.h" // Para GAMECANVAS_HEIGHT, GAMECANVAS_WIDTH #include "animated_sprite.h" // for AnimatedSprite
#include "input.h" // Para Input, REPEAT_FALSE, inputs_e #include "asset.h" // for Asset
#include "resource.h" // Para Resource #include "defines.h" // for GAMECANVAS_HEIGHT, GAMECANVAS_WIDTH
#include "screen.h" // Para Screen #include "global_events.h" // for check
#include "text.h" // Para Text, TXT_CENTER, TXT_COLOR #include "global_inputs.h" // for check
#include "asset.h" #include "input.h" // for Input
#include "options.h" #include "options.h" // for Options, options, OptionsVideo, Sect...
class Asset; #include "resource.h" // for Resource
#include "screen.h" // for Screen
#include "text.h" // for Text, TEXT_CENTER, TEXT_COLOR
// Constructor // Constructor
Credits::Credits() Credits::Credits()
@@ -25,16 +27,16 @@ Credits::Credits()
input_(Input::get()) input_(Input::get())
{ {
// Reserva memoria para los punteros // Reserva memoria para los punteros
text_ = new Text(resource_->getOffset("smb2.txt"), resource_->getTexture("smb2.png"), renderer_); text_ = resource_->getText("smb2");
sprite_ = new AnimatedSprite(renderer_, resource_->getAnimation("shine.ani")); sprite_ = std::make_shared<AnimatedSprite>(resource_->getTexture("shine.png"), resource_->getAnimations("shine.ani"));
// Inicializa variables // Inicializa variables
options.section.name = SECTION_CREDITS; options.section.section = Section::CREDITS;
options.section.subsection = 0; options.section.subsection = Subsection::NONE;
sprite_->setRect({194, 174, 8, 8}); sprite_->setPosition({194, 174, 8, 8});
// Cambia el color del borde // Cambia el color del borde
screen_->setBorderColor(stringToColor(options.palette, "black")); screen_->setBorderColor(stringToColor(options.video.palette, "black"));
// Crea la textura para el texto que se escribe en pantalla // Crea la textura para el texto que se escribe en pantalla
text_texture_ = SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT); text_texture_ = SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT);
@@ -65,8 +67,6 @@ Credits::Credits()
// Destructor // Destructor
Credits::~Credits() Credits::~Credits()
{ {
delete text_;
delete sprite_;
SDL_DestroyTexture(text_texture_); SDL_DestroyTexture(text_texture_);
SDL_DestroyTexture(cover_texture_); SDL_DestroyTexture(cover_texture_);
} }
@@ -77,65 +77,25 @@ void Credits::checkEvents()
SDL_Event event; SDL_Event event;
while (SDL_PollEvent(&event)) while (SDL_PollEvent(&event))
{ {
// Evento de salida de la aplicación globalEvents::check(event);
if (event.type == SDL_QUIT)
{
options.section.name = SECTION_QUIT;
break;
}
} }
} }
// Comprueba las entradas // Comprueba las entradas
void Credits::checkInput() void Credits::checkInput()
{ {
globalInputs::check();
if (input_->checkInput(input_exit, REPEAT_FALSE))
{
options.section.name = SECTION_QUIT;
}
else if (input_->checkInput(input_toggle_border, REPEAT_FALSE))
{
screen_->toggleBorder();
}
else if (input_->checkInput(input_toggle_videomode, REPEAT_FALSE))
{
screen_->toggleVideoMode();
}
else if (input_->checkInput(input_window_dec_size, REPEAT_FALSE))
{
screen_->decWindowSize();
}
else if (input_->checkInput(input_window_inc_size, REPEAT_FALSE))
{
screen_->incWindowSize();
}
else if (input_->checkInput(input_toggle_palette, REPEAT_FALSE))
{
switchPalette();
}
else if (input_->checkInput(input_pause, REPEAT_FALSE) || input_->checkInput(input_accept, REPEAT_FALSE) || input_->checkInput(input_jump, REPEAT_FALSE))
{
options.section.name = SECTION_TITLE;
options.section.subsection = 0;
}
} }
// Inicializa los textos // Inicializa los textos
void Credits::iniTexts() void Credits::iniTexts()
{ {
std::string keys = ""; std::string keys = "";
if (options.keys == ctrl_cursor) if (options.keys == ControlScheme::CURSOR)
{ {
keys = "CURSORS"; keys = "CURSORS";
} }
else if (options.keys == ctrl_opqa) else if (options.keys == ControlScheme::OPQA)
{ {
keys = "O,P AND Q"; keys = "O,P AND Q";
} }
@@ -146,62 +106,62 @@ void Credits::iniTexts()
#ifndef GAME_CONSOLE #ifndef GAME_CONSOLE
texts_.clear(); texts_.clear();
texts_.push_back({"", stringToColor(options.palette, "white")}); texts_.push_back({"", stringToColor(options.video.palette, "white")});
texts_.push_back({"INSTRUCTIONS:", stringToColor(options.palette, "yellow")}); texts_.push_back({"INSTRUCTIONS:", stringToColor(options.video.palette, "yellow")});
texts_.push_back({"", stringToColor(options.palette, "white")}); texts_.push_back({"", stringToColor(options.video.palette, "white")});
texts_.push_back({"HELP JAILDOC TO GET BACK ALL", stringToColor(options.palette, "white")}); texts_.push_back({"HELP JAILDOC TO GET BACK ALL", stringToColor(options.video.palette, "white")});
texts_.push_back({"HIS PROJECTS AND GO TO THE", stringToColor(options.palette, "white")}); texts_.push_back({"HIS PROJECTS AND GO TO THE", stringToColor(options.video.palette, "white")});
texts_.push_back({"JAIL TO FINISH THEM", stringToColor(options.palette, "white")}); texts_.push_back({"JAIL TO FINISH THEM", stringToColor(options.video.palette, "white")});
texts_.push_back({"", stringToColor(options.palette, "white")}); texts_.push_back({"", stringToColor(options.video.palette, "white")});
texts_.push_back({"", stringToColor(options.palette, "white")}); texts_.push_back({"", stringToColor(options.video.palette, "white")});
texts_.push_back({"KEYS:", stringToColor(options.palette, "yellow")}); texts_.push_back({"KEYS:", stringToColor(options.video.palette, "yellow")});
texts_.push_back({"", stringToColor(options.palette, "white")}); texts_.push_back({"", stringToColor(options.video.palette, "white")});
texts_.push_back({keys + " TO MOVE AND JUMP", stringToColor(options.palette, "white")}); texts_.push_back({keys + " TO MOVE AND JUMP", stringToColor(options.video.palette, "white")});
texts_.push_back({"M TO SWITCH THE MUSIC", stringToColor(options.palette, "white")}); texts_.push_back({"M TO SWITCH THE MUSIC", stringToColor(options.video.palette, "white")});
texts_.push_back({"H TO PAUSE THE GAME", stringToColor(options.palette, "white")}); texts_.push_back({"H TO PAUSE THE GAME", stringToColor(options.video.palette, "white")});
texts_.push_back({"F1-F2 TO CHANGE WINDOWS SIZE", stringToColor(options.palette, "white")}); texts_.push_back({"F1-F2 TO CHANGE WINDOWS SIZE", stringToColor(options.video.palette, "white")});
texts_.push_back({"F3 TO SWITCH TO FULLSCREEN", stringToColor(options.palette, "white")}); texts_.push_back({"F3 TO SWITCH TO FULLSCREEN", stringToColor(options.video.palette, "white")});
texts_.push_back({"B TO TOOGLE THE BORDER SCREEN", stringToColor(options.palette, "white")}); texts_.push_back({"B TO TOOGLE THE BORDER SCREEN", stringToColor(options.video.palette, "white")});
texts_.push_back({"", stringToColor(options.palette, "white")}); texts_.push_back({"", stringToColor(options.video.palette, "white")});
texts_.push_back({"", stringToColor(options.palette, "white")}); texts_.push_back({"", stringToColor(options.video.palette, "white")});
texts_.push_back({"A GAME BY JAILDESIGNER", stringToColor(options.palette, "yellow")}); texts_.push_back({"A GAME BY JAILDESIGNER", stringToColor(options.video.palette, "yellow")});
texts_.push_back({"MADE ON SUMMER/FALL 2022", stringToColor(options.palette, "yellow")}); texts_.push_back({"MADE ON SUMMER/FALL 2022", stringToColor(options.video.palette, "yellow")});
texts_.push_back({"", stringToColor(options.palette, "white")}); texts_.push_back({"", stringToColor(options.video.palette, "white")});
texts_.push_back({"", stringToColor(options.palette, "white")}); texts_.push_back({"", stringToColor(options.video.palette, "white")});
texts_.push_back({"I LOVE JAILGAMES! ", stringToColor(options.palette, "white")}); texts_.push_back({"I LOVE JAILGAMES! ", stringToColor(options.video.palette, "white")});
texts_.push_back({"", stringToColor(options.palette, "white")}); texts_.push_back({"", stringToColor(options.video.palette, "white")});
#else #else
texts.clear(); texts.clear();
texts.push_back({"", stringToColor(options.palette, "white")}); texts.push_back({"", stringToColor(options.video.palette, "white")});
texts.push_back({"INSTRUCTIONS:", stringToColor(options.palette, "yellow")}); texts.push_back({"INSTRUCTIONS:", stringToColor(options.video.palette, "yellow")});
texts.push_back({"", stringToColor(options.palette, "white")}); texts.push_back({"", stringToColor(options.video.palette, "white")});
texts.push_back({"HELP JAILDOC TO GET BACK ALL", stringToColor(options.palette, "white")}); texts.push_back({"HELP JAILDOC TO GET BACK ALL", stringToColor(options.video.palette, "white")});
texts.push_back({"HIS PROJECTS AND GO TO THE", stringToColor(options.palette, "white")}); texts.push_back({"HIS PROJECTS AND GO TO THE", stringToColor(options.video.palette, "white")});
texts.push_back({"JAIL TO FINISH THEM", stringToColor(options.palette, "white")}); texts.push_back({"JAIL TO FINISH THEM", stringToColor(options.video.palette, "white")});
texts.push_back({"", stringToColor(options.palette, "white")}); texts.push_back({"", stringToColor(options.video.palette, "white")});
texts.push_back({"", stringToColor(options.palette, "white")}); texts.push_back({"", stringToColor(options.video.palette, "white")});
texts.push_back({"KEYS:", stringToColor(options.palette, "yellow")}); texts.push_back({"KEYS:", stringToColor(options.video.palette, "yellow")});
texts.push_back({"", stringToColor(options.palette, "white")}); texts.push_back({"", stringToColor(options.video.palette, "white")});
texts.push_back({"B TO JUMP", stringToColor(options.palette, "white")}); texts.push_back({"B TO JUMP", stringToColor(options.video.palette, "white")});
texts.push_back({"R TO SWITCH THE MUSIC", stringToColor(options.palette, "white")}); texts.push_back({"R TO SWITCH THE MUSIC", stringToColor(options.video.palette, "white")});
texts.push_back({"L TO SWAP THE COLOR PALETTE", stringToColor(options.palette, "white")}); texts.push_back({"L TO SWAP THE COLOR PALETTE", stringToColor(options.video.palette, "white")});
texts.push_back({"START TO PAUSE", stringToColor(options.palette, "white")}); texts.push_back({"START TO PAUSE", stringToColor(options.video.palette, "white")});
texts.push_back({"SELECT TO EXIT", stringToColor(options.palette, "white")}); texts.push_back({"SELECT TO EXIT", stringToColor(options.video.palette, "white")});
texts.push_back({"", stringToColor(options.palette, "white")}); texts.push_back({"", stringToColor(options.video.palette, "white")});
texts.push_back({"", stringToColor(options.palette, "white")}); texts.push_back({"", stringToColor(options.video.palette, "white")});
texts.push_back({"", stringToColor(options.palette, "white")}); texts.push_back({"", stringToColor(options.video.palette, "white")});
texts.push_back({"A GAME BY JAILDESIGNER", stringToColor(options.palette, "yellow")}); texts.push_back({"A GAME BY JAILDESIGNER", stringToColor(options.video.palette, "yellow")});
texts.push_back({"MADE ON SUMMER/FALL 2022", stringToColor(options.palette, "yellow")}); texts.push_back({"MADE ON SUMMER/FALL 2022", stringToColor(options.video.palette, "yellow")});
texts.push_back({"", stringToColor(options.palette, "white")}); texts.push_back({"", stringToColor(options.video.palette, "white")});
texts.push_back({"", stringToColor(options.palette, "white")}); texts.push_back({"", stringToColor(options.video.palette, "white")});
texts.push_back({"I LOVE JAILGAMES! ", stringToColor(options.palette, "white")}); texts.push_back({"I LOVE JAILGAMES! ", stringToColor(options.video.palette, "white")});
texts.push_back({"", stringToColor(options.palette, "white")}); texts.push_back({"", stringToColor(options.video.palette, "white")});
#endif #endif
} }
@@ -213,7 +173,7 @@ void Credits::fillTexture()
// Rellena la textura de texto // Rellena la textura de texto
SDL_SetRenderTarget(renderer_, text_texture_); SDL_SetRenderTarget(renderer_, text_texture_);
color_t c = stringToColor(options.palette, "black"); Color c = stringToColor(options.video.palette, "black");
SDL_SetRenderDrawColor(renderer_, c.r, c.g, c.b, 0xFF); SDL_SetRenderDrawColor(renderer_, c.r, c.g, c.b, 0xFF);
SDL_RenderClear(renderer_); SDL_RenderClear(renderer_);
@@ -223,14 +183,14 @@ void Credits::fillTexture()
for (auto t : texts_) for (auto t : texts_)
{ {
text_->writeDX(TXT_CENTER | TXT_COLOR, PLAY_AREA_CENTER_X, i * size, t.label, 1, t.color); text_->writeDX(TEXT_CENTER | TEXT_COLOR, PLAY_AREA_CENTER_X, i * size, t.label, 1, t.color);
i++; i++;
} }
// Escribe el corazón // Escribe el corazón
const int textLenght = text_->lenght(texts_[22].label, 1) - text_->lenght(" ", 1); // Se resta el ultimo caracter que es un espacio const int textLenght = text_->lenght(texts_[22].label, 1) - text_->lenght(" ", 1); // Se resta el ultimo caracter que es un espacio
const int posX = ((PLAY_AREA_WIDTH - textLenght) / 2) + textLenght; const int posX = ((PLAY_AREA_WIDTH - textLenght) / 2) + textLenght;
text_->writeColored(posX, 176, "}", stringToColor(options.palette, "bright_red")); text_->writeColored(posX, 176, "}", stringToColor(options.video.palette, "bright_red"));
// Recoloca el sprite del brillo // Recoloca el sprite del brillo
sprite_->setPosX(posX + 2); sprite_->setPosX(posX + 2);
@@ -287,7 +247,7 @@ void Credits::updateCounter()
// Comprueba si ha terminado la sección // Comprueba si ha terminado la sección
if (counter_ > 1200) if (counter_ > 1200)
{ {
options.section.name = SECTION_DEMO; options.section.section = Section::DEMO;
} }
} }
@@ -295,7 +255,7 @@ void Credits::updateCounter()
void Credits::update() void Credits::update()
{ {
// Comprueba que la diferencia de ticks sea mayor a la velocidad del juego // Comprueba que la diferencia de ticks sea mayor a la velocidad del juego
if (SDL_GetTicks() - ticks_ > ticks_speed_) if (SDL_GetTicks() - ticks_ > GAME_SPEED)
{ {
// Actualiza el contador de ticks // Actualiza el contador de ticks
ticks_ = SDL_GetTicks(); ticks_ = SDL_GetTicks();
@@ -347,7 +307,7 @@ void Credits::render()
// Bucle para el logo del juego // Bucle para el logo del juego
void Credits::run() void Credits::run()
{ {
while (options.section.name == SECTION_CREDITS) while (options.section.section == Section::CREDITS)
{ {
update(); update();
checkEvents(); checkEvents();
@@ -358,6 +318,6 @@ void Credits::run()
// Cambia la paleta // Cambia la paleta
void Credits::switchPalette() void Credits::switchPalette()
{ {
options.palette = options.palette == p_zxspectrum ? p_zxarne : p_zxspectrum; options.video.palette = options.video.palette == Palette::ZXSPECTRUM ? Palette::ZXARNE : Palette::ZXSPECTRUM;
fillTexture(); fillTexture();
} }

View File

@@ -1,17 +1,17 @@
#pragma once #pragma once
#include <SDL2/SDL_events.h> // Para SDL_Event #include <SDL2/SDL_render.h> // for SDL_Texture, SDL_Renderer
#include <SDL2/SDL_render.h> // Para SDL_Renderer, SDL_Texture #include <SDL2/SDL_stdinc.h> // for Uint32
#include <SDL2/SDL_stdinc.h> // Para Uint32 #include <memory> // for shared_ptr
#include <string> // Para basic_string, string #include <string> // for string
#include <vector> // Para vector #include <vector> // for vector
#include "utils.h" // Para color_t #include "utils.h" // for Color
class AnimatedSprite; class AnimatedSprite; // lines 10-10
class Asset; class Asset; // lines 11-11
class Input; class Input; // lines 12-12
class Resource; class Resource; // lines 13-13
class Screen; class Screen; // lines 14-14
class Text; class Text; // lines 15-15
class Credits class Credits
{ {
@@ -19,26 +19,25 @@ private:
struct captions_t struct captions_t
{ {
std::string label; // Texto a escribir std::string label; // Texto a escribir
color_t color; // Color del texto Color color; // Color del texto
}; };
// Objetos y punteros // Objetos y punteros
Screen *screen_; // Objeto encargado de dibujar en pantalla Screen *screen_; // Objeto encargado de dibujar en pantalla
SDL_Renderer *renderer_; // El renderizador de la ventana SDL_Renderer *renderer_; // El renderizador de la ventana
Resource *resource_; // Objeto con los recursos Resource *resource_; // Objeto con los recursos
Asset *asset_; // Objeto con los ficheros de recursos Asset *asset_; // Objeto con los ficheros de recursos
Input *input_; // Objeto pata gestionar la entrada Input *input_; // Objeto pata gestionar la entrada
Text *text_; // Objeto para escribir texto en pantalla std::shared_ptr<Text> text_; // Objeto para escribir texto en pantalla
SDL_Texture *text_texture_; // Textura para dibujar el texto SDL_Texture *text_texture_; // Textura para dibujar el texto
SDL_Texture *cover_texture_; // Textura para cubrir el texto SDL_Texture *cover_texture_; // Textura para cubrir el texto
AnimatedSprite *sprite_; // Sprite para el brillo del corazón std::shared_ptr<AnimatedSprite> sprite_; // Sprite para el brillo del corazón
// Variables // Variables
int counter_ = 0; // Contador int counter_ = 0; // Contador
bool counter_enabled_ = true; // Indica si esta activo el contador bool counter_enabled_ = true; // Indica si esta activo el contador
int sub_counter_ = 0; // Contador secundario int sub_counter_ = 0; // Contador secundario
Uint32 ticks_ = 0; // Contador de ticks para ajustar la velocidad del programa Uint32 ticks_ = 0; // Contador de ticks para ajustar la velocidad del programa
Uint32 ticks_speed_ = 15; // Velocidad a la que se repiten los bucles del programa
std::vector<captions_t> texts_; // Vector con los textos std::vector<captions_t> texts_; // Vector con los textos
// Actualiza las variables // Actualiza las variables

View File

@@ -1,11 +1,9 @@
#include "debug.h" #include "debug.h"
#include <algorithm> // Para max #include <algorithm> // for max
#include "asset.h" // Para Asset #include "resource.h" // for Resource
#include "text.h" // Para Text #include "screen.h" // for Screen
#include "texture.h" // Para Texture #include "text.h" // for Text
#include "utils.h" #include "utils.h" // for Color
#include "screen.h"
#include "asset.h"
// [SINGLETON] // [SINGLETON]
Debug *Debug::debug_ = nullptr; Debug *Debug::debug_ = nullptr;
@@ -13,38 +11,30 @@ Debug *Debug::debug_ = nullptr;
// [SINGLETON] Crearemos el objeto con esta función estática // [SINGLETON] Crearemos el objeto con esta función estática
void Debug::init() void Debug::init()
{ {
Debug::debug_ = new Debug(); Debug::debug_ = new Debug();
} }
// [SINGLETON] Destruiremos el objeto con esta función estática // [SINGLETON] Destruiremos el objeto con esta función estática
void Debug::destroy() void Debug::destroy()
{ {
delete Debug::debug_; delete Debug::debug_;
} }
// [SINGLETON] Con este método obtenemos el objeto y podemos trabajar con él // [SINGLETON] Con este método obtenemos el objeto y podemos trabajar con él
Debug *Debug::get() Debug *Debug::get()
{ {
return Debug::debug_; return Debug::debug_;
} }
// Constructor // Constructor
Debug::Debug() Debug::Debug()
// Copia la dirección de los objetos // Copia la dirección de los objetos
: screen_(Screen::get()), : screen_(Screen::get()),
renderer_(Screen::get()->getRenderer()), renderer_(Screen::get()->getRenderer())
asset_(Asset::get())
{ {
// Reserva memoria para los punteros // Reserva memoria para los punteros
texture_ = new Texture(renderer_, asset_->get("debug.png")); texture_ = Resource::get()->getTexture("debug.png");
text_ = new Text(asset_->get("debug.txt"), texture_, renderer_); text_ = Resource::get()->getText("debug");
}
// Destructor
Debug::~Debug()
{
delete texture_;
delete text_;
} }
// Actualiza las variables // Actualiza las variables
@@ -73,7 +63,7 @@ void Debug::render()
y = 0; y = 0;
for (auto l : log_) for (auto l : log_)
{ {
text_->writeColored(x_ + 10, y, l, color_t(255, 255, 255)); text_->writeColored(x_ + 10, y, l, Color(255, 255, 255));
y += text_->getCharacterSize() + 1; y += text_->getCharacterSize() + 1;
} }
} }
@@ -84,45 +74,3 @@ void Debug::setPos(SDL_Point p)
x_ = p.x; x_ = p.x;
y_ = p.y; y_ = p.y;
} }
// Añade un texto para mostrar
void Debug::add(std::string text)
{
slot_.push_back(text);
}
// Borra la información de debug
void Debug::clear()
{
slot_.clear();
}
// Añade un texto para mostrar en el apartado log
void Debug::addToLog(std::string text)
{
log_.push_back(text);
}
// Borra la información de debug del apartado log
void Debug::clearLog()
{
log_.clear();
}
// Establece el valor de la variable
void Debug::setEnabled(bool value)
{
enabled_ = value;
}
// Obtiene el valor de la variable
bool Debug::getEnabled()
{
return enabled_;
}
// Cambia el valor de la variable
void Debug::switchEnabled()
{
enabled_ = !enabled_;
}

View File

@@ -1,13 +1,13 @@
#pragma once #pragma once
#include <SDL2/SDL_rect.h> // Para SDL_Point #include <SDL2/SDL_rect.h> // for SDL_Point
#include <SDL2/SDL_render.h> // Para SDL_Renderer #include <SDL2/SDL_render.h> // for SDL_Renderer
#include <string> // Para string #include <memory> // for shared_ptr
#include <vector> // Para vector #include <string> // for string
class Asset; #include <vector> // for vector
class Screen; class Screen; // lines 9-9
class Text; class Text; // lines 10-10
class Texture; class Texture; // lines 11-11
// Clase Debug // Clase Debug
class Debug class Debug
@@ -17,11 +17,10 @@ private:
static Debug *debug_; static Debug *debug_;
// Objetos y punteros // Objetos y punteros
Screen *screen_; // Objeto encargado de dibujar en pantalla Screen *screen_; // Objeto encargado de dibujar en pantalla
SDL_Renderer *renderer_; // El renderizador de la ventana SDL_Renderer *renderer_; // El renderizador de la ventana
Asset *asset_; // Objeto con los ficheros de recursos std::shared_ptr<Text> text_; // Objeto encargado de escribir texto en pantalla
Text *text_; // Objeto encargado de escribir texto en pantalla std::shared_ptr<Texture> texture_; // Textura para el texto
Texture *texture_; // Textura para el texto
// Variables // Variables
std::vector<std::string> slot_; // Vector con los textos a escribir std::vector<std::string> slot_; // Vector con los textos a escribir
@@ -34,7 +33,7 @@ private:
Debug(); Debug();
// Destructor // Destructor
~Debug(); ~Debug() = default;
public: public:
// [SINGLETON] Crearemos el objeto con esta función estática // [SINGLETON] Crearemos el objeto con esta función estática
@@ -55,24 +54,14 @@ public:
// Establece la posición donde se colocará la información de debug // Establece la posición donde se colocará la información de debug
void setPos(SDL_Point p); void setPos(SDL_Point p);
// Añade un texto para mostrar // Getters
void add(std::string text); bool getEnabled() { return enabled_; }
// Borra la información de debug // Setters
void clear(); void add(std::string text) { slot_.push_back(text); }
void clear() { slot_.clear(); }
// Añade un texto para mostrar en el apartado log void addToLog(std::string text) { log_.push_back(text); }
void addToLog(std::string text); void clearLog() { log_.clear(); }
void setEnabled(bool value) { enabled_ = value; }
// Borra la información de debug del apartado log void switchEnabled() { enabled_ = !enabled_; }
void clearLog();
// Establece el valor de la variable
void setEnabled(bool value);
// Obtiene el valor de la variable
bool getEnabled();
// Cambia el valor de la variable
void switchEnabled();
}; };

View File

@@ -5,9 +5,12 @@
#include "utils.h" #include "utils.h"
// Textos // Textos
constexpr const char* WINDOW_CAPTION = "JailDoctor's Dilemma"; constexpr const char *WINDOW_CAPTION = "JailDoctor's Dilemma";
constexpr const char* TEXT_COPYRIGHT = "@2022 JailDesigner"; constexpr const char *TEXT_COPYRIGHT = "@2022 JailDesigner";
constexpr const char* VERSION = "0.7"; constexpr const char *VERSION = "1.09";
// Velocidad del juego
constexpr Uint32 GAME_SPEED = 1000 / 60;
// Tamaño de bloque // Tamaño de bloque
constexpr int BLOCK = 8; constexpr int BLOCK = 8;
@@ -44,24 +47,6 @@ constexpr int GAMECANVAS_CENTER_Y = GAMECANVAS_HEIGHT / 2;
constexpr int GAMECANVAS_FIRST_QUARTER_Y = GAMECANVAS_HEIGHT / 4; constexpr int GAMECANVAS_FIRST_QUARTER_Y = GAMECANVAS_HEIGHT / 4;
constexpr int GAMECANVAS_THIRD_QUARTER_Y = (GAMECANVAS_HEIGHT / 4) * 3; constexpr int GAMECANVAS_THIRD_QUARTER_Y = (GAMECANVAS_HEIGHT / 4) * 3;
// Secciones del programa
constexpr int SECTION_LOGO = 0;
constexpr int SECTION_LOADING_SCREEN = 1;
constexpr int SECTION_TITLE = 2;
constexpr int SECTION_CREDITS = 3;
constexpr int SECTION_GAME = 4;
constexpr int SECTION_DEMO = 5;
constexpr int SECTION_GAME_OVER = 6;
constexpr int SECTION_ENDING = 7;
constexpr int SECTION_ENDING2 = 8;
constexpr int SECTION_QUIT = 9;
// Subsecciones
constexpr int SUBSECTION_LOGO_TO_INTRO = 0;
constexpr int SUBSECTION_LOGO_TO_TITLE = 1;
constexpr int SUBSECTION_TITLE_WITH_LOADING_SCREEN = 2;
constexpr int SUBSECTION_TITLE_WITHOUT_LOADING_SCREEN = 3;
// Colores // Colores
const color_t borderColor = {0x27, 0x27, 0x36}; const Color borderColor = {0x27, 0x27, 0x36};
const color_t black = {0xFF, 0xFF, 0xFF}; const Color black = {0xFF, 0xFF, 0xFF};

View File

@@ -1,71 +1,71 @@
#include "demo.h" #include "demo.h"
#include <SDL2/SDL_rect.h> // Para SDL_Rect #include <SDL2/SDL_events.h> // for SDL_PollEvent, SDL_Event
#include <SDL2/SDL_timer.h> // Para SDL_GetTicks #include <SDL2/SDL_rect.h> // for SDL_Rect
#include <iostream> // Para basic_ostream, basic_ios, operator<<, cout #include <SDL2/SDL_timer.h> // for SDL_GetTicks
#include "asset.h" // Para Asset #include <iostream> // for basic_ostream, operator<<, cout, endl
#include "const.h" // Para BLOCK, PLAY_AREA_WIDTH, SECTION_DEMO #include "asset.h" // for Asset
#include "input.h" // Para Input, REPEAT_FALSE, inputs_e #include "debug.h" // for Debug
#include "item_tracker.h" // Para ItemTracker #include "defines.h" // for BLOCK, PLAY_AREA_WIDTH, GAMECANVAS_CENT...
#include "resource.h" // Para Resource #include "global_events.h" // for check
#include "room.h" // Para Room #include "global_inputs.h" // for check
#include "screen.h" // Para Screen #include "input.h" // for Input
#include "text.h" // Para Text, TXT_CENTER, TXT_COLOR #include "item_tracker.h" // for ItemTracker
#include "utils.h" // Para color_t, stringToColor, options_t, secti... #include "options.h" // for Options, options, OptionsVideo, Section...
#include "options.h" #include "resource.h" // for Resource
#include "debug.h" #include "room.h" // for Room
#include "screen.h" // for Screen
#include "text.h" // for Text, TEXT_CENTER, TEXT_COLOR
#include "utils.h" // for Color, stringToColor, colorAreEqual
// Constructor // Constructor
Demo::Demo() Demo::Demo()
: screen(Screen::get()), : screen_(Screen::get()),
renderer(Screen::get()->getRenderer()), renderer_(Screen::get()->getRenderer()),
resource(Resource::get()), resource_(Resource::get()),
asset(Asset::get()), asset_(Asset::get()),
input(Input::get()), input_(Input::get()),
debug(Debug::get()) debug_(Debug::get())
{ {
// Inicia algunas variables // Inicia algunas variables
board.iniClock = SDL_GetTicks(); board_ = std::make_shared<ScoreboardData>();
rooms.push_back("04.room"); board_->ini_clock = SDL_GetTicks();
rooms.push_back("54.room"); rooms_.push_back("04.room");
rooms.push_back("20.room"); rooms_.push_back("54.room");
rooms.push_back("09.room"); rooms_.push_back("20.room");
rooms.push_back("05.room"); rooms_.push_back("09.room");
rooms.push_back("11.room"); rooms_.push_back("05.room");
rooms.push_back("31.room"); rooms_.push_back("11.room");
rooms.push_back("44.room"); rooms_.push_back("31.room");
rooms_.push_back("44.room");
roomIndex = 0; room_index_ = 0;
currentRoom = rooms[roomIndex]; current_room_ = rooms_[room_index_];
// Crea los objetos // Crea los objetos
itemTracker = new ItemTracker(); ItemTracker::init();
scoreboard = new Scoreboard(&board); scoreboard_ = std::make_shared<Scoreboard>(board_);
room = new Room(resource->getRoom(currentRoom), itemTracker, &board.items, false); room_ = std::make_shared<Room>(resource_->getRoom(current_room_), board_);
text = new Text(resource->getOffset("smb2.txt"), resource->getTexture("smb2.png"), renderer); text_ = resource_->getText("smb2");
// Inicializa el resto de variables // Inicializa el resto de variables
counter = 0; counter_ = 0;
roomTime = 400; room_time_ = 400;
ticks = 0; ticks_ = 0;
ticksSpeed = 15; board_->lives = 9;
board.lives = 9; board_->items = 0;
board.items = 0; board_->rooms = 1;
board.rooms = 1; board_->jail_is_open = false;
board.jailEnabled = false; board_->music = true;
board.music = true;
setScoreBoardColor(); setScoreBoardColor();
options.section.name = SECTION_DEMO; options.section.section = Section::DEMO;
options.section.subsection = 0; options.section.subsection = Subsection::NONE;
} }
// Destructor
Demo::~Demo() Demo::~Demo()
{ {
// Libera la memoria de los objetos ItemTracker::destroy();
delete itemTracker;
delete scoreboard;
delete room;
delete text;
} }
// Comprueba los eventos de la cola // Comprueba los eventos de la cola
@@ -74,64 +74,20 @@ void Demo::checkEvents()
SDL_Event event; SDL_Event event;
while (SDL_PollEvent(&event)) while (SDL_PollEvent(&event))
{ {
// Evento de salida de la aplicación globalEvents::check(event);
if (event.type == SDL_QUIT)
{
options.section.name = SECTION_QUIT;
screen->setBorderColor(stringToColor(options.palette, "black"));
break;
}
} }
} }
// Comprueba las entradas // Comprueba las entradas
void Demo::checkInput() void Demo::checkInput()
{ {
if (input->checkInput(input_exit, REPEAT_FALSE)) globalInputs::check();
{
options.section.name = SECTION_QUIT;
}
else if (input->checkInput(input_toggle_border, REPEAT_FALSE))
{
screen->toggleBorder();
reLoadTextures();
}
else if (input->checkInput(input_toggle_videomode, REPEAT_FALSE))
{
screen->toggleVideoMode();
reLoadTextures();
}
else if (input->checkInput(input_window_dec_size, REPEAT_FALSE))
{
screen->decWindowSize();
reLoadTextures();
}
else if (input->checkInput(input_window_inc_size, REPEAT_FALSE))
{
screen->incWindowSize();
reLoadTextures();
}
else if (input->checkInput(input_toggle_palette, REPEAT_FALSE))
{
switchPalette();
}
else if (input->checkInput(input_pause, REPEAT_FALSE) || input->checkInput(input_accept, REPEAT_FALSE) || input->checkInput(input_jump, REPEAT_FALSE))
{
options.section.name = SECTION_TITLE;
options.section.subsection = 0;
}
} }
// Bucle para el juego // Bucle para el juego
void Demo::run() void Demo::run()
{ {
while (options.section.name == SECTION_DEMO) while (options.section.section == Section::DEMO)
{ {
update(); update();
checkEvents(); checkEvents();
@@ -143,21 +99,20 @@ void Demo::run()
void Demo::update() void Demo::update()
{ {
// Comprueba que la diferencia de ticks sea mayor a la velocidad del juego // Comprueba que la diferencia de ticks sea mayor a la velocidad del juego
if (SDL_GetTicks() - ticks > ticksSpeed) if (SDL_GetTicks() - ticks_ > GAME_SPEED)
{ {
// Actualiza el contador de ticks // Actualiza el contador de ticks
ticks = SDL_GetTicks(); ticks_ = SDL_GetTicks();
// Comprueba las entradas // Comprueba las entradas
checkInput(); checkInput();
// Actualiza los objetos // Actualiza los objetos
room->update(); room_->update();
scoreboard->update(); scoreboard_->update();
screen->updateFX();
checkRoomChange(); checkRoomChange();
screen->update(); screen_->update();
} }
} }
@@ -165,18 +120,17 @@ void Demo::update()
void Demo::render() void Demo::render()
{ {
// Prepara para dibujar el frame // Prepara para dibujar el frame
screen->start(); screen_->start();
// Dibuja los elementos del juego en orden // Dibuja los elementos del juego en orden
room->renderMap(); room_->renderMap();
room->renderEnemies(); room_->renderEnemies();
room->renderItems(); room_->renderItems();
renderRoomName(); renderRoomName();
scoreboard->render(); scoreboard_->render();
screen->renderFX();
// Actualiza la pantalla // Actualiza la pantalla
screen->render(); screen_->render();
} }
// Escribe el nombre de la pantalla // Escribe el nombre de la pantalla
@@ -184,11 +138,11 @@ void Demo::renderRoomName()
{ {
// Texto en el centro de la pantalla // Texto en el centro de la pantalla
SDL_Rect rect = {0, 16 * BLOCK, PLAY_AREA_WIDTH, BLOCK * 2}; SDL_Rect rect = {0, 16 * BLOCK, PLAY_AREA_WIDTH, BLOCK * 2};
color_t color = stringToColor(options.palette, "white"); Color color = stringToColor(options.video.palette, "white");
SDL_SetRenderDrawColor(renderer, color.r, color.g, color.b, 0xFF); SDL_SetRenderDrawColor(renderer_, color.r, color.g, color.b, 0xFF);
SDL_RenderFillRect(renderer, &rect); SDL_RenderFillRect(renderer_, &rect);
text->writeDX(TXT_CENTER | TXT_COLOR, GAMECANVAS_CENTER_X, 16 * 8 + 4, room->getName(), 1, room->getBGColor()); text_->writeDX(TEXT_CENTER | TEXT_COLOR, GAMECANVAS_CENTER_X, 16 * 8 + 4, room_->getName(), 1, room_->getBGColor());
} }
// Recarga todas las texturas // Recarga todas las texturas
@@ -198,26 +152,26 @@ void Demo::reLoadTextures()
{ {
std::cout << "** RELOAD REQUESTED" << std::endl; std::cout << "** RELOAD REQUESTED" << std::endl;
} }
room->reLoadTexture(); room_->reLoadTexture();
scoreboard->reLoadTexture(); scoreboard_->reLoadTexture();
text->reLoadTexture(); text_->reLoadTexture();
} }
// Cambia la paleta // Cambia la paleta
void Demo::switchPalette() void Demo::switchPalette()
{ {
// Modifica la variable // Modifica la variable
if (options.palette == p_zxspectrum) if (options.video.palette == Palette::ZXSPECTRUM)
{ {
options.palette = p_zxarne; options.video.palette = Palette::ZXARNE;
} }
else else
{ {
options.palette = p_zxspectrum; options.video.palette = Palette::ZXSPECTRUM;
} }
room->reLoadPalette(); room_->reLoadPalette();
scoreboard->reLoadPalette(); scoreboard_->reLoadPalette();
// Pone el color del marcador en función del color del borde de la habitación // Pone el color del marcador en función del color del borde de la habitación
setScoreBoardColor(); setScoreBoardColor();
@@ -228,21 +182,19 @@ bool Demo::changeRoom(std::string file)
{ {
// En las habitaciones los limites tienen la cadena del fichero o un 0 en caso de no limitar con nada // En las habitaciones los limites tienen la cadena del fichero o un 0 en caso de no limitar con nada
if (file != "0") if (file != "0")
{
// Verifica que exista el fichero que se va a cargar // Verifica que exista el fichero que se va a cargar
if (asset->get(file) != "") if (asset_->get(file) != "")
{ {
// Elimina la habitación actual // Crea un objeto habitación a partir del fichero
delete room; room_ = std::make_shared<Room>(resource_->getRoom(file), board_);
room = nullptr;
// Crea un objeto habitación nuevo a partir del fichero
room = new Room(resource->getRoom(file), itemTracker, &board.items, false);
// Pone el color del marcador en función del color del borde de la habitación // Pone el color del marcador en función del color del borde de la habitación
setScoreBoardColor(); setScoreBoardColor();
return true; return true;
} }
}
return false; return false;
} }
@@ -250,19 +202,19 @@ bool Demo::changeRoom(std::string file)
// Comprueba si se ha de cambiar de habitación // Comprueba si se ha de cambiar de habitación
void Demo::checkRoomChange() void Demo::checkRoomChange()
{ {
counter++; counter_++;
if (counter == roomTime) if (counter_ == room_time_)
{ {
counter = 0; counter_ = 0;
roomIndex++; room_index_++;
if (roomIndex == (int)rooms.size()) if (room_index_ == (int)rooms_.size())
{ {
options.section.name = SECTION_LOGO; options.section.section = Section::LOGO;
options.section.subsection = SUBSECTION_LOGO_TO_TITLE; options.section.subsection = Subsection::LOGO_TO_TITLE;
} }
else else
{ {
changeRoom(rooms[roomIndex]); changeRoom(rooms_[room_index_]);
} }
} }
} }
@@ -271,13 +223,13 @@ void Demo::checkRoomChange()
void Demo::setScoreBoardColor() void Demo::setScoreBoardColor()
{ {
// Obtiene el color del borde // Obtiene el color del borde
const color_t c = room->getBorderColor(); const Color color = room_->getBorderColor();
// Si el color es negro lo cambia a blanco // Si el color es negro lo cambia a blanco
const color_t cBlack = stringToColor(options.palette, "black"); const Color black_color = stringToColor(options.video.palette, "black");
board.color = colorAreEqual(c, cBlack) ? stringToColor(options.palette, "white") : c; board_->color = colorAreEqual(color, black_color) ? stringToColor(options.video.palette, "white") : color;
// Si el color es negro brillante lo cambia a blanco // Si el color es negro brillante lo cambia a blanco
const color_t cBrightBlack = stringToColor(options.palette, "bright_black"); const Color bright_blac_color = stringToColor(options.video.palette, "bright_black");
board.color = colorAreEqual(c, cBrightBlack) ? stringToColor(options.palette, "white") : c; board_->color = colorAreEqual(color, bright_blac_color) ? stringToColor(options.video.palette, "white") : color;
} }

View File

@@ -1,46 +1,42 @@
#pragma once #pragma once
#include <SDL2/SDL_events.h> // Para SDL_Event #include <SDL2/SDL_render.h> // for SDL_Renderer
#include <SDL2/SDL_render.h> // Para SDL_Renderer #include <SDL2/SDL_stdinc.h> // for Uint32
#include <SDL2/SDL_stdinc.h> // Para Uint32 #include <memory> // for shared_ptr
#include <string> // Para string, basic_string #include <string> // for string
#include <vector> // Para vector #include <vector> // for vector
#include "scoreboard.h" // Para board_t #include "scoreboard.h" // for board_t
class Asset; class Asset; // lines 11-11
class Debug; class Debug; // lines 12-12
class Input; class Input; // lines 13-13
class ItemTracker; class ItemTracker; // lines 14-14
class Resource; class Resource; // lines 15-15
class Room; class Room; // lines 16-16
class Screen; class Screen; // lines 17-17
class Text; class Text; // lines 18-18
struct options_t;
struct section_t;
class Demo class Demo
{ {
private: private:
// Objetos y punteros // Objetos y punteros
Screen *screen; // Objeto encargado de manejar el renderizador Screen *screen_; // Objeto encargado de manejar el renderizador
SDL_Renderer *renderer; // El renderizador de la ventana SDL_Renderer *renderer_; // El renderizador de la ventana
Room *room; // Objeto encargado de gestionar cada habitación del juego Resource *resource_; // Objeto con los recursos
Resource *resource; // Objeto con los recursos Asset *asset_; // Objeto con la ruta a todos los ficheros de recursos
Asset *asset; // Objeto con la ruta a todos los ficheros de recursos Input *input_; // Objeto pata gestionar la entrada
Input *input; // Objeto pata gestionar la entrada Debug *debug_; // Objeto para gestionar la información de debug
Text *text; // Objeto para los textos del juego std::shared_ptr<Room> room_; // Objeto encargado de gestionar cada habitación del juego
Scoreboard *scoreboard; // Objeto encargado de gestionar el marcador std::shared_ptr<Text> text_; // Objeto para los textos del juego
ItemTracker *itemTracker; // Lleva el control de los objetos recogidos std::shared_ptr<Scoreboard> scoreboard_; // Objeto encargado de gestionar el marcador
Debug *debug; // Objeto para gestionar la información de debug
// Variables // Variables
Uint32 ticks; // Contador de ticks para ajustar la velocidad del programa Uint32 ticks_; // Contador de ticks para ajustar la velocidad del programa
Uint32 ticksSpeed; // Velocidad a la que se repiten los bucles del programa std::string current_room_; // Fichero de la habitación actual
std::string currentRoom; // Fichero de la habitación actual std::shared_ptr<ScoreboardData> board_; // Estructura con los datos del marcador
board_t board; // Estructura con los datos del marcador int counter_; // Contador para el modo demo
int counter; // Contador para el modo demo int room_time_; // Tiempo que se muestra cada habitacion
int roomTime; // Tiempo que se muestra cada habitacion int room_index_; // Indice para el vector de habitaciones
int roomIndex; // Indice para el vector de habitaciones std::vector<std::string> rooms_; // Listado con los mapas de la demo
std::vector<std::string> rooms; // Listado con los mapas de la demo
// Actualiza el juego, las variables, comprueba la entrada, etc. // Actualiza el juego, las variables, comprueba la entrada, etc.
void update(); void update();

File diff suppressed because it is too large Load Diff

View File

@@ -1,16 +1,9 @@
#pragma once #pragma once
#include <SDL2/SDL_render.h> // for SDL_Renderer #include <SDL2/SDL_render.h> // for SDL_Renderer
#include <SDL2/SDL_video.h> // for SDL_Window #include <SDL2/SDL_video.h> // for SDL_Window
#include <string> // for string #include <string> // for string
class Asset; // lines 6-6 struct JA_Music_t; // lines 11-11
class Debug; // lines 8-8
class Input; // lines 14-14
class Resource; // lines 17-17
class Screen; // lines 18-18
struct JA_Music_t; // lines 20-20
struct options_t; // lines 21-21
struct section_t; // lines 22-22
class Director class Director
{ {
@@ -20,7 +13,6 @@ private:
SDL_Renderer *renderer_; // El renderizador de la ventana SDL_Renderer *renderer_; // El renderizador de la ventana
// Variables // Variables
JA_Music_t *title_music_; // Musica del titulo
std::string executable_path_; // Path del ejecutable std::string executable_path_; // Path del ejecutable
std::string system_folder_; // Carpeta del sistema donde guardar datos std::string system_folder_; // Carpeta del sistema donde guardar datos
@@ -30,9 +22,6 @@ private:
// Crea la carpeta del sistema donde guardar datos // Crea la carpeta del sistema donde guardar datos
void createSystemFolder(const std::string &folder); void createSystemFolder(const std::string &folder);
// Carga los recursos
void loadResources(section_t section);
// Inicializa jail_audio // Inicializa jail_audio
void initJailAudio(); void initJailAudio();

View File

@@ -1,44 +1,46 @@
#include "ending.h" #include "ending.h"
#include <SDL2/SDL_blendmode.h> // Para SDL_BLENDMODE_BLEND #include <SDL2/SDL_blendmode.h> // for SDL_BLENDMODE_BLEND
#include <SDL2/SDL_error.h> // Para SDL_GetError #include <SDL2/SDL_error.h> // for SDL_GetError
#include <SDL2/SDL_pixels.h> // Para SDL_PIXELFORMAT_RGBA8888 #include <SDL2/SDL_events.h> // for SDL_PollEvent, SDL_Event
#include <SDL2/SDL_rect.h> // Para SDL_Rect #include <SDL2/SDL_pixels.h> // for SDL_PIXELFORMAT_RGBA8888
#include <SDL2/SDL_timer.h> // Para SDL_GetTicks #include <SDL2/SDL_rect.h> // for SDL_Rect
#include <algorithm> // Para min #include <SDL2/SDL_timer.h> // for SDL_GetTicks
#include <iostream> // Para basic_ostream, operator<<, basic_ios #include <algorithm> // for min
#include "asset.h" // Para Asset #include <iostream> // for basic_ostream, operator<<, cout, endl
#include "const.h" // Para GAMECANVAS_HEIGHT, GAMECANVAS_WIDTH #include "asset.h" // for Asset
#include "input.h" // Para Input, REPEAT_FALSE, inputs_e #include "defines.h" // for GAMECANVAS_HEIGHT, GAMECANVAS_WIDTH
#include "jail_audio.h" // Para JA_SetVolume, JA_DeleteMusic, JA_Loa... #include "global_events.h" // for check
#include "resource.h" // Para Resource #include "global_inputs.h" // for check
#include "screen.h" // Para Screen #include "input.h" // for Input
#include "sprite.h" // Para Sprite #include "jail_audio.h" // for JA_SetVolume, JA_PlayMusic, JA_StopM...
#include "text.h" // Para Text, TXT_STROKE #include "options.h" // for Options, options, OptionsVideo, Sect...
#include "texture.h" // Para Texture #include "resource.h" // for Resource
#include "utils.h" // Para color_t, stringToColor, options_t #include "screen.h" // for Screen
#include "options.h" #include "sprite.h" // for Sprite
#include "text.h" // for Text, TEXT_STROKE
#include "texture.h" // for Texture
#include "utils.h" // for Color, stringToColor, Palette
// Constructor // Constructor
Ending::Ending() Ending::Ending()
: screen(Screen::get()), : screen_(Screen::get()),
renderer(Screen::get()->getRenderer()), renderer_(Screen::get()->getRenderer()),
resource(Resource::get()), resource_(Resource::get()),
asset(Asset::get()), asset_(Asset::get()),
input(Input::get()) input_(Input::get())
{ {
// Reserva memoria para los punteros a objetos // Reserva memoria para los punteros a objetos
text = new Text(resource->getOffset("smb2.txt"), resource->getTexture("smb2.png"), renderer); text_ = resource_->getText("smb2");
music = JA_LoadMusic(asset->get("ending1.ogg").c_str()); music = resource_->getMusic("ending1.ogg");
// Inicializa variables // Inicializa variables
counter = -1; counter_ = -1;
preCounter = 0; pre_counter_ = 0;
coverCounter = 0; cover_counter_ = 0;
options.section.name = SECTION_ENDING; options.section.section = Section::ENDING;
options.section.subsection = 0; options.section.subsection = Subsection::NONE;
ticks = 0; ticks_ = 0;
ticksSpeed = 15; current_scene_ = 0;
scene = 0;
// Inicializa los textos // Inicializa los textos
iniTexts(); iniTexts();
@@ -50,18 +52,18 @@ Ending::Ending()
iniScenes(); iniScenes();
// Cambia el color del borde // Cambia el color del borde
screen->setBorderColor(stringToColor(options.palette, "black")); screen_->setBorderColor(stringToColor(options.video.palette, "black"));
// Crea la textura para cubrir el rexto // Crea la textura para cubrir el rexto
coverTexture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT + 8); cover_texture_ = SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT + 8);
if (coverTexture == nullptr) if (cover_texture_ == nullptr)
{ {
if (options.console) if (options.console)
{ {
std::cout << "Error: canvasTexture could not be created!\nSDL Error: " << SDL_GetError() << std::endl; std::cout << "Error: canvasTexture could not be created!\nSDL Error: " << SDL_GetError() << std::endl;
} }
} }
SDL_SetTextureBlendMode(coverTexture, SDL_BLENDMODE_BLEND); SDL_SetTextureBlendMode(cover_texture_, SDL_BLENDMODE_BLEND);
// Rellena la textura para la cortinilla // Rellena la textura para la cortinilla
fillCoverTexture(); fillCoverTexture();
@@ -71,37 +73,17 @@ Ending::Ending()
Ending::~Ending() Ending::~Ending()
{ {
// Libera la memoria de los objetos // Libera la memoria de los objetos
delete text; SDL_DestroyTexture(cover_texture_);
SDL_DestroyTexture(coverTexture);
for (auto st : spriteTexts)
{
delete st.sprite;
delete st.texture;
delete st.coverSprite;
delete st.coverTexture;
}
spriteTexts.clear();
for (auto sp : spritePics)
{
delete sp.sprite;
delete sp.coverSprite;
delete sp.coverTexture;
}
spritePics.clear();
JA_DeleteMusic(music);
} }
// Actualiza el objeto // Actualiza el objeto
void Ending::update() void Ending::update()
{ {
// Comprueba que la diferencia de ticks sea mayor a la velocidad del juego // Comprueba que la diferencia de ticks sea mayor a la velocidad del juego
if (SDL_GetTicks() - ticks > ticksSpeed) if (SDL_GetTicks() - ticks_ > GAME_SPEED)
{ {
// Actualiza el contador de ticks // Actualiza el contador de ticks
ticks = SDL_GetTicks(); ticks_ = SDL_GetTicks();
// Comprueba las entradas // Comprueba las entradas
checkInput(); checkInput();
@@ -118,7 +100,7 @@ void Ending::update()
// Actualiza el volumen de la musica // Actualiza el volumen de la musica
updateMusicVolume(); updateMusicVolume();
screen->update(); screen_->update();
} }
} }
@@ -126,32 +108,30 @@ void Ending::update()
void Ending::render() void Ending::render()
{ {
// Prepara para empezar a dibujar en la textura de juego // Prepara para empezar a dibujar en la textura de juego
screen->start(); screen_->start();
// Limpia la pantalla // Limpia la pantalla
screen->clean(stringToColor(options.palette, "black")); screen_->clean(stringToColor(options.video.palette, "black"));
// Dibuja las imagenes de la escena // Dibuja las imagenes de la escena
spritePics[scene].sprite->render(); sprite_pics_[current_scene_].sprite->render();
spritePics[scene].coverSprite->render(); sprite_pics_[current_scene_].cover_sprite->render();
// Dibuja los textos de la escena // Dibuja los textos de la escena
for (auto ti : scenes[scene].textIndex) for (auto ti : scenes_[current_scene_].text_index)
{ {
if (counter > ti.trigger) if (counter_ > ti.trigger)
{ {
spriteTexts[ti.index].sprite->render(); sprite_texts_[ti.index].sprite->render();
spriteTexts[ti.index].coverSprite->render(); sprite_texts_[ti.index].cover_sprite->render();
} }
} }
// Dibuja la cortinilla de cambio de escena // Dibuja la cortinilla de cambio de escena
renderCoverTexture(); renderCoverTexture();
// text->write(0, 0, std::to_string(counter));
// Vuelca el contenido del renderizador en pantalla // Vuelca el contenido del renderizador en pantalla
screen->render(); screen_->render();
} }
// Comprueba el manejador de eventos // Comprueba el manejador de eventos
@@ -160,56 +140,21 @@ void Ending::checkEvents()
SDL_Event event; SDL_Event event;
while (SDL_PollEvent(&event)) while (SDL_PollEvent(&event))
{ {
// Evento de salida de la aplicación globalEvents::check(event);
if (event.type == SDL_QUIT)
{
options.section.name = SECTION_QUIT;
break;
}
} }
} }
// Comprueba las entradas // Comprueba las entradas
void Ending::checkInput() void Ending::checkInput()
{ {
globalInputs::check();
if (input->checkInput(input_exit, REPEAT_FALSE))
{
options.section.name = SECTION_LOGO;
options.section.subsection = SUBSECTION_LOGO_TO_INTRO;
}
else if (input->checkInput(input_toggle_border, REPEAT_FALSE))
{
screen->toggleBorder();
}
else if (input->checkInput(input_toggle_videomode, REPEAT_FALSE))
{
screen->toggleVideoMode();
}
else if (input->checkInput(input_window_dec_size, REPEAT_FALSE))
{
screen->decWindowSize();
}
else if (input->checkInput(input_window_inc_size, REPEAT_FALSE))
{
screen->incWindowSize();
}
else if (input->checkInput(input_toggle_palette, REPEAT_FALSE))
{
switchPalette();
}
} }
// Inicializa los textos // Inicializa los textos
void Ending::iniTexts() void Ending::iniTexts()
{ {
// Vector con los textos // Vector con los textos
std::vector<textAndPos_t> texts; std::vector<TextAndPosition> texts;
// Escena #0 // Escena #0
texts.push_back({"HE FINALLY MANAGED", 32}); texts.push_back({"HE FINALLY MANAGED", 32});
@@ -241,73 +186,66 @@ void Ending::iniTexts()
texts.push_back({"WERE BORN...", 158}); texts.push_back({"WERE BORN...", 158});
// Crea los sprites // Crea los sprites
for (auto st : spriteTexts) sprite_texts_.clear();
{
delete st.sprite;
delete st.texture;
delete st.coverSprite;
delete st.coverTexture;
}
spriteTexts.clear();
for (auto t : texts) for (auto t : texts)
{ {
endingTexture_t st; EndingTexture st;
const int width = text->lenght(t.caption, 1) + 2 + 2; const int width = text_->lenght(t.caption, 1) + 2 + 2;
const int height = text->getCharacterSize() + 2 + 2; const int height = text_->getCharacterSize() + 2 + 2;
color_t c = stringToColor(options.palette, "black"); Color c = stringToColor(options.video.palette, "black");
// Crea la texture // Crea la texture
st.texture = new Texture(renderer); st.texture = std::make_shared<Texture>(renderer_);
st.texture->createBlank(renderer, width, height, SDL_TEXTUREACCESS_TARGET); st.texture->createBlank(width, height);
st.texture->setAsRenderTarget(renderer); st.texture->setAsRenderTarget(renderer_);
st.texture->setBlendMode(SDL_BLENDMODE_BLEND); st.texture->setBlendMode(SDL_BLENDMODE_BLEND);
text->writeDX(TXT_STROKE, 2, 2, t.caption, 1, c, 2, c); text_->writeDX(TEXT_STROKE, 2, 2, t.caption, 1, c, 2, c);
// Crea el sprite // Crea el sprite
st.sprite = new Sprite({0, 0, st.texture->getWidth(), st.texture->getHeight()}, st.texture, renderer); st.sprite = std::make_shared<Sprite>(st.texture, 0, 0, st.texture->getWidth(), st.texture->getHeight());
st.sprite->setPos({(GAMECANVAS_WIDTH - st.texture->getWidth()) / 2, t.pos}); st.sprite->setPosition((GAMECANVAS_WIDTH - st.texture->getWidth()) / 2, t.pos);
// Crea la coverTexture // Crea la coverTexture
st.coverTexture = new Texture(renderer); st.cover_texture = std::make_shared<Texture>(renderer_);
st.coverTexture->createBlank(renderer, width, height + 8, SDL_TEXTUREACCESS_TARGET); st.cover_texture->createBlank(width, height + 8);
st.coverTexture->setAsRenderTarget(renderer); st.cover_texture->setAsRenderTarget(renderer_);
st.coverTexture->setBlendMode(SDL_BLENDMODE_BLEND); st.cover_texture->setBlendMode(SDL_BLENDMODE_BLEND);
// Rellena la coverTexture con color transparente // Rellena la coverTexture con color transparente
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0); SDL_SetRenderDrawColor(renderer_, 0, 0, 0, 0);
SDL_RenderClear(renderer); SDL_RenderClear(renderer_);
// Los primeros 8 pixels crea una malla // Los primeros 8 pixels crea una malla
c = stringToColor(options.palette, "black"); c = stringToColor(options.video.palette, "black");
SDL_SetRenderDrawColor(renderer, c.r, c.g, c.b, 0xFF); SDL_SetRenderDrawColor(renderer_, c.r, c.g, c.b, 0xFF);
for (int i = 0; i < width; i += 2) for (int i = 0; i < width; i += 2)
{ {
SDL_RenderDrawPoint(renderer, i, 0); SDL_RenderDrawPoint(renderer_, i, 0);
SDL_RenderDrawPoint(renderer, i, 2); SDL_RenderDrawPoint(renderer_, i, 2);
SDL_RenderDrawPoint(renderer, i, 4); SDL_RenderDrawPoint(renderer_, i, 4);
SDL_RenderDrawPoint(renderer, i, 6); SDL_RenderDrawPoint(renderer_, i, 6);
SDL_RenderDrawPoint(renderer, i + 1, 5); SDL_RenderDrawPoint(renderer_, i + 1, 5);
SDL_RenderDrawPoint(renderer, i + 1, 7); SDL_RenderDrawPoint(renderer_, i + 1, 7);
} }
// El resto se rellena de color sólido // El resto se rellena de color sólido
SDL_Rect rect = {0, 8, width, height}; SDL_Rect rect = {0, 8, width, height};
c = stringToColor(options.palette, "black"); c = stringToColor(options.video.palette, "black");
SDL_SetRenderDrawColor(renderer, c.r, c.g, c.b, 0xFF); SDL_SetRenderDrawColor(renderer_, c.r, c.g, c.b, 0xFF);
SDL_RenderFillRect(renderer, &rect); SDL_RenderFillRect(renderer_, &rect);
// Crea el sprite // Crea el sprite
st.coverSprite = new Sprite({0, 0, st.coverTexture->getWidth(), st.coverTexture->getHeight() - 8}, st.coverTexture, renderer); st.cover_sprite = std::make_shared<Sprite>(st.cover_texture, 0, 0, st.cover_texture->getWidth(), st.cover_texture->getHeight() - 8);
st.coverSprite->setPos({(GAMECANVAS_WIDTH - st.coverTexture->getWidth()) / 2, t.pos}); st.cover_sprite->setPosition((GAMECANVAS_WIDTH - st.cover_texture->getWidth()) / 2, t.pos);
st.coverSprite->setSpriteClip(0, 8, -1, -1); st.cover_sprite->setClip(0, 8, -1, -1);
// Inicializa variables // Inicializa variables
st.clipDesp = 8; st.clip_desp = 8;
st.clipHeight = height; st.clip_height = height;
spriteTexts.push_back(st); sprite_texts_.push_back(st);
} }
} }
@@ -315,9 +253,9 @@ void Ending::iniTexts()
void Ending::iniPics() void Ending::iniPics()
{ {
// Vector con las rutas y la posición // Vector con las rutas y la posición
std::vector<textAndPos_t> pics; std::vector<TextAndPosition> pics;
if (options.palette == p_zxspectrum) if (options.video.palette == Palette::ZXSPECTRUM)
{ {
pics.push_back({"ending1.png", 48}); pics.push_back({"ending1.png", 48});
pics.push_back({"ending2.png", 26}); pics.push_back({"ending2.png", 26});
@@ -335,67 +273,61 @@ void Ending::iniPics()
} }
// Crea los sprites // Crea los sprites
for (auto sp : spritePics) sprite_pics_.clear();
{
delete sp.sprite;
delete sp.coverSprite;
delete sp.coverTexture;
}
spritePics.clear();
for (auto p : pics) for (auto p : pics)
{ {
endingTexture_t sp; EndingTexture sp;
// Crea la texture // Crea la texture
sp.texture = resource->getTexture(p.caption); sp.texture = resource_->getTexture(p.caption);
const int width = sp.texture->getWidth(); const int width = sp.texture->getWidth();
const int height = sp.texture->getHeight(); const int height = sp.texture->getHeight();
// Crea el sprite // Crea el sprite
sp.sprite = new Sprite({0, 0, width, height}, sp.texture, renderer); sp.sprite = std::make_shared<Sprite>(sp.texture, 0, 0, width, height);
sp.sprite->setPos({(GAMECANVAS_WIDTH - width) / 2, p.pos}); sp.sprite->setPosition((GAMECANVAS_WIDTH - width) / 2, p.pos);
// Crea la coverTexture // Crea la coverTexture
sp.coverTexture = new Texture(renderer); sp.cover_texture = std::make_shared<Texture>(renderer_);
sp.coverTexture->createBlank(renderer, width, height + 8, SDL_TEXTUREACCESS_TARGET); sp.cover_texture->createBlank(width, height + 8);
sp.coverTexture->setAsRenderTarget(renderer); sp.cover_texture->setAsRenderTarget(renderer_);
sp.coverTexture->setBlendMode(SDL_BLENDMODE_BLEND); sp.cover_texture->setBlendMode(SDL_BLENDMODE_BLEND);
// Rellena la coverTexture con color transparente // Rellena la coverTexture con color transparente
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0); SDL_SetRenderDrawColor(renderer_, 0, 0, 0, 0);
SDL_RenderClear(renderer); SDL_RenderClear(renderer_);
// Los primeros 8 pixels crea una malla // Los primeros 8 pixels crea una malla
color_t c = stringToColor(options.palette, "black"); Color c = stringToColor(options.video.palette, "black");
SDL_SetRenderDrawColor(renderer, c.r, c.g, c.b, 0xFF); SDL_SetRenderDrawColor(renderer_, c.r, c.g, c.b, 0xFF);
for (int i = 0; i < width; i += 2) for (int i = 0; i < width; i += 2)
{ {
SDL_RenderDrawPoint(renderer, i, 0); SDL_RenderDrawPoint(renderer_, i, 0);
SDL_RenderDrawPoint(renderer, i, 2); SDL_RenderDrawPoint(renderer_, i, 2);
SDL_RenderDrawPoint(renderer, i, 4); SDL_RenderDrawPoint(renderer_, i, 4);
SDL_RenderDrawPoint(renderer, i, 6); SDL_RenderDrawPoint(renderer_, i, 6);
SDL_RenderDrawPoint(renderer, i + 1, 5); SDL_RenderDrawPoint(renderer_, i + 1, 5);
SDL_RenderDrawPoint(renderer, i + 1, 7); SDL_RenderDrawPoint(renderer_, i + 1, 7);
} }
// El resto se rellena de color sólido // El resto se rellena de color sólido
SDL_Rect rect = {0, 8, width, height}; SDL_Rect rect = {0, 8, width, height};
c = stringToColor(options.palette, "black"); c = stringToColor(options.video.palette, "black");
SDL_SetRenderDrawColor(renderer, c.r, c.g, c.b, 0xFF); SDL_SetRenderDrawColor(renderer_, c.r, c.g, c.b, 0xFF);
SDL_RenderFillRect(renderer, &rect); SDL_RenderFillRect(renderer_, &rect);
// Crea el sprite // Crea el sprite
sp.coverSprite = new Sprite({0, 0, sp.coverTexture->getWidth(), sp.coverTexture->getHeight() - 8}, sp.coverTexture, renderer); sp.cover_sprite = std::make_shared<Sprite>(sp.cover_texture, 0, 0, sp.cover_texture->getWidth(), sp.cover_texture->getHeight() - 8);
sp.coverSprite->setPos({(GAMECANVAS_WIDTH - sp.coverTexture->getWidth()) / 2, p.pos}); sp.cover_sprite->setPosition((GAMECANVAS_WIDTH - sp.cover_texture->getWidth()) / 2, p.pos);
sp.coverSprite->setSpriteClip(0, 8, -1, -1); sp.cover_sprite->setClip(0, 8, -1, -1);
// Inicializa variables // Inicializa variables
sp.clipDesp = 8; sp.clip_desp = 8;
sp.clipHeight = height; sp.clip_height = height;
spritePics.push_back(sp); sprite_pics_.push_back(sp);
} }
} }
@@ -407,79 +339,79 @@ void Ending::iniScenes()
const int lapse = 80; const int lapse = 80;
// Crea el contenedor // Crea el contenedor
scene_t sc; SceneData sc;
// Inicializa el vector // Inicializa el vector
scenes.clear(); scenes_.clear();
// Crea la escena #0 // Crea la escena #0
sc.counterEnd = 1000; sc.counter_end = 1000;
sc.pictureIndex = 0; sc.picture_index = 0;
sc.textIndex.clear(); sc.text_index.clear();
trigger = 85 * 2; trigger = 85 * 2;
trigger += lapse; trigger += lapse;
sc.textIndex.push_back({0, trigger}); sc.text_index.push_back({0, trigger});
trigger += lapse; trigger += lapse;
sc.textIndex.push_back({1, trigger}); sc.text_index.push_back({1, trigger});
trigger += lapse * 3; trigger += lapse * 3;
sc.textIndex.push_back({2, trigger}); sc.text_index.push_back({2, trigger});
trigger += lapse; trigger += lapse;
sc.textIndex.push_back({3, trigger}); sc.text_index.push_back({3, trigger});
scenes.push_back(sc); scenes_.push_back(sc);
// Crea la escena #1 // Crea la escena #1
sc.counterEnd = 1400; sc.counter_end = 1400;
sc.pictureIndex = 1; sc.picture_index = 1;
sc.textIndex.clear(); sc.text_index.clear();
trigger = 140 * 2; trigger = 140 * 2;
trigger += lapse; trigger += lapse;
sc.textIndex.push_back({4, trigger}); sc.text_index.push_back({4, trigger});
trigger += lapse; trigger += lapse;
sc.textIndex.push_back({5, trigger}); sc.text_index.push_back({5, trigger});
trigger += lapse; trigger += lapse;
sc.textIndex.push_back({6, trigger}); sc.text_index.push_back({6, trigger});
trigger += lapse * 3; trigger += lapse * 3;
sc.textIndex.push_back({7, trigger}); sc.text_index.push_back({7, trigger});
trigger += lapse; trigger += lapse;
sc.textIndex.push_back({8, trigger}); sc.text_index.push_back({8, trigger});
trigger += lapse * 3; trigger += lapse * 3;
sc.textIndex.push_back({9, trigger}); sc.text_index.push_back({9, trigger});
scenes.push_back(sc); scenes_.push_back(sc);
// Crea la escena #2 // Crea la escena #2
sc.counterEnd = 1000; sc.counter_end = 1000;
sc.pictureIndex = 2; sc.picture_index = 2;
sc.textIndex.clear(); sc.text_index.clear();
trigger = 148 / 2; trigger = 148 / 2;
trigger += lapse; trigger += lapse;
sc.textIndex.push_back({10, trigger}); sc.text_index.push_back({10, trigger});
trigger += lapse; trigger += lapse;
sc.textIndex.push_back({11, trigger}); sc.text_index.push_back({11, trigger});
scenes.push_back(sc); scenes_.push_back(sc);
// Crea la escena #3 // Crea la escena #3
sc.counterEnd = 800; sc.counter_end = 800;
sc.pictureIndex = 3; sc.picture_index = 3;
sc.textIndex.clear(); sc.text_index.clear();
trigger = 87 / 2; trigger = 87 / 2;
trigger += lapse; trigger += lapse;
sc.textIndex.push_back({12, trigger}); sc.text_index.push_back({12, trigger});
trigger += lapse / 2; trigger += lapse / 2;
sc.textIndex.push_back({13, trigger}); sc.text_index.push_back({13, trigger});
scenes.push_back(sc); scenes_.push_back(sc);
// Crea la escena #4 // Crea la escena #4
sc.counterEnd = 1000; sc.counter_end = 1000;
sc.pictureIndex = 4; sc.picture_index = 4;
sc.textIndex.clear(); sc.text_index.clear();
trigger = 91 * 2; trigger = 91 * 2;
trigger += lapse; trigger += lapse;
sc.textIndex.push_back({14, trigger}); sc.text_index.push_back({14, trigger});
trigger += lapse * 2; trigger += lapse * 2;
sc.textIndex.push_back({15, trigger}); sc.text_index.push_back({15, trigger});
trigger += lapse * 3; trigger += lapse * 3;
sc.textIndex.push_back({16, trigger}); sc.text_index.push_back({16, trigger});
scenes.push_back(sc); scenes_.push_back(sc);
} }
// Bucle principal // Bucle principal
@@ -487,7 +419,7 @@ void Ending::run()
{ {
JA_PlayMusic(music); JA_PlayMusic(music);
while (options.section.name == SECTION_ENDING) while (options.section.section == Section::ENDING)
{ {
update(); update();
checkEvents(); checkEvents();
@@ -502,80 +434,80 @@ void Ending::run()
void Ending::updateCounters() void Ending::updateCounters()
{ {
// Incrementa el contador // Incrementa el contador
if (preCounter < 200) if (pre_counter_ < 200)
{ {
preCounter++; pre_counter_++;
} }
else else
{ {
counter++; counter_++;
} }
if (counter > scenes[scene].counterEnd - 100) if (counter_ > scenes_[current_scene_].counter_end - 100)
{ {
coverCounter++; cover_counter_++;
} }
} }
// Actualiza las cortinillas de los elementos // Actualiza las cortinillas de los elementos
void Ending::updateSpriteCovers() void Ending::updateSpriteCovers()
{ // Actualiza la cortinilla de los textos { // Actualiza la cortinilla de los textos
if (counter % 4 == 0) if (counter_ % 4 == 0)
{ {
for (auto ti : scenes[scene].textIndex) for (auto ti : scenes_[current_scene_].text_index)
{ {
if (counter > ti.trigger) if (counter_ > ti.trigger)
{ {
if (spriteTexts[ti.index].clipDesp > 0) if (sprite_texts_[ti.index].clip_desp > 0)
{ {
spriteTexts[ti.index].clipDesp -= 2; sprite_texts_[ti.index].clip_desp -= 2;
} }
else if (spriteTexts[ti.index].clipHeight > 0) else if (sprite_texts_[ti.index].clip_height > 0)
{ {
spriteTexts[ti.index].clipHeight -= 2; sprite_texts_[ti.index].clip_height -= 2;
spriteTexts[ti.index].coverSprite->setPosY(spriteTexts[ti.index].coverSprite->getPosY() + 2); sprite_texts_[ti.index].cover_sprite->setY(sprite_texts_[ti.index].cover_sprite->getY() + 2);
} }
spriteTexts[ti.index].coverSprite->setSpriteClip(0, spriteTexts[ti.index].clipDesp, spriteTexts[ti.index].coverSprite->getWidth(), spriteTexts[ti.index].clipHeight); sprite_texts_[ti.index].cover_sprite->setClip(0, sprite_texts_[ti.index].clip_desp, sprite_texts_[ti.index].cover_sprite->getWidth(), sprite_texts_[ti.index].clip_height);
} }
} }
} }
// Actualiza la cortinilla de las imagenes // Actualiza la cortinilla de las imagenes
if (counter % 2 == 0) if (counter_ % 2 == 0)
{ {
if (spritePics[scene].clipDesp > 0) if (sprite_pics_[current_scene_].clip_desp > 0)
{ {
spritePics[scene].clipDesp -= 2; sprite_pics_[current_scene_].clip_desp -= 2;
} }
else if (spritePics[scene].clipHeight > 0) else if (sprite_pics_[current_scene_].clip_height > 0)
{ {
spritePics[scene].clipHeight -= 2; sprite_pics_[current_scene_].clip_height -= 2;
if (spritePics[scene].clipHeight < 0) if (sprite_pics_[current_scene_].clip_height < 0)
{ {
spritePics[scene].clipHeight = 0; sprite_pics_[current_scene_].clip_height = 0;
} }
spritePics[scene].coverSprite->setPosY(spritePics[scene].coverSprite->getPosY() + 2); sprite_pics_[current_scene_].cover_sprite->setY(sprite_pics_[current_scene_].cover_sprite->getY() + 2);
} }
spritePics[scene].coverSprite->setSpriteClip(0, spritePics[scene].clipDesp, spritePics[scene].coverSprite->getWidth(), spritePics[scene].clipHeight); sprite_pics_[current_scene_].cover_sprite->setClip(0, sprite_pics_[current_scene_].clip_desp, sprite_pics_[current_scene_].cover_sprite->getWidth(), sprite_pics_[current_scene_].clip_height);
} }
} }
// Comprueba si se ha de cambiar de escena // Comprueba si se ha de cambiar de escena
void Ending::checkChangeScene() void Ending::checkChangeScene()
{ {
if (counter > scenes[scene].counterEnd) if (counter_ > scenes_[current_scene_].counter_end)
{ {
scene++; current_scene_++;
counter = 0; counter_ = 0;
coverCounter = 0; cover_counter_ = 0;
if (scene == 5) if (current_scene_ == 5)
{ {
// Termina el bucle // Termina el bucle
options.section.name = SECTION_ENDING2; options.section.section = Section::ENDING2;
// Mantiene los valores anteriores // Mantiene los valores anteriores
scene = 4; current_scene_ = 4;
coverCounter = 100; cover_counter_ = 100;
} }
} }
} }
@@ -584,75 +516,50 @@ void Ending::checkChangeScene()
void Ending::fillCoverTexture() void Ending::fillCoverTexture()
{ {
// Rellena la textura que cubre el texto con color transparente // Rellena la textura que cubre el texto con color transparente
SDL_SetRenderTarget(renderer, coverTexture); SDL_SetRenderTarget(renderer_, cover_texture_);
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0); SDL_SetRenderDrawColor(renderer_, 0, 0, 0, 0);
SDL_RenderClear(renderer); SDL_RenderClear(renderer_);
// Los primeros 8 pixels crea una malla // Los primeros 8 pixels crea una malla
const color_t c = stringToColor(options.palette, "brack"); const Color color = stringToColor(options.video.palette, "black");
SDL_SetRenderDrawColor(renderer, c.r, c.g, c.b, 0xFF); SDL_SetRenderDrawColor(renderer_, color.r, color.g, color.b, 0xFF);
for (int i = 0; i < 256; i += 2) for (int i = 0; i < 256; i += 2)
{ {
SDL_RenderDrawPoint(renderer, i + 0, GAMECANVAS_HEIGHT + 0); SDL_RenderDrawPoint(renderer_, i + 0, GAMECANVAS_HEIGHT + 0);
SDL_RenderDrawPoint(renderer, i + 1, GAMECANVAS_HEIGHT + 1); SDL_RenderDrawPoint(renderer_, i + 1, GAMECANVAS_HEIGHT + 1);
SDL_RenderDrawPoint(renderer, i + 0, GAMECANVAS_HEIGHT + 2); SDL_RenderDrawPoint(renderer_, i + 0, GAMECANVAS_HEIGHT + 2);
SDL_RenderDrawPoint(renderer, i + 1, GAMECANVAS_HEIGHT + 3); SDL_RenderDrawPoint(renderer_, i + 1, GAMECANVAS_HEIGHT + 3);
SDL_RenderDrawPoint(renderer, i, GAMECANVAS_HEIGHT + 4); SDL_RenderDrawPoint(renderer_, i, GAMECANVAS_HEIGHT + 4);
SDL_RenderDrawPoint(renderer, i, GAMECANVAS_HEIGHT + 6); SDL_RenderDrawPoint(renderer_, i, GAMECANVAS_HEIGHT + 6);
} }
// El resto se rellena de color sólido // El resto se rellena de color sólido
SDL_Rect rect = {0, 0, 256, GAMECANVAS_HEIGHT}; SDL_Rect rect = {0, 0, 256, GAMECANVAS_HEIGHT};
SDL_RenderFillRect(renderer, &rect); SDL_RenderFillRect(renderer_, &rect);
SDL_SetRenderTarget(renderer, nullptr); SDL_SetRenderTarget(renderer_, nullptr);
} }
// Dibuja la cortinilla de cambio de escena // Dibuja la cortinilla de cambio de escena
void Ending::renderCoverTexture() void Ending::renderCoverTexture()
{ {
if (coverCounter > 0) if (cover_counter_ > 0)
{ // Dibuja la textura que cubre el texto { // Dibuja la textura que cubre el texto
const int offset = std::min(coverCounter, 100); const int offset = std::min(cover_counter_, 100);
SDL_Rect srcRect = {0, 200 - (coverCounter * 2), 256, offset * 2}; SDL_Rect srcRect = {0, 200 - (cover_counter_ * 2), 256, offset * 2};
SDL_Rect dstRect = {0, 0, 256, offset * 2}; SDL_Rect dstRect = {0, 0, 256, offset * 2};
SDL_RenderCopy(renderer, coverTexture, &srcRect, &dstRect); SDL_RenderCopy(renderer_, cover_texture_, &srcRect, &dstRect);
} }
} }
// Actualiza el volumen de la musica // Actualiza el volumen de la musica
void Ending::updateMusicVolume() void Ending::updateMusicVolume()
{ {
if (scene == 4 && coverCounter > 0) if (current_scene_ == 4 && cover_counter_ > 0)
{ {
const float step = (100.0f - coverCounter) / 100.0f; const float step = (100.0f - cover_counter_) / 100.0f;
const int volume = 128 * step; const int volume = 128 * step;
JA_SetVolume(volume); JA_SetVolume(volume);
} }
} }
// Cambia la paleta
void Ending::switchPalette()
{
if (options.palette == p_zxspectrum)
{
options.palette = p_zxarne;
spritePics[0].sprite->setTexture(resource->getTexture("ending1_zxarne.png"));
spritePics[1].sprite->setTexture(resource->getTexture("ending2_zxarne.png"));
spritePics[2].sprite->setTexture(resource->getTexture("ending3_zxarne.png"));
spritePics[3].sprite->setTexture(resource->getTexture("ending4_zxarne.png"));
spritePics[4].sprite->setTexture(resource->getTexture("ending5_zxarne.png"));
}
else
{
options.palette = p_zxspectrum;
spritePics[0].sprite->setTexture(resource->getTexture("ending1.png"));
spritePics[1].sprite->setTexture(resource->getTexture("ending2.png"));
spritePics[2].sprite->setTexture(resource->getTexture("ending3.png"));
spritePics[3].sprite->setTexture(resource->getTexture("ending4.png"));
spritePics[4].sprite->setTexture(resource->getTexture("ending5.png"));
}
}

View File

@@ -1,36 +1,34 @@
#pragma once #pragma once
#include <SDL2/SDL_events.h> // Para SDL_Event #include <SDL2/SDL_render.h> // for SDL_Renderer, SDL_Texture
#include <SDL2/SDL_render.h> // Para SDL_Renderer, SDL_Texture #include <SDL2/SDL_stdinc.h> // for Uint32
#include <SDL2/SDL_stdinc.h> // Para Uint32 #include <memory> // for shared_ptr
#include <string> // Para basic_string, string #include <string> // for string
#include <vector> // Para vector #include <vector> // for vector
class Asset; class Asset; // lines 9-9
class Input; class Input; // lines 10-10
class Resource; class Resource; // lines 11-11
class Screen; class Screen; // lines 12-12
class Sprite; class Sprite; // lines 13-13
class Text; class Text; // lines 14-14
class Texture; class Texture; // lines 15-15
struct JA_Music_t; struct JA_Music_t; // lines 16-16
struct options_t;
struct section_t;
class Ending class Ending
{ {
private: private:
// Estructuras // Estructuras
struct endingTexture_t // Estructura con dos texturas y sprites, uno para mostrar y el otro hace de cortinilla struct EndingTexture // Estructura con dos texturas y sprites, uno para mostrar y el otro hace de cortinilla
{ {
Texture *texture; // Textura a mostrar std::shared_ptr<Texture> texture; // Textura a mostrar
Sprite *sprite; // Sprite para mostrar la textura std::shared_ptr<Sprite> sprite; // Sprite para mostrar la textura
Texture *coverTexture; // Textura que cubre a la otra textura std::shared_ptr<Texture> cover_texture; // Textura que cubre a la otra textura
Sprite *coverSprite; // Sprite para mostrar la textura que cubre a la otra textura std::shared_ptr<Sprite> cover_sprite; // Sprite para mostrar la textura que cubre a la otra textura
int clipDesp; // Desplazamiento del spriteClip de la textura de cobertura int clip_desp; // Desplazamiento del spriteClip de la textura de cobertura
int clipHeight; // Altura del spriteClip de la textura de cobertura int clip_height; // Altura del spriteClip de la textura de cobertura
}; };
struct textAndPos_t // Estructura con un texto y su posición en el eje Y struct TextAndPosition // Estructura con un texto y su posición en el eje Y
{ {
std::string caption; // Texto std::string caption; // Texto
int pos; // Posición int pos; // Posición
@@ -42,32 +40,31 @@ private:
int trigger; int trigger;
}; };
struct scene_t // Estructura para crear cada una de las escenas del final struct SceneData // Estructura para crear cada una de las escenas del final
{ {
std::vector<asdhk> textIndex; // Indices del vector de textos a mostrar y su disparador std::vector<asdhk> text_index; // Indices del vector de textos a mostrar y su disparador
int pictureIndex; // Indice del vector de imagenes a mostrar int picture_index; // Indice del vector de imagenes a mostrar
int counterEnd; // Valor del contador en el que finaliza la escena int counter_end; // Valor del contador en el que finaliza la escena
}; };
// Objetos y punteros // Objetos y punteros
Screen *screen; // Objeto encargado de dibujar en pantalla Screen *screen_; // Objeto encargado de dibujar en pantalla
SDL_Renderer *renderer; // El renderizador de la ventana SDL_Renderer *renderer_; // El renderizador de la ventana
Resource *resource; // Objeto con los recursos Resource *resource_; // Objeto con los recursos
Asset *asset; // Objeto con los ficheros de recursos Asset *asset_; // Objeto con los ficheros de recursos
Input *input; // Objeto pata gestionar la entrada Input *input_; // Objeto pata gestionar la entrada
Text *text; // Objeto para escribir texto en pantalla std::shared_ptr<Text> text_; // Objeto para escribir texto en pantalla
SDL_Texture *coverTexture; // Textura para cubrir el texto SDL_Texture *cover_texture_; // Textura para cubrir el texto
// Variables // Variables
int counter; // Contador int counter_; // Contador
int preCounter; // Contador previo int pre_counter_; // Contador previo
int coverCounter; // Contador para la cortinilla int cover_counter_; // Contador para la cortinilla
Uint32 ticks; // Contador de ticks para ajustar la velocidad del programa Uint32 ticks_; // Contador de ticks para ajustar la velocidad del programa
Uint32 ticksSpeed; // Velocidad a la que se repiten los bucles del programa std::vector<EndingTexture> sprite_texts_; // Vector con los sprites de texto con su cortinilla
std::vector<endingTexture_t> spriteTexts; // Vector con los sprites de texto con su cortinilla std::vector<EndingTexture> sprite_pics_; // Vector con los sprites de texto con su cortinilla
std::vector<endingTexture_t> spritePics; // Vector con los sprites de texto con su cortinilla int current_scene_; // Escena actual
int scene; // Escena actual std::vector<SceneData> scenes_; // Vector con los textos e imagenes de cada escena
std::vector<scene_t> scenes; // Vector con los textos e imagenes de cada escena
JA_Music_t *music; // Musica que suena durante el final JA_Music_t *music; // Musica que suena durante el final
// Actualiza el objeto // Actualiza el objeto
@@ -109,9 +106,6 @@ private:
// Actualiza el volumen de la musica // Actualiza el volumen de la musica
void updateMusicVolume(); void updateMusicVolume();
// Cambia la paleta
void switchPalette();
public: public:
// Constructor // Constructor
Ending(); Ending();

View File

@@ -1,56 +1,57 @@
#include "ending2.h" #include "ending2.h"
#include <SDL2/SDL_blendmode.h> // for SDL_BLENDMODE_BLEND #include <SDL2/SDL_blendmode.h> // for SDL_BLENDMODE_BLEND
#include <SDL2/SDL_events.h> // for SDL_PollEvent, SDL_Event
#include <SDL2/SDL_rect.h> // for SDL_Rect
#include <SDL2/SDL_timer.h> // for SDL_GetTicks #include <SDL2/SDL_timer.h> // for SDL_GetTicks
#include <algorithm> // for max, min, replace #include <algorithm> // for max, min, replace
#include "animatedsprite.h" // for AnimatedSprite #include "animated_sprite.h" // for AnimatedSprite
#include "asset.h" // for Asset #include "asset.h" // for Asset
#include "const.h" // for GAMECANVAS_HEIGHT, GAMECANVAS_CENTER_X #include "defines.h" // for GAMECANVAS_HEIGHT, GAMECANVAS_CENTER_X
#include "input.h" // for Input, REPEAT_FALSE, inputs_e #include "global_events.h" // for check
#include "jail_audio.h" // for JA_SetVolume, JA_DeleteMusic, JA_Loa... #include "global_inputs.h" // for check
#include "movingsprite.h" // for MovingSprite #include "input.h" // for Input
#include "jail_audio.h" // for JA_SetVolume, JA_PlayMusic, JA_StopM...
#include "moving_sprite.h" // for MovingSprite
#include "options.h" // for Options, options, OptionsVideo, Sect...
#include "resource.h" // for Resource #include "resource.h" // for Resource
#include "screen.h" // for Screen #include "screen.h" // for Screen
#include "text.h" // for Text #include "text.h" // for Text
#include "texture.h" // for Texture #include "texture.h" // for Texture
#include "utils.h" // for color_t, stringToColor, options_t #include "utils.h" // for Color, stringToColor
#include "options.h"
// Constructor // Constructor
Ending2::Ending2() Ending2::Ending2()
: screen(Screen::get()), : screen_(Screen::get()),
renderer(Screen::get()->getRenderer()), renderer_(Screen::get()->getRenderer()),
resource(Resource::get()), resource_(Resource::get()),
asset(Asset::get()), asset_(Asset::get()),
input(Input::get()) input_(Input::get())
{ {
// Reserva memoria para los punteros a objetos // Reserva memoria para los punteros a objetos
text = new Text(resource->getOffset("smb2.txt"), resource->getTexture("smb2.png"), renderer); text_ = resource_->getText("smb2");
music = JA_LoadMusic(asset->get("ending2.ogg").c_str()); music_ = resource_->getMusic("ending2.ogg");
// Inicializa variables // Inicializa variables
counterEnabled = false; counter_enabled_ = false;
preCounter = 0; pre_counter_ = 0;
postCounter = 0; post_counter_ = 0;
postCounterEnabled = false; post_counter_enabled_ = false;
options.section.name = SECTION_ENDING2; options.section.section = Section::ENDING2;
options.section.subsection = 0; options.section.subsection = Subsection::NONE;
ticks = 0; ticks_ = 0;
ticksSpeed = 15; dist_sprite_text_ = 8;
distSpriteText = 8; dist_sprite_sprite_ = 0;
distSpriteSprite = 0; sprite_desp_speed_ = -0.2f;
despSpeed = -0.2f;
firstCol = GAMECANVAS_FIRST_QUARTER_X + (GAMECANVAS_WIDTH / 16);
secondCol = GAMECANVAS_THIRD_QUARTER_X - (GAMECANVAS_WIDTH / 16);
// Inicializa el vector de colores // Inicializa el vector de colores
const std::vector<std::string> colorList = {"white", "yellow", "cyan", "green", "magenta", "red", "blue", "black"}; const std::vector<std::string> color_list = {"white", "yellow", "cyan", "green", "magenta", "red", "blue", "black"};
for (auto cl : colorList) for (auto color : color_list)
{ {
colors.push_back(stringToColor(options.palette, cl)); colors_.push_back(stringToColor(options.video.palette, color));
} }
// Cambia el color del borde // Cambia el color del borde
screen->setBorderColor(stringToColor(options.palette, "black")); screen_->setBorderColor(stringToColor(options.video.palette, "black"));
// Inicializa la lista de sprites // Inicializa la lista de sprites
iniSpriteList(); iniSpriteList();
@@ -68,26 +69,14 @@ Ending2::Ending2()
createTexts(); createTexts();
} }
// Destructor
Ending2::~Ending2()
{
// Libera la memoria de los objetos
delete text;
JA_DeleteMusic(music);
deleteSprites();
deleteSpriteTexts();
deleteTexts();
}
// Actualiza el objeto // Actualiza el objeto
void Ending2::update() void Ending2::update()
{ {
// Comprueba que la diferencia de ticks sea mayor a la velocidad del juego // Comprueba que la diferencia de ticks sea mayor a la velocidad del juego
if (SDL_GetTicks() - ticks > ticksSpeed) if (SDL_GetTicks() - ticks_ > GAME_SPEED)
{ {
// Actualiza el contador de ticks // Actualiza el contador de ticks
ticks = SDL_GetTicks(); ticks_ = SDL_GetTicks();
// Comprueba las entradas // Comprueba las entradas
checkInput(); checkInput();
@@ -95,7 +84,7 @@ void Ending2::update()
// Actualiza los contadores // Actualiza los contadores
updateCounters(); updateCounters();
if (counterEnabled) if (counter_enabled_)
{ {
// Actualiza los sprites // Actualiza los sprites
updateSprites(); updateSprites();
@@ -113,7 +102,7 @@ void Ending2::update()
// Actualiza el volumen de la musica // Actualiza el volumen de la musica
updateMusicVolume(); updateMusicVolume();
screen->update(); screen_->update();
} }
} }
@@ -121,10 +110,10 @@ void Ending2::update()
void Ending2::render() void Ending2::render()
{ {
// Prepara para empezar a dibujar en la textura de juego // Prepara para empezar a dibujar en la textura de juego
screen->start(); screen_->start();
// Limpia la pantalla // Limpia la pantalla
screen->clean(stringToColor(options.palette, "black")); screen_->clean(stringToColor(options.video.palette, "black"));
// Dibuja los sprites // Dibuja los sprites
renderSprites(); renderSprites();
@@ -135,7 +124,7 @@ void Ending2::render()
// Dibuja los sprites con el texto del final // Dibuja los sprites con el texto del final
renderTexts(); renderTexts();
const std::string txt = std::to_string(postCounter); const std::string txt = std::to_string(post_counter_);
// text->write(0, 192 - 8, txt); // text->write(0, 192 - 8, txt);
// Dibuja la cuadricula // Dibuja la cuadricula
@@ -155,24 +144,24 @@ void Ending2::render()
{ {
// Dibuja una trama arriba y abajo // Dibuja una trama arriba y abajo
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0xFF); SDL_SetRenderDrawColor(renderer_, 0, 0, 0, 0xFF);
for (int i = 0; i < 256; i += 2) for (int i = 0; i < 256; i += 2)
{ {
SDL_RenderDrawPoint(renderer, i + 0, 0); SDL_RenderDrawPoint(renderer_, i + 0, 0);
SDL_RenderDrawPoint(renderer, i + 1, 1); SDL_RenderDrawPoint(renderer_, i + 1, 1);
SDL_RenderDrawPoint(renderer, i + 0, 2); SDL_RenderDrawPoint(renderer_, i + 0, 2);
SDL_RenderDrawPoint(renderer, i + 1, 3); SDL_RenderDrawPoint(renderer_, i + 1, 3);
SDL_RenderDrawPoint(renderer, i, 4); SDL_RenderDrawPoint(renderer_, i, 4);
SDL_RenderDrawPoint(renderer, i, 6); SDL_RenderDrawPoint(renderer_, i, 6);
SDL_RenderDrawPoint(renderer, i + 0, 191); SDL_RenderDrawPoint(renderer_, i + 0, 191);
SDL_RenderDrawPoint(renderer, i + 1, 190); SDL_RenderDrawPoint(renderer_, i + 1, 190);
SDL_RenderDrawPoint(renderer, i + 0, 189); SDL_RenderDrawPoint(renderer_, i + 0, 189);
SDL_RenderDrawPoint(renderer, i + 1, 188); SDL_RenderDrawPoint(renderer_, i + 1, 188);
SDL_RenderDrawPoint(renderer, i, 187); SDL_RenderDrawPoint(renderer_, i, 187);
SDL_RenderDrawPoint(renderer, i, 185); SDL_RenderDrawPoint(renderer_, i, 185);
} }
// SDL_RenderDrawLine(renderer, 0, 1, 255, 1); // SDL_RenderDrawLine(renderer, 0, 1, 255, 1);
// SDL_RenderDrawLine(renderer, 0, 3, 255, 3); // SDL_RenderDrawLine(renderer, 0, 3, 255, 3);
@@ -181,7 +170,7 @@ void Ending2::render()
} }
// Vuelca el contenido del renderizador en pantalla // Vuelca el contenido del renderizador en pantalla
screen->render(); screen_->render();
} }
// Comprueba el manejador de eventos // Comprueba el manejador de eventos
@@ -190,57 +179,22 @@ void Ending2::checkEvents()
SDL_Event event; SDL_Event event;
while (SDL_PollEvent(&event)) while (SDL_PollEvent(&event))
{ {
// Evento de salida de la aplicación globalEvents::check(event);
if (event.type == SDL_QUIT)
{
options.section.name = SECTION_QUIT;
break;
}
} }
} }
// Comprueba las entradas // Comprueba las entradas
void Ending2::checkInput() void Ending2::checkInput()
{ {
globalInputs::check();
if (input->checkInput(input_exit, REPEAT_FALSE))
{
options.section.name = SECTION_LOGO;
options.section.subsection = SUBSECTION_LOGO_TO_INTRO;
}
else if (input->checkInput(input_toggle_border, REPEAT_FALSE))
{
screen->toggleBorder();
}
else if (input->checkInput(input_toggle_videomode, REPEAT_FALSE))
{
screen->toggleVideoMode();
}
else if (input->checkInput(input_window_dec_size, REPEAT_FALSE))
{
screen->decWindowSize();
}
else if (input->checkInput(input_window_inc_size, REPEAT_FALSE))
{
screen->incWindowSize();
}
else if (input->checkInput(input_toggle_palette, REPEAT_FALSE))
{
switchPalette();
}
} }
// Bucle principal // Bucle principal
void Ending2::run() void Ending2::run()
{ {
JA_PlayMusic(music); JA_PlayMusic(music_);
while (options.section.name == SECTION_ENDING2) while (options.section.section == Section::ENDING2)
{ {
update(); update();
checkEvents(); checkEvents();
@@ -255,24 +209,24 @@ void Ending2::run()
void Ending2::updateCounters() void Ending2::updateCounters()
{ {
// Incrementa el contador // Incrementa el contador
if (preCounter < 200) if (pre_counter_ < 200)
{ {
preCounter++; pre_counter_++;
} }
else else
{ {
counterEnabled = true; counter_enabled_ = true;
} }
if (postCounterEnabled) if (post_counter_enabled_)
{ {
postCounter++; post_counter_++;
} }
if (postCounter > 600) if (post_counter_ > 600)
{ {
options.section.name = SECTION_LOGO; options.section.section = Section::LOGO;
options.section.subsection = SUBSECTION_LOGO_TO_INTRO; options.section.subsection = Subsection::LOGO_TO_INTRO;
} }
} }
@@ -280,103 +234,100 @@ void Ending2::updateCounters()
void Ending2::iniSpriteList() void Ending2::iniSpriteList()
{ {
// Reinicia el vector // Reinicia el vector
spriteList.clear(); sprite_list_.clear();
// Añade los valores // Añade los valores
spriteList.push_back("bin"); sprite_list_.push_back("bin");
spriteList.push_back("floppy"); sprite_list_.push_back("floppy");
spriteList.push_back("bird"); sprite_list_.push_back("bird");
spriteList.push_back("chip"); sprite_list_.push_back("chip");
spriteList.push_back("jeannine"); sprite_list_.push_back("jeannine");
spriteList.push_back("spark"); sprite_list_.push_back("spark");
spriteList.push_back("code"); sprite_list_.push_back("code");
spriteList.push_back("paco"); sprite_list_.push_back("paco");
spriteList.push_back("elsa"); sprite_list_.push_back("elsa");
spriteList.push_back("z80"); sprite_list_.push_back("z80");
spriteList.push_back("bell"); sprite_list_.push_back("bell");
spriteList.push_back("dong"); sprite_list_.push_back("dong");
spriteList.push_back("amstrad_cs"); sprite_list_.push_back("amstrad_cs");
spriteList.push_back("breakout"); sprite_list_.push_back("breakout");
spriteList.push_back("flying_arounder"); sprite_list_.push_back("flying_arounder");
spriteList.push_back("stopped_arounder"); sprite_list_.push_back("stopped_arounder");
spriteList.push_back("walking_arounder"); sprite_list_.push_back("walking_arounder");
spriteList.push_back("arounders_door"); sprite_list_.push_back("arounders_door");
spriteList.push_back("arounders_machine"); sprite_list_.push_back("arounders_machine");
spriteList.push_back("abad"); sprite_list_.push_back("abad");
spriteList.push_back("abad_bell"); sprite_list_.push_back("abad_bell");
spriteList.push_back("lord_abad"); sprite_list_.push_back("lord_abad");
spriteList.push_back("bat"); sprite_list_.push_back("bat");
spriteList.push_back("batman_bell"); sprite_list_.push_back("batman_bell");
spriteList.push_back("batman_fire"); sprite_list_.push_back("batman_fire");
spriteList.push_back("batman"); sprite_list_.push_back("batman");
spriteList.push_back("demon"); sprite_list_.push_back("demon");
spriteList.push_back("heavy"); sprite_list_.push_back("heavy");
spriteList.push_back("dimallas"); sprite_list_.push_back("dimallas");
spriteList.push_back("guitar"); sprite_list_.push_back("guitar");
spriteList.push_back("jailbattle_alien"); sprite_list_.push_back("jailbattle_alien");
spriteList.push_back("jailbattle_human"); sprite_list_.push_back("jailbattle_human");
spriteList.push_back("jailer_#1"); sprite_list_.push_back("jailer_#1");
spriteList.push_back("jailer_#2"); sprite_list_.push_back("jailer_#2");
spriteList.push_back("jailer_#3"); sprite_list_.push_back("jailer_#3");
spriteList.push_back("bry"); sprite_list_.push_back("bry");
spriteList.push_back("upv_student"); sprite_list_.push_back("upv_student");
spriteList.push_back("lamp"); sprite_list_.push_back("lamp");
spriteList.push_back("robot"); sprite_list_.push_back("robot");
spriteList.push_back("congo"); sprite_list_.push_back("congo");
spriteList.push_back("crosshair"); sprite_list_.push_back("crosshair");
spriteList.push_back("tree_thing"); sprite_list_.push_back("tree_thing");
spriteList.push_back("matatunos"); sprite_list_.push_back("matatunos");
spriteList.push_back("tuno"); sprite_list_.push_back("tuno");
spriteList.push_back("mummy"); sprite_list_.push_back("mummy");
spriteList.push_back("sam"); sprite_list_.push_back("sam");
spriteList.push_back("qvoid"); sprite_list_.push_back("qvoid");
spriteList.push_back("sigmasua"); sprite_list_.push_back("sigmasua");
spriteList.push_back("tv_panel"); sprite_list_.push_back("tv_panel");
spriteList.push_back("tv"); sprite_list_.push_back("tv");
spriteList.push_back("spider"); sprite_list_.push_back("spider");
spriteList.push_back("shock"); sprite_list_.push_back("shock");
spriteList.push_back("wave"); sprite_list_.push_back("wave");
spriteList.push_back("player"); sprite_list_.push_back("player");
} }
// Carga todos los sprites desde una lista // Carga todos los sprites desde una lista
void Ending2::loadSprites() void Ending2::loadSprites()
{ {
// Borra la memoria ocupada por los sprites
deleteSprites();
// Inicializa variables // Inicializa variables
maxSpriteWidth = 0; sprite_max_width_ = 0;
maxSpriteHeight = 0; sprite_max_height_ = 0;
// Carga los sprites // Carga los sprites
for (auto sl : spriteList) for (auto sl : sprite_list_)
{ {
sprites.push_back(new AnimatedSprite(renderer, resource->getAnimation(sl + ".ani"))); sprites_.emplace_back(std::make_shared<AnimatedSprite>(resource_->getTexture(sl + ".png"), resource_->getAnimations(sl + ".ani")));
maxSpriteWidth = std::max(sprites.back()->getAnimationClip(0, 0).w, maxSpriteWidth); sprite_max_width_ = std::max(sprites_.back()->getWidth(), sprite_max_width_);
maxSpriteHeight = std::max(sprites.back()->getAnimationClip(0, 0).h, maxSpriteHeight); sprite_max_height_ = std::max(sprites_.back()->getHeight(), sprite_max_height_);
} }
} }
// Actualiza los sprites // Actualiza los sprites
void Ending2::updateSprites() void Ending2::updateSprites()
{ {
for (auto sprite : sprites) for (auto sprite : sprites_)
{ {
sprite->update(); sprite->update();
} }
@@ -385,7 +336,7 @@ void Ending2::updateSprites()
// Actualiza los sprites de texto // Actualiza los sprites de texto
void Ending2::updateTextSprites() void Ending2::updateTextSprites()
{ {
for (auto sprite : spriteTexts) for (auto sprite : sprite_texts_)
{ {
sprite->update(); sprite->update();
} }
@@ -394,24 +345,24 @@ void Ending2::updateTextSprites()
// Actualiza los sprites de texto del final // Actualiza los sprites de texto del final
void Ending2::updateTexts() void Ending2::updateTexts()
{ {
if (texts.back()->getPosY() > GAMECANVAS_CENTER_Y) if (texts_.back()->getPosY() > GAMECANVAS_CENTER_Y)
{ {
for (auto sprite : texts) for (auto sprite : texts_)
{ {
sprite->update(); sprite->update();
} }
} }
else else
{ {
postCounterEnabled = true; post_counter_enabled_ = true;
} }
} }
// Dibuja los sprites // Dibuja los sprites
void Ending2::renderSprites() void Ending2::renderSprites()
{ {
const color_t color = stringToColor(options.palette, "red"); const Color color = stringToColor(options.video.palette, "red");
for (auto sprite : sprites) for (auto sprite : sprites_)
{ {
const bool a = sprite->getRect().y + sprite->getRect().h > 0; const bool a = sprite->getRect().y + sprite->getRect().h > 0;
const bool b = sprite->getRect().y < GAMECANVAS_HEIGHT; const bool b = sprite->getRect().y < GAMECANVAS_HEIGHT;
@@ -423,16 +374,16 @@ void Ending2::renderSprites()
} }
// Pinta el ultimo elemento de otro color // Pinta el ultimo elemento de otro color
const color_t c = stringToColor(options.palette, "white"); const Color c = stringToColor(options.video.palette, "white");
sprites.back()->getTexture()->setColor(c.r, c.g, c.b); sprites_.back()->getTexture()->setColor(c.r, c.g, c.b);
sprites.back()->render(); sprites_.back()->render();
} }
// Dibuja los sprites con el texto // Dibuja los sprites con el texto
void Ending2::renderSpriteTexts() void Ending2::renderSpriteTexts()
{ {
const color_t color = stringToColor(options.palette, "white"); const Color color = stringToColor(options.video.palette, "white");
for (auto sprite : spriteTexts) for (auto sprite : sprite_texts_)
{ {
const bool a = sprite->getRect().y + sprite->getRect().h > 0; const bool a = sprite->getRect().y + sprite->getRect().h > 0;
const bool b = sprite->getRect().y < GAMECANVAS_HEIGHT; const bool b = sprite->getRect().y < GAMECANVAS_HEIGHT;
@@ -447,7 +398,7 @@ void Ending2::renderSpriteTexts()
// Dibuja los sprites con el texto del final // Dibuja los sprites con el texto del final
void Ending2::renderTexts() void Ending2::renderTexts()
{ {
for (auto sprite : texts) for (auto sprite : texts_)
{ {
const bool a = sprite->getRect().y + sprite->getRect().h > 0; const bool a = sprite->getRect().y + sprite->getRect().h > 0;
const bool b = sprite->getRect().y < GAMECANVAS_HEIGHT; const bool b = sprite->getRect().y < GAMECANVAS_HEIGHT;
@@ -461,69 +412,64 @@ void Ending2::renderTexts()
// Coloca los sprites en su sito // Coloca los sprites en su sito
void Ending2::placeSprites() void Ending2::placeSprites()
{ {
for (int i = 0; i < (int)sprites.size(); ++i) for (int i = 0; i < (int)sprites_.size(); ++i)
{ {
const int x = i % 2 == 0 ? firstCol : secondCol; const int x = i % 2 == 0 ? FIRST_COL_ : SECOND_COL_;
const int y = (i / 1) * (maxSpriteHeight + distSpriteText + text->getCharacterSize() + distSpriteSprite) + GAMECANVAS_HEIGHT + 40; const int y = (i / 1) * (sprite_max_height_ + dist_sprite_text_ + text_->getCharacterSize() + dist_sprite_sprite_) + GAMECANVAS_HEIGHT + 40;
const int w = sprites[i]->getAnimationClip(0, 0).w; const int w = sprites_[i]->getWidth();
const int h = sprites[i]->getAnimationClip(0, 0).h; const int h = sprites_[i]->getHeight();
const int dx = -(w / 2); const int dx = -(w / 2);
const int dy = i % 1 == 0 ? maxSpriteHeight - h : (int)(maxSpriteHeight * 1.5f) - h; const int dy = i % 1 == 0 ? sprite_max_height_ - h : (int)(sprite_max_height_ * 1.5f) - h;
sprites[i]->setRect({x + dx, y + dy, w, h}); sprites_[i]->setPosition({x + dx, y + dy, w, h});
sprites[i]->setVelY(despSpeed); sprites_[i]->setVelY(sprite_desp_speed_);
} }
// Recoloca el último sprite, que es el del jugador // Recoloca el último sprite, que es el del jugador
const int w = sprites.back()->getAnimationClip(0, 0).w; const int w = sprites_.back()->getWidth();
const int x = GAMECANVAS_CENTER_X - (w / 2); const int x = GAMECANVAS_CENTER_X - (w / 2);
const int y = sprites.back()->getPosY() + maxSpriteHeight * 2; const int y = sprites_.back()->getPosY() + sprite_max_height_ * 2;
sprites.back()->setPosX(x); sprites_.back()->setPosX(x);
sprites.back()->setPosY(y); sprites_.back()->setPosY(y);
sprites.back()->setCurrentAnimation("walk"); sprites_.back()->setCurrentAnimation("walk");
} }
// Crea los sprites con las texturas con los textos // Crea los sprites con las texturas con los textos
void Ending2::createSpriteTexts() void Ending2::createSpriteTexts()
{ {
// Borra la memoria ocupada por los sprites con las texturas de los textos
deleteSpriteTexts();
// Crea los sprites de texto a partir de la lista // Crea los sprites de texto a partir de la lista
for (int i = 0; i < (int)spriteList.size(); ++i) for (int i = 0; i < (int)sprite_list_.size(); ++i)
{ {
// Calcula constantes // Calcula constantes
std::string txt = spriteList[i]; std::string txt = sprite_list_[i];
std::replace(txt.begin(), txt.end(), '_', ' '); std::replace(txt.begin(), txt.end(), '_', ' ');
txt = txt == "player" ? "JAILDOCTOR" : txt; // Reemplaza el texto txt = txt == "player" ? "JAILDOCTOR" : txt; // Reemplaza el texto
const int w = text->lenght(txt, 1); const int w = text_->lenght(txt, 1);
const int h = text->getCharacterSize(); const int h = text_->getCharacterSize();
const int x = i % 2 == 0 ? firstCol : secondCol; const int x = i % 2 == 0 ? FIRST_COL_ : SECOND_COL_;
const int dx = -(w / 2); const int dx = -(w / 2);
const int y = sprites[i]->getPosY() + sprites[i]->getHeight() + distSpriteText; const int y = sprites_[i]->getPosY() + sprites_[i]->getHeight() + dist_sprite_text_;
// Cambia la posición del último sprite // Cambia la posición del último sprite
const int X = (i == (int)spriteList.size() - 1) ? GAMECANVAS_CENTER_X - (w / 2) : x + dx; const int X = (i == (int)sprite_list_.size() - 1) ? GAMECANVAS_CENTER_X - (w / 2) : x + dx;
// Crea la textura // Crea la textura
Texture *texture = new Texture(renderer); auto texture = std::make_shared<Texture>(renderer_);
texture->createBlank(renderer, w, h, SDL_TEXTUREACCESS_TARGET); texture->createBlank(w, h);
texture->setAsRenderTarget(renderer); texture->setAsRenderTarget(renderer_);
texture->setBlendMode(SDL_BLENDMODE_BLEND); texture->setBlendMode(SDL_BLENDMODE_BLEND);
text->write(0, 0, txt); text_->write(0, 0, txt);
// Crea el sprite // Crea el sprite
MovingSprite *sprite = new MovingSprite(X, y, w, h, 0.0f, despSpeed, 0.0f, 0.0f, texture, renderer); SDL_Rect pos = {X, y, w, h};
spriteTexts.push_back(sprite); sprite_texts_.emplace_back(std::make_shared<MovingSprite>(texture, pos));
sprite_texts_.back()->setVelY(sprite_desp_speed_);
} }
} }
// Crea los sprites con las texturas con los textos del final // Crea los sprites con las texturas con los textos del final
void Ending2::createTexts() void Ending2::createTexts()
{ {
// Borra la memoria ocupada por los sprites con las texturas de los textos del final
deleteTexts();
// Crea los primeros textos // Crea los primeros textos
std::vector<std::string> list; std::vector<std::string> list;
list.push_back("STARRING"); list.push_back("STARRING");
@@ -532,27 +478,28 @@ void Ending2::createTexts()
for (int i = 0; i < (int)list.size(); ++i) for (int i = 0; i < (int)list.size(); ++i)
{ {
// Calcula constantes // Calcula constantes
const int w = text->lenght(list[i], 1); const int w = text_->lenght(list[i], 1);
const int h = text->getCharacterSize(); const int h = text_->getCharacterSize();
const int x = GAMECANVAS_CENTER_X; const int x = GAMECANVAS_CENTER_X;
const int dx = -(w / 2); const int dx = -(w / 2);
const int y = GAMECANVAS_HEIGHT + (text->getCharacterSize() * (i * 2)); const int y = GAMECANVAS_HEIGHT + (text_->getCharacterSize() * (i * 2));
// Crea la textura // Crea la textura
Texture *texture = new Texture(renderer); auto texture = std::make_shared<Texture>(renderer_);
texture->createBlank(renderer, w, h, SDL_TEXTUREACCESS_TARGET); texture->createBlank(w, h);
texture->setAsRenderTarget(renderer); texture->setAsRenderTarget(renderer_);
texture->setBlendMode(SDL_BLENDMODE_BLEND); texture->setBlendMode(SDL_BLENDMODE_BLEND);
text->write(0, 0, list[i]); text_->write(0, 0, list[i]);
// Crea el sprite // Crea el sprite
MovingSprite *sprite = new MovingSprite(x + dx, y, w, h, 0.0f, despSpeed, 0.0f, 0.0f, texture, renderer); SDL_Rect pos = {x + dx, y, w, h};
texts.push_back(sprite); texts_.emplace_back(std::make_shared<MovingSprite>(texture, pos));
texts_.back()->setVelY(sprite_desp_speed_);
} }
// Crea los últimos textos // Crea los últimos textos
// El primer texto va a continuación del ultimo spriteText // El primer texto va a continuación del ultimo spriteText
const int start = spriteTexts.back()->getPosY() + text->getCharacterSize() * 15; const int start = sprite_texts_.back()->getPosY() + text_->getCharacterSize() * 15;
list.clear(); list.clear();
list.push_back("THANK YOU"); list.push_back("THANK YOU");
list.push_back("FOR PLAYING!"); list.push_back("FOR PLAYING!");
@@ -561,82 +508,46 @@ void Ending2::createTexts()
for (int i = 0; i < (int)list.size(); ++i) for (int i = 0; i < (int)list.size(); ++i)
{ {
// Calcula constantes // Calcula constantes
const int w = text->lenght(list[i], 1); const int w = text_->lenght(list[i], 1);
const int h = text->getCharacterSize(); const int h = text_->getCharacterSize();
const int x = GAMECANVAS_CENTER_X; const int x = GAMECANVAS_CENTER_X;
const int dx = -(w / 2); const int dx = -(w / 2);
const int y = start + (text->getCharacterSize() * (i * 2)); const int y = start + (text_->getCharacterSize() * (i * 2));
// Crea la textura // Crea la textura
Texture *texture = new Texture(renderer); auto texture = std::make_shared<Texture>(renderer_);
texture->createBlank(renderer, w, h, SDL_TEXTUREACCESS_TARGET); texture->createBlank(w, h);
texture->setAsRenderTarget(renderer); texture->setAsRenderTarget(renderer_);
texture->setBlendMode(SDL_BLENDMODE_BLEND); texture->setBlendMode(SDL_BLENDMODE_BLEND);
text->write(0, 0, list[i]); text_->write(0, 0, list[i]);
// Crea el sprite // Crea el sprite
MovingSprite *sprite = new MovingSprite(x + dx, y, w, h, 0.0f, despSpeed, 0.0f, 0.0f, texture, renderer); SDL_Rect pos = {x + dx, y, w, h};
texts.push_back(sprite); texts_.emplace_back(std::make_shared<MovingSprite>(texture, pos));
texts_.back()->setVelY(sprite_desp_speed_);
} }
} }
// Borra la memoria ocupada por los sprites con las texturas de los textos
void Ending2::deleteSpriteTexts()
{
for (auto sprite : spriteTexts)
{
delete sprite->getTexture();
delete sprite;
}
spriteTexts.clear();
}
// Borra la memoria ocupada por los sprites
void Ending2::deleteSprites()
{
for (auto sprite : sprites)
{
delete sprite;
}
sprites.clear();
}
// Borra la memoria ocupada por los sprites con las texturas de los textos del final
void Ending2::deleteTexts()
{
for (auto text : texts)
{
delete text;
}
texts.clear();
}
// Actualiza el fade final // Actualiza el fade final
void Ending2::updateFinalFade() void Ending2::updateFinalFade()
{ {
// La variable step va de 0 a 40 en el tramo de postCounter que va de 500 a 540. Al dividirlo por 40, va de 0.0f a 1.0f // La variable step va de 0 a 40 en el tramo de postCounter que va de 500 a 540. Al dividirlo por 40, va de 0.0f a 1.0f
const float step = std::min(std::max(postCounter, 500) - 500, 40) / 40.0f; const float step = std::min(std::max(post_counter_, 500) - 500, 40) / 40.0f;
const int index = (colors.size() - 1) * step; const int index = (colors_.size() - 1) * step;
for (auto t : texts) for (auto t : texts_)
{ {
t->getTexture()->setColor(colors[index].r, colors[index].g, colors[index].b); t->getTexture()->setColor(colors_[index].r, colors_[index].g, colors_[index].b);
} }
} }
// Actualiza el volumen de la musica // Actualiza el volumen de la musica
void Ending2::updateMusicVolume() void Ending2::updateMusicVolume()
{ {
if (postCounter > 0) if (post_counter_ > 0)
{ {
const float step = (600.0f - postCounter) / 600.0f; const float step = (600.0f - post_counter_) / 600.0f;
const int volume = 128 * step; const int volume = 128 * step;
JA_SetVolume(volume); JA_SetVolume(volume);
} }
} }
// Cambia la paleta
void Ending2::switchPalette()
{
options.palette = (options.palette == p_zxspectrum) ? p_zxarne : p_zxspectrum;
}

View File

@@ -1,10 +1,12 @@
#pragma once #pragma once
#include <SDL2/SDL_events.h> // for SDL_Event
#include <SDL2/SDL_render.h> // for SDL_Renderer #include <SDL2/SDL_render.h> // for SDL_Renderer
#include <SDL2/SDL_stdinc.h> // for Uint32 #include <SDL2/SDL_stdinc.h> // for Uint32
#include <memory> // for shared_ptr
#include <string> // for string #include <string> // for string
#include <vector> // for vector #include <vector> // for vector
#include "utils.h" // for Color
#include "defines.h" // for GAMECANVAS_FIRST_QUARTER_X, GAMECANVAS_THIRD_QUARTER_X, GAMECANVAS_WIDTH
class AnimatedSprite; // lines 9-9 class AnimatedSprite; // lines 9-9
class Asset; // lines 10-10 class Asset; // lines 10-10
class Input; // lines 11-11 class Input; // lines 11-11
@@ -13,41 +15,39 @@ class Resource; // lines 13-13
class Screen; // lines 14-14 class Screen; // lines 14-14
class Text; // lines 15-15 class Text; // lines 15-15
struct JA_Music_t; // lines 16-16 struct JA_Music_t; // lines 16-16
struct color_t;
struct options_t;
struct section_t;
class Ending2 class Ending2
{ {
private: private:
// Constantes
static constexpr int FIRST_COL_ = GAMECANVAS_FIRST_QUARTER_X + (GAMECANVAS_WIDTH / 16); // Primera columna por donde desfilan los sprites
static constexpr int SECOND_COL_ = GAMECANVAS_THIRD_QUARTER_X - (GAMECANVAS_WIDTH / 16); // Segunda columna por donde desfilan los sprites
// Objetos y punteros // Objetos y punteros
Screen *screen; // Objeto encargado de dibujar en pantalla Screen *screen_; // Objeto encargado de dibujar en pantalla
SDL_Renderer *renderer; // El renderizador de la ventana SDL_Renderer *renderer_; // El renderizador de la ventana
Resource *resource; // Objeto con los recursos Resource *resource_; // Objeto con los recursos
Asset *asset; // Objeto con los ficheros de recursos Asset *asset_; // Objeto con los ficheros de recursos
Input *input; // Objeto pata gestionar la entrada Input *input_; // Objeto pata gestionar la entrada
Text *text; // Objeto para escribir texto en pantalla std::shared_ptr<Text> text_; // Objeto para escribir texto en pantalla
std::vector<AnimatedSprite *> sprites; // Vector con todos los sprites a dibujar std::vector<std::shared_ptr<AnimatedSprite>> sprites_; // Vector con todos los sprites a dibujar
std::vector<MovingSprite *> spriteTexts; // Vector con los sprites de texto de los sprites std::vector<std::shared_ptr<MovingSprite>> sprite_texts_; // Vector con los sprites de texto de los sprites
std::vector<MovingSprite *> texts; // Vector con los sprites de texto std::vector<std::shared_ptr<MovingSprite>> texts_; // Vector con los sprites de texto
// Variables // Variables
bool counterEnabled; // Indica si está el contador habilitado bool counter_enabled_; // Indica si está el contador habilitado
int preCounter; // Contador previo int pre_counter_; // Contador previo
int postCounter; // Contador posterior int post_counter_; // Contador posterior
bool postCounterEnabled; // Indica si está habilitado el contador bool post_counter_enabled_; // Indica si está habilitado el contador
Uint32 ticks; // Contador de ticks para ajustar la velocidad del programa Uint32 ticks_; // Contador de ticks para ajustar la velocidad del programa
Uint32 ticksSpeed; // Velocidad a la que se repiten los bucles del programa JA_Music_t *music_; // Musica que suena durante el final
JA_Music_t *music; // Musica que suena durante el final std::vector<std::string> sprite_list_; // Lista con todos los sprites a dibujar
std::vector<std::string> spriteList; // Lista con todos los sprites a dibujar std::vector<Color> colors_; // Vector con los colores para el fade
std::vector<color_t> colors; // Vector con los colores para el fade int sprite_max_width_; // El valor de ancho del sprite mas ancho
int maxSpriteWidth; // El valor de ancho del sprite mas ancho int sprite_max_height_; // El valor de alto del sprite mas alto
int maxSpriteHeight; // El valor de alto del sprite mas alto int dist_sprite_text_; // Distancia entre el sprite y el texto que lo acompaña
int distSpriteText; // Distancia entre el sprite y el texto que lo acompaña int dist_sprite_sprite_; // Distancia entre dos sprites de la misma columna
int distSpriteSprite; // Distancia entre dos sprites de la misma columna float sprite_desp_speed_; // Velocidad de desplazamiento de los sprites
float despSpeed; // Velocidad de desplazamiento de los sprites
int firstCol; // Primera columna por donde desfilan los sprites
int secondCol; // Segunda columna por donde desfilan los sprites
// Actualiza el objeto // Actualiza el objeto
void update(); void update();
@@ -97,30 +97,18 @@ private:
// Crea los sprites con las texturas con los textos del final // Crea los sprites con las texturas con los textos del final
void createTexts(); void createTexts();
// Borra la memoria ocupada por los sprites con las texturas de los textos
void deleteSpriteTexts();
// Borra la memoria ocupada por los sprites
void deleteSprites();
// Borra la memoria ocupada por los sprites con las texturas de los textos del final
void deleteTexts();
// Actualiza el fade final // Actualiza el fade final
void updateFinalFade(); void updateFinalFade();
// Actualiza el volumen de la musica // Actualiza el volumen de la musica
void updateMusicVolume(); void updateMusicVolume();
// Cambia la paleta
void switchPalette();
public: public:
// Constructor // Constructor
Ending2(); Ending2();
// Destructor // Destructor
~Ending2(); ~Ending2() = default;
// Bucle principal // Bucle principal
void run(); void run();

View File

@@ -1,119 +1,110 @@
#include "enemy.h" #include "enemy.h"
#include <stdlib.h> // Para rand #include <SDL2/SDL_render.h> // for SDL_RendererFlip, SDL_FLIP_NONE, SDL_FL...
#include <algorithm> // Para min #include <stdlib.h> // for rand
#include "animatedsprite.h" // Para AnimatedSprite #include "animated_sprite.h" // for AnimatedSprite
#include "texture.h" // Para Texture #include "options.h" // for Options, OptionsVideo, options
#include "resource.h" // for Resource
#include "texture.h" // for Texture
// Constructor // Constructor
Enemy::Enemy(enemy_t enemy) Enemy::Enemy(EnemyData enemy)
{ {
// Crea objetos // Crea objetos
sprite = new AnimatedSprite(enemy.renderer, enemy.animation); sprite_ = std::make_shared<AnimatedSprite>(Resource::get()->getTexture(enemy.texture_path), Resource::get()->getAnimations(enemy.animation_path));
// Obten el resto de valores // Obten el resto de valores
x1 = enemy.x1; x1_ = enemy.x1;
x2 = enemy.x2; x2_ = enemy.x2;
y1 = enemy.y1; y1_ = enemy.y1;
y2 = enemy.y2; y2_ = enemy.y2;
palette = enemy.palette; color_string_ = enemy.color;
colorString = enemy.color; setPalette(options.video.palette);
color = stringToColor(palette, colorString); sprite_->setPosX(enemy.x);
sprite->setPosX(enemy.x); sprite_->setPosY(enemy.y);
sprite->setPosY(enemy.y); sprite_->setVelX(enemy.vx);
sprite->setVelX(enemy.vx); sprite_->setVelY(enemy.vy);
sprite->setVelY(enemy.vy); sprite_->setWidth(enemy.w);
sprite->setWidth(enemy.w); sprite_->setHeight(enemy.h);
sprite->setHeight(enemy.h); should_flip_ = enemy.flip;
doFlip = enemy.flip; should_mirror_ = enemy.mirror;
mirror = enemy.mirror;
if (doFlip)
{
if (enemy.vx < 0.0f)
{
sprite->setFlipH(true);
}
}
sprite->setFlipV(mirror);
collider = getRect(); const SDL_RendererFlip flip = (should_flip_ && enemy.vx < 0.0f) ? SDL_FLIP_HORIZONTAL : SDL_FLIP_NONE;
const SDL_RendererFlip mirror = should_mirror_ ? SDL_FLIP_VERTICAL : SDL_FLIP_NONE;
sprite_->setFlip(static_cast<SDL_RendererFlip>(flip | mirror));
collider_ = getRect();
// Coloca un frame al azar o el designado // Coloca un frame al azar o el designado
if (enemy.frame == -1) if (enemy.frame == -1)
{ {
sprite->setCurrentFrame(rand() % sprite->getNumFrames()); sprite_->setCurrentAnimationFrame(rand() % sprite_->getCurrentAnimationSize());
} }
else else
{ {
sprite->setCurrentFrame(std::min(enemy.frame, sprite->getNumFrames() - 1)); sprite_->setCurrentAnimationFrame(enemy.frame);
} }
} }
// Destructor
Enemy::~Enemy()
{
delete sprite;
}
// Pinta el enemigo en pantalla // Pinta el enemigo en pantalla
void Enemy::render() void Enemy::render()
{ {
sprite->getTexture()->setColor(color.r, color.g, color.b); sprite_->getTexture()->setColor(color_.r, color_.g, color_.b);
sprite->render(); sprite_->render();
sprite->getTexture()->setColor(255, 255, 255); sprite_->getTexture()->setColor(255, 255, 255);
} }
// Actualiza las variables del objeto // Actualiza las variables del objeto
void Enemy::update() void Enemy::update()
{ {
sprite->update(); sprite_->update();
checkPath(); checkPath();
collider = getRect(); collider_ = getRect();
} }
// Comprueba si ha llegado al limite del recorrido para darse media vuelta // Comprueba si ha llegado al limite del recorrido para darse media vuelta
void Enemy::checkPath() void Enemy::checkPath()
{ {
if (sprite->getPosX() > x2 || sprite->getPosX() < x1) if (sprite_->getPosX() > x2_ || sprite_->getPosX() < x1_)
{ {
// Recoloca // Recoloca
if (sprite->getPosX() > x2) if (sprite_->getPosX() > x2_)
{ {
sprite->setPosX(x2); sprite_->setPosX(x2_);
} }
else else
{ {
sprite->setPosX(x1); sprite_->setPosX(x1_);
} }
// Cambia el sentido // Cambia el sentido
sprite->setVelX(sprite->getVelX() * (-1)); sprite_->setVelX(sprite_->getVelX() * (-1));
// Invierte el sprite // Invierte el sprite
if (doFlip) if (should_flip_)
{ {
sprite->flipH(); sprite_->flip();
} }
} }
if (sprite->getPosY() > y2 || sprite->getPosY() < y1) if (sprite_->getPosY() > y2_ || sprite_->getPosY() < y1_)
{ {
// Recoloca // Recoloca
if (sprite->getPosY() > y2) if (sprite_->getPosY() > y2_)
{ {
sprite->setPosY(y2); sprite_->setPosY(y2_);
} }
else else
{ {
sprite->setPosY(y1); sprite_->setPosY(y1_);
} }
// Cambia el sentido // Cambia el sentido
sprite->setVelY(sprite->getVelY() * (-1)); sprite_->setVelY(sprite_->getVelY() * (-1));
// Invierte el sprite // Invierte el sprite
if (doFlip) if (should_flip_)
{ {
sprite->flipH(); sprite_->flip();
} }
} }
} }
@@ -121,24 +112,23 @@ void Enemy::checkPath()
// Devuelve el rectangulo que contiene al enemigo // Devuelve el rectangulo que contiene al enemigo
SDL_Rect Enemy::getRect() SDL_Rect Enemy::getRect()
{ {
return sprite->getRect(); return sprite_->getRect();
} }
// Obtiene el rectangulo de colision del enemigo // Obtiene el rectangulo de colision del enemigo
SDL_Rect &Enemy::getCollider() SDL_Rect &Enemy::getCollider()
{ {
return collider; return collider_;
} }
// Recarga la textura // Recarga la textura
void Enemy::reLoadTexture() void Enemy::reLoadTexture()
{ {
sprite->getTexture()->reLoad(); sprite_->getTexture()->reLoad();
} }
// Asigna la paleta // Asigna la paleta
void Enemy::setPalette(palette_e pal) void Enemy::setPalette(Palette pal)
{ {
palette = pal; color_ = stringToColor(pal, color_string_);
color = stringToColor(palette, colorString);
} }

View File

@@ -1,62 +1,58 @@
#pragma once #pragma once
#include <SDL2/SDL_rect.h> // Para SDL_Rect #include <SDL2/SDL_rect.h> // for SDL_Rect
#include <SDL2/SDL_render.h> // Para SDL_Renderer #include <memory> // for shared_ptr
#include <string> // Para basic_string, string #include <string> // for string
#include "utils.h" // Para palette_e, color_t #include "utils.h" // for Color
class AnimatedSprite; class AnimatedSprite;
struct animatedSprite_t;
// Estructura para pasar los datos de un enemigo // Estructura para pasar los datos de un enemigo
struct enemy_t struct EnemyData
{ {
SDL_Renderer *renderer; // El renderizador de la ventana std::string texture_path; // Ruta al fichero con la textura
animatedSprite_t *animation; // Puntero a las animaciones del enemigo std::string animation_path; // Ruta al fichero con la animación
std::string animationString; // Ruta al fichero con la animación int w; // Anchura del enemigo
int w; // Anchura del enemigo int h; // Altura del enemigo
int h; // Altura del enemigo float x; // Posición inicial en el eje X
float x; // Posición inicial en el eje X float y; // Posición inicial en el eje Y
float y; // Posición inicial en el eje Y float vx; // Velocidad en el eje X
float vx; // Velocidad en el eje X float vy; // Velocidad en el eje Y
float vy; // Velocidad en el eje Y int x1; // Limite izquierdo de la ruta en el eje X
int x1; // Limite izquierdo de la ruta en el eje X int x2; // Limite derecho de la ruta en el eje X
int x2; // Limite derecho de la ruta en el eje X int y1; // Limite superior de la ruta en el eje Y
int y1; // Limite superior de la ruta en el eje Y int y2; // Limite inferior de la ruta en el eje Y
int y2; // Limite inferior de la ruta en el eje Y bool flip; // Indica si el enemigo hace flip al terminar su ruta
bool flip; // Indica si el enemigo hace flip al terminar su ruta bool mirror; // Indica si el enemigo está volteado verticalmente
bool mirror; // Indica si el enemigo está volteado verticalmente int frame; // Frame inicial para la animación del enemigo
int frame; // Frame inicial para la animación del enemigo std::string color; // Color del enemigo
std::string color; // Color del enemigo
palette_e palette; // Paleta de colores
}; };
class Enemy class Enemy
{ {
private: private:
// Objetos y punteros // Objetos y punteros
AnimatedSprite *sprite; // Sprite del enemigo std::shared_ptr<AnimatedSprite> sprite_; // Sprite del enemigo
// Variables // Variables
color_t color; // Color del enemigo Color color_; // Color del enemigo
std::string colorString; // Color del enemigo en formato texto std::string color_string_; // Color del enemigo en formato texto
palette_e palette; // Paleta de colores int x1_; // Limite izquierdo de la ruta en el eje X
int x1; // Limite izquierdo de la ruta en el eje X int x2_; // Limite derecho de la ruta en el eje X
int x2; // Limite derecho de la ruta en el eje X int y1_; // Limite superior de la ruta en el eje Y
int y1; // Limite superior de la ruta en el eje Y int y2_; // Limite inferior de la ruta en el eje Y
int y2; // Limite inferior de la ruta en el eje Y SDL_Rect collider_; // Caja de colisión
SDL_Rect collider; // Caja de colisión bool should_flip_; // Indica si el enemigo hace flip al terminar su ruta
bool doFlip; // Indica si el enemigo hace flip al terminar su ruta bool should_mirror_; // Indica si el enemigo se dibuja volteado verticalmente
bool mirror; // Indica si el enemigo se dibuja volteado verticalmente
// Comprueba si ha llegado al limite del recorrido para darse media vuelta // Comprueba si ha llegado al limite del recorrido para darse media vuelta
void checkPath(); void checkPath();
public: public:
// Constructor // Constructor
Enemy(enemy_t enemy); Enemy(EnemyData enemy);
// Destructor // Destructor
~Enemy(); ~Enemy() = default;
// Pinta el enemigo en pantalla // Pinta el enemigo en pantalla
void render(); void render();
@@ -74,5 +70,5 @@ public:
void reLoadTexture(); void reLoadTexture();
// Asigna la paleta // Asigna la paleta
void setPalette(palette_e pal); void setPalette(Palette pal);
}; };

View File

@@ -8,7 +8,7 @@
#include <vector> // for vector #include <vector> // for vector
#include "asset.h" // for Asset #include "asset.h" // for Asset
#include "cheevos.h" // for Cheevos #include "cheevos.h" // for Cheevos
#include "const.h" // for PLAY_AREA_HEIGHT, GAMECANVAS_WIDTH #include "defines.h" // for PLAY_AREA_HEIGHT, GAMECANVAS_WIDTH
#include "debug.h" // for Debug #include "debug.h" // for Debug
#include "input.h" // for Input, REPEAT_FALSE, inputs_e #include "input.h" // for Input, REPEAT_FALSE, inputs_e
#include "item_tracker.h" // for ItemTracker #include "item_tracker.h" // for ItemTracker
@@ -22,6 +22,9 @@
#include "utils.h" // for options_t, cheat_t, stringToColor #include "utils.h" // for options_t, cheat_t, stringToColor
#include "options.h" #include "options.h"
#include "notifier.h" #include "notifier.h"
#include "global_inputs.h"
#include "global_events.h"
//#include "surface.h"
// Constructor // Constructor
Game::Game() Game::Game()
@@ -30,37 +33,39 @@ Game::Game()
asset_(Asset::get()), asset_(Asset::get()),
input_(Input::get()), input_(Input::get()),
resource_(Resource::get()), resource_(Resource::get()),
debug_(Debug::get()) debug_(Debug::get()),
cheevos_(Cheevos::get())
{ {
// Inicia algunas variables // Inicia algunas variables
board_.iniClock = SDL_GetTicks(); //test_surface_ = std::make_shared<Surface>(Screen::get()->getSurface(), "test.gif");
board_ = std::make_shared<ScoreboardData>();
board_->ini_clock = SDL_GetTicks();
#ifdef DEBUG #ifdef DEBUG
current_room_ = "03.room"; current_room_ = "03.room";
const int x = 25; constexpr int X = 25;
const int y = 13; constexpr int Y = 13;
spawn_point_ = {x * 8, y * 8, 0, 0, 0, s_standing, SDL_FLIP_HORIZONTAL}; spawn_point_ = PlayerSpawn(X * 8, Y * 8, 0, 0, 0, PlayerState::STANDING, SDL_FLIP_HORIZONTAL);
debug_->setEnabled(false); debug_->setEnabled(false);
#else #else
current_room_ = "03.room"; current_room_ = "03.room";
const int x = 25; constexpr int X = 25;
const int y = 13; constexpr int Y = 13;
spawn_point_ = {x * 8, y * 8, 0, 0, 0, s_standing, SDL_FLIP_HORIZONTAL}; spawn_point_ = PlayerSpawn(X * 8, Y * 8, 0, 0, 0, PlayerState::STANDING, SDL_FLIP_HORIZONTAL);
#endif #endif
// Crea los objetos // Crea los objetos
cheevos_ = Cheevos::get(); ItemTracker::init();
scoreboard_ = new Scoreboard(&board_); scoreboard_ = std::make_shared<Scoreboard>(board_);
item_tracker_ = new ItemTracker(); room_tracker_ = std::make_shared<RoomTracker>();
room_tracker_ = new RoomTracker(); room_ = std::make_shared<Room>(resource_->getRoom(current_room_), board_);
room_ = new Room(resource_->getRoom(current_room_), item_tracker_, &board_.items, false); std::string player_texture = options.cheats.alternate_skin == Cheat::CheatState::ENABLED ? "player2.png" : "player.png";
const std::string playerPNG = options.cheat.altSkin ? "player2.png" : "player.png"; std::string player_animations = options.cheats.alternate_skin == Cheat::CheatState::ENABLED ? "player2.ani" : "player.ani";
const std::string playerANI = options.cheat.altSkin ? "player2.ani" : "player.ani"; const PlayerData player(spawn_point_, player_texture, player_animations, room_);
const player_t player = {spawn_point_, playerPNG, playerANI, room_}; player_ = std::make_shared<Player>(player);
player_ = new Player(player); text_ = resource_->getText("smb2");
text_ = new Text(resource_->getOffset("smb2.txt"), resource_->getTexture("smb2.png"), renderer_); music_ = resource_->getMusic("game.ogg");
music_ = JA_LoadMusic(asset_->get("game.ogg").c_str()); death_sound_ = resource_->getSound("death.wav");
death_sound_ = JA_LoadSound(asset_->get("death.wav").c_str()); stats_ = std::make_shared<Stats>(asset_->get("stats.csv"), asset_->get("stats_buffer.csv"));
stats_ = new Stats(asset_->get("stats.csv"), asset_->get("stats_buffer.csv"));
// Crea la textura para poner el nombre de la habitación // Crea la textura para poner el nombre de la habitación
room_name_texture_ = SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, GAMECANVAS_WIDTH, text_->getCharacterSize() * 2); room_name_texture_ = SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, GAMECANVAS_WIDTH, text_->getCharacterSize() * 2);
@@ -83,15 +88,14 @@ Game::Game()
// Inicializa el resto de variables // Inicializa el resto de variables
ticks_ = 0; ticks_ = 0;
ticks_speed_ = 15; board_->lives = 9;
board_.lives = 9;
#ifdef DEBUG #ifdef DEBUG
board_.lives = 9; board_->lives = 9;
#endif #endif
board_.items = 0; board_->items = 0;
board_.rooms = 1; board_->rooms = 1;
board_.music = true; board_->music = true;
board_.jailEnabled = options.cheat.jailEnabled; board_->jail_is_open = options.cheats.jail_is_open == Cheat::CheatState::ENABLED;
setScoreBoardColor(); setScoreBoardColor();
room_tracker_->addRoom(current_room_); room_tracker_->addRoom(current_room_);
paused_ = false; paused_ = false;
@@ -100,28 +104,16 @@ Game::Game()
total_items_ = getTotalItems(); total_items_ = getTotalItems();
initStats(); initStats();
stats_->addVisit(room_->getName()); stats_->addVisit(room_->getName());
const bool cheats = options.cheat.infiniteLives || options.cheat.invincible || options.cheat.jailEnabled; cheevos_->enable(!options.cheats.enabled()); // Deshabilita los logros si hay trucos activados
cheevos_->enable(!cheats); // Deshabilita los logros si hay trucos activados
options.section.name = SECTION_GAME; options.section.section = Section::GAME;
options.section.subsection = 0; options.section.subsection = Subsection::NONE;
} }
Game::~Game() Game::~Game()
{ {
// Libera la memoria de los objetos ItemTracker::destroy();
delete scoreboard_;
delete item_tracker_;
delete room_tracker_;
delete room_;
delete player_;
delete text_;
delete stats_;
SDL_DestroyTexture(room_name_texture_); SDL_DestroyTexture(room_name_texture_);
JA_DeleteMusic(music_);
JA_DeleteSound(death_sound_);
} }
// Comprueba los eventos de la cola // Comprueba los eventos de la cola
@@ -130,33 +122,22 @@ void Game::checkEvents()
SDL_Event event; SDL_Event event;
while (SDL_PollEvent(&event)) while (SDL_PollEvent(&event))
{ {
// Evento de salida de la aplicación globalEvents::check(event);
if (event.type == SDL_QUIT)
{
options.section.name = SECTION_QUIT;
screen_->setBorderColor(stringToColor(options.palette, "black"));
break;
}
if (event.type == SDL_RENDER_DEVICE_RESET || event.type == SDL_RENDER_TARGETS_RESET)
{
reLoadTextures();
}
#ifdef DEBUG
if (event.type == SDL_KEYDOWN && event.key.repeat == 0) if (event.type == SDL_KEYDOWN && event.key.repeat == 0)
{ {
switch (event.key.keysym.scancode) switch (event.key.keysym.scancode)
{ {
#ifdef DEBUG
case SDL_SCANCODE_G: case SDL_SCANCODE_G:
debug_->switchEnabled(); debug_->switchEnabled();
options.cheat.invincible = debug_->getEnabled(); options.cheats.invincible = static_cast<Cheat::CheatState>(debug_->getEnabled());
board_.music = !debug_->getEnabled(); board_->music = !debug_->getEnabled();
board_.music ? JA_ResumeMusic() : JA_PauseMusic(); board_->music ? JA_ResumeMusic() : JA_PauseMusic();
break; break;
case SDL_SCANCODE_R: case SDL_SCANCODE_R:
resource_->reLoad(); resource_->reload();
break; break;
case SDL_SCANCODE_W: case SDL_SCANCODE_W:
@@ -176,92 +157,57 @@ void Game::checkEvents()
break; break;
case SDL_SCANCODE_F6: case SDL_SCANCODE_F6:
Notifier::get()->show("ACHIEVEMENT UNLOCKED!", "I LIKE MY MULTICOLOURED FRIENDS", 2); Notifier::get()->show({"ACHIEVEMENT UNLOCKED!", "I LIKE MY MULTICOLOURED FRIENDS"}, NotificationText::LEFT, 2, false, "F6");
break; break;
case SDL_SCANCODE_F7: case SDL_SCANCODE_F7:
Notifier::get()->show("ACHIEVEMENT UNLOCKED!", "I LIKE MY MULTICOLOURED FRIENDS", 3); Notifier::get()->show({"ACHIEVEMENT UNLOCKED!", "I LIKE MY MULTICOLOURED FRIENDS"}, NotificationText::LEFT, 3, false, "F7");
break; break;
case SDL_SCANCODE_F8: case SDL_SCANCODE_F8:
Notifier::get()->show("JAILDESIGNER IS LOGGED IN", "", 4); Notifier::get()->show({"JAILDESIGNER", "IS LOGGED IN"}, NotificationText::LEFT, 4, false);
break; break;
case SDL_SCANCODE_F9: case SDL_SCANCODE_F9:
Notifier::get()->show("JAILDESIGNER IS LOGGED IN", "", 5); Notifier::get()->show({"JAILDESIGNER", "IS LOGGED IN"}, NotificationText::LEFT, 5, false);
break; break;
#endif
default: default:
break; break;
} }
} }
#endif
} }
} }
// Comprueba el teclado // Comprueba el teclado
void Game::checkInput() void Game::checkInput()
{ {
if (input_->checkInput(input_exit, REPEAT_FALSE)) if (input_->checkInput(input_toggle_music, REPEAT_FALSE))
{ {
options.section.name = SECTION_TITLE; board_->music = !board_->music;
} board_->music ? JA_ResumeMusic() : JA_PauseMusic();
Notifier::get()->show({"MUSIC " + std::string(board_->music ? "ENABLED" : "DISABLED")}, NotificationText::CENTER);
else if (input_->checkInput(input_toggle_music, REPEAT_FALSE))
{
board_.music = !board_.music;
board_.music ? JA_ResumeMusic() : JA_PauseMusic();
} }
else if (input_->checkInput(input_pause, REPEAT_FALSE)) else if (input_->checkInput(input_pause, REPEAT_FALSE))
{ {
switchPause(); switchPause();
Notifier::get()->show({std::string(paused_ ? "GAME PAUSED" : "GAME RUNNING")}, NotificationText::CENTER);
} }
else if (input_->checkInput(input_toggle_border, REPEAT_FALSE)) globalInputs::check();
{
screen_->toggleBorder();
reLoadTextures();
}
else if (input_->checkInput(input_toggle_videomode, REPEAT_FALSE))
{
screen_->toggleVideoMode();
reLoadTextures();
}
else if (input_->checkInput(input_toggle_shaders, REPEAT_FALSE))
{
screen_->toggleShaders();
}
else if (input_->checkInput(input_window_dec_size, REPEAT_FALSE))
{
screen_->decWindowSize();
reLoadTextures();
}
else if (input_->checkInput(input_window_inc_size, REPEAT_FALSE))
{
screen_->incWindowSize();
reLoadTextures();
}
else if (input_->checkInput(input_toggle_palette, REPEAT_FALSE))
{
switchPalette();
}
} }
// Bucle para el juego // Bucle para el juego
void Game::run() void Game::run()
{ {
JA_PlayMusic(music_); JA_PlayMusic(music_);
if (!board_.music) if (!board_->music)
{ {
JA_PauseMusic(); JA_PauseMusic();
} }
while (options.section.name == SECTION_GAME) while (options.section.section == Section::GAME)
{ {
update(); update();
checkEvents(); checkEvents();
@@ -275,7 +221,7 @@ void Game::run()
void Game::update() void Game::update()
{ {
// Comprueba que la diferencia de ticks sea mayor a la velocidad del juego // Comprueba que la diferencia de ticks sea mayor a la velocidad del juego
if (SDL_GetTicks() - ticks_ > ticks_speed_) if (SDL_GetTicks() - ticks_ > GAME_SPEED)
{ {
// Actualiza el contador de ticks // Actualiza el contador de ticks
ticks_ = SDL_GetTicks(); ticks_ = SDL_GetTicks();
@@ -316,6 +262,7 @@ void Game::render()
{ {
// Prepara para dibujar el frame // Prepara para dibujar el frame
screen_->start(); screen_->start();
//test_surface_->render(0, 0, 10, 10, 64, 64);
// Dibuja los elementos del juego en orden // Dibuja los elementos del juego en orden
room_->renderMap(); room_->renderMap();
@@ -339,9 +286,9 @@ void Game::render()
// Pasa la información de debug // Pasa la información de debug
void Game::updateDebugInfo() void Game::updateDebugInfo()
{ {
debug_->add("X = " + std::to_string(static_cast<int>(player_->x)) + ", Y = " + std::to_string(static_cast<int>(player_->y))); debug_->add("X = " + std::to_string(static_cast<int>(player_->x_)) + ", Y = " + std::to_string(static_cast<int>(player_->y_)));
debug_->add("VX = " + std::to_string(player_->vx).substr(0, 4) + ", VY = " + std::to_string(player_->vy).substr(0, 4)); debug_->add("VX = " + std::to_string(player_->vx_).substr(0, 4) + ", VY = " + std::to_string(player_->vy_).substr(0, 4));
debug_->add("STATE = " + std::to_string(player_->state)); debug_->add("STATE = " + std::to_string(static_cast<int>(player_->state_)));
} }
// Pone la información de debug en pantalla // Pone la información de debug en pantalla
@@ -393,12 +340,8 @@ bool Game::changeRoom(std::string file)
// Verifica que exista el fichero que se va a cargar // Verifica que exista el fichero que se va a cargar
if (asset_->get(file) != "") if (asset_->get(file) != "")
{ {
// Elimina la habitación actual
delete room_;
room_ = nullptr;
// Crea un objeto habitación nuevo a partir del fichero // Crea un objeto habitación nuevo a partir del fichero
room_ = new Room(resource_->getRoom(file), item_tracker_, &board_.items, board_.jailEnabled); room_ = std::make_shared<Room>(resource_->getRoom(file), board_);
// Pone el nombre de la habitación en la textura // Pone el nombre de la habitación en la textura
fillRoomNameTexture(); fillRoomNameTexture();
@@ -409,8 +352,8 @@ bool Game::changeRoom(std::string file)
if (room_tracker_->addRoom(file)) if (room_tracker_->addRoom(file))
{ {
// Incrementa el contador de habitaciones visitadas // Incrementa el contador de habitaciones visitadas
board_.rooms++; board_->rooms++;
options.stats.rooms = board_.rooms; options.stats.rooms = board_->rooms;
// Actualiza las estadisticas // Actualiza las estadisticas
stats_->addVisit(room_->getName()); stats_->addVisit(room_->getName());
@@ -469,24 +412,24 @@ void Game::checkIfPlayerIsAlive()
// Comprueba si ha terminado la partida // Comprueba si ha terminado la partida
void Game::checkGameOver() void Game::checkGameOver()
{ {
if (board_.lives < 0 && black_screen_counter_ > 17) if (board_->lives < 0 && black_screen_counter_ > 17)
{ {
options.section.name = SECTION_GAME_OVER; options.section.section = Section::GAME_OVER;
} }
} }
// Mata al jugador // Mata al jugador
void Game::killPlayer() void Game::killPlayer()
{ {
if (options.cheat.invincible) if (options.cheats.invincible == Cheat::CheatState::ENABLED)
{ {
return; return;
} }
// Resta una vida al jugador // Resta una vida al jugador
if (!options.cheat.infiniteLives) if (options.cheats.infinite_lives == Cheat::CheatState::DISABLED)
{ {
board_.lives--; --board_->lives;
} }
// Actualiza las estadisticas // Actualiza las estadisticas
@@ -495,10 +438,6 @@ void Game::killPlayer()
// Invalida el logro de pasarse el juego sin morir // Invalida el logro de pasarse el juego sin morir
cheevos_->invalidate(11); cheevos_->invalidate(11);
// Destruye la habitacion y el jugador
delete room_;
delete this->player_;
// Sonido // Sonido
JA_PlaySound(death_sound_); JA_PlaySound(death_sound_);
@@ -506,15 +445,15 @@ void Game::killPlayer()
setBlackScreen(); setBlackScreen();
// Crea la nueva habitación y el nuevo jugador // Crea la nueva habitación y el nuevo jugador
room_ = new Room(resource_->getRoom(current_room_),item_tracker_, &board_.items, board_.jailEnabled); room_ = std::make_shared<Room>(resource_->getRoom(current_room_), board_);
const std::string playerPNG = options.cheat.altSkin ? "player2.png" : "player.png"; std::string player_texture = options.cheats.alternate_skin == Cheat::CheatState::ENABLED ? "player2.png" : "player.png";
const std::string playerANI = options.cheat.altSkin ? "player2.ani" : "player.ani"; std::string player_animations = options.cheats.alternate_skin == Cheat::CheatState::ENABLED ? "player2.ani" : "player.ani";
const player_t player = {spawn_point_, playerPNG, playerANI, room_}; const PlayerData player(spawn_point_, player_texture, player_animations, room_);
this->player_ = new Player(player); player_ = std::make_shared<Player>(player);
// Pone los objetos en pausa mientras esta la habitación en negro // Pone los objetos en pausa mientras esta la habitación en negro
room_->pause(); room_->pause();
this->player_->pause(); player_->pause();
} }
// Recarga todas las texturas // Recarga todas las texturas
@@ -530,26 +469,6 @@ void Game::reLoadTextures()
text_->reLoadTexture(); text_->reLoadTexture();
} }
// Cambia la paleta
void Game::switchPalette()
{
if (options.console)
{
std::cout << "** PALETTE SWITCH REQUESTED" << std::endl;
}
// Modifica la variable
options.palette = (options.palette == p_zxspectrum) ? p_zxarne : p_zxspectrum;
// Recarga las paletas
room_->reLoadPalette();
player_->reLoadPalette();
scoreboard_->reLoadPalette();
// Pone el color del marcador en función del color del borde de la habitación
setScoreBoardColor();
}
// Establece la pantalla en negro // Establece la pantalla en negro
void Game::setBlackScreen() void Game::setBlackScreen()
{ {
@@ -580,7 +499,7 @@ void Game::renderBlackScreen()
if (black_screen_) if (black_screen_)
{ {
screen_->clean(); screen_->clean();
screen_->setBorderColor(stringToColor(options.palette, "black")); screen_->setBorderColor(stringToColor(options.video.palette, "black"));
} }
} }
@@ -588,25 +507,25 @@ void Game::renderBlackScreen()
void Game::setScoreBoardColor() void Game::setScoreBoardColor()
{ {
// Obtiene el color del borde // Obtiene el color del borde
const color_t colorBorder = room_->getBorderColor(); const Color colorBorder = room_->getBorderColor();
const bool isBlack = colorAreEqual(colorBorder, stringToColor(options.palette, "black")); const bool isBlack = colorAreEqual(colorBorder, stringToColor(options.video.palette, "black"));
const bool isBrightBlack = colorAreEqual(colorBorder, stringToColor(options.palette, "bright_black")); const bool isBrightBlack = colorAreEqual(colorBorder, stringToColor(options.video.palette, "bright_black"));
// Si el color del borde es negro o negro brillante cambia el texto del marcador a blanco // Si el color del borde es negro o negro brillante cambia el texto del marcador a blanco
board_.color = isBlack || isBrightBlack ? stringToColor(options.palette, "white") : colorBorder; board_->color = isBlack || isBrightBlack ? stringToColor(options.video.palette, "white") : colorBorder;
} }
// Comprueba si ha finalizado el juego // Comprueba si ha finalizado el juego
bool Game::checkEndGame() bool Game::checkEndGame()
{ {
const bool isOnTheRoom = room_->getName() == "THE JAIL"; // Estar en la habitación que toca const bool isOnTheRoom = room_->getName() == "THE JAIL"; // Estar en la habitación que toca
const bool haveTheItems = board_.items >= int(total_items_ * 0.9f) || options.cheat.jailEnabled; // Con mas del 90% de los items recogidos const bool haveTheItems = board_->items >= int(total_items_ * 0.9f) || options.cheats.jail_is_open == Cheat::CheatState::ENABLED; // Con mas del 90% de los items recogidos
const bool isOnTheDoor = player_->getRect().x <= 128; // Y en la ubicación que toca (En la puerta) const bool isOnTheDoor = player_->getRect().x <= 128; // Y en la ubicación que toca (En la puerta)
if (haveTheItems) if (haveTheItems)
{ {
board_.jailEnabled = true; board_->jail_is_open = true;
} }
if (haveTheItems && isOnTheRoom && isOnTheDoor) if (haveTheItems && isOnTheRoom && isOnTheDoor)
@@ -614,7 +533,7 @@ bool Game::checkEndGame()
// Comprueba los logros de completar el juego // Comprueba los logros de completar el juego
checkEndGameCheevos(); checkEndGameCheevos();
options.section.name = SECTION_ENDING; options.section.section = Section::ENDING;
return true; return true;
} }
@@ -625,10 +544,9 @@ bool Game::checkEndGame()
int Game::getTotalItems() int Game::getTotalItems()
{ {
int items = 0; int items = 0;
std::vector<res_room_t> *rooms = new std::vector<res_room_t>; auto rooms = resource_->getRooms();
rooms = resource_->getAllRooms();
for (auto room : *rooms) for (auto room : rooms)
{ {
items += room.room->items.size(); items += room.room->items.size();
} }
@@ -668,7 +586,7 @@ void Game::switchPause()
// Da vidas al jugador cuando está en la Jail // Da vidas al jugador cuando está en la Jail
void Game::checkRestoringJail() void Game::checkRestoringJail()
{ {
if (room_->getName() != "THE JAIL" || board_.lives == 9) if (room_->getName() != "THE JAIL" || board_->lives == 9)
{ {
return; return;
} }
@@ -684,11 +602,11 @@ void Game::checkRestoringJail()
if (counter == 100) if (counter == 100)
{ {
counter = 0; counter = 0;
board_.lives++; board_->lives++;
JA_PlaySound(death_sound_); JA_PlaySound(death_sound_);
// Invalida el logro de completar el juego sin entrar a la jail // Invalida el logro de completar el juego sin entrar a la jail
const bool haveTheItems = board_.items >= int(total_items_ * 0.9f); const bool haveTheItems = board_->items >= int(total_items_ * 0.9f);
if (!haveTheItems) if (!haveTheItems)
{ {
cheevos_->invalidate(9); cheevos_->invalidate(9);
@@ -699,10 +617,9 @@ void Game::checkRestoringJail()
// Inicializa el diccionario de las estadísticas // Inicializa el diccionario de las estadísticas
void Game::initStats() void Game::initStats()
{ {
std::vector<res_room_t> *rooms = new std::vector<res_room_t>; auto rooms = resource_->getRooms();
rooms = resource_->getAllRooms();
for (auto room : *rooms) for (auto room : rooms)
{ {
stats_->addDictionary(room.room->number, room.room->name); stats_->addDictionary(room.room->number, room.room->name);
} }
@@ -717,12 +634,12 @@ void Game::fillRoomNameTexture()
SDL_SetRenderTarget(renderer_, room_name_texture_); SDL_SetRenderTarget(renderer_, room_name_texture_);
// Rellena la textura de color // Rellena la textura de color
const color_t color = stringToColor(options.palette, "white"); const Color color = stringToColor(options.video.palette, "white");
SDL_SetRenderDrawColor(renderer_, color.r, color.g, color.b, 0xFF); SDL_SetRenderDrawColor(renderer_, color.r, color.g, color.b, 0xFF);
SDL_RenderClear(renderer_); SDL_RenderClear(renderer_);
// Escribe el texto en la textura // Escribe el texto en la textura
text_->writeDX(TXT_CENTER | TXT_COLOR, GAMECANVAS_CENTER_X, text_->getCharacterSize() / 2, room_->getName(), 1, room_->getBGColor()); text_->writeDX(TEXT_CENTER | TEXT_COLOR, GAMECANVAS_CENTER_X, text_->getCharacterSize() / 2, room_->getName(), 1, room_->getBGColor());
// Deja el renderizador por defecto // Deja el renderizador por defecto
SDL_SetRenderTarget(renderer_, nullptr); SDL_SetRenderTarget(renderer_, nullptr);
@@ -732,42 +649,42 @@ void Game::fillRoomNameTexture()
void Game::checkSomeCheevos() void Game::checkSomeCheevos()
{ {
// Logros sobre la cantidad de items // Logros sobre la cantidad de items
if (board_.items == total_items_) if (board_->items == total_items_)
{ {
cheevos_->unlock(4); cheevos_->unlock(4);
cheevos_->unlock(3); cheevos_->unlock(3);
cheevos_->unlock(2); cheevos_->unlock(2);
cheevos_->unlock(1); cheevos_->unlock(1);
} }
else if (board_.items >= total_items_ * 0.75f) else if (board_->items >= total_items_ * 0.75f)
{ {
cheevos_->unlock(3); cheevos_->unlock(3);
cheevos_->unlock(2); cheevos_->unlock(2);
cheevos_->unlock(1); cheevos_->unlock(1);
} }
else if (board_.items >= total_items_ * 0.5f) else if (board_->items >= total_items_ * 0.5f)
{ {
cheevos_->unlock(2); cheevos_->unlock(2);
cheevos_->unlock(1); cheevos_->unlock(1);
} }
else if (board_.items >= total_items_ * 0.25f) else if (board_->items >= total_items_ * 0.25f)
{ {
cheevos_->unlock(1); cheevos_->unlock(1);
} }
// Logros sobre las habitaciones visitadas // Logros sobre las habitaciones visitadas
if (board_.rooms >= 60) if (board_->rooms >= 60)
{ {
cheevos_->unlock(7); cheevos_->unlock(7);
cheevos_->unlock(6); cheevos_->unlock(6);
cheevos_->unlock(5); cheevos_->unlock(5);
} }
else if (board_.rooms >= 40) else if (board_->rooms >= 40)
{ {
cheevos_->unlock(6); cheevos_->unlock(6);
cheevos_->unlock(5); cheevos_->unlock(5);
} }
else if (board_.rooms >= 20) else if (board_->rooms >= 20)
{ {
cheevos_->unlock(5); cheevos_->unlock(5);
} }
@@ -783,7 +700,7 @@ void Game::checkEndGameCheevos()
cheevos_->unlock(9); cheevos_->unlock(9);
// "Complete the game with all items" // "Complete the game with all items"
if (board_.items == total_items_) if (board_->items == total_items_)
{ {
cheevos_->unlock(10); cheevos_->unlock(10);
} }

View File

@@ -7,6 +7,8 @@
#include <string> // Para string, basic_string #include <string> // Para string, basic_string
#include "player.h" // Para playerSpawn_t #include "player.h" // Para playerSpawn_t
#include "scoreboard.h" // Para board_t #include "scoreboard.h" // Para board_t
#include "room.h"
//#include "surface.h"
class Asset; class Asset;
class Cheevos; class Cheevos;
class Debug; class Debug;
@@ -20,42 +22,41 @@ class Stats;
class Text; class Text;
struct JA_Music_t; struct JA_Music_t;
struct JA_Sound_t; struct JA_Sound_t;
struct options_t; struct Options;
struct section_t; struct SectionState;
class Game class Game
{ {
private: private:
// Objetos y punteros // Objetos y punteros
Screen *screen_; // Objeto encargado de manejar el renderizador Screen *screen_; // Objeto encargado de manejar el renderizador
SDL_Renderer *renderer_; // El renderizador de la ventana SDL_Renderer *renderer_; // El renderizador de la ventana
Room *room_; // Objeto encargado de gestionar cada habitación del juego Asset *asset_; // Objeto con la ruta a todos los ficheros de recursos
Player *player_; // Objeto con el jugador Input *input_; // Objeto pata gestionar la entrada
ItemTracker *item_tracker_; // Lleva el control de los objetos recogidos Resource *resource_; // Objeto con los recursos
RoomTracker *room_tracker_; // Lleva el control de las habitaciones visitadas Debug *debug_; // Objeto para gestionar la información de debug
Asset *asset_; // Objeto con la ruta a todos los ficheros de recursos Cheevos *cheevos_; // Objeto encargado de gestionar los logros del juego
Input *input_; // Objeto pata gestionar la entrada std::shared_ptr<Room> room_; // Objeto encargado de gestionar cada habitación del juego
Text *text_; // Objeto para los textos del juego std::shared_ptr<Player> player_; // Objeto con el jugador
Scoreboard *scoreboard_; // Objeto encargado de gestionar el marcador std::shared_ptr<RoomTracker> room_tracker_; // Lleva el control de las habitaciones visitadas
Cheevos *cheevos_; // Objeto encargado de gestionar los logros del juego std::shared_ptr<Text> text_; // Objeto para los textos del juego
Resource *resource_; // Objeto con los recursos std::shared_ptr<Scoreboard> scoreboard_; // Objeto encargado de gestionar el marcador
Debug *debug_; // Objeto para gestionar la información de debug std::shared_ptr<Stats> stats_; // Objeto encargado de gestionar las estadísticas
Stats *stats_; // Objeto encargado de gestionar las estadísticas SDL_Texture *room_name_texture_; // Textura para escribir el nombre de la habitación
SDL_Texture *room_name_texture_; // Textura para escribir el nombre de la habitación //std::shared_ptr<Surface> test_surface_;
// Variables // Variables
JA_Music_t *music_; // Musica que suena durante el juego JA_Music_t *music_; // Musica que suena durante el juego
Uint32 ticks_; // Contador de ticks para ajustar la velocidad del programa Uint32 ticks_; // Contador de ticks para ajustar la velocidad del programa
Uint32 ticks_speed_; // Velocidad a la que se repiten los bucles del programa std::string current_room_; // Fichero de la habitación actual
std::string current_room_; // Fichero de la habitación actual PlayerSpawn spawn_point_; // Lugar de la habitación donde aparece el jugador
playerSpawn_t spawn_point_; // Lugar de la habitación donde aparece el jugador JA_Sound_t *death_sound_; // Sonido a reproducir cuando muere el jugador
JA_Sound_t *death_sound_; // Sonido a reproducir cuando muere el jugador std::shared_ptr<ScoreboardData> board_; // Estructura con los datos del marcador
board_t board_; // Estructura con los datos del marcador bool paused_; // Indica si el juego se encuentra en pausa
bool paused_; // Indica si el juego se encuentra en pausa bool black_screen_; // Indica si la pantalla está en negro. Se utiliza para la muerte del jugador
bool black_screen_; // Indica si la pantalla está en negro. Se utiliza para la muerte del jugador int black_screen_counter_; // Contador para temporizar la pantalla en negro
int black_screen_counter_; // Contador para temporizar la pantalla en negro int total_items_; // Cantidad total de items que hay en el mapeado del juego
int total_items_; // Cantidad total de items que hay en el mapeado del juego SDL_Rect room_name_rect_; // Rectangulo donde pintar la textura con el nombre de la habitación
SDL_Rect room_name_rect_; // Rectangulo donde pintar la textura con el nombre de la habitación
// Actualiza el juego, las variables, comprueba la entrada, etc. // Actualiza el juego, las variables, comprueba la entrada, etc.
void update(); void update();
@@ -104,9 +105,6 @@ private:
// Recarga todas las texturas // Recarga todas las texturas
void reLoadTextures(); void reLoadTextures();
// Cambia la paleta
void switchPalette();
// Establece la pantalla en negro // Establece la pantalla en negro
void setBlackScreen(); void setBlackScreen();

View File

@@ -1,74 +1,63 @@
#include "game_over.h" #include "game_over.h"
#include <SDL2/SDL_timer.h> // Para SDL_GetTicks #include <SDL2/SDL_events.h> // for SDL_PollEvent, SDL_Event
#include <algorithm> // Para min, max #include <SDL2/SDL_timer.h> // for SDL_GetTicks
#include <string> // Para basic_string, operator+, to_string, char... #include <algorithm> // for min, max
#include "animatedsprite.h" // Para AnimatedSprite #include <string> // for basic_string, operator+, to_string, cha...
#include "asset.h" // Para Asset #include "animated_sprite.h" // for AnimatedSprite
#include "const.h" // Para GAMECANVAS_CENTER_X, SECTION_GAME_OVER #include "asset.h" // for Asset
#include "input.h" // Para Input, REPEAT_FALSE, inputs_e #include "defines.h" // for GAMECANVAS_CENTER_X
#include "jail_audio.h" // Para JA_DeleteMusic, JA_LoadMusic, JA_PlayMusic #include "global_events.h" // for check
#include "resource.h" // Para Resource #include "global_inputs.h" // for check
#include "screen.h" // Para Screen #include "input.h" // for Input
#include "text.h" // Para Text, TXT_CENTER, TXT_COLOR #include "jail_audio.h" // for JA_PlayMusic
#include "texture.h" // Para Texture #include "options.h" // for Options, options, OptionsStats, Section...
#include "options.h" #include "resource.h" // for Resource
#include "screen.h" // for Screen
#include "text.h" // for TEXT_CENTER, TEXT_COLOR, Text
#include "texture.h" // for Texture
// Constructor // Constructor
GameOver::GameOver() GameOver::GameOver()
: screen(Screen::get()), : screen_(Screen::get()),
renderer(Screen::get()->getRenderer()), renderer_(Screen::get()->getRenderer()),
resource(Resource::get()), resource_(Resource::get()),
asset(Asset::get()), asset_(Asset::get()),
input(Input::get()) input_(Input::get())
{ {
// Reserva memoria para los punteros a objetos // Reserva memoria para los punteros a objetos
text = new Text(resource->getOffset("smb2.txt"), resource->getTexture("smb2.png"), renderer); text_ = resource_->getText("smb2");
playerSprite = new AnimatedSprite(renderer, resource->getAnimation("player_game_over.ani")); player_sprite_ = std::make_shared<AnimatedSprite>(resource_->getTexture("player_game_over.png"), resource_->getAnimations("player_game_over.ani"));
tvSprite = new AnimatedSprite(renderer, resource->getAnimation("tv.ani")); tv_sprite_ = std::make_shared<AnimatedSprite>(resource_->getTexture("tv.png"), resource_->getAnimations("tv.ani"));
music = JA_LoadMusic(asset->get("game_over.ogg").c_str()); music_ = resource_->getMusic("game_over.ogg");
// Inicializa variables // Inicializa variables
preCounter = 0; pre_counter_ = 0;
counter = 0; counter_ = 0;
options.section.name = SECTION_GAME_OVER; options.section.section = Section::GAME_OVER;
options.section.subsection = 0; options.section.subsection = Subsection::NONE;
ticks = 0; ticks_ = 0;
ticksSpeed = 15; player_sprite_->setPosX(GAMECANVAS_CENTER_X + 10);
endSection = 400; player_sprite_->setPosY(30);
iniFade = 310; tv_sprite_->setPosX(GAMECANVAS_CENTER_X - tv_sprite_->getWidth() - 10);
fadeLenght = 20; tv_sprite_->setPosY(30);
playerSprite->setPosX(GAMECANVAS_CENTER_X + 10);
playerSprite->setPosY(30);
tvSprite->setPosX(GAMECANVAS_CENTER_X - tvSprite->getAnimationClip(0, 0).w - 10);
tvSprite->setPosY(30);
// Inicializa el vector de colores // Inicializa el vector de colores
const std::vector<std::string> colorList = {"white", "yellow", "cyan", "green", "magenta", "red", "blue", "black"}; const std::vector<std::string> colorList = {"white", "yellow", "cyan", "green", "magenta", "red", "blue", "black"};
for (auto cl : colorList) for (auto cl : colorList)
{ {
colors.push_back(stringToColor(options.palette, cl)); colors_.push_back(stringToColor(options.video.palette, cl));
} }
color = colors.back(); color_ = colors_.back();
}
// Destructor
GameOver::~GameOver()
{
// Libera la memoria de los objetos
delete text;
delete playerSprite;
delete tvSprite;
JA_DeleteMusic(music);
} }
// Actualiza el objeto // Actualiza el objeto
void GameOver::update() void GameOver::update()
{ {
// Comprueba que la diferencia de ticks sea mayor a la velocidad del juego // Comprueba que la diferencia de ticks sea mayor a la velocidad del juego
if (SDL_GetTicks() - ticks > ticksSpeed) if (SDL_GetTicks() - ticks_ > GAME_SPEED)
{ {
// Actualiza el contador de ticks // Actualiza el contador de ticks
ticks = SDL_GetTicks(); ticks_ = SDL_GetTicks();
// Comprueba las entradas // Comprueba las entradas
checkInput(); checkInput();
@@ -80,44 +69,41 @@ void GameOver::update()
updateCounters(); updateCounters();
// Actualiza los dos sprites // Actualiza los dos sprites
playerSprite->update(); player_sprite_->update();
tvSprite->update(); tv_sprite_->update();
screen->update(); screen_->update();
} }
} }
// Dibuja el final en pantalla // Dibuja el final en pantalla
void GameOver::render() void GameOver::render()
{ {
const int y = 32; constexpr int Y = 32;
// Prepara para empezar a dibujar en la textura de juego screen_->start();
screen->start(); screen_->clean();
// Limpia la pantalla
screen->clean();
// Escribe el texto de GAME OVER // Escribe el texto de GAME OVER
text->writeDX(TXT_CENTER | TXT_COLOR, GAMECANVAS_CENTER_X, y, "G A M E O V E R", 1, color); text_->writeDX(TEXT_CENTER | TEXT_COLOR, GAMECANVAS_CENTER_X, Y, "G A M E O V E R", 1, color_);
// Dibuja los sprites // Dibuja los sprites
playerSprite->setPosY(y + 30); player_sprite_->setPosY(Y + 30);
tvSprite->setPosY(y + 30); tv_sprite_->setPosY(Y + 30);
renderSprites(); renderSprites();
// Escribe el texto con las habitaciones y los items // Escribe el texto con las habitaciones y los items
const std::string itemsTxt = std::to_string(options.stats.items / 100) + std::to_string((options.stats.items % 100) / 10) + std::to_string(options.stats.items % 10); const std::string itemsTxt = std::to_string(options.stats.items / 100) + std::to_string((options.stats.items % 100) / 10) + std::to_string(options.stats.items % 10);
const std::string roomsTxt = std::to_string(options.stats.rooms / 100) + std::to_string((options.stats.rooms % 100) / 10) + std::to_string(options.stats.rooms % 10); const std::string roomsTxt = std::to_string(options.stats.rooms / 100) + std::to_string((options.stats.rooms % 100) / 10) + std::to_string(options.stats.rooms % 10);
text->writeDX(TXT_CENTER | TXT_COLOR, GAMECANVAS_CENTER_X, y + 80, "ITEMS: " + itemsTxt, 1, color); text_->writeDX(TEXT_CENTER | TEXT_COLOR, GAMECANVAS_CENTER_X, Y + 80, "ITEMS: " + itemsTxt, 1, color_);
text->writeDX(TXT_CENTER | TXT_COLOR, GAMECANVAS_CENTER_X, y + 90, "ROOMS: " + roomsTxt, 1, color); text_->writeDX(TEXT_CENTER | TEXT_COLOR, GAMECANVAS_CENTER_X, Y + 90, "ROOMS: " + roomsTxt, 1, color_);
// Escribe el texto con "Tu peor pesadilla" // Escribe el texto con "Tu peor pesadilla"
text->writeDX(TXT_CENTER | TXT_COLOR, GAMECANVAS_CENTER_X, y + 110, "YOUR WORST NIGHTMARE IS", 1, color); text_->writeDX(TEXT_CENTER | TEXT_COLOR, GAMECANVAS_CENTER_X, Y + 110, "YOUR WORST NIGHTMARE IS", 1, color_);
text->writeDX(TXT_CENTER | TXT_COLOR, GAMECANVAS_CENTER_X, y + 120, options.stats.worstNightmare, 1, color); text_->writeDX(TEXT_CENTER | TEXT_COLOR, GAMECANVAS_CENTER_X, Y + 120, options.stats.worst_nightmare, 1, color_);
// Vuelca el contenido del renderizador en pantalla // Vuelca el contenido del renderizador en pantalla
screen->render(); screen_->render();
} }
// Comprueba el manejador de eventos // Comprueba el manejador de eventos
@@ -126,55 +112,20 @@ void GameOver::checkEvents()
SDL_Event event; SDL_Event event;
while (SDL_PollEvent(&event)) while (SDL_PollEvent(&event))
{ {
// Evento de salida de la aplicación globalEvents::check(event);
if (event.type == SDL_QUIT)
{
options.section.name = SECTION_QUIT;
options.section.subsection = 0;
break;
}
} }
} }
// Comprueba las entradas // Comprueba las entradas
void GameOver::checkInput() void GameOver::checkInput()
{ {
globalInputs::check();
if (input->checkInput(input_exit, REPEAT_FALSE))
{
options.section.name = SECTION_QUIT;
}
else if (input->checkInput(input_toggle_border, REPEAT_FALSE))
{
screen->toggleBorder();
}
else if (input->checkInput(input_toggle_videomode, REPEAT_FALSE))
{
screen->toggleVideoMode();
}
else if (input->checkInput(input_window_dec_size, REPEAT_FALSE))
{
screen->decWindowSize();
}
else if (input->checkInput(input_window_inc_size, REPEAT_FALSE))
{
screen->incWindowSize();
}
else if (input->checkInput(input_toggle_palette, REPEAT_FALSE))
{
switchPalette();
}
} }
// Bucle principal // Bucle principal
void GameOver::run() void GameOver::run()
{ {
while (options.section.name == SECTION_GAME_OVER) while (options.section.section == Section::GAME_OVER)
{ {
update(); update();
checkEvents(); checkEvents();
@@ -185,61 +136,55 @@ void GameOver::run()
// Actualiza el color usado para renderizar los textos e imagenes // Actualiza el color usado para renderizar los textos e imagenes
void GameOver::updateColor() void GameOver::updateColor()
{ {
const int half = endSection / 2; const int half = COUNTER_SECTION_END_ / 2;
if (counter < half) if (counter_ < half)
{ {
const float step = std::min(counter, fadeLenght) / (float)fadeLenght; const float step = std::min(counter_, COUNTER_FADE_LENGHT_) / (float)COUNTER_FADE_LENGHT_;
const int index = (colors.size() - 1) - int((colors.size() - 1) * step); const int index = (colors_.size() - 1) - int((colors_.size() - 1) * step);
color = colors[index]; color_ = colors_[index];
} }
else else
{ {
const float step = std::min(std::max(counter, iniFade) - iniFade, fadeLenght) / (float)fadeLenght; const float step = std::min(std::max(counter_, COUNTER_INIT_FADE_) - COUNTER_INIT_FADE_, COUNTER_FADE_LENGHT_) / (float)COUNTER_FADE_LENGHT_;
const int index = (colors.size() - 1) * step; const int index = (colors_.size() - 1) * step;
color = colors[index]; color_ = colors_[index];
} }
} }
// Dibuja los sprites // Dibuja los sprites
void GameOver::renderSprites() void GameOver::renderSprites()
{ {
playerSprite->getTexture()->setColor(color.r, color.g, color.b); player_sprite_->getTexture()->setColor(color_.r, color_.g, color_.b);
playerSprite->render(); player_sprite_->render();
tvSprite->getTexture()->setColor(color.r, color.g, color.b); tv_sprite_->getTexture()->setColor(color_.r, color_.g, color_.b);
tvSprite->render(); tv_sprite_->render();
} }
// Actualiza los contadores // Actualiza los contadores
void GameOver::updateCounters() void GameOver::updateCounters()
{ {
// Actualiza el contador // Actualiza el contador
if (preCounter < 50) if (pre_counter_ < 50)
{ {
preCounter++; pre_counter_++;
} }
else else
{ {
counter++; counter_++;
} }
// Hace sonar la música // Hace sonar la música
if (counter == 1) if (counter_ == 1)
{ {
JA_PlayMusic(music, 0); JA_PlayMusic(music_, 0);
} }
// Comprueba si ha terminado la sección // Comprueba si ha terminado la sección
else if (counter == endSection) else if (counter_ == COUNTER_SECTION_END_)
{ {
options.section.name = SECTION_LOGO; options.section.section = Section::LOGO;
options.section.subsection = SUBSECTION_LOGO_TO_TITLE; options.section.subsection = Subsection::LOGO_TO_TITLE;
} }
} }
// Cambia la paleta
void GameOver::switchPalette()
{
options.palette = (options.palette == p_zxspectrum) ? p_zxarne : p_zxspectrum;
}

View File

@@ -1,42 +1,43 @@
#pragma once #pragma once
#include <SDL2/SDL_events.h> // Para SDL_Event #include <SDL2/SDL_render.h> // for SDL_Renderer
#include <SDL2/SDL_render.h> // Para SDL_Renderer #include <SDL2/SDL_stdinc.h> // for Uint32
#include <SDL2/SDL_stdinc.h> // Para Uint32 #include <memory> // for shared_ptr
#include <vector> // Para vector #include <vector> // for vector
#include "utils.h" // Para color_t #include "utils.h" // for Color
class AnimatedSprite; class AnimatedSprite; // lines 9-9
class Asset; class Asset; // lines 10-10
class Input; class Input; // lines 11-11
class Resource; class Resource; // lines 12-12
class Screen; class Screen; // lines 13-13
class Text; class Text; // lines 14-14
struct JA_Music_t; struct JA_Music_t; // lines 15-15
class GameOver class GameOver
{ {
private: private:
// Constantes
static constexpr int COUNTER_SECTION_END_ = 400; // Contador: cuando acaba la sección
static constexpr int COUNTER_INIT_FADE_ = 310; // Contador: cuando emiepza el fade
static constexpr int COUNTER_FADE_LENGHT_ = 20; // Contador: duración del fade
// Objetos y punteros // Objetos y punteros
Screen *screen; // Objeto encargado de dibujar en pantalla Screen *screen_; // Objeto encargado de dibujar en pantalla
SDL_Renderer *renderer; // El renderizador de la ventana SDL_Renderer *renderer_; // El renderizador de la ventana
Resource *resource; // Objeto con los recursos Resource *resource_; // Objeto con los recursos
Asset *asset; // Objeto con los ficheros de recursos Asset *asset_; // Objeto con los ficheros de recursos
Input *input; // Objeto pata gestionar la entrada Input *input_; // Objeto pata gestionar la entrada
Text *text; // Objeto para escribir texto en pantalla std::shared_ptr<Text> text_; // Objeto para escribir texto en pantalla
AnimatedSprite *playerSprite; // Sprite con el jugador std::shared_ptr<AnimatedSprite> player_sprite_; // Sprite con el jugador
AnimatedSprite *tvSprite; // Sprite con el televisor std::shared_ptr<AnimatedSprite> tv_sprite_; // Sprite con el televisor
// Variables // Variables
int preCounter; // Contador previo int pre_counter_ = 0; // Contador previo
int counter; // Contador int counter_ = 0; // Contador
Uint32 ticks; // Contador de ticks para ajustar la velocidad del programa Uint32 ticks_ = 0; // Contador de ticks para ajustar la velocidad del programa
Uint32 ticksSpeed; // Velocidad a la que se repiten los bucles del programa std::vector<Color> colors_; // Vector con los colores para el fade
std::vector<color_t> colors; // Vector con los colores para el fade Color color_; // Color usado para el texto y los sprites
color_t color; // Color usado para el texto y los sprites JA_Music_t *music_; // Musica que suena durante el juego
int endSection; // Contador: cuando acaba la sección
int iniFade; // Contador: cuando emiepza el fade
int fadeLenght; // Contador: duración del fade
JA_Music_t *music; // Musica que suena durante el juego
// Actualiza el objeto // Actualiza el objeto
void update(); void update();
@@ -59,15 +60,12 @@ private:
// Actualiza los contadores // Actualiza los contadores
void updateCounters(); void updateCounters();
// Cambia la paleta
void switchPalette();
public: public:
// Constructor // Constructor
GameOver(); GameOver();
// Destructor // Destructor
~GameOver(); ~GameOver() = default;
// Bucle principal // Bucle principal
void run(); void run();

View File

@@ -1,94 +1,9 @@
#include "gif.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <fcntl.h> #include <fcntl.h>
#define EXTENSION_INTRODUCER 0x21
#define IMAGE_DESCRIPTOR 0x2C
#define TRAILER 0x3B
#define GRAPHIC_CONTROL 0xF9
#define APPLICATION_EXTENSION 0xFF
#define COMMENT_EXTENSION 0xFE
#define PLAINTEXT_EXTENSION 0x01
#define READ(dst, size) memcpy(dst, buffer, size); buffer += size
typedef struct
{
unsigned short width;
unsigned short height;
unsigned char fields;
unsigned char background_color_index;
unsigned char pixel_aspect_ratio;
}
screen_descriptor_t;
typedef struct
{
unsigned char r;
unsigned char g;
unsigned char b;
}
rgb;
typedef struct
{
unsigned short image_left_position;
unsigned short image_top_position;
unsigned short image_width;
unsigned short image_height;
unsigned char fields;
}
image_descriptor_t;
typedef struct
{
unsigned char byte;
int prev;
int len;
}
dictionary_entry_t;
typedef struct
{
unsigned char extension_code;
unsigned char block_size;
}
extension_t;
typedef struct
{
unsigned char fields;
unsigned short delay_time;
unsigned char transparent_color_index;
}
graphic_control_extension_t;
typedef struct
{
unsigned char application_id[ 8 ];
unsigned char version[ 3 ];
}
application_extension_t;
typedef struct
{
unsigned short left;
unsigned short top;
unsigned short width;
unsigned short height;
unsigned char cell_width;
unsigned char cell_height;
unsigned char foreground_color;
unsigned char background_color;
}
plaintext_extension_t;
//static unsigned short width = 0;
//static unsigned short height = 0;
//static unsigned char* uncompressed_data = NULL;
void uncompress( int code_length, void uncompress( int code_length,
const unsigned char *input, const unsigned char *input,
int input_length, int input_length,

65
source/gif.h Normal file
View File

@@ -0,0 +1,65 @@
#pragma once
#include <stdint.h>
#define EXTENSION_INTRODUCER 0x21
#define IMAGE_DESCRIPTOR 0x2C
#define TRAILER 0x3B
#define GRAPHIC_CONTROL 0xF9
#define APPLICATION_EXTENSION 0xFF
#define COMMENT_EXTENSION 0xFE
#define PLAINTEXT_EXTENSION 0x01
#define READ(dst, size) memcpy(dst, buffer, size); buffer += size
typedef struct {
unsigned short width;
unsigned short height;
unsigned char fields;
unsigned char background_color_index;
unsigned char pixel_aspect_ratio;
} screen_descriptor_t;
typedef struct {
unsigned char r, g, b;
} rgb;
typedef struct {
unsigned short image_left_position;
unsigned short image_top_position;
unsigned short image_width;
unsigned short image_height;
unsigned char fields;
} image_descriptor_t;
typedef struct {
unsigned char byte;
int prev;
int len;
} dictionary_entry_t;
typedef struct {
unsigned char extension_code;
unsigned char block_size;
} extension_t;
typedef struct {
unsigned char fields;
unsigned short delay_time;
unsigned char transparent_color_index;
} graphic_control_extension_t;
typedef struct {
unsigned char application_id[8];
unsigned char version[3];
} application_extension_t;
typedef struct {
unsigned short left, top, width, height;
unsigned char cell_width, cell_height;
unsigned char foreground_color, background_color;
} plaintext_extension_t;
void uncompress(int code_length, const unsigned char *input, int input_length, unsigned char *out);
uint32_t* LoadPalette(unsigned char *buffer);
unsigned char* LoadGif(unsigned char *buffer, unsigned short* w, unsigned short* h);

24
source/global_events.cpp Normal file
View File

@@ -0,0 +1,24 @@
#include "global_events.h"
#include "options.h" // Para Options, options, OptionsGame, OptionsAudio
#include "mouse.h"
namespace globalEvents
{
// Comprueba los eventos que se pueden producir en cualquier sección del juego
void check(const SDL_Event &event)
{
// Evento de salida de la aplicación
if (event.type == SDL_QUIT)
{
options.section.section = Section::QUIT;
return;
}
if (event.type == SDL_RENDER_DEVICE_RESET || event.type == SDL_RENDER_TARGETS_RESET)
{
// reLoadTextures();
}
Mouse::handleEvent(event);
}
}

9
source/global_events.h Normal file
View File

@@ -0,0 +1,9 @@
#pragma once
#include <SDL2/SDL_events.h>
namespace globalEvents
{
// Comprueba los eventos que se pueden producir en cualquier sección del juego
void check(const SDL_Event &event);
}

107
source/global_inputs.cpp Normal file
View File

@@ -0,0 +1,107 @@
#include "global_inputs.h"
#include <string> // for basic_string
#include <vector> // for vector
#include "input.h" // for Input, REPEAT_FALSE, inputs_e
#include "notifier.h" // for Notifier
#include "options.h" // for Section, Options, options, SectionState, Optio...
#include "screen.h" // for Screen
#include "utils.h" // for Palette
namespace globalInputs
{
void quit()
{
const std::string code = options.section.section == Section::GAME ? "PRESS AGAIN TO RETURN TO MENU" : "PRESS AGAIN TO EXIT";
auto code_found = stringInVector(Notifier::get()->getCodes(), code);
if (code_found)
{
// Si la notificación de salir está activa, cambia de sección
options.section.section = options.section.section == Section::GAME ? Section::TITLE : Section::QUIT;
}
else
{
// Si la notificación de salir no está activa, muestra la notificación
Notifier::get()->show({code}, NotificationText::CENTER, -1, true, code);
}
}
// Cambia la paleta de colores
void switchPalette()
{
options.video.palette = options.video.palette == Palette::ZXSPECTRUM ? Palette::ZXARNE : Palette::ZXSPECTRUM;
}
// Cambia de seccion
void skip_section()
{
switch (options.section.section)
{
case Section::LOGO:
case Section::LOADING_SCREEN:
case Section::CREDITS:
case Section::DEMO:
case Section::GAME_OVER:
case Section::ENDING:
case Section::ENDING2:
options.section.section = Section::TITLE;
options.section.subsection = Subsection::NONE;
break;
default:
break;
}
}
// Comprueba los inputs que se pueden introducir en cualquier sección del juego
void check()
{
if (Input::get()->checkInput(input_exit, REPEAT_FALSE))
{
quit();
}
else if (Input::get()->checkInput(input_accept, REPEAT_FALSE))
{
skip_section();
}
else if (Input::get()->checkInput(input_toggle_border, REPEAT_FALSE))
{
Screen::get()->toggleBorder();
Notifier::get()->show({"BORDER " + std::string(options.video.border.enabled ? "ENABLED" : "DISABLED")}, NotificationText::CENTER);
}
else if (Input::get()->checkInput(input_toggle_videomode, REPEAT_FALSE))
{
Screen::get()->toggleVideoMode();
Notifier::get()->show({"FULLSCREEN " + std::string(options.video.mode == 0 ? "DISABLED" : "ENABLED")}, NotificationText::CENTER);
}
else if (Input::get()->checkInput(input_window_dec_size, REPEAT_FALSE))
{
if (Screen::get()->decWindowZoom())
{
Notifier::get()->show({"WINDOW ZOOM x" + std::to_string(options.window.zoom)}, NotificationText::CENTER);
}
}
else if (Input::get()->checkInput(input_window_inc_size, REPEAT_FALSE))
{
if (Screen::get()->incWindowZoom())
{
Notifier::get()->show({"WINDOW ZOOM x" + std::to_string(options.window.zoom)}, NotificationText::CENTER);
}
}
else if (Input::get()->checkInput(input_toggle_shaders, REPEAT_FALSE))
{
Screen::get()->toggleShaders();
Notifier::get()->show({"SHADERS " + std::string(options.video.shaders ? "ENABLED" : "DISABLED")}, NotificationText::CENTER);
}
else if (Input::get()->checkInput(input_toggle_palette, REPEAT_FALSE))
{
switchPalette();
Notifier::get()->show({"PALETTE " + std::string(options.video.palette == Palette::ZXSPECTRUM ? "ZX SPECTRUM" : "ZX ARNE")}, NotificationText::CENTER);
}
}
}

7
source/global_inputs.h Normal file
View File

@@ -0,0 +1,7 @@
#pragma once
namespace globalInputs
{
// Comprueba los inputs que se pueden introducir en cualquier sección del juego
void check();
}

View File

@@ -76,9 +76,9 @@ private:
std::vector<std::string> controller_names_; // Vector con los nombres de los mandos std::vector<std::string> controller_names_; // Vector con los nombres de los mandos
int num_gamepads_; // Numero de mandos conectados int num_gamepads_; // Numero de mandos conectados
std::string db_path_; // Ruta al archivo gamecontrollerdb.txt std::string db_path_; // Ruta al archivo gamecontrollerdb.txt
bool verbose_ = true; // Indica si ha de mostrar mensajes bool verbose_ = true; // Indica si ha de mostrar mensajes
i_disable_e disabled_until_; // Tiempo que esta deshabilitado i_disable_e disabled_until_; // Tiempo que esta deshabilitado
bool enabled_ = true; // Indica si está habilitado bool enabled_ = true; // Indica si está habilitado
// Constructor // Constructor
explicit Input(const std::string &game_controller_db_path); explicit Input(const std::string &game_controller_db_path);

View File

@@ -1,82 +1,57 @@
#include "item.h" #include "item.h"
#include "resource.h"
#include "sprite.h" // Para Sprite #include "sprite.h" // Para Sprite
#include "texture.h" // Para Texture #include "texture.h" // Para Texture
// Constructor // Constructor
Item::Item(item_t item) Item::Item(ItemData item)
{ {
const int itemSize = 8; constexpr int ITEMSIZE = 8;
// Crea objetos; // Crea objetos;
sprite = new Sprite(item.x, item.y, itemSize, itemSize, item.texture, item.renderer); sprite_ = std::make_shared<Sprite>(Resource::get()->getTexture(item.tile_set_file), item.x, item.y, ITEMSIZE, ITEMSIZE);
// Inicia variables // Inicia variables
sprite->setSpriteClip((item.tile % 10) * itemSize, (item.tile / 10) * itemSize, itemSize, itemSize); sprite_->setClip((item.tile % 10) * ITEMSIZE, (item.tile / 10) * ITEMSIZE, ITEMSIZE, ITEMSIZE);
collider = sprite->getRect(); collider_ = sprite_->getRect();
colorChangeSpeed = 4; change_color_speed = 4;
counter = item.counter * colorChangeSpeed; counter_ = item.counter * change_color_speed;
// Inicializa los colores // Inicializa los colores
color_t c = item.color1; color_.push_back(item.color1);
color.push_back(c); color_.push_back(item.color1);
color.push_back(c);
c = item.color2; color_.push_back(item.color2);
color.push_back(c); color_.push_back(item.color2);
color.push_back(c);
}
// Destructor
Item::~Item()
{
delete sprite;
} }
// Pinta el objeto en pantalla // Pinta el objeto en pantalla
void Item::render() void Item::render()
{ {
const int index = (counter / colorChangeSpeed) % color.size(); const int index = (counter_ / change_color_speed) % color_.size();
sprite->getTexture()->setColor(color[index].r, color[index].g, color[index].b); sprite_->getTexture()->setColor(color_[index].r, color_[index].g, color_[index].b);
sprite->render(); sprite_->render();
sprite->getTexture()->setColor(255, 255, 255); sprite_->getTexture()->setColor(255, 255, 255);
}
// Actualiza las variables del objeto
void Item::update()
{
counter++;
}
// Obtiene el rectangulo de colision del objeto
SDL_Rect &Item::getCollider()
{
return collider;
} }
// Obtiene su ubicación // Obtiene su ubicación
SDL_Point Item::getPos() SDL_Point Item::getPos()
{ {
const SDL_Point p = {sprite->getPosX(), sprite->getPosY()}; const SDL_Point p = {sprite_->getX(), sprite_->getY()};
return p; return p;
} }
// Recarga la textura
void Item::reLoadTexture()
{
sprite->getTexture()->reLoad();
}
// Asigna los colores del objeto // Asigna los colores del objeto
void Item::setColors(color_t col1, color_t col2) void Item::setColors(Color col1, Color col2)
{ {
// Reinicializa el vector de colores // Reinicializa el vector de colores
color.clear(); color_.clear();
// Añade el primer color // Añade el primer color
color.push_back(col1); color_.push_back(col1);
color.push_back(col1); color_.push_back(col1);
// Añade el segundo color // Añade el segundo color
color.push_back(col2); color_.push_back(col2);
color.push_back(col2); color_.push_back(col2);
} }

View File

@@ -1,63 +1,62 @@
#pragma once #pragma once
#include <SDL2/SDL_rect.h> // Para SDL_Rect, SDL_Point #include <SDL2/SDL_rect.h> // for SDL_Rect, SDL_Point
#include <SDL2/SDL_render.h> // Para SDL_Renderer #include <SDL2/SDL_render.h> // for SDL_Renderer
#include <string> // Para basic_string, string #include <memory> // for shared_ptr, __shared_ptr_access
#include <vector> // Para vector #include <string> // for string
#include "utils.h" // Para color_t #include <vector> // for vector
class Sprite; #include "sprite.h" // for Sprite
class Texture; #include "texture.h" // for Texture
#include "utils.h" // for Color
struct item_t struct ItemData
{ {
SDL_Renderer *renderer; // El renderizador de la ventana std::string tile_set_file; // Ruta al fichero con los gráficos del item
Texture *texture; // Textura con los gráficos del item int x; // Posición del item en pantalla
std::string tileSetFile; // Ruta al fichero con los gráficos del item int y; // Posición del item en pantalla
int x; // Posición del item en pantalla int tile; // Número de tile dentro de la textura
int y; // Posición del item en pantalla int counter; // Contador inicial. Es el que lo hace cambiar de color
int tile; // Número de tile dentro de la textura Color color1; // Uno de los dos colores que se utiliza para el item
int counter; // Contador inicial. Es el que lo hace cambiar de color Color color2; // Uno de los dos colores que se utiliza para el item
color_t color1; // Uno de los dos colores que se utiliza para el item
color_t color2; // Uno de los dos colores que se utiliza para el item
// Constructor por defecto // Constructor
item_t() : renderer(nullptr), texture(nullptr), x(0), y(0), tile(0), counter(0), color1(), color2() {} ItemData() : x(0), y(0), tile(0), counter(0), color1(), color2() {}
}; };
class Item class Item
{ {
private: private:
// Objetos y punteros // Objetos y punteros
Sprite *sprite; // Sprite del objeto std::shared_ptr<Sprite> sprite_; // Sprite del objeto
// Variables // Variables
std::vector<color_t> color; // Vector con los colores del objeto std::vector<Color> color_; // Vector con los colores del objeto
int counter; // Contador interno int counter_; // Contador interno
SDL_Rect collider; // Rectangulo de colisión SDL_Rect collider_; // Rectangulo de colisión
int colorChangeSpeed; // Cuanto mas alto, mas tarda en cambiar de color int change_color_speed; // Cuanto mas alto, mas tarda en cambiar de color
public: public:
// Constructor // Constructor
Item(item_t item); Item(ItemData item);
// Destructor // Destructor
~Item(); ~Item() = default;
// Pinta el objeto en pantalla // Pinta el objeto en pantalla
void render(); void render();
// Actualiza las variables del objeto // Actualiza las variables del objeto
void update(); void update() { counter_++; }
// Obtiene el rectangulo de colision del objeto // Obtiene el rectangulo de colision del objeto
SDL_Rect &getCollider(); SDL_Rect &getCollider() { return collider_; }
// Obtiene su ubicación // Obtiene su ubicación
SDL_Point getPos(); SDL_Point getPos();
// Recarga la textura // Recarga la textura
void reLoadTexture(); void reLoadTexture() { sprite_->getTexture()->reLoad(); }
// Asigna los colores del objeto // Asigna los colores del objeto
void setColors(color_t col1, color_t col2); void setColors(Color col1, Color col2);
}; };

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