Compare commits

...

13 Commits
v0.1 ... v0.4

16 changed files with 683 additions and 70 deletions

View File

@@ -1,4 +1,3 @@
id=1
name=Test Room name=Test Room
bg_color=black bg_color=black
tileset=room1.png tileset=room1.png
@@ -6,7 +5,10 @@ room_up=0
room_down=0 room_down=0
room_left=0 room_left=0
room_right=02.room room_right=02.room
tilemap=41,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,41,41,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,41,41,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,41,41,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,41,41,0,0,0,0,41,41,41,41,41,41,41,41,41,41,41,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,41,41,0,0,41,41,41,41,41,0,0,0,0,0,0,0,0,0,81,0,0,0,0,0,0,0,0,0,0,0,0,0,41,41,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,41,41,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,41,41,0,0,0,0,0,0,0,0,0,0,0,0,41,41,41,41,0,0,0,0,0,0,0,0,0,0,0,41,41,41,41,41,41,41,41,0,0,0,0,0,0,0,0,0,41,41,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,41,41,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,41,0,0,0,0,0,41,41,0,0,0,0,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,0,0,0,0,0,41,0,0,0,0,0,0,0,0,0,81,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,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41
[tilemap]
room1.tmx
[tilemap-end]
[enemy] [enemy]
tileset=enemy01.png tileset=enemy01.png
@@ -34,4 +36,9 @@ y2=72
color=yellow color=yellow
[enemy-end] [enemy-end]
item=1,10,10 [item]
tileset=items.png
tile=1
x=10
y=10
[item-end]

View File

@@ -1,4 +1,3 @@
id=2
name=Test Room 2 name=Test Room 2
bg_color=black bg_color=black
tileset=room1.png tileset=room1.png
@@ -6,7 +5,7 @@ room_up=0
room_down=0 room_down=0
room_left=01.room room_left=01.room
room_right=0 room_right=0
tilemap=43,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,43,43,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,43,43,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,43,43,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,43,43,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,43,43,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,43,43,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,43,43,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,43,43,43,43,43,0,0,0,0,0,0,0,0,0,43,43,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,43,43,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,43,43,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,43,43,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,43,0,0,0,0,0,0,0,83,83,83,83,83,83,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,83,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,63,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63
enemy=1,0,0,0,1 [tilemap]
enemy=2,10,0,0,1 room2.tmx
item=1,10,10 [tilemap-end]

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

@@ -0,0 +1,24 @@
<?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">
<tileset firstgid="1" source="../../resources/tilesets/room1.tsx"/>
<layer id="1" name="Capa de patrones 1" width="32" height="16">
<data encoding="csv">
41,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,41,
41,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,41,
41,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,41,
41,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,41,
41,0,0,0,0,41,41,41,41,41,41,41,41,41,41,41,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,41,
41,0,0,41,41,41,41,41,0,0,0,0,0,0,0,0,0,81,0,0,0,0,0,0,0,0,0,0,0,0,0,41,
41,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,41,
41,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,41,41,0,0,0,0,0,0,0,0,0,0,0,0,41,
41,41,41,0,0,0,0,0,0,0,0,0,0,0,41,41,41,41,41,41,41,41,0,0,0,0,0,0,0,0,0,41,
41,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,41,
41,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,41,0,0,0,0,0,41,
41,0,0,0,0,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,0,0,0,0,0,41,
0,0,0,0,0,0,0,0,0,81,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,
41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,
41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41
</data>
</layer>
</map>

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

@@ -0,0 +1,24 @@
<?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">
<tileset firstgid="1" source="../../resources/tilesets/room1.tsx"/>
<layer id="1" name="Capa de patrones 1" width="32" height="16">
<data encoding="csv">
43,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,43,
43,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,43,
43,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,43,
43,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,43,
43,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,43,
43,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,43,
43,0,0,0,0,0,0,0,0,0,0,83,83,83,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,43,
43,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,43,43,43,43,43,0,0,0,0,0,0,0,0,0,43,
43,0,0,0,0,0,0,0,0,83,0,0,0,0,0,0,0,0,0,3,0,0,0,0,83,83,0,0,0,0,0,43,
43,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,43,
43,0,0,0,0,0,0,0,0,83,0,0,0,0,0,0,0,0,0,3,0,0,0,0,83,83,0,0,0,0,0,43,
43,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,43,
0,0,0,0,0,0,0,83,83,83,83,83,83,0,0,0,0,0,0,3,0,0,0,0,83,83,0,0,0,0,0,0,
0,0,0,0,0,83,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,
63,43,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,43,43,43,43,43,43,43,43,43,43,43,63,
63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63
</data>
</layer>
</map>

BIN
media/player/player01.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 222 B

View File

@@ -29,9 +29,9 @@ const int VIEW_HEIGHT = SCREEN_HEIGHT * 3;
// Zona de juego // Zona de juego
const int PLAY_AREA_TOP = (0 * BLOCK); const int PLAY_AREA_TOP = (0 * BLOCK);
const int PLAY_AREA_BOTTOM = GAMECANVAS_HEIGHT - (4 * BLOCK); const int PLAY_AREA_BOTTOM = (16 * BLOCK);
const int PLAY_AREA_LEFT = (0 * BLOCK); const int PLAY_AREA_LEFT = (0 * BLOCK);
const int PLAY_AREA_RIGHT = GAMECANVAS_WIDTH - (0 * BLOCK); const int PLAY_AREA_RIGHT = (32 * BLOCK);
const int PLAY_AREA_WIDTH = PLAY_AREA_RIGHT - PLAY_AREA_LEFT; const int PLAY_AREA_WIDTH = PLAY_AREA_RIGHT - PLAY_AREA_LEFT;
const int PLAY_AREA_HEIGHT = PLAY_AREA_BOTTOM - PLAY_AREA_TOP; const int PLAY_AREA_HEIGHT = PLAY_AREA_BOTTOM - PLAY_AREA_TOP;
const int PLAY_AREA_CENTER_X = PLAY_AREA_LEFT + (PLAY_AREA_WIDTH / 2); const int PLAY_AREA_CENTER_X = PLAY_AREA_LEFT + (PLAY_AREA_WIDTH / 2);
@@ -41,6 +41,11 @@ const int PLAY_AREA_CENTER_Y = PLAY_AREA_TOP + (PLAY_AREA_HEIGHT / 2);
const int PLAY_AREA_FIRST_QUARTER_Y = PLAY_AREA_HEIGHT / 4; const int PLAY_AREA_FIRST_QUARTER_Y = PLAY_AREA_HEIGHT / 4;
const int PLAY_AREA_THIRD_QUARTER_Y = (PLAY_AREA_HEIGHT / 4) * 3; const int PLAY_AREA_THIRD_QUARTER_Y = (PLAY_AREA_HEIGHT / 4) * 3;
#define BORDER_TOP 0
#define BORDER_RIGHT 1
#define BORDER_BOTTOM 2
#define BORDER_LEFT 3
// Anclajes de pantalla // Anclajes de pantalla
const int GAMECANVAS_CENTER_X = GAMECANVAS_WIDTH / 2; const int GAMECANVAS_CENTER_X = GAMECANVAS_WIDTH / 2;
const int GAMECANVAS_FIRST_QUARTER_X = GAMECANVAS_WIDTH / 4; const int GAMECANVAS_FIRST_QUARTER_X = GAMECANVAS_WIDTH / 4;

View File

@@ -198,8 +198,11 @@ void Director::setFileList()
mAsset->add("/data/config.bin", data, false); mAsset->add("/data/config.bin", data, false);
mAsset->add("/data/room/01.room", room); mAsset->add("/data/room/01.room", room);
mAsset->add("/data/room/02.room", room); mAsset->add("/data/room/02.room", room);
mAsset->add("/data/room/room1.tmx", room);
mAsset->add("/data/room/room2.tmx", room);
mAsset->add("/media/tilesets/room1.png", bitmap); mAsset->add("/media/tilesets/room1.png", bitmap);
mAsset->add("/media/enemies/enemy01.png", bitmap); mAsset->add("/media/enemies/enemy01.png", bitmap);
mAsset->add("/media/player/player01.png", bitmap);
} }
// Carga el fichero de configuración // Carga el fichero de configuración

View File

@@ -9,8 +9,10 @@ Game::Game(SDL_Window *window, SDL_Renderer *renderer, Asset *asset, Lang *lang,
mLang = lang; mLang = lang;
mInput = input; mInput = input;
// Crea los objetos
mScreen = new Screen(window, renderer); mScreen = new Screen(window, renderer);
mRoom = new Room(mAsset->get("01.room"), mRenderer, mAsset); mRoom = new Room(mAsset->get("01.room"), mRenderer, mAsset);
mPlayer = new Player(mAsset->get("player01.png"), mRenderer, mAsset, mInput, mRoom);
mEventHandler = new SDL_Event(); mEventHandler = new SDL_Event();
mTextureText = new LTexture(); mTextureText = new LTexture();
mText = new Text(mAsset->get("smb2.txt"), mTextureText, renderer); mText = new Text(mAsset->get("smb2.txt"), mTextureText, renderer);
@@ -19,11 +21,13 @@ Game::Game(SDL_Window *window, SDL_Renderer *renderer, Asset *asset, Lang *lang,
Game::~Game() Game::~Game()
{ {
// Borra las referencias a los punteros
mRenderer = nullptr; mRenderer = nullptr;
mAsset = nullptr; mAsset = nullptr;
mLang = nullptr; mLang = nullptr;
mInput = nullptr; mInput = nullptr;
// Libera la memoria de los objetos
delete mEventHandler; delete mEventHandler;
mEventHandler = nullptr; mEventHandler = nullptr;
@@ -37,6 +41,9 @@ Game::~Game()
delete mRoom; delete mRoom;
mRoom = nullptr; mRoom = nullptr;
delete mRoom;
mRoom = nullptr;
delete mText; delete mText;
mText = nullptr; mText = nullptr;
@@ -106,8 +113,11 @@ void Game::update()
} }
} }
checkInput();
mRoom->update(); mRoom->update();
mPlayer->update();
checkPlayerAndWalls(); // Debe ir detras del player update, por si se ha metido en algun muro
checkPlayerOnBorder();
checkPlayerOnFloor();
} }
} }
@@ -115,36 +125,55 @@ void Game::update()
void Game::draw() void Game::draw()
{ {
// Prepara para dibujar el frame // Prepara para dibujar el frame
const color_t color = {0xAA, 0x55, 0x55};
mScreen->start(); mScreen->start();
mScreen->clean(color);
mScreen->clean(mRoom->getBGColor()); mScreen->clean(mRoom->getBGColor());
mRoom->drawMap(); mRoom->drawMap();
mRoom->drawEnemies(); mRoom->drawEnemies();
mPlayer->draw();
// Texto en el centro de la pantalla // Texto en el centro de la pantalla
mText->writeCentered(GAMECANVAS_CENTER_X, 18 * 8, mRoom->getName()); SDL_Rect rect = {0, 16 * 8, PLAY_AREA_RIGHT, 8};
color_t color = stringToColor("light_black");
SDL_SetRenderDrawColor(mRenderer, color.r, color.g, color.b, 0xFF);
SDL_RenderFillRect(mRenderer, &rect);
mText->writeCentered(GAMECANVAS_CENTER_X, 16 * 8, mRoom->getName());
// Debug info
std::string text;
text = "status: " + std::to_string(mPlayer->status);
mText->write(0, 17 * 8, text);
text = "foot: " + std::to_string((int)mPlayer->getLeftFoot().y);
mText->write(0, 18 * 8, text);
const int a = (mPlayer->lastPosition.y + 16) / 8;
const int b = mPlayer->getLeftFoot().y / 8;
text = "tile: " + std::to_string(a) + " - " + std::to_string(b);
mText->write(0, 19 * 8, text);
// Actualiza la pantalla // Actualiza la pantalla
mScreen->blit(); mScreen->blit();
} }
// Comprueba la entrada // Comprueba la entrada
/*
void Game::checkInput() void Game::checkInput()
{ {
if (mInput->checkInput(INPUT_UP, REPEAT_FALSE)) if (mInput->checkInput(INPUT_UP, REPEAT_FALSE))
changeRoom(mRoom->getRoomUp()); changeRoom(mRoom->getRoomUp());
if (mInput->checkInput(INPUT_DOWN, REPEAT_FALSE)) if (mInput->checkInput(INPUT_DOWN, REPEAT_FALSE))
changeRoom(mRoom->getRoomDown()); changeRoom(mRoom->getRoomDown());
if (mInput->checkInput(INPUT_LEFT, REPEAT_FALSE)) if (mInput->checkInput(INPUT_LEFT, REPEAT_FALSE))
changeRoom(mRoom->getRoomLeft()); changeRoom(mRoom->getRoomLeft());
if (mInput->checkInput(INPUT_RIGHT, REPEAT_FALSE)) if (mInput->checkInput(INPUT_RIGHT, REPEAT_FALSE))
changeRoom(mRoom->getRoomRight()); changeRoom(mRoom->getRoomRight());
} }
*/
// Cambia de habitación // Cambia de habitación
bool Game::changeRoom(std::string file) bool Game::changeRoom(std::string file)
@@ -165,6 +194,97 @@ bool Game::changeRoom(std::string file)
success = true; success = true;
} }
return success; return success;
}
// Comprueba si el jugador esta en el borde de la pantalla
void Game::checkPlayerOnBorder()
{
if (mPlayer->getOnBorder())
{
if (changeRoom(mRoom->getRoom(mPlayer->getBorder())))
{
mPlayer->switchBorders();
}
}
}
// 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
const int a = (mPlayer->lastPosition.y + 16) / 8;
const int b = mPlayer->getLeftFoot().y / 8;
const bool tile_change = a != b;
const bool is_not_going_up = mPlayer->getVelY() >= 0;
const bool is_tile_aligned = mPlayer->getLeftFoot().y % 8 == 0;
if (((is_not_going_up) && (is_tile_aligned)) || ((is_not_going_up) && (tile_change)))
{
bool test = false;
test |= (mRoom->getTile(mPlayer->getLeftFoot()) == TILE_SOLID);
test |= (mRoom->getTile(mPlayer->getRightFoot()) == TILE_SOLID);
test |= (mRoom->getTile(mPlayer->getLeftFoot()) == TILE_TRAVESSABLE);
test |= (mRoom->getTile(mPlayer->getRightFoot()) == TILE_TRAVESSABLE);
// Tiene uno de los pies sobre una superficie
if (test)
{
mPlayer->setStatus(STATUS_STANDING);
// Si ha habido un cambio de tile, hay que recolocarlo
if (tile_change)
{
int offset = (int)mPlayer->sprite->getPosY() % 8;
mPlayer->sprite->setPosY((int)mPlayer->sprite->getPosY() - offset);
}
}
// Tiene ambos pies sobre el vacío
else if (mPlayer->getStatus() != STATUS_JUMPING)
{
mPlayer->setStatus(STATUS_FALLING);
}
}
}
// Comprueba que el jugador no atraviese ninguna pared
void Game::checkPlayerAndWalls()
{
// Comprueba las cuatro esquinas de los dos tiles del jugador
const SDL_Rect rect = mPlayer->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};
bool test = false;
test |= (mRoom->getTile(p1) == TILE_SOLID);
test |= (mRoom->getTile(p2) == TILE_SOLID);
test |= (mRoom->getTile(p3) == TILE_SOLID);
test |= (mRoom->getTile(p4) == TILE_SOLID);
test |= (mRoom->getTile(p5) == TILE_SOLID);
test |= (mRoom->getTile(p6) == TILE_SOLID);
test |= (mRoom->getTile(p7) == TILE_SOLID);
test |= (mRoom->getTile(p8) == TILE_SOLID);
if (test)
{
// Si hay colisión, deshace el movimiento y lo pone en modo caída
mPlayer->undoLastMove();
mPlayer->setStatus(STATUS_FALLING);
}
} }

View File

@@ -2,7 +2,6 @@
#include "ifdefs.h" #include "ifdefs.h"
#include "const.h" #include "const.h"
#include "utils.h" #include "utils.h"
#include "sprite.h" #include "sprite.h"
#include "movingsprite.h" #include "movingsprite.h"
#include "text.h" #include "text.h"
@@ -14,6 +13,7 @@
#include "screen.h" #include "screen.h"
#include "asset.h" #include "asset.h"
#include "room.h" #include "room.h"
#include "player.h"
#include "jail_audio.h" #include "jail_audio.h"
#ifndef GAME_H #ifndef GAME_H
@@ -27,6 +27,7 @@ private:
SDL_Event *mEventHandler; // Manejador de eventos SDL_Event *mEventHandler; // Manejador de eventos
Screen *mScreen; // Objeto encargado de manejar el renderizador Screen *mScreen; // Objeto encargado de manejar el renderizador
Room *mRoom; // Objeto encargado de gestionar cada habitación del juego Room *mRoom; // Objeto encargado de gestionar cada habitación del juego
Player *mPlayer; // Objeto con el jugador
Asset *mAsset; // Objeto con la ruta a todos los ficheros de recursos Asset *mAsset; // Objeto con la ruta a todos los ficheros de recursos
Lang *mLang; // Objeto para gestionar los textos en diferentes idiomas Lang *mLang; // Objeto para gestionar los textos en diferentes idiomas
Input *mInput; // Objeto pata gestionar la entrada Input *mInput; // Objeto pata gestionar la entrada
@@ -49,12 +50,21 @@ private:
// Pinta los objetos en pantalla // Pinta los objetos en pantalla
void draw(); void draw();
// Comprueba la entrada // Comprueba la entrada y actua
void checkInput(); //void checkInput();
// Cambia de habitación // Cambia de habitación
bool changeRoom(std::string file); bool changeRoom(std::string file);
// Comprueba si el jugador esta en el borde de la pantalla y actua
void checkPlayerOnBorder();
// Comprueba si el jugador esta sobre el suelo
void checkPlayerOnFloor();
// Comprueba que el jugador no atraviese ninguna pared
void checkPlayerAndWalls();
public: public:
// Constructor // Constructor
Game(SDL_Window *window, SDL_Renderer *renderer, Asset *asset, Lang *lang, Input *input); Game(SDL_Window *window, SDL_Renderer *renderer, Asset *asset, Lang *lang, Input *input);

