Saturday, January 17, 2015

Expanding the Animation Class

The first thing I noticed after creating the animated sprite is that I had the need to allow a single sprite to have multiple animations. This was apparent when I wanted to have a player controlled sprite move around the screen in two dimensions. Instead of creating a new rendering component as I initially used, I chose to create an animated sprite and use the same rendering component. This means that the user can once again extend this animated class to do whatever they require. 

There are many corner cases that need to be analyzed later to determine how to make the animation transitions seamless.



Above is a small video of the character moving around the screen. I show some movement while holding the arrow keys down, as well as showing some intermittent key presses that make the sprite look like it's in slow motion.

Below is the controlling application example.


 #include "precomp.hpp"  
 #include "Engine.hpp"  
 #include "Animation.hpp"  
 #include "AnimatedSprite.hpp"  
 #include <stdlib.h>  
 #include <iostream>  
 Engine* engine;  
 AnimatedSprite* link;  
 std::string forward("f");  
 std::string back("b");  
 std::string left("l");  
 std::string right("r");  
 ge::Key lastKey = ge::Unknown;  
 int deltaMove = 10;  
 void doKeyRelease(int key)  
 {  
   static bool fs = false;  
   switch(key)  
   {  
     case ge::Escape:  
       engine->close();  
       break;  
     case ge::Return:  
       engine->setFullScreen(!fs);  
       fs = !fs;  
       break;  
     case ge::Left:  
     case ge::Right:  
     case ge::Down:  
     case ge::Up:  
       link->pause();  
     default:  
       break;  
   }  
 };  
 void doKeyPress(int key)  
 {  
   switch(key)  
   {  
     case ge::Left:  
       if(lastKey != ge::Left)  
       {  
         lastKey = ge::Left;  
         link->setAnimation(left);  
         link->goToFirstFrame();  
       }  
       else  
       {  
         link->play();  
       }  
       link->move(deltaMove * -1,0);  
       break;  
     case ge::Right:  
       if(lastKey != ge::Right)  
       {  
         lastKey = ge::Right;  
         link->setAnimation(right);  
         link->goToFirstFrame();  
       }  
       else  
       {  
         link->play();  
       }  
       link->move(deltaMove,0);  
       break;  
     case ge::Up:  
       if(lastKey != ge::Up)  
       {  
         lastKey = ge::Up;  
         link->setAnimation(back);  
         link->goToFirstFrame();  
       }  
       else  
       {  
         link->play();  
       }  
       link->move(0,deltaMove * -1);  
       break;  
     case ge::Down:  
       if(lastKey != ge::Down)  
       {  
         lastKey = ge::Down;  
         link->setAnimation(forward);  
         link->goToFirstFrame();  
       }  
       else  
       {  
         link->play();  
       }  
       link->move(0,deltaMove);  
       break;  
     default:  
       break;  
   }  
 };  
 int main(int aargc, const char* argv[])  
 {  
   // Setup the window  
   engine = new Engine("Game Engine Sprite Test", 800,600);  
   engine->setFrameRate(60);  
   engine->registerKeyPressedCallback(doKeyPress);  
   engine->registerKeyReleasedCallback(doKeyRelease);  
   // Load a texture  
   int t0 = engine->addTexture("link.png");  
   // Create collision area  
   std::vector<ge::fVertex> square;  
   square.push_back(ge::fVertex(0.0f,0.0f));  
   square.push_back(ge::fVertex(64.0f,0.0f));  
   square.push_back(ge::fVertex(64.0f,64.0f));  
   square.push_back(ge::fVertex(0.0f,64.0f));  
   // Create a collider sprite  
   link = new AnimatedSprite();  
   link->setScale(.5f,.5f);  
   link->setTexture(t0);  
   link->setSpeed(100);  
   // Set link as a collider  
   link->setCollision(&square, ge::Collision_SOLID);  
   Animation* linkForward = new Animation();  
   Animation* linkBack = new Animation();  
   Animation* linkLeft = new Animation();  
   Animation* linkRight = new Animation();  
   // StartX, StartY, Width, Height  
   // create link forward movement  
   linkForward->addFrame(0,0,120,130);  
   linkForward->addFrame(0,520,120,130);  
   linkForward->addFrame(120,520,120,130);  
   linkForward->addFrame(240,520,120,130);  
   linkForward->addFrame(360,520,120,130);  
   linkForward->addFrame(480,520,120,130);  
   linkForward->addFrame(600,520,120,130);  
   linkForward->addFrame(720,520,120,130);  
   linkForward->addFrame(840,520,120,130);  
   linkForward->addFrame(960,520,120,130);  
   linkForward->addFrame(1080,520,120,130);  
   // create link left movement  
   linkLeft->addFrame(0,130,120,130);  
   linkLeft->addFrame(0,650,120,130);  
   linkLeft->addFrame(120,650,120,130);  
   linkLeft->addFrame(240,650,120,130);  
   linkLeft->addFrame(360,650,120,130);  
   linkLeft->addFrame(480,650,120,130);  
   linkLeft->addFrame(600,650,120,130);  
   linkLeft->addFrame(720,650,120,130);  
   linkLeft->addFrame(840,650,120,130);  
   linkLeft->addFrame(960,650,120,130);  
   linkLeft->addFrame(1080,650,120,130);  
   // create link back movement  
   linkBack->addFrame(0,260,120,130);  
   linkBack->addFrame(0,780,120,130);  
   linkBack->addFrame(120,780,120,130);  
   linkBack->addFrame(240,780,120,130);  
   linkBack->addFrame(360,780,120,130);  
   linkBack->addFrame(480,780,120,130);  
   linkBack->addFrame(600,780,120,130);  
   linkBack->addFrame(720,780,120,130);  
   linkBack->addFrame(840,780,120,130);  
   linkBack->addFrame(960,780,120,130);  
   linkBack->addFrame(1080,780,120,130);  
   // create link right movement  
   linkRight->addFrame(0,390,120,130);  
   linkRight->addFrame(0,910,120,130);  
   linkRight->addFrame(120,910,120,130);  
   linkRight->addFrame(240,910,120,130);  
   linkRight->addFrame(360,910,120,130);  
   linkRight->addFrame(480,910,120,130);  
   linkRight->addFrame(600,910,120,130);  
   linkRight->addFrame(720,910,120,130);  
   linkRight->addFrame(840,910,120,130);  
   linkRight->addFrame(960,910,120,130);  
   linkRight->addFrame(1080,910,120,130);  
   // Add the animation to the sprite  
   link->addAnimation(forward, linkForward);  
   link->addAnimation(back, linkBack);  
   link->addAnimation(left, linkLeft);  
   link->addAnimation(right, linkRight);  
   // initialize the link sprite  
   link->setAnimation(forward);  
   link->pause();         // we don't want him moving  
   link->goToFirstFrame();     // not strictly neccessary  
   // Add our link as a sprite  
   engine->addSprite(link);  
   //std::vector<Entity*>::iterator it;  
   while(engine->isRunning())  
   {  
     engine->run();  
   }  
   delete engine;  
   engine = NULL;  
 }  

No comments:

Post a Comment