This commit is contained in:
2022-09-11 11:42:10 +02:00
52 changed files with 2804 additions and 658 deletions

View File

@@ -1,9 +1,10 @@
name=void main name=void main
bgColor=black bgColor=black
border=red
tileset=standard.png tileset=standard.png
roomUp=0 roomUp=0
roomDown=0 roomDown=0
roomLeft=0 roomLeft=06.room
roomRight=02.room roomRight=02.room
[tilemap] [tilemap]

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<map version="1.9" tiledversion="1.9.0" orientation="orthogonal" renderorder="right-down" width="32" height="16" tilewidth="8" tileheight="8" infinite="0" nextlayerid="2" nextobjectid="1"> <map version="1.9" tiledversion="1.9.1" orientation="orthogonal" renderorder="right-down" width="32" height="16" tilewidth="8" tileheight="8" infinite="0" nextlayerid="2" nextobjectid="1">
<tileset firstgid="1" source="../../../jaildoctors_dilemma_resources/tilesets/standard.tsx"/> <tileset firstgid="1" source="../../../jaildoctors_dilemma_resources/tilesets/standard.tsx"/>
<layer id="1" name="Capa de patrones 1" width="32" height="16"> <layer id="1" name="Capa de patrones 1" width="32" height="16">
<data encoding="csv"> <data encoding="csv">
@@ -15,8 +15,8 @@
21,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,211,0,0,0,0,0,0,0, 21,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,211,0,0,0,0,0,0,0,
21,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 21,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
21,0,0,0,0,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,0,0,0,0,0,0,0, 21,0,0,0,0,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,0,0,0,0,0,0,0,
21,0,0,0,0,0,0,0,0,211,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,211,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
21,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21, 21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,
21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21 21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21
</data> </data>

View File

@@ -1,5 +1,6 @@
name=case switch name=case switch
bgColor=black bgColor=black
border=green
tileset=standard.png tileset=standard.png
roomUp=0 roomUp=0
roomDown=04.room roomDown=04.room
@@ -23,7 +24,7 @@ x1=14
y1=0 y1=0
x2=14 x2=14
y2=12 y2=12
color=purple color=magenta
[/enemy] [/enemy]
[item] [item]

View File

@@ -1,24 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<map version="1.9" tiledversion="1.9.0" orientation="orthogonal" renderorder="right-down" width="32" height="16" tilewidth="8" tileheight="8" infinite="0" nextlayerid="2" nextobjectid="1"> <map version="1.9" tiledversion="1.9.1" orientation="orthogonal" renderorder="right-down" width="32" height="16" tilewidth="8" tileheight="8" infinite="0" nextlayerid="2" nextobjectid="1">
<tileset firstgid="1" source="../../../jaildoctors_dilemma_resources/tilesets/standard.tsx"/> <tileset firstgid="1" source="../../../jaildoctors_dilemma_resources/tilesets/standard.tsx"/>
<layer id="1" name="Capa de patrones 1" width="32" height="16"> <layer id="1" name="Capa de patrones 1" width="32" height="16">
<data encoding="csv"> <data encoding="csv">
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,23, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,23, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,23, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,23, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,23, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,23, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24,
0,0,0,0,0,0,0,0,0,0,0,203,203,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,23, 0,0,0,0,0,0,0,0,0,0,0,203,203,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,23,23,23,23,23,0,0,0,0,0,0,0,0,0,23, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24,24,24,24,24,0,0,0,0,0,0,0,0,0,24,
23,23,23,23,23,23,0,0,0,203,0,0,0,0,0,0,0,0,0,23,0,0,0,0,203,203,0,0,0,0,0,0, 24,24,24,24,24,24,0,0,0,203,0,0,0,0,0,0,0,0,0,24,0,0,0,0,203,203,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,23,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,203,0,0,0,0,0,0,0,0,0,23,0,0,0,0,203,203,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,203,0,0,0,0,0,0,0,0,0,24,0,0,0,0,203,203,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,23,0,0,0,0,0,0,0,0,0,203,203,23, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24,0,0,0,0,0,0,0,0,0,203,203,24,
0,0,0,0,0,0,0,203,203,203,203,203,203,0,0,0,0,0,0,23,0,0,0,0,203,203,0,0,0,0,0,23, 0,0,0,0,0,0,0,203,203,203,203,203,203,0,0,0,0,0,0,24,0,0,0,0,203,203,0,0,0,0,0,24,
0,0,0,0,0,203,0,0,0,0,0,0,0,0,0,0,0,0,0,23,0,0,0,0,0,0,0,0,0,0,0,23, 0,0,0,0,0,203,0,0,0,0,0,0,0,0,0,0,0,0,0,24,0,0,0,0,0,0,0,0,0,0,0,24,
43,23,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,23,83,83,83,83,83,83,83,83,83,83,83,83, 44,24,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24,84,84,84,84,84,84,84,84,84,84,84,84,
43,43,43,43,43,43,43,43,43,43,43,43,43,43,223,0,0,223,43,43,43,43,43,43,43,43,43,43,43,43,43,43 44,44,44,44,44,44,44,44,44,44,44,44,44,44,223,0,0,223,44,44,44,44,44,44,44,44,44,44,44,44,44,44
</data> </data>
</layer> </layer>
</map> </map>

View File

@@ -1,5 +1,6 @@
name=the edge name=the edge
bgColor=light_black bgColor=bright_black
border=black
tileset=standard.png tileset=standard.png
roomUp=0 roomUp=0
roomDown=05.room roomDown=05.room
@@ -39,7 +40,7 @@ x1=10
y1=2 y1=2
x2=10 x2=10
y2=13 y2=13
color=light_blue color=bright_blue
[/enemy] [/enemy]
[enemy] [enemy]
@@ -55,7 +56,7 @@ x1=16
y1=2 y1=2
x2=16 x2=16
y2=13 y2=13
color=purple color=magenta
[/enemy] [/enemy]
[item] [item]

View File

@@ -1,5 +1,6 @@
name=The Fridge name=The Fridge
bgColor=blue bgColor=blue
border=blue
tileset=standard.png tileset=standard.png
roomUp=02.room roomUp=02.room
roomDown=0 roomDown=0
@@ -23,7 +24,7 @@ x1=1
y1=3 y1=3
x2=14 x2=14
y2=3 y2=3
color=purple color=magenta
[/enemy] [/enemy]
[enemy] [enemy]
@@ -39,7 +40,7 @@ x1=10
y1=7 y1=7
x2=30 x2=30
y2=7 y2=7
color=light_white color=bright_white
[/enemy] [/enemy]
[enemy] [enemy]
@@ -55,7 +56,7 @@ x1=15
y1=12 y1=12
x2=30 x2=30
y2=12 y2=12
color=light_purple color=bright_magenta
[/enemy] [/enemy]
[item] [item]

View File

@@ -1,5 +1,6 @@
name=sigmasua name=sigmasua
bgColor=black bgColor=black
border=blue
tileset=standard.png tileset=standard.png
roomUp=03.room roomUp=03.room
roomDown=0 roomDown=0
@@ -55,7 +56,7 @@ x1=10
y1=10 y1=10
x2=10 x2=10
y2=13 y2=13
color=light_red color=bright_red
[/enemy] [/enemy]
[enemy] [enemy]
@@ -71,7 +72,7 @@ x1=23
y1=10 y1=10
x2=23 x2=23
y2=13 y2=13
color=light_red color=bright_red
[/enemy] [/enemy]
[item] [item]

12
data/room/06.room Normal file
View File

@@ -0,0 +1,12 @@
name=the test room
bgColor=black
border=blue
tileset=standard.png
roomUp=0
roomDown=0
roomLeft=0
roomRight=01.room
[tilemap]
06.tmx
[/tilemap]

24
data/room/06.tmx Normal file
View File

@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<map version="1.9" tiledversion="1.9.1" orientation="orthogonal" renderorder="right-down" width="32" height="16" tilewidth="8" tileheight="8" infinite="0" nextlayerid="2" nextobjectid="1">
<tileset firstgid="1" source="../../../jaildoctors_dilemma_resources/tilesets/standard.tsx"/>
<layer id="1" name="Capa de patrones 1" width="32" height="16">
<data encoding="csv">
26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,
26,0,0,0,0,0,0,0,0,0,0,0,0,0,0,183,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,26,
26,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,183,0,0,0,0,0,0,0,0,0,0,0,0,0,0,26,
26,0,0,0,0,0,86,0,0,0,0,0,0,0,0,0,0,183,0,0,0,0,0,0,0,0,0,0,0,0,0,26,
26,0,0,0,86,86,86,0,0,0,0,0,0,0,0,0,0,0,183,0,0,0,0,0,0,0,0,0,0,0,0,26,
26,0,0,0,86,0,86,0,0,0,0,0,0,0,0,167,66,66,66,66,187,0,0,0,0,164,65,65,0,0,0,26,
26,0,0,0,86,0,86,0,0,0,0,0,0,0,162,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,26,
26,0,0,0,0,0,0,0,0,0,0,0,0,162,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,26,
26,0,0,0,0,0,0,0,0,0,0,0,162,0,0,0,0,0,0,0,0,0,0,0,0,62,62,0,0,0,0,26,
26,0,0,0,0,0,0,0,0,161,212,212,212,212,212,212,212,0,212,212,0,0,0,0,0,62,62,0,0,0,0,26,
26,0,0,0,0,0,0,0,161,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,26,
26,0,0,0,0,0,0,161,0,0,0,0,0,0,0,0,0,269,0,0,0,0,0,0,0,0,22,22,0,0,0,26,
26,0,0,0,0,0,161,0,0,0,0,0,0,0,0,0,0,269,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
26,0,0,0,0,161,0,0,0,0,0,0,0,0,0,0,81,289,81,0,0,0,0,0,0,0,0,0,0,0,0,0,
26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,
26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26
</data>
</layer>
</map>

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
media/music/title.ogg Normal file

Binary file not shown.

View File

Before

Width:  |  Height:  |  Size: 222 B

After

Width:  |  Height:  |  Size: 222 B

24
media/player/player2.ani Normal file
View File

@@ -0,0 +1,24 @@
frames_per_row=8
frame_width=8
frame_height=16
[animation]
name=stand
speed=8
loop=0
frames=0
[/animation]
[animation]
name=walk
speed=8
loop=0
frames=0,1,2,3,4,5,6,7
[/animation]
[animation]
name=walk_menu
speed=0
loop=0
frames=0,1,2,3,4,5,6,7
[/animation]

BIN
media/player/player2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 314 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 5.5 KiB

View File

@@ -10,7 +10,7 @@
// Textos // Textos
#define WINDOW_CAPTION "JailDoctor's Dilemma" #define WINDOW_CAPTION "JailDoctor's Dilemma"
#define TEXT_COPYRIGHT "@2022 JailDesigner" #define TEXT_COPYRIGHT "@2022 JailDesigner"
#define VERSION "0.1" #define VERSION "0.6"
// Tamaño de bloque // Tamaño de bloque
#define BLOCK 8 #define BLOCK 8

85
source/debug.cpp Normal file
View File

@@ -0,0 +1,85 @@
#include "debug.h"
// Constructor
Debug::Debug(SDL_Renderer *renderer, Screen *screen, Asset *asset)
{
// Copia la dirección de los objetos
this->renderer = renderer;
this->screen = screen;
this->asset = asset;
// Reserva memoria para los punteros
text = new Text(asset->get("debug.png"), asset->get("debug.txt"), renderer);
// Inicializa variables
x = 0;
y = 0;
enabled = false;
}
// Destructor
Debug::~Debug()
{
delete text;
}
// Actualiza las variables
void Debug::update()
{
}
// Dibuja en pantalla
void Debug::render()
{
int y = this->y;
int w = 0;
for (auto s : slot)
{
text->write(x, y, s);
w = (std::max(w, (int)s.length()));
y += text->getCharacterSize() + 1;
if (y > 192 - text->getCharacterSize())
{
y = this->y;
x += w * text->getCharacterSize() + 2;
}
}
}
// Establece la posición donde se colocará la información de debug
void Debug::setPos(SDL_Point p)
{
x = p.x;
y = p.y;
}
// Añade un texto para mostrar
void Debug::add(std::string text)
{
slot.push_back(text);
}
// Borra la información de debug
void Debug::clear()
{
slot.clear();
}
// Establece el valor de la variable
void Debug::setEnabled(bool value)
{
enabled = value;
}
// Obtiene el valor de la variable
bool Debug::getEnabled()
{
return enabled;
}
// Cambia el valor de la variable
void Debug::switchEnabled()
{
enabled = !enabled;
}

60
source/debug.h Normal file
View File

@@ -0,0 +1,60 @@
#pragma once
#include <SDL2/SDL.h>
#include "const.h"
#include "utils.h"
#include "screen.h"
#include "asset.h"
#include "text.h"
#include <vector>
#include <string>
#ifndef DEBUG_H
#define DEBUG_H
// Clase Debug
class Debug
{
private:
SDL_Renderer *renderer; // El renderizador de la ventana
Screen *screen; // Objeto encargado de dibujar en pantalla
Asset *asset; // Objeto con los ficheros de recursos
Text *text; // Objeto encargado de escribir texto en pantalla
std::vector<std::string> slot; // Vector con los textos a escribir
int x; // Posicion donde escribir el texto de debug
int y; // Posición donde escribir el texto de debug
bool enabled; // Indica si esta activo el modo debug
public:
// Constructor
Debug(SDL_Renderer *renderer, Screen *screen, Asset *asset);
// Destructor
~Debug();
// Actualiza las variables
void update();
// Dibuja en pantalla
void render();
// Establece la posición donde se colocará la información de debug
void setPos(SDL_Point p);
// Añade un texto para mostrar
void add(std::string text);
// Borra la información de debug
void clear();
// Establece el valor de la variable
void setEnabled(bool value);
// Obtiene el valor de la variable
bool getEnabled();
// Cambia el valor de la variable
void switchEnabled();
};
#endif

View File

@@ -17,7 +17,7 @@ Director::Director(std::string path)
} }
else else
{ {
section.name = SECTION_PROG_TITLE; section.name = SECTION_PROG_GAME;
section.subsection = 0; section.subsection = 0;
} }
@@ -43,6 +43,7 @@ Director::Director(std::string path)
initInput(); initInput();
screen = new Screen(window, renderer, options, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT); screen = new Screen(window, renderer, options, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT);
screen->setBorderColor(borderColor); screen->setBorderColor(borderColor);
debug = new Debug(renderer, screen, asset);
} }
Director::~Director() Director::~Director()
@@ -51,6 +52,7 @@ Director::~Director()
delete asset; delete asset;
delete input; delete input;
delete screen; delete screen;
delete debug;
SDL_DestroyRenderer(renderer); SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window); SDL_DestroyWindow(window);
@@ -164,11 +166,13 @@ bool Director::setFileList()
asset->add("/data/room/03.room", room); asset->add("/data/room/03.room", room);
asset->add("/data/room/04.room", room); asset->add("/data/room/04.room", room);
asset->add("/data/room/05.room", room); asset->add("/data/room/05.room", room);
asset->add("/data/room/06.room", room);
asset->add("/data/room/01.tmx", room); asset->add("/data/room/01.tmx", room);
asset->add("/data/room/02.tmx", room); asset->add("/data/room/02.tmx", room);
asset->add("/data/room/03.tmx", room); asset->add("/data/room/03.tmx", room);
asset->add("/data/room/04.tmx", room); asset->add("/data/room/04.tmx", room);
asset->add("/data/room/05.tmx", room); asset->add("/data/room/05.tmx", room);
asset->add("/data/room/06.tmx", room);
asset->add("/media/tilesets/standard.png", bitmap); asset->add("/media/tilesets/standard.png", bitmap);
@@ -181,12 +185,16 @@ bool Director::setFileList()
asset->add("/media/enemies/sigmasua.png", bitmap); asset->add("/media/enemies/sigmasua.png", bitmap);
asset->add("/media/enemies/sigmasua.ani", data); asset->add("/media/enemies/sigmasua.ani", data);
asset->add("/media/player/player01.png", bitmap); asset->add("/media/player/player.png", bitmap);
asset->add("/media/player/player01.ani", data); asset->add("/media/player/player.ani", data);
asset->add("/media/items/items.png", bitmap); asset->add("/media/items/items.png", bitmap);
asset->add("/media/music/jd.ogg", music); asset->add("/media/music/title.ogg", music);
asset->add("/media/music/game.ogg", music);
asset->add("/media/music/loading_sound1.ogg", music);
asset->add("/media/music/loading_sound2.ogg", music);
asset->add("/media/music/loading_sound3.ogg", music);
asset->add("/media/sound/item.wav", sound); asset->add("/media/sound/item.wav", sound);
@@ -229,6 +237,9 @@ void Director::runLogo()
// Ejecuta la seccion de juego de la introducción // Ejecuta la seccion de juego de la introducción
void Director::runIntro() void Director::runIntro()
{ {
intro = new Intro(renderer, screen, asset);
setSection(intro->run());
delete intro;
} }
// Ejecuta la seccion de juego con el titulo y los menus // Ejecuta la seccion de juego con el titulo y los menus
@@ -242,7 +253,7 @@ void Director::runTitle()
// Ejecuta la seccion de juego donde se juega // Ejecuta la seccion de juego donde se juega
void Director::runGame() void Director::runGame()
{ {
game = new Game(renderer, screen, asset, input); game = new Game(renderer, screen, asset, input, debug);
setSection(game->run()); setSection(game->run());
delete game; delete game;
} }

View File

@@ -9,7 +9,9 @@
#include "game.h" #include "game.h"
#include "logo.h" #include "logo.h"
#include "title.h" #include "title.h"
#include "intro.h"
#include "asset.h" #include "asset.h"
#include "debug.h"
#include "const.h" #include "const.h"
#ifndef DIRECTOR_H #ifndef DIRECTOR_H
@@ -26,7 +28,9 @@ private:
Game *game; // Objeto para gestionar la sección del juego Game *game; // Objeto para gestionar la sección del juego
Logo *logo; // Objeto para gestionar la sección del logo del programa Logo *logo; // Objeto para gestionar la sección del logo del programa
Title *title; // Objeto para gestionar la pantalla de título Title *title; // Objeto para gestionar la pantalla de título
Intro *intro; // Onjeto para gestionar la introducción del juego
Asset *asset; // Objeto que gestiona todos los ficheros de recursos Asset *asset; // Objeto que gestiona todos los ficheros de recursos
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

View File

@@ -1,36 +1,43 @@
#include "game.h" #include "game.h"
// Constructor // Constructor
Game::Game(SDL_Renderer *renderer, Screen *screen, Asset *asset, Input *input) Game::Game(SDL_Renderer *renderer, Screen *screen, Asset *asset, Input *input, Debug *debug)
{ {
// Inicia variables // Inicia algunas variables
clock = SDL_GetTicks(); clock = SDL_GetTicks();
currentRoom = "01.room"; currentRoom = "01.room";
spawnPoint = {2 * 8, 12 * 8, 0, 0, 0, STATUS_STANDING, SDL_FLIP_NONE}; spawnPoint = {16, 96, 0, 0, 0, s_standing, SDL_FLIP_NONE};
debug = false;
currentRoom = "06.room";
spawnPoint = {240, 96, 0, 0, 0, s_standing, SDL_FLIP_HORIZONTAL};
// Copia los punteros // Copia los punteros
this->renderer = renderer; this->renderer = renderer;
this->asset = asset; this->asset = asset;
this->screen = screen; this->screen = screen;
this->input = input; this->input = input;
this->debug = debug;
debug->setEnabled(true);
// Crea los objetos // Crea los objetos
scoreboard = new ScoreBoard(renderer, asset, &playerLives, &itemsPicked, &clock); scoreboard = new ScoreBoard(renderer, asset, &playerLives, &itemsPicked, &clock);
itemTracker = new ItemTracker(); itemTracker = new ItemTracker();
room = new Room(asset->get(currentRoom), renderer, asset, itemTracker, &itemsPicked); room = new Room(asset->get(currentRoom), renderer, screen, asset, itemTracker, &itemsPicked, debug);
player = new Player(spawnPoint, asset->get("player01.png"), asset->get("player01.ani"), renderer, asset, input, room); player = new Player(spawnPoint, asset->get("player.png"), asset->get("player.ani"), renderer, asset, input, room, debug);
eventHandler = new SDL_Event(); eventHandler = new SDL_Event();
text = new Text(asset->get("smb2.png"), asset->get("smb2.txt"), renderer); text = new Text(asset->get("smb2.png"), asset->get("smb2.txt"), renderer);
debugText = new Text(asset->get("debug.png"), asset->get("debug.txt"), renderer); music = JA_LoadMusic(asset->get("game.ogg").c_str());
music = JA_LoadMusic(asset->get("jd.ogg").c_str()); test = new Test(renderer, screen, asset, debug);
// Inicializa variables // Inicializa el resto de variables
ticks = 0; ticks = 0;
ticksSpeed = 15; ticksSpeed = 15;
playerLives = 9; playerLives = 9;
itemsPicked = 0; itemsPicked = 0;
player->setInvincible(debug->getEnabled());
musicEnabled = !debug->getEnabled();
section.name = SECTION_PROG_GAME; section.name = SECTION_PROG_GAME;
section.subsection = SUBSECTION_GAME_PLAY; section.subsection = SUBSECTION_GAME_PLAY;
} }
@@ -44,25 +51,13 @@ Game::~Game()
// Libera la memoria de los objetos // Libera la memoria de los objetos
delete scoreboard; delete scoreboard;
scoreboard = nullptr;
delete itemTracker; delete itemTracker;
itemTracker = nullptr;
delete room; delete room;
room = nullptr;
delete player; delete player;
player = nullptr;
delete eventHandler; delete eventHandler;
eventHandler = nullptr;
delete text; delete text;
text = nullptr;
delete debugText; delete test;
debugText = nullptr;
} }
// Comprueba los eventos de la cola // Comprueba los eventos de la cola
@@ -75,10 +70,13 @@ void Game::checkEventHandler()
if (eventHandler->type == SDL_QUIT) if (eventHandler->type == SDL_QUIT)
{ {
section.name = SECTION_PROG_QUIT; section.name = SECTION_PROG_QUIT;
screen->setBorderColor(stringToColor("black"));
break; break;
} }
else if ((eventHandler->type == SDL_KEYDOWN) and (eventHandler->key.repeat == 0)) else if ((eventHandler->type == SDL_KEYDOWN) and (eventHandler->key.repeat == 0))
{ {
//test->update();
switch (eventHandler->key.keysym.scancode) switch (eventHandler->key.keysym.scancode)
{ {
case SDL_SCANCODE_ESCAPE: case SDL_SCANCODE_ESCAPE:
@@ -86,7 +84,10 @@ void Game::checkEventHandler()
break; break;
case SDL_SCANCODE_D: case SDL_SCANCODE_D:
debug = !debug; debug->switchEnabled();
player->setInvincible(debug->getEnabled());
musicEnabled = !debug->getEnabled();
musicEnabled ? JA_PlayMusic(music) : JA_StopMusic();
break; break;
case SDL_SCANCODE_M: case SDL_SCANCODE_M:
@@ -128,7 +129,10 @@ void Game::checkEventHandler()
// Bucle para el juego // Bucle para el juego
section_t Game::run() section_t Game::run()
{ {
if (musicEnabled)
{
JA_PlayMusic(music); JA_PlayMusic(music);
}
while (section.name == SECTION_PROG_GAME) while (section.name == SECTION_PROG_GAME)
{ {
@@ -158,16 +162,14 @@ void Game::update()
checkEventHandler(); checkEventHandler();
// Actualiza los objetos // Actualiza los objetos
debug->clear();
room->update(); room->update();
{
player->update(); player->update();
checkPlayerAndWalls(); // Debe ir detras del player update, por si se ha metido en algun muro
}
checkPlayerOnBorder(); checkPlayerOnBorder();
checkPlayerOnFloor();
checkPlayerAndItems(); checkPlayerAndItems();
checkPlayerAndEnemies(); checkPlayerAndEnemies();
scoreboard->update(); scoreboard->update();
updateDebugInfo();
} }
} }
@@ -187,21 +189,35 @@ void Game::render()
// Debug info // Debug info
renderDebugInfo(); renderDebugInfo();
//test->render();
// Actualiza la pantalla // Actualiza la pantalla
screen->blit(); screen->blit();
} }
// Pasa la información de debug
void Game::updateDebugInfo()
{
debug->add("X = " + std::to_string((int)player->x) + ", Y = " + std::to_string((int)player->y));
debug->add("VX = " + std::to_string(player->vx).substr(0, 4) + ", VY = " + std::to_string(player->vy).substr(0, 4));
debug->add("STATE = " + std::to_string(player->state));
}
// Pone la información de debug en pantalla // Pone la información de debug en pantalla
void Game::renderDebugInfo() void Game::renderDebugInfo()
{ {
if (!debug) if (!debug->getEnabled())
{ {
return; return;
} }
// Borra el marcador
SDL_Rect rect = {0, 18 * BLOCK, PLAY_AREA_WIDTH, GAMECANVAS_HEIGHT - PLAY_AREA_HEIGHT};
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderFillRect(renderer, &rect);
// Pinta la rejilla // Pinta la rejilla
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 64); /*SDL_SetRenderDrawColor(renderer, 255, 255, 255, 32);
for (int i = 0; i < PLAY_AREA_BOTTOM; i += 8) for (int i = 0; i < PLAY_AREA_BOTTOM; i += 8)
{ // Lineas horizontales { // Lineas horizontales
SDL_RenderDrawLine(renderer, 0, i, PLAY_AREA_RIGHT, i); SDL_RenderDrawLine(renderer, 0, i, PLAY_AREA_RIGHT, i);
@@ -209,39 +225,23 @@ void Game::renderDebugInfo()
for (int i = 0; i < PLAY_AREA_RIGHT; i += 8) for (int i = 0; i < PLAY_AREA_RIGHT; i += 8)
{ // Lineas verticales { // Lineas verticales
SDL_RenderDrawLine(renderer, i, 0, i, PLAY_AREA_BOTTOM - 1); SDL_RenderDrawLine(renderer, i, 0, i, PLAY_AREA_BOTTOM - 1);
} }*/
// Pinta el texto // Pinta el texto
std::string text; debug->setPos({1, 18 * 8});
const int inc = debugText->getCharacterWidth() + 1; debug->render();
int line = 131;
text = "status: " + std::to_string(player->status);
debugText->write(0, line += inc, text);
text = "foot: " + std::to_string((int)player->getLeftFoot().y);
debugText->write(0, line += inc, text);
const int a = (player->lastPosition.y + 16) / 8;
const int b = player->getLeftFoot().y / 8;
text = "tile: " + std::to_string(a) + " - " + std::to_string(b);
debugText->write(0, line += inc, text);
const bool collision = checkPlayerAndEnemies();
text = "collision: " + std::to_string(collision);
debugText->write(0, line += inc, text);
} }
// Escribe el nombre de la pantalla // Escribe el nombre de la pantalla
void Game::renderRoomName() void Game::renderRoomName()
{ {
// Texto en el centro de la pantalla // Texto en el centro de la pantalla
SDL_Rect rect = {0, 16 * BLOCK, PLAY_AREA_WIDTH, BLOCK}; SDL_Rect rect = {0, 16 * BLOCK, PLAY_AREA_WIDTH, BLOCK * 2};
color_t color = stringToColor("light_black"); color_t color = stringToColor("white");
SDL_SetRenderDrawColor(renderer, color.r, color.g, color.b, 0xFF); SDL_SetRenderDrawColor(renderer, color.r, color.g, color.b, 0xFF);
SDL_RenderFillRect(renderer, &rect); SDL_RenderFillRect(renderer, &rect);
text->writeCentered(GAMECANVAS_CENTER_X, 16 * 8, room->getName()); text->writeDX(TXT_CENTER | TXT_COLOR, GAMECANVAS_CENTER_X, 16 * 8 + 4, room->getName(), 1, room->getBGColor());
} }
// Cambia de habitación // Cambia de habitación
@@ -259,7 +259,10 @@ bool Game::changeRoom(std::string file)
room = nullptr; room = nullptr;
// Crea un objeto habitación nuevo a partir del fichero // Crea un objeto habitación nuevo a partir del fichero
room = new Room(asset->get(file), renderer, asset, itemTracker, &itemsPicked); room = new Room(asset->get(file), renderer, screen, asset, itemTracker, &itemsPicked, debug);
// Pasa la nueva habitación al jugador
player->setRoom(room);
success = true; success = true;
} }
@@ -282,105 +285,6 @@ void Game::checkPlayerOnBorder()
} }
} }
// Comprueba si el jugador esta sobre el suelo
void Game::checkPlayerOnFloor()
{
// Comprueba si tiene suelo bajo los pies solo cuando no hay velocidad de subida
// y solo cuando el pie este encima de un bloque, es decir, en multiplos de 8
// *** HAY UN POSIBLE PROBLEMA y es que caiga muy rapido y viaje a mas de un pixel de velocidad,
// con lo que se saltaria la comprobación
// *** POSIBLE SOLUCION. Comprobar si el tile actual del pie es diferente al tile del pie previo.
// Esto indica que se ha saltado la comprobacion cada 8 pixeles.
// En este caso habría que recolocar al jugador en el sitio
// *** PARECE RESUELTO
const int a = (player->lastPosition.y + 16) / 8;
const int b = player->getLeftFoot().y / 8;
const bool tile_change = a != b;
const bool is_not_going_up = player->getVelY() >= 0;
const bool is_tile_aligned = player->getLeftFoot().y % 8 == 0;
if (((is_not_going_up) && (is_tile_aligned)) || ((is_not_going_up) && (tile_change)))
{
bool test = false;
test |= (room->getTile(player->getLeftFoot()) == TILE_SOLID);
test |= (room->getTile(player->getRightFoot()) == TILE_SOLID);
test |= (room->getTile(player->getLeftFoot()) == TILE_TRAVESSABLE);
test |= (room->getTile(player->getRightFoot()) == TILE_TRAVESSABLE);
// Tiene uno de los pies sobre una superficie
if (test)
{
player->setStatus(STATUS_STANDING);
// Si ha habido un cambio de tile, hay que recolocarlo
if (tile_change)
{
int offset = (int)player->sprite->getPosY() % 8;
player->sprite->setPosY((int)player->sprite->getPosY() - offset);
}
}
// Tiene ambos pies sobre el vacío
else if (player->getStatus() != STATUS_JUMPING)
{
player->setStatus(STATUS_FALLING);
}
}
}
// Comprueba que el jugador no atraviese ninguna pared
void Game::checkPlayerAndWalls()
{
// Obtiene los ocho puntos de colisión del jugador
const SDL_Rect rect = player->getRect();
const SDL_Point p1 = {rect.x, rect.y};
const SDL_Point p2 = {rect.x + 7, rect.y};
const SDL_Point p3 = {rect.x + 7, rect.y + 7};
const SDL_Point p4 = {rect.x, rect.y + 7};
const SDL_Point p5 = {rect.x, rect.y + 8};
const SDL_Point p6 = {rect.x + 7, rect.y + 8};
const SDL_Point p7 = {rect.x + 7, rect.y + 15};
const SDL_Point p8 = {rect.x, rect.y + 15};
// Comprueba si ha colisionado con un muro
bool wall = false;
wall |= (room->getTile(p1) == TILE_SOLID);
wall |= (room->getTile(p2) == TILE_SOLID);
wall |= (room->getTile(p3) == TILE_SOLID);
wall |= (room->getTile(p4) == TILE_SOLID);
wall |= (room->getTile(p5) == TILE_SOLID);
wall |= (room->getTile(p6) == TILE_SOLID);
wall |= (room->getTile(p7) == TILE_SOLID);
wall |= (room->getTile(p8) == TILE_SOLID);
if (wall)
{
// Si hay colisión, deshace el movimiento y lo pone en modo caída
player->undoLastMove();
player->setStatus(STATUS_FALLING);
}
// Comprueba si ha colisionado con un tile de los que matan al jugador
bool death = false;
death |= (room->getTile(p1) == TILE_KILL);
death |= (room->getTile(p2) == TILE_KILL);
death |= (room->getTile(p3) == TILE_KILL);
death |= (room->getTile(p4) == TILE_KILL);
death |= (room->getTile(p5) == TILE_KILL);
death |= (room->getTile(p6) == TILE_KILL);
death |= (room->getTile(p7) == TILE_KILL);
death |= (room->getTile(p8) == TILE_KILL);
if (death)
{
killPlayer();
}
}
// Comprueba las colisiones del jugador con los enemigos // Comprueba las colisiones del jugador con los enemigos
bool Game::checkPlayerAndEnemies() bool Game::checkPlayerAndEnemies()
{ {
@@ -401,6 +305,11 @@ void Game::checkPlayerAndItems()
// Mata al jugador // Mata al jugador
void Game::killPlayer() void Game::killPlayer()
{ {
if (player->getInvincible())
{
return;
}
playerLives--; playerLives--;
// Destruye la habitacion y el jugador // Destruye la habitacion y el jugador
@@ -408,8 +317,8 @@ void Game::killPlayer()
delete player; delete player;
// Crea la nueva habitación y el nuevo jugador // Crea la nueva habitación y el nuevo jugador
room = new Room(asset->get(currentRoom), renderer, asset, itemTracker, &itemsPicked); room = new Room(asset->get(currentRoom), renderer, screen, asset, itemTracker, &itemsPicked, debug);
player = new Player(spawnPoint, asset->get("player01.png"), asset->get("player01.ani"), renderer, asset, input, room); player = new Player(spawnPoint, asset->get("player.png"), asset->get("player.ani"), renderer, asset, input, room, debug);
} }
// Recarga todas las texturas // Recarga todas las texturas

View File

@@ -13,6 +13,8 @@
#include "player.h" #include "player.h"
#include "jail_audio.h" #include "jail_audio.h"
#include "scoreboard.h" #include "scoreboard.h"
#include "debug.h"
#include "test.h"
#ifndef GAME_H #ifndef GAME_H
#define GAME_H #define GAME_H
@@ -30,18 +32,19 @@ private:
Asset *asset; // Objeto con la ruta a todos los ficheros de recursos Asset *asset; // Objeto con la ruta a todos los ficheros de recursos
Input *input; // Objeto pata gestionar la entrada Input *input; // Objeto pata gestionar la entrada
Text *text; // Objeto para los textos del juego Text *text; // Objeto para los textos del juego
Text *debugText; // Objeto para los textos de debug del juego
ScoreBoard *scoreboard; // Objeto encargado de gestionar el marcador ScoreBoard *scoreboard; // Objeto encargado de gestionar el marcador
JA_Music music; // Musica que suena durante el juego JA_Music music; // Musica que suena durante el juego
Debug *debug; // Objeto para gestionar la información de debug
bool musicEnabled; // Indica si ha de sonar la musica durante el juego
int ticks; // Contador de ticks para ajustar la velocidad del programa int ticks; // Contador de ticks para ajustar la velocidad del programa
int ticksSpeed; // Velocidad a la que se repiten los bucles del programa int ticksSpeed; // Velocidad a la que se repiten los bucles del programa
section_t section; // Seccion actual dentro del juego section_t section; // Seccion actual dentro del juego
std::string currentRoom; // Fichero de la habitación actual std::string currentRoom; // Fichero de la habitación actual
player_t spawnPoint; // Lugar de la habitación donde aparece el jugador player_t spawnPoint; // Lugar de la habitación donde aparece el jugador
bool debug; // Indica si el modo debug está activo
int playerLives; // Lleva la cuenta de ls vidas restantes del jugador int playerLives; // Lleva la cuenta de ls vidas restantes del jugador
int itemsPicked; // Lleva la cuenta de los objetos recogidos int itemsPicked; // Lleva la cuenta de los objetos recogidos
Uint32 clock; // Cuenta el tiempo que dura la partida Uint32 clock; // Cuenta el tiempo que dura la partida
Test *test;
// Actualiza el juego, las variables, comprueba la entrada, etc. // Actualiza el juego, las variables, comprueba la entrada, etc.
void update(); void update();
@@ -52,6 +55,9 @@ private:
// Comprueba los eventos de la cola // Comprueba los eventos de la cola
void checkEventHandler(); void checkEventHandler();
// Pone la información de debug en pantalla
void updateDebugInfo();
// Pone la información de debug en pantalla // Pone la información de debug en pantalla
void renderDebugInfo(); void renderDebugInfo();
@@ -64,12 +70,6 @@ private:
// Comprueba si el jugador esta en el borde de la pantalla y actua // Comprueba si el jugador esta en el borde de la pantalla y actua
void checkPlayerOnBorder(); void checkPlayerOnBorder();
// Comprueba si el jugador esta sobre el suelo
void checkPlayerOnFloor();
// Comprueba que el jugador no atraviese ninguna pared
void checkPlayerAndWalls();
// Comprueba las colisiones del jugador con los enemigos // Comprueba las colisiones del jugador con los enemigos
bool checkPlayerAndEnemies(); bool checkPlayerAndEnemies();
@@ -84,7 +84,7 @@ private:
public: public:
// Constructor // Constructor
Game(SDL_Renderer *renderer, Screen *screen, Asset *asset, Input *input); Game(SDL_Renderer *renderer, Screen *screen, Asset *asset, Input *input, Debug *debug);
// Destructor // Destructor
~Game(); ~Game();

View File

@@ -177,7 +177,7 @@ bool Input::discoverGameController()
std::cout << "SDL_GetError() = " << SDL_GetError() << std::endl; std::cout << "SDL_GetError() = " << SDL_GetError() << std::endl;
} }
//mGameController = mConnectedControllers[0]; // mGameController = mConnectedControllers[0];
SDL_GameControllerEventState(SDL_ENABLE); SDL_GameControllerEventState(SDL_ENABLE);
} }

View File

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

239
source/intro.cpp Normal file
View File

@@ -0,0 +1,239 @@
#include "intro.h"
// Constructor
Intro::Intro(SDL_Renderer *renderer, Screen *screen, Asset *asset)
{
// Copia la dirección de los objetos
this->renderer = renderer;
this->screen = screen;
this->asset = asset;
// Reserva memoria para los punteros
eventHandler = new SDL_Event();
texture = new LTexture(renderer, asset->get("loading_screen1.png"));
texture2 = new LTexture(renderer, asset->get("loading_screen2.png"));
sprite = new Sprite(0, 0, texture->getWidth(), texture->getHeight(), texture, renderer);
sprite2 = new Sprite(0, 0, texture2->getWidth(), texture2->getHeight(), texture2, renderer);
loadingSound1 = JA_LoadMusic(asset->get("loading_sound1.ogg").c_str());
loadingSound2 = JA_LoadMusic(asset->get("loading_sound2.ogg").c_str());
loadingSound3 = JA_LoadMusic(asset->get("loading_sound3.ogg").c_str());
// Inicializa variables
preCounter = 0;
counter = 0;
section.name = SECTION_PROG_INTRO;
section.subsection = 0;
ticks = 0;
ticksSpeed = 15;
loadCounter = 0;
loadCounter = 0;
load1 = true;
load2 = false;
// Cambia el color del borde
screen->setBorderColor(stringToColor("black"));
}
// Destructor
Intro::~Intro()
{
delete texture;
delete texture2;
delete sprite;
delete sprite2;
delete eventHandler;
JA_DeleteMusic(loadingSound1);
JA_DeleteMusic(loadingSound2);
JA_DeleteMusic(loadingSound3);
// delete text;
}
// Comprueba el manejador de eventos
void Intro::checkEventHandler()
{
// Comprueba los eventos que hay en la cola
while (SDL_PollEvent(eventHandler) != 0)
{
// Evento de salida de la aplicación
if (eventHandler->type == SDL_QUIT)
{
section.name = SECTION_PROG_QUIT;
break;
}
// Cualquier tecla pulsada
if ((eventHandler->type == SDL_KEYDOWN) || (eventHandler->type == SDL_JOYBUTTONDOWN))
{
section.name = SECTION_PROG_TITLE;
section.subsection = 0;
}
}
}
// Gestiona el contador de carga
void Intro::updateLoad()
{
if (load1)
{
loadCounter = counter / 20;
if (loadCounter == 25)
{
load1 = false;
load2 = true;
loadCounter = 0;
JA_PlayMusic(loadingSound3);
}
}
else
{
loadCounter += 2;
loadCounter = std::min(loadCounter, 768);
}
}
// Gestiona el contador interno
void Intro::updateCounter()
{
if (preCounter >= 50)
{
if (counter == 0)
{
JA_PlayMusic(loadingSound2);
}
counter++;
}
else
{
preCounter++;
}
}
// Dibuja la pantalla de carga
void Intro::renderLoad()
{
// Carga 1 - Blanco y negro
if (load1)
{
sprite->render();
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
// Muestra las lineas 0..63
if (loadCounter < 8)
{
SDL_Rect rect = {0, 0 + loadCounter, 256, 8 - loadCounter};
SDL_RenderFillRect(renderer, &rect);
for (int i = 0; i < 6; i++)
{
rect.y += 8;
SDL_RenderFillRect(renderer, &rect);
}
rect.y += 8;
rect.h = 128;
SDL_RenderFillRect(renderer, &rect);
}
// Muestra las lineas 64..127
else if (loadCounter >= 8 && loadCounter < 16)
{
SDL_Rect rect = {0, 64 + (loadCounter - 8), 256, 8 - (loadCounter - 8)};
SDL_RenderFillRect(renderer, &rect);
for (int i = 0; i < 6; i++)
{
rect.y += 8;
SDL_RenderFillRect(renderer, &rect);
}
rect.y += 8;
rect.h = 64;
SDL_RenderFillRect(renderer, &rect);
}
// Muestra las lineas 128..191
else if (loadCounter >= 16 && loadCounter < 23)
{
SDL_Rect rect = {0, 128 + (loadCounter - 16), 256, 8 - (loadCounter - 16)};
SDL_RenderFillRect(renderer, &rect);
for (int i = 0; i < 6; i++)
{
rect.y += 8;
SDL_RenderFillRect(renderer, &rect);
}
}
}
else
// Carga 2 - Color
{
sprite->render();
SDL_Rect rect = {0, 0, 8, 8};
for (int i = 0; i < loadCounter; i++)
{
rect.x = (i * 8) % 256;
rect.y = (i / 32) * 8;
sprite2->setPos(rect);
sprite2->setSpriteClip(rect);
sprite2->render();
}
}
}
// Actualiza las variables
void Intro::update()
{
// Comprueba que la diferencia de ticks sea mayor a la velocidad del juego
if (SDL_GetTicks() - ticks > ticksSpeed)
{
// Actualiza el contador de ticks
ticks = SDL_GetTicks();
// Comprueba el manejador de eventos
checkEventHandler();
// Gestiona el contador interno
updateCounter();
// Gestiona el contador de carga
updateLoad();
// Comprueba si ha terminado la intro
if (loadCounter >= 768)
{
section.name = SECTION_PROG_TITLE;
section.subsection = 0;
JA_StopMusic();
}
}
}
// Dibuja en pantalla
void Intro::render()
{
// Prepara para empezar a dibujar en la textura de juego
screen->start();
// Limpia la pantalla
screen->clean();
// Dibuja la pantalla de carga
renderLoad();
// text->write(0, 0, std::to_string(loadCounter));
// text->write(0, 8, std::to_string(loadCounter));
// Vuelca el contenido del renderizador en pantalla
screen->blit();
}
// Bucle para el logo del juego
section_t Intro::run()
{
// Inicia el sonido de carga
JA_PlayMusic(loadingSound1);
while (section.name == SECTION_PROG_INTRO)
{
update();
render();
}
return section;
}

70
source/intro.h Normal file
View File

@@ -0,0 +1,70 @@
#pragma once
#include <SDL2/SDL.h>
#include "const.h"
#include "utils.h"
#include "sprite.h"
#include "screen.h"
#include "asset.h"
#include "jail_audio.h"
#include <vector>
#include <string>
#include "text.h"
#ifndef INTRO_H
#define INTRO_H
// Clase Intro
class Intro
{
private:
SDL_Renderer *renderer; // El renderizador de la ventana
Screen *screen; // Objeto encargado de dibujar en pantalla
Asset *asset; // Objeto con los ficheros de recursos
LTexture *texture; // Textura con los graficos "JAILGAMES"
LTexture *texture2; // Textura con los graficos "Since 1998"
SDL_Event *eventHandler; // Manejador de eventos
Sprite *sprite; // Sprite para manejar la textura
Sprite *sprite2; // Sprite para manejar la textura2
int preCounter; // Contador previo para realizar una pausa inicial
int counter; // Contador
section_t section; // Estado del bucle principal para saber si continua o se sale
int ticks; // Contador de ticks para ajustar la velocidad del programa
int ticksSpeed; // Velocidad a la que se repiten los bucles del programa
int loadCounter; // Contador para controlar las cargas
bool load1, load2;
JA_Music loadingSound1, loadingSound2, loadingSound3;
// Text *text;
// Actualiza las variables
void update();
// Dibuja en pantalla
void render();
// Comprueba el manejador de eventos
void checkEventHandler();
// Gestiona el contador interno
void updateCounter();
// Gestiona el contador de carga
void updateLoad();
// Dibuja la pantalla de carga
void renderLoad();
public:
// Constructor
Intro(SDL_Renderer *renderer, Screen *screen, Asset *asset);
// Destructor
~Intro();
// Bucle principal
section_t run();
};
#endif

View File

@@ -10,7 +10,7 @@ Item::Item(item_t item)
renderer = item.renderer; renderer = item.renderer;
// Crea objetos // Crea objetos
texture = new LTexture(renderer,asset->get(item.tileset)); texture = new LTexture(renderer, asset->get(item.tileset));
sprite = new Sprite(item.x, item.y, 8, 8, texture, renderer); sprite = new Sprite(item.x, item.y, 8, 8, texture, renderer);
// Inicia variables // Inicia variables
@@ -26,7 +26,7 @@ Item::Item(item_t item)
c = stringToColor("red"); c = stringToColor("red");
color.push_back(c); color.push_back(c);
c = stringToColor("purple"); c = stringToColor("magenta");
color.push_back(c); color.push_back(c);
c = stringToColor("green"); c = stringToColor("green");

View File

@@ -49,7 +49,7 @@ Logo::Logo(SDL_Renderer *renderer, Screen *screen, Asset *asset)
c = stringToColor("red"); c = stringToColor("red");
color.push_back(c); color.push_back(c);
c = stringToColor("purple"); c = stringToColor("magenta");
color.push_back(c); color.push_back(c);
c = stringToColor("green"); c = stringToColor("green");
@@ -61,8 +61,11 @@ Logo::Logo(SDL_Renderer *renderer, Screen *screen, Asset *asset)
c = stringToColor("yellow"); c = stringToColor("yellow");
color.push_back(c); color.push_back(c);
c = stringToColor("light_white"); c = stringToColor("bright_white");
color.push_back(c); color.push_back(c);
// Cambia el color del borde
screen->setBorderColor(stringToColor("black"));
} }
// Destructor // Destructor
@@ -102,22 +105,9 @@ void Logo::checkEventHandler()
} }
} }
// Actualiza las variables // Gestiona el logo de JAILGAME
void Logo::update() void Logo::updateJAILGAMES()
{ {
// Comprueba que la diferencia de ticks sea mayor a la velocidad del juego
if (SDL_GetTicks() - ticks > ticksSpeed)
{
// Actualiza el contador de ticks
ticks = SDL_GetTicks();
// Comprueba el manejador de eventos
checkEventHandler();
// Incrementa el contador
counter++;
// update de JAILGAMES
if (counter > 30) if (counter > 30)
{ {
for (int i = 1; i < sprite.size(); i++) for (int i = 1; i < sprite.size(); i++)
@@ -145,9 +135,11 @@ void Logo::update()
} }
} }
} }
}
// update de fade // Gestiona el color de las texturas
{ void Logo::updateTextureColors()
{
const int ini = 70; const int ini = 70;
const int inc = 4; const int inc = 4;
@@ -220,12 +212,33 @@ void Logo::update()
texture->setColor(color[0].r, color[0].g, color[0].b); texture->setColor(color[0].r, color[0].g, color[0].b);
texture2->setColor(color[0].r, color[0].g, color[0].b); texture2->setColor(color[0].r, color[0].g, color[0].b);
} }
} }
// Actualiza las variables
void Logo::update()
{
// Comprueba que la diferencia de ticks sea mayor a la velocidad del juego
if (SDL_GetTicks() - ticks > ticksSpeed)
{
// Actualiza el contador de ticks
ticks = SDL_GetTicks();
// Comprueba el manejador de eventos
checkEventHandler();
// Incrementa el contador
counter++;
// Gestiona el logo de JAILGAME
updateJAILGAMES();
// Gestiona el color de las texturas
updateTextureColors();
// Comprueba si ha terminado el logo // Comprueba si ha terminado el logo
if (counter == endLogo + postLogo) if (counter == endLogo + postLogo)
{ {
section.name = SECTION_PROG_TITLE; section.name = SECTION_PROG_INTRO;
section.subsection = 0; section.subsection = 0;
} }
} }

View File

@@ -42,6 +42,12 @@ private:
// Comprueba el manejador de eventos // Comprueba el manejador de eventos
void checkEventHandler(); void checkEventHandler();
// Gestiona el logo de JAILGAME
void updateJAILGAMES();
// Gestiona el color de las texturas
void updateTextureColors();
public: public:
// Constructor // Constructor
Logo(SDL_Renderer *renderer, Screen *screen, Asset *asset); Logo(SDL_Renderer *renderer, Screen *screen, Asset *asset);

View File

