Showing posts with label Animation. Show all posts
Showing posts with label Animation. Show all posts

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;  
 }  

Thursday, January 15, 2015

Animated Sprite

Developing the capability for animated sprites caused me to re-design how an entity is created. Before, you'd ask the engine to create one and return it to you. Well since you already have to have the header file for this and I want to provide the capability of custom updates to the entities, I have to allow the user to subclass the entities. This means the user is responsible for cleaning up it's entities. 

Below is the code for adding a sprite. Each sprite is a frame in a sprite sheet and is looped based on the speed the user wants.


 #include "precomp.hpp"  
 #include "Engine.hpp"  
 #include "Animation.hpp"  
 #include <stdlib.h>  
 int main(int aargc, const char* argv[])  
 {  
   // Setup the window  
   Engine* engine = new Engine("Game Engine Sprite Test", 800,600);  
   // 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  
   Animation* link = new Animation();  
   link->setScale(.5f,.5f);  
   link->setTexture(t0);  
   link->setSpeed(200);  
   link->setLoop(true);  
   // StartX, StartY, Width, Height  
   link->addFrame(0,0,120,130);  
   link->addFrame(0,520,120,130);  
   link->addFrame(120,520,120,130);  
   link->addFrame(240,520,120,130);  
   link->addFrame(360,520,120,130);  
   link->addFrame(480,520,120,130);  
   link->addFrame(600,520,120,130);  
   link->addFrame(720,520,120,130);  
   link->addFrame(840,520,120,130);  
   link->addFrame(960,520,120,130);  
   link->addFrame(1080,520,120,130);  
   link->play();  
   // Set link as a collider  
   //link->setCollision(&square, ge::Collision_SOLID);  
   // Add our link as a sprite  
   engine->addSprite(link);  
   //std::vector<Entity*>::iterator it;  
   while(engine->isRunning())  
   {  
     engine->run();  
   }  
   delete engine;  
   engine = NULL;  
 }  


I will have another post explaining the entity class in detail and it's components.