BeagleRescue/src/ecs/SpriteComponent.h

220 lines
6.3 KiB
C++

/*
* 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,
spriteBackground,
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 fin(json);
if(fin.is_open()){
} else {
std::cout<<"json file is NOT open"<<std::endl;
}
if(fin.fail()){
std::cout<<"json file open fail"<<std::endl;
} else{
}
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");
int tagsCount = cJSON_GetArraySize(frameTags);
for (int t = 0; t < tagsCount; t++)
{
cJSON * animItem = cJSON_GetArrayItem(frameTags,t);
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);
}
Animation idle = Animation(0,3,100);
animations.emplace("Idle", idle);
Animation walk = Animation(1,3,100);
animations.emplace("Walk", walk);
Animation jump = Animation(2,1,100);
animations.emplace("Jump", jump);
Animation fall = Animation(3,1,100);
animations.emplace("Fall",fall);
Play("Idle");
}
setTex(id);
}
SpriteComponent(std::string id, SpriteType sType, char fontLetter, int letterW, int letterH, int letterScale)
{
spriteType = sType;
setTex(id);
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: case spriteBackground:
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: case spriteBackground:
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_ */