Animated sprites

This commit is contained in:
/nick haya 2022-02-07 15:14:52 +08:00
parent df225436fc
commit 5202f0afa3
4 changed files with 65 additions and 6 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@ -10,13 +10,16 @@ using namespace std;
using namespace Render;
class MainState : public State {
Object objs;
AnimatedObject objs;
Object title;
virtual void Create() {
title.create(0, 0, "data/bg.png");
AddObject(&title);
objs.create(50, 50, "data/smile.png");
AddObject(&objs);
objs.AddAnimation("idle", {{0, 0, 50, 50}, {50, 0, 50, 50}});
objs.PlayAnimation("idle");
objs.framerate = 1;
title.scale.y = 0;
title.center.x = WINDOW_WIDTH/2;
title.center.y = WINDOW_HEIGHT/2;

View File

@ -59,6 +59,11 @@ void Render::Object::create(int x, int y, string path){
_ori_h = h_;
}
void Render::AnimatedObject::create(int x, int y, string path){
Render::Object::create(x,y,path);
startTime = SDL_GetTicks();
}
void Render::State::AddObject(Render::Object* object) {
object->id = obj.size();
this->obj.push_back(object);
@ -79,6 +84,33 @@ void Render::Object::Draw(float dt) {
_sc_h = _h-cam_rect.h;
}
void Render::AnimatedObject::Draw(float dt) {
Render::Object::Draw(dt);
if (current_framename != "") {
int frameToDraw = ((SDL_GetTicks() - startTime) * framerate / 1000) % frameRects[current_framename].size();
current_frame = frameToDraw;
int sx = frameRects[current_framename][current_frame].x;
int sy = frameRects[current_framename][current_frame].y;
int sw = frameRects[current_framename][current_frame].w;
int sh = frameRects[current_framename][current_frame].h;
_sc_w = frameRects[current_framename][current_frame].w;
_sc_h = frameRects[current_framename][current_frame].h;
src_rect = {sx, sy, sw, sh};
}
}
void Render::AnimatedObject::AddAnimation(string anim_name, vector<SDL_Rect> points) {
frameRects.insert({anim_name, points});
}
void Render::AnimatedObject::PlayAnimation(string anim_name) {
current_framename = anim_name;
}
void Render::Object::centerSelf(AXIS axis) {
switch (axis) {
case X:
@ -162,7 +194,7 @@ bool Render::Update() {
lastUpdate = current;
current_state->Draw();
current_state->Draw(dT);
int end = SDL_GetPerformanceCounter();

View File

@ -46,7 +46,7 @@ namespace Render {
void create(int x = 0, int y = 0, string path = "");
void Draw(float dt);
virtual void Draw(float dt);
int x, y, w, h;
@ -61,6 +61,10 @@ namespace Render {
SDL_Texture* _tex = nullptr;
void set_property(string name, bool value);
SDL_Rect get_src() {return src_rect;};
SDL_Rect src_rect = {0, 0, 0, 0};
void centerSelf(AXIS axis = XY);
private:
int _x, _y, _w, _h;
@ -69,6 +73,22 @@ namespace Render {
map<string, bool> _properties;
};
class AnimatedObject : public Object {
public:
void create(int x = 0, int y = 0, string path = "");
void AddAnimation(string anim_name, vector<SDL_Rect> points);
void PlayAnimation(string anim_name);
virtual void Draw(float dt);
int framerate = 24;
map<string, vector<SDL_Rect>> frameRects;
string current_framename = "";
int current_frame = 0;
private:
int startTime;
};
/*
* A state is where you would contain said objects.
*/
@ -89,13 +109,17 @@ namespace Render {
/*
* State draw point. Make sure to call State::Draw() first when overriding this!!!
*/
virtual void Draw(){
virtual void Draw(float dt){
SDL_RenderClear(renderer);
if (obj.size() > 0)
for (int i = 0; i < obj.size(); i++) {
obj[i]->Draw(0);
obj[i]->Draw(dt);
SDL_Rect r = {obj[i]->_sc_x, obj[i]->_sc_y, obj[i]->_sc_w, obj[i]->_sc_h};
SDL_RenderCopyEx(renderer, obj[i]->_tex, NULL, &r, obj[i]->angle, &obj[i]->center, SDL_FLIP_NONE);
SDL_Rect r2 = obj[i]->src_rect;
if (r2.w != 0 && r2.h != 0)
SDL_RenderCopyEx(renderer, obj[i]->_tex, &r2, &r, obj[i]->angle, &obj[i]->center, SDL_FLIP_NONE);
else
SDL_RenderCopyEx(renderer, obj[i]->_tex, NULL, &r, obj[i]->angle, &obj[i]->center, SDL_FLIP_NONE);
}
SDL_RenderPresent(renderer);
}