diff --git a/data/font/smb2.png b/data/font/smb2.png new file mode 100644 index 0000000..b11fade Binary files /dev/null and b/data/font/smb2.png differ diff --git a/data/font/smb2.txt b/data/font/smb2.txt new file mode 100644 index 0000000..a9c8655 --- /dev/null +++ b/data/font/smb2.txt @@ -0,0 +1,194 @@ +# box width +8 +# box height +8 +# 32 espacio ( ) +7 +# 33 ! +7 +# 34 " +7 +# 35 # +7 +# 36 $ +7 +# 37 % +7 +# 38 & +7 +# 39 ' +7 +# 40 ( +7 +# 41 ) +7 +# 42 * +7 +# 43 + +7 +# 44 , +7 +# 45 - +7 +# 46 . +7 +# 47 / +7 +# 48 0 +7 +# 49 1 +7 +# 50 2 +7 +# 51 3 +7 +# 52 4 +7 +# 53 5 +7 +# 54 6 +7 +# 55 7 +7 +# 56 8 +7 +# 57 9 +7 +# 58 : +7 +# 59 ; +7 +# 60 < +7 +# 61 = +7 +# 62 > +7 +# 63 ? +7 +# 64 @ +7 +# 65 A +7 +# 66 B +7 +# 67 C +7 +# 68 D +7 +# 69 E +7 +# 70 F +7 +# 71 G +7 +# 72 H +7 +# 73 I +7 +# 74 J +7 +# 75 K +7 +# 76 L +7 +# 77 M +7 +# 78 N +7 +# 79 O +7 +# 80 P +7 +# 81 Q +7 +# 82 R +7 +# 83 S +7 +# 84 T +7 +# 85 U +7 +# 86 V +7 +# 87 W +7 +# 88 X +7 +# 89 Y +7 +# 90 Z +7 +# 91 [ +7 +# 92 \ +7 +# 93 ] +7 +# 94 ^ +7 +# 95 _ +7 +# 96 ` +7 +# 97 a +7 +# 98 b +7 +# 99 c +7 +# 100 d +7 +# 101 e +7 +# 102 f +7 +# 103 g +7 +# 104 h +7 +# 105 i +7 +# 106 j +7 +# 107 k +7 +# 108 l +7 +# 109 m +7 +# 110 n +7 +# 111 o +7 +# 112 p +7 +# 113 q +7 +# 114 r +7 +# 115 s +7 +# 116 t +7 +# 117 u +7 +# 118 v +7 +# 119 w +7 +# 120 x +7 +# 121 y +7 +# 122 z +7 +# 123 { +7 +# 124 | +7 +# 125 } +7 +# 126 ~ +7 \ No newline at end of file diff --git a/source/asset.cpp b/source/asset.cpp index 21f1bba..761337f 100644 --- a/source/asset.cpp +++ b/source/asset.cpp @@ -83,7 +83,7 @@ bool Asset::checkFile(std::string path) const std::string filename = path.substr(path.find_last_of("\\/") + 1); SDL_RWops *file = SDL_RWFromFile(path.c_str(), "r+b"); - if (file != NULL) + if (file != nullptr) { result = "OK"; success = true; diff --git a/source/const.h b/source/const.h index 2571514..08a3e06 100644 --- a/source/const.h +++ b/source/const.h @@ -19,8 +19,10 @@ #define GAMECANVAS_HEIGHT 240 // Zona de juego -const int PLAY_AREA_TOP = (4 * BLOCK); -const int PLAY_AREA_BOTTOM = (30 * BLOCK); +const int PLAY_AREA_X = 0; +const int PLAY_AREA_Y = (4 * BLOCK); +const int PLAY_AREA_TOP = (0 * BLOCK); +const int PLAY_AREA_BOTTOM = (26 * BLOCK); const int PLAY_AREA_LEFT = (0 * BLOCK); const int PLAY_AREA_RIGHT = (40 * BLOCK); const int PLAY_AREA_WIDTH = PLAY_AREA_RIGHT - PLAY_AREA_LEFT; @@ -32,6 +34,16 @@ 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_THIRD_QUARTER_Y = (PLAY_AREA_HEIGHT / 4) * 3; +// Marcador +const int SCOREBOARD_X = 0; +const int SCOREBOARD_Y = 0; +const int SCOREBOARD_TOP = (0 * BLOCK); +const int SCOREBOARD_BOTTOM = (4 * BLOCK); +const int SCOREBOARD_LEFT = (0 * BLOCK); +const int SCOREBOARD_RIGHT = (40 * BLOCK); +const int SCOREBOARD_WIDTH = SCOREBOARD_RIGHT - SCOREBOARD_LEFT; +const int SCOREBOARD_HEIGHT = SCOREBOARD_BOTTOM - SCOREBOARD_TOP; + // Anclajes de pantalla const int GAMECANVAS_CENTER_X = GAMECANVAS_WIDTH / 2; const int GAMECANVAS_FIRST_QUARTER_X = GAMECANVAS_WIDTH / 4; diff --git a/source/game.cpp b/source/game.cpp index 80bf383..e127622 100644 --- a/source/game.cpp +++ b/source/game.cpp @@ -20,6 +20,12 @@ Game::Game(SDL_Renderer *renderer, Screen *screen, Asset *asset, Input *input, D enemyEngine = new EnemyEngine(renderer, asset, player, map, asset->get(map->getEnemyFile())); music = JA_LoadMusic(asset->get("music_surface.ogg").c_str()); + // Crea la textura para dibujar los sprites + spriteLayer = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, PLAY_AREA_WIDTH, PLAY_AREA_HEIGHT); + if (spriteLayer == nullptr) + printf("Error: map_layer0 could not be created!\nSDL Error: %s\n", SDL_GetError()); + SDL_SetTextureBlendMode(spriteLayer, SDL_BLENDMODE_BLEND); + // Inicializa variables ticks = 0; ticksSpeed = 15; @@ -36,6 +42,8 @@ Game::Game(SDL_Renderer *renderer, Screen *screen, Asset *asset, Input *input, D // Destructor Game::~Game() { + SDL_DestroyTexture(spriteLayer); + delete scoreboard; delete eventHandler; delete itemTracker; @@ -96,21 +104,58 @@ void Game::update() // Pinta los objetos en pantalla void Game::render() { + // Rellena las texturas + fillSpriteTexture(); + scoreboard->fillTexture(); + // Prepara para dibujar el frame screen->start(); screen->clean(); - // Dibuja los objetos - map->render(); - enemyEngine->render(); - player->render(); + // Dibuja la capa 0 + map->renderLayer0(); + + // Dibuja la capa 1 + map->renderLayer1(); + + // Dibuja la capa de sprites + renderSprites(); + + // Dibuja el marcador scoreboard->render(); + + // Dibuja la información de debug renderDebugInfo(); // Actualiza la pantalla screen->blit(); } +// Dibuja los sprites en la textura +void Game::fillSpriteTexture() +{ + // Cambia el puntero del renderizador a la textura y la limpia + SDL_SetRenderTarget(renderer, spriteLayer); + SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0x00); + SDL_RenderClear(renderer); + + // Dibuja los sprites en la textura + map->renderActors(); + enemyEngine->render(); + player->render(); + + // Vuelve a colocar el renderizador apuntando a la pantalla + SDL_SetRenderTarget(renderer, nullptr); +} + +// Dibuja los sprites +void Game::renderSprites() +{ + // Copia la textura al renderizador + SDL_Rect rect = {PLAY_AREA_X, PLAY_AREA_Y, PLAY_AREA_WIDTH, PLAY_AREA_HEIGHT}; + SDL_RenderCopy(renderer, spriteLayer, NULL, &rect); +} + // Comprueba los eventos de la cola void Game::checkEventHandler() { @@ -218,12 +263,13 @@ void Game::renderDebugInfo() } // Pinta mascaras - SDL_SetRenderDrawColor(renderer, 0, 255, 0, 128); + SDL_SetRenderDrawColor(renderer, 0, 255, 0, 192); SDL_Rect rect = player->sprite->getRect(); + rect.y += SCOREBOARD_HEIGHT; SDL_RenderFillRect(renderer, &rect); // Pinta el texto - debug->setPos({1, PLAY_AREA_TOP}); + debug->setPos({1, 1 + SCOREBOARD_HEIGHT}); debug->render(); } diff --git a/source/game.h b/source/game.h index 7269328..b2fd40f 100644 --- a/source/game.h +++ b/source/game.h @@ -32,6 +32,7 @@ private: ScoreBoard *scoreboard; // Objeto encargado de gestionar el marcador board_t board; // Estructura con los datos del marcador Debug *debug; // Objeto para gestionar la información de debug + SDL_Texture *spriteLayer; // Textura para dibujar los sprites section_t section; // Seccion actual dentro 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 @@ -43,6 +44,12 @@ private: // Pinta los objetos en pantalla void render(); + // Dibuja los sprites en la textura + void fillSpriteTexture(); + + // Copia la textura de sprites a la pantalla + void renderSprites(); + // Comprueba los eventos de la cola void checkEventHandler(); diff --git a/source/map.cpp b/source/map.cpp index 8a3363b..34365a4 100644 --- a/source/map.cpp +++ b/source/map.cpp @@ -22,11 +22,11 @@ Map::Map(std::string file, SDL_Renderer *renderer, Asset *asset, ItemTracker *it tileset_width = texture_tile->getWidth() / tile_size; // Crea las texturas para dibujar el mapa - map_layer0 = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT); + map_layer0 = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, PLAY_AREA_WIDTH, PLAY_AREA_HEIGHT); if (map_layer0 == NULL) printf("Error: map_layer0 could not be created!\nSDL Error: %s\n", SDL_GetError()); - map_layer1 = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT); + map_layer1 = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, PLAY_AREA_WIDTH, PLAY_AREA_HEIGHT); if (map_layer1 == NULL) printf("Error: map_layer1 could not be created!\nSDL Error: %s\n", SDL_GetError()); @@ -428,7 +428,7 @@ void Map::fillMapTexture() // con lo que esta pintando desde fuera de la textura clip.x = ((tilemap_l0[(y * map_width) + x] - 1) % tileset_width) * tile_size; clip.y = ((tilemap_l0[(y * map_width) + x] - 1) / tileset_width) * tile_size; - texture_tile->render(renderer, x * tile_size, (y * tile_size) + PLAY_AREA_TOP, &clip); + texture_tile->render(renderer, x * tile_size, y * tile_size, &clip); } } @@ -448,7 +448,7 @@ void Map::fillMapTexture() // con lo que esta pintando desde fuera de la textura clip.x = ((tilemap_l1[(y * map_width) + x] - 1) % tileset_width) * tile_size; clip.y = ((tilemap_l1[(y * map_width) + x] - 1) / tileset_width) * tile_size; - texture_tile->render(renderer, x * tile_size, (y * tile_size) + PLAY_AREA_TOP, &clip); + texture_tile->render(renderer, x * tile_size, y * tile_size, &clip); } } @@ -456,14 +456,33 @@ void Map::fillMapTexture() SDL_SetRenderTarget(renderer, nullptr); } -// Dibuja el mapa en pantalla +// Dibuja todos los elementos del mapa void Map::render() { - // Dibuja la textura con el mapa en pantalla - SDL_Rect rect = {0, 0, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT}; - SDL_RenderCopy(renderer, map_layer0, &rect, NULL); - SDL_RenderCopy(renderer, map_layer1, &rect, NULL); + renderLayer0(); + renderLayer1(); + renderActors(); +} +// Dibuja la capa 0 +void Map::renderLayer0() +{ + // Dibuja la textura con el mapa en pantalla + SDL_Rect rect = {PLAY_AREA_X, PLAY_AREA_Y, PLAY_AREA_WIDTH, PLAY_AREA_HEIGHT}; + SDL_RenderCopy(renderer, map_layer0, NULL, &rect); +} + +// Dibuja la capa 1 +void Map::renderLayer1() +{ + // Dibuja la textura con el mapa en pantalla + SDL_Rect rect = {PLAY_AREA_X, PLAY_AREA_Y, PLAY_AREA_WIDTH, PLAY_AREA_HEIGHT}; + SDL_RenderCopy(renderer, map_layer1, NULL, &rect); +} + +// Dibuja los actores +void Map::renderActors() +{ for (auto actor : actors) { actor->render(); @@ -487,7 +506,7 @@ e_tile_map Map::getTile(SDL_Point p) const int y = std::max(getPlayArea(b_top), (std::min(p.y, getPlayArea(b_bottom) - 1))); // Calcula el tile - const int tile = collisionmap[(((y + PLAY_AREA_TOP) / tile_size) * map_width) + (x / tile_size)]; + const int tile = collisionmap[((y / tile_size) * map_width) + (x / tile_size)]; // Las 8 primeras filas son tiles de fondo if (tile == 0) diff --git a/source/map.h b/source/map.h index 1bf6f8b..b39ae84 100644 --- a/source/map.h +++ b/source/map.h @@ -82,9 +82,18 @@ public: // Actualiza todas las variables void update(); - // Dibuja el objeto + // Dibuja todos los elementos del mapa void render(); + // Dibuja la capa 1 + void renderLayer0(); + + // Dibuja la capa 1 + void renderLayer1(); + + // Dibuja los actores + void renderActors(); + // Devuelve el tipo de tile que hay en un punto e_tile_map getTile(SDL_Point p); diff --git a/source/prog.cpp b/source/prog.cpp index fca745e..0a19e2f 100644 --- a/source/prog.cpp +++ b/source/prog.cpp @@ -405,6 +405,8 @@ bool Prog::setFileList() asset->add("/data/font/debug.txt", font); asset->add("/data/font/dogica.png", font); asset->add("/data/font/dogica.txt", font); + asset->add("/data/font/smb2.png", font); + asset->add("/data/font/smb2.txt", font); // Ficheros de enemigos asset->add("/data/actors/enemies/walking_eye.png", bitmap); diff --git a/source/scoreboard.cpp b/source/scoreboard.cpp index e365b33..e81800a 100644 --- a/source/scoreboard.cpp +++ b/source/scoreboard.cpp @@ -13,7 +13,13 @@ ScoreBoard::ScoreBoard(SDL_Renderer *renderer, Asset *asset, board_t *board) // Reserva memoria para los objetos texture = new LTexture(renderer, asset->get("player.png")); sprite = new Sprite({0, 0, 0, 0}, texture, renderer); - text = new Text(asset->get("dogica.png"), asset->get("dogica.txt"), renderer); + text = new Text(asset->get("smb2.png"), asset->get("smb2.txt"), renderer); + + // Crea la textura para dibujar el marcador + layer = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, SCOREBOARD_WIDTH, SCOREBOARD_HEIGHT); + if (layer == nullptr) + printf("Error: map_layer0 could not be created!\nSDL Error: %s\n", SDL_GetError()); + SDL_SetTextureBlendMode(layer, SDL_BLENDMODE_BLEND); // Inicializa las variables counter = 0; @@ -22,24 +28,37 @@ ScoreBoard::ScoreBoard(SDL_Renderer *renderer, Asset *asset, board_t *board) // Destructor ScoreBoard::~ScoreBoard() { + SDL_DestroyTexture(layer); + delete texture; delete sprite; delete text; } -// Pinta el objeto en pantalla -void ScoreBoard::render() +// Dibuja el marcador en la textura +void ScoreBoard::fillTexture() { - // Ponenegro el fondo del marcador - const SDL_Rect rect = {0, 0, PLAY_AREA_WIDTH, 2 * 8}; - SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); - SDL_RenderFillRect(renderer, &rect); + // Cambia el puntero del renderizador a la textura y la limpia + SDL_SetRenderTarget(renderer, layer); + SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0xFF); + SDL_RenderClear(renderer); // Escribe los textos text->writeCentered(PLAY_AREA_CENTER_FIRST_QUARTER_X, 1, "-LIVES-"); text->writeCentered(PLAY_AREA_CENTER_FIRST_QUARTER_X, 1 + text->getCharacterSize(), std::to_string(board->lives)); text->writeCentered(PLAY_AREA_CENTER_THIRD_QUARTER_X, 1, "-DIAMONDS-"); text->writeCentered(PLAY_AREA_CENTER_THIRD_QUARTER_X, 1 + text->getCharacterSize(), std::to_string(board->diamonds)); + + // Vuelve a colocar el renderizador apuntando a la pantalla + SDL_SetRenderTarget(renderer, nullptr); +} + +// Pinta el objeto en pantalla +void ScoreBoard::render() +{ + // Dibuja la textura con el marcador en pantalla + SDL_Rect rect = {SCOREBOARD_X, SCOREBOARD_Y, SCOREBOARD_WIDTH, SCOREBOARD_HEIGHT}; + SDL_RenderCopy(renderer, layer, NULL, &rect); } // Actualiza las variables del objeto diff --git a/source/scoreboard.h b/source/scoreboard.h index 5ed3cc3..fa441ae 100644 --- a/source/scoreboard.h +++ b/source/scoreboard.h @@ -24,6 +24,7 @@ private: LTexture *texture; // Textura con los graficos Sprite *sprite; // Sprite para mostrar los graficos SDL_Renderer *renderer; // El renderizador de la ventana + SDL_Texture *layer; // Textura donde dibujar el marcador Asset *asset; // Objeto con la ruta a todos los ficheros de recursos Text *text; // Objeto para escribir texto int counter; // Contador interno @@ -36,6 +37,9 @@ public: // Destructor ~ScoreBoard(); + // Dibuja el marcador en la textura + void fillTexture(); + // Pinta el objeto en pantalla void render();