first commit

This commit is contained in:
2021-01-29 21:14:20 -05:00
commit b2acceb4b9
78 changed files with 6774 additions and 0 deletions

28
src/ecs/Animation.h Normal file
View File

@ -0,0 +1,28 @@
/*
* Animation.h
*
* Created on: Mar 27, 2020
* Author: ayoungblood
*/
#ifndef SRC_ECS_ANIMATION_H_
#define SRC_ECS_ANIMATION_H_
struct Animation
{
int index;
int frames;
int speed;
Animation() {}
Animation(int i, int f, int s)
{
index = i;
frames = f;
speed = s;
}
};
#endif /* SRC_ECS_ANIMATION_H_ */

104
src/ecs/ColliderComponent.h Normal file
View File

@ -0,0 +1,104 @@
/*
* ColliderComponent.h
*
* Created on: Mar 8, 2020
* Author: ayoungblood
*/
#ifndef SRC_ECS_COLLIDERCOMPONENT_H_
#define SRC_ECS_COLLIDERCOMPONENT_H_
#include <string>
#include "SDL2/SDL.h"
#include "Components.h"
#include "../assetmgr/TextureManager.h"
#include <iostream>
class ColliderComponent : public Component
{
public:
SDL_Rect collider;
std::string tag;
SDL_Texture* tex;
SDL_Rect srcR, destR;
TransformComponent* transform;
ColliderComponent(std::string t)
{
tag = t;
// collider.x = 10;
// collider.y = 52;
// collider.w = collider.h = 12;
}
ColliderComponent(std::string t, int xpos, int ypos, int size, int scale)
{
tag = t;
collider.x = xpos;
collider.y = ypos;
collider.w = collider.h = size*scale;
}
ColliderComponent(std::string t, int width, int height)
{
tag = t;
collider.w = width;
collider.h = height;
}
void init() override
{
if (!entity->hasComponent<TransformComponent>())
{
entity->addComponent<TransformComponent>();
}
transform = &entity->getComponent<TransformComponent>();
tex = TextureManager::LoadTexture("assets/ColTex.png");
srcR = { 0, 0, 16, 16};
destR = { collider.x, collider.y, collider.w, collider.h };
// if(tag == "player"){
// destR = { 18, 28, 24, 24 };
// transform->height = 24;
// transform->width = 24;
// std::cout << "player collider init() ran" << std::endl;
// std::cout << "destR.w: " << destR.w << std::endl;
// std::cout << "destR.h: " << destR.h << std::endl;
// }
// Game::colliders.push_back(this);
}
void update() override
{
// if(tag != "terrain")
// {
// collider.x = static_cast<int>(transform->position.x)+9;
// collider.y = static_cast<int>(transform->position.y)+28;
//// collider.w = transform->width * transform->scale;
//// collider.h = transform->height * transform->scale;
// collider.w = 12 * transform->scale;
// collider.h = 12 * transform->scale;
//
//// std::cout << "collider.w: " << collider.w << std::endl;
//// std::cout << "collider.h: " << collider.h << std::endl;
//// std::cout << "tag: " << tag << std::endl;
// }
destR.x = collider.x - Game::camera.x;
destR.y = collider.y - Game::camera.y;
// std::cout << "tag: " << tag << std::endl;
}
void draw() override
{
if(tag == "terrain")
{
TextureManager::Draw(tex, srcR, destR, SDL_FLIP_NONE);
}
}
};
#endif /* SRC_ECS_COLLIDERCOMPONENT_H_ */

23
src/ecs/Components.h Normal file
View File

@ -0,0 +1,23 @@
/*
* Components.h
*
* Created on: Feb 21, 2020
* Author: ayoungblood
*/
#ifndef SRC_COMPONENTS_H_
#define SRC_COMPONENTS_H_
#include "ECS.h"
#include "TransformComponent.h"
#include "SpriteComponent.h"
#include "KeyboardController.h"
#include "ColliderComponent.h"
#include "ProjectileComponent.h"
#include "TileComponent.h"
#include "UIFontComponent.h"
#endif /* SRC_COMPONENTS_H_ */

14
src/ecs/ECS.cpp Normal file
View File

@ -0,0 +1,14 @@
/*
* ECS.cpp
*
* Created on: Mar 24, 2020
* Author: ayoungblood
*/
#include "ECS.h"
void Entity::addGroup(Group mGroup)
{
groupBitset[mGroup] = true;
manager.AddToGroup(this, mGroup);
}

177
src/ecs/ECS.h Normal file
View File

@ -0,0 +1,177 @@
/*
* ECS.h
*
* Created on: Feb 21, 2020
* Author: ayoungblood
*/
#ifndef SRC_ECS_H_
#define SRC_ECS_H_
#include <iostream>
#include <vector>
#include <memory>
#include <algorithm>
#include <bitset>
#include <array>
class Component;
class Entity;
class Manager;
using ComponentID = std::size_t;
using Group = std::size_t;
inline ComponentID getNewComponentTypeID()
{
static ComponentID lastID = 0u;
return lastID++;
}
template <typename T> inline ComponentID getComponentTypeID() noexcept
{
static_assert (std::is_base_of<Component, T>::value, "");
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
{
public:
Entity* entity;
virtual void init() {}
virtual void update() {}
virtual void draw() {}
virtual ~Component() {}
};
class Entity
{
private:
Manager& manager;
bool active = true;
std::vector<std::unique_ptr<Component>> components;
ComponentArray componentArray;
ComponentBitSet componentBitSet;
GroupBitset groupBitset;
public:
Entity(Manager& mManager) : manager(mManager) {}
void update()
{
for(auto& c : components) c->update();
}
void draw()
{
for(auto& c : components) c->draw();
}
bool isActive() const { return active; }
void destroy() { 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>()];
}
template <typename T, typename... TArgs>
T& addComponent(TArgs&&... mArgs)
{
T* c(new T(std::forward<TArgs>(mArgs)...));
c->entity = this;
std::unique_ptr<Component> uPtr{ c };
components.emplace_back(std::move(uPtr));
componentArray[getComponentTypeID<T>()] = c;
componentBitSet[getComponentTypeID<T>()] = true;
c->init();
return *c;
}
template<typename T> T& getComponent() const
{
auto ptr(componentArray[getComponentTypeID<T>()]);
return *static_cast<T*>(ptr);
}
};
class Manager
{
private:
std::vector<std::unique_ptr<Entity>> entities;
std::array<std::vector<Entity*>, maxGroups> groupedEntities;
public:
void update()
{
for (auto& e : entities) e->update();
}
void draw()
{
for (auto& e : entities) e->draw();
}
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)
{
return !mEntity->isActive();
}),
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(*this);
std::unique_ptr<Entity> uPtr{ e };
entities.emplace_back(std::move(uPtr));
return *e;
}
};
#endif /* SRC_ECS_H_ */

View File

@ -0,0 +1,126 @@
/*
* KeyboardController.h
*
* Created on: Mar 1, 2020
* Author: ayoungblood
*/
#ifndef SRC_ECS_KEYBOARDCONTROLLER_H_
#define SRC_ECS_KEYBOARDCONTROLLER_H_
#include "../game/Game.hpp"
#include "ECS.h"
#include "Components.h"
#include "../assetmgr/AssetManager.h"
class KeyboardController : public Component
{
public:
TransformComponent *transform;
SpriteComponent *sprite;
Game *game;
void init() override
{
transform = &entity->getComponent<TransformComponent>();
sprite = &entity->getComponent<SpriteComponent>();
}
void update() override
{
if (Game::event.type == SDL_KEYDOWN)
{
switch (Game::event.key.keysym.sym)
{
case SDLK_UP:
transform->velocity.y = -1;
// sprite->Play("WalkNorth");
if (transform->velocity.x < 0)
{
// sprite->Play("WalkNW");
}
if (transform->velocity.x > 0)
{
// sprite->Play("WalkNW");
// sprite->spriteFlip = SDL_FLIP_HORIZONTAL;
}
break;
case SDLK_DOWN:
transform->velocity.y = 1;
// sprite->Play("WalkSouth");
if (transform->velocity.x < 0)
{
// sprite->Play("WalkSW");
}
if (transform->velocity.x > 0)
{
// sprite->Play("WalkSW");
// sprite->spriteFlip = SDL_FLIP_HORIZONTAL;
}
break;
case SDLK_LEFT:
transform->velocity.x = -1;
// sprite->Play("Walk");
break;
case SDLK_RIGHT:
transform->velocity.x = 1;
// sprite->Play("Walk");
// sprite->spriteFlip = SDL_FLIP_HORIZONTAL;
break;
case SDLK_k:
// game->printDebug("");
break;
case SDLK_j:
if (Mix_PlayChannel(-1, Game::assets->GetSoundClip("bwoop"),0) == 0)
{
Mix_PlayChannel(-1, Game::assets->GetSoundClip("bwoop"),0);
}
break;
default:
break;
}
}
if (Game::event.type == SDL_KEYUP)
{
switch (Game::event.key.keysym.sym)
{
case SDLK_UP:
transform->velocity.y = 0;
// sprite->Play("Idle");
// sprite->spriteFlip = SDL_FLIP_NONE;
break;
case SDLK_DOWN:
transform->velocity.y = 0;
// sprite->Play("Idle");
// sprite->spriteFlip = SDL_FLIP_NONE;
break;
case SDLK_LEFT:
transform->velocity.x = 0;
// sprite->Play("Idle");
break;
case SDLK_RIGHT:
transform->velocity.x = 0;
// sprite->Play("Idle");
// sprite->spriteFlip = SDL_FLIP_NONE;
break;
case SDLK_k:
if (Game::debugCollisionBoxes)
{ Game::debugCollisionBoxes = false; }
else
{Game::debugCollisionBoxes = true; }
break;
case SDLK_ESCAPE: // exit the game when Escape pressed
Game::isRunning = false;
break;
default:
break;
}
}
}
};
#endif /* SRC_ECS_KEYBOARDCONTROLLER_H_ */

