15 Commits

Author SHA1 Message Date
14f7a79927 Actualizar 'README.md' 2022-08-05 23:13:55 +02:00
4f6a6a4918 Actualizar 'Makefile' 2021-09-20 13:48:59 +02:00
f5b35cee6b Trabajando en la versión de opendingux 2021-09-17 20:55:36 +02:00
454791fe96 Añadidos modos en pantalla completa para el escalado entero y mantener la relación de aspecto 2021-09-15 11:48:57 +02:00
3f165be114 Commit para seguir en otro ordenador 2021-09-15 06:37:54 +02:00
778672a6f5 Commit para seguir en otro ordenador 2021-09-14 22:52:25 +02:00
8c919abc9d Trabajando en el escalado entero y el tamaño personalizable de la ventana de renderizado a traves de las opciones 2021-09-14 21:15:52 +02:00
7e37da3999 Restituido ballong.png a los colores originales 2021-09-14 17:03:13 +02:00
842d5dd56b Limpieza de código 2021-09-11 09:06:53 +02:00
ea3f16b8ac Añadida la clase screen al código 2021-09-10 23:52:58 +02:00
3fe0861e4f Trabajando en integrar la clase screen 2021-09-10 23:04:52 +02:00
b28d798545 Actualizado el numero de versión 2021-09-10 20:55:46 +02:00
bdf092d46e Limpieza de código. Modificada la fuente nokiabig2. Puestas ayudas para los dos jugadores. Cambiado el tamaño del mensaje de juego completado 2021-09-10 20:46:24 +02:00
09421a093d Limpieza de código 2021-09-10 14:02:29 +02:00
a7d7cdd047 Modificados los graficos de los globos y del jugador 1. Rebajada la dificultad de las últimas pantallas descendiendo el nivel de amenaza 2021-09-10 10:55:01 +02:00
46 changed files with 798 additions and 790 deletions

View File

@@ -6,4 +6,8 @@ macos:
linux:
mkdir -p bin
g++ source/*.cpp -std=c++11 -Os -lSDL2 -ffunction-sections -fdata-sections -Wl,--gc-sections -o bin/$(executable)_linux
strip -s -R .comment -R .gnu.version bin/$(executable)_linux --strip-unneeded
strip -s -R .comment -R .gnu.version bin/$(executable)_linux --strip-unneeded
opendingux:
mkdir -p bin
/opt/gcw0-toolchain/usr/bin/mipsel-linux-gcc -D GCWZERO -O2 -std=c++11 -I/opt/gcw0-toolchain/usr/mipsel-gcw0-linux-uclibc/sysroot/usr/include/SDL2 -D_GNU_SOURCE=1 -D_REENTRANT -lSDL2 -lSDL2_mixer -lstdc++ source/*.cpp -o bin/$(executable)_opendingux
/opt/gcw0-toolchain/usr/bin/mksquashfs ./default.gcw0.desktop ./icon.png ./bin ./data ./media coffee_crisis.opk -all-root -noappend -no-exports -no-xattrs

View File

@@ -1,6 +1,6 @@
# Coffee Crisis
Coffe Crisis es un juego arcade que pondrá a prueba tus reflejos. Empezado el verano de 2020 y terminado el verano de 2021. Intenta conseguir todos los puntos que puedas con una sola vida y ayuda a Bal1 a defender la UPV ante la invasión de la cafeína durante 10 estresantes oleadas.
Coffe Crisis es un juego arcade que pondrá a prueba tus reflejos. Empezado durante el verano de 2020 y terminado un año despues, en el verano de 2021. Intenta conseguir todos los puntos que puedas con una sola vida a traves de los 10 nievels de juego y ayuda a Bal1 a defender la UPV de la invasión de la cafeína esférica y saltarina.
## Compilar

9
default.gcw0.desktop Normal file
View File

@@ -0,0 +1,9 @@
[Desktop Entry]
Version=1.0
Type=Application
Name=Coffee Crisis
Comment=Coffee Crisis
Icon=icon
Exec=bin/coffee_crisis_opendingux
Categories=games;Game;SDL;
Terminal=false

BIN
icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.6 KiB

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.0 KiB

After

Width:  |  Height:  |  Size: 6.9 KiB

View File

@@ -4,13 +4,11 @@
// Constructor
AnimatedSprite::AnimatedSprite()
{
//init(nullptr, nullptr);
}
// Destructor
AnimatedSprite::~AnimatedSprite()
{
//init(nullptr, nullptr);
}
// Iniciador
@@ -41,10 +39,10 @@ void AnimatedSprite::animate(int index)
{
if (mEnabled)
{
// Calculamos el frame actual a partir del contador
// Calcula el frame actual a partir del contador
mCurrentFrame = mAnimationCounter / mAnimation[index].speed;
// Si alcanzamos el final de la animación, reiniciamos el contador de la animación
// Si alcanza el final de la animación, reinicia el contador de la animación
// en función de la variable loop
if (mCurrentFrame >= mAnimation[index].numFrames)
{
@@ -56,10 +54,10 @@ void AnimatedSprite::animate(int index)
// En caso contrario
else
{
// Escogemos el frame correspondiente de la animación
// Escoge el frame correspondiente de la animación
setSpriteClip(mAnimation[index].frames[mCurrentFrame]);
// Incrementamos el contador de la animacion
// Incrementa el contador de la animacion
mAnimationCounter++;
}
}

View File

@@ -351,13 +351,16 @@ void Balloon::init(float x, float y, Uint8 kind, float velx, float speed, Uint16
mPosX = x;
mPosY = y;
mBouncing.enabled = false; // Si el efecto está activo
mBouncing.counter = 0; // Countador para el efecto
mBouncing.speed = 0; // Velocidad a la que transcurre el efecto
mBouncing.zoomW = 1.0f; // Zoom aplicado a la anchura
mBouncing.zoomH = 1.0f; // Zoom aplicado a la altura
mBouncing.despX = 0.0f; // Desplazamiento de pixeles en el eje X antes de pintar el objeto con zoom
// Valores para el efecto de rebote
mBouncing.enabled = false;
mBouncing.counter = 0;
mBouncing.speed = 0;
mBouncing.zoomW = 1.0f;
mBouncing.zoomH = 1.0f;
mBouncing.despX = 0.0f;
mBouncing.despY = 0.0f;
mBouncing.w = {1.10f, 1.05f, 1.00f, 0.95f, 0.90f, 0.95f, 1.00f, 1.02f, 1.05f, 1.02f};
mBouncing.h = {0.90f, 0.95f, 1.00f, 1.05f, 1.10f, 1.05f, 1.00f, 0.98f, 0.95f, 0.98f};
// Textura con los gráficos del sprite
mSprite->setTexture(texture);
@@ -432,13 +435,9 @@ void Balloon::allignTo(int x)
mPosX = float(x - (mWidth / 2));
if (mPosX < PLAY_AREA_LEFT)
{
mPosX = PLAY_AREA_LEFT + 1;
}
else if ((mPosX + mWidth) > PLAY_AREA_RIGHT)
{
mPosX = float(PLAY_AREA_RIGHT - mWidth - 1);
}
// Posición X,Y del sprite
mSprite->setPosX(getPosX());
@@ -531,10 +530,12 @@ void Balloon::move()
}
/*
Para aplicar la gravedad, el diseño original la aplicaba en cada iteración del bucle
Al añadir el modificador de velocidad se reduce la distancia que recorre el objeto y por
tanto recibe mas gravedad. Para solucionarlo se va a aplicar la gravedad cuando se haya
recorrido una distancia igual a la velocidad en Y, que era el cálculo inicial
*/
// Incrementa la variable que calcula la distancia acumulada en Y
@@ -550,11 +551,6 @@ void Balloon::move()
mVelY += mGravity;
std::min(mVelY, mMaxVelY);
}
// Aplica la gravedad al objeto
//if (mVelY > mMaxVelY)
// mVelY = mMaxVelY;
//else if (mCounter % 1 == 0)
// mVelY += mGravity;
// Actualiza la posición del sprite
mSprite->setPosX(getPosX());
@@ -603,7 +599,7 @@ void Balloon::disable()
void Balloon::pop()
{
setPopping(true);
mSprite->setAnimationCounter(0);
mSprite->setAnimationCounter(0);
mSprite->disableRotate();
setTimeToLive(120);
setStop(true);
@@ -679,12 +675,6 @@ void Balloon::updateState()
updateColliders();
}
// Hace visible el globo de forma intermitente
//if (mCreationCounter > 100)
// setVisible(mCreationCounter / 10 % 2 == 0);
//else
// setVisible(mCreationCounter / 5 % 2 == 0);
mCreationCounter--;
}
// El contador ha llegado a cero
@@ -711,7 +701,8 @@ void Balloon::updateState()
if (mStoppedCounter > 0)
mStoppedCounter--;
// Si el contador ha llegado a cero, ya no está detenido
else if (!isPopping()) // Quitarles el estado "detenido" si no estan explosionandoxq
else if (!isPopping())
// Quitarles el estado "detenido" si no estan explosionando
setStop(false);
}
}
@@ -910,7 +901,6 @@ circle_t &Balloon::getCollider()
// Alinea el circulo de colisión con la posición del objeto globo
void Balloon::updateColliders()
{
// Align collider to center of balloon
mCollider.x = Uint16(mPosX + mCollider.r);
mCollider.y = mPosY + mCollider.r;
}
@@ -940,6 +930,7 @@ void Balloon::bounceStart()
mBouncing.despX = 0;
mBouncing.despY = 0;
}
void Balloon::bounceStop()
{
mBouncing.enabled = false;
@@ -951,6 +942,7 @@ void Balloon::bounceStop()
mBouncing.despX = 0.0f;
mBouncing.despY = 0.0f;
}
void Balloon::updateBounce()
{
if (mBouncing.enabled)

View File

@@ -1,13 +1,71 @@
#pragma once
#include "utils.h"
#include "animatedsprite.h"
#include <vector>
#ifndef BALLOON_H
#define BALLOON_H
// Cantidad de elementos del vector con los valores de la deformación del globo al rebotar
#define MAX_BOUNCE 10
// Clase globo
// Tipos de globo
#define BALLOON_1 1
#define BALLOON_2 2
#define BALLOON_3 3
#define BALLOON_4 4
#define HEXAGON_1 5
#define HEXAGON_2 6
#define HEXAGON_3 7
#define HEXAGON_4 8
#define POWER_BALL 9
// Puntos de globo
#define BALLOON_SCORE_1 50
#define BALLOON_SCORE_2 100
#define BALLOON_SCORE_3 200
#define BALLOON_SCORE_4 400
// Tamaños de globo
#define BALLOON_SIZE_1 1
#define BALLOON_SIZE_2 2
#define BALLOON_SIZE_3 3
#define BALLOON_SIZE_4 4
// Clases de globo
#define BALLOON_CLASS 0
#define HEXAGON_CLASS 1
// Velocidad del globo
#define BALLOON_VELX_POSITIVE 0.7f
#define BALLOON_VELX_NEGATIVE -0.7f
// Indice para las animaciones de los globos
#define BALLOON_MOVING_ANIMATION 0
#define BALLOON_POP_ANIMATION 1
#define BALLOON_BORN_ANIMATION 2
// Cantidad posible de globos
#define MAX_BALLOONS 100
// Velocidades a las que se mueven los globos
#define BALLOON_SPEED_1 0.60f
#define BALLOON_SPEED_2 0.70f
#define BALLOON_SPEED_3 0.80f
#define BALLOON_SPEED_4 0.90f
#define BALLOON_SPEED_5 1.00f
// Tamaño de los globos
#define BALLOON_WIDTH_1 8
#define BALLOON_WIDTH_2 13
#define BALLOON_WIDTH_3 21
#define BALLOON_WIDTH_4 37
// PowerBall
#define POWERBALL_SCREENPOWER_MINIMUM 10
#define POWERBALL_COUNTER 8
// Clase Balloon
class Balloon
{
private:
@@ -44,17 +102,15 @@ private:
struct bouncing // Estructura para las variables para el efecto de los rebotes
{
bool enabled; // Si el efecto está activo
Uint8 counter; // Countador para el efecto
Uint8 speed; // Velocidad a la que transcurre el efecto
float zoomW; // Zoom aplicado a la anchura
float zoomH; // Zoom aplicado a la altura
float despX; // Desplazamiento de pixeles en el eje X antes de pintar el objeto con zoom
float despY; // Desplazamiento de pixeles en el eje Y antes de pintar el objeto con zoom
// Vector con los valores de zoom para el ancho y alto del globo
float w[MAX_BOUNCE] = {1.10f, 1.05f, 1.00f, 0.95f, 0.90f, 0.95f, 1.00f, 1.02f, 1.05f, 1.02f};
float h[MAX_BOUNCE] = {0.90f, 0.95f, 1.00f, 1.05f, 1.10f, 1.05f, 1.00f, 0.98f, 0.95f, 0.98f};
bool enabled; // Si el efecto está activo
Uint8 counter; // Countador para el efecto
Uint8 speed; // Velocidad a la que transcurre el efecto
float zoomW; // Zoom aplicado a la anchura
float zoomH; // Zoom aplicado a la altura
float despX; // Desplazamiento de pixeles en el eje X antes de pintar el objeto con zoom
float despY; // Desplazamiento de pixeles en el eje Y antes de pintar el objeto con zoom
std::vector<float> w; // Vector con los valores de zoom para el ancho del globo
std::vector<float> h; // Vector con los valores de zoom para el alto del globo
};
bouncing mBouncing;

View File

@@ -11,7 +11,6 @@ Bullet::Bullet()
// Destructor
Bullet::~Bullet()
{
//init(0, 0, NO_KIND, nullptr, nullptr);
delete mSprite;
mSprite = nullptr;
}
@@ -107,7 +106,7 @@ void Bullet::render()
Uint8 Bullet::move()
{
// Variable con el valor de retorno
Uint8 msg = MSG_OK;
Uint8 msg = BULLET_MOVE_OK;
// Mueve el objeto a su nueva posición
mPosX += mVelX;
@@ -119,7 +118,7 @@ Uint8 Bullet::move()
mKind = NO_KIND;
// Mensaje de salida
msg = MSG_BULLET_OUT;
msg = BULLET_MOVE_OUT;
}
// Mueve el objeto a su nueva posición en vertical
@@ -132,7 +131,7 @@ Uint8 Bullet::move()
mKind = NO_KIND;
// Mensaje de salida
msg = MSG_BULLET_OUT;
msg = BULLET_MOVE_OUT;
}
// Actualiza la posición del sprite
@@ -145,18 +144,6 @@ Uint8 Bullet::move()
return msg;
}
#ifdef TEST
void Bullet::testMove()
{
// Update sprite position
mSprite->setPosX(mPosX);
mSprite->setPosY(mPosY);
// Update circle colliders
shiftColliders();
}
#endif
// Deshabilita el objeto
void Bullet::erase()
{
@@ -167,13 +154,9 @@ void Bullet::erase()
bool Bullet::isActive()
{
if (mKind == NO_KIND)
{
return false;
}
else
{
return true;
}
}
// Obtiene el valor de la variable

View File

@@ -5,7 +5,16 @@
#ifndef BULLET_H
#define BULLET_H
// Clase bala
// Tipos de bala
#define BULLET_UP 1
#define BULLET_LEFT 2
#define BULLET_RIGHT 3
// Tipos de retorno de la funcion move de la bala
#define BULLET_MOVE_OK 0
#define BULLET_MOVE_OUT 1
// Clase Bullet
class Bullet
{
private:

View File

@@ -2,84 +2,25 @@
#include "ifdefs.h"
#include "utils.h"
#include "lang.h"
#include <string>
#ifndef CONST_H
#define CONST_H
// Textos
#define WINDOW_CAPTION "Coffee Crisis"
#define TEXT_COPYRIGHT "@2020,2021 JailDesigner (v2.0.1)"
// Recursos
#define BINFILE_SCORE 0
#define BINFILE_DEMO 1
#define BINFILE_CONFIG 2
#define TOTAL_BINFILE 3
#define MUSIC_INTRO 0
#define MUSIC_PLAYING 1
#define MUSIC_TITLE 2
#define TOTAL_MUSIC 3
#define SOUND_BALLOON 0
#define SOUND_BUBBLE1 1
#define SOUND_BUBBLE2 2
#define SOUND_BUBBLE3 3
#define SOUND_BUBBLE4 4
#define SOUND_BULLET 5
#define SOUND_COFFEE_OUT 6
#define SOUND_HISCORE 7
#define SOUND_ITEM_DROP 8
#define SOUND_ITEM_PICKUP 9
#define SOUND_MENU_CANCEL 10
#define SOUND_MENU_MOVE 11
#define SOUND_MENU_SELECT 12
#define SOUND_PLAYER_COLLISION 13
#define SOUND_STAGE_CHANGE 14
#define SOUND_TITLE 15
#define SOUND_CLOCK 16
#define SOUND_POWERBALL 17
#define TOTAL_SOUND 18
#define TEXTURE_BALLOON 0
#define TEXTURE_BULLET 1
#define TEXTURE_FONT_BLACK 2
#define TEXTURE_FONT_BLACK_X2 3
#define TEXTURE_FONT_NOKIA 4
#define TEXTURE_FONT_WHITE 5
#define TEXTURE_FONT_WHITE_X2 6
#define TEXTURE_GAME_BG 7
#define TEXTURE_GAME_TEXT 8
#define TEXTURE_INTRO 9
#define TEXTURE_ITEMS 10
#define TEXTURE_LOGO 11
#define TEXTURE_MENU 12
#define TEXTURE_PLAYER_BODY 13
#define TEXTURE_PLAYER_DEATH 14
#define TEXTURE_PLAYER_LEGS 15
#define TEXTURE_TITLE 16
#define TOTAL_TEXTURE 17
// Tamaño de bloque
#define BLOCK 8
#define HALF_BLOCK BLOCK / 2
// Tamaño de la pantalla real
// Tamaño de la pantalla que contendrá la pantalla de juego
//#define REAL_SCREEN_WIDTH 256
//#define REAL_SCREEN_HEIGHT 192
// Tamaño de la pantalla de juego
#define SCREEN_WIDTH 256
const int SCREEN_HEIGHT = SCREEN_WIDTH * 3 / 4;
#define SCREEN_HEIGHT 192
// Tamaño de la pantalla que se muestra
const int VIEW_WIDTH = SCREEN_WIDTH * 3;
const int VIEW_HEIGHT = SCREEN_HEIGHT * 3;
// Cantidad de enteros a escribir en los ficheros de datos
#define TOTAL_SCORE_DATA 3
#define TOTAL_DEMO_DATA 2000
//const int VIEW_WIDTH = REAL_SCREEN_WIDTH * 3;
//const int VIEW_HEIGHT = REAL_SCREEN_HEIGHT * 3;
// Zona de juego
const int PLAY_AREA_TOP = (0 * BLOCK);
@@ -103,48 +44,6 @@ const int SCREEN_CENTER_Y = SCREEN_HEIGHT / 2;
const int SCREEN_FIRST_QUARTER_Y = SCREEN_HEIGHT / 4;
const int SCREEN_THIRD_QUARTER_Y = (SCREEN_HEIGHT / 4) * 3;
// Opciones de menu
#define MENU_NO_OPTION -1
#define MENU_OPTION_START 0
#define MENU_OPTION_QUIT 1
#define MENU_OPTION_TOTAL 2
// Tipos de fondos para el menu
#define MENU_BACKGROUND_TRANSPARENT 0
#define MENU_BACKGROUND_SOLID 1
// Estados del jugador
#define PLAYER_STATUS_WALKING_LEFT 0
#define PLAYER_STATUS_WALKING_RIGHT 1
#define PLAYER_STATUS_WALKING_STOP 2
#define PLAYER_STATUS_FIRING_UP 0
#define PLAYER_STATUS_FIRING_LEFT 1
#define PLAYER_STATUS_FIRING_RIGHT 2
#define PLAYER_STATUS_FIRING_NO 3
#define PLAYER_ANIMATION_LEGS_WALKING_LEFT 0
#define PLAYER_ANIMATION_LEGS_WALKING_RIGHT 1
#define PLAYER_ANIMATION_LEGS_WALKING_STOP 2
#define PLAYER_ANIMATION_BODY_WALKING_LEFT 0
#define PLAYER_ANIMATION_BODY_FIRING_LEFT 1
#define PLAYER_ANIMATION_BODY_WALKING_RIGHT 2
#define PLAYER_ANIMATION_BODY_FIRING_RIGHT 3
#define PLAYER_ANIMATION_BODY_WALKING_STOP 4
#define PLAYER_ANIMATION_BODY_FIRING_UP 5
#define PLAYER_ANIMATION_HEAD_WALKING_LEFT 0
#define PLAYER_ANIMATION_HEAD_FIRING_LEFT 1
#define PLAYER_ANIMATION_HEAD_WALKING_RIGHT 2
#define PLAYER_ANIMATION_HEAD_FIRING_RIGHT 3
#define PLAYER_ANIMATION_HEAD_WALKING_STOP 4
#define PLAYER_ANIMATION_HEAD_FIRING_UP 5
// Variables del jugador
#define PLAYER_INVULNERABLE_COUNTER 200
#define PLAYER_POWERUP_COUNTER 1500
// Secciones del programa
#define PROG_SECTION_LOGO 0
#define PROG_SECTION_INTRO 1
@@ -162,197 +61,17 @@ const int SCREEN_THIRD_QUARTER_Y = (SCREEN_HEIGHT / 4) * 3;
#define TITLE_SECTION_3 5
#define TITLE_SECTION_INSTRUCTIONS 6
// Modo para las instrucciones
#define INSTRUCTIONS_MODE_MANUAL 0
#define INSTRUCTIONS_MODE_AUTO 1
// Estados de cada elemento que pertenece a un evento
#define EVENT_WAITING 1
#define EVENT_RUNNING 2
#define EVENT_COMPLETED 3
// Cantidad de eventos de la intro
#define INTRO_TOTAL_BITMAPS 6
#define INTRO_TOTAL_TEXTS 9
const int INTRO_TOTAL_EVENTS = INTRO_TOTAL_BITMAPS + INTRO_TOTAL_TEXTS;
// Cantidad de eventos de la pantalla de titulo
#define TITLE_TOTAL_EVENTS 2
// Relaciones de Id con nomnbres
#define BITMAP0 0
#define BITMAP1 1
#define BITMAP2 2
#define BITMAP3 3
#define BITMAP4 4
#define BITMAP5 5
#define TEXT0 6
#define TEXT1 7
#define TEXT2 8
#define TEXT3 9
#define TEXT4 10
#define TEXT5 11
#define TEXT6 12
#define TEXT7 13
#define TEXT8 14
// Anclajes para el marcador de puntos
const int SCORE_WORD_X = (SCREEN_WIDTH / 4) - ((5 * BLOCK) / 2);
const int SCORE_WORD_Y = SCREEN_HEIGHT - (3 * BLOCK) + 2;
const int SCORE_NUMBER_X = (SCREEN_WIDTH / 4) - ((6 * BLOCK) / 2);
const int SCORE_NUMBER_Y = SCREEN_HEIGHT - (2 * BLOCK) + 2;
const int HISCORE_WORD_X = ((SCREEN_WIDTH / 4) * 3) - ((8 * BLOCK) / 2);
const int HISCORE_WORD_Y = SCREEN_HEIGHT - (3 * BLOCK) + 2;
const int HISCORE_NUMBER_X = ((SCREEN_WIDTH / 4) * 3) - ((6 * BLOCK) / 2);
const int HISCORE_NUMBER_Y = SCREEN_HEIGHT - (2 * BLOCK) + 2;
const int MULTIPLIER_WORD_X = (SCREEN_WIDTH / 2) - ((4 * BLOCK) / 2);
const int MULTIPLIER_WORD_Y = SCREEN_HEIGHT - (3 * BLOCK) + 2;
const int MULTIPLIER_NUMBER_X = (SCREEN_WIDTH / 2) - ((3 * BLOCK) / 2);
const int MULTIPLIER_NUMBER_Y = SCREEN_HEIGHT - (2 * BLOCK) + 2;
// Ningun tipo
#define NO_KIND 0
// Tipos de globo
#define BALLOON_1 1
#define BALLOON_2 2
#define BALLOON_3 3
#define BALLOON_4 4
#define HEXAGON_1 5
#define HEXAGON_2 6
#define HEXAGON_3 7
#define HEXAGON_4 8
#define POWER_BALL 9
// Puntos de globo
#define BALLOON_SCORE_1 50
#define BALLOON_SCORE_2 100
#define BALLOON_SCORE_3 200
#define BALLOON_SCORE_4 400
// Tamaños de globo
#define BALLOON_SIZE_1 1
#define BALLOON_SIZE_2 2
#define BALLOON_SIZE_3 3
#define BALLOON_SIZE_4 4
// Clases de globo
#define BALLOON_CLASS 0
#define HEXAGON_CLASS 1
// Velocidad del globo
#define BALLOON_VELX_POSITIVE 0.7f
#define BALLOON_VELX_NEGATIVE -0.7f
// Indice para las animaciones de los globos
#define BALLOON_MOVING_ANIMATION 0
#define BALLOON_POP_ANIMATION 1
#define BALLOON_BORN_ANIMATION 2
// Cantidad posible de globos
#define MAX_BALLOONS 100
// Velocidades a las que se mueven los enemigos
#define BALLOON_SPEED_1 0.60f
#define BALLOON_SPEED_2 0.70f
#define BALLOON_SPEED_3 0.80f
#define BALLOON_SPEED_4 0.90f
#define BALLOON_SPEED_5 1.00f
// Tamaño de los globos
#define BALLOON_WIDTH_1 8
#define BALLOON_WIDTH_2 13
#define BALLOON_WIDTH_3 21
#define BALLOON_WIDTH_4 37
// PowerBall
#define POWERBALL_SCREENPOWER_MINIMUM 10
#define POWERBALL_COUNTER 8
// Tipos de bala
#define BULLET_UP 1
#define BULLET_LEFT 2
#define BULLET_RIGHT 3
// Cantidad posible de globos
#define MAX_BULLETS 50
// Tipos de objetos
#define ITEM_POINTS_1_DISK 1
#define ITEM_POINTS_2_GAVINA 2
#define ITEM_POINTS_3_PACMAR 3
#define ITEM_CLOCK 4
#define ITEM_COFFEE 5
#define ITEM_POWER_BALL 6
#define ITEM_COFFEE_MACHINE 7
// Porcentaje de aparición de los objetos
#define ITEM_POINTS_1_DISK_ODDS 10
#define ITEM_POINTS_2_GAVINA_ODDS 6
#define ITEM_POINTS_3_PACMAR_ODDS 3
#define ITEM_CLOCK_ODDS 5
#define ITEM_COFFEE_ODDS 5
#define ITEM_POWER_BALL_ODDS 0
#define ITEM_COFFEE_MACHINE_ODDS 4
// Cantidad de objetos simultaneos
#define MAX_ITEMS 10
// Valores para las variables asociadas a los objetos
#define REMAINING_EXPLOSIONS 3
#define REMAINING_EXPLOSIONS_COUNTER 50
#define TIME_STOPPED_COUNTER 300
// Estados de entrada
#define NO_INPUT 0
#define INPUT_FIRE_LEFT 7
#define INPUT_FIRE_UP 8
#define INPUT_FIRE_RIGHT 9
#define INPUT_PAUSE 10
// Zona muerta del mando analógico
#define JOYSTICK_DEAD_ZONE 8000
// Tipos de mensajes para el retorno de las funciones
#define MSG_OK 0
#define MSG_BULLET_OUT 1
// Tipos de texto
#define TEXT_FIXED 0
#define TEXT_VARIABLE 1
// Cantidad de elementos del vector de SmartSprites
#define MAX_SMART_SPRITES 10
// Cantidad máxima de gotas de café
#define MAX_COFFEE_DROPS 100
// Contadores
#define TITLE_COUNTER 800
#define STAGE_COUNTER 200
#define INSTRUCTIONS_COUNTER 600
#define DEATH_COUNTER 350
#define SHAKE_COUNTER 10
#define HELP_COUNTER 1000
// Colores
const color_t bgColor = {0x27, 0x27, 0x36};
const color_t noColor = {0xFF, 0xFF, 0xFF};
const color_t shdwTxtColor = {0x43, 0x43, 0x4F};
// Formaciones enemigas
#define NUMBER_OF_ENEMY_FORMATIONS 100
#define MAX_NUMBER_OF_ENEMIES_IN_A_FORMATION 50
// Dificultad del juego
#define DIFFICULTY_EASY 0
#define DIFFICULTY_NORMAL 1
#define DIFFICULTY_HARD 2
// Tipo de filtro
#define FILTER_NEAREST 0
#define FILTER_LINEAL 1
#endif

View File

@@ -22,22 +22,26 @@ Director::Director(std::string path)
if (!checkFileList())
section = PROG_SECTION_QUIT;
// Inicializa el objeto de idioma
// Crea el objeto de idioma
mLang = new Lang(mFileList);
// Crea el puntero a la estructura y carga el fichero de configuración
mOptions = new options_t;
if (!loadConfigFile())
{
mOptions->fullScreenMode = 0;
mOptions->windowSize = 3;
mOptions->language = en_UK;
mOptions->difficulty = DIFFICULTY_NORMAL;
mOptions->input[0].deviceType = INPUT_USE_KEYBOARD;
mOptions->input[1].deviceType = INPUT_USE_GAMECONTROLLER;
mOptions->filter = FILTER_NEAREST;
mOptions->vSync = true;
}
loadConfigFile();
//if (!loadConfigFile())
//{
// mOptions->fullScreenMode = 0;
// mOptions->windowSize = 3;
// mOptions->language = en_UK;
// mOptions->difficulty = DIFFICULTY_NORMAL;
// mOptions->input[0].deviceType = INPUT_USE_KEYBOARD;
// mOptions->input[1].deviceType = INPUT_USE_GAMECONTROLLER;
// mOptions->filter = FILTER_NEAREST;
// mOptions->vSync = true;
// mOptions->screenHeight = SCREEN_HEIGHT;
// mOptions->screenWidth = SCREEN_WIDTH;
// mOptions->integerScale = true;
//}
// Crea los objetos
mInput = new Input(mFileList[53]);
@@ -45,14 +49,18 @@ Director::Director(std::string path)
// Inicializa SDL
initSDL();
// Crea el objeto para dibujar en pantalla (Requiere initSDL)
mScreen = new Screen(mWindow, mRenderer, mOptions);
// Inicializa JailAudio
initJailAudio();
// Aplica las opciones
SDL_SetWindowFullscreen(mWindow, mOptions->fullScreenMode);
SDL_SetWindowSize(mWindow, SCREEN_WIDTH * mOptions->windowSize, SCREEN_HEIGHT * mOptions->windowSize);
//SDL_SetWindowFullscreen(mWindow, mOptions->fullScreenMode);
//SDL_SetWindowSize(mWindow, REAL_SCREEN_WIDTH * mOptions->windowSize, REAL_SCREEN_HEIGHT * mOptions->windowSize);
mLang->setLang(mOptions->language);
#ifdef __MIPSEL__
DIR *dir = opendir("/media/data/local/home/.coffee_crisis");
if (dir)
@@ -76,6 +84,9 @@ Director::~Director()
delete mInput;
mInput = nullptr;
delete mScreen;
mScreen = nullptr;
delete mLang;
mLang = nullptr;
@@ -145,8 +156,7 @@ bool Director::initSDL()
bool success = true;
// Inicializa SDL
//if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMECONTROLLER | SDL_INIT_AUDIO) < 0)
if (SDL_Init(SDL_INIT_EVERYTHING) < 0)
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMECONTROLLER | SDL_INIT_AUDIO) < 0)
{
printf("SDL could not initialize!\nSDL Error: %s\n", SDL_GetError());
success = false;
@@ -156,14 +166,14 @@ bool Director::initSDL()
// Inicia el generador de numeros aleatorios
std::srand(static_cast<unsigned int>(SDL_GetTicks()));
// Establece el filtro de la textura a nearest
// Establece el filtro de la textura
if (!SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, std::to_string(mOptions->filter).c_str()))
{
printf("Warning: Nearest texture filtering not enabled!\n");
}
// Crea la ventana
mWindow = SDL_CreateWindow(WINDOW_CAPTION, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, VIEW_WIDTH, VIEW_HEIGHT, SDL_WINDOW_SHOWN | SDL_WINDOW_ALLOW_HIGHDPI);
mWindow = SDL_CreateWindow(WINDOW_CAPTION, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, mOptions->screenWidth * mOptions->windowSize, mOptions->screenHeight * mOptions->windowSize, SDL_WINDOW_SHOWN | SDL_WINDOW_ALLOW_HIGHDPI);
if (mWindow == NULL)
{
printf("Window could not be created!\nSDL Error: %s\n", SDL_GetError());
@@ -188,7 +198,7 @@ bool Director::initSDL()
SDL_SetRenderDrawColor(mRenderer, 0x00, 0x00, 0x00, 0xFF);
// Establece el tamaño del buffer de renderizado
SDL_RenderSetLogicalSize(mRenderer, SCREEN_WIDTH, SCREEN_HEIGHT);
SDL_RenderSetLogicalSize(mRenderer, mOptions->screenWidth, mOptions->screenHeight);
// Establece el modo de mezcla
SDL_SetRenderDrawBlendMode(mRenderer, SDL_BLENDMODE_BLEND);
@@ -359,6 +369,10 @@ bool Director::loadConfigFile()
mOptions->input[1].deviceType = INPUT_USE_GAMECONTROLLER;
mOptions->filter = FILTER_NEAREST;
mOptions->vSync = true;
mOptions->screenWidth = SCREEN_WIDTH;
mOptions->screenHeight = SCREEN_HEIGHT;
mOptions->integerScale = true;
mOptions->keepAspect = true;
// Indicador de éxito en la carga
bool success = true;
@@ -387,6 +401,10 @@ bool Director::loadConfigFile()
SDL_RWwrite(file, &mOptions->input[1].deviceType, sizeof(mOptions->input[1].deviceType), 1);
SDL_RWwrite(file, &mOptions->filter, sizeof(mOptions->filter), 1);
SDL_RWwrite(file, &mOptions->vSync, sizeof(mOptions->vSync), 1);
SDL_RWwrite(file, &mOptions->screenWidth, sizeof(mOptions->screenWidth), 1);
SDL_RWwrite(file, &mOptions->screenHeight, sizeof(mOptions->screenHeight), 1);
SDL_RWwrite(file, &mOptions->integerScale, sizeof(mOptions->integerScale), 1);
SDL_RWwrite(file, &mOptions->keepAspect, sizeof(mOptions->keepAspect), 1);
// Cierra el fichero
SDL_RWclose(file);
@@ -410,6 +428,10 @@ bool Director::loadConfigFile()
SDL_RWread(file, &mOptions->input[1].deviceType, sizeof(mOptions->input[1].deviceType), 1);
SDL_RWread(file, &mOptions->filter, sizeof(mOptions->filter), 1);
SDL_RWread(file, &mOptions->vSync, sizeof(mOptions->vSync), 1);
SDL_RWread(file, &mOptions->screenWidth, sizeof(mOptions->screenWidth), 1);
SDL_RWread(file, &mOptions->screenHeight, sizeof(mOptions->screenHeight), 1);
SDL_RWread(file, &mOptions->integerScale, sizeof(mOptions->integerScale), 1);
SDL_RWread(file, &mOptions->keepAspect, sizeof(mOptions->keepAspect), 1);
// Normaliza los valores
if (!((mOptions->fullScreenMode == 0) ||
@@ -446,6 +468,10 @@ bool Director::saveConfigFile()
SDL_RWwrite(file, &mOptions->input[1].deviceType, sizeof(mOptions->input[1].deviceType), 1);
SDL_RWwrite(file, &mOptions->filter, sizeof(mOptions->filter), 1);
SDL_RWwrite(file, &mOptions->vSync, sizeof(mOptions->vSync), 1);
SDL_RWwrite(file, &mOptions->screenWidth, sizeof(mOptions->screenWidth), 1);
SDL_RWwrite(file, &mOptions->screenHeight, sizeof(mOptions->screenHeight), 1);
SDL_RWwrite(file, &mOptions->integerScale, sizeof(mOptions->integerScale), 1);
SDL_RWwrite(file, &mOptions->keepAspect, sizeof(mOptions->keepAspect), 1);
printf("Writing file %s\n", filename.c_str());
@@ -485,21 +511,21 @@ void Director::setSection(section_t section)
void Director::runLogo()
{
mLogo = new Logo(mRenderer, mFileList);
mLogo = new Logo(mRenderer, mScreen, mFileList);
setSection(mLogo->run());
delete mLogo;
}
void Director::runIntro()
{
mIntro = new Intro(mRenderer, mFileList, mLang);
mIntro = new Intro(mRenderer, mScreen, mFileList, mLang);
setSection(mIntro->run());
delete mIntro;
}
void Director::runTitle()
{
mTitle = new Title(mWindow, mRenderer, mInput, mFileList, mOptions, mLang);
mTitle = new Title(mWindow, mRenderer, mScreen, mInput, mFileList, mOptions, mLang);
setSection(mTitle->run(mSection.subsection));
delete mTitle;
}
@@ -507,9 +533,9 @@ void Director::runTitle()
void Director::runGame()
{
if (mSection.subsection == GAME_SECTION_PLAY_1P)
mGame = new Game(1, mRenderer, mFileList, mLang, mInput, false, mOptions);
mGame = new Game(1, mRenderer, mScreen, mFileList, mLang, mInput, false, mOptions);
if (mSection.subsection == GAME_SECTION_PLAY_2P)
mGame = new Game(2, mRenderer, mFileList, mLang, mInput, false, mOptions);
mGame = new Game(2, mRenderer, mScreen, mFileList, mLang, mInput, false, mOptions);
setSection(mGame->run());
delete mGame;
}

View File

@@ -19,33 +19,35 @@
#include "title.h"
#include "game.h"
#include "input.h"
#include "screen.h"
#include "fade.h"
//#include <math.h>
#ifndef DIRECTOR_H
#define DIRECTOR_H
// Textos
#define WINDOW_CAPTION "Coffee Crisis"
// Cantidad máxima de elementos para el vector con las rutas de los ficheros de recursos
#define MAX_FILE_LIST 100
// Director
// Clase Director
class Director
{
private:
SDL_Window *mWindow; // La ventana donde dibujamos
SDL_Renderer *mRenderer; // El renderizador de la ventana
Logo *mLogo; // Objeto para la sección del logo
Intro *mIntro; // Objeto para la sección de la intro
Title *mTitle; // Objeto para la sección del titulo y el menu de opciones
Game *mGame; // Objeto para la sección del juego
Input *mInput; // Objeto Input para gestionar las entradas
Lang *mLang; // Objeto para gestionar los textos en diferentes idiomas
SDL_Window *mWindow; // La ventana donde dibujamos
SDL_Renderer *mRenderer; // El renderizador de la ventana
Screen *mScreen; // Objeto encargado de dibujar en pantalla
Logo *mLogo; // Objeto para la sección del logo
Intro *mIntro; // Objeto para la sección de la intro
Title *mTitle; // Objeto para la sección del titulo y el menu de opciones
Game *mGame; // Objeto para la sección del juego
Input *mInput; // Objeto Input para gestionar las entradas
Lang *mLang; // Objeto para gestionar los textos en diferentes idiomas
std::string mFileList[MAX_FILE_LIST]; // Vector con las rutas a los ficheros de recursos
struct options_t *mOptions; // Variable con todas las opciones del programa
std::string mExecutablePath; // Path del ejecutable
section_t mSection; // Sección y subsección actual del programa;
std::string mExecutablePath; // Path del ejecutable
section_t mSection; // Sección y subsección actual del programa;
// Inicializa jail_audio
void initJailAudio();

View File

@@ -25,9 +25,6 @@ void Fade::init(Uint8 r, Uint8 g, Uint8 b)
mEnabled = false;
mFinished = false;
mCounter = 0;
//mR = 0x27;
//mG = 0x27;
//mB = 0x36;
mR = r;
mG = g;
mB = b;
@@ -121,7 +118,7 @@ void Fade::render()
break;
}
}
if (mFinished)
{
SDL_SetRenderDrawColor(mRenderer, mR, mG, mB, 255);
@@ -153,16 +150,7 @@ bool Fade::isEnabled()
// Comprueba si ha terminado la transicion
bool Fade::hasEnded()
{
if (mFinished)
{
//mEnabled = false;
//mFinished = false;
return true;
}
else
{
return false;
}
return mFinished;
}
// Establece el tipo de fade

View File

@@ -5,11 +5,12 @@
#ifndef FADE_H
#define FADE_H
// Tipos de fundido
#define FADE_FULLSCREEN 0
#define FADE_CENTER 1
#define FADE_RANDOM_SQUARE 2
// Fade
// Clase Fade
class Fade
{
private:

View File

@@ -5,10 +5,11 @@
#endif
// Constructor
Game::Game(int numPlayers, SDL_Renderer *renderer, std::string *filelist, Lang *lang, Input *input, bool demo, options_t *options)
Game::Game(int numPlayers, SDL_Renderer *renderer, Screen *screen, std::string *filelist, Lang *lang, Input *input, bool demo, options_t *options)
{
// Copia los punteros
mRenderer = renderer;
mScreen = screen;
mFileList = filelist;
mLang = lang;
mInput = input;
@@ -100,6 +101,7 @@ Game::~Game()
mOptions->input[0].deviceType = mOnePlayerControl;
mRenderer = nullptr;
mScreen = nullptr;
mFileList = nullptr;
mLang = nullptr;
mInput = nullptr;
@@ -388,9 +390,6 @@ void Game::init()
initEnemyPools();
initGameStages();
// BORRAR
//mStage[mCurrentStage].currentPower = mStage[mCurrentStage].powerToComplete - 10;
// Modo debug
mDebug.enabled = false;
mDebug.enemySet = 0;
@@ -400,7 +399,7 @@ void Game::init()
mDemo.recording = false;
mDemo.counter = 0;
// Iniciualiza el objeto para el fundido
// Inicializa el objeto para el fundido
mFade->init(0x27, 0x27, 0x36);
// Inicializa el objeto con el menu de pausa
@@ -1412,7 +1411,7 @@ void Game::initGameStages()
mStage[2].currentPower = 0;
mStage[2].powerToComplete = 600;
mStage[2].minMenace = 7 + (4 * 3);
mStage[2].maxMenace = 7 + (4 * 6);
mStage[2].maxMenace = 7 + (4 * 5);
mStage[2].enemyPool = &mEnemyPool[2];
// STAGE 4
@@ -1420,7 +1419,7 @@ void Game::initGameStages()
mStage[3].currentPower = 0;
mStage[3].powerToComplete = 600;
mStage[3].minMenace = 7 + (4 * 3);
mStage[3].maxMenace = 7 + (4 * 7);
mStage[3].maxMenace = 7 + (4 * 5);
mStage[3].enemyPool = &mEnemyPool[3];
// STAGE 5
@@ -1428,47 +1427,47 @@ void Game::initGameStages()
mStage[4].currentPower = 0;
mStage[4].powerToComplete = 600;
mStage[4].minMenace = 7 + (4 * 4);
mStage[4].maxMenace = 7 + (4 * 8);
mStage[4].maxMenace = 7 + (4 * 6);
mStage[4].enemyPool = &mEnemyPool[4];
// STAGE 6
mStage[5].number = 6;
mStage[5].currentPower = 0;
mStage[5].powerToComplete = 600;
mStage[5].minMenace = 7 + (4 * 5);
mStage[5].maxMenace = 7 + (4 * 10);
mStage[5].minMenace = 7 + (4 * 4);
mStage[5].maxMenace = 7 + (4 * 6);
mStage[5].enemyPool = &mEnemyPool[5];
// STAGE 7
mStage[6].number = 7;
mStage[6].currentPower = 0;
mStage[6].powerToComplete = 650;
mStage[6].minMenace = 7 + (4 * 6);
mStage[6].maxMenace = 7 + (4 * 11);
mStage[6].minMenace = 7 + (4 * 5);
mStage[6].maxMenace = 7 + (4 * 7);
mStage[6].enemyPool = &mEnemyPool[6];
// STAGE 8
mStage[7].number = 8;
mStage[7].currentPower = 0;
mStage[7].powerToComplete = 750;
mStage[7].minMenace = 7 + (4 * 7);
mStage[7].maxMenace = 7 + (4 * 12);
mStage[7].minMenace = 7 + (4 * 5);
mStage[7].maxMenace = 7 + (4 * 7);
mStage[7].enemyPool = &mEnemyPool[7];
// STAGE 9
mStage[8].number = 9;
mStage[8].currentPower = 0;
mStage[8].powerToComplete = 850;
mStage[8].minMenace = 7 + (4 * 8);
mStage[8].maxMenace = 7 + (4 * 13);
mStage[8].minMenace = 7 + (4 * 6);
mStage[8].maxMenace = 7 + (4 * 8);
mStage[8].enemyPool = &mEnemyPool[8];
// STAGE 10
mStage[9].number = 10;
mStage[9].currentPower = 0;
mStage[9].powerToComplete = 950;
mStage[9].minMenace = 7 + (4 * 9);
mStage[9].maxMenace = 7 + (4 * 15);
mStage[9].minMenace = 7 + (4 * 7);
mStage[9].maxMenace = 7 + (4 * 10);
mStage[9].enemyPool = &mEnemyPool[9];
}
@@ -1515,7 +1514,7 @@ void Game::deployEnemyFormation()
mStage[mCurrentStage].enemyPool->set[set]->init[i].creationCounter,
mTextureBalloon);
mEnemyDeployCounter = 255;
mEnemyDeployCounter = 300;
}
}
}
@@ -1526,12 +1525,6 @@ void Game::increaseStageCurrentPower(Uint8 power)
mStage[mCurrentStage].currentPower += power;
}
// Establece el valor de la variable
/*void Game::setScore(Uint32 score)
{
mScore = score;
}*/
// Establece el valor de la variable
void Game::setHiScore(Uint32 score)
{
@@ -1607,39 +1600,8 @@ std::string Game::updateScoreText(Uint32 num)
// Pinta el marcador en pantalla usando un objeto texto
void Game::renderScoreBoard()
{
//color_t color = {0, 0, 0};
// Si el jugador esta muerto, no pintes el fondo del marcador, así que pase por encima cuando sale despedido
//if (mPlayer[0]->isAlive())
mSpriteScoreBoard->render();
/*
// SCORE
mText->writeCentered(PLAY_AREA_CENTER_FIRST_QUARTER_X, SCORE_WORD_Y - 6, mLang->getText(39), 0);
mText->writeCentered(PLAY_AREA_CENTER_FIRST_QUARTER_X, SCORE_NUMBER_Y - 6, updateScoreText(mPlayer[0]->getScore()), 0);
// HI-SCORE
mText->writeCentered(PLAY_AREA_CENTER_THIRD_QUARTER_X, HISCORE_WORD_Y - 6, mLang->getText(40), 0);
mText->writeCentered(PLAY_AREA_CENTER_THIRD_QUARTER_X, HISCORE_NUMBER_Y - 6, updateScoreText(mHiScore), 0);
// MULT
color.g = 255;
mText->writeColored(MULTIPLIER_WORD_X, MULTIPLIER_WORD_Y - 6, mLang->getText(41), color);
color.g = 192;
mTextX2->writeShadowed(PLAY_AREA_CENTER_X - 16, SCORE_WORD_Y + 5, std::to_string(mPlayer[0]->getScoreMultiplier()).substr(0, 1), color, 1);
mText->writeShadowed(PLAY_AREA_CENTER_X - 2, SCORE_WORD_Y + 12, ".", color);
mText->writeShadowed(PLAY_AREA_CENTER_X + 4, SCORE_WORD_Y + 12, std::to_string(mPlayer[0]->getScoreMultiplier()).substr(2, 1), color);
// STAGE
mText->writeCentered(PLAY_AREA_CENTER_FIRST_QUARTER_X, SCORE_NUMBER_Y + 4, mLang->getText(42) + std::to_string(mStage[mCurrentStage].number), 0);
// POWER
mSpritePowerMeter->setSpriteClip(256, 184, 40, 8);
mSpritePowerMeter->render();
const float percent = (mStage[mCurrentStage].currentPower * 40.0f) / mStage[mCurrentStage].powerToComplete;
mSpritePowerMeter->setSpriteClip(296, 184, (int)percent, 8);
mSpritePowerMeter->render();
*/
const int offset1 = 162;
const int offset2 = offset1 + 7;
const int offset3 = offset2 + 7;
@@ -1801,8 +1763,6 @@ void Game::updateDeath()
if (allAreDead)
{
//JA_StopMusic();
if (mDeathCounter > 0)
{
mDeathCounter--;
@@ -2244,7 +2204,6 @@ void Game::checkBulletBalloonCollision()
int index = mBullet[j]->getOwner();
mPlayer[index]->incScoreMultiplier();
mPlayer[index]->addScore(Uint32(mBalloon[i]->getScore() * mPlayer[index]->getScoreMultiplier() * mDifficultyScoreMultiplier));
//setScore(mPlayer[index]->getScore());
updateHiScore();
// Explota el globo
@@ -2281,7 +2240,7 @@ void Game::moveBullets()
{
for (int i = 0; i < MAX_BULLETS; i++)
if (mBullet[i]->isActive())
if (mBullet[i]->move() == MSG_BULLET_OUT)
if (mBullet[i]->move() == BULLET_MOVE_OUT)
mPlayer[mBullet[i]->getOwner()]->decScoreMultiplier();
}
@@ -2357,11 +2316,6 @@ void Game::resetItems()
// Devuelve un item en función del azar
Uint8 Game::dropItem()
{
//if (mPlayer[0]->isPowerUp() || (mCoffeeMachineEnabled))
// return NO_KIND;
//else
// return ITEM_COFFEE_MACHINE;
const Uint8 luckyNumber = rand() % 100;
const Uint8 item = rand() % 6;
@@ -2426,6 +2380,7 @@ void Game::createItemScoreSprite(int x, int y, SmartSprite *sprite)
{
const Uint8 index = getSmartSpriteFreeIndex();
// Crea una copia del objeto
*mSmartSprite[index] = *sprite;
mSmartSprite[index]->setPosX(x);
mSmartSprite[index]->setPosY(y);
@@ -2842,12 +2797,12 @@ void Game::checkGameInput()
mPlayer[index]->setInput(INPUT_RIGHT);
if (mDemo.dataFile[mDemo.counter].noInput == 1)
mPlayer[index]->setInput(NO_INPUT);
mPlayer[index]->setInput(INPUT_NULL);
if (mDemo.dataFile[mDemo.counter].fire == 1)
if (mPlayer[index]->canFire())
{
mPlayer[index]->setInput(INPUT_FIRE_UP);
mPlayer[index]->setInput(INPUT_BUTTON_2);
createBullet(mPlayer[index]->getPosX() + (mPlayer[index]->getWidth() / 2) - 4, mPlayer[index]->getPosY() + (mPlayer[index]->getHeight() / 2), BULLET_UP, mPlayer[index]->isPowerUp(), index);
mPlayer[index]->setFireCooldown(10);
}
@@ -2855,7 +2810,7 @@ void Game::checkGameInput()
if (mDemo.dataFile[mDemo.counter].fireLeft == 1)
if (mPlayer[index]->canFire())
{
mPlayer[index]->setInput(INPUT_FIRE_LEFT);
mPlayer[index]->setInput(INPUT_BUTTON_1);
createBullet(mPlayer[index]->getPosX() + (mPlayer[index]->getWidth() / 2) - 4, mPlayer[index]->getPosY() + (mPlayer[index]->getHeight() / 2), BULLET_UP, mPlayer[index]->isPowerUp(), index);
mPlayer[index]->setFireCooldown(10);
}
@@ -2863,7 +2818,7 @@ void Game::checkGameInput()
if (mDemo.dataFile[mDemo.counter].fireRight == 1)
if (mPlayer[index]->canFire())
{
mPlayer[index]->setInput(INPUT_FIRE_RIGHT);
mPlayer[index]->setInput(INPUT_BUTTON_3);
createBullet(mPlayer[index]->getPosX() + (mPlayer[index]->getWidth() / 2) - 4, mPlayer[index]->getPosY() + (mPlayer[index]->getHeight() / 2), BULLET_UP, mPlayer[index]->isPowerUp(), index);
mPlayer[index]->setFireCooldown(10);
}
@@ -2900,7 +2855,7 @@ void Game::checkGameInput()
else
{
// Ninguno de los dos inputs anteriores
mPlayer[i]->setInput(NO_INPUT);
mPlayer[i]->setInput(INPUT_NULL);
mDemo.keys.noInput = 1;
}
}
@@ -2909,7 +2864,7 @@ void Game::checkGameInput()
{
if (mPlayer[i]->canFire())
{
mPlayer[i]->setInput(INPUT_FIRE_UP);
mPlayer[i]->setInput(INPUT_BUTTON_2);
createBullet(mPlayer[i]->getPosX() + (mPlayer[i]->getWidth() / 2) - 4, mPlayer[i]->getPosY() + (mPlayer[i]->getHeight() / 2), BULLET_UP, mPlayer[i]->isPowerUp(), i);
mPlayer[i]->setFireCooldown(10);
@@ -2925,7 +2880,7 @@ void Game::checkGameInput()
{
if (mPlayer[i]->canFire())
{
mPlayer[i]->setInput(INPUT_FIRE_LEFT);
mPlayer[i]->setInput(INPUT_BUTTON_1);
createBullet(mPlayer[i]->getPosX() + (mPlayer[i]->getWidth() / 2) - 4, mPlayer[i]->getPosY() + (mPlayer[i]->getHeight() / 2), BULLET_LEFT, mPlayer[i]->isPowerUp(), i);
mPlayer[i]->setFireCooldown(10);
@@ -2941,7 +2896,7 @@ void Game::checkGameInput()
{
if (mPlayer[i]->canFire())
{
mPlayer[i]->setInput(INPUT_FIRE_RIGHT);
mPlayer[i]->setInput(INPUT_BUTTON_3);
createBullet(mPlayer[i]->getPosX() + (mPlayer[i]->getWidth() / 2) - 4, mPlayer[i]->getPosY() + (mPlayer[i]->getHeight() / 2), BULLET_RIGHT, mPlayer[i]->isPowerUp(), i);
mPlayer[i]->setFireCooldown(10);
@@ -2981,10 +2936,6 @@ void Game::renderMessages()
if ((mCounter < STAGE_COUNTER) && (!mDemo.enabled))
{
mSpriteGetReady->setPosX((int)mGetReadyBitmapPath[mCounter]);
//mSpriteGetReady->render();
//const color_t color = {0x17, 0x17, 0x26};
//mTextBig->writeShadowed((int)mGetReadyBitmapPath[mCounter], PLAY_AREA_CENTER_Y - 8, mLang->getText(75), color, 2);
//mTextBig->writeDX(TXT_STROKE, (int)mGetReadyBitmapPath[mCounter], PLAY_AREA_CENTER_Y - 8, mLang->getText(75), 1, noColor, 1, shdwTxtColor);
mTextNokiaBig2->write((int)mGetReadyBitmapPath[mCounter], PLAY_AREA_CENTER_Y - 8, mLang->getText(75), -2);
}
@@ -2992,11 +2943,7 @@ void Game::renderMessages()
if (mTimeStopped)
{
if ((mTimeStoppedCounter > 100) || (mTimeStoppedCounter % 10 > 4))
mTextNokia2->writeDX(TXT_CENTER, PLAY_AREA_CENTER_X, PLAY_AREA_FIRST_QUARTER_Y, mLang->getText(36) + std::to_string(mTimeStoppedCounter / 10), -1, noColor, 1, shdwTxtColor);
//{
// mTextNokiaBig2->writeDX(TXT_CENTER, PLAY_AREA_CENTER_X, PLAY_AREA_FIRST_QUARTER_Y, mLang->getText(36), -2);
// mTextNokiaBig2->writeDX(TXT_CENTER, PLAY_AREA_CENTER_X, PLAY_AREA_FIRST_QUARTER_Y + mTextNokiaBig2->getCharacterWidth() + 2, std::to_string(mTimeStoppedCounter / 10), -2);
//}
mTextNokia2->writeDX(TXT_CENTER, PLAY_AREA_CENTER_X, PLAY_AREA_FIRST_QUARTER_Y, mLang->getText(36) + std::to_string(mTimeStoppedCounter / 10), -1, noColor, 1, shdwTxtColor);
if (mTimeStoppedCounter > 100)
{
@@ -3027,7 +2974,7 @@ void Game::renderMessages()
{ // Texto de juego completado
text = mLang->getText(50);
mTextNokiaBig2->writeDX(TXT_CENTER, PLAY_AREA_CENTER_X, mStageBitmapPath[mStageBitmapCounter], text, -2, noColor, 1, shdwTxtColor);
mTextNokiaBig2->writeDX(TXT_CENTER, PLAY_AREA_CENTER_X, mStageBitmapPath[mStageBitmapCounter] + mTextNokiaBig2->getCharacterWidth() + 2, mLang->getText(76), -1, noColor, 1, shdwTxtColor);
mTextNokia2->writeDX(TXT_CENTER, PLAY_AREA_CENTER_X, mStageBitmapPath[mStageBitmapCounter] + mTextNokiaBig2->getCharacterWidth() + 2, mLang->getText(76), -1, noColor, 1, shdwTxtColor);
}
}
}
@@ -3059,8 +3006,14 @@ void Game::shakeScreen()
for (int n = 0; n < 8; n++)
{
// Limpia la pantalla
SDL_SetRenderDrawColor(mRenderer, 0x00, 0x00, 0x00, 0xFF);
SDL_RenderClear(mRenderer);
//SDL_SetRenderDrawColor(mRenderer, 0x00, 0x00, 0x00, 0xFF);
//SDL_RenderClear(mRenderer);
// Prepara para empezar a dibujar en la textura de juego
mScreen->start();
// Limpia la pantalla
mScreen->clean(bgColor);
// Dibuja los objetos
mSpriteBackground->setPosX(0);
@@ -3086,7 +3039,10 @@ void Game::shakeScreen()
renderScoreBoard();
// Actualiza la pantalla
SDL_RenderPresent(mRenderer);
//SDL_RenderPresent(mRenderer);
// Vuelca el contenido del renderizador en pantalla
mScreen->blit();
SDL_Delay(50);
}
}
@@ -3142,9 +3098,11 @@ section_t Game::run()
updatePlayField();
}
// Prepara para empezar a dibujar en la textura de juego
mScreen->start();
// Limpia la pantalla
SDL_SetRenderDrawColor(mRenderer, 0x00, 0x00, 0x00, 0xFF);
SDL_RenderClear(mRenderer);
mScreen->clean(bgColor);
// Dibuja los objetos
renderPlayField();
@@ -3152,8 +3110,8 @@ section_t Game::run()
// Pinta la informacion de debug
renderDebugInfo();
// Actualiza la pantalla
SDL_RenderPresent(mRenderer);
// Vuelca el contenido del renderizador en pantalla
mScreen->blit();
}
}
@@ -3197,19 +3155,19 @@ void Game::runPausedGame()
}
}
// Dibuja los objetos
//renderBackground();
//renderBalloons();
//renderBullets();
//for (int i = 0; i < mNumPlayers; i++)
// mPlayer[i]->render();
//renderScoreBoard();
// Prepara para empezar a dibujar en la textura de juego
mScreen->start();
// Limpia la pantalla
mScreen->clean(bgColor);
// Pinta el escenario
renderPlayField();
mMenuPause->render();
mFade->render();
// Actualiza la pantalla
SDL_RenderPresent(mRenderer);
// Vuelca el contenido del renderizador en pantalla
mScreen->blit();
// Comprueba las entradas para el menu
mMenuPause->checkInput();
@@ -3218,7 +3176,6 @@ void Game::runPausedGame()
switch (mMenuPause->getItemSelected())
{
case 0:
//mMenuPause->reset();
mSection.name = PROG_SECTION_GAME;
if (mNumPlayers == 1)
mSection.subsection = GAME_SECTION_PLAY_1P;
@@ -3229,7 +3186,6 @@ void Game::runPausedGame()
break;
case 1:
//mMenuPause->reset();
mFade->setFadeType(FADE_CENTER);
mFade->activateFade();
break;
@@ -3297,9 +3253,11 @@ void Game::runGameOverScreen()
}
}
// Prepara para empezar a dibujar en la textura de juego
mScreen->start();
// Limpia la pantalla
SDL_SetRenderDrawColor(mRenderer, 0x27, 0x27, 0x36, 0xFF);
SDL_RenderClear(mRenderer);
mScreen->clean(bgColor);
// Dibuja los objetos
if (mNumPlayers == 1)
@@ -3317,8 +3275,8 @@ void Game::runGameOverScreen()
mMenuGameOver->render();
mFade->render();
// Muestra la pantalla
SDL_RenderPresent(mRenderer);
// Vuelca el contenido del renderizador en pantalla
mScreen->blit();
// Comprueba las entradas para el menu
mMenuGameOver->checkInput();
@@ -3346,13 +3304,9 @@ void Game::runGameOverScreen()
void Game::renderDebugInfo()
{
const color_t color = {0xFF, 0x20, 0x20};
//mText->writeShadowed(2, 2 + 0 * BLOCK, "POW: " + std::to_string(mPlayer[0]->mPowerUpCounter), color);
//if (mHelper.needCoffeeMachine)
// mText->writeShadowed(2, 2 + 1 * BLOCK, "NEED COFFEMACHINE", color);
if (mDebug.enabled)
{
//SDL_RenderSetLogicalSize(mRenderer, SCREEN_WIDTH * 2, SCREEN_HEIGHT * 2);
mText->writeShadowed(2, 2 + 0 * BLOCK, "menace(umb): " + std::to_string(mMenaceCurrent) + "(" + std::to_string(mMenaceThreshold) + ")", color);
mText->writeShadowed(2, 2 + 1 * BLOCK, "currentPower: " + std::to_string(mStage[mCurrentStage].currentPower), color);
mText->writeShadowed(2, 2 + 2 * BLOCK, "mCurrentStage:" + std::to_string(mCurrentStage), color);
@@ -3451,19 +3405,21 @@ void Game::updateGameCompleted()
// Actualiza las variables de ayuda
void Game::updateHelper()
{
// El ayudante solo funciona para un jugador
// Solo ofrece ayuda cuando la amenaza o la velocidad es elevada
// Solo ofrece ayuda cuando la amenaza es elevada
if (mMenaceCurrent > 15)
{
if (mPlayer[0]->getCoffees() == 0)
mHelper.needCoffee = true;
else
mHelper.needCoffee = false;
for (int i = 0; i < mNumPlayers; i++)
{
if (mPlayer[i]->getCoffees() == 0)
mHelper.needCoffee = true;
else
mHelper.needCoffee = false;
if (!mPlayer[0]->isPowerUp())
mHelper.needCoffeeMachine = true;
else
mHelper.needCoffeeMachine = false;
if (!mPlayer[i]->isPowerUp())
mHelper.needCoffeeMachine = true;
else
mHelper.needCoffeeMachine = false;
}
}
else
{

View File

@@ -1,28 +1,62 @@
#pragma once
#include "ifdefs.h"
#include "const.h"
#include "utils.h"
#include "sprite.h"
#include "movingsprite.h"
#include "smartsprite.h"
#include "player.h"
#include "balloon.h"
#include "bullet.h"
#include "item.h"
#include "text.h"
#include "writer.h"
#include "menu.h"
#include "input.h"
#include "const.h"
#include "fade.h"
#include "ifdefs.h"
#include "input.h"
#include "item.h"
#include "jail_audio.h"
#include "menu.h"
#include "movingsprite.h"
#include "player.h"
#include "screen.h"
#include "smartsprite.h"
#include "sprite.h"
#include "text.h"
#include "utils.h"
#include "writer.h"
#ifndef GAME_H
#define GAME_H
// Game
// Cantidad de elementos a escribir en los ficheros de datos
#define TOTAL_SCORE_DATA 3
#define TOTAL_DEMO_DATA 2000
// Contadores
#define STAGE_COUNTER 200
#define SHAKE_COUNTER 10
#define HELP_COUNTER 1000
// Formaciones enemigas
#define NUMBER_OF_ENEMY_FORMATIONS 100
#define MAX_NUMBER_OF_ENEMIES_IN_A_FORMATION 50
// Cantidad de elementos del vector de SmartSprites
#define MAX_SMART_SPRITES 10
// Cantidad máxima posible de balas
#define MAX_BULLETS 50
// Porcentaje de aparición de los objetos
#define ITEM_POINTS_1_DISK_ODDS 10
#define ITEM_POINTS_2_GAVINA_ODDS 6
#define ITEM_POINTS_3_PACMAR_ODDS 3
#define ITEM_CLOCK_ODDS 5
#define ITEM_COFFEE_ODDS 5
#define ITEM_POWER_BALL_ODDS 0
#define ITEM_COFFEE_MACHINE_ODDS 4
// Cantidad de objetos simultaneos
#define MAX_ITEMS 10
// Valores para las variables asociadas a los objetos
#define REMAINING_EXPLOSIONS 3
#define REMAINING_EXPLOSIONS_COUNTER 50
#define TIME_STOPPED_COUNTER 300
// Clase Game
class Game
{
private:
@@ -80,6 +114,7 @@ private:
};
SDL_Renderer *mRenderer; // El renderizador de la ventana
Screen *mScreen; // Objeto encargado de dibujar en pantalla
std::string *mFileList; // Lista de ficheros con los recursos
Lang *mLang; // Objeto para gestionar los textos en diferentes idiomas
@@ -109,13 +144,13 @@ private:
LTexture *mTextureTextScoreBoard; // Textura para el texto del marcador
LTexture *mTextureTextBig; // Textura para el texto grande
LTexture *mTextureTextNokia2; // Textura para la fuente de texto Nokia
LTexture *mTextureTextNokiaBig2; // Textura para la fuente de texto Nokia grande
LTexture *mTextureTextNokiaBig2; // Textura para la fuente de texto Nokia grande
Text *mText; // Fuente para los textos del juego
Text *mTextBig; // Fuente de texto grande
Text *mTextScoreBoard; // Fuente para el marcador del juego
Text *mTextNokia2; // Otra fuente de texto para mesajes
Text *mTextNokiaBig2; // Y la versión en grande
Text *mTextNokiaBig2; // Y la versión en grande
Menu *mMenuGameOver; // Menú de la pantalla de game over
Menu *mMenuPause; // Menú de la pantalla de pausa
@@ -180,7 +215,7 @@ private:
SDL_Rect mGradientRect[4]; // Vector con las coordenadas de los 4 gradientes
Uint16 mBalloonsPopped; // Lleva la cuenta de los globos explotados
Uint8 mLastEnemyDeploy; // Guarda cual ha sido la última formación desplegada para no repetir;
Uint8 mEnemyDeployCounter; // Cuando se lanza una formación, se le da un valor y no sale otra hasta que llegue a cero
int mEnemyDeployCounter; // Cuando se lanza una formación, se le da un valor y no sale otra hasta que llegue a cero
float mEnemySpeed; // Velocidad a la que se mueven los enemigos
float mDefaultEnemySpeed; // Velocidad base de los enemigos, sin incrementar
effect_t mEffect; // Variable para gestionar los efectos visuales
@@ -500,7 +535,7 @@ private:
public:
// Constructor
Game(int numPlayers, SDL_Renderer *renderer, std::string *filelist, Lang *lang, Input *input, bool demo, options_t *options);
Game(int numPlayers, SDL_Renderer *renderer, Screen *screen, std::string *filelist, Lang *lang, Input *input, bool demo, options_t *options);
// Destructor
~Game();

View File

@@ -1,15 +1,4 @@
#ifdef _WIN64
#include "C:\Program Files\mingw-w64\x86_64-8.1.0-posix-seh-rt_v6-rev0\mingw64\lib\gcc\x86_64-w64-mingw32\8.1.0\include\c++\SDL2\SDL.h"
#endif
#ifdef _WIN32
#include "C:\Program Files\mingw-w64\x86_64-8.1.0-posix-seh-rt_v6-rev0\mingw64\lib\gcc\x86_64-w64-mingw32\8.1.0\include\c++\SDL2\SDL.h"
#endif
#ifdef __APPLE__
//#include "/Library/Frameworks/SDL2.framework/Versions/A/Headers/SDL.h"
#include <SDL2/SDL.h>
#endif
#ifdef __linux__
#ifdef __MIPSEL__

View File

@@ -1,9 +1,6 @@
#include "input.h"
#include <iostream>
// Contestar cuantos joystics ha detectado
// Preguntarlepor los joystics que ha encontrado para ir poniendolos en la variable de opciones
// Constructor
Input::Input(std::string file)
{

View File

@@ -49,11 +49,10 @@ private:
};
GameControllerBindings_t mGameControllerBindings[17]; // Vector con las teclas asociadas a los inputs predefinidos
//SDL_GameController *mGameController; // Manejador para el mando
std::vector<SDL_GameController*> mConnectedControllers;
std::vector<std::string> mControllerNames;
int mNumGamepads;
std::string mDBpath; // Ruta al archivo gamecontrollerdb.txt
std::vector<SDL_GameController *> mConnectedControllers; // Vector con todos los mandos conectados
std::vector<std::string> mControllerNames; // Vector con los nombres de los mandos
int mNumGamepads; // Numero de mandos conectados
std::string mDBpath; // Ruta al archivo gamecontrollerdb.txt
// Comprueba si hay un mando conectado
bool discoverGameController();
@@ -72,7 +71,7 @@ public:
void bindGameControllerButton(Uint8 input, SDL_GameControllerButton button);
// Comprueba si un input esta activo
bool checkInput(Uint8 input, bool repeat, int device=INPUT_USE_ANY, int index=0);
bool checkInput(Uint8 input, bool repeat, int device = INPUT_USE_ANY, int index = 0);
// Comprueba si hay algun mando conectado
bool gameControllerFound();

View File

@@ -7,10 +7,11 @@
const Uint8 SELF = 0;
// Constructor
Instructions::Instructions(SDL_Renderer *renderer, std::string *fileList, Lang *lang)
Instructions::Instructions(SDL_Renderer *renderer, Screen *screen, std::string *fileList, Lang *lang)
{
// Copia los punteros
mRenderer = renderer;
mScreen = screen;
mFileList = fileList;
mLang = lang;
@@ -30,6 +31,11 @@ Instructions::Instructions(SDL_Renderer *renderer, std::string *fileList, Lang *
// Destructor
Instructions::~Instructions()
{
mRenderer = nullptr;
mScreen = nullptr;
mFileList = nullptr;
mLang = nullptr;
mItemTexture->unload();
delete mItemTexture;
mItemTexture = nullptr;
@@ -209,9 +215,11 @@ void Instructions::run(Uint8 mode)
// Cambia el destino de renderizado
SDL_SetRenderTarget(mRenderer, nullptr);
// Limpia el renderizador
SDL_SetRenderDrawColor(mRenderer, bgColor.r, bgColor.g, bgColor.b, 255);
SDL_RenderClear(mRenderer);
// Prepara para empezar a dibujar en la textura de juego
mScreen->start();
// Limpia la pantalla
mScreen->clean(bgColor);
// Establece la ventana del backbuffer
if (mode == INSTRUCTIONS_MODE_AUTO)
@@ -222,7 +230,7 @@ void Instructions::run(Uint8 mode)
// Copia el backbuffer al renderizador
SDL_RenderCopy(mRenderer, mBackbuffer, NULL, &window);
// Dibuja el renderizador en pantalla
SDL_RenderPresent(mRenderer);
// Vuelca el contenido del renderizador en pantalla
mScreen->blit();
}
}

View File

@@ -1,23 +1,31 @@
#pragma once
#include "ifdefs.h"
#include "utils.h"
#include "const.h"
#include "ifdefs.h"
#include "jail_audio.h"
#include "screen.h"
#include "sprite.h"
#include "text.h"
#include "jail_audio.h"
#include "utils.h"
#ifndef INSTRUCTIONS_H
#define INSTRUCTIONS_H
// Instructions
// Contadores
#define INSTRUCTIONS_COUNTER 600
// Modo para las instrucciones
#define INSTRUCTIONS_MODE_MANUAL 0
#define INSTRUCTIONS_MODE_AUTO 1
// Clase Instructions
class Instructions
{
private:
SDL_Renderer *mRenderer; // El renderizador de la ventana
Screen *mScreen; // Objeto encargado de dibujar en pantalla
LTexture *mItemTexture; // Textura con los graficos
LTexture *mTextTexture; // Textura con los graficos
SDL_Event *mEventHandler; // Manejador de eventos
SDL_Renderer *mRenderer; // El renderizador de la ventana
SDL_Texture *mBackbuffer; // Textura para usar como backbuffer
Sprite *mSprite; // Sprite con la textura de las instrucciones
std::string *mFileList; // Lista de ficheros
@@ -43,7 +51,7 @@ private:
public:
// Constructor
Instructions(SDL_Renderer *renderer, std::string *fileList, Lang *lang);
Instructions(SDL_Renderer *renderer, Screen *screen, std::string *fileList, Lang *lang);
// Destructor
~Instructions();

View File

@@ -5,10 +5,11 @@
#endif
// Constructor
Intro::Intro(SDL_Renderer *renderer, std::string *fileList, Lang *lang)
Intro::Intro(SDL_Renderer *renderer, Screen *screen, std::string *fileList, Lang *lang)
{
// Copia los punteros
mRenderer = renderer;
mScreen = screen;
mFileList = fileList;
mLang = lang;
@@ -28,6 +29,11 @@ Intro::Intro(SDL_Renderer *renderer, std::string *fileList, Lang *lang)
// Destructor
Intro::~Intro()
{
mRenderer = nullptr;
mScreen = nullptr;
mFileList = nullptr;
mLang = nullptr;
delete mEventHandler;
mEventHandler = nullptr;
@@ -181,9 +187,7 @@ void Intro::init()
mWriter[8]->setSpeed(20);
for (int i = 0; i < INTRO_TOTAL_TEXTS; i++)
{
mWriter[i]->center(SCREEN_CENTER_X);
}
}
// Carga los recursos
@@ -206,37 +210,35 @@ section_t Intro::run()
{
init();
// Si la música no está sonando
// Si la música no está sonando la hace sonar
if ((JA_GetMusicState() == JA_MUSIC_INVALID) || (JA_GetMusicState() == JA_MUSIC_STOPPED))
{
// Reproduce la música
JA_PlayMusic(mMusic, 0);
}
while (mSection.name == PROG_SECTION_INTRO)
{
// Comprueba los eventos que hay en la cola
while (SDL_PollEvent(mEventHandler) != 0)
{
// Evento de salida de la aplicación
if (mEventHandler->type == SDL_QUIT)
{
mSection.name = PROG_SECTION_QUIT;
break;
}
if ((mEventHandler->type == SDL_KEYDOWN) || (mEventHandler->type == SDL_JOYBUTTONDOWN))
{
JA_StopMusic();
mSection = {PROG_SECTION_TITLE, TITLE_SECTION_1};
}
}
// Actualiza las variables
if (SDL_GetTicks() - mTicks > mTicksSpeed)
{
// Actualiza el contador de ticks
mTicks = SDL_GetTicks();
// Comprueba los eventos que hay en la cola
while (SDL_PollEvent(mEventHandler) != 0)
{
// Evento de salida de la aplicación
if (mEventHandler->type == SDL_QUIT)
{
mSection.name = PROG_SECTION_QUIT;
break;
}
if ((mEventHandler->type == SDL_KEYDOWN) || (mEventHandler->type == SDL_JOYBUTTONDOWN))
{
JA_StopMusic();
mSection = {PROG_SECTION_TITLE, TITLE_SECTION_1};
}
}
// Actualiza los objetos
for (int i = 0; i < INTRO_TOTAL_BITMAPS; i++)
mBitmap[i]->update();
@@ -356,9 +358,11 @@ section_t Intro::run()
}
}
// Prepara para empezar a dibujar en la textura de juego
mScreen->start();
// Limpia la pantalla
SDL_SetRenderDrawColor(mRenderer, bgColor.r, bgColor.g, bgColor.b, 0xFF);
SDL_RenderClear(mRenderer);
mScreen->clean(bgColor);
// Dibuja los objetos
for (int i = 0; i < INTRO_TOTAL_BITMAPS; i++)
@@ -366,8 +370,8 @@ section_t Intro::run()
for (int i = 0; i < INTRO_TOTAL_TEXTS; i++)
mWriter[i]->render();
// Actualiza la pantalla
SDL_RenderPresent(mRenderer);
// Vuelca el contenido del renderizador en pantalla
mScreen->blit();
}
return mSection;

View File

@@ -2,7 +2,7 @@
#include "ifdefs.h"
#include "const.h"
#include "utils.h"
#include "screen.h"
#include "smartsprite.h"
#include "writer.h"
#include "jail_audio.h"
@@ -10,14 +10,37 @@
#ifndef INTRO_H
#define INTRO_H
// Intro
// Cantidad de eventos de la intro
#define INTRO_TOTAL_BITMAPS 6
#define INTRO_TOTAL_TEXTS 9
const int INTRO_TOTAL_EVENTS = INTRO_TOTAL_BITMAPS + INTRO_TOTAL_TEXTS;
// Relaciones de Id con nombres
#define BITMAP0 0
#define BITMAP1 1
#define BITMAP2 2
#define BITMAP3 3
#define BITMAP4 4
#define BITMAP5 5
#define TEXT0 6
#define TEXT1 7
#define TEXT2 8
#define TEXT3 9
#define TEXT4 10
#define TEXT5 11
#define TEXT6 12
#define TEXT7 13
#define TEXT8 14
// Clase Intro
class Intro
{
private:
SDL_Renderer *mRenderer; // El renderizador de la ventana
Screen *mScreen; // Objeto encargado de dibujar en pantalla
LTexture *mBitmapTexture; // Textura con los graficos
LTexture *mTextTexture; // Textura con los caracteres de texto
SDL_Event *mEventHandler; // Manejador de eventos
SDL_Renderer *mRenderer; // El renderizador de la ventana
std::string *mFileList; // Lista de ficheros
Lang *mLang; // Objeto para gestionar los textos en diferentes idiomas
section_t mSection; // Estado del bucle principal para saber si continua o se sale
@@ -31,7 +54,7 @@ private:
public:
// Constructor
Intro(SDL_Renderer *renderer, std::string *fileList, Lang *lang);
Intro(SDL_Renderer *renderer, Screen *screen, std::string *fileList, Lang *lang);
// Destructor
~Intro();

View File

@@ -1,6 +1,5 @@
#include "const.h"
#include "item.h"
#include <stdio.h>
// Constructor
Item::Item()

View File

@@ -6,7 +6,16 @@
#ifndef ITEM_H
#define ITEM_H
// Clase AnimatedSprite
// Tipos de objetos
#define ITEM_POINTS_1_DISK 1
#define ITEM_POINTS_2_GAVINA 2
#define ITEM_POINTS_3_PACMAR 3
#define ITEM_CLOCK 4
#define ITEM_COFFEE 5
#define ITEM_POWER_BALL 6
#define ITEM_COFFEE_MACHINE 7
// Clase Item
class Item
{
private:

View File

@@ -1,6 +1,6 @@
#ifdef __MIPSEL__
#include "jail_audio.h"
#include "SDL_mixer.h"
#include <SDL2/SDL_mixer.h>
struct JA_Sound_t {
Mix_Chunk *mix_chunk;

View File

@@ -5,7 +5,7 @@
#ifndef LANG_H
#define LANG_H
// Lang codes
// Códigos de idioma
#define es_ES 0
#define ba_BA 1
#define en_UK 2
@@ -18,15 +18,15 @@
class Lang
{
private:
std::string *mFileList; // Lista de ficheros con los recursos
std::string mTextStrings[MAX_TEXT_STRINGS];
std::string *mFileList; // Lista de ficheros con los recursos
std::string mTextStrings[MAX_TEXT_STRINGS]; // Vector con los textos
public:
// Constructor
Lang(std::string *fileList);
// Constructor
Lang(std::string *fileList);
// Destructor
~Lang();
// Destructor
~Lang();
// Inicializa los textos del juego en el idioma seleccionado
bool setLang(Uint8 lang);

View File

@@ -4,16 +4,15 @@
#include <dirent.h>
#endif
# define INIT_FADE 100
# define END_LOGO 200
#define INIT_FADE 100
#define END_LOGO 200
// Constructor
Logo::Logo(SDL_Renderer *renderer, std::string *fileList)
Logo::Logo(SDL_Renderer *renderer, Screen *screen, std::string *fileList)
{
// Copia la dirección del renderizador
// Copia la dirección de los objetos
mRenderer = renderer;
// Copia la dirección del la lista de ficheros
mScreen = screen;
mFileList = fileList;
// Reserva memoria para los punteros
@@ -30,6 +29,10 @@ Logo::Logo(SDL_Renderer *renderer, std::string *fileList)
// Destructor
Logo::~Logo()
{
mRenderer = nullptr;
mScreen = nullptr;
mFileList = nullptr;
mTexture->unload();
delete mTexture;
mTexture = nullptr;
@@ -96,9 +99,11 @@ section_t Logo::run()
}
}
// Limpia el destino
SDL_SetRenderDrawColor(mRenderer, bgColor.r, bgColor.g, bgColor.b, 255);
SDL_RenderClear(mRenderer);
// Prepara para empezar a dibujar en la textura de juego
mScreen->start();
// Limpia la pantalla
mScreen->clean(bgColor);
// Dibuja los objetos
mSprite->render();
@@ -114,8 +119,8 @@ section_t Logo::run()
SDL_RenderFillRect(mRenderer, &rect);
}
// Actualiza la pantalla
SDL_RenderPresent(mRenderer);
// Vuelca el contenido del renderizador en pantalla
mScreen->blit();
// Comprueba si ha terminado el logo
if (SDL_GetTicks() - mTicks > mTicksSpeed)

View File

@@ -2,23 +2,24 @@
#include "ifdefs.h"
#include "const.h"
#include "utils.h"
#include "sprite.h"
#include "screen.h"
#include "jail_audio.h"
#ifndef LOGO_H
#define LOGO_H
// Logo
// Clase Logo
class Logo
{
private:
SDL_Renderer *mRenderer; // El renderizador de la ventana
Screen *mScreen; // Objeto encargado de dibujar en pantalla
std::string *mFileList; // Lista de ficheros
LTexture *mTexture; // Textura con los graficos
SDL_Event *mEventHandler; // Manejador de eventos
SDL_Renderer *mRenderer; // El renderizador de la ventana
SDL_Texture *mBackbuffer; // Textura para usar como backbuffer
Sprite *mSprite; // Sprite con la textura del logo
std::string *mFileList; // Lista de ficheros
Uint16 mCounter; // Contador
section_t mSection; // Estado del bucle principal para saber si continua o se sale
Uint32 mTicks; // Contador de ticks para ajustar la velocidad del programa
@@ -26,7 +27,7 @@ private:
public:
// Constructor
Logo(SDL_Renderer *renderer, std::string *fileList);
Logo(SDL_Renderer *renderer, Screen *screen, std::string *fileList);
// Destructor
~Logo();

View File

@@ -227,26 +227,15 @@ bool Menu::increaseSelectorIndex()
mSelector.h = mSelector.originH = getSelectorHeight(mSelector.index);
// Calcula cual es el siguiente elemento
//if (mSelector.index < (mTotalItems - 1))
//{
// mSelector.index++;
// while ((!mItem[mSelector.index].selectable) && (mSelector.index < (mTotalItems - 1)))
// mSelector.index++;
// success = true;
//}
// Calcula cual es el siguiente elemento (versión con loop)
//if (mSelector.index < (mTotalItems - 1))
{
++mSelector.index %= mTotalItems;
while (!mItem[mSelector.index].selectable)
//mSelector.index++;
++mSelector.index %= mTotalItems;
while (!mItem[mSelector.index].selectable)
//mSelector.index++;
++mSelector.index %= mTotalItems;
success = true;
}
success = true;
// Establece las coordenadas y altura de destino
if (success)
{ // Establece las coordenadas y altura de destino
{
mSelector.targetY = mItem[mSelector.index].rect.y;
mSelector.despY = (mSelector.targetY - mSelector.originY) / mSelector.numJumps;
@@ -271,33 +260,22 @@ bool Menu::decreaseSelectorIndex()
mSelector.h = mSelector.originH = getSelectorHeight(mSelector.index);
// Calcula cual es el siguiente elemento
//if (mSelector.index > 0)
//{
// mSelector.index--;
// while ((!mItem[mSelector.index].selectable) && (mSelector.index > 0))
// mSelector.index--;
// success = true;
//}
// Calcula cual es el siguiente elemento (versión con loop)
//if (mSelector.index > 0)
if (mSelector.index == 0)
mSelector.index = mTotalItems;
else
mSelector.index--;
while (!mItem[mSelector.index].selectable)
{
if (mSelector.index == 0)
mSelector.index = mTotalItems;
else
mSelector.index--;
while (!mItem[mSelector.index].selectable)
{
if (mSelector.index == 0)
mSelector.index = mTotalItems;
else
mSelector.index--;
}
success = true;
}
success = true;
// Establece las coordenadas y altura de destino
if (success)
{ // Establece las coordenadas y altura de destino
{
mSelector.targetY = mItem[mSelector.index].rect.y;
mSelector.despY = (mSelector.targetY - mSelector.originY) / mSelector.numJumps;
@@ -370,10 +348,6 @@ void Menu::render()
mText->write(mItem[i].rect.x, mItem[i].rect.y, mItem[i].label);
}
}
//borrar
//mText->write(0, 0, std::to_string(mSelector.h) + " " + std::to_string(mSelector.incH) + " " + std::to_string(mSelector.resizing));
//mText->write(0, 8, std::to_string(mSelector.y) + " " + std::to_string(mSelector.despY) + " " + std::to_string(mSelector.moving));
}
}
@@ -433,9 +407,6 @@ void Menu::centerMenuOnX(int value)
mIsCenteredOnX = true;
mCenterX = value;
// Actualiza el rectangulo de fondo para recalcular las dimensiones
//setRectSize();
// Establece la nueva posición centrada en funcion del elemento más ancho
mPosX = (value) - (findWidth() / 2);
@@ -453,9 +424,6 @@ void Menu::centerMenuOnY(int value)
mIsCenteredOnY = true;
mCenterY = value;
// Actualiza el rectangulo de fondo para recalcular las dimensiones
//setRectSize();
// Establece la nueva posición centrada en funcion del elemento más ancho
mPosY = (value) - (findHeight() / 2);
@@ -497,7 +465,6 @@ void Menu::addItem(std::string text, Uint8 hPaddingDown, bool selectable, bool g
setTotalItems(mTotalItems + 1);
mCenterX = mPosX + (findWidth() / 2);
//setSelectorPos(0);
reorganize();
}
@@ -520,16 +487,12 @@ void Menu::setDefaultActionWhenCancel(Uint8 item)
void Menu::checkInput()
{
if (mInput->checkInput(INPUT_UP, REPEAT_FALSE))
{
if (decreaseSelectorIndex())
JA_PlaySound(mSoundMove);
}
if (mInput->checkInput(INPUT_DOWN, REPEAT_FALSE))
{
if (increaseSelectorIndex())
JA_PlaySound(mSoundMove);
}
if (mInput->checkInput(INPUT_ACCEPT, REPEAT_FALSE))
{

View File

@@ -8,9 +8,17 @@
#ifndef MENU_H
#define MENU_H
// Cantidad máxima de items en el menu
#define MENU_MAX_ITEMS 50
// Clase menu
// Tipos de fondos para el menu
#define MENU_BACKGROUND_TRANSPARENT 0
#define MENU_BACKGROUND_SOLID 1
// Opciones de menu
#define MENU_NO_OPTION -1
// Clase Menu
class Menu
{
private:

View File

@@ -262,15 +262,15 @@ void Player::setInput(Uint8 input)
setWalkingStatus(PLAYER_STATUS_WALKING_RIGHT);
break;
case INPUT_FIRE_UP:
case INPUT_BUTTON_2:
setFiringStatus(PLAYER_STATUS_FIRING_UP);
break;
case INPUT_FIRE_LEFT:
case INPUT_BUTTON_1:
setFiringStatus(PLAYER_STATUS_FIRING_LEFT);
break;
case INPUT_FIRE_RIGHT:
case INPUT_BUTTON_3:
setFiringStatus(PLAYER_STATUS_FIRING_RIGHT);
break;
@@ -291,10 +291,7 @@ void Player::move()
// Si el jugador abandona el area de juego por los laterales
if ((mPosX < PLAY_AREA_LEFT - 5) || (mPosX + mWidth > PLAY_AREA_RIGHT + 5))
{
// Restaura su posición
mPosX -= mVelX;
}
mPosX -= mVelX; // Restaura su posición
// Actualiza la posición del sprite
mSpriteLegs->setPosX(getPosX());
@@ -509,13 +506,9 @@ bool Player::canFire()
{
// Si el contador a llegado a cero, podemos disparar. En caso contrario decrementamos el contador
if (mCooldown > 0)
{
return false;
}
else
{
return true;
}
}
// Establece el valor de la variable

View File

@@ -6,7 +6,42 @@
#ifndef PLAYER_H
#define PLAYER_H
// The player
// Contadores
#define DEATH_COUNTER 350
// Estados del jugador
#define PLAYER_STATUS_WALKING_LEFT 0
#define PLAYER_STATUS_WALKING_RIGHT 1
#define PLAYER_STATUS_WALKING_STOP 2
#define PLAYER_STATUS_FIRING_UP 0
#define PLAYER_STATUS_FIRING_LEFT 1
#define PLAYER_STATUS_FIRING_RIGHT 2
#define PLAYER_STATUS_FIRING_NO 3
#define PLAYER_ANIMATION_LEGS_WALKING_RIGHT 1
#define PLAYER_ANIMATION_LEGS_WALKING_STOP 2
#define PLAYER_ANIMATION_BODY_WALKING_LEFT 0
#define PLAYER_ANIMATION_BODY_FIRING_LEFT 1
#define PLAYER_ANIMATION_BODY_WALKING_RIGHT 2
#define PLAYER_ANIMATION_BODY_FIRING_RIGHT 3
#define PLAYER_ANIMATION_BODY_WALKING_STOP 4
#define PLAYER_ANIMATION_BODY_FIRING_UP 5
#define PLAYER_ANIMATION_HEAD_WALKING_LEFT 0
#define PLAYER_ANIMATION_HEAD_FIRING_LEFT 1
#define PLAYER_ANIMATION_HEAD_WALKING_RIGHT 2
#define PLAYER_ANIMATION_HEAD_FIRING_RIGHT 3
#define PLAYER_ANIMATION_HEAD_WALKING_STOP 4
#define PLAYER_ANIMATION_HEAD_FIRING_UP 5
#define PLAYER_ANIMATION_LEGS_WALKING_LEFT 0
// Variables del jugador
#define PLAYER_INVULNERABLE_COUNTER 200
#define PLAYER_POWERUP_COUNTER 1500
// Clase Player
class Player
{
private:

133
source/screen.cpp Normal file
View File

@@ -0,0 +1,133 @@
#include "screen.h"
#include "const.h"
#include <string>
#include <stdio.h>
// Constructor
Screen::Screen(SDL_Window *window, SDL_Renderer *renderer, options_t *options)
{
// Inicializa variables
mWindow = window;
mRenderer = renderer;
mOptions = options;
mGameCanvasWidth = SCREEN_WIDTH;
mGameCanvasHeight = SCREEN_HEIGHT;
// Establece el modo de video
setVideoMode(mOptions->fullScreenMode);
// Define el color del borde para el modo de pantalla completa
mBorderColor = {0x27, 0x27, 0x36};
mBorderColor = {0x00, 0x00, 0x00};
// Crea la textura donde se dibujan los graficos del juego
mGameCanvas = SDL_CreateTexture(mRenderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, mGameCanvasWidth, mGameCanvasHeight);
if (mGameCanvas == NULL)
printf("TitleSurface could not be created!\nSDL Error: %s\n", SDL_GetError());
}
// Destructor
Screen::~Screen()
{
mRenderer = nullptr;
}
// Limpia la pantalla
void Screen::clean(color_t color)
{
SDL_SetRenderDrawColor(mRenderer, color.r, color.g, color.b, 0xFF);
SDL_RenderClear(mRenderer);
}
// Prepara para empezar a dibujar en la textura de juego
void Screen::start()
{
SDL_SetRenderTarget(mRenderer, mGameCanvas);
}
// Vuelca el contenido del renderizador en pantalla
void Screen::blit()
{
// Vuelve a dejar el renderizador en modo normal
SDL_SetRenderTarget(mRenderer, NULL);
// Borra el contenido previo
SDL_SetRenderDrawColor(mRenderer, mBorderColor.r, mBorderColor.g, mBorderColor.b, 0xFF);
SDL_RenderClear(mRenderer);
// Copia la textura de juego en el renderizador en la posición adecuada
SDL_RenderCopy(mRenderer, mGameCanvas, NULL, &mDest);
// Muestra por pantalla el renderizador
SDL_RenderPresent(mRenderer);
}
// Establece el modo de video
void Screen::setVideoMode(int fullScreenMode)
{
// Aplica el modo de video
SDL_SetWindowFullscreen(mWindow, fullScreenMode);
// Si está activo el modo ventana quita el borde
if (fullScreenMode == 0)
{
mScreenWidth = mGameCanvasWidth;
mScreenHeight = mGameCanvasHeight;
mDest = {0, 0, mGameCanvasWidth, mGameCanvasHeight};
// Modifica el tamaño del renderizador y de la ventana
SDL_RenderSetLogicalSize(mRenderer, mScreenWidth, mScreenHeight);
SDL_SetWindowSize(mWindow, mScreenWidth * mOptions->windowSize, mScreenHeight * mOptions->windowSize);
}
// Si está activo el modo de pantalla completa añade el borde
if (fullScreenMode == SDL_WINDOW_FULLSCREEN_DESKTOP)
{
// Obten el alto y el ancho de la ventana
SDL_GetWindowSize(mWindow, &mScreenWidth, &mScreenHeight);
// Aplica el escalado al rectangulo donde se pinta la textura del juego
if (mOptions->integerScale)
{
// Calcula el tamaño de la escala máxima
int scale = 0;
while (((mGameCanvasWidth * (scale + 1)) <= mScreenWidth) && ((mGameCanvasHeight * (scale + 1)) <= mScreenHeight))
{
scale++;
}
mDest.w = mGameCanvasWidth * scale;
mDest.h = mGameCanvasHeight * scale;
mDest.x = (mScreenWidth - mDest.w) / 2;
mDest.y = (mScreenHeight - mDest.h) / 2;
}
else if (mOptions->keepAspect)
{
float ratio = (float)mGameCanvasWidth / (float)mGameCanvasHeight;
if ((mScreenWidth - mGameCanvasWidth) >= (mScreenHeight - mGameCanvasHeight))
{
mDest.h = mScreenHeight;
mDest.w = (int)((mScreenHeight * ratio) + 0.5f);
mDest.x = (mScreenWidth - mDest.w) / 2;
mDest.y = (mScreenHeight - mDest.h) / 2;
}
else
{
mDest.w = mScreenWidth;
mDest.h = (int)((mScreenWidth / ratio) + 0.5f);
mDest.x = (mScreenWidth - mDest.w) / 2;
mDest.y = (mScreenHeight - mDest.h) / 2;
}
}
else
{
mDest.w = mScreenWidth;
mDest.h = mScreenHeight;
mDest.x = mDest.y = 0;
}
// Modifica el tamaño del renderizador
SDL_RenderSetLogicalSize(mRenderer, mScreenWidth, mScreenHeight);
}
}

44
source/screen.h Normal file
View File

@@ -0,0 +1,44 @@
#pragma once
#include "ifdefs.h"
#include "utils.h"
#ifndef SCREEN_H
#define SCREEN_H
// Clase Screen
class Screen
{
private:
SDL_Window *mWindow; // Ventana de la aplicación
SDL_Renderer *mRenderer; // El renderizador de la ventana
SDL_Texture *mGameCanvas; // Textura para completar la ventana de juego hasta la pantalla completa
options_t *mOptions; // Variable con todas las opciones del programa
int mScreenWidth; // Ancho de la pantalla
int mScreenHeight; // Alto de la pantalla
int mGameCanvasWidth; // Ancho de la textura donde se dibuja el juego
int mGameCanvasHeight; // Alto de la textura donde se dibuja el juego
SDL_Rect mDest; // Coordenadas donde se va a dibujar la textura del juego
color_t mBorderColor; // Color del borde añadido a la textura de juego para rellenar la pantalla
public:
// Constructor
Screen(SDL_Window *window, SDL_Renderer *renderer, options_t *options);
// Destructor
~Screen();
// Limpia la pantalla
void clean(color_t color);
// Prepara para empezar a dibujar en la textura de juego
void start();
// Vuelca el contenido del renderizador en pantalla
void blit();
// Establece el modo de video
void setVideoMode(int fullScreenMode);
};
#endif

View File

@@ -4,13 +4,11 @@
// Constructor
SmartSprite::SmartSprite()
{
//init(nullptr, nullptr);
}
// Destructor
SmartSprite::~SmartSprite()
{
//init(nullptr, nullptr);
}
// Inicializador
@@ -114,7 +112,7 @@ bool SmartSprite::update()
// Comprueba si se desplaza en el eje X hacia la derecha
if ((getAccelX() > 0) || ((getAccelX() == 0) && (getVelX() > 0)))
{
// Comprueba si hemos llegado al destino
// Comprueba si ha llegado al destino
if (getPosX() > mDestX)
{
// Lo coloca en posición
@@ -128,7 +126,7 @@ bool SmartSprite::update()
// Comprueba si se desplaza en el eje X hacia la izquierda
else if ((getAccelX() < 0) || ((getAccelX() == 0) && (getVelX() < 0)))
{
// Comprueba si hemos llegado al destino
// Comprueba si ha llegado al destino
if (getPosX() < mDestX)
{
// Lo coloca en posición
@@ -143,7 +141,7 @@ bool SmartSprite::update()
// Comprueba si se desplaza en el eje Y hacia abajo
if ((getAccelY() > 0) || ((getAccelY() == 0) && (getVelY() > 0)))
{
// Comprueba si hemos llegado al destino
// Comprueba si ha llegado al destino
if (getPosY() > mDestY)
{
// Lo coloca en posición
@@ -157,7 +155,7 @@ bool SmartSprite::update()
// Comprueba si se desplaza en el eje Y hacia arriba
else if ((getAccelY() < 0) || ((getAccelY() == 0) && (getVelY() < 0)))
{
// Comprueba si hemos llegado al destino
// Comprueba si ha llegado al destino
if (getPosY() < mDestY)
{
// Lo coloca en posición
@@ -171,13 +169,9 @@ bool SmartSprite::update()
// Comprueba si ha llegado a su destino
if ((getPosX() == mDestX) && (getPosY() == mDestY))
{
mIsOnDestination = true;
}
else
{
mIsOnDestination = false;
}
// Si esta en el destino comprueba su contador
if (mIsOnDestination)
@@ -185,7 +179,7 @@ bool SmartSprite::update()
// Si el contador es mayor que cero, lo decrementa
if (mEnabledCounter > 0)
{
--mEnabledCounter;
mEnabledCounter--;
}
// Si ha llegado a cero, deshabilita el objeto o manda el aviso en función de si tiene Id
else if (mEnabledCounter == 0)
@@ -215,9 +209,7 @@ bool SmartSprite::isOnDestination()
void SmartSprite::render()
{
if (mEnabled)
{
MovingSprite::render();
}
}
// Establece el valor de la variable

View File

@@ -10,7 +10,7 @@
#define TXT_CENTER 4
#define TXT_STROKE 8
// Clase texto. Pinta texto en pantalla a partir de un bitmap
// Clase Text. Pinta texto en pantalla a partir de una cadena y un bitmap
class Text
{
private:
@@ -18,9 +18,9 @@ private:
struct Offset
{
int x;
int y;
Uint8 w;
int x; // Posición en el eje X dentro del bitmap
int y; // Posición en el eje Y dentro del bitmap
Uint8 w; // Ancho en pixeles de la letra
};
Offset mOffset[128]; // Vector con las posiciones y ancho de cada letra

View File

@@ -5,11 +5,12 @@
#endif
// Constructor
Title::Title(SDL_Window *window, SDL_Renderer *renderer, Input *input, std::string *fileList, options_t *options, Lang *lang)
Title::Title(SDL_Window *window, SDL_Renderer *renderer, Screen *screen, Input *input, std::string *fileList, options_t *options, Lang *lang)
{
// Copia las direcciones de los punteros
mWindow = window;
mRenderer = renderer;
mScreen = screen;
mInput = input;
mFileList = fileList;
mOptions = options;
@@ -33,6 +34,7 @@ Title::Title(SDL_Window *window, SDL_Renderer *renderer, Input *input, std::stri
mMenu.title = new Menu(mRenderer, mText, mInput, mFileList);
mMenu.options = new Menu(mRenderer, mText, mInput, mFileList);
// Crea la textura para el mosaico de fondo
mBackground = SDL_CreateTexture(mRenderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, SCREEN_WIDTH * 2, SCREEN_HEIGHT * 2);
if (mBackground == NULL)
printf("TitleSurface could not be created!\nSDL Error: %s\n", SDL_GetError());
@@ -43,6 +45,7 @@ Title::~Title()
{
mWindow = nullptr;
mRenderer = nullptr;
mScreen = nullptr;
mInput = nullptr;
mFileList = nullptr;
mOptions = nullptr;
@@ -136,22 +139,23 @@ void Title::init(bool demo, Uint8 subsection)
mFade->init(0x17, 0x17, 0x26);
mDemo = demo;
//if (!mInput->gameControllerFound())
{
mOptions->input[0].id = 0;
mOptions->input[0].name = "KEYBOARD";
mOptions->input[0].deviceType = INPUT_USE_KEYBOARD;
// Pone valores por defecto a las opciones de control
mOptions->input[0].id = 0;
mOptions->input[0].name = "KEYBOARD";
mOptions->input[0].deviceType = INPUT_USE_KEYBOARD;
mOptions->input[1].id = 0;
mOptions->input[1].name = "GAME CONTROLLER";
mOptions->input[1].deviceType = INPUT_USE_GAMECONTROLLER;
}
mOptions->input[1].id = 0;
mOptions->input[1].name = "GAME CONTROLLER";
mOptions->input[1].deviceType = INPUT_USE_GAMECONTROLLER;
// Comprueba si hay mandos conectados
checkInputDevices();
mDeviceIndex[0] = mAvailableInputDevices.size() - 1;
mDeviceIndex[1] = 0;
// Pone valores por defecto
mDeviceIndex[0] = mAvailableInputDevices.size() - 1; // El último dispositivo encontrado es el teclado
mDeviceIndex[1] = 0; // El primer mando encontrado. Si no ha encontrado ninguno es el teclado
// Si ha encontrado un mando se lo asigna al segundo jugador
if (mInput->gameControllerFound())
{
mOptions->input[1].id = mAvailableInputDevices[mDeviceIndex[1]].id;
@@ -244,6 +248,7 @@ void Title::init(bool demo, Uint8 subsection)
// Crea el mosaico de fondo del titulo
createTiledBackground();
// Coloca la ventana que recorre el mosaico de fondo de manera que coincida con el mosaico que hay pintado en el titulo al iniciar
mBackgroundWindow.x = 128;
mBackgroundWindow.y = 96;
mBackgroundWindow.w = SCREEN_WIDTH;
@@ -251,9 +256,7 @@ void Title::init(bool demo, Uint8 subsection)
// Inicializa los valores del vector con los valores del seno
for (int i = 0; i < 360; i++)
{
mSin[i] = SDL_sinf((float)i * 3.14f / 180.0f);
}
// Inicializa los objetos de menu
mMenu.title->init("TITLE", 0, (14 * BLOCK) + 4, MENU_BACKGROUND_TRANSPARENT);
@@ -380,7 +383,6 @@ void Title::updateMenuLabels()
else
{
mMenu.options->setGreyed(i, false);
//mMenu.options->setItemCaption(i, mInput->getControllerName(0));
mMenu.options->setItemCaption(i, mOptions->input[0].name);
}
break;
@@ -410,7 +412,6 @@ void Title::updateMenuLabels()
else
{
mMenu.options->setGreyed(i, false);
//mMenu.options->setItemCaption(i, mInput->getControllerName(0));
mMenu.options->setItemCaption(i, mOptions->input[1].name);
}
break;
@@ -496,15 +497,18 @@ void Title::updateMenuLabels()
// CANCEL
mMenu.options->setItemCaption(i, mLang->getText(10)); // CANCEL
// Recoloca el menu de opciones
mMenu.options->centerMenuOnX(SCREEN_CENTER_X);
mMenu.options->centerMenuOnY(SCREEN_CENTER_Y);
mMenu.options->centerMenuElementsOnX();
// Establece las etiquetas del menu de titulo
mMenu.title->setItemCaption(0, mLang->getText(51)); // 1 PLAYER
mMenu.title->setItemCaption(1, mLang->getText(52)); // 2 PLAYERS
mMenu.title->setItemCaption(2, mLang->getText(1)); // OPTIONS
mMenu.title->setItemCaption(3, mLang->getText(3)); // QUIT
// Recoloca el menu de titulo
mMenu.title->centerMenuOnX(SCREEN_CENTER_X);
mMenu.title->centerMenuElementsOnX();
}
@@ -512,8 +516,12 @@ void Title::updateMenuLabels()
// Aplica las opciones de menu seleccionadas
void Title::applyOptions()
{
SDL_SetWindowFullscreen(mWindow, mOptions->fullScreenMode);
SDL_SetWindowSize(mWindow, SCREEN_WIDTH * mOptions->windowSize, SCREEN_HEIGHT * mOptions->windowSize);
//SDL_SetWindowFullscreen(mWindow, mOptions->fullScreenMode);
//if (mOptions->fullScreenMode == 0)
// SDL_SetWindowSize(mWindow, mOptions->screenWidth * mOptions->windowSize, mOptions->screenHeight * mOptions->windowSize);
//SDL_RenderSetLogicalSize(mRenderer, mOptions->screenWidth, mOptions->screenHeight);
mScreen->setVideoMode(mOptions->fullScreenMode);
mLang->setLang(mOptions->language);
updateMenuLabels();
@@ -552,9 +560,11 @@ section_t Title::run(Uint8 subsection)
mCrisisBitmap->update();
}
// Prepara para empezar a dibujar en la textura de juego
mScreen->start();
// Limpia la pantalla
SDL_SetRenderDrawColor(mRenderer, bgColor.r, bgColor.g, bgColor.b, 255);
SDL_RenderClear(mRenderer);
mScreen->clean(bgColor);
// Dibuja el tileado de fondo
SDL_RenderCopy(mRenderer, mBackground, &mBackgroundWindow, NULL);
@@ -566,8 +576,8 @@ section_t Title::run(Uint8 subsection)
mCoffeeBitmap->render();
mCrisisBitmap->render();
// Actualiza la pantalla
SDL_RenderPresent(mRenderer);
// Vuelca el contenido del renderizador en pantalla
mScreen->blit();
// Si los objetos han llegado a su destino, cambiamos de Sección
if ((mEvents[0] == EVENT_COMPLETED) && (mEvents[0] == EVENT_COMPLETED))
@@ -604,9 +614,11 @@ section_t Title::run(Uint8 subsection)
int b = mCrisisBitmap->getPosX();
for (int n = 0; n < 11 * 3; n++)
{
// Prepara para empezar a dibujar en la textura de juego
mScreen->start();
// Limpia la pantalla
SDL_SetRenderDrawColor(mRenderer, bgColor.r, bgColor.g, bgColor.b, 255);
SDL_RenderClear(mRenderer);
mScreen->clean(bgColor);
// Dibuja el tileado de fondo
SDL_RenderCopy(mRenderer, mBackground, &mBackgroundWindow, NULL);
@@ -624,8 +636,8 @@ section_t Title::run(Uint8 subsection)
mDustBitmapR->render();
mDustBitmapL->render();
// Actualiza la pantalla
SDL_RenderPresent(mRenderer);
// Vuelca el contenido del renderizador en pantalla
mScreen->blit();
}
mSection.subsection = TITLE_SECTION_3;
@@ -655,10 +667,7 @@ section_t Title::run(Uint8 subsection)
// Si la música no está sonando
if ((JA_GetMusicState() == JA_MUSIC_INVALID) || (JA_GetMusicState() == JA_MUSIC_STOPPED))
{
// Reproduce la música
JA_PlayMusic(mMusic);
}
JA_PlayMusic(mMusic); // Reproduce la música
// Calcula la lógica de los objetos
if (SDL_GetTicks() - mTicks > mTicksSpeed)
@@ -842,14 +851,14 @@ section_t Title::run(Uint8 subsection)
}
if (mMenu.active->getName() == "TITLE")
{
mCounter--;
}
}
// Prepara para empezar a dibujar en la textura de juego
mScreen->start();
// Limpia la pantalla
SDL_SetRenderDrawColor(mRenderer, bgColor.r, bgColor.g, bgColor.b, 255);
SDL_RenderClear(mRenderer);
mScreen->clean(bgColor);
// Dibuja el tileado de fondo
SDL_RenderCopy(mRenderer, mBackground, &mBackgroundWindow, NULL);
@@ -883,8 +892,8 @@ section_t Title::run(Uint8 subsection)
// Fade
mFade->render();
// Actualiza la pantalla
SDL_RenderPresent(mRenderer);
// Vuelca el contenido del renderizador en pantalla
mScreen->blit();
}
else if (mCounter == 0)
{
@@ -913,7 +922,7 @@ section_t Title::run(Uint8 subsection)
// Ejecuta la parte donde se muestran las instrucciones
void Title::runInstructions(Uint8 mode)
{
mInstructions = new Instructions(mRenderer, mFileList, mLang);
mInstructions = new Instructions(mRenderer, mScreen, mFileList, mLang);
mInstructions->run(mode);
delete mInstructions;
}
@@ -921,7 +930,7 @@ void Title::runInstructions(Uint8 mode)
// Ejecuta el juego en modo demo
void Title::runDemoGame()
{
mDemoGame = new Game(1, mRenderer, mFileList, mLang, mInput, true, mOptions);
mDemoGame = new Game(1, mRenderer, mScreen, mFileList, mLang, mInput, true, mOptions);
mDemoGame->run();
delete mDemoGame;
}
@@ -949,29 +958,23 @@ bool Title::updatePlayerInputs(int numPlayer)
}
else // Si hay mas de un dispositivo, se recorre el vector
{
printf("numplayer:%i\n",numPlayer);
printf("deviceindex:%i\n",mDeviceIndex[numPlayer]);
printf("numplayer:%i\n", numPlayer);
printf("deviceindex:%i\n", mDeviceIndex[numPlayer]);
// Incrementa el indice
if (mDeviceIndex[numPlayer] < numDevices - 1)
mDeviceIndex[numPlayer]++;
else
mDeviceIndex[numPlayer] = 0;
printf("deviceindex:%i\n",mDeviceIndex[numPlayer]);
printf("deviceindex:%i\n", mDeviceIndex[numPlayer]);
// Si coincide con el del otro jugador, se lo intercambian
if (mDeviceIndex[0] == mDeviceIndex[1])
{
printf("%i:%i\n",mDeviceIndex[0],mDeviceIndex[1]);
//const int temp = mDeviceIndex[0];
//mDeviceIndex[0] = mDeviceIndex[1];
//mDeviceIndex[1] = temp;
const int theOtherPlayer = (numPlayer + 1) % 2;
mDeviceIndex[theOtherPlayer]--;
if (mDeviceIndex[theOtherPlayer] < 0)
mDeviceIndex[theOtherPlayer]=numDevices-1;
printf("%i:%i\n",mDeviceIndex[0],mDeviceIndex[1]);
mDeviceIndex[theOtherPlayer] = numDevices - 1;
}
// Copia el dispositivo marcado por el indice a la variable de opciones de cada jugador

View File

@@ -2,11 +2,9 @@
#include "ifdefs.h"
#include "const.h"
#include "utils.h"
#include "sprite.h"
#include "movingsprite.h"
#include "smartsprite.h"
#include "item.h"
#include "text.h"
#include "menu.h"
@@ -14,16 +12,28 @@
#include "input.h"
#include "instructions.h"
#include "game.h"
#include "screen.h"
#include "jail_audio.h"
#ifndef TITLE_H
#define TITLE_H
// Title
// Textos
#define TEXT_COPYRIGHT "@2020,2021 JailDesigner (v2.0.3)"
// Contadores
#define TITLE_COUNTER 800
// Cantidad de eventos de la pantalla de titulo
#define TITLE_TOTAL_EVENTS 2
// Clase Title
class Title
{
private:
SDL_Window *mWindow; // Ventana de la aplicación
SDL_Renderer *mRenderer; // El renderizador de la ventana
Screen *mScreen; // Objeto encargado de dibujar en pantalla
AnimatedSprite *mDustBitmapL; // Sprite con la el polvo que aparece al colisionar el texto de la pantalla de titulo
AnimatedSprite *mDustBitmapR; // Sprite con la el polvo que aparece al colisionar el texto de la pantalla de titulo
bool mMenuVisible; // Indicador para saber si se muestra el menu del titulo o la frase intermitente
@@ -36,7 +46,6 @@ private:
LTexture *mTextTexture2; // Textura con los gráficos para el texto
SDL_Event *mEventHandler; // Manejador de eventos
SDL_Rect mBackgroundWindow; // Ventana visible para la textura de fondo del titulo
SDL_Renderer *mRenderer; // El renderizador de la ventana
SDL_Texture *mBackground; // Textura dibujar el fondo del titulo
SmartSprite *mCoffeeBitmap; // Sprite con la palabra COFFEE para la pantalla de titulo
SmartSprite *mCrisisBitmap; // Sprite con la palabra CRISIS para la pantalla de titulo
@@ -70,10 +79,10 @@ private:
};
menu_t mMenu; // Variable con todos los objetos menus y sus variables
struct options_t *mOptions; // Variable con todas las variables de las opciones del programa
options_t mOptionsPrevious; // Variable de respaldo para las opciones
struct options_t *mOptions; // Variable con todas las variables de las opciones del programa
options_t mOptionsPrevious; // Variable de respaldo para las opciones
std::vector<input_t> mAvailableInputDevices; // Vector con todos los metodos de control disponibles
int mDeviceIndex[2]; // Indice para el jugador [i] del vector de dispositivos de entrada disponibles
int mDeviceIndex[2]; // Indice para el jugador [i] del vector de dispositivos de entrada disponibles
// Carga los recursos necesarios para la sección 'Title'
bool loadMedia();
@@ -104,7 +113,7 @@ private:
public:
// Constructor
Title(SDL_Window *window, SDL_Renderer *renderer, Input *input, std::string *fileList, options_t *options, Lang *lang);
Title(SDL_Window *window, SDL_Renderer *renderer, Screen *screen, Input *input, std::string *fileList, options_t *options, Lang *lang);
// Destructor
~Title();

View File

@@ -17,10 +17,7 @@ bool checkCollision(circle_t &a, circle_t &b)
// Si la distancia entre el centro de los circulos es inferior a la suma de sus radios
if (distanceSquared(a.x, a.y, b.x, b.y) < (totalRadiusSquared))
{
// Los circulos han colisionado
return true;
}
return true; // Los circulos han colisionado
// En caso contrario
return false;
@@ -114,11 +111,11 @@ bool checkCollision(SDL_Rect &a, SDL_Rect &b)
// Carga un archivo de imagen en una textura
bool loadTextureFromFile(LTexture *texture, std::string path, SDL_Renderer *renderer)
{
bool success = true;
if (!texture->loadFromFile(path, renderer))
{
printf("Failed to load %s texture!\n", path.c_str());
success = false;
}
return success;
bool success = true;
if (!texture->loadFromFile(path, renderer))
{
printf("Failed to load %s texture!\n", path.c_str());
success = false;
}
return success;
}

View File

@@ -6,6 +6,15 @@
#ifndef UTILS_H
#define UTILS_H
// Dificultad del juego
#define DIFFICULTY_EASY 0
#define DIFFICULTY_NORMAL 1
#define DIFFICULTY_HARD 2
// Tipo de filtro
#define FILTER_NEAREST 0
#define FILTER_LINEAL 1
// Estructura para definir un circulo
struct circle_t
{
@@ -55,9 +64,13 @@ struct options_t
input_t input[2]; // Modo de control (teclado o mando)
Uint8 language; // Idioma usado en el juego
Uint32 fullScreenMode; // Contiene el valor del modo de pantalla completa
Uint8 windowSize; // Contiene el valor del tamaño de la ventana
Uint8 windowSize; // Contiene el valor por el que se multiplica el tamaño de la ventana
Uint32 filter; // Filtro usado para el escalado de la imagen
bool vSync; // Indica si se quiere usar vsync o no
int screenWidth; // Ancho de la pantalla/ventana
int screenHeight; // Alto de la pantalla/ventana
bool integerScale; // Indica si el escalado de la imagen ha de ser entero en el modo a pantalla completa
bool keepAspect; // Indica si se ha de mantener la relación de aspecto al poner el modo a pantalla completa
};
// Calcula el cuadrado de la distancia entre dos puntos

View File

@@ -134,9 +134,7 @@ void Writer::update()
void Writer::render()
{
if (mEnabled)
{
mText->write(mPosX, mPosY, mCaption, mKerning, mIndex);
}
}
// Centra la cadena de texto a un punto X

View File

@@ -5,7 +5,7 @@
#ifndef WRITER_H
#define WRITER_H
// Clase texto. Pinta texto en pantalla a partir de un bitmap
// Clase Writer. Pinta texto en pantalla a partir de una cadena y un bitmap
class Writer
{
private: