30 Commits
v1.01 ... v1.05

Author SHA1 Message Date
1b49097f80 Cambiado el tamaño por defecto del borde 2022-11-19 09:27:55 +01:00
859e3f3b44 Actualizado Makefile 2022-11-19 09:27:24 +01:00
3fa7657c79 Cuendo el jugador entra a la Jail, recupera todas sus vidas 2022-11-19 09:22:10 +01:00
e90c61a416 FIx: El jugador no se moria al caer de alto si se mantenia la tecla de slto pulsada 2022-11-19 09:02:35 +01:00
d003b51de4 Reparada la clase Screen 2022-11-19 07:49:01 +01:00
8d381010c8 Trabajando en la clase Screen 2022-11-19 07:37:03 +01:00
2216c9632e Trabajando en las notificaciones 2022-11-18 23:15:38 +01:00
fdc8797d2b Arreglada la clase Screen. Había un lio de conceptos con varias variables 2022-11-18 20:09:03 +01:00
90bdad7d51 Modificado Makefile 2022-11-18 10:43:54 +01:00
d50b193d9f Cambiado el fichero de estadisticas a stats.csv 2022-11-18 10:43:01 +01:00
ee885d5ca7 Ya crea correctamente la carpeta de sistema en las tres plataformas 2022-11-18 10:40:51 +01:00
bb3a0f263b Ya crea la carpeta de sistema en MacOS y Windows 2022-11-18 10:35:15 +01:00
85d6c48f42 Ya crea la carpeta de sistema en Linux 2022-11-18 09:48:46 +01:00
896dd9daef Trabajando en el guardado de las estadisticas en las carpetas del sistema 2022-11-18 07:32:15 +01:00
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
31 changed files with 1221 additions and 356 deletions

3
.gitignore vendored
View File

@@ -1,5 +1,6 @@
.vscode .vscode
*config.txt *config.txt
*stats.txt
*.DS_Store *.DS_Store
thumbs.db thumbs.db
*.exe *.exe
@@ -9,4 +10,4 @@ thumbs.db
*.tar.gz *.tar.gz
*.zip *.zip
*.app *.app
*_debug *_debug*

View File

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

View File

@@ -10,10 +10,10 @@ Asset::Asset(std::string executablePath)
} }
// Añade un elemento a la lista // Añade un elemento a la lista
void Asset::add(std::string file, enum assetType type, bool required) void Asset::add(std::string file, enum assetType type, bool required, bool absolute)
{ {
item_t temp; item_t temp;
temp.file = executablePath + file; temp.file = absolute ? file : executablePath + file;
temp.type = type; temp.type = type;
temp.required = required; temp.required = required;
fileList.push_back(temp); fileList.push_back(temp);
@@ -50,7 +50,10 @@ bool Asset::check()
if (verbose) 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 // Comprueba la lista de ficheros clasificandolos por tipo

View File

@@ -31,6 +31,7 @@ private:
std::string file; // Ruta del fichero desde la raiz del directorio std::string file; // Ruta del fichero desde la raiz del directorio
enum assetType type; // Indica el tipo de recurso enum assetType type; // Indica el tipo de recurso
bool required; // Indica si es un fichero que debe de existir bool required; // Indica si es un fichero que debe de existir
//bool absolute; // Indica si la ruta que se ha proporcionado es una ruta absoluta
}; };
// Variables // Variables
@@ -50,7 +51,7 @@ public:
Asset(std::string path); Asset(std::string path);
// Añade un elemento a la lista // Añade un elemento a la lista
void add(std::string file, enum assetType type, bool required = true); void add(std::string file, enum assetType type, bool required = true, bool absolute = false);
// Devuelve un elemento de la lista a partir de una cadena // Devuelve un elemento de la lista a partir de una cadena
std::string get(std::string text); std::string get(std::string text);

154
source/common/jscore.cpp Normal file
View File

@@ -0,0 +1,154 @@
#include "jscore.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#ifdef _WIN32
#include <winsock2.h>
#else
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#endif
#include <unistd.h>
#include <string>
#include <vector>
namespace jscore {
using namespace std;
struct user {
string name;
int points;
};
vector<user> score;
#define bzero(b,len) (memset((b), '\0', (len)), (void) 0)
int sock;
struct sockaddr_in client;
int PORT = 9911;
string HOST = "jaildoctor.duckdns.org";
#ifdef WIN32
WSADATA WsaData;
#endif
bool jscore_error = false;
string error_message;
void init(std::string host, const int port) {
PORT = port;
HOST = host;
}
void setErrorMessage(string message) {
jscore_error = true;
error_message = message;
}
string sendRequest(const string request) {
#ifdef WIN32
int ret = WSAStartup(0x101,&WsaData);
if (ret != 0) return 0;
#endif
struct hostent * host = gethostbyname(HOST.c_str());
if ( (host == NULL) || (host->h_addr == NULL) ) {
setErrorMessage("Error retrieving DNS information.\n");
return "";
}
bzero(&client, sizeof(client));
client.sin_family = AF_INET;
client.sin_port = htons( PORT );
memcpy(&client.sin_addr, host->h_addr, host->h_length);
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0) {
setErrorMessage("Error creating socket.\n");
return "";
}
if ( connect(sock, (struct sockaddr *)&client, sizeof(client)) < 0 ) {
close(sock);
setErrorMessage("Could not connect\n");
return "";
}
string r = request + " HTTP/1.1\r\nHost: "+HOST+"\r\nConnection: close\r\n\r\n\r\n";
if (send(sock, r.c_str(), r.length(), 0) != (int)r.length()) {
setErrorMessage("Error sending request.\n");
return "";
}
char cur;
char start[5]="\r\n\r\n";
int pos = 0;
while ( recv(sock, &cur, 1,0) > 0 ) {
if (cur==start[pos]) { pos++; if (pos == 4) break; } else { pos = 0; }
}
char buffer[1024]; buffer[0]=0; pos=0;
while ( recv(sock, &cur, 1,0) > 0 ) {
buffer[pos] = cur;
pos++;
}
#ifdef WIN32
WSACleanup();
#endif
buffer[pos]=0;
return buffer;
}
const bool initOnlineScore(string game) {
string strbuff = sendRequest("GET /score-list.php?game=" + game);
if (jscore_error) return not jscore_error;
user u;
char buffer[1024];
strcpy(buffer, strbuff.c_str());
char *str = buffer;
char *p = str;
score.clear();
while (*p!=0) {
while (*p!=',') {p++;}
*p=0; u.name = str; p++; str=p;
while (*p!='\n') {p++;}
*p=0; u.points = atoi(str); p++; str=p;
score.push_back(u);
}
return not jscore_error;
}
const int getNumUsers() {
return score.size();
}
string getUserName(const int index) {
return score[index].name;
}
const int getPoints(const int index) {
return score[index].points;
}
const bool updateUserPoints(string game, string user, const int points) {
string strbuff = sendRequest("GET /score-update.php?game=" + game + "&user=" + user + "&points=" + to_string(points));
initOnlineScore(game);
return not jscore_error;
}
const int getUserPoints(string game, std::string user) {
return atoi(sendRequest("GET /getuserpoints.php?game=" + game + "&user=" + user).c_str());
}
string getUserData(string game, string user) {
return sendRequest("GET /getuserdata.php?game=" + game + "&user=" + user);
}
void setUserData(string game, string user, string data) {
sendRequest("GET /setuserdata.php?game=" + game + "&user=" + user + "&data=" + data);
}
};

16
source/common/jscore.h Normal file
View File

@@ -0,0 +1,16 @@
#pragma once
#include <string>
namespace jscore {
void init(std::string host, const int port);
const bool initOnlineScore(std::string game);
const int getNumUsers();
std::string getUserName(const int index);
const int getPoints(const int index);
const int getUserPoints(std::string game, std::string user);
const bool updateUserPoints(std::string game, std::string user, const int points);
std::string getUserData(std::string game, std::string user);
void setUserData(std::string game, std::string user, std::string data);
};

162
source/common/notify.cpp Normal file
View File

@@ -0,0 +1,162 @@
#include "notify.h"
#include <string>
#include <stdio.h>
#include <iostream>
// Constructor
Notify::Notify(SDL_Renderer *renderer, std::string bitmapFile, std::string textFile)
{
// Inicializa variables
this->renderer = renderer;
bgColor = {64, 64, 64};
waitTime = 300;
// Crea objetos
texture = new Texture(renderer, bitmapFile);
text = new Text(textFile, texture, renderer);
}
// Destructor
Notify::~Notify()
{
// Libera la memoria de los objetos
delete texture;
delete text;
for (auto notification : notifications)
{
delete notification.sprite;
delete notification.texture;
}
}
// Dibuja las notificaciones por pantalla
void Notify::render()
{
for (int i = (int)notifications.size() - 1; i >= 0; --i)
{
notifications.at(i).sprite->render();
}
}
// Actualiza el estado de las notificaiones
void Notify::update()
{
for (int i = 0; i < (int)notifications.size(); ++i)
{
notifications.at(i).counter++;
// Comprueba los estados
if (notifications.at(i).state == ns_rising)
{
const float step = ((float)notifications.at(i).counter / notifications.at(i).travelDist);
const int alpha = 255 * step;
notifications.at(i).rect.y++;
notifications.at(i).texture->setAlpha(alpha);
if (notifications.at(i).rect.y == notifications.at(i).y)
{
notifications.at(i).state = ns_stay;
notifications.at(i).texture->setAlpha(255);
notifications.at(i).counter = 0;
}
}
else if (notifications.at(i).state == ns_stay)
{
if (notifications.at(i).counter == waitTime)
{
notifications.at(i).state = ns_vanishing;
notifications.at(i).counter = 0;
}
}
else if (notifications.at(i).state == ns_vanishing)
{
const float step = (notifications.at(i).counter / (float)notifications.at(i).travelDist);
const int alpha = 255 * (1 - step);
notifications.at(i).rect.y--;
notifications.at(i).texture->setAlpha(alpha);
if (notifications.at(i).rect.y == notifications.at(i).y - notifications.at(i).travelDist)
{
notifications.at(i).state = ns_finished;
}
}
notifications.at(i).sprite->setRect(notifications.at(i).rect);
}
clearFinishedNotifications();
}
// Elimina las notificaciones finalizadas
void Notify::clearFinishedNotifications()
{
for (int i = (int)notifications.size() - 1; i >= 0; --i)
{
if (notifications.at(i).state == ns_finished)
{
delete notifications.at(i).sprite;
delete notifications.at(i).texture;
notifications.erase(notifications.begin() + i);
}
}
}
// Muestra una notificación de texto por pantalla;
void Notify::showText(std::string text)
{
// Crea constantes
const int width = this->text->lenght(text) + (this->text->getCharacterSize() * 2);
const int height = this->text->getCharacterSize() * 2;
const int despH = this->text->getCharacterSize() / 2;
const int despV = despH;
const int travelDist = height + despV;
const int offset = (int)notifications.size() > 0 ? notifications.back().y + travelDist : despV;
// Crea la notificacion
notification_t n;
// inicializa variables
n.y = offset;
n.travelDist = travelDist;
n.counter = 0;
n.state = ns_rising;
n.text = text;
n.rect = {despH, offset - travelDist, width, height};
// Crea la textura
n.texture = new Texture(renderer);
n.texture->createBlank(renderer, width, height, SDL_TEXTUREACCESS_TARGET);
n.texture->setAsRenderTarget(renderer);
SDL_SetRenderDrawColor(renderer, bgColor.r, bgColor.g, bgColor.b, 255);
SDL_RenderClear(renderer);
n.texture->setBlendMode(SDL_BLENDMODE_BLEND);
this->text->writeDX(TXT_CENTER | TXT_STROKE, width / 2, despV, text, 1, {255, 255, 255}, 1, {0, 0, 0});
// Crea el sprite
n.sprite = new Sprite(n.rect, n.texture, renderer);
// Añade la notificación a la lista
notifications.push_back(n);
//std::cout << "Notification " << notifications.size() << std::endl;
//std::cout << "width " << width << std::endl;
//std::cout << "height " << height << std::endl;
//std::cout << "offset " << offset << std::endl;
//std::cout << "desp " << despH << std::endl;
}
// Indica si hay notificaciones activas
bool Notify::active()
{
if ((int)notifications.size() > 0)
{
return true;
}
return false;
}

82
source/common/notify.h Normal file
View File

@@ -0,0 +1,82 @@
#pragma once
#include <SDL2/SDL.h>
#include "text.h"
#include "texture.h"
#include "sprite.h"
#include "utils.h"
#include <vector>
#ifndef NOTIFY_H
#define NOTIFY_H
class Notify
{
private:
enum notification_state_e
{
ns_rising,
ns_stay,
ns_vanishing,
ns_finished
};
enum notification_position_e
{
upperLeft,
upperCenter,
upperRight,
middleLeft,
middleRight,
bottomLeft,
bottomCenter,
bottomRight
};
struct notification_t
{
std::string text;
int counter;
notification_state_e state;
notification_position_e position;
Texture *texture;
Sprite *sprite;
SDL_Rect rect;
int y;
int travelDist;
};
// Objetos y punteros
SDL_Renderer *renderer; // El renderizador de la ventana
Texture *texture; // Textura para la fuente de las notificaciones
Text *text; // Objeto para dibujar texto
// Variables
color_t bgColor; // Color de fondo de las notificaciones
int waitTime; // Tiempo que se ve la notificación
std::vector<notification_t> notifications; // La lista de notificaciones activas
// Elimina las notificaciones finalizadas
void clearFinishedNotifications();
public:
// Dibuja las notificaciones por pantalla
void render();
// Actualiza el estado de las notificaiones
void update();
// Constructor
Notify(SDL_Renderer *renderer, std::string bitmapFile, std::string textFile);
// Destructor
~Notify();
// Muestra una notificación de texto por pantalla;
void showText(std::string text);
// Indica si hay notificaciones activas
bool active();
};
#endif

View File

@@ -3,15 +3,21 @@
#include <iostream> #include <iostream>
// Constructor // Constructor
Screen::Screen(SDL_Window *window, SDL_Renderer *renderer, options_t *options, int gameInternalResX, int gameInternalResY) Screen::Screen(SDL_Window *window, SDL_Renderer *renderer, Asset *asset, options_t *options)
{ {
// Inicializa variables // Inicializa variables
this->window = window; this->window = window;
this->renderer = renderer; this->renderer = renderer;
this->options = options; this->options = options;
this->asset = asset;
gameCanvasWidth = gameInternalResX; // Crea los objetos
gameCanvasHeight = gameInternalResY; notify = new Notify(renderer, asset->get("smb2.png"), asset->get("smb2.txt"));
gameCanvasWidth = options->gameWidth;
gameCanvasHeight = options->gameHeight;
borderWidth = options->gameWidth * options->borderSize;
borderHeight = options->gameHeight * options->borderSize;
iniFade(); iniFade();
iniSpectrumFade(); iniSpectrumFade();
@@ -27,15 +33,16 @@ Screen::Screen(SDL_Window *window, SDL_Renderer *renderer, options_t *options, i
} }
// Establece el modo de video // Establece el modo de video
setVideoMode(options->fullScreenMode); setVideoMode(options->videoMode);
// Calcula los anclajes // Inicializa variables
anchor.left = 0; notifyActive = false;
anchor.right = gameCanvasWidth; }
anchor.center = gameCanvasWidth / 2;
anchor.top = 0; // Destructor
anchor.bottom = gameCanvasHeight; Screen::~Screen()
anchor.middle = gameCanvasHeight / 2; {
delete notify;
} }
// Limpia la pantalla // Limpia la pantalla
@@ -64,107 +71,100 @@ void Screen::blit()
// Copia la textura de juego en el renderizador en la posición adecuada // Copia la textura de juego en el renderizador en la posición adecuada
SDL_RenderCopy(renderer, gameCanvas, nullptr, &dest); SDL_RenderCopy(renderer, gameCanvas, nullptr, &dest);
// Dibuja las notificaciones
renderNotifications();
// Muestra por pantalla el renderizador // Muestra por pantalla el renderizador
SDL_RenderPresent(renderer); SDL_RenderPresent(renderer);
} }
// Establece el modo de video // Establece el modo de video
void Screen::setVideoMode(int fullScreenMode) void Screen::setVideoMode(int videoMode)
{ {
// Aplica el modo de video // Aplica el modo de video
SDL_SetWindowFullscreen(window, fullScreenMode); SDL_SetWindowFullscreen(window, videoMode);
// Si está activo el modo ventana quita el borde // Si está activo el modo ventana quita el borde
if (fullScreenMode == 0) if (videoMode == 0)
{ {
if (options->borderEnabled) if (options->borderEnabled)
{ {
const int incWidth = gameCanvasWidth * options->borderSize; windowWidth = gameCanvasWidth + borderWidth;
const int incHeight = gameCanvasHeight * options->borderSize; windowHeight = gameCanvasHeight + borderHeight;
screenWidth = gameCanvasWidth + incWidth; dest = {0 + (borderWidth / 2), 0 + (borderHeight / 2), gameCanvasWidth, gameCanvasHeight};
screenHeight = gameCanvasHeight + incHeight;
dest = {0 + (incWidth / 2), 0 + (incHeight / 2), gameCanvasWidth, gameCanvasHeight};
} }
else else
{ {
screenWidth = gameCanvasWidth; windowWidth = gameCanvasWidth;
screenHeight = gameCanvasHeight; windowHeight = gameCanvasHeight;
dest = {0, 0, gameCanvasWidth, gameCanvasHeight}; dest = {0, 0, gameCanvasWidth, gameCanvasHeight};
} }
// Modifica el tamaño del renderizador y de la ventana // Modifica el tamaño del renderizador y de la ventana
SDL_RenderSetLogicalSize(renderer, screenWidth, screenHeight); SDL_RenderSetLogicalSize(renderer, windowWidth, windowHeight);
SDL_SetWindowSize(window, screenWidth * options->windowSize, screenHeight * options->windowSize); SDL_SetWindowSize(window, windowWidth * options->windowSize, windowHeight * options->windowSize);
} }
// Si está activo el modo de pantalla completa añade el borde // Si está activo el modo de pantalla completa añade el borde
else if (fullScreenMode == SDL_WINDOW_FULLSCREEN_DESKTOP) else if (videoMode == SDL_WINDOW_FULLSCREEN_DESKTOP)
{ {
// Obten el alto y el ancho de la ventana // Obten el alto y el ancho de la ventana
SDL_GetWindowSize(window, &screenWidth, &screenHeight); SDL_GetWindowSize(window, &windowWidth, &windowHeight);
// Aplica el escalado al rectangulo donde se pinta la textura del juego // Aplica el escalado al rectangulo donde se pinta la textura del juego
if (options->integerScale) if (options->integerScale)
{ {
// Calcula el tamaño de la escala máxima // Calcula el tamaño de la escala máxima
int scale = 0; int scale = 0;
while (((gameCanvasWidth * (scale + 1)) <= screenWidth) && ((gameCanvasHeight * (scale + 1)) <= screenHeight)) while (((gameCanvasWidth * (scale + 1)) <= windowWidth) && ((gameCanvasHeight * (scale + 1)) <= windowHeight))
{ {
scale++; scale++;
} }
dest.w = gameCanvasWidth * scale; dest.w = gameCanvasWidth * scale;
dest.h = gameCanvasHeight * scale; dest.h = gameCanvasHeight * scale;
dest.x = (screenWidth - dest.w) / 2; dest.x = (windowWidth - dest.w) / 2;
dest.y = (screenHeight - dest.h) / 2; dest.y = (windowHeight - dest.h) / 2;
} }
else if (options->keepAspect) else if (options->keepAspect)
{ {
float ratio = (float)gameCanvasWidth / (float)gameCanvasHeight; float ratio = (float)gameCanvasWidth / (float)gameCanvasHeight;
if ((screenWidth - gameCanvasWidth) >= (screenHeight - gameCanvasHeight)) if ((windowWidth - gameCanvasWidth) >= (windowHeight - gameCanvasHeight))
{ {
dest.h = screenHeight; dest.h = windowHeight;
dest.w = (int)((screenHeight * ratio) + 0.5f); dest.w = (int)((windowHeight * ratio) + 0.5f);
dest.x = (screenWidth - dest.w) / 2; dest.x = (windowWidth - dest.w) / 2;
dest.y = (screenHeight - dest.h) / 2; dest.y = (windowHeight - dest.h) / 2;
} }
else else
{ {
dest.w = screenWidth; dest.w = windowWidth;
dest.h = (int)((screenWidth / ratio) + 0.5f); dest.h = (int)((windowWidth / ratio) + 0.5f);
dest.x = (screenWidth - dest.w) / 2; dest.x = (windowWidth - dest.w) / 2;
dest.y = (screenHeight - dest.h) / 2; dest.y = (windowHeight - dest.h) / 2;
} }
} }
else else
{ {
dest.w = screenWidth; dest.w = windowWidth;
dest.h = screenHeight; dest.h = windowHeight;
dest.x = dest.y = 0; dest.x = dest.y = 0;
} }
// Modifica el tamaño del renderizador // Modifica el tamaño del renderizador
SDL_RenderSetLogicalSize(renderer, screenWidth, screenHeight); SDL_RenderSetLogicalSize(renderer, windowWidth, windowHeight);
} }
// Actualiza el valor de la variable // Actualiza el valor de la variable
options->fullScreenMode = fullScreenMode; options->videoMode = videoMode;
} }
// Camibia entre pantalla completa y ventana // Camibia entre pantalla completa y ventana
void Screen::switchVideoMode() void Screen::switchVideoMode()
{ {
if (options->fullScreenMode == 0) options->videoMode = (options->videoMode == 0) ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0;
{ setVideoMode(options->videoMode);
options->fullScreenMode = SDL_WINDOW_FULLSCREEN_DESKTOP;
}
else
{
options->fullScreenMode = 0;
}
setVideoMode(options->fullScreenMode);
} }
// Cambia el tamaño de la ventana // Cambia el tamaño de la ventana
@@ -338,4 +338,30 @@ void Screen::renderFX()
{ {
renderFade(); renderFade();
renderSpectrumFade(); renderSpectrumFade();
}
// Actualiza el notificador
void Screen::updateNotifier()
{
notify->update();
notifyActive = notify->active();
}
// Muestra una notificación de texto por pantalla;
void Screen::showText(std::string text)
{
notify->showText(text);
}
// Dibuja las notificaciones
void Screen::renderNotifications()
{
//if (!notifyActive)
//{
// return;
//}
//SDL_RenderSetLogicalSize(renderer, windowWidth * options->windowSize, windowHeight * options->windowSize);
notify->render();
//SDL_RenderSetLogicalSize(renderer, windowWidth, windowHeight);
} }

View File

@@ -1,6 +1,8 @@
#pragma once #pragma once
#include <SDL2/SDL.h> #include <SDL2/SDL.h>
#include "asset.h"
#include "notify.h"
#include "utils.h" #include "utils.h"
#include <vector> #include <vector>
@@ -10,42 +12,35 @@
#define FILTER_NEAREST 0 #define FILTER_NEAREST 0
#define FILTER_LINEAL 1 #define FILTER_LINEAL 1
struct anchor_t
{
int left; // Parte izquierda de la pantalla de juego
int right; // Parte drecha de la pantalla de juego
int center; // Parte central horizontal de la pantalla de juego
int top; // Parte superior de la pantalla de juego
int bottom; // Parte infoerior de la pantalla de juego
int middle; // Parte central vertical de la pantalla de juego
};
// Clase Screen
class Screen class Screen
{ {
private: private:
// Objetos y punteros // Objetos y punteros
SDL_Window *window; // Ventana de la aplicación SDL_Window *window; // Ventana de la aplicación
SDL_Renderer *renderer; // El renderizador de la ventana SDL_Renderer *renderer; // El renderizador de la ventana
Asset *asset; // Objeto con el listado de recursos
SDL_Texture *gameCanvas; // Textura para completar la ventana de juego hasta la pantalla completa SDL_Texture *gameCanvas; // Textura para completar la ventana de juego hasta la pantalla completa
options_t *options; // Variable con todas las opciones del programa options_t *options; // Variable con todas las opciones del programa
Notify *notify; // Dibuja notificaciones por pantalla
// Variables // Variables
int screenWidth; // Ancho de la pantalla o ventana int windowWidth; // Ancho de la pantalla o ventana
int screenHeight; // Alto de la pantalla o ventana int windowHeight; // Alto de la pantalla o ventana
int gameCanvasWidth; // Resolución interna del juego. Es el ancho de la textura donde se dibuja el juego int gameCanvasWidth; // Resolución interna del juego. Es el ancho de la textura donde se dibuja el juego
int gameCanvasHeight; // Resolución interna del juego. Es el alto de la textura donde se dibuja el juego int gameCanvasHeight; // Resolución interna del juego. Es el alto de la textura donde se dibuja el juego
anchor_t anchor; // Variable con los anclajes de la pantalla int borderWidth; // Anchura del borde
int borderHeight; // Anltura del borde
SDL_Rect dest; // Coordenadas donde se va a dibujar la textura del juego sobre la pantalla o ventana SDL_Rect dest; // Coordenadas donde se va a dibujar la textura del juego sobre la pantalla o ventana
color_t borderColor; // Color del borde añadido a la textura de juego para rellenar la pantalla color_t borderColor; // Color del borde añadido a la textura de juego para rellenar la pantalla
bool notifyActive; // Indica si hay notificaciones activas
// Variables - Efectos // Variables - Efectos
bool fade; // Indica si esta activo el efecto de fade bool fade; // Indica si esta activo el efecto de fade
int fadeCounter; // Temporizador para el efecto de fade int fadeCounter; // Temporizador para el efecto de fade
int fadeLenght; // Duración del fade int fadeLenght; // Duración del fade
bool spectrumFade; // Indica si esta activo el efecto de fade spectrum bool spectrumFade; // Indica si esta activo el efecto de fade spectrum
int spectrumFadeCounter; // Temporizador para el efecto de fade spectrum int spectrumFadeCounter; // Temporizador para el efecto de fade spectrum
int spectrumFadeLenght; // Duración del fade spectrum int spectrumFadeLenght; // Duración del fade spectrum
std::vector<color_t> spectrumColor; // Colores para el fade spectrum std::vector<color_t> spectrumColor; // Colores para el fade spectrum
// Inicializa las variables para el fade // Inicializa las variables para el fade
@@ -66,9 +61,15 @@ private:
// Dibuja el spectrum fade // Dibuja el spectrum fade
void renderSpectrumFade(); void renderSpectrumFade();
// Dibuja las notificaciones
void renderNotifications();
public: public:
// Constructor // Constructor
Screen(SDL_Window *window, SDL_Renderer *renderer, options_t *options, int gameInternalResX, int gameInternalResY); Screen(SDL_Window *window, SDL_Renderer *renderer, Asset *asset, options_t *options);
// Destructor
~Screen();
// Limpia la pantalla // Limpia la pantalla
void clean(color_t color = {0x00, 0x00, 0x00}); void clean(color_t color = {0x00, 0x00, 0x00});
@@ -80,7 +81,7 @@ public:
void blit(); void blit();
// Establece el modo de video // Establece el modo de video
void setVideoMode(int fullScreenMode); void setVideoMode(int videoMode);
// Camibia entre pantalla completa y ventana // Camibia entre pantalla completa y ventana
void switchVideoMode(); void switchVideoMode();
@@ -120,6 +121,12 @@ public:
// Dibuja los efectos // Dibuja los efectos
void renderFX(); void renderFX();
// Actualiza el notificador
void updateNotifier();
// Muestra una notificación de texto por pantalla;
void showText(std::string text);
}; };
#endif #endif

View File

@@ -70,22 +70,36 @@ struct cheat_t
bool altSkin; // Indicxa si se usa una skin diferente para el jugador bool altSkin; // Indicxa si se usa una skin diferente para el jugador
}; };
// Estructura para el servicio online
struct online_t
{
bool enabled; // Indica si se quiere usar el modo online o no
std::string server; // Servidor para los servicios online
int port; // Puerto del servidor
std::string gameID; // Identificador del juego para los servicios online
std::string jailerID; // Identificador del jugador para los servicios online
int score; // Puntuación almacenada online
};
// Estructura con todas las opciones de configuración del programa // Estructura con todas las opciones de configuración del programa
struct options_t struct options_t
{ {
Uint32 fullScreenMode; // Contiene el valor del modo de pantalla completa Uint32 videoMode; // Contiene el valor del modo de pantalla completa
int windowSize; // Contiene el valor por el que se multiplica el tamaño de la ventana int 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 Uint32 filter; // Filtro usado para el escalado de la imagen
bool vSync; // Indica si se quiere usar vsync o no bool vSync; // Indica si se quiere usar vsync o no
int screenWidth; // Ancho de la pantalla o ventana int gameWidth; // Ancho de la resolucion nativa del juego
int screenHeight; // Alto de la pantalla o ventana int gameHeight; // Alto de la resolucion nativa del juego
bool integerScale; // Indica si el escalado de la imagen ha de ser entero en el modo a pantalla completa 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 bool keepAspect; // Indica si se ha de mantener la relación de aspecto al poner el modo a pantalla completa
bool borderEnabled; // Indica si ha de mostrar el borde en el modo de ventana bool borderEnabled; // Indica si ha de mostrar el borde en el modo de ventana
float borderSize; // Porcentaje de borde que se añade a lo ventana float borderSize; // Porcentaje de borde que se añade a lo ventana
palette_e palette; // Paleta de colores a usar en el juego 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 bool console; // Indica si ha de mostrar información por la consola de texto
cheat_t cheat; // Contiene trucos y ventajas para el juego cheat_t cheat; // Contiene trucos y ventajas para el juego
int rooms; // Cantidad de habitaciones visitadas
int items; // Cantidad de items obtenidos
online_t online; // Datos del servicio online
}; };
// Calcula el cuadrado de la distancia entre dos puntos // Calcula el cuadrado de la distancia entre dos puntos

View File

@@ -168,7 +168,7 @@ void Credits::fillTexture()
{ {
// Inicializa los textos // Inicializa los textos
iniTexts(); iniTexts();
// Rellena la textura de texto // Rellena la textura de texto
SDL_SetRenderTarget(renderer, textTexture); SDL_SetRenderTarget(renderer, textTexture);
color_t c = stringToColor(options->palette, "black"); color_t c = stringToColor(options->palette, "black");
@@ -264,6 +264,9 @@ void Credits::update()
// Actualiza el contador // Actualiza el contador
updateCounter(); updateCounter();
// Actualiza las notificaciones
screen->updateNotifier();
// Actualiza el sprite con el brillo // Actualiza el sprite con el brillo
if (counter > 770) if (counter > 770)
{ {

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("31.room");
rooms.push_back("44.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; roomIndex = 0;
currentRoom = rooms.at(roomIndex); currentRoom = rooms.at(roomIndex);
@@ -214,6 +153,9 @@ void Demo::update()
scoreboard->update(); scoreboard->update();
screen->updateFX(); screen->updateFX();
checkRoomChange(); checkRoomChange();
// Actualiza las notificaciones
screen->updateNotifier();
} }
} }
@@ -250,7 +192,7 @@ void Demo::renderRoomName()
// Recarga todas las texturas // Recarga todas las texturas
void Demo::reLoadTextures() void Demo::reLoadTextures()
{ {
if (options->console) if (options->console)
{ {
std::cout << "** RELOAD REQUESTED" << std::endl; std::cout << "** RELOAD REQUESTED" << std::endl;
} }

View File

@@ -1,7 +1,15 @@
#include "director.h" #include "common/jscore.h"
#include "common/utils.h" #include "common/utils.h"
#include "director.h"
#include <errno.h>
#include <iostream> #include <iostream>
#include <string> #include <string>
#include <sys/stat.h>
#include <unistd.h>
#ifndef _WIN32
#include <pwd.h>
#endif
// Constructor // Constructor
Director::Director(int argc, char *argv[]) Director::Director(int argc, char *argv[])
@@ -19,6 +27,9 @@ Director::Director(int argc, char *argv[])
// Comprueba los parametros del programa // Comprueba los parametros del programa
checkProgramArguments(argc, argv); checkProgramArguments(argc, argv);
// Crea la carpeta del sistema donde guardar datos
createSystemFolder();
// Crea el objeto que controla los ficheros de recursos // Crea el objeto que controla los ficheros de recursos
asset = new Asset(executablePath); asset = new Asset(executablePath);
asset->setVerbose(options->console); asset->setVerbose(options->console);
@@ -26,7 +37,7 @@ Director::Director(int argc, char *argv[])
// Si falta algún fichero no inicia el programa // Si falta algún fichero no inicia el programa
if (!setFileList()) if (!setFileList())
{ {
section.name = SECTION_PROG_QUIT; exit(EXIT_FAILURE);
} }
// Inicializa variables desde el fichero de configuración // Inicializa variables desde el fichero de configuración
@@ -42,11 +53,13 @@ Director::Director(int argc, char *argv[])
resource = new Resource(renderer, asset, options); resource = new Resource(renderer, asset, options);
input = new Input(asset->get("gamecontrollerdb.txt")); input = new Input(asset->get("gamecontrollerdb.txt"));
initInput(); initInput();
screen = new Screen(window, renderer, options, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT); screen = new Screen(window, renderer, asset, options);
screen->setBorderColor(borderColor); screen->setBorderColor(borderColor);
screen->setVideoMode(options->fullScreenMode);
debug = new Debug(renderer, screen, asset); debug = new Debug(renderer, screen, asset);
music = JA_LoadMusic(asset->get("title.ogg").c_str()); music = JA_LoadMusic(asset->get("title.ogg").c_str());
// Inicializa los servicios online
//initOnline();
} }
Director::~Director() Director::~Director()
@@ -68,6 +81,56 @@ Director::~Director()
SDL_Quit(); SDL_Quit();
} }
// Inicializa los servicios online
void Director::initOnline()
{
if (!options->online.enabled)
{
return;
}
// Obten el Jailer ID
if (options->online.jailerID == "")
{ // Jailer ID no definido
screen->showText("No ha especificado ningun Jailer ID");
std::cout << "No ha especificado ningun Jailer ID" << std::endl;
}
else
{ // Jailer ID iniciado
// Establece el servidor y el puerto
jscore::init(options->online.server, options->online.port);
// Obtiene la información online
if (jscore::initOnlineScore(options->online.gameID))
{
screen->showText(options->online.jailerID + " ha iniciado sesion");
std::cout << options->online.jailerID << " ha iniciado sesion" << std::endl;
}
else
{
screen->showText("Fallo al conectar a " + options->online.server);
std::cout << "Fallo al conectar a " << options->online.server << std::endl;
options->online.enabled = false;
return;
}
// Obten las estadisticas online
const int points = jscore::getUserPoints(options->online.gameID, options->online.jailerID);
if (points == 0)
{ // Fallo de conexión o no hay registros
screen->showText("No se ha podido obtener la puntuacion online");
std::cout << "No se ha podido obtener la puntuacion online" << std::endl;
}
else
{
options->online.score = points;
}
}
}
// Crea e inicializa las opciones del programa // Crea e inicializa las opciones del programa
void Director::iniOptions() void Director::iniOptions()
{ {
@@ -75,14 +138,16 @@ void Director::iniOptions()
options = new options_t; options = new options_t;
// Inicializa valores // Inicializa valores
options->fullScreenMode = 0; options->gameWidth = GAMECANVAS_WIDTH;
options->gameHeight = GAMECANVAS_HEIGHT;
options->videoMode = 0;
options->windowSize = 3; options->windowSize = 3;
options->filter = FILTER_NEAREST; options->filter = FILTER_NEAREST;
options->vSync = true; options->vSync = true;
options->integerScale = true; options->integerScale = true;
options->keepAspect = true; options->keepAspect = true;
options->borderEnabled = true; options->borderEnabled = true;
options->borderSize = 0.1f; options->borderSize = 0.2f;
options->palette = p_zxspectrum; options->palette = p_zxspectrum;
// Estos valores no se guardan en el fichero de configuraci´ón // Estos valores no se guardan en el fichero de configuraci´ón
@@ -91,6 +156,15 @@ void Director::iniOptions()
options->cheat.invincible = false; options->cheat.invincible = false;
options->cheat.jailEnabled = false; options->cheat.jailEnabled = false;
options->cheat.altSkin = false; options->cheat.altSkin = false;
options->rooms = 0;
options->items = 0;
// Online
options->online.enabled = false;
options->online.server = "";
options->online.port = 0;
options->online.gameID = "jaildoctors_dilemma_test";
options->online.jailerID = "";
} }
// Comprueba los parametros del programa // Comprueba los parametros del programa
@@ -181,19 +255,33 @@ bool Director::loadConfig()
saveConfig(); saveConfig();
} }
// Normaliza los valores
const bool a = options->videoMode == 0;
const bool b = options->videoMode == SDL_WINDOW_FULLSCREEN;
const bool c = options->videoMode == SDL_WINDOW_FULLSCREEN_DESKTOP;
if (!(a || b || c))
{
options->videoMode = 0;
}
if (options->windowSize < 1 || options->windowSize > 4)
{
options->windowSize = 3;
}
// Aplica opciones // Aplica opciones
if (options->borderEnabled) // if (options->borderEnabled)
{ //{
const int incWidth = GAMECANVAS_WIDTH * options->borderSize; // const int incWidth = GAMECANVAS_WIDTH * options->borderSize;
const int incHeight = GAMECANVAS_HEIGHT * options->borderSize; // const int incHeight = GAMECANVAS_HEIGHT * options->borderSize;
options->screenWidth = (GAMECANVAS_WIDTH + incWidth) * options->windowSize; // options->gameWidth = GAMECANVAS_WIDTH + incWidth;
options->screenHeight = (GAMECANVAS_HEIGHT + incHeight) * options->windowSize; // options->gameHeight = GAMECANVAS_HEIGHT + incHeight;
} //}
else // else
{ //{
options->screenWidth = GAMECANVAS_WIDTH * options->windowSize; // options->gameWidth = GAMECANVAS_WIDTH;
options->screenHeight = GAMECANVAS_HEIGHT * options->windowSize; // options->gameHeight = GAMECANVAS_HEIGHT;
} //}
return success; return success;
} }
@@ -206,20 +294,36 @@ bool Director::saveConfig()
// Crea y abre el fichero de texto // Crea y abre el fichero de texto
std::ofstream file(asset->get("config.txt")); std::ofstream file(asset->get("config.txt"));
if (file.good())
{
if (options->console)
{
std::cout << asset->get("config.txt") << " open for writing" << std::endl;
}
}
else
{
if (options->console)
{
std::cout << asset->get("config.txt") << " can't be opened" << std::endl;
}
}
// Escribe en el fichero // Escribe en el fichero
if (options->fullScreenMode == 0) file << "## VISUAL OPTIONS\n";
if (options->videoMode == 0)
{ {
file << "fullScreenMode=0\n"; file << "videoMode=0\n";
} }
else if (options->fullScreenMode == SDL_WINDOW_FULLSCREEN) else if (options->videoMode == SDL_WINDOW_FULLSCREEN)
{ {
file << "fullScreenMode=SDL_WINDOW_FULLSCREEN\n"; file << "videoMode=SDL_WINDOW_FULLSCREEN\n";
} }
else if (options->fullScreenMode == SDL_WINDOW_FULLSCREEN_DESKTOP) else if (options->videoMode == SDL_WINDOW_FULLSCREEN_DESKTOP)
{ {
file << "fullScreenMode=SDL_WINDOW_FULLSCREEN_DESKTOP\n"; file << "videoMode=SDL_WINDOW_FULLSCREEN_DESKTOP\n";
} }
file << "windowSize=" + std::to_string(options->windowSize) + "\n"; file << "windowSize=" + std::to_string(options->windowSize) + "\n";
@@ -240,12 +344,64 @@ bool Director::saveConfig()
file << "borderSize=" + std::to_string(options->borderSize) + "\n"; file << "borderSize=" + std::to_string(options->borderSize) + "\n";
file << "palette=" + std::to_string(options->palette) + "\n"; file << "palette=" + std::to_string(options->palette) + "\n";
file << "\n## ONLINE OPTIONS\n";
file << "enabled=" + boolToString(options->online.enabled) + "\n";
file << "server=" + options->online.server + "\n";
file << "port=" + std::to_string(options->online.port) + "\n";
file << "jailerID=" + options->online.jailerID + "\n";
// Cierra el fichero // Cierra el fichero
file.close(); file.close();
return success; return success;
} }
// Crea la carpeta del sistema donde guardar datos
void Director::createSystemFolder()
{
#ifdef _WIN32
systemFolder = std::string(getenv("APPDATA")) + "/jaildoctors_dilemma";
#elif __APPLE__
struct passwd *pw = getpwuid(getuid());
const char *homedir = pw->pw_dir;
systemFolder = std::string(homedir) + "/Library/Application Support/jaildoctors_dilemma";
#elif __linux__
struct passwd *pw = getpwuid(getuid());
const char *homedir = pw->pw_dir;
systemFolder = std::string(homedir) + "/.jaildoctors_dilemma";
#endif
struct stat st = {0};
if (stat(systemFolder.c_str(), &st) == -1)
{
errno = 0;
#ifdef _WIN32
int ret = mkdir(systemFolder.c_str());
#else
int ret = mkdir(systemFolder.c_str(), S_IRWXU);
#endif
if (ret == -1)
{
switch (errno)
{
case EACCES:
printf("the parent directory does not allow write");
exit(EXIT_FAILURE);
case EEXIST:
printf("pathname already exists");
exit(EXIT_FAILURE);
case ENAMETOOLONG:
printf("pathname is too long");
exit(EXIT_FAILURE);
default:
perror("mkdir");
exit(EXIT_FAILURE);
}
}
}
}
// Carga los recursos // Carga los recursos
void Director::loadResources(section_t section) void Director::loadResources(section_t section)
{ {
@@ -810,19 +966,19 @@ bool Director::setOptions(options_t *options, std::string var, std::string value
// Indicador de éxito en la asignación // Indicador de éxito en la asignación
bool success = true; bool success = true;
if (var == "fullScreenMode") if (var == "videoMode")
{ {
if (value == "SDL_WINDOW_FULLSCREEN_DESKTOP") if (value == "SDL_WINDOW_FULLSCREEN_DESKTOP")
{ {
options->fullScreenMode = SDL_WINDOW_FULLSCREEN_DESKTOP; options->videoMode = SDL_WINDOW_FULLSCREEN_DESKTOP;
} }
else if (value == "SDL_WINDOW_FULLSCREEN") else if (value == "SDL_WINDOW_FULLSCREEN")
{ {
options->fullScreenMode = SDL_WINDOW_FULLSCREEN; options->videoMode = SDL_WINDOW_FULLSCREEN;
} }
else else
{ {
options->fullScreenMode = 0; options->videoMode = 0;
} }
} }
@@ -891,7 +1047,31 @@ bool Director::setOptions(options_t *options, std::string var, std::string value
} }
} }
else if (var == "") else if (var == "enabled")
{
options->online.enabled = stringToBool(value);
}
else if (var == "server")
{
options->online.server = value;
}
else if (var == "port")
{
if (value == "")
{
value = "0";
}
options->online.port = std::stoi(value);
}
else if (var == "jailerID")
{
options->online.jailerID = value;
}
else if (var == "" || var.substr(0, 1) == "#")
{ {
} }
@@ -971,7 +1151,15 @@ bool Director::initSDL()
} }
// Crea la ventana // Crea la ventana
window = SDL_CreateWindow(WINDOW_CAPTION, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, options->screenWidth, options->screenHeight, SDL_WINDOW_SHOWN | SDL_WINDOW_ALLOW_HIGHDPI); int incW = 0;
int incH = 0;
if (options->borderEnabled)
{
incW = options->gameWidth * options->borderSize;
incH = options->gameHeight * options->borderSize;
}
window = SDL_CreateWindow(WINDOW_CAPTION, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, (options->gameWidth + incW) * options->windowSize, (options->gameHeight + incH) * options->windowSize, SDL_WINDOW_SHOWN | SDL_WINDOW_ALLOW_HIGHDPI);
if (window == nullptr) if (window == nullptr)
{ {
if (options->console) if (options->console)
@@ -1006,7 +1194,7 @@ bool Director::initSDL()
SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0xFF); SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0xFF);
// Establece el tamaño del buffer de renderizado // Establece el tamaño del buffer de renderizado
SDL_RenderSetLogicalSize(renderer, options->screenWidth, options->screenHeight); SDL_RenderSetLogicalSize(renderer, options->gameWidth, options->gameHeight);
// Establece el modo de mezcla // Establece el modo de mezcla
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND); SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);
@@ -1039,6 +1227,7 @@ bool Director::setFileList()
// Configuración // Configuración
asset->add(prefix + "/data/input/gamecontrollerdb.txt", t_data); asset->add(prefix + "/data/input/gamecontrollerdb.txt", t_data);
asset->add(prefix + "/data/config/config.txt", t_data, false); asset->add(prefix + "/data/config/config.txt", t_data, false);
asset->add(systemFolder + "/stats.csv", t_data, false, true);
// Habitaciones // Habitaciones
asset->add(prefix + "/data/room/01.room", t_room); asset->add(prefix + "/data/room/01.room", t_room);
@@ -1555,4 +1744,4 @@ void Director::run()
break; break;
} }
} }
} }

View File

@@ -40,7 +40,7 @@ private:
Credits *credits; // Objeto para gestionar los creditos del juego Credits *credits; // Objeto para gestionar los creditos del juego
Demo *demo; // Objeto para gestionar el modo demo, en el que se ven pantallas del juego Demo *demo; // Objeto para gestionar el modo demo, en el que se ven pantallas del juego
Ending *ending; // Objeto para gestionar el final del juego Ending *ending; // Objeto para gestionar el final del juego
Ending2 *ending2; // Objeto para gestionar el final del juego Ending2 *ending2; // Objeto para gestionar el final del juego
GameOver *gameOver; // Objeto para gestionar el final de la partida GameOver *gameOver; // Objeto para gestionar el final de la partida
Debug *debug; // Objeto para getsionar la información de debug Debug *debug; // Objeto para getsionar la información de debug
struct options_t *options; // Variable con todas las opciones del programa struct options_t *options; // Variable con todas las opciones del programa
@@ -49,6 +49,10 @@ private:
JA_Music music; // Musica del titulo JA_Music music; // Musica del titulo
std::string executablePath; // Path del ejecutable std::string executablePath; // Path del ejecutable
section_t section; // Sección y subsección actual del programa; section_t section; // Sección y subsección actual del programa;
std::string systemFolder; // Carpeta del sistema donde guardar datos
// Inicializa los servicios online
void initOnline();
// Crea e inicializa las opciones del programa // Crea e inicializa las opciones del programa
void iniOptions(); void iniOptions();
@@ -62,6 +66,9 @@ private:
// Guarda el fichero de configuración // Guarda el fichero de configuración
bool saveConfig(); bool saveConfig();
// Crea la carpeta del sistema donde guardar datos
void createSystemFolder();
// Carga los recursos // Carga los recursos
void loadResources(section_t section); void loadResources(section_t section);

View File

@@ -103,6 +103,9 @@ void Ending::update()
// Actualiza el volumen de la musica // Actualiza el volumen de la musica
updateMusicVolume(); updateMusicVolume();
// Actualiza las notificaciones
screen->updateNotifier();
} }
} }

View File

@@ -102,6 +102,9 @@ void Ending2::update()
// Actualiza el volumen de la musica // Actualiza el volumen de la musica
updateMusicVolume(); updateMusicVolume();
// Actualiza las notificaciones
screen->updateNotifier();
} }
} }

View File

@@ -21,9 +21,9 @@ Game::Game(SDL_Renderer *renderer, Screen *screen, Resource *resource, Asset *as
this->options = options; this->options = options;
#ifdef DEBUG #ifdef DEBUG
currentRoom = "14.room"; currentRoom = "02.room";
const int x1 = 1; const int x1 = 20;
const int y1 = 13; const int y1 = 6;
spawnPoint = {x1 * 8, y1 * 8, 0, 0, 0, s_standing, SDL_FLIP_HORIZONTAL}; spawnPoint = {x1 * 8, y1 * 8, 0, 0, 0, s_standing, SDL_FLIP_HORIZONTAL};
#endif #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); text = new Text(resource->getOffset("smb2.txt"), resource->getTexture("smb2.png"), renderer);
music = JA_LoadMusic(asset->get("game.ogg").c_str()); music = JA_LoadMusic(asset->get("game.ogg").c_str());
deathSound = JA_LoadSound(asset->get("death.wav").c_str()); deathSound = JA_LoadSound(asset->get("death.wav").c_str());
stats = new Stats(asset->get("stats.csv"));
stats->addVisit(room->getName());
// Inicializa el resto de variables // Inicializa el resto de variables
ticks = 0; ticks = 0;
@@ -70,6 +72,7 @@ Game::~Game()
delete player; delete player;
delete eventHandler; delete eventHandler;
delete text; delete text;
delete stats;
JA_DeleteMusic(music); JA_DeleteMusic(music);
JA_DeleteSound(deathSound); JA_DeleteSound(deathSound);
@@ -89,6 +92,11 @@ void Game::checkEventHandler()
break; 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)) if ((eventHandler->type == SDL_KEYDOWN) and (eventHandler->key.repeat == 0))
{ {
switch (eventHandler->key.keysym.scancode) switch (eventHandler->key.keysym.scancode)
@@ -123,6 +131,10 @@ void Game::checkEventHandler()
case SDL_SCANCODE_D: case SDL_SCANCODE_D:
goToRoom(BORDER_RIGHT); goToRoom(BORDER_RIGHT);
break; break;
case SDL_SCANCODE_F6:
screen->showText("MAMA MIRA! SIN MANOS!");
break;
#endif #endif
case SDL_SCANCODE_M: case SDL_SCANCODE_M:
@@ -207,8 +219,11 @@ void Game::update()
// Comprueba los eventos de la cola // Comprueba los eventos de la cola
checkEventHandler(); checkEventHandler();
// Actualiza los objetos #ifdef DEBUG
debug->clear(); debug->clear();
#endif
// Actualiza los objetos
room->update(); room->update();
player->update(); player->update();
checkPlayerOnBorder(); checkPlayerOnBorder();
@@ -217,12 +232,18 @@ void Game::update()
checkIfPlayerIsAlive(); checkIfPlayerIsAlive();
checkGameOver(); checkGameOver();
checkEndGame(); checkEndGame();
checkRestoringJail();
scoreboard->update(); scoreboard->update();
input->update(); input->update();
updateDebugInfo();
updateBlackScreen(); updateBlackScreen();
screen->updateFX();
// Actualiza las notificaciones
screen->updateNotifier();
#ifdef DEBUG
updateDebugInfo();
#endif
} }
} }
@@ -241,14 +262,16 @@ void Game::render()
scoreboard->render(); scoreboard->render();
renderBlackScreen(); renderBlackScreen();
#ifdef DEBUG
// Debug info // Debug info
renderDebugInfo(); renderDebugInfo();
// screen->renderFX(); #endif
// Actualiza la pantalla // Actualiza la pantalla
screen->blit(); screen->blit();
} }
#ifdef DEBUG
// Pasa la información de debug // Pasa la información de debug
void Game::updateDebugInfo() void Game::updateDebugInfo()
{ {
@@ -285,6 +308,7 @@ void Game::renderDebugInfo()
debug->setPos({1, 18 * 8}); debug->setPos({1, 18 * 8});
debug->render(); debug->render();
} }
#endif
// Escribe el nombre de la pantalla // Escribe el nombre de la pantalla
void Game::renderRoomName() void Game::renderRoomName()
@@ -321,8 +345,13 @@ bool Game::changeRoom(std::string file)
setScoreBoardColor(); setScoreBoardColor();
if (roomTracker->addRoom(file)) if (roomTracker->addRoom(file))
{ // Incrementa el contador de habitaciones visitadas {
// Incrementa el contador de habitaciones visitadas
board.rooms++; board.rooms++;
options->rooms = board.rooms;
// Actualiza las estadisticas
stats->addVisit(room->getName());
} }
// Pasa la nueva habitación al jugador // Pasa la nueva habitación al jugador
@@ -398,6 +427,9 @@ void Game::killPlayer()
board.lives--; board.lives--;
} }
// Actualiza las estadisticas
stats->addDeath(room->getName());
// Destruye la habitacion y el jugador // Destruye la habitacion y el jugador
delete room; delete room;
delete this->player; delete this->player;
@@ -569,4 +601,22 @@ void Game::switchPause()
scoreboard->pause(); scoreboard->pause();
paused = true; paused = true;
} }
}
// Da vidas al jugador cuando está en la Jail
void Game::checkRestoringJail()
{
if (room->getName() != "THE JAIL" || board.lives == 9)
{
return;
}
static int counter = 0;
counter++;
if (counter == 100)
{
counter = 0;
board.lives++;
JA_PlaySound(deathSound);
}
} }

View File

@@ -17,6 +17,7 @@
#include "room_tracker.h" #include "room_tracker.h"
#include "room.h" #include "room.h"
#include "scoreboard.h" #include "scoreboard.h"
#include "stats.h"
#ifndef GAME_H #ifndef GAME_H
#define GAME_H #define GAME_H
@@ -39,6 +40,7 @@ private:
Resource *resource; // Objeto con los recursos Resource *resource; // Objeto con los recursos
Debug *debug; // Objeto para gestionar la información de debug Debug *debug; // Objeto para gestionar la información de debug
options_t *options; // Puntero a las opciones del juego options_t *options; // Puntero a las opciones del juego
Stats *stats; // Objeto encargado de gestionar las estadísticas
// Variables // Variables
JA_Music music; // Musica que suena durante el juego JA_Music music; // Musica que suena durante el juego
@@ -63,11 +65,13 @@ private:
// Comprueba los eventos de la cola // Comprueba los eventos de la cola
void checkEventHandler(); void checkEventHandler();
#ifdef DEBUG
// Pone la información de debug en pantalla // Pone la información de debug en pantalla
void updateDebugInfo(); void updateDebugInfo();
// Pone la información de debug en pantalla // Pone la información de debug en pantalla
void renderDebugInfo(); void renderDebugInfo();
#endif
// Escribe el nombre de la pantalla // Escribe el nombre de la pantalla
void renderRoomName(); void renderRoomName();
@@ -123,6 +127,9 @@ private:
// Pone el juego en pausa // Pone el juego en pausa
void switchPause(); void switchPause();
// Da vidas al jugador cuando está en la Jail
void checkRestoringJail();
public: public:
// Constructor // Constructor
Game(SDL_Renderer *renderer, Screen *screen, Resource *resource, Asset *asset, options_t *options, Input *input, Debug *debug); Game(SDL_Renderer *renderer, Screen *screen, Resource *resource, Asset *asset, options_t *options, Input *input, Debug *debug);

View File

@@ -28,9 +28,9 @@ GameOver::GameOver(SDL_Renderer *renderer, Screen *screen, Resource *resource, A
iniFade = 310; iniFade = 310;
fadeLenght = 20; fadeLenght = 20;
playerSprite->setPosX(GAMECANVAS_CENTER_X + 10); 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->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 // Inicializa el vector de colores
const std::vector<std::string> colorList = {"white", "yellow", "cyan", "green", "magenta", "red", "blue", "black"}; const std::vector<std::string> colorList = {"white", "yellow", "cyan", "green", "magenta", "red", "blue", "black"};
@@ -73,6 +73,9 @@ void GameOver::update()
// Actualiza los dos sprites // Actualiza los dos sprites
playerSprite->update(); playerSprite->update();
tvSprite->update(); tvSprite->update();
// Actualiza las notificaciones
screen->updateNotifier();
} }
} }
@@ -86,12 +89,16 @@ void GameOver::render()
screen->clean(); screen->clean();
// Escribe el texto de GAME OVER // 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 // Dibuja los sprites
renderSprites(); 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 // Vuelca el contenido del renderizador en pantalla
screen->blit(); screen->blit();
@@ -180,7 +187,7 @@ void GameOver::updateColor()
if (counter < half) 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 float step = std::min(counter, fadeLenght) / (float)fadeLenght;
const int index = (colors.size() - 1) - int((colors.size() - 1) * step); const int index = (colors.size() - 1) - int((colors.size() - 1) * step);
color = colors.at(index); color = colors.at(index);

View File

@@ -251,6 +251,9 @@ void Intro::update()
// Gestiona el contador de carga // Gestiona el contador de carga
updateLoad(); updateLoad();
// Actualiza las notificaciones
screen->updateNotifier();
// Comprueba si ha terminado la intro // Comprueba si ha terminado la intro
if (loadCounter >= 768) if (loadCounter >= 768)
{ {
@@ -281,7 +284,7 @@ void Intro::render()
section_t Intro::run() section_t Intro::run()
{ {
// Inicia el sonido de carga // Inicia el sonido de carga
JA_SetVolume(64); JA_SetVolume(64);
JA_PlayMusic(loadingSound1); JA_PlayMusic(loadingSound1);
while (section.name == SECTION_PROG_INTRO) while (section.name == SECTION_PROG_INTRO)
@@ -290,7 +293,7 @@ section_t Intro::run()
render(); render();
} }
JA_SetVolume(128); JA_SetVolume(128);
return section; return section;
} }

View File

@@ -85,7 +85,7 @@ void Logo::checkEventHandler()
switch (eventHandler->key.keysym.scancode) switch (eventHandler->key.keysym.scancode)
{ {
case SDL_SCANCODE_ESCAPE: case SDL_SCANCODE_ESCAPE:
//std::cout << "PULSADO ESCAPE" << std::endl; // std::cout << "PULSADO ESCAPE" << std::endl;
section.name = SECTION_PROG_QUIT; section.name = SECTION_PROG_QUIT;
break; break;
@@ -262,6 +262,9 @@ void Logo::update()
// Gestiona el color de las texturas // Gestiona el color de las texturas
updateTextureColors(); updateTextureColors();
// Actualiza las notificaciones
screen->updateNotifier();
// Comprueba si ha terminado el logo // Comprueba si ha terminado el logo
if (counter == endLogo + postLogo) if (counter == endLogo + postLogo)
{ {

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

View File

@@ -87,7 +87,13 @@ public:
int fallCounter; // Cuenta el tiempo de caida int fallCounter; // Cuenta el tiempo de caida
bool alive; // Indica si el jugador esta vivo o no bool alive; // Indica si el jugador esta vivo o no
int maxFallHeight; // Altura maxima permitida de caída. 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 // Comprueba las entradas y modifica variables
void checkInput(); void checkInput();

View File

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

158
source/stats.cpp Normal file
View File

@@ -0,0 +1,158 @@
#include "stats.h"
#include <iostream>
#include <fstream>
#include <sstream>
// Constructor
Stats::Stats(std::string file)
{
filePath = file;
list.clear();
loadFromFile();
}
// Destructor
Stats::~Stats()
{
#ifndef DEBUG
saveToFile();
#endif
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);
if (file.good())
{
std::cout << filePath << " open for writing" << std::endl;
}
else
{
std::cout << filePath << " can't be opened" << std::endl;
}
// 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

View File

@@ -115,6 +115,12 @@ void Title::checkEventHandler()
switchPalette(); switchPalette();
break; break;
#ifdef DEBUG
case SDL_SCANCODE_F6:
screen->showText("MAMA MIRA! SIN MANOS!");
break;
#endif
default: default:
break; break;
} }
@@ -176,6 +182,9 @@ void Title::update()
// Actualiza la marquesina // Actualiza la marquesina
updateMarquee(); updateMarquee();
// Actualiza las notificaciones
screen->updateNotifier();
// Comprueba si ha terminado la marquesina y acaba con el titulo // Comprueba si ha terminado la marquesina y acaba con el titulo
if (letters.at(letters.size() - 1).x < -10) if (letters.at(letters.size() - 1).x < -10)
{ {