How to Customize ArtPig Animations

[Section1] [Section2] [Section3] [Section4] [Section5] [Section6]

Section 5: Running animation by APSSymbol

In the video guides, APAnimation class was used to play the exported files in iPhone. APAnimation, APXAnimation for Cocos2D-X, class is a simple implementation of using ArtPig Library, and it has a few methods like 'play', 'stop', and 'rootNode'. Using APAnimation is simple and easy but quite limited without allowing any kind of customizations. Since ArtPig Library is open source, you can look at APAnimation.mm to see how ArtPig symbols are used as an example.

For customizations, we need to use APSSymbol class directly. In 'HelloWorldLayer.h' file, we need to import 'artpig.h' which includes most of the header files of ArtPig classes. Then, declare APSSymbol object instead of APAnimation. As previously explained, a symbol represents a character which consists of graphic groups and action groups. In the current ArtPigEditor, there is only one symbol tagged with 'Symbol1' and one action group tagged with 'ActionGroup1'.

HelloWorldLayer.h

#import "artpig.h"
// HelloWorldLayer
@interface HelloWorldLayer : CCLayer
{
    artpig::APSSymbol *_symbol;
}
// returns a CCScene that contains the HelloWorldLayer as the only child
+(CCScene *) scene;
@end

Since most of the ArtPig classes are written in C++, we need to change the extensions of 'AppDelegate.m' and 'HelloWorldLayer.m' to 'mm' so that xcode compiler understands C++ codes.

Look at the modified 'HelloWorldLayer.mm' below.

HelloWorldLayer.mm

// Import the interfaces
#import "HelloWorldLayer.h"
using namespace artpig;
using namespace std;
// HelloWorldLayer implementation
@implementation HelloWorldLayer
+(CCScene *) scene
{
// 'scene' is an autorelease object.
CCScene *scene = [CCScene node];
// 'layer' is an autorelease object.
HelloWorldLayer *layer = [HelloWorldLayer node];
// add layer as a child to scene
[scene addChild: layer];
// return the scene
return scene;
}
// on "init" you need to initialize your instance
-(id) init
{
    
if( (self=[super init])) {
        /** Get the resource manager with project ID 'pigrun'. The returned 
         resource manager value is managed by APSResourceManager class, and it
         must not be deleted by 'HelloWorldLayer.mm'
         */
APSResourceManager *manager = APSResourceManager::getResourceManagerForProjectId("pigrun");
        if (manager) {
            // Allocate and initialize a new symbol by resource manager.
            _symbol = manager->newSymbol();
            if (_symbol) {
                // Set symbol's scale value to fit into the current screen.
                _symbol->setScale(manager->getScaleModelToDevice());
                
                // Preload all required data so that the animation runs without delay.
                _symbol->preloadData();
                
                // Add symbol's root CCNode object as a child of HelloWorldLayer.
                [self addChild:_symbol->getRootNode()];
                
                // Trigger prologue action groups.
                _symbol->triggerPrologueActionGroups();
            }
        }
}
return self;
}
// on "dealloc" you need to release all your retained objects
- (void) dealloc
{
    if (_symbol) {
        delete _symbol;
    }
    
    APSResourceManager::removeResourceManagerForProjectId("pigrun");
    
// don't forget to call "super dealloc"
[super dealloc];
}
@end

APSResourceManager manages media files and symbols, and there is one APSResourceManager object for each project. If symbols have their own image files for the same image, that might be wasteful. Instead, each symbol requests the project's resource manager to get media files.

APSResourceManager *manager = APSResourceManager::getResourceManagerForProjectId("pigrun");

APSResourceManager::getResourceManagerForProjectId("pigrun") creates a APSResourceManager object with the project id 'pigrun'. The APSResourceManager object is created only when getResourceManagerForProjectId() is called for the first time, and the same object is returned for the later calls. Because APSResourceManager objects are managed by APSResourceManager class, do not try to delete the returned object in your code.

_symbol = manager->newSymbol();

Once APSResourceManager object with project id 'pigrun' is obtained, we can create APSSymbol object. The object returned by newSymbol() is not managed by the resource manager, but APSSymbol class has a property 'resourceManager'. The property is set to the APSResourceManager object which has created the symbol.

You can call the method with a tag parameter, and newSymbol()'s default parameter is "Symbol1". You can call it with a symbol tag other than "Symbol1", like calling newSymbol("Car"), but it is only valid in the next update.

In addition, we can call newSymbol() as many times as we want to have more than one instance for the same symbol.

_symbol->setScale(manager->getScaleModelToDevice());

manager->getScaleModelToDevice() returns x and y scale values(CCPoint) which make model screen size fit into the current screen size in runtime.

_symbol->preloadData();

Calling _symbol->preloadData() loads all required data for the animation so that it runs without a break.

 [self addChild:_symbol->getRootNode()];

_symbol->getRootNode() returns the CCLayer object which is the root of the symbol's graphic structure. Keep in mind that _symbol, an APSSymbol object, owns the returned CCLayer, and the same CCLayer is returned for the later calls.

_symbol->triggerPrologueActionGroups();

A prologue action group is supposed to run at the beginning of animation in a project. In the current ArtPigEditor, there is only one symbol with one action group which is prologue. triggerPrologueActionGroups() method triggers the prologue action group to start.

Try to compile and run this project. Up to this point, 'HelloWorldLayer.mm' only plays the animation of 'pigrun' project, but we are ready to customize it.

pigrun-simulation