Jump to content

  • Log In with Google      Sign In   
  • Create Account

Calling all IT Pros from Canada and Australia.. we need your help! Support our site by taking a quick sponsored surveyand win a chance at a $50 Amazon gift card. Click here to get started!


Like
1Likes
Dislike

Cocos2d: Working with Sprites

By Nathan Burba | Published Feb 21 2012 09:31 PM in Mobile Development

sprite ccsprite velocity bat using sprites recipe animation draw
If you find this article contains errors or problems rendering it unreadable (missing images or files, mangled code, improper text formatting, etc) please contact the editor so corrections can be made. Thank you for helping us improve this resource

Cocos2d is first and foremost a rich graphical API which allows a game developer easy access to a broad range of functionality. In this article, we will take a look at the basic uses of sprites.

In this article by Nathan Burba, author of Cocos2d for iPhone 1 Game Development Cookbook, we will cover the following topics:


Drawing sprites
The most fundamental task in 2D game development is drawing a sprite. Cocos2d provides the user with a lot of flexibility in this area. In this recipe we will cover drawing sprites using CCSprite, spritesheets, CCSpriteFrameCache, and CCSpriteBatchNode. We will also go over mipmapping. In this recipe we see a scene with Alice from Through The Looking Glass.

Posted Image


Getting ready
Please refer to the project RecipeCollection01 for the full working code of this recipe.

How to do it...
Execute the following code:

@implementation Ch1_DrawingSprites
-(CCLayer*) runRecipe {
  /*** Draw a sprite using CCSprite ***/
  CCSprite *tree1 = [CCSprite spriteWithFile:@"tree.png"];

  //Position the sprite using the tree base as a guide (y anchor 
point = 0)
[tree1 setPosition:ccp(20,20)];
  tree1.anchorPoint = ccp(0.5f,0);
  [tree1 setScale:1.5f];
  [self addChild:tree1 z:2 tag:TAG_TREE_SPRITE_1];

  /*** Load a set of spriteframes from a PLIST file and draw one by
name ***/

  //Get the sprite frame cache singleton
  CCSpriteFrameCache *cache = [CCSpriteFrameCache
sharedSpriteFrameCache];

  //Load our scene sprites from a spritesheet
  [cache addSpriteFramesWithFile:@"alice_scene_sheet.plist"];

  //Specify the sprite frame and load it into a CCSprite
  CCSprite *alice = [CCSprite spriteWithSpriteFrameName:@"alice.png"];

  //Generate Mip Maps for the sprite
  [alice.texture generateMipmap];
  ccTexParams texParams = { GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR, GL_
CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE };
  [alice.texture setTexParameters:&texParams];

  //Set other information.
  [alice setPosition:ccp(120,20)];
  [alice setScale:0.4f];
  alice.anchorPoint = ccp(0.5f,0);

  //Add Alice with a zOrder of 2 so she appears in front of other
sprites
  [self addChild:alice z:2 tag:TAG_ALICE_SPRITE];

  //Make Alice grow and shrink.
  [alice runAction: [CCRepeatForever actionWithAction:
   [CCSequence actions:[CCScaleTo actionWithDuration:4.0f scale
:0.7f], [CCScaleTo actionWithDuration:4.0f scale:0.1f], nil] ] ];

  /*** Draw a sprite CGImageRef ***/
  UIImage *uiImage = [UIImage imageNamed: @"cheshire_cat.png"];
  CGImageRef imageRef = [uiImage CGImage];
  CCSprite *cat = [CCSprite spriteWithCGImage:imageRef key:@
"cheshire_cat.png"];
  [cat setPosition:ccp(250,180)];
  [cat setScale:0.4f];
  [self addChild:cat z:3 tag:TAG_CAT_SPRITE];

  /*** Draw a sprite using CCTexture2D ***/
  CCTexture2D *texture = [[CCTextureCache sharedTextureCache]
addImage:@"tree.png"];
  CCSprite *tree2 = [CCSprite spriteWithTexture:texture];
  [tree2 setPosition:ccp(300,20)];
  tree2.anchorPoint = ccp(0.5f,0);
  [tree2 setScale:2.0f];
  [self addChild:tree2 z:2 tag:TAG_TREE_SPRITE_2];

  /*** Draw a sprite using CCSpriteFrameCache and CCTexture2D ***/
  CCSpriteFrame *frame = [CCSpriteFrame frameWithTexture:texture
rect:tree2.textureRect];
  [[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFrame:
frame name:@"tree.png"];
  CCSprite *tree3 = [CCSprite spriteWithSpriteFrame:[[CCSpriteFrame
Cache sharedSpriteFrameCache] spriteFrameByName:@"tree.png"]];
  [tree3 setPosition:ccp(400,20)];
  tree3.anchorPoint = ccp(0.5f,0);
  [tree3 setScale:1.25f];
  [self addChild:tree3 z:2 tag:TAG_TREE_SPRITE_3];

  /*** Draw sprites using CCBatchSpriteNode ***/

  //Clouds
  CCSpriteBatchNode *cloudBatch = [CCSpriteBatchNode
batchNodeWithFile:@"cloud_01.png" capacity:10];
  [self addChild:cloudBatch z:1 tag:TAG_CLOUD_BATCH];
  for(int x=0; x   CCSprite *s = [CCSprite spriteWithBatchNode:cloudBatch
rect:CGRectMake(0,0,64,64)];
   [s setOpacity:100];
   [cloudBatch addChild:s];
   [s setPosition:ccp(arc4random()%500-50, arc4random()%150+200)];
  }

  //Middleground Grass
  int capacity = 10;
  CCSpriteBatchNode *grassBatch1 = [CCSpriteBatchNode
batchNodeWithFile:@"grass_01.png" capacity:capacity];
  [self addChild:grassBatch1 z:1 tag:TAG_GRASS_BATCH_1];
  for(int x=0; x   CCSprite *s = [CCSprite spriteWithBatchNode:grassBatch1
rect:CGRectMake(0,0,64,64)];
   [s setOpacity:255];
   [grassBatch1 addChild:s];
   [s setPosition:ccp(arc4random()%500-50, arc4random()%20+70)];
  }

  //Foreground Grass
  CCSpriteBatchNode *grassBatch2 = [CCSpriteBatchNode
batchNodeWithFile:@"grass_01.png" capacity:10];
  [self addChild:grassBatch2 z:3 tag:TAG_GRASS_BATCH_2];
  for(int x=0; x   CCSprite *s = [CCSprite spriteWithBatchNode:grassBatch2
rect:CGRectMake(0,0,64,64)];
   [s setOpacity:255];
   [grassBatch2 addChild:s];
   [s setPosition:ccp(arc4random()%500-50, arc4random()%40-10)];
  }

  /*** Draw colored rectangles using a 1px x 1px white texture ***/

  //Draw the sky using blank.png
  [self drawColoredSpriteAt:ccp(240,190) withRect:CGRectMa
ke(0,0,480,260) withColor:ccc3(150,200,200) withZ:0];

  //Draw the ground using blank.png
  [self drawColoredSpriteAt:ccp(240,30)
withRect:CGRectMake(0,0,480,60) withColor:ccc3(80,50,25) withZ:0];

  return self;
}

-(void) drawColoredSpriteAt:(CGPoint)position withRect:(CGRect)rect
withColor:(ccColor3B)color withZ:(float)z {
  CCSprite *sprite = [CCSprite spriteWithFile:@"blank.png"];
  [sprite setPosition:position];
  [sprite setTextureRect:rect];
  [sprite setColor:color];
  [self addChild:sprite];

  //Set Z Order
  [self reorderChild:sprite z:z];
}

@end

How it works...
This recipe takes us through most of the common ways of drawing sprites:
  • Creating a CCSprite from a file:
    First, we have the simplest way to draw a sprite. This involves using the CCSprite class method as follows:
    +(id)spriteWithFile:(NSString*)filename;
    

    This is the most straightforward way to initialize a sprite and is adequate for many situations.
  • Other ways to load a sprite from a file:
    After this, we will see examples of CCSprite creation using UIImage/CGImageRef, CCTexture2D, and a CCSpriteFrame instantiated using a CCTexture2D object. CGImageRef support allows you to tie Cocos2d into other frameworks and toolsets. CCTexture2D is the underlying mechanism for texture creation.
  • Loading spritesheets using CCSpriteFrameCache:
    Next, we will see the most powerful way to use sprites, the CCSpriteFrameCache class. Introduced in Cocos2d-iPhone v0.99, the CCSpriteFrameCache singleton is a cache of all sprite frames. Using a spritesheet and its associated PLIST file we can load multiple sprites into the cache. From here we can create CCSprite objects with sprites from the cache:
    +(id)spriteWithSpriteFrameName:(NSString*)filename;
    
  • Mipmapping:
    Mipmapping allows you to scale a texture or to zoom in or out of a scene without aliasing your sprites. When we scale Alice down to a small size, aliasing will inevitably occur. With mipmapping turned on, Cocos2d dynamically generates lower resolution textures to smooth out any pixelation at smaller scales. Go ahead and comment out the following lines:
    [alice.texture generateMipmap];
      ccTexParams texParams = { GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR,
    GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE };
      [alice.texture setTexParameters:&texParams];
    

    Now you should see this pixelation as Alice gets smaller.
  • Drawing many derivative sprites with CCSpriteBatchNode:
    The CCSpriteBatchNode class, added in v0.99.5, introduces an efficient way to draw and re-draw the same sprite over and over again. A batch node is created with the following method:
    CCSpriteBatchNode *cloudBatch = [CCSpriteBatchNode
    batchNodeWithFile:@"cloud_01.png" capacity:10];
    

    Then, you create as many sprites as you want using the follow code:
    CCSprite *s = [CCSprite spriteWithBatchNode:cloudBatch
    rect:CGRectMake(0,0,64,64)];
      [cloudBatch addChild:s];
    

    Setting the capacity to the number of sprites you plan to draw tells Cocos2d to allocate that much space. This is yet another tweak for extra efficiency, though it is not absolutely necessary that you do this. In these three examples we draw 10 randomly placed clouds and 60 randomly placed bits of grass.
  • Drawing colored rectangles:
    Finally, we have a fairly simple technique that has a variety of uses. By drawing a sprite with a blank 1px by 1px white texture and then coloring it and setting its textureRect property we can create very useful colored bars:
    CCSprite *sprite = [CCSprite spriteWithFile:@"blank.png"];
    [sprite setTextureRect:CGRectMake(0,0,480,320)];
    [sprite setColor:ccc3(255,128,0)];
    

    In this example we have used this technique to create very simple ground and sky backgrounds.




Coloring sprites
In the previous recipe we used colored rectangles to draw both the ground and the sky. The ability to set texture color and opacity are simple tools which, if used properly, can create very cool effects. In this recipe we will create a cinematic scene where two samurai face each other with glowing swords.

Posted Image


Getting ready
Please refer to the project RecipeCollection01 for full working code of this recipe. Also, note that some code has been omitted for brevity.

How to do it...
Execute the following code:

#import "CCGradientLayer.h

@implementation Ch1_ColoringSprites

-(CCLayer*) runRecipe {
  [self initButtons];

  //The Fade Scene Sprite
  CCSprite *fadeSprite = [CCSprite spriteWithFile:@"blank.png"];
  [fadeSprite setOpacity:0];
  [fadeSprite setPosition:ccp(240,160)];
  [fadeSprite setTextureRect:CGRectMake(0,0,480,320)];
  [self addChild:fadeSprite z:3 tag:TAG_FADE_SPRITE];

  //Add a gradient below the mountains
//CCGradientDirectionT_B is an enum provided by CCGradientLayer
  CCGradientLayer *gradientLayer = [CCGradientLayer layerWithColor:
ccc4(61,33,62,255) toColor:ccc4(65,89,54,255) withDirection:
CCGradient DirectionT_B width:480 height:100];
  [gradientLayer setPosition:ccp(0,50)];
  [self addChild:gradientLayer z:0 tag:TAG_GROUND_GRADIENT];

  //Add a sinister red glow gradient behind the evil samurai
  CCGradientLayer *redGradient = [CCGradientLayer
layerWithColor:ccc4(0,0,0,0) toColor:ccc4(255,0,0,100) withDirection
:CCGradientDirectionT_B width:200 height:200];
  [redGradient setPosition:ccp(280,60)];
  [redGradient setRotation:-90];
  [self addChild:redGradient z:2 tag:TAG_RED_GRADIENT];

  // Make the swords glow
  [self glowAt:ccp(230,280) withScale:CGSizeMake(3.0f, 11.0f)
withColor:ccc3(0,230,255) withRotation:45.0f withSprite:goodSamurai];
  [self glowAt:ccp(70,280) withScale:CGSizeMake(3.0f, 11.0f)
withColor:ccc3(255,200,2) withRotation:-45.0f withSprite:evilSamurai];

  return self;
}

-(void) initButtons {
  [CCMenuItemFont setFontSize:16];

  //'Fade To Black' button
  CCMenuItemFont* fadeToBlack = [CCMenuItemFont itemFromString:@
"FADE TO BLACK" target:self selector:@selector(fadeToBlackCallback:)];
  CCMenu *fadeToBlackMenu = [CCMenu menuWithItems:fadeToBlack, nil];
   fadeToBlackMenu.position = ccp( 180 , 20 );
   [self addChild:fadeToBlackMenu z:4 tag:TAG_FADE_TO_BLACK];
}

/* Fade the scene to black */
-(void) fadeToBlackCallback:(id)sender {
  CCSprite *fadeSprite = [self getChildByTag:TAG_FADE_SPRITE];
  [fadeSprite stopAllActions];
  [fadeSprite setColor:ccc3(0,0,0)];
  [fadeSprite setOpacity:0.0f];
  [fadeSprite runAction:
  [CCSequence actions:[CCFadeIn actionWithDuration:2.0f], [CCFadeOut
actionWithDuration:2.0f], nil] ];
}

/* Create a glow effect */
-(void) glowAt:(CGPoint)position withScale:(CGSize)size
withColor:(ccColor3B)color withRotation:(float)rotation
withSprite:(CCSprite*)sprite {
  CCSprite *glowSprite = [CCSprite spriteWithFile:@"fire.png"];
  [glowSprite setColor:color];
  [glowSprite setPosition:position];
  [glowSprite setRotation:rotation];
  [glowSprite setBlendFunc: (ccBlendFunc) { GL_ONE, GL_ONE }];
  [glowSprite runAction: [CCRepeatForever actionWithAction:
   [CCSequence actions:[CCScaleTo actionWithDuration:0.9f
scaleX:size.width scaleY:size.height], [CCScaleTo
actionWithDuration:0.9f scaleX:size.width*0.75f scaleY:size.
height*0.75f], nil] ] ];
  [glowSprite runAction: [CCRepeatForever actionWithAction:
   [CCSequence actions:[CCFadeTo actionWithDuration:0.9f
opacity:150], [CCFadeTo actionWithDuration:0.9f opacity:255], nil] ]
];
  [sprite addChild:glowSprite];
}

@end

How it works...
This recipe shows a number of color based techniques.
  • Setting sprite color:
    The simplest use of color involves setting the color of a sprite using the following method:
    -(void) setColor:(ccColor3B)color;
    

    Setting sprite color effectively reduces the color you can display but it allows some programmatic flexibility in drawing. In this recipe we use setColor for a number of things, including drawing a blue sky, a yellow sun, black "dramatic movie bars", and more.
    ccColor3B is a C struct which contains three GLubyte variables. Use the following helper macro to create ccColor3B structures:
    ccColor3B ccc3(const GLubyte r, const GLubyte g, const GLubyte
    b);
    

    Cocos2d also specifies a number of pre-defined colors as constants. These include the following:
    ccWHITE, ccYELLOW, ccBLUE, ccGREEN, ccRED,
    ccMAGENTA, ccBLACK, ccORANGE, ccGRAY
    
  • Fading to a color:
    To fade a scene to a specific color we use the blank.png technique we went over in the last recipe. We first draw a sprite as large as the screen, then color the sprite to the color we want to fade to, and then finally run a CCFadeIn action on the sprite to fade to that color:
    [fadeSprite setColor:ccc3(255,255,255)];
    [fadeSprite setOpacity:0.0f];
    [fadeSprite runAction: [CCFadeIn actionWithDuration:2.0f] ];
    
  • Using CCGradientLayer:
    Using the CCGradientLayer class we can programmatically create gradients. To make the mountains in the background fade into the ground the two samurai are standing on we created a gradient using this method:
      CCGradientLayer *gradientLayer = [CCGradientLayer layerWithColor
    :ccc4(61,33,62,255) toColor:ccc4(65,89,54,255) withDirection:CCGra
    dientDirectionT_B width:480 height:100];
      [gradientLayer setPosition:ccp(0,50)];
      [self addChild:gradientLayer z:0 tag:TAG_GROUND_GRADIENT];
    

    Because CCGradientLayer lets you control opacity as well as color, it has many uses. As you can see there is also a sinister red glow behind the evil samurai.
  • Making a sprite glow: To make the swords in the demo glow we use subtle color manipulation, additive blending and fading and scaling actions. First we load the fire.png sprite supplied by Cocos2d. By changing its X and Y scale independently we can make it thinner or fatter. Once you have the desired scale ratio (in this demo we use x:y 3:11 because the sword is so thin) you can constantly scale and fade the sprite in and out to give some life to the effect. You also need to set the blend function to { GL_ONE, GL_ONE } for additive blending. Finally this effect sprite is added to the actual sprite to make it seem like it glows.
    CCSprite *glowSprite = [CCSprite spriteWithFile:@"fire.png"];
      [glowSprite setColor:color];
      [glowSprite setPosition:position];
      [glowSprite setRotation:rotation];
      [glowSprite setBlendFunc: (ccBlendFunc) { GL_ONE, GL_ONE }];
      [glowSprite runAction: [CCRepeatForever actionWithAction:
      [CCSequence actions:[CCScaleTo actionWithDuration:0.9f
    scaleX:size.width scaleY:size.height], [CCScaleTo
    actionWithDuration:0.9f scaleX:size.width*0.75f scaleY:size.
    height*0.75f], nil] ] ];
      [glowSprite runAction: [CCRepeatForever actionWithAction:
      [CCSequence actions:[CCFadeTo actionWithDuration:0.9f
    opacity:150], [CCFadeTo actionWithDuration:0.9f opacity:255], nil]
    ] ];
      [sprite addChild:glowSprite];
    








Animating sprites
Now it is time to add some animation to our sprites. One thing that should be stressed about animation is that it is only as complicated as you make it. In this recipe we will use very simple animation to create a compelling effect. We will create a scene where bats fly around a creepy looking castle. I've also added a cool lightning effect based on the technique used to make the swords glow in the previous recipe.

Posted Image


Getting ready
Please refer to the project RecipeCollection01 for full working code of this recipe. Also note that some code has been omitted for brevity.

How to do it...
Execute the following code:

//SimpleAnimObject.h
@interface SimpleAnimObject : CCSprite {
  int animationType;
  CGPoint velocity;
}

@interface Ch1_AnimatingSprites {
  NSMutableArray *bats;
  CCAnimation *batFlyUp;
  CCAnimation *batGlideDown;
  CCSprite *lightningBolt;
  CCSprite *lightningGlow;
  int lightningRemoveCount;
}

-(CCLayer*) runRecipe {
  //Add our PLIST to the SpriteFrameCache
  [[CCSpriteFrameCache sharedSpriteFrameCache] 
addSpriteFramesWithFile:@"simple_bat.plist"];

  //Add a lightning bolt
  lightningBolt = [CCSprite spriteWithFile:@"lightning_bolt.png"];
  [lightningBolt setPosition:ccp(240,160)];
  [lightningBolt setOpacity:64];
  [lightningBolt retain];

  //Add a sprite to make it light up other areas.
  lightningGlow = [CCSprite spriteWithFile:@"lightning_glow.png"];
  [lightningGlow setColor:ccc3(255,255,0)];
  [lightningGlow setPosition:ccp(240,160)];
  [lightningGlow setOpacity:100];
  [lightningGlow setBlendFunc: (ccBlendFunc) { GL_ONE, GL_ONE }];
  [lightningBolt addChild:lightningGlow];

  //Set a counter for lightning duration randomization
  lightningRemoveCount = 0;

  //Bats Array Initialization
  bats = [[NSMutableArray alloc] init];

  //Add bats using a batch node.
  CCSpriteBatchNode *batch1 = [CCSpriteBatchNode
batchNodeWithFile:@"simple_bat.png" capacity:10];
  [self addChild:batch1 z:2 tag:TAG_BATS];

  //Make them start flying up.
  for(int x=0; x   //Create SimpleAnimObject of bat
   SimpleAnimObject *bat = [SimpleAnimObject
spriteWithBatchNode:batch1 rect:CGRectMake(0,0,48,48)];
  [batch1 addChild:bat];
  [bat setPosition:ccp(arc4random()%400+40, arc4random()%150+150)];

  //Make the bat fly up. Get the animation delay (flappingSpeed).
  float flappingSpeed = [self makeBatFlyUp:bat];

  //Base y velocity on flappingSpeed.
  bat.velocity = ccp((arc4random()%1000)/500 + 0.2f, 0.1f/
flappingSpeed);

  //Add a pointer to this bat object to the NSMutableArray
  [bats addObject:[NSValue valueWithPointer:bat]];
  [bat retain];

  //Set the bat's direction based on x velocity.
  if(bat.velocity.x > 0){
   bat.flipX = YES;
  }
 }

  //Schedule physics updates
  [self schedule:@selector(step:)];

  return self;
}

-(float)makeBatFlyUp:(SimpleAnimObject*)bat {
  CCSpriteFrameCache * cache = [CCSpriteFrameCache
sharedSpriteFrameCache];

  //Randomize animation speed.
  float delay = (float)(arc4random()%5+5)/80;
  CCAnimation *animation = [[CCAnimation alloc] initWithName:@
"simply_bat_fly" delay:delay];

  //Randomize animation frame order.
  int num = arc4random()%4+1;
  for(int i=1; i   [animation addFrame:[cache spriteFrameByName:[NSString
stringWithFormat:@"simple_bat_0%i.png",num]]];
   num++;
   if(num > 4){ num = 1; }
  }

  //Stop any running animations and apply this one.
  [bat stopAllActions];
  [bat runAction:[CCRepeatForever actionWithAction: [CCAnimate 
actionWithAnimation:animation]]];

  //Keep track of which animation is running.
  bat.animationType = BAT_FLYING_UP;

  return delay; //We return how fast the bat is flapping.
}

-(void)makeBatGlideDown:(SimpleAnimObject*)bat {
  CCSpriteFrameCache * cache = [CCSpriteFrameCache
sharedSpriteFrameCache];

  //Apply a simple single frame gliding animation.
  CCAnimation *animation = [[CCAnimation alloc] initWithName:@
"simple_bat_glide" delay:100.0f];
 [animation addFrame:[cache spriteFrameByName:@"simple_bat_01.png"]];

  //Stop any running animations and apply this one.
  [bat stopAllActions];
  [bat runAction:[CCRepeatForever actionWithAction: [CCAnimate 
actionWithAnimation:animation]]];

  //Keep track of which animation is running.
  bat.animationType = BAT_GLIDING_DOWN;
}

-(void)step:(ccTime)delta {
  CGSize s = [[CCDirector sharedDirector] winSize];

for(id key in bats){
  //Get SimpleAnimObject out of NSArray of NSValue objects.
  SimpleAnimObject *bat = [key pointerValue];

  //Make sure bats don't fly off the screen
  if(bat.position.x > s.width){
   bat.velocity = ccp(-bat.velocity.x, bat.velocity.y);
   bat.flipX = NO;
  }else if(bat.position.x	bat.velocity = ccp(-bat.velocity.x, bat.velocity.y);
   bat.flipX = YES;
  }else if(bat.position.y > s.height){
   bat.velocity = ccp(bat.velocity.x, -bat.velocity.y);
   [self makeBatGlideDown:bat];
  }else if(bat.position.y	bat.velocity = ccp(bat.velocity.x, -bat.velocity.y);
   [self makeBatFlyUp:bat];
  }

  //Randomly make them fly back up
  if(arc4random()%100 == 7){
   if(bat.animationType == BAT_GLIDING_DOWN){ [self
makeBatFlyUp:bat]; bat.velocity = ccp(bat.velocity.x, -bat.
velocity.y); }
   else if(bat.animationType == BAT_FLYING_UP){ [self
makeBatGlideDown:bat]; bat.velocity = ccp(bat.velocity.x, -bat.
velocity.y); }
  }

  //Update bat position based on direction
  bat.position = ccp(bat.position.x + bat.velocity.x, bat.position.y
+ bat.velocity.y);
  }

  //Randomly make lightning strike
  if(arc4random()%70 == 7){
  if(lightningRemoveCount	[self addChild:lightningBolt z:1 tag:TAG_LIGHTNING_BOLT];
   lightningRemoveCount = arc4random()%5+5;
   }
  }

  //Count down
  lightningRemoveCount -= 1;

  //Clean up any old lightning bolts
  if(lightningRemoveCount == 0){
   [self removeChildByTag:TAG_LIGHTNING_BOLT cleanup:NO];
  }
}

@end

How it works...
This recipe shows us how to structure animation based classes through the use of SimpleAnimObject:
  • Animated object class structure:
    When switching from one animation to another it is often important to keep track of what state the animated object is in. In our example we use SimpleAnimObject, which keeps an arbitrary animationType variable. We also maintain a velocity variable that has a Y scalar value that is inversely proportional to the animation frame delay:
    @interface SimpleAnimObject : CCSprite {
      int animationType;
      CGPoint velocity;
    }
    

    Depending on how in-depth you want your animation system to be you should maintain more information such as, for example, a pointer to the running CCAnimation instance, frame information, and physical bodies.
There's more...
As you get more involved with Cocos2d game development you will become more and more tempted to use asynchronous actions for gameplay logic and AI. Derived from the CCAction class, these actions can be used for everything from moving a CCNode using CCMoveBy to animating a CCSprite using CCAnimate. When an action is run, an asynchronous timing mechanism is maintained in the background. First time game programmers often over-rely on this feature. The extra overhead required by this technique can multiply quickly when multiple actions are being run. In the following example we have used a simple integer timer that allows us to regulate how long lightning lasts onscreen:

//Randomly make lightning strike
if(arc4random()%70 == 7){
 if(lightningRemoveCount   [self addChild:lightningBolt z:1 tag:TAG_LIGHTNING_BOLT];
  lightningRemoveCount = arc4random()%5+5;
 }
}

//Count down
lightningRemoveCount -= 1;

//Clean up any old lightning bolts
if(lightningRemoveCount == 0){
 [self removeChildByTag:TAG_LIGHTNING_BOLT cleanup:NO];
}

Synchronous timers like the one shown in the preceding code snippet are often, but not always, preferable to asynchronous actions. Keep this in mind as your games grow in size and scope.

Summary
In this article we took a look at the basic uses of sprites.





Comments
The article is very excellent.

From coach outlet,coach factory,coach factory outlet,coach outlet store,coach outlet store online,coach factory online,coach factory outlet online,coach outlet online satellite photos speculate louboutin,louboutin outlet,louboutin outlet italia that the test device is about 120-150 meters long, about 80 abercrombie and fitch,abercrombie,abercrombie and fitch UK meters long electromagnetic rail, tory burch outlet,tory burch,tory burch handbags,tory burch shoes,tory burch sale,toryburch,tory burch sandals,toryburch.com,tory burch flip flops able to build such a large scale polo ralph lauren outlet online,ralph lauren,polo ralph,polo ralph lauren,ralph lauren outlet,polo shirts,ralph lauren outlet online,polo ralph lauren outlet,ralphlauren.com,polo outlet,ralph lauren polo experimental vans shoes,vans outlet,vans store,star wars vans shoes,cheap vans,vans shoes outlet,white vans,black vans,red vans,vans star wars,vans sneakers,vans shoes outlet store,vans sale,cheap vans shoes facilities "proves that China has been fully validated and mastered a large linear induction motors, advanced energy storage devices vans,vans scarpe,vans italia forced burberry outlet online,burberry,burberry outlet,burberry handbags,burberry factory outlet,burberry sale and air force,nike air force,air force 1,air force one,nike air force 1,nike air force one,air force one nike high-performance pulse generator key prada outlet,prada,prada handbags,prada sunglasses,prada shoes,prada bags technologies such as electromagnetic catapults. "Compared to the steam catapult, the advantages of electromagnetic catapult michael kors,michael kors canada,michael kors outlet,michael kors outlet canada is comprehensive, first accelerating force michael kors handbags,michael kors outlet,michael kors outlet online,michael kors,kors outlet,michael kors outlet online sale,michael kors handbags clearance,michael kors purses,michaelkors.com,michael kors bags,michael kors shoes,michaelkors,cheap michael kors uniform and controllable. "Nimitz" when C-13-1-type steam catapults louis vuitton outlet,louis vuitton outlet online,louis vuitton,louisvuitton.com,authentic louis vuitton,louis vuitton factory outlet,cheap louis vuitton on the emission oakley sunglasses,cheap oakley sunglasses,oakley sunglasses cheap,oakley vault,oakleys,oakley.com,sunglasses outlet,cheap oakley,oakley outlet,cheap sunglasses,oakley prescription glasses,fake oakleys,oakley sunglasses outlet,oakley glasses,oakley store,fake oakley,oakley sale,cheap oakleys,discount oakley sunglasses level can birkin bag,hermes belt,hermes handbags,hermes birkin,hermes bags,birkin bags reach the maximum overload 6g, while the average acceleration of the kate spade handbags,kate spade,kate spade outlet,katespade whole trip nike air max,air max,air max pas cher,air max one,air max 90,air max france is just a little more than 2g. F / A-18 fighter pilots often ridicule C-13-1 in the rear section catapult air max,nike air max themselves often do not have the louis vuitton,borse louis vuitton,louis vuitton sito ufficiale,louis vuitton outlet aircraft engine longchamp,longchamp bags,longchamp uk acceleration "to force." With the speed and cylinder volume increases, the vast majority of the expansion of chi flat iron,chi hair the superheated steam for steam energy to accelerate and promote themselves, and gas expansion increased hollister,hollister uk,abercrombie,abercrombie fitch,abercrombie and fitch the proportion of steam required increase in volume after the establishment party relationships. Steam catapult length and cylinder volume almost reached its limit, until the end of the ejection stroke, steam basically only accelerated piston aircraft little help.Electromagnetic catapult launch thrust segment is not the kind of sudden explosive impact of steam, air max,nike air max,air max 90,nike air max 90,air max 1 the peak air jordan,jordan pas cher,air jordan pas cher,nike air jordan,air jordan france overload can nfl jerseys,jerseys,baseball jerseys,cheap jerseys,nba jerseys,hockey jerseys,basketball jerseys,jerseys from china,cheap nfl jerseys be reduced from 6g to 3g, which polo ralph lauren outlet,ralph lauren,polo ralph,polo ralph lauren,ralph lauren outlet,polo shirts,ralph lauren outlet online,polo ralph lauren outlet online,ralphlauren.com,polo outlet,ralph lauren polo will not only help toms outlet to extend ray ban,rayban,occhiali ray ban the life of the herve leger,herve leger dresses aircraft, the pilot's body to feel is a good improvement. In addition, since the electromagnetic sac longchamp,longchamp,longchamps,longchamp pas cher,sac longchamp pas cher,longchamp pliage,longchamp soldes,sac longchamps,longchamp france catapult launch acceleration and length does not matter, in addition to being the aerodynamic drag and friction affect, louboutin,christian louboutin,red bottom shoes,louboutin shoes,red bottoms,louboutin outlet,christian louboutin shoes,christian louboutin outlet,red bottom shoes for women,louboutins the catapult into the iphone 6 cases,iphone 6 case,iphone 5c cases,iphone 5s cases,iphone cases,iphone case,iphone 5 cases,iphone 4s cases,iphone 4 cases,ipad cases,ipad mini cases,ipad air cases,galaxy s5 cases,galaxy s4 cases,phone cases early part of the last paragraph of the basic acceleration will not fluctuate too much, which is a gradual decline over the steam catapult more and more efficiency. According to calculations, the average acceleration of the same, electromagnetic catapults than nike free,nike free run,free running,free run,nike running steam catapults make aircraft more than 8-15% load. hogan,hogan outlet,scarpe hogan,hogan sito ufficiale,hogan interactive When the ejection of different weights, different models takeoff speed, electromagnetic catapult catapult also flexible and accurate converse pas cher,converse control of ralph lauren,ralph lauren uk,ralph lauren outlet,polo ralph lauren outlet energy through the computer.Electromagnetic catapult ejection hollister,hollister canada,abercrombie and fitch,abercrombie,abercrombie and,abercrombie kids,af efficiency is easton bats also higher than the steam michael kors outlet online,michael kors,kors outlet,michael kors outlet,michael kors handbags,michael kors outlet online sale,michael kors handbags clearance,michael kors purses,michaelkors.com,michael kors bags,michael kors shoes,michaelkors,cheap michael kors catapult, to enhance the nike huarache,nike huaraches,nike air huarache sense that major combat aircraft, such as christian louboutin shoes,louboutin shoes,louboutin outlet,louboutin,christian louboutin,red bottom shoes,red bottoms,christian louboutin outlet,red bottom shoes for women,louboutins the use vanessa bruno,sac vanessa bruno,vanessa bruno sac,vanessa bruno pas cher,cabas vanessa bruno,sac vanessa bruno en solde,sac vanessa bruno pas cher of electromagnetic catapult aircraft carrier-based Sunrise Ford momentum true religion from "Nimitz" coach outlet,coach factory outlet,coach outlet store,coach factory,coach outlet store online,coach factory online,coach factory outlet online,coach outlet online class of 120 jimmy choo,jimmy choo shoes,jimmy choo outlet,jimmy choo handbags sorties to 160 sorties: new balance shoes,new balance,balance shoes,new balance outlet,new balance store,new balance store locator,new balance shoes for women,joe's new balance outlet,newbalance,newbalance.com,new balance walking shoes Sunrise peak momentum from the air max,nike air max,air max 2015,nike air max 2015,air max 90,airmax,air max 95,nike air max 90 original 220-240 vehicles to 270 vehicles. At the same time, the hollister,abercrombie absence of pandora jewelry,pandora charms,pandora bracelet,pandora bracelets,pandora rings,pandora jewelry store locator,pandora charm,pandora charms clearance,pandora store,pandora jewelry outlet store,pandora jewelry sale online a large cylinder, the volume of the electromagnetic catapult is relatively michael kors outlet,michael kors outlet online,michael kors,kors outlet,michael kors handbags,michael kors outlet online sale,michael kors handbags clearance,michael kors purses,michaelkors.com,michael kors bags,michael kors shoes,michaelkors,cheap michael kors small, supra shoes very beneficial to the swarovski uk "Liaoning" class platform installation.In recent years, China's electronic technology valentino shoes,valentino,valentinos weaponry rapid progress. By 2020 there converse,scarpe converse,converse italia,converse sito ufficiale,converse all star six years, Ma Weiming nike trainers,nike trainers uk academician and his beats by dre,dr dre,beats headphones,dre beats,beats by dr,beats by dr dre,beats audio,dr dre beats,dre headphones,beats by dre headphones,beats by dr. dre,cheap beats research team there kate spade outlet,kate spade,katespade,kate spade handbags is still time, the oakley,occhiali oakley,oakley italia Chinese navy as a steam catapult can cross this threshold, so the first one sac louis vuitton,louis vuitton,louis vuitton pas cher,sac louis vuitton pas cher,louis vuitton france domestic carrier mounted montre pas cher directly on 2-3 sets of electromagnetic catapults, "Liaoning "saturation volume level karen millen dresses on the 2nd carrier longchamp,longchamp handbags,longchamp outlet,longchamp bags,long champ aircraft ship will likely rise to around 65, the amount of actual service burberry outlet online,burberry outlet,burberry,burberry handbags,burberry factory outlet,burberry sale carrier aircraft louis vuitton,louis vuitton bags,louis vuitton handbags,louis vuitton uk can reach the size of 55, plus three times now mulberry,mulberry handbags,mulberry outlet,mulberry bags,mulberry uk and can be loaded oakley sunglasses,oakley vault,oakley sunglasses cheap,oakleys,oakley.com,sunglasses outlet,cheap oakley,cheap oakley sunglasses,oakley outlet,cheap sunglasses,oakley prescription glasses,fake oakleys,oakley sunglasses outlet,oakley glasses,oakley store,fake oakley,oakley sale,cheap oakleys,discount oakley sunglasses with petrol bombs attendance combat new michael kors outlet store,michael kors outlet,michael kors outlet online,michael kors,kors outlet,michael kors handbags,michael kors outlet online sale,michael kors handbags clearance,michael kors purses,michaelkors.com,michael kors bags,michael kors shoes,michaelkors,cheap michael kors carrier machine. Ship "new wine in old bottles" operational capability hollister,abercrombie,hollister sito ufficiale,abercrombie italia,abercrombie and fitch,abercrombie outlet of the aircraft carrier is expected to rolex watches,replica watches,omega watches,rolex watches for sale,replica watches uk,fake rolex reach "Forrester" class and the "Kitty Hawk" grade level.Nuclear fantasy and realityIf the "Liaoning" on the 2nd class destroyers finally tiffany and co jewelry,tiffany and co outlet,tiffany and co,tiffany's,tiffanys,tiffany co,tiffany jewelry adopted electromagnetic catapult, you bottega veneta,bottega,bottega veneta outlet must do the appropriate upgrade rolex watches,rolex,watches for men,watches for women,omega watches,replica watches,rolex watches for sale,rolex replica,rolex watch,cartier watches,rolex submariner,fake rolex,rolex replica watches,replica rolex its power systems, electromagnetic catapults need strong power protection, vans,vans pas cher,vans soldes especially louboutin outlet,louboutin,christian louboutin,red bottom shoes,louboutin shoes,red bottoms,christian louboutin shoes,christian louboutin outlet,red bottom shoes for women,louboutins in high-voltage power supply capacity of the instantaneous ejection time, which is probably "Liaoning" No existing power system can not provide."Admiral Kuznetsov" was thomas sabo uk adopted four TB-12 true religion steam turbine and eight supercharged boiler. TB-12's predecessor is TB-8, and TB-8 is just the louboutin,chaussure louboutin,louboutin pas cher,chaussures louboutin,chaussure louboutin pas cher,louboutin france domestic 051 destroyers host Domestic Model 453 type air max,nike air max,air max pas cher,air max one,air max 90,air max france steam turbine. TB-8 coach purses,coach handbags,coach bags power is 36,000 horsepower, 051 destroyers then adopted two sets of TB-8 steam turbine speed was 38 knots, power TB-12 increased to 45,000 horsepower. In addition, China converse shoes,converse,converse.com,converse sneakers,converse outlet introduced the "modern" GTZA-674 type steam turbine installed on class instyler ionic styler,instyler destroyer is improved longchamp handbags,longchamp,longchamp outlet,longchamp bags,long champ TB-12's.TB-8 from the mcm handbags,mcm bags,mcm backpack,mcm outlet TB-12 and michael kors outlet online sale,michael kors,kors outlet,michael kors outlet,michael kors handbags,michael kors outlet online,michael kors handbags clearance,michael kors purses,michaelkors.com,michael kors bags,michael kors shoes,michaelkors,cheap michael kors then GTZA-674, China in the series steam turbine has accumulated a wealth of technology, use and maintenance experience. If the steam timberland outlet turbine on "Liaoning" was used for the localization model, I believe, at least up to the level of GTZA-674, michael kors,sac michael kors,michael kors pas cher,sac michael kors pas cher,michael kors france with louis vuitton,louis vuitton canada,louis vuitton outlet,louis vuitton outlet online a coach outlet store online,coach outlet store,coach outlet total output power of north face,the north face,north face uk,north face jackets,north face outlet,northface four steam turbines for 200,000 horsepower. The power tiffany and co jewelry,tiffany and co outlet,tiffany and co,tiffany's,tiffanys,tiffany co,tiffany jewelry system maintains no catapult "Liaoning" No high speed sailing is no problem, but if it is using a new electromagnetic catapult aircraft on some stretched up. "Ford" was only four electromagnetic catapult while charging it takes about north face jackets,north face,the north face,northface,north face outlet,north face jackets clearance,the north face outlet 200,000 horsepower, if the "Liaoning" on the 2nd class destroyers to install ray ban sunglasses outlet,ray ban sunglasses,ray ban,rayban,ray bans,ray ban outlet,ray-ban,raybans,ray ban wayfarer,ray-ban sunglasses,raybans.com,rayban sunglasses,cheap ray ban three links of london uk sets of the same power sac guess,guess pas cher,guess,guess collection,sac a main guess of the electromagnetic catapult, the required electrical energy that is over 16,000 horsepower; hollister taking into steam turbine power generation process in about 50% of energy nike air max,air max,air max 2015,nike air max 2015,air max 90,airmax,air max 95,nike air max 90 consumption, only lululemon outlet,lululemon,yoga pants,lulu lemon,lulu.com,lululemon.com three catapult babyliss pro,babyliss maximum prada handbags,prada,prada sunglasses,prada shoes,prada outlet,prada bags required lancel power accounted for about 16% of the total power of the ship, which is bound to gucci outlet,gucci handbags,gucci belts,gucci shoes,gucci,gucci belt,gucci sunglasses,gucci bags,cheap gucci seriously ghd,ghd hair,ghd hair straighteners,ghd straighteners affect the use of aircraft speed and lacoste,polo lacoste,lacoste pas cher,lacoste.fr,lacoste soldes,survetement lacoste other electrical equipment.More insanity,insanity workout,insanity workout calendar,insanity calendar,insanity workout schedule vigilance is needed, longchamp outlet,longchamp,longchamp handbags,longchamp bags,long champ whether it is "Admiral Kuznetsov" was still in India, "Vic Rama Tia" No, they are installed roshe run,nike roshe,roshe runs,nike roshe run,nike roshes TB-12 ray ban sunglasses,ray ban sunglasses outlet,ray ban,rayban,ray bans,ray ban outlet,ray-ban,raybans,ray ban wayfarer,ray-ban sunglasses,raybans.com,rayban sunglasses,cheap ray ban steam turbine and auxiliary boilers occurred many times in the course of giuseppe zanotti,giuseppe zanotti outlet major accident. Russia louis vuitton,louis vuitton outlet online,louis vuitton outlet,louisvuitton.com,authentic louis vuitton,louis vuitton factory outlet,cheap louis vuitton has north face outlet,north face,the north face,northface,north face jackets,north face jackets clearance,the north face outlet a rich pandora jewelry,pandora charms,pandora bracelet,pandora bracelets,pandora rings,pandora jewelry store locator,pandora charm,pandora charms clearance,pandora store,pandora jewelry outlet store,pandora jewelry sale online ship with a steam turbine development and experience like this, the reliability of the hermes,sac hermes,hermes pas cher,sac hermes pas cher TB-12 based on the development of China-made large true religion ship with the first soccer shoes,nike mercurial generation of louboutin,christian louboutin,louboutin shoes,louboutins,louboutin uk,christian louboutin uk,red bottom shoes,red bottoms,louboutin outlet,christian louboutin shoes,christian louboutin outlet steam turbines also needs further examination.Needless to say, the best use of the wedding dresses,wedding dress,dresses for wedding,bride dresses,dresses for weddings,wedding dresses uk,cheap wedding dresses,vintage wedding dresses,monsoon wedding dresses,lace wedding dresses,wedding dresses for older brides,wedding dresses 2014 electromagnetic catapult powered aircraft carrier lululemon,lululemon canada,lululemon outlet canada,lululemon outlet online program is certainly similar to "Ford" class nike roshe run,roshe run,nike roshe,rosh run,roshe run pas cher,nike roshe france nuclear-powered + all-electric propulsion tn pas cher,nike tn,nike tn pas cher,nike tn requin,tn requin,tn requin pas cher system. Nuclear coach factory outlet,coach factory,coach factory outlet online,coach factory online energy juicy couture can provide catapult inexhaustible; wedding dresses,prom dresses,bridesmaid dresses,evening dresses,beach wedding dresses,cheap wedding dresses,homecoming dresses,prom dresses,wedding dresses and the all-electric propulsion system eliminates ray ban pas cher,ray ban,rayban,lunette ray ban pas cher the mechanical transmission mechanism, the reactor will supply energy into louis vuitton outlet stores,louis vuitton outlet online,louis vuitton,louis vuitton outlet,louisvuitton.com,authentic louis vuitton,louis vuitton factory outlet,cheap louis vuitton electrical energy directly to the catapult, propeller motors, timberland,timberland pas cher,chaussure timberland pas cher,timberland france as well as other power line carrier terminal, without the huge transmission layout is very conducive to aircraft interior design, handling and juicy couture outlet maintenance is also very convenient. Of course, louis vuitton outlet online,louis vuitton,louis vuitton outlet,louisvuitton.com,authentic louis vuitton,louis vuitton factory outlet,cheap louis vuitton the all-electric propulsion system for the energy chanel handbags,chanel bags,chanel sunglasses,chanel purses,chanel outlet conversion efficiency is generally better than mechanical transmission, with burberry,sac burberry,burberry pas cher,sac burberry pas cher,burberry france endless nike blazer,blazer nike,nike blazer pas cher energy asics,asics gel,asics running,asics running shoes,asics shoes,asics gel nimbus,asics gel kayano,asics gt reactors ralph lauren,polo ralph lauren,ralph lauren outlet,ralph lauren italia,ralph lauren sito ufficiale is undoubtedly the most suitable partner.Real possibility of view, "Liao in" class on the 2nd ship a "nuclear" nike roshe,roshe run,nike roshe run,roshe runs power system louis vuitton,sac louis vuitton,louis vuitton pas cher,sac louis vuitton pas cher,louis vuitton france is unlikely. Although Russia discuss the "Admiral Kuznetsov" No. overhaul conversion program, the dress had been discussed nuclear power, eventually dropped. I reebok outlet,reebok,reebok skyscape,reebok shoes will not speak on the basic platform "Liaoning" was doing true religion so beating ferragamo shoes,ferragamo,salvatore ferragamo,ferragamo belts,ferragamo belt,ferragamo outlet the availability of the technical feasibility of internal transformation, China I am afraid there is no ready-made high-performance aircraft for use nike shoes,nike outlet,nike factory,nike store,nike factory outlet,nike outlet store,cheap nike shoes,nike sneakers pressurized water reactor. The new reactors on 094 strategic nuclear submarines mac cosmetics,m a c cosmetics,mac makeup,maccosmetics.com reportedly good performance, celine handbags,celine bag,celine bags there has been no reliable sources have new balance pas cher,new balance,new balance femme confirmed that the boat has been the longchamp,sac longchamp,longchamps,longchamp pas cher,sac longchamp pas cher,longchamp pliage,longchamp soldes,sac longchamps,longchamp france formation of combat, the maturity of its power systems doubtful. We should also not forget that the abercrombie and fitch,abercrombie and,abercrombie,abercrombie kids,abercrombie fitch,abercrombie.com risk ray ban sunglasses uk of north face,the north face,north face pas cher,north face soldes,north face france boats reactors ship with p90x,p90x3,p90x workout,p90x workout schedule,p90x workout sheets,p90x 3,p90x2 a great change, oakley sunglasses cheap,cheap oakley sunglasses,oakley sunglasses,oakley vault,oakleys,oakley.com,sunglasses outlet,cheap oakley,oakley outlet,cheap sunglasses,oakley prescription glasses,fake oakleys,oakley sunglasses outlet,oakley glasses,oakley store,fake oakley,oakley sale,cheap oakleys,discount oakley sunglasses the air max US nuclear aircraft carriers and nuclear submarines had never shared michael kors,michael kors uk,michael kors handbags,michael kors bags reactor; France has the world's top nuclear technology in michael kors outlet,michael kors,kors outlet,michael kors handbags,michael kors outlet online,michael kors outlet online sale,michael kors handbags clearance,michael kors purses,michaelkors.com,michael kors bags,michael kors shoes,michaelkors,cheap michael kors the construction of "Charles de swarovski jewelry Gaulle" when granted directly jordan shoes,jordans,air jordan,jordan retro,jordan 11,jordan xx9,jordan 6,new jordans,air jordans,cheap jordans,retro jordans,jordan retro 11,jordan 5,air jordan 11,jordans for sale,jordan 4,jordan 1,jordan future,jordan 3,jordan 12,michael jordan shoes,air jordan shoes,air jordan retro to the intended Reactor "Triumph" class gucci,borse gucci,gucci sito ufficiale,gucci outlet strategic nuclear submarine used louis vuitton handbags,vuitton handbags,louis vuitton bags,louis vuitton purses in the hollister,abercrombie,abercrombie fitch,hollister france,hollister pas cher,abercrombie and fitch,hollister pas cher "Charles de Gaulle". nike air max,air max,air max 90,nike air max 90,air max 1 K15 natural circulation integral nike free,free run,nike free run,nike free pas cher,nike free run pas cher,nike free france PWR technology really advanced in the "Triumph" class did a great job, but mounted on the "Charles de Gaulle" pandora charms,pandora uk,pandora bracelet,pandora rings,pandora,pandora sale,pandora bracelets,pandora jewellery,pandora ring,pandora charm,pandora earrings,pandora jewelry,pandora necklace,pandora charms uk is the "acclimatization", resulting oakley pas cher,oakley,oakley soldes,lunette oakley pas cher,oakley france in "Charles de Gaulle" period is prolonged, the installation of mont blanc,montblanc,mont blanc pens pressure cabin dead weight after barely put to use, ralph lauren,polo ralph lauren,ralph lauren pas cher,polo ralph lauren pas cher,ralph lauren france but still in the sea trials and follow-up service during soccer jerseys,soccer jersey,usa soccer jersey,football jerseys times of nike free,free running,nike free run,nike free 5.0,free running 2,nike running shoes,nike free trainer,nike free trainer 5.0,free runs,free run 5.0 exposure problems.


Note: Please offer only positive, constructive comments - we are looking to promote a positive atmosphere where collaboration is valued above all else.




PARTNERS