0
0
mirror of https://github.com/Nimac0/SDL_Minigame synced 2026-01-12 12:33:43 +00:00

Compare commits

...

7 Commits

Author SHA1 Message Date
Benedikt Galbavy
c19171328d
Merge pull request #84 from VEGO-Engine/tmxlite
Added support for .tmx maps
2024-11-05 19:50:56 +01:00
Benedikt Galbavy
21f970cb19
Merge pull request #85 from VEGO-Engine/remove-assets
Removed assets and startscreen from engine
2024-11-05 19:47:22 +01:00
23c750c409 Implemented requested changes 2024-11-05 19:45:24 +01:00
7c82ee5beb Removed all assets* from Engine 2024-11-05 19:35:31 +01:00
d7f11e7ebd Readded animations 2024-11-05 16:14:35 +01:00
476d24e930 Code clean-up 2024-11-05 16:14:22 +01:00
ba8dca8abc added loading of tmx files 2024-11-04 23:27:26 +01:00
51 changed files with 149 additions and 183 deletions

3
.gitmodules vendored
View File

@ -14,3 +14,6 @@
path = extern/SDL_ttf
url = https://github.com/libsdl-org/SDL_ttf.git
branch = release-2.22.x
[submodule "extern/tmxlite"]
path = extern/tmxlite
url = https://github.com/fallahn/tmxlite.git

View File

@ -17,10 +17,13 @@ set(SDL2TTF_VENDORED ON)
set(SDL2_SOURCE_DIR ${ENGINE_SOURCE_DIR}/extern/SDL”)
set(TMXLITE_STATIC_LIB TRUE)
add_subdirectory(extern/SDL EXCLUDE_FROM_ALL)
add_subdirectory(extern/SDL_image EXCLUDE_FROM_ALL)
add_subdirectory(extern/SDL_mixer EXCLUDE_FROM_ALL)
add_subdirectory(extern/SDL_ttf EXCLUDE_FROM_ALL)
add_subdirectory(extern/tmxlite/tmxlite EXCLUDE_FROM_ALL)
file(GLOB_RECURSE SOURCES ${ENGINE_SOURCE_DIR}/src/*.cpp)
add_library(${PROJECT_NAME} ${SOURCES})
@ -33,6 +36,7 @@ target_link_libraries(${PROJECT_NAME} PUBLIC # should be private when all SDL fu
SDL2_image::SDL2_image-static
SDL2_mixer::SDL2_mixer-static
SDL2_ttf::SDL2_ttf-static
tmxlite
)
if(CMAKE_BUILD_TYPE MATCHES "Debug")

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,106 +0,0 @@
{ "frames": [
{
"filename": "MapNew.aseprite",
"frame": { "x": 0, "y": 0, "w": 32, "h": 32 },
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 32, "h": 32 },
"sourceSize": { "w": 32, "h": 32 },
"duration": 100
},
{
"filename": "MapNew.aseprite",
"frame": { "x": 32, "y": 0, "w": 32, "h": 32 },
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 32, "h": 32 },
"sourceSize": { "w": 32, "h": 32 },
"duration": 100
},
{
"filename": "MapNew.aseprite",
"frame": { "x": 64, "y": 0, "w": 32, "h": 32 },
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 32, "h": 32 },
"sourceSize": { "w": 32, "h": 32 },
"duration": 100
},
{
"filename": "MapNew.aseprite",
"frame": { "x": 96, "y": 0, "w": 32, "h": 32 },
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 32, "h": 32 },
"sourceSize": { "w": 32, "h": 32 },
"duration": 100
},
{
"filename": "MapNew.aseprite",
"frame": { "x": 128, "y": 0, "w": 32, "h": 32 },
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 32, "h": 32 },
"sourceSize": { "w": 32, "h": 32 },
"duration": 100
},
{
"filename": "MapNew.aseprite",
"frame": { "x": 160, "y": 0, "w": 32, "h": 32 },
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 32, "h": 32 },
"sourceSize": { "w": 32, "h": 32 },
"duration": 100
},
{
"filename": "MapNew.aseprite",
"frame": { "x": 192, "y": 0, "w": 32, "h": 32 },
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 32, "h": 32 },
"sourceSize": { "w": 32, "h": 32 },
"duration": 100
},
{
"filename": "MapNew.aseprite",
"frame": { "x": 224, "y": 0, "w": 32, "h": 32 },
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 32, "h": 32 },
"sourceSize": { "w": 32, "h": 32 },
"duration": 100
},
{
"filename": "MapNew.aseprite",
"frame": { "x": 256, "y": 0, "w": 32, "h": 32 },
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 32, "h": 32 },
"sourceSize": { "w": 32, "h": 32 },
"duration": 100
},
{
"filename": "MapNew.aseprite",
"frame": { "x": 288, "y": 0, "w": 32, "h": 32 },
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 32, "h": 32 },
"sourceSize": { "w": 32, "h": 32 },
"duration": 100
}
],
"meta": {
"app": "https://www.aseprite.org/",
"version": "1.3.2-x64",
"format": "RGBA8888",
"size": { "w": 320, "h": 32 },
"scale": "1",
"frameTags": [
],
"layers": [
],
"slices": [
]
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.3 KiB

View File

@ -1,20 +0,0 @@
3,3,3,3,3,3,3,3,3,3,7,1,1,1,9,3,3,3,3,3,3,3,3,3,3
3,3,3,3,3,3,3,3,3,3,7,1,1,1,9,3,3,3,3,3,3,3,2,3,3
3,3,3,3,3,3,3,3,3,3,7,1,1,1,9,3,3,3,3,3,3,2,2,2,3
3,3,3,2,3,3,3,3,2,3,7,1,1,1,9,3,3,3,3,3,3,3,2,2,3
3,3,2,2,3,3,3,3,3,3,7,1,1,1,9,3,3,3,3,3,3,3,3,3,3
3,3,2,2,2,3,3,3,3,3,7,1,1,1,9,3,3,2,3,3,3,3,3,3,3
3,3,2,2,2,3,3,3,3,3,7,1,1,1,9,3,3,3,3,3,3,3,3,3,3
3,3,3,2,2,3,3,3,3,3,7,1,1,1,9,3,3,3,3,3,3,3,3,3,3
3,3,3,3,2,3,3,3,3,3,7,1,1,1,9,3,3,3,3,3,3,3,3,3,3
3,3,3,3,3,3,3,3,3,3,7,1,1,1,9,3,3,3,3,3,3,3,3,3,3
3,3,3,3,3,3,3,3,3,3,7,1,1,1,9,3,3,3,3,3,3,3,3,3,3
3,3,3,3,3,3,3,3,3,3,7,1,1,1,9,3,3,3,3,3,2,3,3,3,3
3,3,3,2,2,3,3,3,3,3,7,1,1,1,9,3,3,3,3,2,2,3,3,3,3
3,3,3,3,3,3,3,3,3,3,7,1,1,1,9,3,3,3,3,2,2,2,3,3,3
3,3,3,3,3,3,3,3,3,3,7,1,1,1,9,3,3,3,3,2,2,3,3,3,3
3,3,3,3,3,3,3,2,3,3,7,1,1,1,9,3,2,3,3,2,3,3,3,3,3
3,3,3,3,3,3,3,3,3,3,7,1,1,1,9,3,2,3,3,3,3,3,3,3,3
2,2,3,3,3,3,3,3,3,3,7,1,1,1,9,3,3,3,3,3,3,3,3,3,3
3,2,2,3,3,3,3,3,3,3,7,1,1,1,9,3,3,3,3,3,3,3,3,3,3
3,3,3,3,3,3,3,3,3,3,7,1,1,1,9,3,3,3,3,3,3,3,3,3,3

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 571 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 407 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 751 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 913 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 836 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 847 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 877 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 271 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 943 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1011 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 279 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 550 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 643 B

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 279 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 914 B

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

1
extern/tmxlite vendored Submodule

@ -0,0 +1 @@
Subproject commit fcef1a28ade8406e290d5fd168a8950e6996844f

View File

@ -1,5 +1,6 @@
#pragma once
#include <tmxlite/Types.hpp>
#include <map>
#include <string>
@ -10,8 +11,6 @@ public:
Map() = default;
~Map() = default;
// code comment below is a test for doxygen - do not remove
/*!
*
* \brief
@ -21,6 +20,17 @@ public:
* \return Boolean for success
*
*/
[[deprecated("ID based text files are not supported anymore, use .txm maps instead")]]
static void loadMap(const char* path, int sizeX, int sizeY, GameInternal* game, const std::map<int, std::pair<std::string, bool>>* textureDict /* backreference */);
[[deprecated]]
static void addTile(unsigned long id, int x, int y, GameInternal* game, const std::map<int, std::pair<std::string, bool>>* textureDict);
/*!
* \brief Loads a .tmx map
* \param path Path to the `.tmx` map file
*
*/
static void loadMapTmx(const char* path);
private:
static void addTile(float x, float y, const tmx::Vector2u& mapTileSize, int u, int v, int zIndex, const char* texturePath);
};

View File

@ -31,8 +31,12 @@ private:
uint8_t speed = 100;
bool flipped = false;
int textureXOffset;
int textureYOffset;
public:
SpriteComponent(const char* path, int zIndex);
SpriteComponent(const char* path, int xOffset, int yOffset, int zIndex);
SpriteComponent(
const char* path,
bool isAnimated,

View File

@ -5,6 +5,7 @@
#include "CollisionHandler.h"
#include "AssetManager.h"
#include "RenderManager.h"
#include "SDL_mixer.h"
#include "SoundManager.h"
#include "TileComponent.h"
#include "Direction.h"
@ -62,11 +63,11 @@ void GameInternal::init(const char* title, int xpos, int ypos, int width, int he
return;
}
SDL_Surface* icon = SDL_LoadBMP("assets/iconImage.bmp");
if(!icon)
// bad
SDL_Surface* icon;
if((icon = SDL_LoadBMP("assets/iconImage.bmp")))
{
std::cout << "ERROR: Couldn't create icon!" << std::endl;
return;
SDL_SetWindowIcon(window, icon);
}
SDL_SetWindowIcon(window, icon);
@ -80,12 +81,6 @@ void GameInternal::init(const char* title, int xpos, int ypos, int width, int he
}
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
SDL_Texture* backgroundTexture = GameInternal::textureManager->loadTexture("assets/startscreen.png");
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, backgroundTexture, NULL, NULL);
SDL_RenderPresent(renderer);
if (Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 2048) < 0)
{
std::cout << "ERROR: Mixer couldnt be initialized! " << SDL_GetError() << std::endl;
@ -96,43 +91,6 @@ void GameInternal::init(const char* title, int xpos, int ypos, int width, int he
Mix_Volume(-1, MIX_MAX_VOLUME);
Mix_AllocateChannels(16);
//SDL_Event event;
bool hasQuit = false;
while (!hasQuit)
{
SDL_PollEvent(&event);
if (event.type == SDL_QUIT)
{
hasQuit = true;
break;
}
if (event.type == SDL_KEYDOWN)
{
if (event.key.keysym.scancode == SDL_SCANCODE_RETURN)
{
std::cout << "Enter pressed > Game start..." << std::endl;
break;
}
if (event.key.keysym.scancode == SDL_SCANCODE_ESCAPE)
{
std::cout << "Escape pressed > Game quit..." << std::endl;
hasQuit = true;
}
}
}
if (hasQuit)
{
this->setRunning(false);
return;
}
if (this->isRunning() == false) return;
map = new Map();
// loading sounds

View File

@ -1,14 +1,30 @@
#include "Map.h"
#include <algorithm>
#include <cctype>
#include <cstdio>
#include <iostream>
#include <fstream>
#include <type_traits>
#include <utility>
#include <vector>
#include <SDL_error.h>
#include <SDL_render.h>
#include <tmxlite/Layer.hpp>
#include <tmxlite/Map.hpp>
#include <tmxlite/Tileset.hpp>
#include <tmxlite/Property.hpp>
#include <tmxlite/TileLayer.hpp>
#include "Constants.h"
#include "GameInternal.h"
#include "SDL_error.h"
#include "SpriteComponent.h"
#include "TextureManager.h"
#include "TileComponent.h"
#include "VEGO.h"
#include "tmxlite/Types.hpp"
void Map::loadMap(const char* path, int sizeX, int sizeY, GameInternal* game, const std::map<int, std::pair<std::string, bool>>* textureDict /* backreference */)
{
@ -36,7 +52,7 @@ void Map::loadMap(const char* path, int sizeX, int sizeY, GameInternal* game, co
if (x != sizeX) {
SDL_SetError("Error loading map: specified x size doesn't match map file!");
std::cout << "ERROR: Map couldnt be loaded! " << SDL_GetError() << std::endl;
SDL_ClearError();
SDL_ClearError();
}
x = 0;
y++;
@ -61,6 +77,95 @@ void Map::addTile(unsigned long id, int x, int y, GameInternal* game, const std:
auto& tile(game->manager.addEntity());
tile.addComponent<TileComponent>(x, y, TILE_SIZE, TILE_SIZE, id, textureDict);
if(tile.getComponent<TileComponent>().hasCollision()) tile.addComponent<ColliderComponent>(tile.getComponent<TileComponent>().getName().data());
if(tile.getComponent<TileComponent>().hasCollision()) tile.addComponent<ColliderComponent>("tile"/*tile.getComponent<TileComponent>().getName().data()*/);
tile.addGroup((size_t)Entity::GroupLabel::MAPTILES);
}
void Map::loadMapTmx(const char* path)
{
tmx::Map map;
if (!map.load(path)) {
// TODO: log to console
}
const std::vector<tmx::Tileset>& tileSets = map.getTilesets();
const std::vector<tmx::Layer::Ptr>& mapLayers = map.getLayers();
const auto mapSize = map.getTileCount();
const auto mapTileSize = map.getTileSize();
std::vector<std::string> texturePaths = {};
for (auto tileSet : tileSets) {
texturePaths.emplace_back(tileSet.getImagePath());
}
for (auto& layer : mapLayers) {
if (layer->getType() == tmx::Layer::Type::Tile) {
auto& tileLayer = layer->getLayerAs<tmx::TileLayer>();
int zIndex = 0;
const std::vector<tmx::Property>& properties = layer->getProperties();
auto zIndexIterator = std::find_if(properties.begin(), properties.end(), [](const tmx::Property& property) {
return property.getName() == "zIndex";
});
if (zIndexIterator != properties.end() && std::is_nothrow_convertible<decltype(zIndexIterator->getType()), int>::value) {
zIndex = zIndexIterator->getIntValue();
}
const auto& tiles = tileLayer.getTiles();
for (auto i = 0u; i < tileSets.size(); i++) {
auto tilesetTexture = VEGO_Game().textureManager->loadTexture(texturePaths.at(i).c_str());
tmx::Vector2i textureSize;
SDL_QueryTexture(tilesetTexture, nullptr, nullptr, &(textureSize.x), &(textureSize.y));
const auto tileCountX = textureSize.x / mapTileSize.x;
const auto tileCountY = textureSize.y / mapTileSize.y;
for (auto idx = 0ul; idx < mapSize.x * mapSize.y; idx++) {
if (idx >= tiles.size() || tiles[idx].ID < tileSets.at(i).getFirstGID()
|| tiles[idx].ID >= (tileSets.at(i).getFirstGID() + tileSets.at(i).getTileCount())) {
continue;
}
const auto x = idx % mapSize.x;
const auto y = idx / mapSize.x;
auto idIndex = (tiles[idx].ID - tileSets.at(i).getFirstGID());
int u = idIndex % tileCountX;
int v = idIndex / tileCountY;
u *= mapTileSize.x; //TODO we should be using the tile set size, as this may be different from the map's grid size
v *= mapTileSize.y;
//normalise the UV
u /= textureSize.x;
v /= textureSize.y;
//vert pos
const float tilePosX = static_cast<float>(x) * mapTileSize.x;
const float tilePosY = (static_cast<float>(y) * mapTileSize.y);
Map::addTile(tilePosX, tilePosY, mapTileSize, u, v, zIndex, texturePaths.at(i).c_str());
}
}
if (layer->getType() == tmx::Layer::Type::Object) {
// spawn objects
continue;
}
}
}
}
void Map::addTile(float x, float y, const tmx::Vector2u& mapTileSize, int u, int v, int zIndex, const char* texturePath)
{
auto& tile(VEGO_Game().manager.addEntity());
tile.addComponent<TransformComponent>(x, y, mapTileSize.x, mapTileSize.y, 1);
tile.addComponent<SpriteComponent>(texturePath, v, u, zIndex); // why does uv need to be reversed?
}

View File

@ -15,7 +15,12 @@
#include "Manager.h"
#include "VEGO.h"
SpriteComponent::SpriteComponent(const char* path, int zIndex) : RenderObject(zIndex, VEGO_Game().renderManager)
SpriteComponent::SpriteComponent(const char* path, int zIndex) : RenderObject(zIndex, VEGO_Game().renderManager), textureXOffset(0), textureYOffset(0)
{
this->texturePath = path;
}
SpriteComponent::SpriteComponent(const char* path, int xOffset, int yOffset, int zIndex) : RenderObject(zIndex, VEGO_Game().renderManager), textureXOffset(xOffset), textureYOffset(yOffset)
{
this->texturePath = path;
}
@ -25,7 +30,7 @@ SpriteComponent::SpriteComponent(
bool isAnimated,
std::map<std::string, std::unique_ptr<Animation>>* animationMap,
std::string defaultAnimation,
int zIndex) : RenderObject(zIndex, VEGO_Game().renderManager)
int zIndex) : RenderObject(zIndex, VEGO_Game().renderManager), textureXOffset(0), textureYOffset(0)
{
animated = isAnimated;
@ -49,20 +54,22 @@ void SpriteComponent::init()
this->transform = &entity->getComponent<TransformComponent>();
this->srcRect.x = this->srcRect.y = 0;
this->srcRect.w = transform->width;
this->srcRect.h = transform->height;
this->srcRect.x = this->textureXOffset * this->srcRect.w;
this->srcRect.y = this->textureYOffset * this->srcRect.h;;
this->update();
}
void SpriteComponent::update()
{
// This code is not compatible for animated tiles
if (animated) {
srcRect.x = srcRect.w * static_cast<int>((SDL_GetTicks() / speed) % frames);
}
srcRect.y = animationIndex * transform->height;
srcRect.y = animationIndex * transform->height;
}
this->destRect.x = this->transform->position.x;
this->destRect.y = this->transform->position.y;