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

migrate spritesheet to hdf5 and implement basic animations

parent 1946b93b
Branches
No related tags found
1 merge request!5Spritesheet
......@@ -8,34 +8,32 @@
#include <iostream>
#include <string>
namespace advanced_wars
{
namespace advanced_wars {
Level::Level(std::string name, int width, int height, std::vector<Tile> tiles,
std::vector<Building> buildings, std::vector<Unit> units)
: name(name), width(width), height(height), buildings(buildings),
units(units) {
/* Commented for testing purposes
: name(name), width(width), height(height), tiles(tiles),
buildings(buildings), units(units) {
if ((size_t)(width * height) != tiles.size()) {
throw std::runtime_error("level tile mismatch");
}
*/
};
void Level::render(Engine &engine, std::vector<SDL_Event> &events)
{
void Level::render(Engine &engine, std::vector<SDL_Event> &events) {
const int RENDERING_SCALE = 3;
// Iterate over all events
while (!events.empty())
{
while (!events.empty()) {
events.erase(events.begin());
}
for (int y = 0; y < this->height; y++)
{
for (int x = 0; x < this->width; x++)
{
size_t idx = 0;
int stage = SDL_GetTicks() / 300;
for (int y = 0; y < this->height; y++) {
for (int x = 0; x < this->width; x++) {
Spritesheet *spritesheet = engine.get_spritesheet();
SDL_Rect dst;
......@@ -44,17 +42,21 @@ namespace advanced_wars
dst.w = spritesheet->get_tile_width() * RENDERING_SCALE;
dst.h = spritesheet->get_tile_height() * RENDERING_SCALE;
if (spritesheet->render_tile(engine.renderer(), 0, 0, &dst) != 0)
{
int tile_id = static_cast<int>(tiles.at(idx).id);
if (spritesheet->render_tile(engine.renderer(), tile_id,
stage % spritesheet->get_tile_steps(tile_id),
&dst) != 0) {
throw std::runtime_error("error while rendering a tile: " +
std::string(SDL_GetError()));
}
idx += 1;
}
}
// Set background color for renderer
if (SDL_SetRenderDrawColor(engine.renderer(), 255, 0, 0, 0))
{
if (SDL_SetRenderDrawColor(engine.renderer(), 255, 0, 0, 0)) {
std::cout << "Could not set render draw color: " << SDL_GetError()
<< std::endl;
}
......
......@@ -25,6 +25,7 @@ private:
std::string name;
int width;
int height;
std::vector<Tile> tiles;
std::vector<Building> buildings;
std::vector<Unit> units;
};
......
......@@ -7,24 +7,53 @@
using namespace advanced_wars;
int main()
{
int main() {
Window window("Advanced Wars", 960, 960);
Engine engine(window);
Level level("Osnabrück", 20, 20, std::vector<Tile>(), std::vector<Building>(),
// Construct a level
std::vector<Tile> tiles(20 * 20, Tile(TileId::PLAIN));
// Fill the edges with water
for (size_t n = 0; n < 20; n++) {
// Vertical
tiles.at(n * 20) = Tile(TileId::WATER);
tiles.at(n * 20 + 19) = Tile(TileId::WATER);
// Horizontal
tiles.at(n) = Tile(TileId::WATER);
tiles.at(19 * 20 + n) = Tile(TileId::WATER);
}
// Make the edges cliffs
for (size_t n = 1; n < 19; n++) {
// Vertical
tiles.at(n * 20 + 1) = Tile(TileId::CLIFF_RIGHT);
tiles.at(n * 20 + 18) = Tile(TileId::CLIFF_LEFT);
// Horizontal
tiles.at(20 + n) = Tile(TileId::CLIFF_BOTTOM);
tiles.at(18 * 20 + n) = Tile(TileId::CLIFF_TOP);
}
// Fix the corners
tiles.at(20 + 1) = Tile(TileId::CLIFF_CORNER_TOP_LEFT);
tiles.at(20 + 18) = Tile(TileId::CLIFF_CORNER_TOP_RIGHT);
tiles.at(18 * 20 + 1) = Tile(TileId::CLIFF_CORNER_BOTTOM_LEFT);
tiles.at(18 * 20 + 18) = Tile(TileId::CLIFF_CORNER_BOTTOM_RIGHT);
Level level("Osnabrück", 20, 20, tiles, std::vector<Building>(),
std::vector<Unit>());
engine.set_scene(level);
Spritesheet spritesheet("../tiles.png", engine);
Spritesheet spritesheet("/media/data/rust/sprite-extractor/spritesheet.h5",
engine);
engine.set_spritesheet(spritesheet);
while (!engine.exited())
{
while (!engine.exited()) {
engine.pump();
engine.render();
}
......
#include "spritesheet.hpp"
#include <SDL_render.h>
#include "SDL_pixels.h"
#include "SDL_surface.h"
#include "engine.hpp"
#include "highfive/H5File.hpp"
#include "highfive/highfive.hpp"
#include <SDL_image.h>
#include <SDL_render.h>
#include <cstddef>
#include <cstdint>
#include <stdexcept>
#include <vector>
namespace advanced_wars {
Spritesheet::Spritesheet(std::string path, Engine &engine) {
HighFive::File file(path, HighFive::File::ReadOnly);
HighFive::DataSet tile_frames_ds = file.getDataSet("tiles/frames");
HighFive::DataSet tile_num_frames_ds = file.getDataSet("tiles/num_frames");
std::vector<std::vector<std::vector<uint32_t>>> tile_frames;
tile_frames_ds.read(tile_frames);
std::vector<uint32_t> tile_num_frames;
tile_num_frames_ds.read(tile_num_frames);
namespace advanced_wars
{
std::vector<uint32_t> buffer(16 * 16 * tile_frames.size(), 0);
Spritesheet::Spritesheet(std::string path, Engine &engine)
{
SDL_Surface *loadedSurface = IMG_Load(path.c_str());
if (loadedSurface == nullptr)
{
throw std::runtime_error("Fehler beim Laden des Bildes " + path + ": " +
std::string(IMG_GetError()));
for (size_t n = 0; n < tile_frames.size(); n++) {
for (size_t y = 0; y < 16; y++) {
for (size_t x = 0; x < 16; x++) {
size_t index = (y * tile_frames.size() * 16) + (n * 16 + x);
buffer.at(index) = tile_frames.at(n).at(y).at(x);
}
}
}
int count = 0;
for (size_t n = 0; n < tile_num_frames.size(); n++) {
this->tiles.push_back(std::pair(count, tile_num_frames.at(n)));
count += tile_num_frames.at(n);
}
texture = SDL_CreateTextureFromSurface(engine.renderer(), loadedSurface);
texture = SDL_CreateTexture(engine.renderer(), SDL_PIXELFORMAT_RGBA8888,
SDL_TEXTUREACCESS_STATIC, count * 16, 16);
if (texture == nullptr)
{
if (texture == nullptr) {
throw std::runtime_error("Fehler beim Erstellen der Textur: " +
std::string(SDL_GetError()));
}
SDL_FreeSurface(loadedSurface);
if (SDL_UpdateTexture(texture, NULL, buffer.data(),
count * 16 * sizeof(int32_t)) != 0) {
throw std::runtime_error("Fehler beim updaten der Textur: " +
std::string(SDL_GetError()));
}
// Temporary
this->tile_width = 16;
this->tile_height = 16;
this->tiles.push_back(std::pair(0, 1));
this->tiles.push_back(std::pair(1, 4));
}
int Spritesheet::get_tile_steps(int tile) { return tiles.at(tile).second; }
......@@ -42,25 +73,22 @@ namespace advanced_wars
int Spritesheet::get_tile_height() { return tile_height; }
int Spritesheet::render_tile(SDL_Renderer *renderer, int tile, int step,
SDL_Rect *rect)
{
if (step >= this->get_tile_steps(tile) || step < 0)
{
SDL_Rect *rect) {
int max_steps = this->get_tile_steps(tile);
if (step >= max_steps || step < 0) {
throw std::runtime_error("Tried to access step " + std::to_string(step) +
" for tile " + std::to_string(tile));
}
int offset = tiles.at(tile).first;
SDL_Rect src;
src.x = tile * tile_width;
src.x = offset * tile_width + step * tile_width;
src.y = 0;
src.w = tile_width;
src.h = tile_height;
/*
std::cout << rect->x << " " << rect->y << " " << rect->w << " " << rect->h
<< std::endl;
*/
return SDL_RenderCopyEx(renderer, texture, &src, rect, 0, NULL,
SDL_FLIP_NONE);
}
......
#include "tile.hpp"
Tile::Tile() {};
Tile::Tile(TileId id)
: id(id) {
};
#ifndef TILE_HPP
#define TILE_HPP
#pragma once
enum TileId {
PLAIN = 0,
WATER = 1,
STREET_HORIZONTAL = 2,
STREET_VERTICAL = 3,
STREET_CORNER_TOP_LEFT = 4,
STREET_CORNER_TOP_RIGHT = 5,
STREET_CORNER_BOTTOM_LEFT = 6,
STREET_CORNER_BOTTOM_RIGHT = 7,
RIFF = 8,
CLIFF_TOP = 9,
CLIFF_BOTTOM = 10,
CLIFF_LEFT = 11,
CLIFF_RIGHT = 12,
CLIFF_CORNER_TOP_LEFT = 13,
CLIFF_CORNER_TOP_RIGHT = 14,
CLIFF_CORNER_BOTTOM_LEFT = 15,
CLIFF_CORNER_BOTTOM_RIGHT = 16,
CLIFF_INVERSE_CORNER_TOP_LEFT = 17,
CLIFF_INVERSE_CORNER_TOP_RIGHT = 18,
CLIFF_INVERSE_CORNER_BOTTOM_LEFT = 19,
CLIFF_INVERSE_CORNER_BOTTOM_RIGHT = 20,
};
class Tile {
public:
Tile();
Tile(TileId id);
TileId id;
};
#endif
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment