2017-04-23 1 views
0

J'apprends actuellement à créer mon premier jeu, et j'ai choisi SDL2 comme moteur de jeu. Je peux créer une animation pour le sprite du personnage principal séparément. Cependant, j'ai pensé que ce serait ridiculement fastidieux de contrôler le sprite de cette façon. J'ai donc chargé la feuille de sprite dans un tableau bidimensionnel en espérant que je serais capable de contrôler l'image-objet avec toutes sortes d'actions avec juste une feuille de sprite.Contrôle de l'image-objet avec un tableau bidimensionnel SDL2

#define HOR_FRAMES 16 
#define VER_FRAMES 16 


    // These are for the images and sprites 
    Sprite catGif; 
    SDL_Rect catRect[VER_FRAMES][HOR_FRAMES]; 

    bool load() 
    { 
    bool success = true; 
    // Load cat sprite sheets 
    if (!catGif.loadFromFile("./assets/pets/fighter_cat_sprite/cat_sprite_base_64.png", 
          sceneRenderer, 0X00, 0x00, 0x00)) 
    { 
     printf("%s", SDL_GetError()); 
     success = false; 
    } 
    else 
    { 
     int initX = 0; 
     int initY = 0; 
     for (int ver = 0; ver < VER_FRAMES; ver++) 
     { 

      for (int hor = 0; hor < HOR_FRAMES; hor++) 
      { 
       catRect[ver][hor].x = initX; 
       catRect[ver][hor].y = initY; 
       catRect[ver][hor].w = 64; 
       catRect[ver][hor].h = 64; 
       initX += 64; 
      } 
      initX = 0; 
      initY += 64; 
     } 
     initX = 0; 
     initY = 0; 
    } 
    return success; 
    } 

Je crée simple ENUM pour définir les actions qui sont les lignes de la feuille de sprite

enum Actions{ 
    IDLE, 
    WALK, 
    TOTAL 
}; 

Après cela, en main(), ajouter la logique de commande et définissez les variables loin que je pense de façon appropriée pour le rendu.

#include "init.h" 
#include "Sprite.h" 

LTexture background(SCREEN_WIDTH, SCREEN_HEIGHT); 
SDL_Rect bgRect; 

LTexture foreground(SCREEN_WIDTH, SCREEN_HEIGHT); 
SDL_Rect fgRect; 

int frame = 0; 
int maxFrame = 0; 
SDL_RendererFlip flipType; 
int main(int argc, char* argv[]) 
{ 
    init(); 
    load(); 

    int action; 

    bool quitFlag = false; 
    SDL_Event event; 

    while (!quitFlag) 
    { 
     action = IDLE; 
     while (SDL_PollEvent(&event) != 0) // Handle events in queue 
     { 
      if (event.type == SDL_QUIT || 
       event.key.keysym.sym == SDLK_ESCAPE) 
       quitFlag = true; 
     } 

     const Uint8* states = SDL_GetKeyboardState(NULL); 

     if (states[SDL_SCANCODE_A]) 
     { 
      maxFrame = 8; 
      action = WALK; 
      flipType = SDL_FLIP_HORIZONTAL; 
      catGif.moveLeft(); 
     } 
     else if (states[SDL_SCANCODE_D]) 
     { 
      maxFrame = 8; 
      action = WALK; 
      flipType = SDL_FLIP_NONE; 
      catGif.moveRight(); 
     } 
     else 
     { 
      maxFrame = 4; 
      action = IDLE; 
     } 

     // Drawing 
     background.clipRender(0, 0, sceneRenderer, &bgRect); 
     foreground.clipRender(0, SCREEN_HEIGHT/2, sceneRenderer, &fgRect); 

     SDL_Rect* currFrame = &catRect[action][frame/maxFrame]; 
     int x = catGif.xGetter(); 
     int y = catGif.yGetter(); 

     catGif.render(x, y, sceneRenderer, currFrame, NULL, 0, flipType); 

     // Update 
     SDL_RenderPresent(sceneRenderer); 

     frame++; 
     if (frame/maxFrame == maxFrame) 
     { 
      frame = 0; 
     } 
    } 

    clean(); 

    return 0; 
} 

L'image-objet a été diffusée lorsque j'ai appuyé sur les boutons A/D. Cependant, des problèmes sont apparus après que j'ai relâché les boutons, la feuille de sprite a continué à se jouer jusqu'à la fin et alors le sprite a disparu, même si la variable "action" a été réglée et il ne peut pas s'incrémenter, Je suis assez sûr de ça. S'il vous plaît aidez-moi à comprendre comment cela s'est passé, j'espère que je peux essayer de le réparer ou d'adopter une autre approche. Je vous remercie. J'utilise code :: blocks 16.01 sur Fedora Linux. Et ceci est la feuille de sprite: cat_sprite_sheet

Répondre

0

Vous devez réinitialiser frame à 0 lors du changement de l'état d'animation.

{ 
    maxFrame = ...; 
    frame = 0; 
    ... 
} 

Le bug est là en raison de == vérifier votre incrément de trame. Si le frame actuel est 40 et que vous libérez A/D, maxFrame est remis à 4. frame/maxFrame = 40/4 = 10 > 4, donc il ne sera jamais égal à maxFrame, et frame ne cesse d'augmenter pour toujours, ainsi faire disparaître votre sprite lorsque [frame/maxFrame] sortira de la limite. Reset frame à 0 pour résoudre ce problème.

+0

Merci d'avoir répondu, je vais essayer et vous dire le résultat. – CutTheCode

+0

Je me suis concentré sur le bug que vous avez signalé, puis j'ai ajouté un drapeau booléen pour indiquer les états de l'image-objet, puis j'ai ajouté la logique pour réinitialiser la variable frame, et cela a fonctionné, merci beaucoup! – CutTheCode