View File

@@ -30,9 +30,12 @@ void MovingSprite::clear()
mAngle = 0.0; // Angulo para dibujarlo mAngle = 0.0; // Angulo para dibujarlo
mRotate = false; // Indica si ha de rotar mRotate = false; // Indica si ha de rotar
mCenter = {0, 0}; // Centro de rotación
mRotateSpeed = 0; // Velocidad de giro mRotateSpeed = 0; // Velocidad de giro
mRotateAmount = 0.0; // Cantidad de grados a girar en cada iteración mRotateAmount = 0.0; // Cantidad de grados a girar en cada iteración
mCounter = 0; // Contador interno mCounter = 0; // Contador interno
mFlip = SDL_FLIP_NONE; // Establece como se ha de voltear el sprite
} }
// Iniciador // Iniciador
@@ -96,7 +99,7 @@ void MovingSprite::move()
void MovingSprite::render() void MovingSprite::render()
{ {
if (mEnabled) if (mEnabled)
mTexture->render(mRenderer, (int)mPosX, (int)mPosY, &mSpriteClip, mZoomW, mZoomH, mAngle); mTexture->render(mRenderer, (int)mPosX, (int)mPosY, &mSpriteClip, mZoomW, mZoomH, mAngle, &mCenter, mFlip);
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
@@ -283,4 +286,10 @@ void MovingSprite::update()
void MovingSprite::switchRotate() void MovingSprite::switchRotate()
{ {
mRotateAmount *= -1; mRotateAmount *= -1;
}
// Establece el valor de la variable
void MovingSprite::setFlip(SDL_RendererFlip flip)
{
mFlip = flip;
} }

View File

@@ -21,11 +21,13 @@ protected:
float mZoomW; // Zoom aplicado a la anchura float mZoomW; // Zoom aplicado a la anchura
float mZoomH; // Zoom aplicado a la altura float mZoomH; // Zoom aplicado a la altura
double mAngle; // Angulo para dibujarlo double mAngle; // Angulo para dibujarlo
bool mRotate; // Indica si ha de rotar bool mRotate; // Indica si ha de rotar
Uint16 mRotateSpeed; // Velocidad de giro Uint16 mRotateSpeed; // Velocidad de giro
double mRotateAmount; // Cantidad de grados a girar en cada iteración double mRotateAmount; // Cantidad de grados a girar en cada iteración
Uint16 mCounter; // Contador interno Uint16 mCounter; // Contador interno
SDL_Point mCenter; // Centro de rotación
SDL_RendererFlip mFlip; // Indica como se voltea el sprite
public: public:
// Constructor // Constructor
@@ -132,6 +134,9 @@ public:
// Cambia el sentido de la rotación // Cambia el sentido de la rotación
void switchRotate(); void switchRotate();
// Establece el valor de la variable
void setFlip(SDL_RendererFlip flip);
}; };
#endif #endif

View File

@@ -2,12 +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(std::string _tileset, SDL_Renderer *_renderer, Asset *_asset) Player::Player(std::string _tileset, SDL_Renderer *_renderer, Asset *_asset, Input *_input, Room *_room)
{ {
// Obten punteros a objetos // Obten punteros a objetos
asset = _asset; asset = _asset;
renderer = _renderer; renderer = _renderer;
input = _input;
// Crea objetos // Crea objetos
texture = new LTexture(); texture = new LTexture();
@@ -18,6 +21,32 @@ Player::Player(std::string _tileset, SDL_Renderer *_renderer, Asset *_asset)
// Inicializa variables // Inicializa variables
color = stringToColor("white"); color = stringToColor("white");
onBorder = false;
border = BORDER_TOP;
jump_ini = 0;
status = STATUS_STANDING;
sprite->setPosX(2 * 8);
sprite->setPosX(10 * 8);
sprite->setPosY(12 * 8);
sprite->setPosY(6 * 8);
sprite->setVelX(0);
sprite->setVelY(0);
sprite->setWidth(8);
sprite->setHeight(16);
sprite->setCurrentFrame(0);
sprite->setAnimationCounter(0);
sprite->setAnimationNumFrames(0, 4);
sprite->setAnimationSpeed(0, 5);
sprite->setAnimationLoop(0, true);
sprite->setAnimationFrames(0, 0, 8 * 0, 0, 8, 16);
sprite->setAnimationFrames(0, 1, 8 * 1, 0, 8, 16);
sprite->setAnimationFrames(0, 2, 8 * 2, 0, 8, 16);
sprite->setAnimationFrames(0, 3, 8 * 3, 0, 8, 16);
sprite->setSpriteClip(sprite->getAnimationClip(0, 0));
lastPosition = getRect();
} }
// Destructor // Destructor
@@ -41,7 +70,208 @@ void Player::draw()
// 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
move(); // Recalcula la posición del jugador y su animación
checkBorders(); // Comprueba si está situado en alguno de los cuatro bordes de la habitación
applyGravity(); // Aplica gravedad al jugador
checkJump(); // Comprueba si ha finalizado el salto
}
// Comprueba las entradas y modifica variables
void Player::checkInput()
{
// Solo comprueba las entradas de dirección cuando está de pie
if ((input->checkInput(INPUT_LEFT, REPEAT_TRUE)) && (status == STATUS_STANDING))
{
sprite->setVelX(-0.6f);
sprite->setFlip(SDL_FLIP_HORIZONTAL);
}
else if ((input->checkInput(INPUT_RIGHT, REPEAT_TRUE)) && (status == STATUS_STANDING))
{
sprite->setVelX(0.6f);
sprite->setFlip(SDL_FLIP_NONE);
}
else if (status == STATUS_STANDING)
{
sprite->setVelX(0);
}
if (input->checkInput(INPUT_UP, REPEAT_FALSE))
{
setStatus(STATUS_JUMPING);
}
}
// Indica si el jugador esta en uno de los cuatro bordes de la pantalla
bool Player::getOnBorder()
{
return onBorder;
}
// Indica en cual de los cuatro bordes se encuentra
int Player::getBorder()
{
return border;
}
// Comprueba si está situado en alguno de los cuatro bordes de la habitación
void Player::checkBorders()
{
if (sprite->getPosX() < PLAY_AREA_LEFT)
{
border = BORDER_LEFT;
onBorder = true;
}
else if (sprite->getPosX() > PLAY_AREA_RIGHT - sprite->getWidth())
{
border = BORDER_RIGHT;
onBorder = true;
}
else if (sprite->getPosY() < PLAY_AREA_TOP)
{
border = BORDER_TOP;
onBorder = true;
}
else if (sprite->getPosY() > PLAY_AREA_BOTTOM - sprite->getHeight())
{
border = BORDER_BOTTOM;
onBorder = true;
}
else
{
onBorder = false;
}
}
// Cambia al jugador de un borde al opuesto. Util para el cambio de pantalla
void Player::switchBorders()
{
if (border == BORDER_TOP)
{
sprite->setPosY(PLAY_AREA_BOTTOM - sprite->getHeight() - 1);
}
else if (border == BORDER_BOTTOM)
{
sprite->setPosY(PLAY_AREA_TOP + 1);
}
else if (border == BORDER_RIGHT)
{
sprite->setPosX(PLAY_AREA_LEFT + 1);
}
if (border == BORDER_LEFT)
{
sprite->setPosX(PLAY_AREA_RIGHT - sprite->getWidth() - 1);
}
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
void Player::applyGravity()
{
if (status == STATUS_JUMPING)
{
sprite->setVelY(sprite->getVelY() + GRAVITY);
if (sprite->getVelY() > MAX_VY)
{
sprite->setVelY(MAX_VY);
}
}
}
// Obtiene el rectangulo que delimita al jugador
SDL_Rect Player::getRect()
{
SDL_Rect rect = {(int)sprite->getPosX(), (int)sprite->getPosY(), sprite->getWidth(), sprite->getHeight()};
return rect;
}
// 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
void Player::move()
{ {
sprite->update(); sprite->update();
sprite->animate(0); if (sprite->getVelX() != 0)
{
sprite->animate(0);
}
}
// Comprueba si ha finalizado el salto
void Player::checkJump()
{
if (status == STATUS_JUMPING)
if (sprite->getVelY() > 0)
if (sprite->getPosY() > jump_ini)
{
status = STATUS_FALLING;
}
} }

View File

@@ -1,28 +1,67 @@
#pragma once #pragma once
#include "ifdefs.h" #include "ifdefs.h"
#include "const.h"
#include "utils.h" #include "utils.h"
#include "asset.h" #include "asset.h"
#include "room.h"
#include "animatedsprite.h" #include "animatedsprite.h"
#include "input.h"
#include <string> #include <string>
#ifndef PLAYER_H #ifndef PLAYER_H
#define PLAYER_H #define PLAYER_H
//#define VX 0.6
#define STATUS_STANDING 0
#define STATUS_JUMPING 1
#define STATUS_FALLING 2
#define GRAVITY 0.035f
#define MAX_VY 1.2f
// Clase Player // Clase Player
class Player class Player
{ {
private: private:
LTexture *texture; // Textura con los graficos del enemigo LTexture *texture; // Textura con los graficos del enemigo
AnimatedSprite *sprite; // Sprite del enemigo Input *input; // Objeto para gestionar la entrada
SDL_Renderer *renderer; // El renderizador de la ventana SDL_Renderer *renderer; // El renderizador de la ventana
Asset *asset; // Objeto con la ruta a todos los ficheros de recursos Asset *asset; // Objeto con la ruta a todos los ficheros de recursos
color_t color; // Color del jugador color_t color; // Color del jugador
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
// Comprueba las entradas y modifica variables
void checkInput();
// Comprueba si se halla en alguno de los cuatro bordes
void checkBorders();
// Asigna velocidad negativa en el eje Y al jugador
void jump();
// Aplica gravedad al jugador
void applyGravity();
// Guarda la posición actual en la variable lastPosition
void setLastPosition();
// Recalcula la posición del jugador y su animación
void move();
// Comprueba si ha finalizado el salto
void checkJump();
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(std::string _tileset, SDL_Renderer *_renderer, Asset *_asset); Player(std::string _tileset, SDL_Renderer *_renderer, Asset *_asset, Input *_input, Room *_room);
// Destructor // Destructor
~Player(); ~Player();
@@ -32,6 +71,36 @@ public:
// Actualiza las variables del objeto // Actualiza las variables del objeto
void update(); void update();
// Indica si el jugador esta en uno de los cuatro bordes de la pantalla
bool getOnBorder();
// Indica en cual de los cuatro bordes se encuentra
int getBorder();
// Cambia al jugador de un borde al opuesto. Util para el cambio de pantalla
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
SDL_Rect getRect();
// Deshace el ultimo movimiento
void undoLastMove();
}; };
#endif #endif

View File

@@ -56,7 +56,7 @@ bool Room::load(std::string _file_path)
printf("Reading file %s\n", filename.c_str()); printf("Reading file %s\n", filename.c_str());
while (std::getline(file, line)) while (std::getline(file, line))
{ {
// Si la linea contiene el texto [enemy] se realiza un proceso distinto // Si la linea contiene el texto [enemy] se realiza el proceso de carga de un enemigo
if (line == "[enemy]") if (line == "[enemy]")
{ {
enemy_t enemy; enemy_t enemy;
@@ -80,6 +80,84 @@ bool Room::load(std::string _file_path)
// Añade el enemigo al vector de enemigos // Añade el enemigo al vector de enemigos
enemy_list.push_back(new Enemy(enemy)); enemy_list.push_back(new Enemy(enemy));
} }
// Si la linea contiene el texto [tilemap] se realiza el proceso de carga del fichero tmx
else if (line == "[tilemap]")
{
//printf("Loading tilemap...\n");
do
{
std::getline(file, line);
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
if (file2.good())
{
bool data_read = false;
while (std::getline(file2, line)) // Lee el fichero linea a linea
{
if (!data_read)
{ // Lee lineas hasta que encuentre donde empiezan los datos del mapa
int pos = 0;
do
{
std::getline(file2, line);
//printf("parsing: %s\n", line.c_str());
pos = line.find("data encoding");
//printf("pos: %i\n", pos);
} while (pos == std::string::npos);
do
{ // Se introducen los valores separados por comas en un vector
data_read = true;
std::getline(file2, line);
if (line != "</data>")
{
//printf("data: %s\n", line.c_str());
std::stringstream ss(line);
std::string tmp;
while (getline(ss, tmp, ','))
{
//printf("tile: %s\n", tmp.c_str());
tilemap.push_back(std::stoi(tmp));
}
}
} while (line != "</data>");
}
}
}
}
} while (line != "[tilemap-end]");
}
// Si la linea contiene el texto [item] se realiza el proceso de carga de un item
else if (line == "[item]")
{
// enemy_t enemy;
// enemy.asset = asset;
// enemy.renderer = renderer;
do
{
std::getline(file, line);
// Encuentra la posición del caracter '='
int pos = line.find("=");
// Procesa las dos subcadenas
// if (!setEnemy(&enemy, line.substr(0, pos), line.substr(pos + 1, line.length())))
//{
// printf("Warning: file %s\n, unknown parameter \"%s\"\n", filename.c_str(), line.substr(0, pos).c_str());
// success = false;
//}
} while (line != "[item-end]");
// Añade el enemigo al vector de enemigos
// enemy_list.push_back(new Enemy(enemy));
}
// En caso contrario se parsea el fichero para buscar las variables y los valores // En caso contrario se parsea el fichero para buscar las variables y los valores
else else
{ {
@@ -114,11 +192,7 @@ bool Room::setVars(std::string _var, std::string _value)
// Indicador de éxito en la asignación // Indicador de éxito en la asignación
bool success = true; bool success = true;
if (_var == "id") if (_var == "name")
{
id = _value;
}
else if (_var == "name")
{ {
name = _value; name = _value;
} }
@@ -156,6 +230,9 @@ bool Room::setVars(std::string _var, std::string _value)
tilemap.push_back(std::stoi(tmp)); tilemap.push_back(std::stoi(tmp));
} }
} }
else if (_var == "")
{
}
else else
{ {
success = false; success = false;
@@ -210,6 +287,9 @@ bool Room::setEnemy(enemy_t *enemy, std::string _var, std::string _value)
{ {
enemy->color = stringToColor(_value); enemy->color = stringToColor(_value);
} }
else if (_var == "[enemy-end]")
{
}
else else
{ {
success = false; success = false;
@@ -281,26 +361,53 @@ void Room::update()
} }
} }
// Devuelve el valor de la variable // Devuelve la cadena del fichero de la habitación contigua segun el borde
std::string Room::getRoomUp() std::string Room::getRoom(int border)
{ {
return room_up; switch (border)
{
case BORDER_TOP:
return room_up;
break;
case BORDER_BOTTOM:
return room_down;
break;
case BORDER_RIGHT:
return room_right;
break;
case BORDER_LEFT:
return room_left;
break;
default:
break;
}
return "";
} }
// Devuelve el valor de la variable // Devuelve el tipo de tile que hay en ese pixel
std::string Room::getRoomDown() int Room::getTile(SDL_Point point)
{ {
return room_down; int pos = ((point.y / 8) * 32) + (point.x / 8);
} int tile = TILE_EMPTY;
// Devuelve el valor de la variable if (pos < 512)
std::string Room::getRoomLeft() {
{ // Los tiles entre el 1 y el 80 son solidos
return room_left; if ((tilemap[pos] > 0) && (tilemap[pos] < 81))
} {
return TILE_SOLID;
}
// Devuelve el valor de la variable // Los tiles mayores de 80 son atravesables
std::string Room::getRoomRight() if (tilemap[pos] > 80)
{ {
return room_right; return TILE_TRAVESSABLE;
} }
}
return tile;
}

View File

@@ -10,6 +10,10 @@
#ifndef ROOM_H #ifndef ROOM_H
#define ROOM_H #define ROOM_H
#define TILE_EMPTY 0
#define TILE_SOLID 1
#define TILE_TRAVESSABLE 2
/* /*
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 si que tendra lo siguiente:
@@ -28,7 +32,6 @@ LISTADO DE ITEMS (tipo, posicion)
class Room class Room
{ {
private: private:
std::string id; // Identificador
std::string name; // Nombre de la habitación std::string name; // Nombre de la habitación
color_t bg_color; // Color de fondo de la habitación color_t bg_color; // Color de fondo de la habitación
std::string room_up; // Identificador de la habitación que se encuentra arriba std::string room_up; // Identificador de la habitación que se encuentra arriba
@@ -78,17 +81,11 @@ public:
// Actualiza las variables y objetos de la habitación // Actualiza las variables y objetos de la habitación
void update(); void update();
// Devuelve el valor de la variable // Devuelve la cadena del fichero de la habitación contigua segun el borde
std::string getRoomUp(); std::string getRoom(int border);
// Devuelve el valor de la variable // Devuelve el tipo de tile que hay en ese pixel
std::string getRoomDown(); int getTile(SDL_Point point);
// Devuelve el valor de la variable
std::string getRoomLeft();
// Devuelve el valor de la variable
std::string getRoomRight();
}; };
#endif #endif

4
todo.txt Normal file
View File

@@ -0,0 +1,4 @@
[x] Hacer que deje de poder moverse tras el salto al alcanzar la misma posicion en altura que tenia cuando saltó
[x] Arreglar que no atraviese tiles atravaseables al caer muy rapido
[x] Leer los mapas directamente del archivo tmx
[ ] Crear la clase item