Compare commits

..

16 Commits
v1.01 ... v1.04

Author SHA1 Message Date
dc8c0c9e4f Fix: Algunas texturas desaparecen al bloquearse la pantalla 2022-11-17 17:54:05 +01:00
7af0dda1a0 En la pantalla de Game Over se muestran las habitaciones y los items conseguidos 2022-11-17 16:33:37 +01:00
0adf8c63f4 Las habitaciones solo cuentan como visitadas una vez por partida 2022-11-17 16:06:31 +01:00
d33f691743 Fix: Algunas texturas desaparecen al bloquearse la pantalla 2022-11-17 16:04:03 +01:00
a304f50e93 Merge branch 'master' of https://gitea.sustancia.synology.me/JailDesigner/jaildoctors_dilemma 2022-11-17 11:53:07 +01:00
496bf5c05c Actualizado Makefile 2022-11-17 11:53:00 +01:00
26a6bd6b1f Cambiada la posición y dirección inicial del tuno magenta en KILLING SPREE 2022-11-17 11:31:54 +01:00
c48dce8634 Actualizado Makefile 2022-11-17 09:36:12 +01:00
a0de547370 Eliminado un warning de variable no utilizada 2022-11-17 09:34:06 +01:00
5af554fecd Añadido soporte preliminar para estadisticas 2022-11-17 09:30:56 +01:00
ea92241d6e Actualizado Makefile 2022-11-16 22:43:26 +01:00
60ea12f51d Resuelto el bug de quedarse atascado en una rampa al caer 2022-11-16 21:56:51 +01:00
36c7063b3e Añadida mas información a asset->check() 2022-11-16 21:12:01 +01:00
c6a1f4aab0 Añadidos mas ifdef DEBUG para quitar código sobrante de la versión final 2022-11-16 20:24:49 +01:00
eed3f9d7d1 Actualizado Makefile 2022-11-16 10:02:32 +01:00
02e6929f5f Actualizado Makefile 2022-11-15 09:58:45 +01:00
18 changed files with 386 additions and 225 deletions

1
.gitignore vendored
View File

@@ -1,5 +1,6 @@
.vscode
*config.txt
*stats.txt
*.DS_Store
thumbs.db
*.exe

View File

@@ -2,7 +2,7 @@ executable = jaildoctors_dilemma
source = source/*.cpp source/common/*.cpp
appName = JailDoctor's Dilemma
releaseFolder = jdd_release
version = v1.01
version = v1.04
# Release names
windowsRelease = $(executable)-$(version)-win32-x64.zip
@@ -12,8 +12,6 @@ linuxRelease = $(executable)-$(version)-linux.tar.gz
windows:
@echo off
powershell if (Test-Path data\config) {Remove-Item data\config -Recurse -Force}
powershell if (-not (Test-Path data\config)) {New-Item data\config -ItemType Directory}
g++ $(source) -D DEBUG -std=c++11 -Wall -Os -lmingw32 -lSDL2main -lSDL2 -ffunction-sections -fdata-sections -Wl,--gc-sections -static-libstdc++ -Wl,-subsystem,windows -o $(executable).exe
strip -s -R .comment -R .gnu.version $(executable).exe --strip-unneeded
@@ -21,11 +19,9 @@ windows_release:
@echo off
# Remove data
powershell if (Test-Path data\config) {Remove-Item data\config -Recurse -Force}
powershell if (Test-Path $(releaseFolder)) {Remove-Item $(releaseFolder) -Recurse -Force}
# Create folders
powershell if (-not (Test-Path data\config)) {New-Item data\config -ItemType Directory}
powershell if (-not (Test-Path $(releaseFolder))) {New-Item $(releaseFolder) -ItemType Directory}
# Copy data
@@ -37,31 +33,34 @@ windows_release:
# Remove data
powershell if (Test-Path "$(releaseFolder)\data\room\map.world") {Remove-Item "$(releaseFolder)\data\room\map.world" -Recurse -Force}
powershell if (Test-Path "$(releaseFolder)\data\room\standard.tsx") {Remove-Item "$(releaseFolder)\data\room\standard.tsx" -Recurse -Force}
powershell if (Test-Path "$(releaseFolder)\data\config") {Remove-Item "$(releaseFolder)\data\config" -Recurse -Force}
# Create data
powershell if (-not (Test-Path "$(releaseFolder)\data\config")) {New-Item "$(releaseFolder)\data\config" -ItemType Directory}
# Build
g++ $(source) -std=c++11 -Wall -Os -lmingw32 -lSDL2main -lSDL2 -ffunction-sections -fdata-sections -Wl,--gc-sections -static-libstdc++ -Wl,-subsystem,windows -o "$(releaseFolder)/$(executable).exe"
strip -s -R .comment -R .gnu.version "$(releaseFolder)/$(executable).exe" --strip-unneeded
# Create ZIP
powershell if (Test-Path $(executable)_win_$(version).zip) {Remove-Item $(windowsRelease)}
powershell if (Test-Path $(windowsRelease)) {Remove-Item $(windowsRelease)}
powershell Compress-Archive -Path "$(releaseFolder)"/* -DestinationPath $(windowsRelease)
# Remove folder
powershell if (Test-Path $(releaseFolder)) {Remove-Item $(releaseFolder) -Recurse -Force}
macos:
rm -rdf data/config
mkdir -p data/config
clang++ $(source) -D DEBUG -std=c++11 -Wall -Os -lSDL2 -ffunction-sections -fdata-sections -o $(executable)_macos
macos_release:
# Remove data
rm -rdf data/config
# Remove data and possible data
rm -rdf "$(releaseFolder)"
rm -rdf Frameworks
rm -f tmp.dmg
rm -f "$(macosIntelRelease)"
rm -f "$(macosAppleSiliconRelease)"
# Create folders
mkdir -p data/config
mkdir -p "$(releaseFolder)/$(appName).app/Contents/Frameworks"
mkdir -p "$(releaseFolder)/$(appName).app/Contents/MacOS"
mkdir -p "$(releaseFolder)/$(appName).app/Contents/Resources"
@@ -75,16 +74,21 @@ macos_release:
# Delete data
rm -f "$(releaseFolder)/$(appName).app/Contents/Resources/data/room/map.world"
rm -f "$(releaseFolder)/$(appName).app/Contents/Resources/data/room/standard.tsx"
rm -rdf "$(releaseFolder)/$(appName).app/Contents/Resources/data/config"
# Create folders
mkdir -p "$(releaseFolder)/$(appName).app/Contents/Resources/data/config"
# Copy files
cp release/*.icns "$(releaseFolder)/$(appName).app/Contents/Resources"
cp release/Info.plist "$(releaseFolder)/$(appName).app/Contents"
cp LICENSE "$(releaseFolder)"
cp README.md "$(releaseFolder)"
# Build INTEL
clang++ $(source) -D MACOS_BUNDLE -std=c++11 -Wall -Os -framework SDL2 -F ./Frameworks -ffunction-sections -fdata-sections -o "$(releaseFolder)/$(appName).app/Contents/MacOS/$(executable)" -rpath @executable_path/../Frameworks/ -target x86_64-apple-macos10.12
# Build INTEL DMG
rm -f "$(macosIntelRelease)"
hdiutil create tmp.dmg -ov -volname "$(appName)" -fs HFS+ -srcfolder "$(releaseFolder)"
hdiutil convert tmp.dmg -format UDZO -o "$(macosIntelRelease)"
rm -f tmp.dmg
@@ -93,7 +97,6 @@ macos_release:
clang++ $(source) -D MACOS_BUNDLE -std=c++11 -Wall -Os -framework SDL2 -F ./Frameworks -ffunction-sections -fdata-sections -o "$(releaseFolder)/$(appName).app/Contents/MacOS/$(executable)" -rpath @executable_path/../Frameworks/ -target arm64-apple-macos11
# Build APPLE SILICON DMG
rm -f "$(macosAppleSiliconRelease)"
hdiutil create tmp.dmg -ov -volname "$(appName)" -fs HFS+ -srcfolder "$(releaseFolder)"
hdiutil convert tmp.dmg -format UDZO -o "$(macosAppleSiliconRelease)"
rm -f tmp.dmg
@@ -103,18 +106,14 @@ macos_release:
rm -rdf "$(releaseFolder)"
linux:
rm -rdf data/config
mkdir -p data/config
g++ $(source) -D DEBUG -std=c++11 -Wall -Os -lSDL2 -ffunction-sections -fdata-sections -Wl,--gc-sections -o $(executable)_linux
strip -s -R .comment -R .gnu.version $(executable)_linux --strip-unneeded
linux_release:
# Remove data
rm -rdf data/config
rm -rdf $(releaseFolder)
# Create folders
mkdir -p data/config
mkdir -p $(releaseFolder)
# Copy data
@@ -125,6 +124,10 @@ linux_release:
# Delete data
rm -f "$(releaseFolder)/data/room/map.world"
rm -f "$(releaseFolder)/data/room/standard.tsx"
rm -rdf "$(releaseFolder)/data/config"
# Create folders
mkdir -p "$(releaseFolder)/data/config"
# Build
g++ $(source) -std=c++11 -Wall -Os -lSDL2 -ffunction-sections -fdata-sections -Wl,--gc-sections -o $(releaseFolder)/$(executable)

View File

@@ -48,9 +48,9 @@ animation=tuno.ani
width=16
height=16
x=28
y=8
y=6
vx=0
vy=0.4
vy=-0.4
x1=28
y1=2
x2=28

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleIdentifier</key>
<string>com.apple.xcode.dsym.jaildoctors_dilemma_debug</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>dSYM</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
</dict>
</plist>

View File

@@ -50,7 +50,10 @@ bool Asset::check()
if (verbose)
{
std::cout << "\n** Checking files." << std::endl;
std::cout << "\n** Checking files" << std::endl;
std::cout << "Executable path is: " << executablePath << std::endl;
std::cout << "Sample filepath: " << fileList.back().file << std::endl;
}
// Comprueba la lista de ficheros clasificandolos por tipo

View File

@@ -86,6 +86,8 @@ struct options_t
palette_e palette; // Paleta de colores a usar en el juego
bool console; // Indica si ha de mostrar información por la consola de texto
cheat_t cheat; // Contiene trucos y ventajas para el juego
int rooms; // Cantidad de habitaciones visitadas
int items; // Cantidad de items obtenidos
};
// Calcula el cuadrado de la distancia entre dos puntos

View File

@@ -14,67 +14,6 @@ Demo::Demo(SDL_Renderer *renderer, Screen *screen, Resource *resource, Asset *as
rooms.push_back("31.room");
rooms.push_back("44.room");
// rooms.push_back("01.room");
// rooms.push_back("02.room");
// rooms.push_back("03.room");
// rooms.push_back("04.room");
// rooms.push_back("05.room");
// rooms.push_back("06.room");
// rooms.push_back("07.room");
// rooms.push_back("08.room");
// rooms.push_back("09.room");
// rooms.push_back("10.room");
// rooms.push_back("11.room");
// rooms.push_back("12.room");
// rooms.push_back("13.room");
// rooms.push_back("14.room");
// rooms.push_back("15.room");
// rooms.push_back("16.room");
// rooms.push_back("17.room");
// rooms.push_back("18.room");
// rooms.push_back("19.room");
// rooms.push_back("20.room");
// rooms.push_back("21.room");
// rooms.push_back("22.room");
// rooms.push_back("23.room");
// rooms.push_back("24.room");
// rooms.push_back("25.room");
// rooms.push_back("26.room");
// rooms.push_back("27.room");
// rooms.push_back("28.room");
// rooms.push_back("29.room");
// rooms.push_back("30.room");
// rooms.push_back("31.room");
// rooms.push_back("32.room");
// rooms.push_back("33.room");
// rooms.push_back("34.room");
// rooms.push_back("35.room");
// rooms.push_back("36.room");
// rooms.push_back("37.room");
// rooms.push_back("38.room");
// rooms.push_back("39.room");
// rooms.push_back("40.room");
// rooms.push_back("41.room");
// rooms.push_back("42.room");
// rooms.push_back("43.room");
// rooms.push_back("44.room");
// rooms.push_back("45.room");
// rooms.push_back("46.room");
// rooms.push_back("47.room");
// rooms.push_back("48.room");
// rooms.push_back("49.room");
// rooms.push_back("50.room");
// rooms.push_back("51.room");
// rooms.push_back("52.room");
// rooms.push_back("53.room");
// rooms.push_back("54.room");
// rooms.push_back("55.room");
// rooms.push_back("56.room");
// rooms.push_back("57.room");
// rooms.push_back("58.room");
// rooms.push_back("59.room");
// rooms.push_back("60.room");
roomIndex = 0;
currentRoom = rooms.at(roomIndex);

View File

@@ -91,6 +91,8 @@ void Director::iniOptions()
options->cheat.invincible = false;
options->cheat.jailEnabled = false;
options->cheat.altSkin = false;
options->rooms = 0;
options->items = 0;
}
// Comprueba los parametros del programa
@@ -1039,6 +1041,7 @@ bool Director::setFileList()
// Configuración
asset->add(prefix + "/data/input/gamecontrollerdb.txt", t_data);
asset->add(prefix + "/data/config/config.txt", t_data, false);
asset->add(prefix + "/data/config/stats.txt", t_data, false);
// Habitaciones
asset->add(prefix + "/data/room/01.room", t_room);

View File

@@ -21,8 +21,8 @@ Game::Game(SDL_Renderer *renderer, Screen *screen, Resource *resource, Asset *as
this->options = options;
#ifdef DEBUG
currentRoom = "14.room";
const int x1 = 1;
currentRoom = "48.room";
const int x1 = 18;
const int y1 = 13;
spawnPoint = {x1 * 8, y1 * 8, 0, 0, 0, s_standing, SDL_FLIP_HORIZONTAL};
#endif
@@ -40,6 +40,8 @@ Game::Game(SDL_Renderer *renderer, Screen *screen, Resource *resource, Asset *as
text = new Text(resource->getOffset("smb2.txt"), resource->getTexture("smb2.png"), renderer);
music = JA_LoadMusic(asset->get("game.ogg").c_str());
deathSound = JA_LoadSound(asset->get("death.wav").c_str());
stats = new Stats(asset->get("stats.txt"));
stats->addVisit(room->getName());
// Inicializa el resto de variables
ticks = 0;
@@ -70,6 +72,7 @@ Game::~Game()
delete player;
delete eventHandler;
delete text;
delete stats;
JA_DeleteMusic(music);
JA_DeleteSound(deathSound);
@@ -89,6 +92,11 @@ void Game::checkEventHandler()
break;
}
if (eventHandler->type == SDL_RENDER_DEVICE_RESET || eventHandler->type == SDL_RENDER_TARGETS_RESET)
{
reLoadTextures();
}
if ((eventHandler->type == SDL_KEYDOWN) and (eventHandler->key.repeat == 0))
{
switch (eventHandler->key.keysym.scancode)
@@ -207,8 +215,11 @@ void Game::update()
// Comprueba los eventos de la cola
checkEventHandler();
// Actualiza los objetos
#ifdef DEBUG
debug->clear();
#endif
// Actualiza los objetos
room->update();
player->update();
checkPlayerOnBorder();
@@ -220,9 +231,11 @@ void Game::update()
scoreboard->update();
input->update();
updateDebugInfo();
updateBlackScreen();
screen->updateFX();
#ifdef DEBUG
updateDebugInfo();
#endif
}
}
@@ -241,14 +254,16 @@ void Game::render()
scoreboard->render();
renderBlackScreen();
#ifdef DEBUG
// Debug info
renderDebugInfo();
// screen->renderFX();
#endif
// Actualiza la pantalla
screen->blit();
}
#ifdef DEBUG
// Pasa la información de debug
void Game::updateDebugInfo()
{
@@ -285,6 +300,7 @@ void Game::renderDebugInfo()
debug->setPos({1, 18 * 8});
debug->render();
}
#endif
// Escribe el nombre de la pantalla
void Game::renderRoomName()
@@ -321,8 +337,13 @@ bool Game::changeRoom(std::string file)
setScoreBoardColor();
if (roomTracker->addRoom(file))
{ // Incrementa el contador de habitaciones visitadas
{
// Incrementa el contador de habitaciones visitadas
board.rooms++;
options->rooms = board.rooms;
// Actualiza las estadisticas
stats->addVisit(room->getName());
}
// Pasa la nueva habitación al jugador
@@ -398,6 +419,9 @@ void Game::killPlayer()
board.lives--;
}
// Actualiza las estadisticas
stats->addDeath(room->getName());
// Destruye la habitacion y el jugador
delete room;
delete this->player;

View File

@@ -17,6 +17,7 @@
#include "room_tracker.h"
#include "room.h"
#include "scoreboard.h"
#include "stats.h"
#ifndef GAME_H
#define GAME_H
@@ -39,6 +40,7 @@ private:
Resource *resource; // Objeto con los recursos
Debug *debug; // Objeto para gestionar la información de debug
options_t *options; // Puntero a las opciones del juego
Stats *stats; // Objeto encargado de gestionar las estadísticas
// Variables
JA_Music music; // Musica que suena durante el juego
@@ -63,11 +65,13 @@ private:
// Comprueba los eventos de la cola
void checkEventHandler();
#ifdef DEBUG
// Pone la información de debug en pantalla
void updateDebugInfo();
// Pone la información de debug en pantalla
void renderDebugInfo();
#endif
// Escribe el nombre de la pantalla
void renderRoomName();

View File

@@ -28,9 +28,9 @@ GameOver::GameOver(SDL_Renderer *renderer, Screen *screen, Resource *resource, A
iniFade = 310;
fadeLenght = 20;
playerSprite->setPosX(GAMECANVAS_CENTER_X + 10);
playerSprite->setPosY(GAMECANVAS_CENTER_Y + 10);
playerSprite->setPosY(GAMECANVAS_CENTER_Y - 10);
tvSprite->setPosX(GAMECANVAS_CENTER_X - tvSprite->getAnimationClip(0, 0).w - 10);
tvSprite->setPosY(GAMECANVAS_CENTER_Y + 10);
tvSprite->setPosY(GAMECANVAS_CENTER_Y - 10);
// Inicializa el vector de colores
const std::vector<std::string> colorList = {"white", "yellow", "cyan", "green", "magenta", "red", "blue", "black"};
@@ -86,12 +86,17 @@ void GameOver::render()
screen->clean();
// Escribe el texto de GAME OVER
text->writeDX(TXT_CENTER | TXT_COLOR, GAMECANVAS_CENTER_X, GAMECANVAS_CENTER_Y - 20, "G A M E O V E R", 1, color);
text->writeDX(TXT_CENTER | TXT_COLOR, GAMECANVAS_CENTER_X, GAMECANVAS_CENTER_Y - 40, "G A M E O V E R", 1, color);
// Dibuja los sprites
renderSprites();
// text->write(0, 0, std::to_string(counter));
// Escribe el texto con las habitaciones y los items
const std::string itemsTxt = std::to_string(options->items / 100) + std::to_string((options->items % 100) / 10) + std::to_string(options->items % 10);
const std::string roomsTxt = std::to_string(options->rooms / 100) + std::to_string((options->rooms % 100) / 10) + std::to_string(options->rooms % 10);
text->writeDX(TXT_CENTER | TXT_COLOR, GAMECANVAS_CENTER_X, GAMECANVAS_CENTER_Y + 40, "ITEMS: " + itemsTxt, 1, color);
text->writeDX(TXT_CENTER | TXT_COLOR, GAMECANVAS_CENTER_X, GAMECANVAS_CENTER_Y + 55, "ROOMS: " + roomsTxt, 1, color);
// Vuelca el contenido del renderizador en pantalla
screen->blit();
@@ -180,7 +185,7 @@ void GameOver::updateColor()
if (counter < half)
{
//const float step = std::min(std::max(counter, iniFade) - iniFade, fadeLenght) / (float)fadeLenght;
// const float step = std::min(std::max(counter, iniFade) - iniFade, fadeLenght) / (float)fadeLenght;
const float step = std::min(counter, fadeLenght) / (float)fadeLenght;
const int index = (colors.size() - 1) - int((colors.size() - 1) * step);
color = colors.at(index);

View File

@@ -93,9 +93,15 @@ Player::Player(player_t player)
fallSound.push_back(JA_LoadSound(asset->get("jump23.wav").c_str()));
fallSound.push_back(JA_LoadSound(asset->get("jump24.wav").c_str()));
r = {0, 0, 0, 0};
jumpCounter = 0;
fallCounter = 0;
#ifdef DEBUG
rx = {0, 0, 0, 0};
ry = {0, 0, 0, 0};
debugColor = {0, 255, 0};
debugPoint = {0, 0};
#endif
}
// Destructor
@@ -114,6 +120,8 @@ void Player::render()
{
sprite->getTexture()->setColor(color.r, color.g, color.b);
sprite->render();
#ifdef DEBUG
if (debug->getEnabled())
{
// Pinta los underfeet
@@ -122,14 +130,28 @@ void Player::render()
SDL_RenderDrawPoint(renderer, underFeet[1].x, underFeet[1].y);
// Pinta rectangulo del jugador
SDL_SetRenderDrawColor(renderer, 0, 255, 0, 192);
SDL_SetRenderDrawColor(renderer, debugColor.r, debugColor.g, debugColor.b, 192);
SDL_Rect rect = getRect();
SDL_RenderFillRect(renderer, &rect);
SDL_SetRenderDrawColor(renderer, 0, 255, 255, 255);
SDL_RenderDrawRect(renderer, &rect);
// Pinta el rectangulo de movimiento
SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
SDL_RenderFillRect(renderer, &r);
if (vx != 0.0f)
{
SDL_RenderFillRect(renderer, &rx);
}
if (vy != 0.0f)
{
SDL_RenderFillRect(renderer, &ry);
}
// Pinta el punto de debug
SDL_SetRenderDrawColor(renderer, rand() % 256, rand() % 256, rand() % 256, 255);
SDL_RenderDrawPoint(renderer, debugPoint.x, debugPoint.y);
}
#endif
}
// Actualiza las variables del objeto
@@ -231,21 +253,25 @@ void Player::checkBorders()
border = BORDER_LEFT;
onBorder = true;
}
else if (x > PLAY_AREA_RIGHT - w)
{
border = BORDER_RIGHT;
onBorder = true;
}
else if (y < PLAY_AREA_TOP)
{
border = BORDER_TOP;
onBorder = true;
}
else if (y > PLAY_AREA_BOTTOM - h)
{
border = BORDER_BOTTOM;
onBorder = true;
}
else
{
onBorder = false;
@@ -273,7 +299,7 @@ void Player::checkState()
vy = 0.0f;
jumpCounter = 0;
fallCounter = 0;
if (!isOnFloor() && !isOnAutoSurface())
if (!isOnFloor() && !isOnAutoSurface() && !isOnDownSlope())
{
setState(s_falling);
vx = 0.0f;
@@ -353,6 +379,10 @@ void Player::move()
applyGravity(); // Aplica gravedad al jugador
checkState(); // Comprueba el estado del jugador
#ifdef DEBUG
debugColor = {0, 255, 0};
#endif
// Se mueve hacia la izquierda
if (vx < 0.0f)
{
@@ -363,7 +393,9 @@ void Player::move()
proj.h = h;
proj.w = ceil(abs(vx)); // Para evitar que tenga un ancho de 0 pixels
r = proj;
#ifdef DEBUG
rx = proj;
#endif
// Comprueba la colisión con las superficies
const int pos = room->checkRightSurfaces(&proj);
@@ -406,7 +438,9 @@ void Player::move()
proj.h = h;
proj.w = ceil(vx); // Para evitar que tenga un ancho de 0 pixels
r = proj;
#ifdef DEBUG
rx = proj;
#endif
// Comprueba la colisión
const int pos = room->checkLeftSurfaces(&proj);
@@ -465,7 +499,9 @@ void Player::move()
proj.h = ceil(abs(vy)); // Para evitar que tenga una altura de 0 pixels
proj.w = w;
r = proj;
#ifdef DEBUG
ry = proj;
#endif
// Comprueba la colisión
const int pos = room->checkBottomSurfaces(&proj);
@@ -492,7 +528,9 @@ void Player::move()
proj.h = ceil(vy); // Para evitar que tenga una altura de 0 pixels
proj.w = w;
r = proj;
#ifdef DEBUG
ry = proj;
#endif
// Comprueba la colisión con las superficies normales y las automáticas
const int pos = std::max(room->checkTopSurfaces(&proj), room->checkAutoSurfaces(&proj));
@@ -516,11 +554,18 @@ void Player::move()
// Calcula la nueva posición
y = p - h;
setState(s_standing);
#ifdef DEBUG
debugColor = {255, 255, 0};
debugPoint = {(int)x + (w / 2), p};
#endif
}
else
{ // No está saltando y no hay colisón con una rampa
// Calcula la nueva posición
y += vy;
#ifdef DEBUG
debugColor = {255, 0, 0};
#endif
}
}
else
@@ -535,7 +580,10 @@ void Player::move()
sprite->setPosX(x);
sprite->setPosY(y);
debug->add("RECT: " + std::to_string(r.x) + "," + std::to_string(r.y) + "," + std::to_string(r.w) + "," + std::to_string(r.h));
#ifdef DEBUG
debug->add("RECT_X: " + std::to_string(rx.x) + "," + std::to_string(rx.y) + "," + std::to_string(rx.w) + "," + std::to_string(rx.h));
debug->add("RECT_Y: " + std::to_string(ry.x) + "," + std::to_string(ry.y) + "," + std::to_string(ry.w) + "," + std::to_string(ry.h));
#endif
}
// Establece la animación del jugador
@@ -571,7 +619,10 @@ void Player::playJumpSound()
{
JA_PlaySound(jumpSound[jumpCounter / 4]);
}
#ifdef DEBUG
debug->add("JUMP: " + std::to_string(jumpCounter / 4));
#endif
}
// Calcula y reproduce el sonido de caer
@@ -581,7 +632,10 @@ void Player::playFallSound()
{
JA_PlaySound(fallSound[std::min((fallCounter / 4), (int)fallSound.size() - 1)]);
}
#ifdef DEBUG
debug->add("FALL: " + std::to_string(fallCounter / 4));
#endif
}
// Comprueba si el jugador tiene suelo debajo de los pies
@@ -604,6 +658,7 @@ bool Player::isOnFloor()
onSlopeL = room->checkLeftSlopes(&underFeet[0]);
onSlopeR = room->checkRightSlopes(&underFeet[1]);
#ifdef DEBUG
if (onFloor)
{
debug->add("ON_FLOOR");
@@ -618,6 +673,7 @@ bool Player::isOnFloor()
{
debug->add("ON_SLOPE_R: " + std::to_string(underFeet[1].x) + "," + std::to_string(underFeet[1].y));
}
#endif
return onFloor || onSlopeL || onSlopeR;
}
@@ -635,10 +691,12 @@ bool Player::isOnAutoSurface()
onAutoSurface |= room->checkAutoSurfaces(&f);
}
#ifdef DEBUG
if (onAutoSurface)
{
debug->add("ON_AUTO_SURFACE");
}
#endif
return onAutoSurface;
}
@@ -659,10 +717,12 @@ bool Player::isOnDownSlope()
onSlope |= room->checkLeftSlopes(&underFeet[0]);
onSlope |= room->checkRightSlopes(&underFeet[1]);
#ifdef DEBUG
if (onSlope)
{
debug->add("ON_DOWN_SLOPE");
}
#endif
return onSlope;
}

View File

@@ -87,7 +87,13 @@ public:
int fallCounter; // Cuenta el tiempo de caida
bool alive; // Indica si el jugador esta vivo o no
int maxFallHeight; // Altura maxima permitida de caída.
SDL_Rect r;
#ifdef DEBUG
SDL_Rect rx; // Rectangulo de desplazamiento para el modo debug
SDL_Rect ry; // Rectangulo de desplazamiento para el modo debug
color_t debugColor; // Color del recuadro de debug del jugador
SDL_Point debugPoint; // Punto para debug
#endif
// Comprueba las entradas y modifica variables
void checkInput();

View File

@@ -554,6 +554,7 @@ void Room::fillMapTexture()
clip.y = (tileMap.at(index) / tileSetWidth) * tileSize;
texture->render(renderer, x * tileSize, y * tileSize, &clip);
#ifdef DEBUG
// ****
if (debug->getEnabled())
{
@@ -565,10 +566,12 @@ void Room::fillMapTexture()
SDL_RenderFillRect(renderer, &clip);
}
}
// ****
// ****
#endif
}
}
#ifdef DEBUG
// ****
if (debug->getEnabled())
{
@@ -649,6 +652,7 @@ void Room::fillMapTexture()
}
}
// ****
#endif
SDL_SetRenderTarget(renderer, nullptr);
}
@@ -659,11 +663,15 @@ void Room::renderMap()
// Dibuja la textura con el mapa en pantalla
SDL_RenderCopy(renderer, mapTexture, nullptr, nullptr);
// Dibuja los tiles animados
// Dibuja los tiles animados
#ifdef DEBUG
if (!debug->getEnabled())
{
renderAnimatedTiles();
}
#else
renderAnimatedTiles();
#endif
}
// Dibuja los enemigos en pantalla
@@ -816,6 +824,7 @@ bool Room::itemCollision(SDL_Rect &rect)
items.erase(items.begin() + i);
JA_PlaySound(itemSound);
*itemsPicked = *itemsPicked + 1;
options->items = *itemsPicked;
return true;
}
}
@@ -882,22 +891,30 @@ int Room::getSlopeHeight(SDL_Point p, tile_e slope)
{
// Calcula la base del tile
int base = ((p.y / tileSize) * tileSize) + tileSize;
#ifdef DEBUG
debug->add("BASE = " + std::to_string(base));
#endif
// Calcula cuanto se ha entrado en el tile horizontalmente
const int pos = (p.x % tileSize); // Esto da un valor entre 0 y 7
#ifdef DEBUG
debug->add("POS = " + std::to_string(pos));
#endif
// Se resta a la base la cantidad de pixeles pos en funcion de la rampa
if (slope == t_slope_r)
{
base -= pos + 1;
#ifdef DEBUG
debug->add("BASE_R = " + std::to_string(base));
#endif
}
else
{
base -= (tileSize - pos);
#ifdef DEBUG
debug->add("BASE_L = " + std::to_string(base));
#endif
}
return base;

147
source/stats.cpp Normal file
View File

@@ -0,0 +1,147 @@
#include "stats.h"
#include <iostream>
#include <fstream>
#include <sstream>
// Constructor
Stats::Stats(std::string file)
{
filePath = file;
list.clear();
loadFromFile();
}
// Destructor
Stats::~Stats()
{
saveToFile();
list.clear();
}
// Añade una muerte a las estadisticas
void Stats::addDeath(std::string name)
{
// Primero busca si ya hay una entrada con ese nombre
const int index = findByName(name);
if (index != -1)
{
list.at(index).died++;
}
// En caso contrario crea la entrada
else
{
stats_t item;
item.name = name;
item.visited = 0;
item.died = 1;
list.push_back(item);
}
}
// Añade una visita a las estadisticas
void Stats::addVisit(std::string name)
{
// Primero busca si ya hay una entrada con ese nombre
const int index = findByName(name);
if (index != -1)
{
list.at(index).visited++;
}
// En caso contrario crea la entrada
else
{
stats_t item;
item.name = name;
item.visited = 1;
item.died = 0;
list.push_back(item);
}
}
// Busca una entrada en la lista por nombre
int Stats::findByName(std::string name)
{
int i = 0;
for (auto l : list)
{
if (l.name == name)
{
return i;
}
i++;
}
return -1;
}
// Carga las estadisticas desde un fichero
bool Stats::loadFromFile()
{
// Indicador de éxito en la carga
bool success = true;
// Variables para manejar el fichero
std::string line;
std::ifstream file(filePath);
// Si el fichero se puede abrir
if (file.good())
{
// Procesa el fichero linea a linea
while (std::getline(file, line))
{
// Comprueba que la linea no sea un comentario
if (line.substr(0, 1) != "#")
{
stats_t stat;
std::stringstream ss(line);
std::string tmp;
// Obtiene el nombre
getline(ss, tmp, ';');
stat.name = tmp;
// Obtiene las visitas
getline(ss, tmp, ';');
stat.visited = std::stoi(tmp);
// Obtiene las muertes
getline(ss, tmp, ';');
stat.died = std::stoi(tmp);
list.push_back(stat);
}
}
// Cierra el fichero
file.close();
}
// El fichero no existe
else
{ // Crea el fichero con los valores por defecto
saveToFile();
}
return success;
}
// Guarda las estadisticas en un fichero
void Stats::saveToFile()
{
// Crea y abre el fichero de texto
std::ofstream file(filePath);
// Escribe en el fichero
file << "# NOMBRE DE LA HABITACION;VISITAS;MUERTES" << std::endl;
for (auto item : list)
{
file << item.name << ";" << item.visited << ";" << item.died << std::endl;
}
// Cierra el fichero
file.close();
}

47
source/stats.h Normal file
View File

@@ -0,0 +1,47 @@
#pragma once
#include <SDL2/SDL.h>
#include "common/utils.h"
#include <string>
#include <vector>
#ifndef STATS_H
#define STATS_H
struct stats_t
{
std::string name; // Nombre de la habitación donde se encuentra el objeto
int visited; // Cuenta las veces que se ha visitado una habitación
int died; // Cuenta las veces que se ha muerto en una habitación
};
class Stats
{
private:
// Variables
std::vector<stats_t> list; // Lista con las estadisticas por habitación
std::string filePath; // Fichero con las estadísticas
// Busca una entrada en la lista por nombre
int findByName(std::string name);
// Carga las estadisticas desde un fichero
bool loadFromFile();
// Guarda las estadisticas en un fichero
void saveToFile();
public:
// Constructor
Stats(std::string file);
// Destructor
~Stats();
// Añade una muerte a las estadisticas
void addDeath(std::string name);
// Añade una visita a las estadisticas
void addVisit(std::string name);
};
#endif

View File

@@ -1,74 +0,0 @@
#include "test.h"
// Constructor
Test::Test(SDL_Renderer *renderer, Screen *screen, Asset *asset, Debug *debug)
{
// Copia la dirección de los objetos
this->renderer = renderer;
this->screen = screen;
this->asset = asset;
this->debug = debug;
// Inicializa variables
for (int i = 0; i < 4; ++i)
{
point_t p;
p.x = rand() % 256;
p.y = rand() % 192;
p.vx = (float)((rand() % 10) + 1) / 10.0f;
p.vy = (float)((rand() % 10) + 1) / 10.0f;
rand() % 2 == 0 ? p.dx = -1 : p.dx = 1;
rand() % 2 == 0 ? p.dy = -1 : p.dy = 1;
p.vx *= p.dx;
p.vy *= p.dy;
points.push_back(p);
}
}
// Actualiza las variables
void Test::update()
{
for (int i = 0; i < (int)points.size(); ++i)
{
points[i].x += points[i].vx;
points[i].y += points[i].vy;
if (points[i].x > 255)
{
points[i].x = 255;
points[i].vx = -(float)((rand() % 10) + 1) / 10.0f;
}
else if (points[i].x < 0)
{
points[i].x = 0;
points[i].vx = (float)((rand() % 10) + 1) / 10.0f;
}
if (points[i].y > 191)
{
points[i].y = 191;
points[i].vy = -(float)((rand() % 10) + 1) / 10.0f;
}
else if (points[i].y < 0)
{
points[i].y = 0;
points[i].vy = (float)((rand() % 10) + 1) / 10.0f;
}
std::string text = "P" + std::to_string(i) + ": x=" + std::to_string(points[i].x).substr(0,3) + " y=" + std::to_string(points[i].y).substr(0,3) + " vx=" + std::to_string(points[i].vx).substr(0,3) + " vy=" + std::to_string(points[i].vy).substr(0,3);
debug->add(text);
}
}
// Dibuja en pantalla
void Test::render()
{
SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
line_t l1 = {(int)points[0].x, (int)points[0].y, (int)points[1].x, (int)points[1].y};
line_t l2 = {(int)points[2].x, (int)points[2].y, (int)points[3].x, (int)points[3].y};
SDL_RenderDrawLine(renderer, l1.x1, l1.y1, l1.x2, l1.y2);
SDL_RenderDrawLine(renderer, l2.x1, l2.y1, l2.x2, l2.y2);
SDL_SetRenderDrawColor(renderer, 0, 255, 0, 255);
SDL_Point p = checkCollision(l1, l2);
SDL_RenderDrawPoint(renderer, p.x, p.y);
}

View File

@@ -1,46 +0,0 @@
#pragma once
#include <SDL2/SDL.h>
#include "common/asset.h"
#include "common/debug.h"
#include "common/screen.h"
#include "common/text.h"
#include "common/utils.h"
#include "const.h"
#include <string>
#include <vector>
#ifndef TEST_H
#define TEST_H
struct point_t
{
float x, y;
float vx, vy;
int dx, dy;
};
class Test
{
private:
// Objetos y punteros
SDL_Renderer *renderer; // El renderizador de la ventana
Screen *screen; // Objeto encargado de dibujar en pantalla
Asset *asset; // Objeto con los ficheros de recursos
Debug *debug;
// Variables
std::vector<point_t> points;
public:
// Constructor
Test(SDL_Renderer *renderer, Screen *screen, Asset *asset, Debug *debug);
// Actualiza las variables
void update();
// Dibuja en pantalla
void render();
};
#endif