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

Merge branch 'basic-spritesheet' into 'main'

add hdf5 support and temporary bogus spritesheet implementation

See merge request fdai7375/cpp-project!2
parents 3ca88a67 6ffd9def
No related branches found
No related tags found
No related merge requests found
......@@ -2,11 +2,14 @@ build/
out/
cmake-build-*/
test.png
.idea/
.vscode/
*.swp
*.swo
*~
.cache/
*.o
*.obj
......
......@@ -7,13 +7,9 @@ project(ADVANCED_WARS
LANGUAGES CXX
)
set(ADVANCED_WARS_SOURCES
src/scene.hpp
src/unit.cpp
src/building.cpp
src/level.cpp
src/engine.cpp
src/window.cpp
file(GLOB ADVANCED_WARS_SOURCES
"${PROJECT_SOURCE_DIR}/src/*.cpp"
"${PROJECT_SOURCE_DIR}/src/*.hpp"
)
# C++ Standard festlegen
......@@ -34,11 +30,17 @@ set(CMAKE_MODULE_PATH ${ADVANCED_WARS_SOURCE_DIR}/cmake/ ${CMAKE_MODULE_PATH})
# SDL2
find_package(SDL2 REQUIRED)
find_package(SDL2_IMAGE REQUIRED)
find_package(HDF5 REQUIRED COMPONENTS CXX)
include_directories(${SDL2_INCLUDE_DIR})
include_directories(${SDL2_IMG_INCLUDE_DIR})
include_directories(${HDF5_INCLUDE_DIRS})
# Executable erstellen
add_executable(advanced_wars src/main.cpp ${ADVANCED_WARS_SOURCES})
target_link_libraries(advanced_wars ${SDL2_LIBRARY} ${SDL2_IMG_LIBRARY})
target_link_libraries(advanced_wars m)
target_link_libraries(advanced_wars
${SDL2_LIBRARY}
${SDL2_IMG_LIBRARY}
${HDF5_LIBRARIES}
m
)
\ No newline at end of file
#include "engine.hpp"
#include "SDL_render.h"
#include "scene.hpp"
#include "spritesheet.hpp"
#include "window.hpp"
#include "engine.hpp"
#include <vector>
#include <stdexcept>
#include <SDL.h>
#include <SDL_image.h>
#include <stdexcept>
#include <vector>
namespace advanced_wars {
Engine::Engine(Window &window, Scene &scene): window(window), scene(scene) {
this->renderer = SDL_CreateRenderer(
this->window.sdl_window(), -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
Engine::Engine(Window &window) : window(window), quit(false) {
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
throw std::runtime_error("SDL could not initialize: " +
std::string(SDL_GetError()));
}
int imgFlags = IMG_INIT_PNG;
if (!(IMG_Init(imgFlags) & imgFlags)) {
throw std::runtime_error(
"SDL_image could not initialize! SDL_image Error: " +
std::string(IMG_GetError()));
}
if (renderer == nullptr) {
this->sdl_renderer =
SDL_CreateRenderer(this->window.sdl_window(), -1,
SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
if (sdl_renderer == nullptr) {
throw std::runtime_error("SDL could not generate renderer: " +
std::string(SDL_GetError()));
}
}
void Engine::set_scene() {}
void Engine::set_scene(Scene &scene) { this->scene = &scene; }
void Engine::set_spritesheet(Spritesheet spritesheet) {
this->spritesheet = spritesheet;
}
void Engine::pump() {
SDL_Event e;
......@@ -30,18 +51,29 @@ void Engine::pump() {
}
}
bool Engine::exited() {
return this->quit;
}
bool Engine::exited() { return this->quit; }
void Engine::render() {
if(SDL_RenderClear(this->renderer) != 0) {
throw std::runtime_error("Could not clear renderer: " + std::string(SDL_GetError()));
if (SDL_RenderClear(this->sdl_renderer) != 0) {
throw std::runtime_error("Could not clear renderer: " +
std::string(SDL_GetError()));
}
if (!scene.has_value()) {
return;
}
this->scene.value()->render(this->sdl_renderer, this->events);
SDL_RenderPresent(this->sdl_renderer);
}
this->scene.render(this->renderer, this->events);
SDL_Renderer *Engine::renderer() { return this->sdl_renderer; }
SDL_RenderPresent(this->renderer);
Engine::~Engine() {
SDL_DestroyRenderer(sdl_renderer);
IMG_Quit();
SDL_Quit();
}
} // namespace advanced_wars
#ifndef ENGINE_HPP
#define ENGINE_HPP
#pragma once
#include "window.hpp"
#include "SDL_render.h"
#include "scene.hpp"
#include "spritesheet.hpp"
#include "window.hpp"
#include <SDL.h>
#include <optional>
#include <vector>
namespace advanced_wars
{
namespace advanced_wars {
/**
* @brief The main window of the game
*/
class Engine
{
class Engine {
public:
Engine(Window &window);
Engine(Window &window, Scene &scene);
/**
* Forbids the creation of copies of a window
*/
Engine(const Engine &) = delete;
Engine &operator=(const Engine &) = delete;
......@@ -28,18 +24,23 @@ public:
void pump();
void set_scene();
void set_scene(Scene &scene);
void set_spritesheet(Spritesheet spritesheet);
void render();
SDL_Renderer *renderer();
~Engine();
private:
Window &window;
Scene &scene;
SDL_Renderer* renderer;
SDL_Renderer *sdl_renderer;
std::optional<Scene *> scene;
std::optional<Spritesheet> spritesheet;
std::vector<SDL_Event> events;
bool quit;
};
}
#endif
} // namespace advanced_wars
#ifndef LEVEL_HPP
#define LEVEL_HPP
#pragma once
#include "building.hpp"
#include "scene.hpp"
#include "tile.hpp"
#include "unit.hpp"
#include "building.hpp"
#include <SDL.h>
#include <string>
#include <vector>
#include <SDL.h>
namespace advanced_wars
{
namespace advanced_wars {
/**
* @brief The main window of the game
*/
class Level: public Scene
{
class Level : public Scene {
public:
Level(std::string name, int width, int height, std::vector<Tile> tiles, std::vector<Building> buildings, std::vector<Unit> units);
Level(std::string name, int width, int height, std::vector<Tile> tiles,
std::vector<Building> buildings, std::vector<Unit> units);
void render(SDL_Renderer *renderer, std::vector<SDL_Event> &events);
......@@ -30,6 +28,4 @@ private:
std::vector<Unit> units;
};
}
#endif
} // namespace advanced_wars
#include "window.hpp"
#include "engine.hpp"
#include "level.hpp"
#include "spritesheet.hpp"
#include "window.hpp"
#include <vector>
using namespace advanced_wars;
......@@ -9,9 +10,16 @@ int main() {
Window window("Advanced Wars", 800, 600);
Level level("Osnabrück",20,20, std::vector<Tile>(), std::vector<Building>(),std::vector<Unit>());
Engine engine(window);
Level level("Osnabrück", 20, 20, std::vector<Tile>(), std::vector<Building>(),
std::vector<Unit>());
engine.set_scene(level);
Spritesheet spritesheet("../test.png", engine);
Engine engine(window, level);
engine.set_spritesheet(spritesheet);
while (!engine.exited()) {
engine.pump();
......
#ifndef SCENE_HPP
#define SCENE_HPP
#pragma once
#include <SDL.h>
#include <vector>
......@@ -8,8 +7,7 @@ namespace advanced_wars {
class Scene {
public:
virtual void render(SDL_Renderer *renderer, std::vector<SDL_Event> &events) = 0;
virtual void render(SDL_Renderer *renderer,
std::vector<SDL_Event> &events) = 0;
};
}
#endif
} // namespace advanced_wars
#include "spritesheet.hpp"
#include "SDL_render.h"
#include "SDL_surface.h"
#include "engine.hpp"
#include <SDL_image.h>
#include <stdexcept>
namespace advanced_wars {
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()));
}
texture = SDL_CreateTextureFromSurface(engine.renderer(), loadedSurface);
if (texture == nullptr) {
throw std::runtime_error("Fehler beim Erstellen der Textur: " +
std::string(SDL_GetError()));
}
SDL_FreeSurface(loadedSurface);
}
int Spritesheet::get_tile_steps(int tile) { return tiles.at(tile).second; }
int Spritesheet::get_tile_width() { return tile_width; }
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) {
throw std::runtime_error("Tried to access step " + std::to_string(step) +
" for tile " + std::to_string(tile));
}
SDL_Rect src;
src.x = tile * tile_width;
src.y = 0;
src.w = tile_width;
src.h = tile_height;
return SDL_RenderCopyEx(renderer, texture, &src, rect, 0, NULL,
SDL_FLIP_NONE);
}
Spritesheet::~Spritesheet() { SDL_DestroyTexture(texture); }
} // namespace advanced_wars
\ No newline at end of file
#pragma once
#include "SDL_render.h"
#include <SDL.h>
#include <string>
#include <vector>
namespace advanced_wars {
// Forward declaration
class Engine;
class Spritesheet {
public:
Spritesheet(std::string path, Engine &engine);
~Spritesheet();
// Tiles
int get_tile_steps(int tile);
int get_tile_width();
int get_tile_height();
int render_tile(SDL_Renderer *renderer, int tile, int step, SDL_Rect *rect);
// Units: TODO
// Buildings: TODO
private:
SDL_Texture *texture;
// Tiles
int tile_width;
int tile_height;
std::vector<std::pair<int, int>> tiles;
};
} // namespace advanced_wars
#include "window.hpp"
#include <stdexcept>
namespace advanced_wars
{
namespace advanced_wars {
Window::Window(std::string title, int w, int h)
{
Window::Window(std::string title, int w, int h) {
/// Init width and height
width = w;
height = h;
// Generate SDL main window
window = SDL_CreateWindow(
title.c_str(),
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
width,
height,
window = SDL_CreateWindow(title.c_str(), SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED, width, height,
SDL_WINDOW_SHOWN);
if(window == nullptr)
{
throw std::runtime_error("SDL window could not be generated: " + std::string(SDL_GetError()));
if (window == nullptr) {
throw std::runtime_error("SDL window could not be generated: " +
std::string(SDL_GetError()));
}
}
int Window::w() { return width; }
int Window::w()
{
return width;
}
int Window::h() { return height; }
int Window::h()
{
return height;
}
SDL_Window *Window::sdl_window() { return window; }
SDL_Window* Window::sdl_window()
{
return window;
}
Window::~Window()
{
if(window)
{
Window::~Window() {
if (window) {
SDL_DestroyWindow(window);
window = nullptr;
}
}
}
} // namespace advanced_wars
#ifndef WINDOW_HPP
#define WINDOW_HPP
#pragma once
#include <string>
#include <SDL.h>
#include <string>
namespace advanced_wars
{
namespace advanced_wars {
/**
* @brief The main window of the game
*/
class Window
{
class Window {
public:
/***
* Creates a main window with given \ref title, width \ref w and height \ref h
*
......@@ -43,7 +39,6 @@ public:
SDL_Window *sdl_window();
private:
/// SDL main window struct
SDL_Window *window;
......@@ -54,6 +49,4 @@ private:
int height;
};
}
#endif
} // namespace advanced_wars
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment