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

tilemap/layer rendering system implemented

This commit is contained in:
Nimac0 2024-01-10 00:24:50 +01:00
parent a3201c77c2
commit 8c6364f41c
54 changed files with 243 additions and 25 deletions

View File

@ -0,0 +1,7 @@
#include "ECS.h"
void Entity::addGroup(Group mGroup)
{
groupBitSet[mGroup] = true;
manager.addToGroup(this, mGroup);
}

View File

@ -9,23 +9,28 @@
class Component;
class Entity;
class Manager;
using ComponentID = std::size_t;
using Group = std::size_t;
inline ComponentID getComponentTypeID()
inline ComponentID getNewComponentTypeID()
{
static ComponentID lastID = 0;
static ComponentID lastID = 0u;
return lastID++;
}
template <typename T> inline ComponentID getComponentTypeID() noexcept
{
static ComponentID typeID = getComponentTypeID();
static ComponentID typeID = getNewComponentTypeID();
return typeID;
}
constexpr std::size_t maxComponents = 32;
constexpr std::size_t maxGroups = 32;
using ComponentBitSet = std::bitset<maxComponents>;
using GroupBitSet = std::bitset<maxGroups>;
using ComponentArray = std::array<Component*, maxComponents>;
class Component
@ -43,6 +48,10 @@ class Component
class Entity
{
public:
Entity(Manager& mManager) : manager(mManager)
{
}
void update()
{
for (auto& c : components) c->update();
@ -56,6 +65,17 @@ class Entity
bool isActive() const { return this->active; }
void destroy() { this->active = false; }
bool hasGroup(Group mGroup)
{
return groupBitSet[mGroup];
}
void addGroup(Group mGroup);
void delGroup(Group mGroup)
{
groupBitSet[mGroup] = false;
}
template <typename T> bool hasComponent() const
{
return componentBitSet[getComponentTypeID<T>()];
@ -84,11 +104,13 @@ class Entity
private:
Manager& manager;
bool active = true;
std::vector<std::unique_ptr<Component>> components;
ComponentArray componentArray;
ComponentBitSet componentBitSet;
GroupBitSet groupBitSet;
};
class Manager
@ -106,6 +128,17 @@ class Manager
void refresh()
{
for (auto i(0u); i < maxGroups; i++)
{
auto& v(groupedEntities[i]);
v.erase(
std::remove_if(std::begin(v), std::end(v),
[i](Entity* mEntity)
{
return !mEntity->isActive() || !mEntity->hasGroup(i);
}),std::end(v));
}
entities.erase(std::remove_if(std::begin(entities), std::end(entities),
[](const std::unique_ptr<Entity>& mEntity)
{
@ -114,9 +147,19 @@ class Manager
std::end(entities));
}
void addToGroup(Entity* mEntity, Group mGroup)
{
groupedEntities[mGroup].emplace_back(mEntity);
}
std::vector<Entity*>& getGroup(Group mGroup)
{
return groupedEntities[mGroup];
}
Entity& addEntity()
{
Entity* e = new Entity();
Entity* e = new Entity(*this);
std::unique_ptr<Entity> uPtr{ e };
entities.emplace_back(std::move(uPtr));
return *e;
@ -124,4 +167,5 @@ class Manager
private:
std::vector<std::unique_ptr<Entity>> entities;
std::array<std::vector<Entity*>, maxGroups> groupedEntities;
};

View File

@ -19,6 +19,14 @@ auto& player(manager.addEntity());
auto& enemy(manager.addEntity());
auto& wall(manager.addEntity());
enum GroupLabel
{
GROUP_MAP,
GROUP_PLAYERS,
GROUP_ENEMIES,
GROUP_COLLIDERS
};
Game::Game()
{
@ -56,6 +64,7 @@ void Game::init(const char* title, int xpos, int ypos, int width, int height, bo
this->isRunning = true;
map = new Map();
map->loadMap("assets/SDL_map_test.txt", 25, 20);
//ecs implementation
@ -63,15 +72,13 @@ void Game::init(const char* title, int xpos, int ypos, int width, int height, bo
player.addComponent<SpriteComponent>("assets/chicken_neutral_knight.png");
player.addComponent<KeyboardController>(SDL_SCANCODE_W, SDL_SCANCODE_S, SDL_SCANCODE_A, SDL_SCANCODE_D);//custom keycontrols can be added
player.addComponent<ColliderComponent>("player");
player.addGroup(GROUP_PLAYERS);
enemy.addComponent<TransformComponent>(400, 400, 2);
enemy.addComponent<TransformComponent>(600, 500, 2);
enemy.addComponent<SpriteComponent>("assets/chicken_neutral.png");
enemy.addComponent<KeyboardController>(SDL_SCANCODE_UP, SDL_SCANCODE_DOWN, SDL_SCANCODE_LEFT, SDL_SCANCODE_RIGHT);
enemy.addComponent<ColliderComponent>("enemy");
wall.addComponent<TransformComponent>(300.0f, 300.0f, 300, 20, 1);
wall.addComponent<SpriteComponent>("assets/stone.png");
wall.addComponent<ColliderComponent>("wall");
enemy.addGroup(GROUP_ENEMIES);
}
@ -112,10 +119,25 @@ void Game::update()
}
auto& tiles(manager.getGroup(GROUP_MAP));
auto& players(manager.getGroup(GROUP_PLAYERS));
auto& enemies(manager.getGroup(GROUP_ENEMIES));
void Game::render()
{
SDL_RenderClear(renderer);
manager.draw();
for (auto& t : tiles)
{
t->draw();
}
for (auto& p : players)
{
p->draw();
}
for (auto& e : enemies)
{
e->draw();
}
SDL_RenderPresent(renderer);
}
@ -130,7 +152,9 @@ void Game::clean()
void Game::addTile(int id, int x, int y)
{
auto& tile(manager.addEntity());
tile.addComponent<TileComponent>(x, y, 32, 32, id);
tile.addComponent<TileComponent>(x, y, TILE_SIZE, TILE_SIZE, id);
if (id == 1) tile.addComponent<ColliderComponent>("water");
tile.addGroup(GROUP_MAP);
}
bool Game::running()

View File

@ -1,5 +1,6 @@
#pragma once
#include "Defines.h"
#include <string>
class Map
{

View File

@ -19,7 +19,6 @@ class SpriteComponent : public Component
void setTexture(const char* path)
{
//SDL_DestroyTexture(this->texture);
this->texture = TextureManager::loadTexture(path);
}

View File

@ -155,6 +155,7 @@
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="ECS.cpp" />
<ClCompile Include="Game.cpp" />
<ClCompile Include="GameObject.cpp" />
<ClCompile Include="KeyboardController.cpp" />

View File

@ -39,6 +39,9 @@
<ClCompile Include="KeyboardController.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ECS.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Game.h">

View File

@ -5,10 +5,12 @@
class TextureDict
{
public:
const std::map<int, const char*> textureDictionary =
const std::map<int, std::string> textureDictionary =
{
{0, "assets/water.png"},
{1, "assets/dirt.png"},
{2, "assets/grass.png"}
{1, "assets/water.png"},
{2, "assets/dirt.png"},
{3, "assets/grass.png"},
{7, "assets/grass_water_left.png"},
{9, "assets/grass_water_right.png"}
};
};

View File

@ -3,7 +3,6 @@
SDL_Texture* TextureManager::loadTexture(const char* fileName)
{
return IMG_LoadTexture(Game::renderer, fileName);
}
void TextureManager::draw(SDL_Texture* texture, SDL_Rect src, SDL_Rect dest)

View File

@ -26,8 +26,15 @@ public:
this->tileRect.h = h;
tileID = id;
auto it = textureDict.textureDictionary.find(tileID)->second; //every id has its own distinct texture (in texturedict.h)
this->path = it;
auto it = textureDict.textureDictionary.find(tileID); //every id has its own distinct texture (in texturedict.h)
if (it == textureDict.textureDictionary.end())
{
std::cout << "it end" << std::endl;
return;
}
bool test = it == textureDict.textureDictionary.end();
std::cout << it->second.data() << std::endl;
this->path = it->second.data();
}
~TileComponent() = default;

View File

@ -57,7 +57,7 @@ public:
void update() override
{
// if(velocity.x != 0 && velocity.y != 0)
double multiplier = velocity.x != 0 && velocity.y != 0 ? 0.707 : 1;
double multiplier = velocity.x != 0 && velocity.y != 0 ? 0.707 : 1; //normalizes vector
position.x += velocity.x * speed * multiplier;
position.y += velocity.y * speed * multiplier;
}

Binary file not shown.

View File

@ -0,0 +1,106 @@
{ "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.

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -0,0 +1 @@
{"width":800,"tilesets":[{"grid":{"tileSize":{"width":32,"height":32}},"image":"MapNewBackup\\tileset1.png"}],"height":640,"frames":[{"duration":0.1}],"filename":"C:\\Users\\User\\Desktop\\FH_TECHNIKUM\\3.Semester\\INNO1\\TestProject\\TestProject\\assets\\MapNewBackup.aseprite","layers":[{"cels":[{"image":"MapNewBackup\\image1.png","frame":0,"bounds":{"height":640,"width":800,"y":0,"x":0}}],"name":"Layer 1"},{"tileset":0,"cels":[{"bounds":{"height":224,"width":320,"y":96,"x":96},"frame":0,"tilemap":{"height":7,"width":10,"tiles":[3,7,1,1,1,9,3,2,2,2,3,7,1,1,1,9,3,2,2,2,3,7,1,1,1,9,3,2,2,2,3,6,4,4,4,8,3,0,0,0,0,3,3,3,3,3,0,0,0,0,0,0,3,3,3,0,0,0,0,0,0,0,3,3,3,0,0,0,0,0]}}],"name":"Map"}]}

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 914 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 877 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 943 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 997 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 891 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1011 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 977 B

Binary file not shown.

View File

@ -0,0 +1,20 @@
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.

Before

Width:  |  Height:  |  Size: 949 B

After

Width:  |  Height:  |  Size: 913 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 456 B

After

Width:  |  Height:  |  Size: 877 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 673 B

After

Width:  |  Height:  |  Size: 943 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1011 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 340 B

After

Width:  |  Height:  |  Size: 914 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

View File

@ -1,24 +1,27 @@
 Game.cpp
C:\Users\User\Desktop\FH_TECHNIKUM\3.Semester\INNO1\TestProject\TestProject\TransformComponent.h(61,36): warning C4244: '+=': conversion from 'double' to 'float', possible loss of data
C:\Users\User\Desktop\FH_TECHNIKUM\3.Semester\INNO1\TestProject\TestProject\TransformComponent.h(62,36): warning C4244: '+=': conversion from 'double' to 'float', possible loss of data
C:\Users\User\Desktop\FH_TECHNIKUM\3.Semester\INNO1\TestProject\TestProject\SpriteComponent.h(38,48): warning C4244: '=': conversion from 'float' to 'int', possible loss of data
C:\Users\User\Desktop\FH_TECHNIKUM\3.Semester\INNO1\TestProject\TestProject\SpriteComponent.h(39,48): warning C4244: '=': conversion from 'float' to 'int', possible loss of data
C:\Users\User\Desktop\FH_TECHNIKUM\3.Semester\INNO1\TestProject\TestProject\SpriteComponent.h(40,48): warning C4244: '=': conversion from 'float' to 'int', possible loss of data
C:\Users\User\Desktop\FH_TECHNIKUM\3.Semester\INNO1\TestProject\TestProject\ColliderComponent.h(30,35): warning C4244: '=': conversion from 'float' to 'int', possible loss of data
C:\Users\User\Desktop\FH_TECHNIKUM\3.Semester\INNO1\TestProject\TestProject\ColliderComponent.h(31,35): warning C4244: '=': conversion from 'float' to 'int', possible loss of data
C:\Users\User\Desktop\FH_TECHNIKUM\3.Semester\INNO1\TestProject\TestProject\ECS.h(67,34): warning C4244: 'argument': conversion from 'int' to 'float', possible loss of data
C:\Users\User\Desktop\FH_TECHNIKUM\3.Semester\INNO1\TestProject\TestProject\TileComponent.h(37,15): message : see reference to function template instantiation 'T &Entity::addComponent<TransformComponent,int&,int&,int&,int&,int>(int &,int &,int &,int &,int &&)' being compiled
C:\Users\User\Desktop\FH_TECHNIKUM\3.Semester\INNO1\TestProject\TestProject\ECS.h(87,34): warning C4244: 'argument': conversion from 'int' to 'float', possible loss of data
C:\Users\User\Desktop\FH_TECHNIKUM\3.Semester\INNO1\TestProject\TestProject\TileComponent.h(44,15): message : see reference to function template instantiation 'T &Entity::addComponent<TransformComponent,int&,int&,int&,int&,int>(int &,int &,int &,int &,int &&)' being compiled
with
[
T=TransformComponent
]
C:\Users\User\Desktop\FH_TECHNIKUM\3.Semester\INNO1\TestProject\TestProject\ECS.h(67,34): warning C4244: 'argument': conversion from '_Ty' to 'float', possible loss of data
C:\Users\User\Desktop\FH_TECHNIKUM\3.Semester\INNO1\TestProject\TestProject\ECS.h(87,34): warning C4244: 'argument': conversion from '_Ty' to 'float', possible loss of data
with
[
_Ty=int
]
C:\Users\User\Desktop\FH_TECHNIKUM\3.Semester\INNO1\TestProject\TestProject\Game.cpp(62,8): message : see reference to function template instantiation 'T &Entity::addComponent<TransformComponent,int,int,int>(int &&,int &&,int &&)' being compiled
C:\Users\User\Desktop\FH_TECHNIKUM\3.Semester\INNO1\TestProject\TestProject\Game.cpp(71,8): message : see reference to function template instantiation 'T &Entity::addComponent<TransformComponent,int,int,int>(int &&,int &&,int &&)' being compiled
with
[
T=TransformComponent
]
Map.cpp
main.cpp
Generating Code...
TestProject.vcxproj -> C:\Users\User\Desktop\FH_TECHNIKUM\3.Semester\INNO1\TestProject\x64\Debug\TestProject.exe

View File

@ -1,3 +1,4 @@
C:\Users\User\Desktop\FH_TECHNIKUM\3.Semester\INNO1\TestProject\TestProject\ECS.cpp;C:\Users\User\Desktop\FH_TECHNIKUM\3.Semester\INNO1\TestProject\TestProject\x64\Debug\ECS.obj
C:\Users\User\Desktop\FH_TECHNIKUM\3.Semester\INNO1\TestProject\TestProject\Game.cpp;C:\Users\User\Desktop\FH_TECHNIKUM\3.Semester\INNO1\TestProject\TestProject\x64\Debug\Game.obj
C:\Users\User\Desktop\FH_TECHNIKUM\3.Semester\INNO1\TestProject\TestProject\GameObject.cpp;C:\Users\User\Desktop\FH_TECHNIKUM\3.Semester\INNO1\TestProject\TestProject\x64\Debug\GameObject.obj
C:\Users\User\Desktop\FH_TECHNIKUM\3.Semester\INNO1\TestProject\TestProject\KeyboardController.cpp;C:\Users\User\Desktop\FH_TECHNIKUM\3.Semester\INNO1\TestProject\TestProject\x64\Debug\KeyboardController.obj