Developer Insights

  GAF from animator and developer points of view

 

Developer: Glera Games
Location: Vilnius, Lithuania           
Game Title: 
Mahjong Treasure Quest 
Game Genre: Mahjong, Board

Framework: Cocos2d-x
Release date: March 17, 2016
 

Kirill Barkouski

Mobile game developer

Glera Games

 

To find the best solution to a task, people often have to reinvent the wheel.  At our company, we spend a lot of time developing products to perfection and have in the past taken up to two years.  While diligently searching for a solution for our animation challenges, we finally found the GAF Converter.

 

Once we began using animations made with GAF, we discovered that the animations could be quickly incorporated into our project without any negative impact on FPS.  Animation requirements became simpler with GAF, which subsequently offered new opportunities to our animators.  A considerable advantage of using GAF is that the new approach to animation arrangement reduces the size of our files by two-thirds!  For example, we had an animation based on our own method that was 300kb, but with GAF, the size of the animation was reduced to 100kb.  This reduction in size allowed us to add more animations with no significant increase in the size of the game; and a great number of active animations on the maps does appeal to our players.  Another cool feature is that our game, Mahjong Treasure Quest, now has touch control animations built into the level maps.  The project is written in Cocos2d-x; therefore, the sample code provided is in C++.

 

Mahjong adobe flash 2d animationMahjong Treasure quest flash 2d animation with GAF

 

Parallax is available when viewing Mahjong Treasure Quest maps of any level, so having smooth touch control was something we kept in the forefront of our minds.  Therefore, all GAF assets are pre-loaded within the initialization method.  While each map is being initialized, the assets are retrieved from a resource cache and assigned to a button:

const auto& chars = chaptersHeroes.at(chapterId); //animations for current chapter
for(const auto& ch : chars){
 string nameIdle = ch.first;

 auto mAssets = (GAFAsset*)_mapChars.at(nameIdle); //assets from cache
 auto animChar = mAssets->createObject();

 animChar->playSequence("idle", true); //start idle animation
 int startFrame = animChar->getStartFrame("idle");
 int endFrame = animChar->getEndFrame("idle");
 int framesCount = endFrame - startFrame;
 animChar->start();
 animChar->setFrame(startFrame +
                                                        Macros::random()%framesCount; //play animation from randrom place

 auto animHolder = Node::create(); //holder for animation object

 animHolder->setAnchorPoint(Vec2::ANCHOR_MIDDLE);
 animHolder->setContentSize(animChar->getContentSize());
 animHolder->addChild(animChar);
 animChar->setNormalizedPosition({.5f, .5f});

 auto charMenuItem = MenuItemLabel::create(animHolder,
                                    CC_CALLBACK_1(ParallaxLevelMap::onMapCharTap,
                                    this)); //menu item object with animation label
 //setting disable color for preventing gray image
 charMenuItem->setDisabledColor(Color3B::WHITE);
 charMenuItem->setAnchorPoint(Vec2::ZERO);
 itemSp->addChild(charMenuItem, 1, 1);

 Vec2 pos = ch.second; //relative position of center on chapter map

 //calculating relative position of bottom left angle
 pos -= Vec2(animChar->getContentSize().width*.5f/itemSp->getContentSize().width,
            animChar->getContentSize().height*.5/itemSp->getContentSize().height);
 charMenuItem->setNormalizedPosition(pos);
}

 

Button-pressing processing method:

void ParallaxLevelMap::onMapCharTap(cocos2d::Ref *sender){
       auto charMenuItem = (MenuItemLabel*)sender;
       //getting access to gaf object from menu item
       auto charObject = (GAFObject*)charMenuItem->getLabel()->getChildByTag(1);
       //not all objects have tap animation
       if(charObject->playSequence("tap", false)){
             //disable menu item for preventing lag on animation
             charMenuItem->setEnabled(false);
             charObject->setAnimationFinishedPlayDelegate([](GAFObject* object){
                   //back to normal state
                   ((MenuItem*)(object->getParent()->getParent()))->setEnabled(true);
                   object->playSequence("idle", true);
                   object->setAnimationFinishedPlayDelegate(nullptr);
             });
       }
}

 

The GAF Converter has given immense relief to our programmers and animators, making it possible for us to easily create a vivid and brisk experience for users.  The procedure of building in animation has entailed almost no issues.  All of the aforementioned, provides the best proof that GAF deserves its place on the market.

 

Kirill Kagan

Animator

Glera Games

 

The use of Flash in mobile gaming was rather limited until recently, as application size requirements involved certain restrictions.  It wasn’t possible to harness all the power of the technology for creating smooth animations with high FPS.  In particular, this was due to spritesheet atlases that simply forced animators to reduce the number of character animation frames as much as possible.  There have always been attempts to convert parametric Flash animation into a format compatible with third-party engines.  A lot of companies have used their own converters.  These attempts have provided fairly acceptable results, although the animator has always remained confined.  In order to make a converter understand the original Adobe Flash file correctly, it had to comply with quite strict requirements that included limitations on number of layers, the necessity to match animations in the file to a determined hierarchy, and no effects, masks, and nesting available.  The GAF Converter is the solution that allows use of Adobe Flash for gaming tasks of any kind.

Example of 2d flash animation made with gaf converter

The advantages from the point of view of an animator:

 

Disadvantages:

 

There is no special way or algorithm of how to use GAF.  Below, you’ll find my approach to creating character animations:

 

Character creation:

 

I’d like to say thanks to the GAF Media team for their excellent product that has helped solve so many issues, and revealed new Flash usage opportunities in a modern gamedev.