Skip to content
Snippets Groups Projects
Commit cad058de authored by David Maul's avatar David Maul :crab:
Browse files

add support for units

parent 81d8ccef
Branches
No related tags found
1 merge request!5Spritesheet
#include "building.hpp"
#include "common.h"
#include "spritesheet.hpp"
namespace advanced_wars
{
namespace advanced_wars {
Building::Building(int x, int y, BuildingId id, Faction faction)
Building::Building(int x, int y, BuildingId id, BuildingFaction faction)
: x(x), y(y), id(id), faction(faction) {};
void Building::render(Engine &engine, std::vector<SDL_Event> &events)
{
void Building::render(Engine &engine, int scale) {
Spritesheet *spritesheet = engine.get_spritesheet();
SDL_Rect src;
......@@ -19,12 +16,14 @@ void Building::render(Engine &engine, std::vector<SDL_Event> &events)
src.h = spritesheet->get_building_height();
SDL_Rect dst;
dst.x = x * spritesheet->get_tile_width() * 3;
dst.y = (y - 1) * spritesheet->get_tile_height() * 3;
dst.w = spritesheet->get_building_width() * 3;
dst.h = spritesheet->get_building_height() * 3;
dst.x = x * spritesheet->get_tile_width() * scale;
dst.y = (y - 1) * spritesheet->get_tile_height() * scale;
dst.w = spritesheet->get_building_width() * scale;
dst.h = spritesheet->get_building_height() * scale;
SDL_RenderCopyEx(engine.renderer(), spritesheet->get_building_textures()[faction], &src, &dst, 0, NULL, SDL_FLIP_NONE);
SDL_RenderCopyEx(engine.renderer(),
spritesheet->get_building_textures()[faction], &src, &dst, 0,
NULL, SDL_FLIP_NONE);
}
} // namespace advanced_wars
\ No newline at end of file
#pragma once
#include "common.h"
#include "scene.hpp"
#include "engine.hpp"
#include "scene.hpp"
namespace advanced_wars {
enum BuildingFaction {
BRED = 0,
BBLUE = 1,
BYELLOW = 2,
BGREEN = 3,
BPURPLE = 4,
BNEUTRAL = 5,
};
enum BuildingId {
HEADQUARTER = 0,
CITY = 1,
......@@ -14,16 +22,16 @@ enum BuildingId {
SATELLITE = 4,
};
class Building : public Scene{
class Building {
public:
Building(int x, int y, BuildingId id, Faction faction);
Building(int x, int y, BuildingId id, BuildingFaction faction);
int x;
int y;
BuildingId id;
Faction faction;
BuildingFaction faction;
void render(Engine &engine, std::vector<SDL_Event> &events) override;
void render(Engine &engine, int scale);
};
} // namespace advanced_wars
\ No newline at end of file
#pragma once
enum Faction {
RED = 0,
BLUE = 1,
YELLOW = 2,
GREEN = 3,
PURPLE = 4,
NEUTRAL = 5,
};
......@@ -29,15 +29,18 @@ void Level::render(Engine &engine, std::vector<SDL_Event> &events) {
}
// Tiles
for(Tile t : tiles)
{
t.render(engine, events);
for (Tile tile : tiles) {
tile.render(engine, RENDERING_SCALE);
}
// Buildings
for (Building building : buildings)
{
building.render(engine, events);
for (Building building : buildings) {
building.render(engine, RENDERING_SCALE);
}
// Units
for (Unit unit : units) {
unit.render(engine, RENDERING_SCALE);
}
// Set background color for renderer
......
#include "building.hpp"
#include "common.h"
#include "engine.hpp"
#include "level.hpp"
#include "spritesheet.hpp"
#include "tile.hpp"
#include "unit.hpp"
#include "window.hpp"
#include <cstddef>
#include <vector>
......@@ -24,7 +24,6 @@ int main() {
}
}
// Fill the edges with water
for (size_t n = 0; n < 20; n++) {
// Vertical
......@@ -58,13 +57,24 @@ int main() {
for (int y = 0; y < 6; y++) {
for (int x = 0; x < 5; x++) {
BuildingId id = static_cast<BuildingId>(x);
Faction faction = static_cast<Faction>(y);
BuildingFaction faction = static_cast<BuildingFaction>(y);
buildings.push_back(Building(3 + x, 3 + 2 * y, id, faction));
}
}
Level level("Osnabrück", 20, 20, tiles, buildings, std::vector<Unit>());
// Units
std::vector<Unit> units;
for (int y = 0; y < 19; y++) {
for (int x = 0; x < 6; x++) {
units.push_back(Unit(x + 9, y + 2, UnitFaction::URED,
static_cast<UnitId>(y), static_cast<UnitState>(x)));
}
}
Level level("Osnabrück", 20, 20, tiles, buildings, units);
engine.set_scene(level);
......
#include "spritesheet.hpp"
#include "SDL_pixels.h"
#include "SDL_surface.h"
#include "building.hpp"
#include "common.h"
#include "engine.hpp"
#include "highfive/H5File.hpp"
#include "highfive/highfive.hpp"
#include <SDL_image.h>
#include <SDL_render.h>
#include <cstddef>
......@@ -71,10 +67,10 @@ Spritesheet::Spritesheet(std::string path, Engine &engine) {
this->tile_height = 16;
// Buildings
std::vector<std::string> factions(
std::vector<std::string> building_factions(
{"red", "blue", "yellow", "green", "purple", "neutral"});
for (std::string faction : factions) {
for (std::string faction : building_factions) {
HighFive::DataSet buildings_ds = file.getDataSet("buildings/" + faction);
std::vector<std::vector<std::vector<uint32_t>>> buildings_frames;
......@@ -119,6 +115,135 @@ Spritesheet::Spritesheet(std::string path, Engine &engine) {
this->building_width = 16;
this->building_height = 32;
// Units
std::vector<std::string> unit_factions(
{"red", "blue", "green", "yellow", "purple"});
std::vector<std::string> units(
{"infantery", "mechanized_infantery", "recon", "medium_tank",
"heavy_tank", "neo_tank", "apc", "anti_air_tank", "artillery",
"rocket_artillery", "anti_air_missile_launcher", "fighter", "bomber",
"battle_helicopter", "transport_helicopter", "battleship", "cruiser",
"lander", "submarine"});
std::vector<std::string> unit_states({"idle", "unavailable"});
std::vector<std::string> unit_movement_states(
{"left", "right", "down", "up"});
for (size_t faction_idx = 0; faction_idx < unit_factions.size();
faction_idx++) {
std::string faction = unit_factions.at(faction_idx);
// Create entry for units for in a faction
unit_textures.push_back(
std::vector<std::vector<std::pair<SDL_Texture *, int>>>());
for (size_t unit_idx = 0; unit_idx < units.size(); unit_idx++) {
std::string unit = units.at(unit_idx);
// Create entry for states for a unit
unit_textures.at(faction_idx)
.push_back(std::vector<std::pair<SDL_Texture *, int>>());
for (size_t state_idx = 0; state_idx < unit_states.size(); state_idx++) {
std::string unit_state = unit_states.at(state_idx);
HighFive::DataSet units_ds =
file.getDataSet("units/" + faction + "/" + unit + "/" + unit_state);
std::vector<std::vector<std::vector<uint32_t>>> unit_frames;
units_ds.read(unit_frames);
std::vector<uint32_t> unit_buffer(16 * 16 * unit_frames.size(), 0);
for (size_t n = 0; n < unit_frames.size(); n++) {
for (size_t y = 0; y < 16; y++) {
for (size_t x = 0; x < 16; x++) {
size_t index = (y * unit_frames.size() * 16) + (n * 16 + x);
unit_buffer.at(index) = unit_frames.at(n).at(16 - y - 1).at(x);
}
}
}
SDL_Texture *tmp = SDL_CreateTexture(
engine.renderer(), SDL_PIXELFORMAT_RGBA8888,
SDL_TEXTUREACCESS_STATIC, unit_frames.size() * 16, 16);
SDL_SetTextureBlendMode(tmp, SDL_BLENDMODE_BLEND);
if (tmp == nullptr) {
throw std::runtime_error(
"Fehler beim Erstellen der Textur für die Tiles: " +
std::string(SDL_GetError()));
}
if (SDL_UpdateTexture(tmp, NULL, unit_buffer.data(),
unit_frames.size() * 16 * sizeof(int32_t)) != 0) {
throw std::runtime_error(
"Fehler beim updaten der Textur für die Tiles: " +
std::string(SDL_GetError()));
}
unit_textures.at(faction_idx)
.at(unit_idx)
.push_back(std::pair<SDL_Texture *, int>(tmp, unit_frames.size()));
}
for (size_t movement_state_idx = 0;
movement_state_idx < unit_movement_states.size();
movement_state_idx++) {
std::string movement_state =
unit_movement_states.at(movement_state_idx);
HighFive::DataSet units_ds = file.getDataSet(
"units/" + faction + "/" + unit + "/movement/" + movement_state);
std::vector<std::vector<std::vector<uint32_t>>> unit_frames;
units_ds.read(unit_frames);
std::vector<uint32_t> unit_buffer(24 * 24 * unit_frames.size(), 0);
for (size_t n = 0; n < unit_frames.size(); n++) {
for (size_t y = 0; y < 24; y++) {
for (size_t x = 0; x < 24; x++) {
size_t index = (y * unit_frames.size() * 24) + (n * 24 + x);
unit_buffer.at(index) = unit_frames.at(n).at(24 - y - 1).at(x);
}
}
}
SDL_Texture *tmp = SDL_CreateTexture(
engine.renderer(), SDL_PIXELFORMAT_RGBA8888,
SDL_TEXTUREACCESS_STATIC, unit_frames.size() * 24, 24);
SDL_SetTextureBlendMode(tmp, SDL_BLENDMODE_BLEND);
if (tmp == nullptr) {
throw std::runtime_error(
"Fehler beim Erstellen der Textur für die Tiles: " +
std::string(SDL_GetError()));
}
if (SDL_UpdateTexture(tmp, NULL, unit_buffer.data(),
unit_frames.size() * 24 * sizeof(int32_t)) != 0) {
throw std::runtime_error(
"Fehler beim updaten der Textur für die Tiles: " +
std::string(SDL_GetError()));
}
unit_textures.at(faction_idx)
.at(unit_idx)
.push_back(std::pair<SDL_Texture *, int>(tmp, unit_frames.size()));
}
}
}
this->unit_width = 16;
this->unit_height = 16;
this->unit_moving_width = 24;
this->unit_moving_height = 24;
}
// Tiles
......@@ -137,10 +262,23 @@ int Spritesheet::get_building_width() { return this->building_width; }
int Spritesheet::get_building_height() { return this->building_height; }
std::vector<SDL_Texture*> Spritesheet::get_building_textures() {
std::vector<SDL_Texture *> &Spritesheet::get_building_textures() {
return building_textures;
}
// Units
int Spritesheet::get_unit_width() { return this->unit_width; }
int Spritesheet::get_unit_height() { return this->unit_height; }
int Spritesheet::get_unit_moving_width() { return this->unit_moving_width; }
int Spritesheet::get_unit_moving_height() { return this->unit_moving_height; }
std::vector<std::vector<std::vector<std::pair<SDL_Texture *, int>>>> &
Spritesheet::get_unit_textures() {
return this->unit_textures;
}
Spritesheet::~Spritesheet() { SDL_DestroyTexture(tile_texture); }
......
#pragma once
#include "common.h"
#include <SDL.h>
#include <SDL_render.h>
#include <string>
......@@ -32,14 +31,24 @@ public:
SDL_Texture *get_tile_texture();
// Buildings: TODO
// Buildings
int get_building_width();
int get_building_height();
std::vector<SDL_Texture*> get_building_textures();
std::vector<SDL_Texture *> &get_building_textures();
// Units
int get_unit_width();
int get_unit_height();
// Units: TODO
int get_unit_moving_width();
int get_unit_moving_height();
std::vector<std::vector<std::vector<std::pair<SDL_Texture *, int>>>> &
get_unit_textures();
private:
// Tiles
......@@ -52,5 +61,13 @@ private:
std::vector<SDL_Texture *> building_textures;
int building_width;
int building_height;
// Units
std::vector<std::vector<std::vector<std::pair<SDL_Texture *, int>>>>
unit_textures;
int unit_width;
int unit_height;
int unit_moving_width;
int unit_moving_height;
};
} // namespace advanced_wars
#include "tile.hpp"
#include "spritesheet.hpp"
#include <stdexcept>
#include <vector>
#include "spritesheet.hpp"
namespace advanced_wars {
......@@ -10,8 +10,7 @@ Tile::Tile(TileId id, int x, int y)
};
void Tile::render(Engine& engine, std::vector<SDL_Event>& events)
{
void Tile::render(Engine &engine, int scale) {
Spritesheet *spritesheet = engine.get_spritesheet();
int max_steps = spritesheet->get_tile_steps(static_cast<int>(id));
......@@ -27,19 +26,20 @@ void Tile::render(Engine& engine, std::vector<SDL_Event>& events)
int offset = tiles.at(id).first;
SDL_Rect src;
src.x = offset * spritesheet->get_tile_width() + step * spritesheet->get_tile_width();
src.x = offset * spritesheet->get_tile_width() +
step * spritesheet->get_tile_width();
src.y = 0;
src.w = spritesheet->get_tile_width();
src.h = spritesheet->get_tile_height();
SDL_Rect dest;
dest.x = x * spritesheet->get_tile_width() * 3;
dest.y = y * spritesheet->get_tile_height() * 3;
dest.w = spritesheet->get_tile_width() * 3;
dest.h = spritesheet->get_tile_height() * 3;
SDL_RenderCopyEx(engine.renderer(), spritesheet->get_tile_texture(), &src, &dest, 0, NULL, SDL_FLIP_NONE);
dest.x = x * spritesheet->get_tile_width() * scale;
dest.y = y * spritesheet->get_tile_height() * scale;
dest.w = spritesheet->get_tile_width() * scale;
dest.h = spritesheet->get_tile_height() * scale;
SDL_RenderCopyEx(engine.renderer(), spritesheet->get_tile_texture(), &src,
&dest, 0, NULL, SDL_FLIP_NONE);
}
} // namespace advanced_wars
\ No newline at end of file
#pragma once
#include "scene.hpp"
#include "engine.hpp"
#include "scene.hpp"
namespace advanced_wars {
......@@ -29,14 +29,14 @@ enum TileId {
CLIFF_INVERSE_CORNER_BOTTOM_RIGHT = 20,
};
class Tile : public Scene{
class Tile {
public:
Tile(TileId id, int x, int y);
TileId id;
int x;
int y;
void render(Engine &engine, std::vector<SDL_Event>& events) override;
void render(Engine &engine, int scale);
};
} // namespace advanced_wars
\ No newline at end of file
#include "unit.hpp"
#include <iostream>
Unit::Unit(int x, int y): x(x), y(y) {};
namespace advanced_wars {
Unit::Unit(int x, int y, UnitFaction faction, UnitId id, UnitState state)
: x(x), y(y), faction(faction), id(id), state(state) {
};
void Unit::render(Engine &engine, int scale) {
Spritesheet *spritesheet = engine.get_spritesheet();
int step = engine.get_stage() % spritesheet->get_unit_textures()
.at(static_cast<int>(faction))
.at(static_cast<int>(id))
.at(static_cast<int>(state))
.second;
if (state == UnitState::IDLE || state == UnitState::UNAVAILABLE) {
SDL_Rect src;
src.x = step * spritesheet->get_unit_width();
src.y = 0;
src.w = spritesheet->get_unit_width();
src.h = spritesheet->get_unit_height();
SDL_Rect dst;
dst.x = x * spritesheet->get_unit_width() * scale;
dst.y = y * spritesheet->get_unit_height() * scale;
dst.w = spritesheet->get_unit_width() * scale;
dst.h = spritesheet->get_unit_height() * scale;
SDL_RenderCopyEx(engine.renderer(),
spritesheet->get_unit_textures()
.at(static_cast<int>(faction))
.at(static_cast<int>(id))
.at(static_cast<int>(state))
.first,
&src, &dst, 0, NULL, SDL_FLIP_NONE);
} else {
// The moving states have a resolution of 24x24 instead of 16x16 and need to
// be handled separately
SDL_Rect src;
src.x = step * spritesheet->get_unit_moving_width();
src.y = 0;
src.w = spritesheet->get_unit_moving_width();
src.h = spritesheet->get_unit_moving_height();
SDL_Rect dst;
dst.x = ((x * spritesheet->get_unit_width()) - 4) * scale;
dst.y = ((y * spritesheet->get_unit_height()) - 4) * scale;
dst.w = spritesheet->get_unit_moving_width() * scale;
dst.h = spritesheet->get_unit_moving_height() * scale;
SDL_RenderCopyEx(engine.renderer(),
spritesheet->get_unit_textures()
.at(static_cast<int>(faction))
.at(static_cast<int>(id))
.at(static_cast<int>(state))
.first,
&src, &dst, 0, NULL, SDL_FLIP_NONE);
}
}
} // namespace advanced_wars
\ No newline at end of file
#ifndef UNIT_HPP
#define UNIT_HPP
#pragma once
#include "engine.hpp"
namespace advanced_wars {
enum UnitFaction {
URED = 0,
UBLUE = 1,
UGREEN = 2,
UYELLOW = 3,
UPURPLE = 4,
};
enum UnitId {
INFANTERY = 0,
MECHANIZED_INFANTERY = 1,
RECON = 2,
MEDIUM_TANK = 3,
HEAVY_TANK = 4,
NEO_TANK = 5,
APC = 6,
ANTI_AIR_TANK = 7,
ARTILLERY = 8,
ROCKET_ARTILLERY = 9,
ANTI_AIR_MISSILE_LAUNCHER = 10,
FIGHTER = 11,
BOMBER = 12,
BATTLE_HELICOPTER = 13,
TRANSPORT_HELICOPTER = 14,
BATTLESHIP = 15,
CRUISER = 16,
LANDER = 17,
SUBMARINE = 18,
};
enum UnitState {
IDLE = 0,
UNAVAILABLE = 1,
MOVEMENTLEFT = 2,
MOVEMENTRIGHT = 3,
MOVEMENTDOWN = 4,
MOVEMENTUP = 5,
};
class Unit {
public:
Unit(int x, int y);
Unit(int x, int y, UnitFaction faction, UnitId id, UnitState state);
void render(Engine &engine, int scale);
private:
// Position
int x;
int y;
UnitFaction faction;
UnitId id;
UnitState state;
};
#endif
} // namespace advanced_wars
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment