Я работаю над решением для управления текстурой и анимацией для небольшого побочного проекта. Хотя проект использует Allegro для рендеринга и ввода, мой вопрос в основном вращается вокруг C и управления памятью. Я хотел опубликовать это здесь, чтобы получить мысли и понимание подхода, так как я ужасен, когда дело доходит до указателей.
По сути, я пытаюсь загрузить все свои ресурсы текстур в центральный менеджер (textureManager), который представляет собой массив структур, содержащих объекты ALLEGRO_BITMAP. Текстуры, хранящиеся в textureManager, в основном представляют собой полные спрайт-листы.
Оттуда у меня есть структура anim (ation), которая содержит информацию, относящуюся к анимации (вместе с указателем на соответствующую текстуру в textureManager).
Чтобы дать вам представление, вот как я настраиваю и играю анимацию «прогулки» игроков:
createAnimation(&player.animations[0], "media/characters/player/walk.png", player.w, player.h);
playAnimation(&player.animations[0], 10);
Визуализация анимации текущего кадра - это всего лишь случай размывания определенной области листа спрайта, сохраненного в textureManager.
Для справки вот код для anim.h и anim.c. Я уверен, что то, что я делаю здесь, возможно, ужасный подход по ряду причин. Я хотел бы услышать о них! Я открываю себя для любых ловушек? Будет ли это работать, как я надеюсь?
anim.h
#ifndef ANIM_H
#define ANIM_H
#define ANIM_MAX_FRAMES 10
#define MAX_TEXTURES 50
struct texture {
bool active;
ALLEGRO_BITMAP *bmp;
};
struct texture textureManager[MAX_TEXTURES];
typedef struct tAnim {
ALLEGRO_BITMAP **sprite;
int w, h;
int curFrame, numFrames, frameCount;
float delay;
} anim;
void setupTextureManager(void);
int addTexture(char *filename);
int createAnimation(anim *a, char *filename, int w, int h);
void playAnimation(anim *a, float delay);
void updateAnimation(anim *a);
#endif
anim.c
void setupTextureManager() {
int i = 0;
for(i = 0; i < MAX_TEXTURES; i++) {
textureManager[i].active = false;
}
}
int addTextureToManager(char *filename) {
int i = 0;
for(i = 0; i < MAX_TEXTURES; i++) {
if(!textureManager[i].active) {
textureManager[i].bmp = al_load_bitmap(filename);
textureManager[i].active = true;
if(!textureManager[i].bmp) {
printf("Error loading texture: %s", filename);
return -1;
}
return i;
}
}
return -1;
}
int createAnimation(anim *a, char *filename, int w, int h) {
int textureId = addTextureToManager(filename);
if(textureId > -1) {
a->sprite = textureManager[textureId].bmp;
a->w = w;
a->h = h;
a->numFrames = al_get_bitmap_width(a->sprite) / w;
printf("Animation loaded with %i frames, given resource id: %i\n", a->numFrames, textureId);
} else {
printf("Texture manager full\n");
return 1;
}
return 0;
}
void playAnimation(anim *a, float delay) {
a->curFrame = 0;
a->frameCount = 0;
a->delay = delay;
}
void updateAnimation(anim *a) {
a->frameCount ++;
if(a->frameCount >= a->delay) {
a->frameCount = 0;
a->curFrame ++;
if(a->curFrame >= a->numFrames) {
a->curFrame = 0;
}
}
}