View File

@ -0,0 +1,58 @@
/*
* Projectile.h
*
* Created on: Apr 4, 2020
* Author: ayoungblood
*/
#ifndef SRC_ECS_PROJECTILECOMPONENT_H_
#define SRC_ECS_PROJECTILECOMPONENT_H_
#include "ECS.h"
#include "Components.h"
#include "../game/Vector2D.h"
class ProjectileComponent : public Component
{
public:
ProjectileComponent(int rng, int sp, Vector2D vel) : range(rng), speed(sp), velocity(vel)
{}
~ProjectileComponent()
{}
void init() override
{
transform = &entity->getComponent<TransformComponent>();
transform->velocity = velocity;
// std::cout << transform->position << std::endl;
}
void update() override
{
distance += speed;
if (distance > range)
{
entity->destroy();
}
else if (transform->position.x > Game::camera.x + Game::camera.w ||
transform->position.x < Game::camera.x ||
transform->position.y > Game::camera.y +Game::camera.h ||
transform->position.y < Game::camera.y)
{
entity->destroy();
}
}
private:
TransformComponent* transform;
int range;
int speed;
int distance;
Vector2D velocity;
};
#endif /* SRC_ECS_PROJECTILECOMPONENT_H_ */

216
src/ecs/SpriteComponent.h Normal file
View File

@ -0,0 +1,216 @@
/*
* SpriteComponent.h
*
* Created on: Feb 22, 2020
* Author: ayoungblood
*/
#ifndef SRC_ECS_SPRITECOMPONENT_H_
#define SRC_ECS_SPRITECOMPONENT_H_
#define ASCII_START_IDX 32
#define ASCII_COUNT 96
#define ASCII_ROW_COUNT 16
#include "Components.h"
#include "SDL2/SDL.h"
#include "../assetmgr/TextureManager.h"
#include "Animation.h"
#include <map>
#include "../assetmgr/AssetManager.h"
#include "../cjson/cJSON.h"
#include <iostream>
#include <fstream>
#include <sstream>
#include <stdio.h>
#include <string>
class SpriteComponent : public Component
{
private:
TransformComponent *transform;
SDL_Texture *texture;
SDL_Rect srcRect, destRect;
char letter;
int frames = 0;
int speed = 100;
int letterWidth, letterHeight;
int scale = 1;
public:
enum SpriteType : std::size_t
{
spriteUIL0,
spriteUIL1,
spriteText,
spriteObject,
spriteTileMap,
spriteActor,
spriteAnimation,
spriteAtlas
};
SpriteType spriteType;
int animIndex = 0;
bool ui = false;
std::map<const char*, Animation> animations;
SDL_RendererFlip spriteFlip = SDL_FLIP_NONE;
// SpriteComponent() = default;
SpriteComponent(std::string id, SpriteType sType)
{
spriteType = sType;
setTex(id);
}
// One initializer to rule them all
SpriteComponent(std::string id, SpriteType sType, std::string json)
{
spriteType = sType;
if(sType == spriteAnimation)
{
std::ifstream jsonText(json);
std::ostringstream tmp;
tmp << jsonText.rdbuf();
std::string aJson = tmp.str();
cJSON * animJson = cJSON_Parse(aJson.c_str());
cJSON * meta = cJSON_GetObjectItem(animJson, "meta");
cJSON * frameTags = cJSON_GetObjectItem(meta,"frameTags");
// printf("frameTags:\n%s\n",cJSON_Print(frameTags));
int tagsCount = cJSON_GetArraySize(frameTags);
// printf("number of tags: \n%d\n",tagsCount);
// cJSON * arrItem = cJSON_GetArrayItem(frameTags,0);
// cJSON * animItem = cJSON_GetArrayItem(frameTags, 0);
// printf("Animation item: \n%s\n",cJSON_Print(animItem));
// printf("arrItem: \n%s\n",cJSON_Print(arrItem));
for (int t = 0; t < tagsCount; t++)
{
// printf("Tag: \n%d\n",t);
// printf("tag number: \n%d\n",t);
cJSON * animItem = cJSON_GetArrayItem(frameTags,t);
// printf("Animation item: \n%s\n",cJSON_Print(animItem));
cJSON * nameJson = cJSON_GetObjectItem(animItem, "name");
const char * name = cJSON_Print(nameJson);
int fromFrame = cJSON_GetObjectItem(animItem, "from")->valueint;
int toFrame = cJSON_GetObjectItem(animItem, "to")->valueint;
Animation anim = Animation(fromFrame,toFrame,100);
animations.emplace(name, anim);
Play(name);
// printf("Animation name: \n%s\n",name);
// printf("animation.frames: %d\n", animations[name].frames);
// printf("animations.index: %d\n", animations[name].index);
// printf("animations.speed: %d\n", animations[name].speed);
}
// if(!animations.empty()){
// printf("animations found!\n");
// }else{
// printf("No animations\n");
// }
// Play("S-Fly");
setTex(id);
}
}
SpriteComponent(std::string id, SpriteType sType, char fontLetter, int letterW, int letterH, int letterScale)
{
spriteType = sType;
setTex(id);
// text = isText;
letter = fontLetter;
letterWidth = letterW;
letterHeight = letterH;
scale = letterScale;
destRect.w = letterW*letterScale;
destRect.h = letterH*letterScale;
}
SpriteComponent(std::string id, SpriteType sType, SDL_Rect srcR, SDL_Rect destR)
{
spriteType = sType;
setTex(id);
srcRect = srcR;
destRect = destR;
}
~SpriteComponent()
{
SDL_DestroyTexture(texture);
}
void setTex(std::string id)
{
texture = Game::assets->GetTexture(id);
}
void init() override
{
transform = &entity->getComponent<TransformComponent>();
switch(spriteType)
{
case spriteText:
srcRect.x = ((letter-ASCII_START_IDX) % ASCII_ROW_COUNT)*letterWidth;
srcRect.y = ((letter-ASCII_START_IDX)/ASCII_ROW_COUNT)*letterHeight;
srcRect.w = letterWidth;
srcRect.h = letterHeight;
destRect.w = letterWidth*scale;
destRect.h = letterHeight*scale;
break;
case spriteUIL0: case spriteUIL1:
break;
case spriteActor: case spriteAnimation: case spriteAtlas: case spriteObject: case spriteTileMap:
srcRect.x = srcRect.y = 0;
srcRect.w = transform->width;
srcRect.h = transform->height;
break;
default:
break;
}
}
void update() override
{
switch(spriteType)
{
case spriteUIL0: case spriteUIL1: case spriteText:
destRect.x = static_cast<int>(transform->position.x);
destRect.y = static_cast<int>(transform->position.y);
break;
case spriteActor: case spriteObject: case spriteAtlas:
srcRect.y = animIndex * transform->height;
destRect.x = static_cast<int>(transform->position.x) - Game::camera.x;
destRect.y = static_cast<int>(transform->position.y) - Game::camera.y;
destRect.w = transform->width * transform->scale;
destRect.h = transform->height * transform->scale;
break;
case spriteTileMap:
break;
case spriteAnimation:
srcRect.x = srcRect.w * static_cast<int>((SDL_GetTicks()/speed) % frames);
srcRect.y = animIndex * transform->height;
destRect.x = static_cast<int>(transform->position.x) - Game::camera.x;
destRect.y = static_cast<int>(transform->position.y) - Game::camera.y;
destRect.w = transform->width * transform->scale;
destRect.h = transform->height * transform->scale;
break;
default:
break;
}
}
void draw() override
{
TextureManager::Draw(texture, srcRect, destRect, spriteFlip);
}
void Play(const char* animName)
{
frames = animations[animName].frames;
animIndex = animations[animName].index;
speed = animations[animName].speed;
}
};
#endif /* SRC_ECS_SPRITECOMPONENT_H_ */

58
src/ecs/TileComponent.h Normal file
View File

@ -0,0 +1,58 @@
/*
* TileComponent.h
*
* Created on: Mar 21, 2020
* Author: ayoungblood
*/
#ifndef SRC_ECS_TILECOMPONENT_H_
#define SRC_ECS_TILECOMPONENT_H_
#include "ECS.h"
#include "SDL2/SDL.h"
#include "../assetmgr/AssetManager.h"
class TileComponent : public Component
{
public:
SDL_Texture* texture;
SDL_Rect srcRect, destRect;
Vector2D position;
TileComponent() = default;
~TileComponent()
{
SDL_DestroyTexture(texture);
}
TileComponent(int srcX, int srcY, int xpos, int ypos, int tsize, int tscale, std::string id)
{
texture = Game::assets->GetTexture(id);
position.x = xpos;
position.y = ypos;
srcRect.x = srcX;
srcRect.y = srcY;
srcRect.w = srcRect.h = tsize;
destRect.x = xpos;
destRect.y = ypos;
destRect.w = destRect.h = tsize * tscale;
}
void update() override
{
destRect.x = position.x - Game::camera.x;
destRect.y = position.y - Game::camera.y;
}
void draw() override
{
TextureManager::Draw(texture, srcRect, destRect, SDL_FLIP_NONE);
}
};
#endif /* SRC_ECS_TILECOMPONENT_H_ */

View File

@ -0,0 +1,68 @@
/*
* TransformComponent.h
*
* Created on: Feb 22, 2020
* Author: ayoungblood
*/
#ifndef SRC_ECS_TransformComponent_H_
#define SRC_ECS_TransformComponent_H_
#include "Components.h"
#include "../game/Vector2D.h"
class TransformComponent : public Component
{
public:
Vector2D position;
Vector2D velocity;
int height = 40;
int width = 30;
int scale = 1;
int speed = 2;
TransformComponent()
{
position.Zero();
}
TransformComponent(int sc)
{
position.x = 64*sc;
position.y = 80*sc;
scale = sc;
speed = speed*sc;
}
TransformComponent(float x, float y)
{
position.Zero();
}
TransformComponent(int x, int y, int w, int h, int sc)
{
position.x = x;
position.y = y;
width = w;
height = h;
scale = sc;
speed = speed*sc;
}
void init() override
{
velocity.Zero();
}
void update() override
{
position.x += velocity.x * speed;
position.y += velocity.y * speed;
}
};
#endif /* SRC_ECS_TransformComponent_H_ */

83
src/ecs/UIFontComponent.h Normal file
View File

@ -0,0 +1,83 @@
/*
* UIFontComponent.h
*
* Created on: May 14, 2020
* Author: ayoungblood
*/
#ifndef SRC_ECS_UIFONTCOMPONENT_H_
#define SRC_ECS_UIFONTCOMPONENT_H_
#define ASCII_START_IDX 32
#define ASCII_COUNT 96
#define ASCII_ROW_COUNT 16
#include "Components.h"
#include "SDL2/SDL.h"
#include "../assetmgr/AssetManager.h"
class UIFontComponent : public Component
{
private:
// SDL_Texture * texture;
// Font dimensions
int _LetterWidth;
int _LetterHeight;
// Track current letter on texture
SDL_Rect _LetterClips[ASCII_COUNT];
public:
// SDL_RendererFlip spriteFlip = SDL_FLIP_NONE;
SDL_Texture* texture;
SDL_Rect srcRect, destRect;
Vector2D position;
// UIFontComponent() = default;
UIFontComponent(std::string id, int letterW, int letterH, int xpos, int ypos, int scale)
{
texture = Game::assets->GetTexture(id);
srcRect = UIFontComponent::SetCharClips(texture, xpos, ypos);
position.x = xpos;
position.y = ypos;
destRect.x = xpos;
destRect.y = ypos;
destRect.w = letterW * scale;
destRect.h = letterH * scale;
}
~UIFontComponent()
{
SDL_DestroyTexture(texture);
}
void update() override
{
}
void draw() override
{
TextureManager::Draw(texture, srcRect, destRect, SDL_FLIP_NONE);
}
SDL_Rect SetCharClips(SDL_Texture* fontTex, int x, int y)
{
SDL_Rect letterClip;
for (int i = 0; i < ASCII_COUNT; ++i)
{
_LetterClips[i].x = x + ((i % ASCII_ROW_COUNT) * _LetterWidth);
_LetterClips[i].y = y + ((i / ASCII_ROW_COUNT) * _LetterHeight);
_LetterClips[i].w = _LetterWidth;
_LetterClips[i].h = _LetterHeight;
letterClip = _LetterClips[i];
}
return letterClip;
}
};
#endif /* SRC_ECS_UIFONTCOMPONENT_H_ */