@@ -2,15 +2,15 @@
#include <fstream> #include <fstream>
#include <sstream> #include <sstream>
// CAUTION!!!!! si no se gasta al final, quitar la referencia a la habitación
// Constructor // Constructor
Player::Player(player_t ini, std::string tileset, std::string animation, SDL_Renderer *renderer, Asset *asset, Input *input, Room *room) Player::Player(player_t ini, std::string tileset, std::string animation, SDL_Renderer *renderer, Asset *asset, Input *input, Room *room, Debug *debug)
{ {
// Obten punteros a objetos // Obten punteros a objetos
this->asset = asset; this->asset = asset;
this->renderer = renderer; this->renderer = renderer;
this->input = input; this->input = input;
this->room = room;
this->debug = debug;
// Crea objetos // Crea objetos
texture = new LTexture(renderer, asset->get(tileset)); texture = new LTexture(renderer, asset->get(tileset));
@@ -20,21 +20,37 @@ Player::Player(player_t ini, std::string tileset, std::string animation, SDL_Ren
color = stringToColor("white"); color = stringToColor("white");
onBorder = false; onBorder = false;
border = BORDER_TOP; border = BORDER_TOP;
invincible = false;
jump_ini = ini.jump_ini; jump_ini = ini.jump_ini;
status = ini.status; state = ini.state;
prevState = state;
x = ini.x;
y = ini.y;
vx = ini.vx;
vy = ini.vy;
w = 8;
h = 16;
maxVY = 1.2f;
sprite->setPosX(ini.x); sprite->setPosX(ini.x);
sprite->setPosY(ini.y); sprite->setPosY(ini.y);
sprite->setVelX(ini.vx);
sprite->setVelY(ini.vy);
sprite->setWidth(8); sprite->setWidth(8);
sprite->setHeight(16); sprite->setHeight(16);
sprite->setFlip(ini.flip); sprite->setFlip(ini.flip);
sprite->setCurrentAnimation("walk");
sprite->animate();
lastPosition = getRect(); lastPosition = getRect();
collider = getRect(); colliderBox = getRect();
const SDL_Point p = {0, 0};
colliderPoints.insert(colliderPoints.end(), {p, p, p, p, p, p, p, p});
underFeet.insert(underFeet.end(), {p, p});
feet.insert(feet.end(), {p, p});
r = {0, 0, 0, 0};
} }
// Destructor // Destructor
@@ -49,43 +65,66 @@ 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();
if (debug->getEnabled())
{
// Pinta los underfeet
SDL_SetRenderDrawColor(renderer, 255, 0, 255, 255);
SDL_RenderDrawPoint(renderer, underFeet[0].x, underFeet[0].y);
SDL_RenderDrawPoint(renderer, underFeet[1].x, underFeet[1].y);
// Pinta rectangulo del jugador
SDL_SetRenderDrawColor(renderer, 0, 255, 0, 192);
SDL_Rect rect = getRect();
SDL_RenderFillRect(renderer, &rect);
// Pinta el rectangulo de movimiento
SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
SDL_RenderFillRect(renderer, &r);
debug->add("RECT: " + std::to_string(r.x) +","+ std::to_string(r.y) +","+ std::to_string(r.w) +","+ std::to_string(r.h));
}
} }
// Actualiza las variables del objeto // Actualiza las variables del objeto
void Player::update() void Player::update()
{ {
setLastPosition(); // Guarda la posición actual en la variable lastPosition
checkInput(); // Comprueba las entradas y modifica variables checkInput(); // Comprueba las entradas y modifica variables
move(); // Recalcula la posición del jugador y su animación move(); // Recalcula la posición del jugador
animate(); // Establece la animación del jugador
checkBorders(); // Comprueba si está situado en alguno de los cuatro bordes de la habitación checkBorders(); // Comprueba si está situado en alguno de los cuatro bordes de la habitación
applyGravity(); // Aplica gravedad al jugador checkJumpEnd(); // Comprueba si ha finalizado el salto al alcanzar la altura de inicio
checkJump(); // Comprueba si ha finalizado el salto
collider = getRect(); // Obtiene el rectangulo que delimita al jugador
} }
// Comprueba las entradas y modifica variables // Comprueba las entradas y modifica variables
void Player::checkInput() void Player::checkInput()
{ {
// Solo comprueba las entradas de dirección cuando está de pie // Solo comprueba las entradas de dirección cuando está dsobre una superficie
if ((input->checkInput(INPUT_LEFT, REPEAT_TRUE)) && (status == STATUS_STANDING)) if (state != s_standing)
{ {
sprite->setVelX(-0.6f); return;
}
if (input->checkInput(INPUT_LEFT, REPEAT_TRUE))
{
vx = -0.6f;
sprite->setFlip(SDL_FLIP_HORIZONTAL); sprite->setFlip(SDL_FLIP_HORIZONTAL);
} }
else if ((input->checkInput(INPUT_RIGHT, REPEAT_TRUE)) && (status == STATUS_STANDING))
else if (input->checkInput(INPUT_RIGHT, REPEAT_TRUE))
{ {
sprite->setVelX(0.6f); vx = 0.6f;
sprite->setFlip(SDL_FLIP_NONE); sprite->setFlip(SDL_FLIP_NONE);
} }
else if (status == STATUS_STANDING)
else
{ {
sprite->setVelX(0); vx = 0.0f;
} }
if (input->checkInput(INPUT_UP, REPEAT_TRUE)) if (input->checkInput(INPUT_UP, REPEAT_TRUE))
{ {
setStatus(STATUS_JUMPING); setState(s_jumping);
vy = -maxVY;
jump_ini = y;
} }
} }
@@ -104,22 +143,22 @@ int Player::getBorder()
// Comprueba si está situado en alguno de los cuatro bordes de la habitación // Comprueba si está situado en alguno de los cuatro bordes de la habitación
void Player::checkBorders() void Player::checkBorders()
{ {
if (sprite->getPosX() < PLAY_AREA_LEFT) if (x < PLAY_AREA_LEFT)
{ {
border = BORDER_LEFT; border = BORDER_LEFT;
onBorder = true; onBorder = true;
} }
else if (sprite->getPosX() > PLAY_AREA_RIGHT - sprite->getWidth()) else if (x > PLAY_AREA_RIGHT - w)
{ {
border = BORDER_RIGHT; border = BORDER_RIGHT;
onBorder = true; onBorder = true;
} }
else if (sprite->getPosY() < PLAY_AREA_TOP) else if (y < PLAY_AREA_TOP)
{ {
border = BORDER_TOP; border = BORDER_TOP;
onBorder = true; onBorder = true;
} }
else if (sprite->getPosY() > PLAY_AREA_BOTTOM - sprite->getHeight()) else if (y > PLAY_AREA_BOTTOM - h)
{ {
border = BORDER_BOTTOM; border = BORDER_BOTTOM;
onBorder = true; onBorder = true;
@@ -130,92 +169,59 @@ void Player::checkBorders()
} }
} }
// Comprueba el estado del jugador
void Player::checkState()
{
// Actualiza las variables en función del estado
if (state == s_falling)
{
vx = 0.0f;
vy = maxVY;
}
else if (state == s_standing)
{
vy = 0.0f;
}
}
// Cambia al jugador de un borde al opuesto. Util para el cambio de pantalla // Cambia al jugador de un borde al opuesto. Util para el cambio de pantalla
void Player::switchBorders() void Player::switchBorders()
{ {
if (border == BORDER_TOP) if (border == BORDER_TOP)
{ {
sprite->setPosY(PLAY_AREA_BOTTOM - sprite->getHeight() - 1); y = PLAY_AREA_BOTTOM - h - 1;
jump_ini += 128; jump_ini += 128;
} }
else if (border == BORDER_BOTTOM) else if (border == BORDER_BOTTOM)
{ {
sprite->setPosY(PLAY_AREA_TOP + 1); y = PLAY_AREA_TOP + 1;
} }
else if (border == BORDER_RIGHT) else if (border == BORDER_RIGHT)
{ {
sprite->setPosX(PLAY_AREA_LEFT + 1); x = PLAY_AREA_LEFT + 1;
} }
if (border == BORDER_LEFT) if (border == BORDER_LEFT)
{ {
sprite->setPosX(PLAY_AREA_RIGHT - sprite->getWidth() - 1); x = PLAY_AREA_RIGHT - w - 1;
} }
onBorder = false; onBorder = false;
} }
// Obtiene el valor del pixel inferior izquierdo del jugador
SDL_Point Player::getLeftFoot()
{
SDL_Point point = {(int)sprite->getPosX(), (int)sprite->getPosY() + sprite->getHeight()};
return point;
}
// Obtiene el valor del pixel inferior derecho del jugador
SDL_Point Player::getRightFoot()
{
SDL_Point point = {(int)sprite->getPosX() + sprite->getWidth() - 1, (int)sprite->getPosY() + sprite->getHeight()};
return point;
}
// Cambia el estado del jugador
void Player::setStatus(int value)
{
// Si quiere cambiar a saltando, ha de ser desde quieto
if ((value == STATUS_JUMPING) && (status == STATUS_STANDING))
{
status = STATUS_JUMPING;
sprite->setVelY(-MAX_VY);
jump_ini = sprite->getPosY();
}
// Modifica el estado a 'cayendo'
if (value == STATUS_FALLING)
{
status = STATUS_FALLING;
sprite->setVelY(MAX_VY);
sprite->setVelX(0);
}
// Modifica el estado a 'de pie'
if (value == STATUS_STANDING)
{
status = STATUS_STANDING;
sprite->setVelY(0.0f);
}
}
// Obtiene el estado del jugador
int Player::getStatus()
{
return status;
}
// Obtiene la velocidad en el eje Y del jugador
float Player::getVelY()
{
return sprite->getVelY();
}
// Aplica gravedad al jugador // Aplica gravedad al jugador
void Player::applyGravity() void Player::applyGravity()
{ {
if (status == STATUS_JUMPING) const float gf = 0.035f;
// La gravedad solo se aplica cuando el jugador esta saltando
// Nunca mientras cae o esta de pie
if (state == s_jumping)
{ {
sprite->setVelY(sprite->getVelY() + GRAVITY); vy += gf;
if (sprite->getVelY() > MAX_VY) if (vy > maxVY)
{ {
sprite->setVelY(MAX_VY); vy = maxVY;
} }
} }
} }
@@ -223,64 +229,482 @@ void Player::applyGravity()
// Obtiene el rectangulo que delimita al jugador // Obtiene el rectangulo que delimita al jugador
SDL_Rect Player::getRect() SDL_Rect Player::getRect()
{ {
return sprite->getRect(); return {(int)x, (int)y, w, h};
} }
// Obtiene el rectangulo de colision del jugador // Obtiene el rectangulo de colision del jugador
SDL_Rect &Player::getCollider() SDL_Rect &Player::getCollider()
{ {
return collider; colliderBox = getRect();
} return colliderBox;
// Guarda la posición actual en la variable lastPosition
void Player::setLastPosition()
{
lastPosition = getRect();
}
// Deshace el ultimo movimiento
void Player::undoLastMove()
{
sprite->setPosX(lastPosition.x);
sprite->setPosY(lastPosition.y);
} }
// Recalcula la posición del jugador y su animación // Recalcula la posición del jugador y su animación
void Player::move() void Player::move()
{ {
sprite->update(); lastPosition = {(int)x, (int)y}; // Guarda la posicion actual antes de modificarla
if (sprite->getVelX() != 0) applyGravity(); // Aplica gravedad al jugador
checkState(); // Comprueba el estado del jugador
// Se mueve hacia la izquierda
if (vx < 0.0f)
{ {
sprite->setCurrentAnimation("walk"); // Crea el rectangulo de proyección en el eje X para ver si colisiona
SDL_Rect proj;
proj.x = (int)(x + vx);
proj.y = (int)y;
proj.h = h;
proj.w = ceil(abs(vx)); // Para evitar que tenga un ancho de 0 pixels
r = proj;
// Comprueba la colisión con las superficies
const int pos = room->checkRightSurfaces(&proj);
// Calcula la nueva posición
if (pos == -1)
{ // Si no hay colisión
x += vx;
}
else
{ // Si hay colisión lo mueve hasta donde no colisiona
x = pos + 1;
}
// Si ha tocado alguna rampa mientras camina (sin saltar), asciende
if (state != s_jumping)
{
v_line_t leftSide = {(int)x, (int)y + h - 2, (int)y + h - 1};
const int ly = room->checkLeftSlopes(&leftSide);
if (ly > -1)
{
y = ly - h;
// setState(s_standing);
}
}
// Si está bajando la rampa, recoloca al jugador
if (isOnDownSlope())
{
y += 1;
}
}
// Se mueve hacia la derecha
else if (vx > 0.0f)
{
// Crea el rectangulo de proyección en el eje X para ver si colisiona
SDL_Rect proj;
proj.x = (int)x + w;
proj.y = (int)y;
proj.h = h;
proj.w = ceil(vx); // Para evitar que tenga un ancho de 0 pixels
r = proj;
// Comprueba la colisión
const int pos = room->checkLeftSurfaces(&proj);
// Calcula la nueva posición
if (pos == -1)
{ // Si no hay colisión
x += vx;
}
else
{ // Si hay colisión lo mueve hasta donde no colisiona
x = pos - w;
}
// Si ha tocado alguna rampa mientras camina (sin saltar), asciende
if (state != s_jumping)
{
v_line_t rightSide = {(int)x + w - 1, (int)y + h - 2, (int)y + h - 1};
const int ry = room->checkRightSlopes(&rightSide);
if (ry > -1)
{
y = ry - h;
// setState(s_standing);
}
}
// Si está bajando la rampa, recoloca al jugador
if (isOnDownSlope())
{
y += 1;
}
}
// Si ha salido del suelo, el jugador cae
if (state == s_standing && !isOnFloor())
{
setState(s_falling);
}
// Se mueve hacia arriba
if (vy < 0.0f)
{
// Crea el rectangulo de proyección en el eje Y para ver si colisiona
SDL_Rect proj;
proj.x = (int)x;
proj.y = (int)(y + vy);
proj.h = ceil(abs(vy)); // Para evitar que tenga una altura de 0 pixels
proj.w = w;
r = proj;
// Comprueba la colisión
const int pos = room->checkBottomSurfaces(&proj);
// Calcula la nueva posición
if (pos == -1)
{ // Si no hay colisión
y += vy;
}
else
{ // Si hay colisión lo mueve hasta donde no colisiona y entra en caída
y = pos + 1;
setState(s_falling);
}
}
// Se mueve hacia abajo
else if (vy > 0.0f)
{
// Crea el rectangulo de proyección en el eje Y para ver si colisiona
SDL_Rect proj;
proj.x = (int)x;
proj.y = (int)y + h;
proj.h = ceil(vy); // Para evitar que tenga una altura de 0 pixels
proj.w = w;
r = proj;
// Comprueba la colisión con los muros
const int pos = room->checkTopSurfaces(&proj);
// Calcula la nueva posición
if (pos == -1)
{ // Si no hay colisión
y += vy;
}
else
{ // Si hay colisión lo mueve hasta donde no colisiona y pasa a estar sobre el suelo
y = pos - h;
setState(s_standing);
}
}
//--------------------------------------------------------------
// Calcula la nueva posición del jugador y compensa en caso de colisión
/*x += vx;
// Comprueba colisiones con muros
if (checkWalls())
{
// Recoloca
if (vx > 0.0f)
{
x = (int)x - ((int)x + w) % tileSize;
} }
else else
{ {
sprite->setCurrentAnimation("stand"); x = (int)x + tileSize - ((int)x % tileSize);
}
}
// Comprueba colisiones con rampas solo si esta quieto o cayendo
else if (vy >= 0.0f)
{
tile_e slope = checkSlopes();
tile_e slope2 = checkSlopes2();
debug->add("SLOPE = " + std::to_string(slope));
debug->add("SLOPE2 = " + std::to_string(slope2));
if (slope != t_empty)
{ // Cuesta hacia la derecha
if (slope == t_slope_r)
{ // Recoloca
y = -h + room->getSlopeHeight(feet[1], t_slope_r);
debug->add("feet[1] = " + std::to_string(feet[1].y));
}
// Cuesta hacia la izquierda
if (slope == t_slope_l)
{ // Recoloca
y = -h + room->getSlopeHeight(feet[0], t_slope_l);
debug->add("feet[0] = " + std::to_string(feet[0].y));
}
}
else if (slope2 != t_empty)
{ // Cuesta hacia la derecha
if (slope2 == t_slope_r)
{ // Recoloca
y = -h + room->getSlopeHeight(underFeet[1], t_slope_r);
debug->add("ufeet[1] = " + std::to_string(underFeet[1].y));
}
// Cuesta hacia la izquierda
if (slope2 == t_slope_l)
{ // Recoloca
y = -h + room->getSlopeHeight(underFeet[0], t_slope_l);
debug->add("ufeet[0] = " + std::to_string(underFeet[0].y));
}
}
}
y += vy;
if (checkWalls())
{
// Recoloca
if (vy > 0.0f)
{ // Bajando
y -= ((int)y + h) % tileSize;
setState(s_standing);
vy = 0.0f;
}
else
{ // Subiendo
y += tileSize - ((int)y % tileSize);
setState(s_falling);
vy = maxVY;
}
}
else
// Si no colisiona con los muros, haz comprobaciones extra
{
const int a = (lastPosition.y + h - 1) / tileSize;
const int b = ((int)y + h - 1) / tileSize;
const bool tile_change = a != b;
bool going_down = vy >= 0.0f;
bool tile_aligned = ((int)y + h) % tileSize == 0;
// Si está cayendo y hay cambio de tile o está justo sobre uno
if (going_down && (tile_aligned || tile_change))
{
// Comprueba si tiene uno de los pies sobre una superficie
if (isOnFloor())
{ // Y deja al jugador de pie
setState(s_standing);
vy = 0.0f;
// Si ademas ha habido un cambio de tile recoloca al jugador
if (tile_change && !checkSlopes2())
{
y = ((int)y - ((int)y % tileSize));
}
}
// Si tiene ambos pies sobre el vacío y no está saltando
else if (state != s_jumping)
{
setState(s_falling);
vy = maxVY;
}
}
going_down = vy >= 0.0f;
tile_aligned = ((int)y + h) % tileSize == 0;
// Si simplemente está cayendo (sin mirar si hay cambio de tile o si está justo sobre uno)
if (going_down)
{
if (state != s_jumping)
{
setState(s_falling);
vy = maxVY;
}
// Si está alineado con el tile mira el suelo (para que no lo mire si está
// dentro de un tile atravesable y lo deje a medias)
if (tile_aligned)
{
if (isOnFloor())
{
setState(s_standing);
vy = 0.0f;
}
}
// EXPERIMENTAL
else if (checkSlopes())
{
setState(s_standing);
vy = 0.0f;
}
}
}*/
// Actualiza la posición del sprite
sprite->setPosX(x);
sprite->setPosY(y);
}
// Establece la animación del jugador
void Player::animate()
{
if (vx != 0)
{
sprite->animate();
} }
} }
// Comprueba si ha finalizado el salto // Comprueba si ha finalizado el salto al alcanzar la altura de inicio
void Player::checkJump() void Player::checkJumpEnd()
{ {
if (status == STATUS_JUMPING) if (state == s_jumping)
if (sprite->getVelY() > 0) if (vy > 0)
if (sprite->getPosY() > jump_ini) if (y >= jump_ini)
{ { // Si alcanza la altura de salto inicial, pasa al estado de caída
setStatus(STATUS_FALLING); setState(s_falling);
vy = maxVY;
} }
} }
// Comprueba si el jugador tiene suelo debajo de los pies
bool Player::isOnFloor()
{
bool onFloor = false;
updateFeet();
// Comprueba las superficies
for (auto f : underFeet)
{
onFloor |= room->checkTopSurfaces(&f);
}
// Comprueba las rampas
onFloor |= room->checkLeftSlopes(&underFeet[0]);
onFloor |= room->checkRightSlopes(&underFeet[1]);
if (onFloor)
{
debug->add("ONFLOOR");
}
return onFloor;
}
// Comprueba si el jugador está sobre una rampa hacia abajo
bool Player::isOnDownSlope()
{
bool onSlope = false;
updateFeet();
// Cuando el jugador baja una escalera, se queda volando
// Hay que mirar otro pixel más por debajo
underFeet[0].y += 1;
underFeet[1].y += 1;
// Comprueba las rampas
onSlope |= room->checkLeftSlopes(&underFeet[0]);
onSlope |= room->checkRightSlopes(&underFeet[1]);
if (onSlope)
{
debug->add("ONSLOPE");
}
return onSlope;
}
// Comprueba que el jugador no atraviese ninguna pared
bool Player::checkWalls()
{
// Actualiza los puntos de colisión
updateColliderPoints();
// Comprueba si ha colisionado con un muro
bool wall = false;
for (auto c : colliderPoints)
{
wall |= (room->getTile(c) == t_wall);
}
return wall;
}
// Comprueba si el jugador está en una rampa
tile_e Player::checkSlopes()
{
// Actualiza los puntos de colisión
updateFeet();
bool slope_l = false;
bool slope_r = false;
// Comprueba si ha colisionado con una rampa
for (auto f : feet)
{
slope_l |= (room->getTile(f) == t_slope_l);
slope_r |= (room->getTile(f) == t_slope_r);
}
if (slope_l)
{
return t_slope_l;
}
if (slope_r)
{
return t_slope_r;
}
return t_empty;
}
// Comprueba si el jugador está en una rampa
tile_e Player::checkSlopes2()
{
// Actualiza los puntos de colisión
updateFeet();
bool slope_l = false;
bool slope_r = false;
bool wall = false;
bool passable = false;
// Comprueba si ha colisionado con una rampa
for (auto f : underFeet)
{
slope_l |= (room->getTile(f) == t_slope_l);
slope_r |= (room->getTile(f) == t_slope_r);
wall |= (room->getTile(f) == t_wall);
passable |= (room->getTile(f) == t_passable);
}
if (wall || passable)
{
return t_empty;
}
if (slope_l)
{
return t_slope_l;
}
if (slope_r)
{
return t_slope_r;
}
return t_empty;
}
// Obtiene algunos parametros del jugador // Obtiene algunos parametros del jugador
player_t Player::getSpawnParams() player_t Player::getSpawnParams()
{ {
player_t params; player_t params;
params.x = sprite->getPosX(); params.x = x;
params.y = sprite->getPosY(); params.y = y;
params.vx = sprite->getVelX(); params.vx = vx;
params.vy = sprite->getVelY(); params.vy = vy;
params.jump_ini = jump_ini; params.jump_ini = jump_ini;
params.status = status; params.state = state;
params.flip = sprite->getFlip(); params.flip = sprite->getFlip();
return params; return params;
@@ -291,3 +715,54 @@ void Player::reLoadTexture()
{ {
texture->reLoad(); texture->reLoad();
} }
// Establece el valor de la variable
void Player::setRoom(Room *room)
{
this->room = room;
}
// Actualiza los puntos de colisión
void Player::updateColliderPoints()
{
const SDL_Rect rect = getRect();
colliderPoints[0] = {rect.x, rect.y};
colliderPoints[1] = {rect.x + 7, rect.y};
colliderPoints[2] = {rect.x + 7, rect.y + 7};
colliderPoints[3] = {rect.x, rect.y + 7};
colliderPoints[4] = {rect.x, rect.y + 8};
colliderPoints[5] = {rect.x + 7, rect.y + 8};
colliderPoints[6] = {rect.x + 7, rect.y + 15};
colliderPoints[7] = {rect.x, rect.y + 15};
}
// Actualiza los puntos de los pies
void Player::updateFeet()
{
const SDL_Point p = {(int)x, (int)y};
underFeet[0] = {p.x, p.y + h};
underFeet[1] = {p.x + 7, p.y + h};
feet[0] = {p.x, p.y + h - 1};
feet[1] = {p.x + 7, p.y + h - 1};
}
// Obtiene el valor de la variable
bool Player::getInvincible()
{
return invincible;
}
// Establece el valor de la variable
void Player::setInvincible(bool value)
{
invincible = value;
}
// Cambia el estado del jugador
void Player::setState(state_e value)
{
prevState = state;
state = value;
}

View File

@@ -7,18 +7,19 @@
#include "animatedsprite.h" #include "animatedsprite.h"
#include "input.h" #include "input.h"
#include "const.h" #include "const.h"
#include "debug.h"
#include <string> #include <string>
#include <vector>
#ifndef PLAYER_H #ifndef PLAYER_H
#define PLAYER_H #define PLAYER_H
//#define VX 0.6 enum state_e
#define STATUS_STANDING 0 {
#define STATUS_JUMPING 1 s_standing,
#define STATUS_FALLING 2 s_jumping,
s_falling
#define GRAVITY 0.035f };
#define MAX_VY 1.2f
struct player_t struct player_t
{ {
@@ -27,24 +28,41 @@ struct player_t
float vx; float vx;
float vy; float vy;
int jump_ini; int jump_ini;
int status; state_e state;
SDL_RendererFlip flip; SDL_RendererFlip flip;
}; };
// Clase Player // Clase Player
class Player class Player
{ {
private: public:
LTexture *texture; // Textura con los graficos del enemigo float x; // Posición del jugador en el eje X
Input *input; // Objeto para gestionar la entrada float y; // Posición del jugador en el eje Y
float vx; // Velocidad/desplazamiento del jugador en el eje X
float vy; // Velocidad/desplazamiento del jugador en el eje Y
int w; // Ancho del jugador
int h; // ALto del jugador
SDL_Renderer *renderer; // El renderizador de la ventana SDL_Renderer *renderer; // El renderizador de la ventana
Input *input; // Objeto para gestionar la entrada
Asset *asset; // Objeto con la ruta a todos los ficheros de recursos Asset *asset; // Objeto con la ruta a todos los ficheros de recursos
Room *room; // Objeto encargado de gestionar cada habitación del juego
LTexture *texture; // Textura con los graficos del enemigo
AnimatedSprite *sprite; // Sprite del enemigo
Debug *debug; // Objeto para gestionar la información de debug
color_t color; // Color del jugador color_t color; // Color del jugador
SDL_Rect collider; // Caja de colisión SDL_Rect colliderBox; // Caja de colisión con los enemigos u objetos
std::vector<SDL_Point> colliderPoints; // Puntos de colisión con el mapa
std::vector<SDL_Point> underFeet; // Contiene los puntos que hay bajo cada pie del jugador
std::vector<SDL_Point> feet; // Contiene los puntos que hay en el pie del jugador
state_e state; // Estado en el que se encuentra el jugador. Util apara saber si está saltando o cayendo
state_e prevState; // Estado previo en el que se encontraba el jugador
bool onBorder; // Indica si el jugador esta en uno de los cuatro bordes de la pantalla bool onBorder; // Indica si el jugador esta en uno de los cuatro bordes de la pantalla
int border; // Indica en cual de los cuatro bordes se encuentra int border; // Indica en cual de los cuatro bordes se encuentra
bool invincible; // Si es invencible, no puede morir
SDL_Rect lastPosition; // Contiene la ultima posición del jugador, por si hay que deshacer algun movimiento
int jump_ini; // Valor del eje Y en el que se inicia el salto
float maxVY; // Velocidad máxima que puede alcanzar al desplazarse en vertical
SDL_Rect r;
// Comprueba las entradas y modifica variables // Comprueba las entradas y modifica variables
void checkInput(); void checkInput();
@@ -52,29 +70,51 @@ private:
// Comprueba si se halla en alguno de los cuatro bordes // Comprueba si se halla en alguno de los cuatro bordes
void checkBorders(); void checkBorders();
// Comprueba el estado del jugador
void checkState();
// Asigna velocidad negativa en el eje Y al jugador // Asigna velocidad negativa en el eje Y al jugador
void jump(); void jump();
// Aplica gravedad al jugador // Aplica gravedad al jugador
void applyGravity(); void applyGravity();
// Guarda la posición actual en la variable lastPosition
void setLastPosition();
// Recalcula la posición del jugador y su animación // Recalcula la posición del jugador y su animación
void move(); void move();
// Comprueba si ha finalizado el salto // Establece la animación del jugador
void checkJump(); void animate();
// Comprueba si ha finalizado el salto al alcanzar la altura de inicio
void checkJumpEnd();
// Comprueba si el jugador tiene suelo debajo de los pies
bool isOnFloor();
// Comprueba si el jugador está sobre una rampa hacia abajo
bool isOnDownSlope();
// Comprueba que el jugador no atraviese ninguna pared
bool checkWalls();
// Comprueba si el jugador está en una rampa
tile_e checkSlopes();
// Comprueba si el jugador está en una rampa
tile_e checkSlopes2();
// Actualiza los puntos de colisión
void updateColliderPoints();
// Actualiza los puntos de los pies
void updateFeet();
// Cambia el estado del jugador
void setState(state_e value);
public: public:
AnimatedSprite *sprite; // Sprite del enemigo
SDL_Rect lastPosition; // Contiene la ultima posición del jugador, por si hay que deshacer algun movimiento
int jump_ini; // Valor del eje Y en el que se inicia el salto
int status; // Estado en el que se encuentra el jugador. Util apara saber si está saltando o cayendo
// Constructor // Constructor
Player(player_t ini, std::string tileset, std::string animation, SDL_Renderer *renderer, Asset *asset, Input *input, Room *room); Player(player_t ini, std::string tileset, std::string animation, SDL_Renderer *renderer, Asset *asset, Input *input, Room *room, Debug *debug);
// Destructor // Destructor
~Player(); ~Player();
@@ -94,35 +134,26 @@ public:
// Cambia al jugador de un borde al opuesto. Util para el cambio de pantalla // Cambia al jugador de un borde al opuesto. Util para el cambio de pantalla
void switchBorders(); void switchBorders();
// Obtiene el valor del pixel inferior izquierdo del jugador
SDL_Point getLeftFoot();
// Obtiene el valor del pixel inferior derecho del jugador
SDL_Point getRightFoot();
// Cambia el estado del jugador
void setStatus(int value);
// Obtiene el estado del jugador
int getStatus();
// Obtiene la velocidad en el eje Y del jugador
float getVelY();
// Obtiene el rectangulo que delimita al jugador // Obtiene el rectangulo que delimita al jugador
SDL_Rect getRect(); SDL_Rect getRect();
// Obtiene el rectangulo de colision del jugador // Obtiene el rectangulo de colision del jugador
SDL_Rect &getCollider(); SDL_Rect &getCollider();
// Deshace el ultimo movimiento
void undoLastMove();
// Obtiene algunos parametros del jugador // Obtiene algunos parametros del jugador
player_t getSpawnParams(); player_t getSpawnParams();
// Recarga la textura // Recarga la textura
void reLoadTexture(); void reLoadTexture();
// Establece el valor de la variable
void setRoom(Room *room);
// Obtiene el valor de la variable
bool getInvincible();
// Establece el valor de la variable
void setInvincible(bool value);
}; };
#endif #endif

View File

@@ -4,19 +4,35 @@
#include <sstream> #include <sstream>
// Constructor // Constructor
Room::Room(std::string file_path, SDL_Renderer *renderer, Asset *asset, ItemTracker *itemTracker, int *items) Room::Room(std::string file_path, SDL_Renderer *renderer, Screen *screen, Asset *asset, ItemTracker *itemTracker, int *items, Debug *debug)
{ {
// Inicializa variables
tileSize = 8;
mapWidth = 32;
mapHeight = 16;
tilesetWidth = 20;
// Copia los punteros a objetos // Copia los punteros a objetos
this->asset = asset;
this->renderer = renderer; this->renderer = renderer;
this->asset = asset;
this->screen = screen;
this->itemTracker = itemTracker; this->itemTracker = itemTracker;
this->itemsPicked = items; this->itemsPicked = items;
this->debug = debug;
// Crea los objetos // Crea los objetos
load(file_path); load(file_path);
texture = new LTexture(renderer, asset->get(tileset)); texture = new LTexture(renderer, asset->get(tileset));
itemSound = JA_LoadSound(asset->get("item.wav").c_str()); itemSound = JA_LoadSound(asset->get("item.wav").c_str());
// Calcula las superficies
setBottomSurfaces();
setTopSurfaces();
setLeftSurfaces();
setRightSurfaces();
setLeftSlopes();
setRightSlopes();
// Crea la textura para el mapa de tiles de la habitación // Crea la textura para el mapa de tiles de la habitación
mapTexture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT); mapTexture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT);
if (mapTexture == NULL) if (mapTexture == NULL)
@@ -24,6 +40,9 @@ Room::Room(std::string file_path, SDL_Renderer *renderer, Asset *asset, ItemTrac
// Pinta el mapa de la habitación en la textura // Pinta el mapa de la habitación en la textura
fillMapTexture(); fillMapTexture();
// Establece el color del borde
screen->setBorderColor(borderColor);
} }
// Destructor // Destructor
@@ -90,13 +109,11 @@ bool Room::load(std::string _file_path)
// Si la linea contiene el texto [tilemap] se realiza el proceso de carga del fichero tmx // Si la linea contiene el texto [tilemap] se realiza el proceso de carga del fichero tmx
else if (line == "[tilemap]") else if (line == "[tilemap]")
{ {
// printf("Loading tilemap...\n");
do do
{ {
std::getline(file, line); std::getline(file, line);
if (line.find(".tmx") != std::string::npos) if (line.find(".tmx") != std::string::npos)
{ {
// printf("Reading file %s\n", asset->get(line).c_str());
std::ifstream file2(asset->get(line)); // Abre el fichero tmx std::ifstream file2(asset->get(line)); // Abre el fichero tmx
if (file2.good()) if (file2.good())
{ {
@@ -109,11 +126,7 @@ bool Room::load(std::string _file_path)
do do
{ {
std::getline(file2, line); std::getline(file2, line);
// printf("parsing: %s\n", line.c_str());
pos = line.find("data encoding"); pos = line.find("data encoding");
// printf("pos: %i\n", pos);
} while (pos == std::string::npos); } while (pos == std::string::npos);
do do
@@ -122,12 +135,10 @@ bool Room::load(std::string _file_path)
std::getline(file2, line); std::getline(file2, line);
if (line != "</data>") if (line != "</data>")
{ {
// printf("data: %s\n", line.c_str());
std::stringstream ss(line); std::stringstream ss(line);
std::string tmp; std::string tmp;
while (getline(ss, tmp, ',')) while (getline(ss, tmp, ','))
{ {
// printf("tile: %s\n", tmp.c_str());
tilemap.push_back(std::stoi(tmp)); tilemap.push_back(std::stoi(tmp));
} }
} }
@@ -213,6 +224,11 @@ bool Room::setVars(std::string var, std::string value)
bgColor = stringToColor(value); bgColor = stringToColor(value);
} }
else if (var == "border")
{
borderColor = stringToColor(value);
}
else if (var == "tileset") else if (var == "tileset")
{ {
tileset = value; tileset = value;
@@ -416,7 +432,82 @@ void Room::fillMapTexture()
clip.x = ((tilemap[(y * 32) + x] - 1) % 20) * 8; clip.x = ((tilemap[(y * 32) + x] - 1) % 20) * 8;
clip.y = ((tilemap[(y * 32) + x] - 1) / 20) * 8; clip.y = ((tilemap[(y * 32) + x] - 1) / 20) * 8;
texture->render(renderer, x * 8, y * 8, &clip); texture->render(renderer, x * 8, y * 8, &clip);
if (debug->getEnabled())
{
if (clip.x != -8)
{
clip.x = x * 8;
clip.y = y * 8;
SDL_SetRenderDrawColor(renderer, 64, 64, 64, 224);
SDL_RenderFillRect(renderer, &clip);
} }
}
}
// ****
if (debug->getEnabled())
{
// BottomSurfaces
if (true)
{
for (auto l : bottomSurfaces)
{
SDL_SetRenderDrawColor(renderer, (rand() % 128) + 96, (rand() % 128) + 96, (rand() % 128) + 96, 0xFF);
SDL_RenderDrawLine(renderer, l.x1, l.y, l.x2, l.y);
}
}
// TopSurfaces
if (true)
{
for (auto l : topSurfaces)
{
SDL_SetRenderDrawColor(renderer, (rand() % 128) + 96, (rand() % 128) + 96, (rand() % 128) + 96, 0xFF);
SDL_RenderDrawLine(renderer, l.x1, l.y, l.x2, l.y);
}
}
// LeftSurfaces
if (true)
{
for (auto l : leftSurfaces)
{
SDL_SetRenderDrawColor(renderer, (rand() % 128) + 96, (rand() % 128) + 96, (rand() % 128) + 96, 0xFF);
SDL_RenderDrawLine(renderer, l.x, l.y1, l.x, l.y2);
}
}
// RightSurfaces
if (true)
{
for (auto l : rightSurfaces)
{
SDL_SetRenderDrawColor(renderer, (rand() % 128) + 96, (rand() % 128) + 96, (rand() % 128) + 96, 0xFF);
SDL_RenderDrawLine(renderer, l.x, l.y1, l.x, l.y2);
}
}
// LeftSlopes
if (true)
{
for (auto l : leftSlopes)
{
SDL_SetRenderDrawColor(renderer, (rand() % 128) + 96, (rand() % 128) + 96, (rand() % 128) + 96, 0xFF);
SDL_RenderDrawLine(renderer, l.x1, l.y1, l.x2, l.y2);
}
}
// RightSlopes
if (true)
{
for (auto l : rightSlopes)
{
SDL_SetRenderDrawColor(renderer, (rand() % 128) + 96, (rand() % 128) + 96, (rand() % 128) + 96, 0xFF);
SDL_RenderDrawLine(renderer, l.x1, l.y1, l.x2, l.y2);
}
}
}
// ****
SDL_SetRenderTarget(renderer, nullptr); SDL_SetRenderTarget(renderer, nullptr);
} }
@@ -490,29 +581,72 @@ std::string Room::getRoom(int border)
} }
// Devuelve el tipo de tile que hay en ese pixel // Devuelve el tipo de tile que hay en ese pixel
int Room::getTile(SDL_Point point) tile_e Room::getTile(SDL_Point point)
{ {
int pos = ((point.y / 8) * 32) + (point.x / 8); const int maxTile = mapWidth * mapHeight;
int tile = TILE_EMPTY; const int pos = ((point.y / tileSize) * mapWidth) + (point.x / tileSize);
tile_e tile = t_empty;
if (pos < 512) if (pos < maxTile)
{ {
// Los tiles entre el 1 y el 80 son solidos // Las filas 0-7 son de tiles t_wall
if ((tilemap[pos] > 0) && (tilemap[pos] < 201)) if ((tilemap[pos] > 0) && (tilemap[pos] < 8 * tilesetWidth))
{ {
return TILE_SOLID; return t_wall;
} }
// Los tiles mayores de 80 son atravesables // La fila 8 es de tiles t_slope_r
if ((tilemap[pos] > 200) && (tilemap[pos] < 381)) else if ((tilemap[pos] >= 8 * tilesetWidth) && (tilemap[pos] < 9 * tilesetWidth))
{ {
return TILE_TRAVESSABLE; return t_slope_r;
} }
// Los tiles mayores de 80 son atravesables // La fila 9 es de tiles t_slope_l
if ((tilemap[pos] > 380) && (tilemap[pos] < 400)) else if ((tilemap[pos] >= 9 * tilesetWidth) && (tilemap[pos] < 10 * tilesetWidth))
{ {
return TILE_KILL; return t_slope_l;
}
// Las filas 10-14 son de tiles t_passable
if ((tilemap[pos] >= 10 * tilesetWidth) && (tilemap[pos] < 15 * tilesetWidth))
{
return t_passable;
}
}
return tile;
}
// Devuelve el tipo de tile que hay en ese indice
tile_e Room::getTile(int index)
{
const int maxTile = mapWidth * mapHeight;
tile_e tile = t_empty;
if (index < maxTile)
{
// Las filas 0-7 son de tiles t_wall
if ((tilemap[index] > 0) && (tilemap[index] < 8 * tilesetWidth))
{
return t_wall;
}
// La fila 8 es de tiles t_slope_r
else if ((tilemap[index] >= 8 * tilesetWidth) && (tilemap[index] < 9 * tilesetWidth))
{
return t_slope_r;
}
// La fila 9 es de tiles t_slope_l
else if ((tilemap[index] >= 9 * tilesetWidth) && (tilemap[index] < 10 * tilesetWidth))
{
return t_slope_l;
}
// Las filas 10-14 son de tiles t_passable
if ((tilemap[index] >= 10 * tilesetWidth) && (tilemap[index] < 15 * tilesetWidth))
{
return t_passable;
} }
} }
@@ -567,3 +701,399 @@ void Room::reLoadTexture()
item->reLoadTexture(); item->reLoadTexture();
} }
} }
// Obten el tamaño del tile
int Room::getTileSize()
{
return 8;
}
// Obten la coordenada de la cuesta a partir de un punto perteneciente a ese tile
int Room::getSlopeHeight(SDL_Point p, tile_e slope)
{
// Calcula la base del tile
int base = ((p.y / tileSize) * tileSize) + tileSize;
debug->add("BASE = " + std::to_string(base));
// Calcula cuanto se ha entrado en el tile horizontalmente
const int pos = (p.x % tileSize); // esto da un valor entre 0 y 7
debug->add("POS = " + std::to_string(pos));
// Se resta a la base la cantidad de pixeles pos en funcion de la rampa
if (slope == t_slope_r)
{
base -= pos + 1;
debug->add("BASE_R = " + std::to_string(base));
}
else
{
base -= (tileSize - pos);
debug->add("BASE_L = " + std::to_string(base));
}
return base;
}
// Calcula las superficies inferiores
void Room::setBottomSurfaces()
{
std::vector<int> tile;
// Busca todos los tiles de tipo muro que no tengan debajo otro muro
// Hay que recorrer la habitación por filas (excepto los de la última fila)
for (int i = 0; i < tilemap.size() - mapWidth; i++)
{
if (getTile(i) == t_wall && getTile(i + mapWidth) != t_wall)
{
tile.push_back(i);
// Si llega al final de la fila, introduce un separador
if (i % mapWidth == mapWidth - 1)
{
tile.push_back(-1);
}
}
}
// Recorre el vector de tiles buscando tiles consecutivos para localizar las superficies
int i = 0;
while (i < tile.size())
{
h_line_t line;
line.x1 = (tile[i] % mapWidth) * tileSize;
line.y = ((tile[i] / mapWidth) * tileSize) + tileSize - 1;
while (tile[i] + 1 == tile[i + 1])
{
i++;
}
line.x2 = ((tile[i] % mapWidth) * tileSize) + tileSize - 1;
bottomSurfaces.push_back(line);
i++;
}
}
// Calcula las superficies superiores
void Room::setTopSurfaces()
{
std::vector<int> tile;
// Busca todos los tiles de tipo muro o pasable que no tengan encima un muro
// Hay que recorrer la habitación por filas (excepto los de la primera fila)
for (int i = mapWidth; i < tilemap.size(); i++)
{
if ((getTile(i) == t_wall || getTile(i) == t_passable) && getTile(i - mapWidth) != t_wall)
{
tile.push_back(i);
// Si llega al final de la fila, introduce un separador
if (i % mapWidth == mapWidth - 1)
{
tile.push_back(-1);
}
}
}
// Recorre el vector de tiles buscando tiles consecutivos para localizar las superficies
int i = 0;
while (i < tile.size())
{
h_line_t line;
line.x1 = (tile[i] % mapWidth) * tileSize;
line.y = (tile[i] / mapWidth) * tileSize;
while (tile[i] + 1 == tile[i + 1])
{
i++;
}
line.x2 = ((tile[i] % mapWidth) * tileSize) + tileSize - 1;
topSurfaces.push_back(line);
i++;
}
}
// Calcula las superficies laterales izquierdas
void Room::setLeftSurfaces()
{
std::vector<int> tile;
// Busca todos los tiles de tipo muro que no tienen a su izquierda un tile de tipo muro
// Hay que recorrer la habitación por columnas (excepto los de la primera columna)
for (int i = 1; i < mapWidth; ++i)
{
for (int j = 0; j < mapHeight; ++j)
{
const int pos = (j * mapWidth + i);
if (getTile(pos) == t_wall && getTile(pos - 1) != t_wall)
{
tile.push_back(pos);
}
}
}
// Recorre el vector de tiles buscando tiles consecutivos
// (Los tiles de la misma columna, la diferencia entre ellos es de mapWidth)
// para localizar las superficies
int i = 0;
while (i < tile.size())
{
v_line_t line;
line.x = (tile[i] % mapWidth) * tileSize;
line.y1 = ((tile[i] / mapWidth) * tileSize);
while (tile[i] + mapWidth == tile[i + 1])
{
i++;
}
line.y2 = ((tile[i] / mapWidth) * tileSize) + tileSize - 1;
leftSurfaces.push_back(line);
i++;
}
}
// Calcula las superficies laterales derechas
void Room::setRightSurfaces()
{
std::vector<int> tile;
// Busca todos los tiles de tipo muro que no tienen a su derecha un tile de tipo muro
// Hay que recorrer la habitación por columnas (excepto los de la última columna)
for (int i = 0; i < mapWidth - 1; ++i)
{
for (int j = 0; j < mapHeight; ++j)
{
const int pos = (j * mapWidth + i);
if (getTile(pos) == t_wall && getTile(pos + 1) != t_wall)
{
tile.push_back(pos);
}
}
}
// Recorre el vector de tiles buscando tiles consecutivos
// (Los tiles de la misma columna, la diferencia entre ellos es de mapWidth)
// para localizar las superficies
int i = 0;
while (i < tile.size())
{
v_line_t line;
line.x = ((tile[i] % mapWidth) * tileSize) + tileSize - 1;
line.y1 = ((tile[i] / mapWidth) * tileSize);
while (tile[i] + mapWidth == tile[i + 1])
{
i++;
}
line.y2 = ((tile[i] / mapWidth) * tileSize) + tileSize - 1;
rightSurfaces.push_back(line);
i++;
}
}
// Encuentra todas las rampas que suben hacia la izquierda
void Room::setLeftSlopes()
{
// Recorre la habitación entera por filas buscando tiles de tipo t_slope_l
std::vector<int> found;
for (int i = 0; i < tilemap.size(); ++i)
{
if (getTile(i) == t_slope_l)
{
found.push_back(i);
}
}
// El primer elemento es el inicio de una rampa. Se añade ese elemento y se buscan los siguientes,
// que seran i + mapWidth + 1. Conforme se añaden se eliminan y se vuelve a escudriñar el vector de
// tiles encontrados hasta que esté vacío
while (found.size() > 0)
{
d_line_t line;
line.x1 = (found[0] % mapWidth) * tileSize;
line.y1 = (found[0] / mapWidth) * tileSize;
int lookingFor = found[0] + mapWidth + 1;
int lastOneFound = found[0];
found.erase(found.begin());
for (int i = 0; i < found.size(); i++)
{
if (found[i] == lookingFor)
{
lastOneFound = lookingFor;
lookingFor += mapWidth + 1;
found.erase(found.begin() + i);
--i;
}
}
line.x2 = ((lastOneFound % mapWidth) * tileSize) + tileSize - 1;
line.y2 = ((lastOneFound / mapWidth) * tileSize) + tileSize - 1;
leftSlopes.push_back(line);
}
}
// Encuentra todas las rampas que suben hacia la derecha
void Room::setRightSlopes()
{
// Recorre la habitación entera por filas buscando tiles de tipo t_slope_r
std::vector<int> found;
for (int i = 0; i < tilemap.size(); ++i)
{
if (getTile(i) == t_slope_r)
{
found.push_back(i);
}
}
// El primer elemento es el inicio de una rampa. Se añade ese elemento y se buscan los siguientes,
// que seran i + mapWidth - 1. Conforme se añaden se eliminan y se vuelve a escudriñar el vector de
// tiles encontrados hasta que esté vacío
while (found.size() > 0)
{
d_line_t line;
line.x1 = ((found[0] % mapWidth) * tileSize) + tileSize - 1;
line.y1 = (found[0] / mapWidth) * tileSize;
int lookingFor = found[0] + mapWidth - 1;
int lastOneFound = found[0];
found.erase(found.begin());
for (int i = 0; i < found.size(); i++)
{
if (found[i] == lookingFor)
{
lastOneFound = lookingFor;
lookingFor += mapWidth - 1;
found.erase(found.begin() + i);
--i;
}
}
line.x2 = (lastOneFound % mapWidth) * tileSize;
line.y2 = ((lastOneFound / mapWidth) * tileSize) + tileSize - 1;
rightSlopes.push_back(line);
}
}
// Comprueba las colisiones
int Room::checkRightSurfaces(SDL_Rect *rect)
{
for (auto s : rightSurfaces)
{
if (checkCollision(s, *rect))
{
return s.x;
}
}
return -1;
}
// Comprueba las colisiones
int Room::checkLeftSurfaces(SDL_Rect *rect)
{
for (auto s : leftSurfaces)
{
if (checkCollision(s, *rect))
{
return s.x;
}
}
return -1;
}
// Comprueba las colisiones
int Room::checkTopSurfaces(SDL_Rect *rect)
{
for (auto s : topSurfaces)
{
if (checkCollision(s, *rect))
{
return s.y;
}
}
return -1;
}
// Comprueba las colisiones
int Room::checkBottomSurfaces(SDL_Rect *rect)
{
for (auto s : bottomSurfaces)
{
if (checkCollision(s, *rect))
{
return s.y;
}
}
return -1;
}
// Comprueba las colisiones
bool Room::checkTopSurfaces(SDL_Point *p)
{
for (auto s : topSurfaces)
{
if (checkCollision(s, *p))
{
return true;
}
}
return false;
}
// Comprueba las colisiones
int Room::checkLeftSlopes(v_line_t *line)
{
for (auto s : leftSlopes)
{
const SDL_Point p = checkCollision(s, *line);
if (p.x != -1)
{
return p.y;
}
}
return -1;
}
// Comprueba las colisiones
bool Room::checkLeftSlopes(SDL_Point *p)
{
for (auto s : leftSlopes)
{
if (checkCollision(*p, s))
{
return true;
}
}
return false;
}
// Comprueba las colisiones
int Room::checkRightSlopes(v_line_t *line)
{
for (auto s : rightSlopes)
{
const SDL_Point p = checkCollision(s, *line);
if (p.x != -1)
{
return p.y;
}
}
return -1;
}
// Comprueba las colisiones
bool Room::checkRightSlopes(SDL_Point *p)
{
for (auto s : rightSlopes)
{
if (checkCollision(*p, s))
{
return true;
}
}
return false;
}

View File

@@ -3,35 +3,42 @@
#include "utils.h" #include "utils.h"
#include "asset.h" #include "asset.h"
#include "screen.h"
#include "enemy.h" #include "enemy.h"
#include "item.h" #include "item.h"
#include "item_tracker.h" #include "item_tracker.h"
#include "const.h" #include "const.h"
#include "jail_audio.h" #include "jail_audio.h"
#include "debug.h"
#include <string> #include <string>
#include <vector> #include <vector>
#ifndef ROOM_H #ifndef ROOM_H
#define ROOM_H #define ROOM_H
#define TILE_EMPTY 0
#define TILE_SOLID 1
#define TILE_TRAVESSABLE 2
#define TILE_KILL 3
/* /*
Cada habitación se crea y destruye cada vez que se entra o sale de la misma Cada habitación se crea y destruye cada vez que se entra o sale de la misma
Cada habitacion si que tendra lo siguiente: Cada habitacion tiene lo siguiente:
ID (numerico) - ID (numerico)
NOMBRE (texto) - NOMBRE (texto)
COLOR DE FONDO (texto) - COLOR DE FONDO (texto)
SET DE TILES (texto, hace referencia a un png de la colección) - COLOR DEL BORDE (texto)
LIMITE SUPERIOR (ID de la habitación superior), INFERIOR, IZQUIERDO y DERECHO - SET DE TILES (texto, hace referencia a un png de la colección)
MAPA DE TILES (array con los indices de los tiles a utilizar) <-- hay que decidir si cada tile del set ya - LIMITE SUPERIOR (ID de la habitación superior), INFERIOR, IZQUIERDO y DERECHO
- MAPA DE TILES (array con los indices de los tiles a utilizar) <-- hay que decidir si cada tile del set ya
tierne propiedades o se ponen en un mapa aparte tierne propiedades o se ponen en un mapa aparte
LISTADO DE ENEMIGOS (tipo, posicion, dx, dy) - LISTADO DE ENEMIGOS (tipo, posicion, dx, dy)
LISTADO DE ITEMS (tipo, posicion) - LISTADO DE ITEMS (tipo, posicion)
*/ */
enum tile_e
{
t_empty,
t_wall,
t_passable,
t_slope_l,
t_slope_r,
t_death
};
// Clase Room // Clase Room
class Room class Room
@@ -39,6 +46,7 @@ class Room
private: private:
std::string name; // Nombre de la habitación std::string name; // Nombre de la habitación
color_t bgColor; // Color de fondo de la habitación color_t bgColor; // Color de fondo de la habitación
color_t borderColor; // Color de fondo de la habitación
std::string roomUp; // Identificador de la habitación que se encuentra arriba std::string roomUp; // Identificador de la habitación que se encuentra arriba
std::string roomDown; // Identificador de la habitación que se encuentra abajp std::string roomDown; // Identificador de la habitación que se encuentra abajp
std::string roomLeft; // Identificador de la habitación que se encuentra a la izquierda std::string roomLeft; // Identificador de la habitación que se encuentra a la izquierda
@@ -49,11 +57,24 @@ private:
std::vector<Item *> items; // Listado con los items que hay en la habitación std::vector<Item *> items; // Listado con los items que hay en la habitación
LTexture *texture; // Textura con los graficos de la habitación LTexture *texture; // Textura con los graficos de la habitación
Asset *asset; // Objeto con la ruta a todos los ficheros de recursos Asset *asset; // Objeto con la ruta a todos los ficheros de recursos
Screen *screen; // Objeto encargado de dibujar en pantalla
ItemTracker *itemTracker; // Lleva el control de los objetos recogidos ItemTracker *itemTracker; // Lleva el control de los objetos recogidos
SDL_Renderer *renderer; // El renderizador de la ventana SDL_Renderer *renderer; // El renderizador de la ventana
SDL_Texture *mapTexture; // Textura para dibujar el mapa de la habitación SDL_Texture *mapTexture; // Textura para dibujar el mapa de la habitación
JA_Sound itemSound; // Sonido producido al coger un objeto JA_Sound itemSound; // Sonido producido al coger un objeto
int *itemsPicked; // Puntero a la cantidad de items recogidos que lleva el juego int *itemsPicked; // Puntero a la cantidad de items recogidos que lleva el juego
Debug *debug; // Objeto para gestionar la información de debug
std::vector<h_line_t> bottomSurfaces; // Lista con las superficies inferiores de la habitación
std::vector<h_line_t> topSurfaces; // Lista con las superficies superiores de la habitación
std::vector<v_line_t> leftSurfaces; // Lista con las superficies laterales de la parte izquierda de la habitación
std::vector<v_line_t> rightSurfaces; // Lista con las superficies laterales de la parte derecha de la habitación
std::vector<d_line_t> leftSlopes; // Lista con todas las rampas que suben hacia la izquierda
std::vector<d_line_t> rightSlopes; // Lista con todas las rampas que suben hacia la derecha
int tileSize; // Ancho del tile en pixels
int mapWidth; // Ancho del mapa en tiles
int mapHeight; // Alto del mapa en tiles
int tilesetWidth; // Ancho del tileset en tiles
// Carga las variables desde un fichero // Carga las variables desde un fichero
bool load(std::string file_path); bool load(std::string file_path);
@@ -70,9 +91,30 @@ private:
// Pinta el mapa de la habitación en la textura // Pinta el mapa de la habitación en la textura
void fillMapTexture(); void fillMapTexture();
// Calcula las superficies inferiores
void setBottomSurfaces();
// Calcula las superficies superiores
void setTopSurfaces();
// Calcula las superficies laterales izquierdas
void setLeftSurfaces();
// Calcula las superficies laterales derechas
void setRightSurfaces();
// Encuentra todas las rampas que suben hacia la izquierda
void setLeftSlopes();
// Encuentra todas las rampas que suben hacia la derecha
void setRightSlopes();
// Devuelve el tipo de tile que hay en ese indice
tile_e getTile(int index);
public: public:
// Constructor // Constructor
Room(std::string file_path, SDL_Renderer *renderer, Asset *asset, ItemTracker *item_tracker, int *items); Room(std::string file_path, SDL_Renderer *renderer, Screen *screen, Asset *asset, ItemTracker *item_tracker, int *items, Debug *debug);
// Destructor // Destructor
~Room(); ~Room();
@@ -99,7 +141,7 @@ public:
std::string getRoom(int border); std::string getRoom(int border);
// Devuelve el tipo de tile que hay en ese pixel // Devuelve el tipo de tile que hay en ese pixel
int getTile(SDL_Point point); tile_e getTile(SDL_Point point);
// Indica si hay colision con un enemigo a partir de un rectangulo // Indica si hay colision con un enemigo a partir de un rectangulo
bool enemyCollision(SDL_Rect &rect); bool enemyCollision(SDL_Rect &rect);
@@ -109,6 +151,39 @@ public:
// Recarga la textura // Recarga la textura
void reLoadTexture(); void reLoadTexture();
// Obten el tamaño del tile
int getTileSize();
// Obten la coordenada de la cuesta a partir de un punto perteneciente a ese tile
int getSlopeHeight(SDL_Point p, tile_e slope);
// Comprueba las colisiones
int checkRightSurfaces(SDL_Rect *rect);
// Comprueba las colisiones
int checkLeftSurfaces(SDL_Rect *rect);
// Comprueba las colisiones
int checkTopSurfaces(SDL_Rect *rect);
// Comprueba las colisiones
int checkBottomSurfaces(SDL_Rect *rect);
// Comprueba las colisiones
bool checkTopSurfaces(SDL_Point *p);
// Comprueba las colisiones
int checkLeftSlopes(v_line_t *line);
// Comprueba las colisiones
bool checkLeftSlopes(SDL_Point *p);
// Comprueba las colisiones
int checkRightSlopes(v_line_t *line);
// Comprueba las colisiones
bool checkRightSlopes(SDL_Point *p);
}; };
#endif #endif

View File

@@ -13,8 +13,8 @@ ScoreBoard::ScoreBoard(SDL_Renderer *renderer, Asset *asset, int *lives, int *it
this->clock = clock; this->clock = clock;
// Reserva memoria para los objetos // Reserva memoria para los objetos
texture = new LTexture(renderer, asset->get("player01.png")); texture = new LTexture(renderer, asset->get("player.png"));
sprite = new AnimatedSprite(texture, renderer, asset->get("player01.ani")); sprite = new AnimatedSprite(texture, renderer, asset->get("player.ani"));
sprite->setCurrentAnimation("walk_menu"); sprite->setCurrentAnimation("walk_menu");
text = new Text(asset->get("smb2.png"), asset->get("smb2.txt"), renderer); text = new Text(asset->get("smb2.png"), asset->get("smb2.txt"), renderer);
@@ -29,7 +29,7 @@ ScoreBoard::ScoreBoard(SDL_Renderer *renderer, Asset *asset, int *lives, int *it
c = stringToColor("red"); c = stringToColor("red");
color.push_back(c); color.push_back(c);
c = stringToColor("purple"); c = stringToColor("magenta");
color.push_back(c); color.push_back(c);
c = stringToColor("green"); c = stringToColor("green");
@@ -44,25 +44,25 @@ ScoreBoard::ScoreBoard(SDL_Renderer *renderer, Asset *asset, int *lives, int *it
c = stringToColor("white"); c = stringToColor("white");
color.push_back(c); color.push_back(c);
c = stringToColor("light_blue"); c = stringToColor("bright_blue");
color.push_back(c); color.push_back(c);
c = stringToColor("light_red"); c = stringToColor("bright_red");
color.push_back(c); color.push_back(c);
c = stringToColor("light_purple"); c = stringToColor("bright_magenta");
color.push_back(c); color.push_back(c);
c = stringToColor("light_green"); c = stringToColor("bright_green");
color.push_back(c); color.push_back(c);
c = stringToColor("light_cyan"); c = stringToColor("bright_cyan");
color.push_back(c); color.push_back(c);
c = stringToColor("light_yellow"); c = stringToColor("bright_yellow");
color.push_back(c); color.push_back(c);
c = stringToColor("light_white"); c = stringToColor("bright_white");
color.push_back(c); color.push_back(c);
} }
@@ -78,12 +78,12 @@ ScoreBoard::~ScoreBoard()
void ScoreBoard::render() void ScoreBoard::render()
{ {
// Dibuja el fondo del marcador // Dibuja el fondo del marcador
const SDL_Rect rect = {0, 17 * BLOCK, PLAY_AREA_WIDTH, GAMECANVAS_HEIGHT - PLAY_AREA_HEIGHT}; const SDL_Rect rect = {0, 18 * BLOCK, PLAY_AREA_WIDTH, GAMECANVAS_HEIGHT - PLAY_AREA_HEIGHT};
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderFillRect(renderer, &rect); SDL_RenderFillRect(renderer, &rect);
// Dibuja las vidas // Dibuja las vidas
sprite->setPosY(18 * BLOCK); sprite->setPosY(19 * BLOCK);
int index; int index;
const int desp = (counter / 40) % 8; const int desp = (counter / 40) % 8;
const int frame = desp % 4; const int frame = desp % 4;
@@ -108,7 +108,7 @@ void ScoreBoard::render()
std::string timeTxt = std::to_string((clock.minutes % 60) / 10) + std::to_string(clock.minutes % 10) + separator + std::to_string((clock.seconds % 60) / 10) + std::to_string(clock.seconds % 10); std::string timeTxt = std::to_string((clock.minutes % 60) / 10) + std::to_string(clock.minutes % 10) + separator + std::to_string((clock.seconds % 60) / 10) + std::to_string(clock.seconds % 10);
std::string text = "Items collected " + itemsTxt + " Time " + timeTxt; std::string text = "Items collected " + itemsTxt + " Time " + timeTxt;
const color_t color = stringToColor("white"); const color_t color = stringToColor("white");
this->text->writeColored(BLOCK, 21 * BLOCK, text, color); this->text->writeColored(BLOCK, 22 * BLOCK, text, color);
} }
// Actualiza las variables del objeto // Actualiza las variables del objeto

79
source/test.cpp Normal file
View File

@@ -0,0 +1,79 @@
#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);
}
}
// Destructor
Test::~Test()
{
}
// Actualiza las variables
void Test::update()
{
for (int i = 0; i < 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);
}

48
source/test.h Normal file
View File

@@ -0,0 +1,48 @@
#pragma once
#include <SDL2/SDL.h>
#include "const.h"
#include "utils.h"
#include "screen.h"
#include "asset.h"
#include "text.h"
#include "debug.h"
#include <vector>
#include <string>
#ifndef TEST_H
#define TEST_H
struct point_t
{
float x, y;
float vx, vy;
int dx, dy;
};
// Clase Test
class Test
{
private:
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;
std::vector<point_t> points;
public:
// Constructor
Test(SDL_Renderer *renderer, Screen *screen, Asset *asset, Debug *debug);
// Destructor
~Test();
// Actualiza las variables
void update();
// Dibuja en pantalla
void render();
};
#endif

View File

@@ -172,7 +172,7 @@ void Text::initOffsetFromFile()
} }
// Devuelve el valor de la variable // Devuelve el valor de la variable
int Text::getCharacterWidth() int Text::getCharacterSize()
{ {
return boxWidth; return boxWidth;
} }

View File

@@ -62,7 +62,7 @@ public:
int lenght(std::string text, int kerning = 1); int lenght(std::string text, int kerning = 1);
// Devuelve el valor de la variable // Devuelve el valor de la variable
int getCharacterWidth(); int getCharacterSize();
// Recarga la textura // Recarga la textura
void reLoadTexture(); void reLoadTexture();

