Basic multi animation support, with walking transition

This commit is contained in:
Doyle Thai 2016-06-23 21:34:38 +10:00
parent 7a2dc3da41
commit 7acf36cd59
4 changed files with 63 additions and 14 deletions

View File

@ -6,7 +6,11 @@ void renderer_entity(Renderer *renderer, Entity *entity, f32 rotate, v3 color)
shader_use(renderer->shader); shader_use(renderer->shader);
mat4 transMatrix = mat4_translate(entity->pos.x, entity->pos.y, 0.0f); mat4 transMatrix = mat4_translate(entity->pos.x, entity->pos.y, 0.0f);
mat4 rotateMatrix = mat4_rotate(rotate, 0.0f, 0.0f, 1.0f); mat4 rotateMatrix = mat4_rotate(rotate, 0.0f, 0.0f, 1.0f);
// NOTE(doyle): We draw everything as a unit square in OGL. Scale it to size // NOTE(doyle): We draw everything as a unit square in OGL. Scale it to size
// TODO(doyle): We should have a notion of hitbox size and texture size
// we're going to render so we can draw textures that may be bigger than the
// entity, (slightly) but keep a consistent bounding box
mat4 scaleMatrix = mat4_scale(entity->size.x, entity->size.y, 1.0f); mat4 scaleMatrix = mat4_scale(entity->size.x, entity->size.y, 1.0f);
mat4 model = mat4_mul(transMatrix, mat4_mul(rotateMatrix, scaleMatrix)); mat4 model = mat4_mul(transMatrix, mat4_mul(rotateMatrix, scaleMatrix));

View File

@ -39,17 +39,29 @@ void worldTraveller_gameInit(GameState *state)
state->state = state_active; state->state = state_active;
/* Init hero */ /* Init hero */
SpriteAnim heroAnim = {NULL, 1, 0, 1.0f, 1.0f};
// TODO(doyle): Get rid of
heroAnim.rect = (v4 *)calloc(1, sizeof(v4));
heroAnim.rect[0] = V4(746.0f, 1018.0f, 804.0f, 920.0f);
Entity heroEnt = {V2(0.0f, 0.0f), Entity heroEnt = {V2(0.0f, 0.0f),
V2(0.0f, 0.0f), V2(0.0f, 0.0f),
V2(58.0f, 98.0f), V2(58.0f, 98.0f),
direction_east, direction_east,
asset_getTexture(texlist_hero), asset_getTexture(texlist_hero),
heroAnim}; 0,
0,
0};
SpriteAnim heroAnimIdle = {NULL, 1, 0, 1.0f, 1.0f};
// TODO(doyle): Get rid of
heroAnimIdle.rect = (v4 *)calloc(1, sizeof(v4));
heroAnimIdle.rect[0] = V4(746.0f, 1018.0f, 804.0f, 920.0f);
heroEnt.anim[heroEnt.freeAnimIndex++] = heroAnimIdle;
SpriteAnim heroAnimWalk = {NULL, 3, 0, 0.10f, 0.10f};
// TODO(doyle): Get rid of
heroAnimWalk.rect = (v4 *)calloc(heroAnimWalk.numRects, sizeof(v4));
heroAnimWalk.rect[0] = V4(641.0f, 1018.0f, 699.0f, 920.0f);
heroAnimWalk.rect[1] = heroAnimIdle.rect[0];
heroAnimWalk.rect[2] = V4(849.0f, 1018.0f, 904.0f, 920.0f);
heroEnt.anim[heroEnt.freeAnimIndex++] = heroAnimWalk;
heroEnt.currAnimIndex = 0;
state->heroIndex = state->freeEntityIndex; state->heroIndex = state->freeEntityIndex;
state->entityList[state->freeEntityIndex++] = heroEnt; state->entityList[state->freeEntityIndex++] = heroEnt;
@ -72,8 +84,15 @@ void worldTraveller_gameInit(GameState *state)
npcAnim.rect[0] = V4(944.0f, 918.0f, 1010.0f, 816.0f); npcAnim.rect[0] = V4(944.0f, 918.0f, 1010.0f, 816.0f);
npcAnim.rect[1] = V4(944.0f, 812.0f, 1010.0f, 710.0f); npcAnim.rect[1] = V4(944.0f, 812.0f, 1010.0f, 710.0f);
Entity npcEnt = {V2(300.0f, 300.0f), V2(0.0f, 0.0f), hero->size, Entity npcEnt = {V2(300.0f, 300.0f),
direction_null, hero->tex, npcAnim}; V2(0.0f, 0.0f),
hero->size,
direction_null,
hero->tex,
0,
0,
0};
npcEnt.anim[npcEnt.freeAnimIndex++] = npcAnim;
state->entityList[state->freeEntityIndex++] = npcEnt; state->entityList[state->freeEntityIndex++] = npcEnt;
/* Init renderer */ /* Init renderer */
@ -158,6 +177,30 @@ INTERNAL void parseInput(GameState *state, const f32 dt)
ddPos = v2_scale(ddPos, 0.70710678118f); ddPos = v2_scale(ddPos, 0.70710678118f);
} }
f32 epsilon = 20.0f;
v2 epsilonDpos = v2_sub(V2(epsilon, epsilon),
V2(absolute(hero->dPos.x), absolute(hero->dPos.y)));
if (epsilonDpos.x >= 0.0f && epsilonDpos.y >= 0.0f)
{
hero->dPos = V2(0.0f, 0.0f);
// TODO(doyle): Change index to use some meaningful name like a string
// or enum for referencing animations, in this case 0 is idle and 1 is
// walking
if (hero->currAnimIndex == 1)
{
SpriteAnim *currAnim = &hero->anim[hero->currAnimIndex];
currAnim->currDuration = currAnim->duration;
currAnim->currRectIndex = 0;
hero->currAnimIndex = 0;
}
} else if (hero->currAnimIndex == 0)
{
SpriteAnim *currAnim = &hero->anim[hero->currAnimIndex];
currAnim->currDuration = currAnim->duration;
currAnim->currRectIndex = 0;
hero->currAnimIndex = 1;
}
f32 heroSpeed = CAST(f32)(22.0f * METERS_TO_PIXEL); // m/s^2 f32 heroSpeed = CAST(f32)(22.0f * METERS_TO_PIXEL); // m/s^2
if (state->keys[GLFW_KEY_LEFT_SHIFT]) if (state->keys[GLFW_KEY_LEFT_SHIFT])
{ {
@ -197,7 +240,7 @@ void worldTraveller_gameUpdateAndRender(GameState *state, const f32 dt)
for (i32 i = 0; i < state->freeEntityIndex; i++) for (i32 i = 0; i < state->freeEntityIndex; i++)
{ {
Entity *entity = &state->entityList[i]; Entity *entity = &state->entityList[i];
SpriteAnim *anim = &entity->anim; SpriteAnim *anim = &entity->anim[entity->currAnimIndex];
v4 currFrameRect = anim->rect[anim->currRectIndex]; v4 currFrameRect = anim->rect[anim->currRectIndex];
anim->currDuration -= dt; anim->currDuration -= dt;
@ -205,7 +248,7 @@ void worldTraveller_gameUpdateAndRender(GameState *state, const f32 dt)
{ {
anim->currRectIndex++; anim->currRectIndex++;
anim->currRectIndex = anim->currRectIndex % anim->numRects; anim->currRectIndex = anim->currRectIndex % anim->numRects;
currFrameRect = anim->rect[anim->currRectIndex]; currFrameRect = anim->rect[anim->currRectIndex];
anim->currDuration = anim->duration; anim->currDuration = anim->duration;
} }

View File

@ -31,7 +31,11 @@ typedef struct Entity
v2 size; v2 size;
enum Direction direction; enum Direction direction;
Texture *tex; Texture *tex;
SpriteAnim anim;
// TODO(doyle): String based access
SpriteAnim anim[16];
i32 freeAnimIndex;
i32 currAnimIndex;
} Entity; } Entity;
#endif #endif

View File

@ -5,9 +5,7 @@
#include <math.h> #include <math.h>
#define squared(x) (x * x) #define squared(x) (x * x)
#define absolute(x) ((x) > 0 ? (x) : -(x))
// TODO(doyle): Use this instead of window's math file ...
//#define abs(x) ((x) > 0 ? (x) : -(x))
/* VECTORS */ /* VECTORS */
typedef union v2 typedef union v2