View File

@@ -13,6 +13,7 @@ Title::Title(SDL_Renderer *renderer, Screen *screen, Asset *asset)
texture = new LTexture(renderer, asset->get("loading_screen2.png")); texture = new LTexture(renderer, asset->get("loading_screen2.png"));
sprite = new Sprite(0, 0, texture->getWidth(), texture->getHeight(), texture, renderer); sprite = new Sprite(0, 0, texture->getWidth(), texture->getHeight(), texture, renderer);
text = new Text(asset->get("smb2.png"), asset->get("smb2.txt"), renderer); text = new Text(asset->get("smb2.png"), asset->get("smb2.txt"), renderer);
music = JA_LoadMusic(asset->get("title.ogg").c_str());
// Inicializa variables // Inicializa variables
counter = 0; counter = 0;
@@ -20,6 +21,19 @@ Title::Title(SDL_Renderer *renderer, Screen *screen, Asset *asset)
section.subsection = 0; section.subsection = 0;
ticks = 0; ticks = 0;
ticksSpeed = 15; ticksSpeed = 15;
longText = "HEY JAILERS!! IT'S 2022 AND WE'RE STILL ROCKING LIKE IT'S 1998!!! HAVE YOU HEARD IT? JAILGAMES ARE BACK!! YEEESSS BACK!! MORE THAN 10 TITLES ON JAILDOC'S KITCHEN!! THATS A LOOOOOOT OF JAILGAMES, BUT WHICH ONE WILL STRIKE FIRST? THERE IS ALSO A NEW DEVICE TO COME P.A.C.O. THAT WILL BLOW YOUR MIND WITH JAILGAMES ON THE GO. BUT WAIT! WHAT'S THAT BEAUTY I'M SEEING RIGHT OVER THERE?? OOOH THAT TINY MINIASCII IS PURE LOVE!! I WANT TO LICK EVERY BYTE OF IT!! OH SHIT! AND DON'T FORGET TO BRING BACK THOSE OLD AND FAT MS-DOS JAILGAMES TO GITHUB TO KEEP THEM ALIVE!! WHAT WILL BE THE NEXT JAILDOC RELEASE? WHAT WILL BE THE NEXT PROJECT TO COME ALIVE?? OH BABY WE DON'T KNOW BUT HERE YOU CAN FIND THE ANSWER, YOU JUST HAVE TO COMPLETE JAILDOCTOR'S DILEMMA ... COULD YOU?";
for (int i = 0; i < longText.length(); i++)
{
letter_t l;
l.letter = longText.substr(i, 1);
l.x = 256;
l.enabled = false;
letters.push_back(l);
}
letters[0].enabled = true;
// Cambia el color del borde
screen->setBorderColor(stringToColor("bright_blue"));
} }
// Destructor // Destructor
@@ -29,6 +43,7 @@ Title::~Title()
delete texture; delete texture;
delete sprite; delete sprite;
delete text; delete text;
JA_DeleteMusic(music);
} }
// Comprueba el manejador de eventos // Comprueba el manejador de eventos
@@ -65,6 +80,42 @@ void Title::checkEventHandler()
} }
} }
// Actualiza la marquesina
void Title::updateMarquee()
{
for (int i = 0; i < letters.size(); i++)
{
if (letters[i].enabled)
{
letters[i].x -= 2;
if (letters[i].x < -10)
{
letters[i].enabled = false;
}
}
else
{
if (i > 0 && letters[i - 1].x < 250)
{
letters[i].enabled = true;
}
}
}
}
// Dibuja la marquesina
void Title::renderMarquee()
{
for (auto l : letters)
{
if (l.enabled)
{
// text->writeColored(l.x, 176, l.letter, {0, 0, 0});
text->write(l.x, 176, l.letter);
}
}
}
// Actualiza las variables // Actualiza las variables
void Title::update() void Title::update()
{ {
@@ -80,8 +131,14 @@ void Title::update()
// Incrementa el contador // Incrementa el contador
counter++; counter++;
// Actualiza la marquesina
updateMarquee();
// Comprueba si ha pasado mucho tiempo y acaba el titulo // Comprueba si ha pasado mucho tiempo y acaba el titulo
if (counter == 1000) // if (counter == 1000)
// Comprueba si ha terminado la marquesina y acaba con el titulo
if (letters[letters.size() - 1].x < -10)
{ {
section.name = SECTION_PROG_LOGO; section.name = SECTION_PROG_LOGO;
section.subsection = 0; section.subsection = 0;
@@ -98,15 +155,18 @@ void Title::render()
// Limpia la pantalla // Limpia la pantalla
screen->clean(); screen->clean();
// Dibuja los objetos // Dibuja el fondo del titulo
sprite->render(); sprite->render();
// Dibuja el texto de PRESS ENTER TO PLAY
SDL_SetRenderDrawColor(renderer, 0, 0, 255, 255); SDL_SetRenderDrawColor(renderer, 0, 0, 255, 255);
SDL_Rect rect = {0, 192 / 5 * 4, 256, 8}; SDL_Rect rect = {0, 192 / 5 * 4, 256, 8};
SDL_RenderFillRect(renderer, &rect); SDL_RenderFillRect(renderer, &rect);
if (counter % 80 < 60) if (counter % 80 < 60)
text->writeCentered(256 / 2, 192 / 5 * 4, "PRESS ENTER TO PLAY"); text->writeCentered(256 / 2, 192 / 5 * 4, "PRESS ENTER TO PLAY");
//text->write(0, 0, std::to_string(counter)); // Dibuja la marquesina
renderMarquee();
// Vuelca el contenido del renderizador en pantalla // Vuelca el contenido del renderizador en pantalla
screen->blit(); screen->blit();
@@ -115,8 +175,7 @@ void Title::render()
// Bucle para el logo del juego // Bucle para el logo del juego
section_t Title::run() section_t Title::run()
{ {
// Detiene la música JA_PlayMusic(music);
JA_StopMusic();
while (section.name == SECTION_PROG_TITLE) while (section.name == SECTION_PROG_TITLE)
{ {
@@ -124,5 +183,7 @@ section_t Title::run()
render(); render();
} }
JA_StopMusic();
return section; return section;
} }

View File

@@ -17,6 +17,13 @@
class Title class Title
{ {
private: private:
struct letter_t
{
std::string letter; // Letra a escribir
int x; // Posición en el eje x
bool enabled; // Solo se escriben y mueven si estan habilitadas
};
SDL_Renderer *renderer; // El renderizador de la ventana SDL_Renderer *renderer; // El renderizador de la ventana
Screen *screen; // Objeto encargado de dibujar en pantalla Screen *screen; // Objeto encargado de dibujar en pantalla
Asset *asset; // Objeto con los ficheros de recursos Asset *asset; // Objeto con los ficheros de recursos
@@ -24,10 +31,13 @@ private:
LTexture *texture; // Textura con los graficos LTexture *texture; // Textura con los graficos
Sprite *sprite; // Sprite para manejar la textura Sprite *sprite; // Sprite para manejar la textura
Text *text; // Objeto para escribir texto en pantalla Text *text; // Objeto para escribir texto en pantalla
JA_Music music; // Musica del titulo
int counter; // Contador int counter; // Contador
section_t section; // Estado del bucle principal para saber si continua o se sale section_t section; // Estado del bucle principal para saber si continua o se sale
std::string longText; // Texto que aparece en la parte inferior del titulo
int ticks; // Contador de ticks para ajustar la velocidad del programa int ticks; // Contador de ticks para ajustar la velocidad del programa
int ticksSpeed; // Velocidad a la que se repiten los bucles del programa int ticksSpeed; // Velocidad a la que se repiten los bucles del programa
std::vector<letter_t> letters; // Vector con las letras de la marquesina
// Actualiza las variables // Actualiza las variables
void update(); void update();
@@ -38,6 +48,12 @@ private:
// Comprueba el manejador de eventos // Comprueba el manejador de eventos
void checkEventHandler(); void checkEventHandler();
// Actualiza la marquesina
void updateMarquee();
// Dibuja la marquesina
void renderMarquee();
public: public:
// Constructor // Constructor
Title(SDL_Renderer *renderer, Screen *screen, Asset *asset); Title(SDL_Renderer *renderer, Screen *screen, Asset *asset);

View File

@@ -74,19 +74,19 @@ bool checkCollision(circle_t &a, SDL_Rect &b)
// Detector de colisiones entre dos rectangulos // Detector de colisiones entre dos rectangulos
bool checkCollision(SDL_Rect &a, SDL_Rect &b) bool checkCollision(SDL_Rect &a, SDL_Rect &b)
{ {
// Calculate the sides of rect A // Calcula las caras del rectangulo a
const int leftA = a.x; const int leftA = a.x;
const int rightA = a.x + a.w; const int rightA = a.x + a.w;
const int topA = a.y; const int topA = a.y;
const int bottomA = a.y + a.h; const int bottomA = a.y + a.h;
// Calculate the sides of rect B // Calcula las caras del rectangulo b
const int leftB = b.x; const int leftB = b.x;
const int rightB = b.x + b.w; const int rightB = b.x + b.w;
const int topB = b.y; const int topB = b.y;
const int bottomB = b.y + b.h; const int bottomB = b.y + b.h;
// If any of the sides from A are outside of B // Si cualquiera de las caras de a está fuera de b
if (bottomA <= topB) if (bottomA <= topB)
{ {
return false; return false;
@@ -107,106 +107,425 @@ bool checkCollision(SDL_Rect &a, SDL_Rect &b)
return false; return false;
} }
// If none of the sides from A are outside B // Si ninguna de las caras está fuera de b
return true; return true;
} }
// Detector de colisiones entre un punto y u rectangulo // Detector de colisiones entre un punto y un rectangulo
bool checkCollision(SDL_Point &p, SDL_Rect &r) bool checkCollision(SDL_Point &p, SDL_Rect &r)
{ {
// Comprueba si el punto está fuera del rectangulo en el eje X // Comprueba si el punto está a la izquierda del rectangulo
if (p.x < r.x) if (p.x < r.x)
{ {
return false; return false;
} }
// Comprueba si el punto está a la derecha del rectangulo
if (p.x > r.x + r.w) if (p.x > r.x + r.w)
{ {
return false; return false;
} }
// Comprueba si el punto está fuera del rectangulo en el eje Y // Comprueba si el punto está por encima del rectangulo
if (p.y < r.y) if (p.y < r.y)
{ {
return false; return false;
} }
// Comprueba si el punto está por debajo del rectangulo
if (p.y > r.y + r.h) if (p.y > r.y + r.h)
{ {
return false; return false;
} }
// Si ha llegado hasta aquí, es que está dentro // Si no está fuera, es que está dentro
return true;
}
// Detector de colisiones entre una linea horizontal y un rectangulo
bool checkCollision(h_line_t &l, SDL_Rect &r)
{
// Comprueba si la linea esta por encima del rectangulo
if (l.y < r.y)
{
return false;
}
// Comprueba si la linea esta por debajo del rectangulo
if (l.y >= r.y + r.h)
{
return false;
}
// Comprueba si el inicio de la linea esta a la derecha del rectangulo
if (l.x1 >= r.x + r.w)
{
return false;
}
// Comprueba si el final de la linea esta a la izquierda del rectangulo
if (l.x2 < r.x)
{
return false;
}
// Si ha llegado hasta aquí, hay colisión
return true;
}
// Detector de colisiones entre una linea vertical y un rectangulo
bool checkCollision(v_line_t &l, SDL_Rect &r)
{
// Comprueba si la linea esta por la izquierda del rectangulo
if (l.x < r.x)
{
return false;
}
// Comprueba si la linea esta por la derecha del rectangulo
if (l.x >= r.x + r.w)
{
return false;
}
// Comprueba si el inicio de la linea esta debajo del rectangulo
if (l.y1 >= r.y + r.h)
{
return false;
}
// Comprueba si el final de la linea esta encima del rectangulo
if (l.y2 < r.y)
{
return false;
}
// Si ha llegado hasta aquí, hay colisión
return true;
}
// Detector de colisiones entre una linea horizontal y un punto
bool checkCollision(h_line_t &l, SDL_Point &p)
{
// Comprueba si el punto esta sobre la linea
if (p.y > l.y)
{
return false;
}
// Comprueba si el punto esta bajo la linea
if (p.y < l.y)
{
return false;
}
// Comprueba si el punto esta a la izquierda de la linea
if (p.x < l.x1)
{
return false;
}
// Comprueba si el punto esta a la derecha de la linea
if (p.x > l.x2)
{
return false;
}
// Si ha llegado aquí, hay colisión
return true;
}
// Detector de colisiones entre dos lineas
SDL_Point checkCollision(line_t &l1, line_t &l2)
{
const float x1 = l1.x1;
const float y1 = l1.y1;
const float x2 = l1.x2;
const float y2 = l1.y2;
const float x3 = l2.x1;
const float y3 = l2.y1;
const float x4 = l2.x2;
const float y4 = l2.y2;
// calculate the direction of the lines
float uA = ((x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3)) / ((y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1));
float uB = ((x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3)) / ((y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1));
// if uA and uB are between 0-1, lines are colliding
if (uA >= 0 && uA <= 1 && uB >= 0 && uB <= 1)
{
// Calcula la intersección
const float x = x1 + (uA * (x2 - x1));
const float y = y1 + (uA * (y2 - y1));
return {(int)round(x), (int)round(y)};
}
return {-1, -1};
}
// Detector de colisiones entre dos lineas
SDL_Point checkCollision(d_line_t &l1, v_line_t &l2)
{
const float x1 = l1.x1;
const float y1 = l1.y1;
const float x2 = l1.x2;
const float y2 = l1.y2;
const float x3 = l2.x;
const float y3 = l2.y1;
const float x4 = l2.x;
const float y4 = l2.y2;
// calculate the direction of the lines
float uA = ((x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3)) / ((y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1));
float uB = ((x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3)) / ((y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1));
// if uA and uB are between 0-1, lines are colliding
if (uA >= 0 && uA <= 1 && uB >= 0 && uB <= 1)
{
// Calcula la intersección
const float x = x1 + (uA * (x2 - x1));
const float y = y1 + (uA * (y2 - y1));
return {(int)x, (int)y};
}
return {-1, -1};
}
// Detector de colisiones entre una linea diagonal y una vertical
/*bool checkCollision(d_line_t &l1, v_line_t &l2)
{
// Normaliza la linea diagonal
normalizeLine(l1);
// Comprueba si la linea vertical esta a la izquierda de la linea diagonal
if (l2.x < l1.x1)
{
return false;
}
// Comprueba si la linea vertical esta a la derecha de la linea diagonal
if (l2.x > l1.x2)
{
return false;
}
// Inacabada
return true;
}*/
// Normaliza una linea diagonal
void normalizeLine(d_line_t &l)
{
// Las lineas diagonales van de izquierda a derecha
// x2 mayor que x1
if (l.x2 < l.x1)
{
const int x = l.x1;
const int y = l.y1;
l.x1 = l.x2;
l.y1 = l.y2;
l.x2 = x;
l.y2 = y;
}
}
// Detector de colisiones entre un punto y una linea diagonal
bool checkCollision(SDL_Point &p, d_line_t &l)
{
// Comprueba si el punto está en alineado con la linea
if (abs(p.x - l.x1) != abs(p.y - l.y1))
{
return false;
}
// Comprueba si está a la derecha de la linea
if (p.x > l.x1 && p.x > l.x2)
{
return false;
}
// Comprueba si está a la izquierda de la linea
if (p.x < l.x1 && p.x < l.x2)
{
return false;
}
// En caso contrario, el punto está en la linea
return true; return true;
} }
// Devuelve un color_t a partir de un string // Devuelve un color_t a partir de un string
color_t stringToColor(std::string str) color_t stringToColor(std::string str)
{ {
color_t color = {0x00, 0x00, 0x00}; const std::string palette = "spectrum";
if (palette == "spectrum")
{
if (str == "black") if (str == "black")
{ {
color = {0x00, 0x00, 0x00}; return {0x00, 0x00, 0x00};
} }
else if (str == "light_black")
else if (str == "bright_black")
{ {
color = {0x3C, 0x35, 0x1F}; return {0x00, 0x00, 0x00};
} }
else if (str == "blue") else if (str == "blue")
{ {
color = {0x31, 0x33, 0x90}; return {0x00, 0x00, 0xd8};
} }
else if (str == "light_blue")
else if (str == "bright_blue")
{ {
color = {0x15, 0x59, 0xDB}; return {0x00, 0x00, 0xFF};
} }
else if (str == "red") else if (str == "red")
{ {
color = {0xA7, 0x32, 0x11}; return {0xd8, 0x00, 0x00};
} }
else if (str == "light_red")
else if (str == "bright_red")
{ {
color = {0xD8, 0x55, 0x25}; return {0xFF, 0x00, 0x00};
} }
else if (str == "purple")
else if (str == "magenta")
{ {
color = {0xA1, 0x55, 0x89}; return {0xd8, 0x00, 0xd8};
} }
else if (str == "light_purple")
else if (str == "bright_magenta")
{ {
color = {0xCD, 0x7A, 0x50}; return {0xFF, 0x00, 0xFF};
} }
else if (str == "green") else if (str == "green")
{ {
color = {0x62, 0x9A, 0x31}; return {0x00, 0xd8, 0x00};
} }
else if (str == "light_green")
else if (str == "bright_green")
{ {
color = {0x9C, 0xD3, 0x3C}; return {0x00, 0xFF, 0x00};
} }
else if (str == "cyan") else if (str == "cyan")
{ {
color = {0x28, 0xA4, 0xCB}; return {0x00, 0xd8, 0xd8};
} }
else if (str == "light_cyan")
else if (str == "bright_cyan")
{ {
color = {0x65, 0xDC, 0xD6}; return {0x00, 0xFF, 0xFF};
} }
else if (str == "yellow") else if (str == "yellow")
{ {
color = {0xE8, 0xBC, 0x50}; return {0xd8, 0xd8, 0x00};
} }
else if (str == "light_yellow")
else if (str == "bright_yellow")
{ {
color = {0xF1, 0xE7, 0x82}; return {0xFF, 0xFF, 0x00};
} }
else if (str == "white") else if (str == "white")
{ {
color = {0xBF, 0xBF, 0xBD}; return {0xd8, 0xd8, 0xd8};
} }
else if (str == "light_white")
else if (str == "bright_white")
{ {
color = {0xF2, 0xF1, 0xED}; return {0xFF, 0xFF, 0xFF};
} }
return color; }
else
{ // zxarne
if (str == "black")
{
return {0x00, 0x00, 0x00};
}
else if (str == "bright_black")
{
return {0x3C, 0x35, 0x1F};
}
else if (str == "blue")
{
return {0x31, 0x33, 0x90};
}
else if (str == "bright_blue")
{
return {0x15, 0x59, 0xDB};
}
else if (str == "red")
{
return {0xA7, 0x32, 0x11};
}
else if (str == "bright_red")
{
return {0xD8, 0x55, 0x25};
}
else if (str == "magenta")
{
return {0xA1, 0x55, 0x89};
}
else if (str == "bright_magenta")
{
return {0xCD, 0x7A, 0x50};
}
else if (str == "green")
{
return {0x62, 0x9A, 0x31};
}
else if (str == "bright_green")
{
return {0x9C, 0xD3, 0x3C};
}
else if (str == "cyan")
{
return {0x28, 0xA4, 0xCB};
}
else if (str == "bright_cyan")
{
return {0x65, 0xDC, 0xD6};
}
else if (str == "yellow")
{
return {0xE8, 0xBC, 0x50};
}
else if (str == "bright_yellow")
{
return {0xF1, 0xE7, 0x82};
}
else if (str == "white")
{
return {0xBF, 0xBF, 0xBD};
}
else if (str == "bright_white")
{
return {0xF2, 0xF1, 0xED};
}
}
return {0x00, 0x00, 0x00};
} }

View File

@@ -34,6 +34,30 @@ struct circle_t
int r; int r;
}; };
// Estructura para definir una linea horizontal
struct h_line_t
{
int x1, x2, y;
};
// Estructura para definir una linea vertical
struct v_line_t
{
int x, y1, y2;
};
// Estructura para definir una linea diagonal
struct d_line_t
{
int x1, y1, x2, y2;
};
// Estructura para definir una linea
struct line_t
{
int x1, y1, x2, y2;
};
// Estructura para definir un color // Estructura para definir un color
struct color_t struct color_t
{ {
@@ -74,9 +98,33 @@ bool checkCollision(circle_t &a, SDL_Rect &b);
// Detector de colisiones entre un dos rectangulos // Detector de colisiones entre un dos rectangulos
bool checkCollision(SDL_Rect &a, SDL_Rect &b); bool checkCollision(SDL_Rect &a, SDL_Rect &b);
// Detector de colisiones entre un punto y u rectangulo // Detector de colisiones entre un punto y un rectangulo
bool checkCollision(SDL_Point &p, SDL_Rect &r); bool checkCollision(SDL_Point &p, SDL_Rect &r);
// Detector de colisiones entre una linea horizontal y un rectangulo
bool checkCollision(h_line_t &l, SDL_Rect &r);
// Detector de colisiones entre una linea vertical y un rectangulo
bool checkCollision(v_line_t &l, SDL_Rect &r);
// Detector de colisiones entre una linea horizontal y un punto
bool checkCollision(h_line_t &l, SDL_Point &p);
// Detector de colisiones entre dos lineas
SDL_Point checkCollision(line_t &l1, line_t &l2);
// Detector de colisiones entre dos lineas
SDL_Point checkCollision(d_line_t &l1, v_line_t &l2);
// Detector de colisiones entre una linea diagonal y una vertical
//bool checkCollision(d_line_t &l1, v_line_t &l2);
// Detector de colisiones entre un punto y una linea diagonal
bool checkCollision(SDL_Point &p, d_line_t &l);
// Normaliza una linea diagonal
void normalizeLine(d_line_t &l);
// Devuelve un color_t a partir de un string // Devuelve un color_t a partir de un string
color_t stringToColor(std::string str); color_t stringToColor(std::string str);

View File

@@ -7,11 +7,12 @@ x (A) Colisiones con los enemigos {cm:2022-08-29}
x (A) Decidir un diseño para qué sucede en caso de morir: Recordar el punto por donde se entró al mapa y la velocidad en el eje X/Y que llevaba el personaje, crear puntos de reaparicion en las habitaciones, etc {cm:2022-08-29} x (A) Decidir un diseño para qué sucede en caso de morir: Recordar el punto por donde se entró al mapa y la velocidad en el eje X/Y que llevaba el personaje, crear puntos de reaparicion en las habitaciones, etc {cm:2022-08-29}
x En el Jet Set Willy el juego recuerda la posicion y el momento. En las Tres Luces de Glaurung solo la posición. Se va a optar por seguir el diseño del Jet Set Willy {cm:2022-08-29} x En el Jet Set Willy el juego recuerda la posicion y el momento. En las Tres Luces de Glaurung solo la posición. Se va a optar por seguir el diseño del Jet Set Willy {cm:2022-08-29}
x (A) Crear tiles que maten {cm:2022-08-29} x (A) Crear tiles que maten {cm:2022-08-29}
(A) Modificar el salto para que coincida con el del JSW, no ha de colisionar lateralmente x (A) Modificar el salto para que coincida con el del JSW, no ha de colisionar lateralmente
(A) Crear tiles que deslicen, (no tipo hielo sino cinta) (A) Crear tiles que arrastren, tipo cinta transportadora
(A) Tiles animados (A) Tiles animados
(A) Crear ascensores (A) Crear ascensores
x (A) Crear rampas
x (A) Enemigos de diferente tamaño {cm:2022-08-30} x (A) Enemigos de diferente tamaño {cm:2022-08-30}
(A) Color de los items al estilo jet set willy de amstrad, que brillan con dos colores (A) Color de los items al estilo jet set willy de amstrad, que brillan con dos colores
x (A) Temporizador de inicio de los items, para poder hacer que brillen a distinto ritmo. Esto es incompatible con lo anterior {cm:2022-08-30} x (A) Temporizador de inicio de los items, para poder hacer que brillen a distinto ritmo. Esto es incompatible con lo anterior {cm:2022-08-30}
@@ -23,16 +24,17 @@ x (A) Tecla F para pasar a pantalla completa {cm:2022-08-30}
x (A) Tecla + y - para cambiar tamaño de ventana. O control F1 a F4 {cm:2022-08-30} x (A) Tecla + y - para cambiar tamaño de ventana. O control F1 a F4 {cm:2022-08-30}
(A) Poner en el marcador el indicador de si esta sonando la música (A) Poner en el marcador el indicador de si esta sonando la música
(A) Poner en el marcador el numero de habitaciones visitadas (A) Poner en el marcador el numero de habitaciones visitadas
(A) Añadir a cada habitación el color del borde (A) Los textos del marcador de colores
(A) Añadir a cada habitación el color del nombre de la habitación x (A) Añadir a cada habitación el color del borde
x (A) Añadir a cada habitación el color del nombre de la habitación
(A) Crear el logo al estilo del logo de ERBE o TOPO, con lineas que lo formen x (A) Crear el logo al estilo del logo de ERBE o TOPO, con lineas que lo formen
(A) El titulo del juego hacerlo parecido al del Jet Set Willy in Paris x (A) El titulo del juego hacerlo parecido al del Jet Set Willy in Paris
- Ha de generarse como las cargas de pantalla de spectrum x - Ha de generarse como las cargas de pantalla de spectrum
- Luego se colorea x - Luego se colorea
- Finalmente, cada elemento cambia de color como si fueran luces de neon x - Finalmente, cada elemento cambia de color como si fueran luces de neon
(A) En el titulo del juego, por la parte inferior ha de aparecer una marquesina con texto, al estilo demoscene x (A) En el titulo del juego, por la parte inferior ha de aparecer una marquesina con texto, al estilo demoscene
(A) La pantalla de titulo no tiene menu, solo un PRESS ENTER TO PLAY x (A) La pantalla de titulo no tiene menu, solo un PRESS ENTER TO PLAY
## TEMAS ## TEMAS