Your SlideShare is downloading. ×
0
在iOS平台上用Cocos2D做开发 | iOS独立开发者 秦春林
在iOS平台上用Cocos2D做开发 | iOS独立开发者 秦春林
在iOS平台上用Cocos2D做开发 | iOS独立开发者 秦春林
在iOS平台上用Cocos2D做开发 | iOS独立开发者 秦春林
在iOS平台上用Cocos2D做开发 | iOS独立开发者 秦春林
在iOS平台上用Cocos2D做开发 | iOS独立开发者 秦春林
在iOS平台上用Cocos2D做开发 | iOS独立开发者 秦春林
在iOS平台上用Cocos2D做开发 | iOS独立开发者 秦春林
在iOS平台上用Cocos2D做开发 | iOS独立开发者 秦春林
在iOS平台上用Cocos2D做开发 | iOS独立开发者 秦春林
在iOS平台上用Cocos2D做开发 | iOS独立开发者 秦春林
在iOS平台上用Cocos2D做开发 | iOS独立开发者 秦春林
在iOS平台上用Cocos2D做开发 | iOS独立开发者 秦春林
在iOS平台上用Cocos2D做开发 | iOS独立开发者 秦春林
在iOS平台上用Cocos2D做开发 | iOS独立开发者 秦春林
在iOS平台上用Cocos2D做开发 | iOS独立开发者 秦春林
在iOS平台上用Cocos2D做开发 | iOS独立开发者 秦春林
在iOS平台上用Cocos2D做开发 | iOS独立开发者 秦春林
在iOS平台上用Cocos2D做开发 | iOS独立开发者 秦春林
在iOS平台上用Cocos2D做开发 | iOS独立开发者 秦春林
在iOS平台上用Cocos2D做开发 | iOS独立开发者 秦春林
在iOS平台上用Cocos2D做开发 | iOS独立开发者 秦春林
在iOS平台上用Cocos2D做开发 | iOS独立开发者 秦春林
在iOS平台上用Cocos2D做开发 | iOS独立开发者 秦春林
在iOS平台上用Cocos2D做开发 | iOS独立开发者 秦春林
在iOS平台上用Cocos2D做开发 | iOS独立开发者 秦春林
在iOS平台上用Cocos2D做开发 | iOS独立开发者 秦春林
在iOS平台上用Cocos2D做开发 | iOS独立开发者 秦春林
在iOS平台上用Cocos2D做开发 | iOS独立开发者 秦春林
在iOS平台上用Cocos2D做开发 | iOS独立开发者 秦春林
在iOS平台上用Cocos2D做开发 | iOS独立开发者 秦春林
在iOS平台上用Cocos2D做开发 | iOS独立开发者 秦春林
在iOS平台上用Cocos2D做开发 | iOS独立开发者 秦春林
在iOS平台上用Cocos2D做开发 | iOS独立开发者 秦春林
在iOS平台上用Cocos2D做开发 | iOS独立开发者 秦春林
在iOS平台上用Cocos2D做开发 | iOS独立开发者 秦春林
在iOS平台上用Cocos2D做开发 | iOS独立开发者 秦春林
在iOS平台上用Cocos2D做开发 | iOS独立开发者 秦春林
在iOS平台上用Cocos2D做开发 | iOS独立开发者 秦春林
在iOS平台上用Cocos2D做开发 | iOS独立开发者 秦春林
在iOS平台上用Cocos2D做开发 | iOS独立开发者 秦春林
在iOS平台上用Cocos2D做开发 | iOS独立开发者 秦春林
在iOS平台上用Cocos2D做开发 | iOS独立开发者 秦春林
在iOS平台上用Cocos2D做开发 | iOS独立开发者 秦春林
在iOS平台上用Cocos2D做开发 | iOS独立开发者 秦春林
在iOS平台上用Cocos2D做开发 | iOS独立开发者 秦春林
在iOS平台上用Cocos2D做开发 | iOS独立开发者 秦春林
在iOS平台上用Cocos2D做开发 | iOS独立开发者 秦春林
在iOS平台上用Cocos2D做开发 | iOS独立开发者 秦春林
在iOS平台上用Cocos2D做开发 | iOS独立开发者 秦春林
在iOS平台上用Cocos2D做开发 | iOS独立开发者 秦春林
在iOS平台上用Cocos2D做开发 | iOS独立开发者 秦春林
在iOS平台上用Cocos2D做开发 | iOS独立开发者 秦春林
在iOS平台上用Cocos2D做开发 | iOS独立开发者 秦春林
在iOS平台上用Cocos2D做开发 | iOS独立开发者 秦春林
在iOS平台上用Cocos2D做开发 | iOS独立开发者 秦春林
在iOS平台上用Cocos2D做开发 | iOS独立开发者 秦春林
在iOS平台上用Cocos2D做开发 | iOS独立开发者 秦春林
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

在iOS平台上用Cocos2D做开发 | iOS独立开发者 秦春林

1,676

Published on

游戏引擎移植者现身讲解:《在iOS平台上用Cocos2D做开发》 | iOS独立开发者 秦春林 | iOS …

游戏引擎移植者现身讲解:《在iOS平台上用Cocos2D做开发》 | iOS独立开发者 秦春林 | iOS DevCamp

议题简介:Cocos2d是iOS平台上著名的游戏引擎,它开源,结构简单清晰,功能强大,是个人或者中小型团队开发的首选方案。本议题将以引擎移植者的身份清晰的讲解Cocos2D的结构,除此之外,还会分享App开发中的实际问题,例如灵活使用层,管理好触摸,整合使用Box2d物理引擎,Cocos2D与UIKit的整合等等开发中遇到的常见问题。

讲师简介:秦春林:独立开发者,曾就职于K2,金和,从事企业方面的开发,之后加入北京友录,OpenXLive从事Windows phone产品开发。2011年参与Cocos2d-x到Windows phone平台的移植,贡献了大部分核心功能,对Coco2D游戏引擎有深刻的了解,现从事iOS开发。热爱开源,喜欢交流。

Published in: Technology, Art & Photos
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
1,676
On Slideshare
0
From Embeds
0
Number of Embeds
4
Actions
Shares
0
Downloads
36
Comments
0
Likes
0
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. iOS DevCamp Produced by CSDN Website: http://devcamp.csdn.net Weibo: http://weibo.com/cmdnclubThursday, August 2, 12
  • 2. 怎样灵活使用Cocos2D 秦春林Thursday, August 2, 12
  • 3. Don’t reinvent the wheelThursday, August 2, 12
  • 4. “In the summer of 2008, several "pythoneros" went to a camp program called PyCamp: Python outdoors. This camp held in Cordoba, in the town of Los Cocos. We were about 50 people. It covered different topics, one of which was seeking way of not having to "reinvent the wheel" in each jurisdiction Pyweek. In this way a group of friends and I decided to put together a framework to make games. We call cocos2d, since the framework is designed to make 2D games, and the word "coconut" emulates the place where the camp took place.” Ricardo QuesadaThursday, August 2, 12
  • 5. 4,000+ gamesThursday, August 2, 12
  • 6. It is free! Without having to learn OpenGL ES to get started Active community & tests Lots of tools It is Simple Why Cocos2d?Thursday, August 2, 12
  • 7. How simple?Thursday, August 2, 12
  • 8. sprite: player Action: CCMoveTo layer: GameLayer scene: GameScene UIView:EAGLViewThursday, August 2, 12
  • 9. Game has Scenes Each Scene has some number of Layers Layers capture user interaction and contain sprites Director manages the scenes Cocos2d BasicsThursday, August 2, 12
  • 10. Anything thats gets drawn or contains things that get drawn is a CCNodeThursday, August 2, 12
  • 11. CCLayer CCMenu CCMenuItemLabel CCMenuItem CCMenuItemSprite CCMenuItemToggle CCParticleSystem CCNode CCScene CCTransitionScene CCSprite CCLabelTTF CCLabelBMFont CCSpriteBatchNode CCTMXLayerThursday, August 2, 12
  • 12. Just like UIViewThursday, August 2, 12
  • 13. They can contain other CCNode nodes (addChild, getChildByTag, removeChild, etc) They can schedule periodic callback (schedule, unschedule, etc) They can execute actions (runAction, stopAction, etc) main featuresThursday, August 2, 12
  • 14. Features of CCNode: - position - scale (x, y) - rotation (in degrees, clockwise) - CCCamera (an interface to gluLookAt ) - CCGridBase (to do mesh transformations) - anchor point - size - visible - z-order - openGL z positionThursday, August 2, 12
  • 15. - (CGAffineTransform)nodeToParentTransform; - (CGAffineTransform)parentToNodeTransform; - (CGAffineTransform)nodeToWorldTransform; - (CGAffineTransform)worldToNodeTransform; - (CGPoint)convertToNodeSpace:(CGPoint)worldPoint; - (CGPoint)convertToWorldSpace:(CGPoint)nodePoint; - (CGPoint)convertTouchToNodeSpace:(UITouch *)touch; transformationThursday, August 2, 12
  • 16. CCLayer GamePlay CCScene CCLayer GamePlayScene BackgroundThursday, August 2, 12
  • 17. CCLayer is a subclass of CCNode that implements: - UIAccelerometerDelegate - CCStandardTouchDelegate - CCTargetedTouchDelegateThursday, August 2, 12
  • 18. Thursday, August 2, 12
  • 19. (NSSet*)touches NO targetedHandlersCount>o standardHandlersCount>o YES foreach...in touches YES foreach...in mutablesTouches foreach...in handlers ccTouchesBegan/Move/ End NO ccTouchBegan YES ccTouchMove/End NO End swallowsTouches NO YES remove from mutableTouchesThursday, August 2, 12
  • 20. ! // ! // process the target handlers 1st ! // ! if( targetedHandlersCount > 0 ) { ! ! for( UITouch *touch in touches ) { ! ! ! for(CCTargetedTouchHandler *handler in targetedHandlers) { ! ! ! ! BOOL claimed = NO; ! ! ! ! if( idx == kCCTouchBegan ) { ! ! ! ! ! claimed = [handler.delegate ccTouchBegan:touch withEvent:event]; ! ! ! ! ! if( claimed ) ! ! ! ! ! ! [handler.claimedTouches addObject:touch]; ! ! ! ! } ! ! ! ! // else (moved, ended, cancelled) ! ! ! ! else if( [handler.claimedTouches containsObject:touch] ) { ! ! ! ! ! claimed = YES; ! ! ! ! ! if( handler.enabledSelectors & helper.type ) ! ! ! ! ! ! [handler.delegate performSelector:helper.touchSel withObject:touch withObject:event]; ! ! ! ! ! if( helper.type & (kCCTouchSelectorCancelledBit | kCCTouchSelectorEndedBit) ) ! ! ! ! ! ! [handler.claimedTouches removeObject:touch]; ! ! ! ! } ! ! ! ! if( claimed && handler.swallowsTouches ) { ! ! ! ! ! if( needsMutableSet ) ! ! ! ! ! ! [mutableTouches removeObject:touch]; ! ! ! ! ! break; ! ! ! ! } ! ! ! } ! ! } ! }Thursday, August 2, 12
  • 21. You must register as a targeted touch delegate ccTouchBegan be invoked separately for each of the available touches The ccTouchBegan method return YES to indicate a touch you care about The swallowsTouches property return YES to indicate only this layer handle the touch Targeted Touch DelegateThursday, August 2, 12
  • 22. A sample: How dose CCMenu work?Thursday, August 2, 12
  • 23. -(BOOL) ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event { ...... ! selectedItem_ = [self itemForTouch:touch]; ! [selectedItem_ selected]; ! if( selectedItem_ ) { ! ! state_ = kCCMenuStateTrackingTouch; ! ! return YES; ! } ! return NO; } -(void) ccTouchMoved:(UITouch *)touch withEvent:(UIEvent *)event { ! CCMenuItem *currentItem = [self itemForTouch:touch]; ! if (currentItem != selectedItem_) { ! ! [selectedItem_ unselected]; ! ! selectedItem_ = currentItem; ! ! [selectedItem_ selected]; ! } } -(void) ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event { ! [selectedItem_ unselected]; ! [selectedItem_ activate]; } CCMenu : CCLayerThursday, August 2, 12
  • 24. Which item is clicked?Thursday, August 2, 12
  • 25. -(CCMenuItem *) itemForTouch: (UITouch *) touch { ! CGPoint touchLocation = [touch locationInView: [touch view]]; ! touchLocation = [[CCDirector sharedDirector] convertToGL: touchLocation]; ! CCMenuItem* item; ! CCARRAY_FOREACH(children_, item){ ! ! // ignore invisible and disabled items: issue #779, #866 ! ! if ( [item visible] && [item isEnabled] ) { ! ! ! CGPoint local = [item convertToNodeSpace:touchLocation]; ! ! ! CGRect r = [item rect]; ! ! ! r.origin = CGPointZero; ! ! ! if( CGRectContainsPoint( r, local ) ) ! ! ! ! return item; ! ! } ! } ! return nil; } You will like this methodThursday, August 2, 12
  • 26. Priority = 2 GameLayer Priority = 1 Priority = 0 Which Layer handle touch events?Thursday, August 2, 12
  • 27. Return YES to claim the touch. -(BOOL)ccTouchBegan ! //* priority used by the menu for the event handler ! kCCMenuHandlerPriority = -128,Thursday, August 2, 12
  • 28. Thursday, August 2, 12
  • 29. CCSprite is a 2d imageThursday, August 2, 12
  • 30. +(id) spriteWithTexture:(CCTexture2D*)texture; +(id) spriteWithTexture:(CCTexture2D*)texture rect:(CGRect)rect; +(id) spriteWithSpriteFrame:(CCSpriteFrame*)spriteFrame; +(id) spriteWithSpriteFrameName:(NSString*)spriteFrameName; +(id) spriteWithFile:(NSString*)filename; +(id) spriteWithFile:(NSString*)filename rect:(CGRect)rect; +(id) spriteWithCGImage: (CGImageRef)image key:(NSString*)key;Thursday, August 2, 12
  • 31. CCTexture frame 0 1 2 3 (setDisplayFrame) CCSprite CCSpriteFrame CCSpriteFrameCacheThursday, August 2, 12
  • 32. CCSpriteSheetThursday, August 2, 12
  • 33. All CCSprites added to a CCSpriteBatchNode are drawn in one OpenGL ES draw call. CCLabelBMFont CCTMXLayer CCSpriteBatchNodeThursday, August 2, 12
  • 34. CCLayer CCScene CCLayer GamePlay Scene CCDirector CCLayer ..... CCLayer startScene CCScene GameOlayScene CCLayer CompleteScene LevelCompleted ..... Scene CCLayerThursday, August 2, 12
  • 35. -(CGSize) winSize; -(CGPoint) convertToGL: (CGPoint) p; -(CGPoint) convertToUI:(CGPoint)p; 200 -(void) runWithScene:(CCScene*) scene; 200 100 -(void) pushScene:(CCScene*) scene; 220 -(void) popScene; -(void) popToRootScene; 200 -(void) replaceScene: (CCScene*) scene; -(void) pause; -(void) resume; CCDirectorThursday, August 2, 12
  • 36. How does CCAction work?Thursday, August 2, 12
  • 37. @property (nonatomic,readonly,assign) id target; +(id) action; -(BOOL) isDone; -(void) startWithTarget:(id)target; -(void) stop; -(void) step: (ccTime) dt; -(void) update: (ccTime) time;Thursday, August 2, 12
  • 38. CCNode CCAction CCActionManager +(id)actionWithDuration:(ccTime)d -(CCAction*)runAction:(CCAction*)action addAction:action target:self -(void) update: (ccTime) dt -(void) update: (ccTime) t [target_ setPosition: ccp( -(void) stopAction: (CCAction*) action; #pragma mark CCNode - Init & cleanup -(id) init { if ((self=[super init]) ) { self.actionManager = [director actionManager]; } return self; }Thursday, August 2, 12
  • 39. Simple,but powerfulThursday, August 2, 12
  • 40. Position/rotation/scale/visible/z-order/opacity/flip/color CCActionInterval && CCActionInstant CCSequence && CCSpawn && CCRepeat effect && 3D Action CCDelayTime CCAnimate CCCallFun && CCPropertyAction Camera CCActionEase CCActionProgressTimerThursday, August 2, 12
  • 41. Thursday, August 2, 12
  • 42. Box2D is C++ 2D rigid physics simulation engine with continuous collision detection All you files thats touch C++ or include it must be Objective- C++(.mm) Tuned for 1 meter sized objects Box2D v2.2.0 User Manual COCOS2D+BOX2DThursday, August 2, 12
  • 43. A game in 6 stepsThursday, August 2, 12
  • 44. setp 1Thursday, August 2, 12
  • 45. what have the template done for us? initPhysics createMenu draw addNewSpriteAtPosition update ccTouchesEndedThursday, August 2, 12
  • 46. ! b2Vec2 gravity; ! gravity.Set(0.0f, -10.0f); ! world = new b2World(gravity); ! ! // Do we want to let bodies sleep? ! world->SetAllowSleeping(true); ! ! world->SetContinuousPhysics(true); ! ! m_debugDraw = new GLESDebugDraw( PTM_RATIO ); ! world->SetDebugDraw(m_debugDraw); ! ! uint32 flags = 0; ! flags += b2Draw::e_shapeBit; ! m_debugDraw->SetFlags(flags);! ! ! ! // Define the ground body. ! b2BodyDef groundBodyDef; ! groundBodyDef.position.Set(0, 0); // bottom-left corner ! ! // Call the body factory which allocates memory for the ground body ! // from a pool and creates the ground box shape (also from a pool). ! // The body is also added to the world. ! b2Body* groundBody = world->CreateBody(&groundBodyDef); ! ! // Define the ground box shape. ! b2EdgeShape groundBox;! ! ! ! // bottom ! groundBox.Set(b2Vec2(0,0), b2Vec2(s.width/PTM_RATIO,0)); ! groundBody->CreateFixture(&groundBox,0);Thursday, August 2, 12
  • 47. Create the dynamic blocks setp 2Thursday, August 2, 12
  • 48. sprite = [CCSprite spriteWithFile:spriteFileName]; [sprite setPosition:ccp(p.x,p.y)]; // Remember ccp() is macro for CGPointMake() [self addChild:sprite]; } ! } ! ! // Define the dynamic body. ! b2BodyDef bodyDef; ! bodyDef.type = b2_dynamicBody; ! bodyDef.position.Set(p.x/PTM_RATIO, p.y/PTM_RATIO); ! bodyDef.userData = sprite; ! ! // Tell the physics world to create the body ! b2Body *body = world->CreateBody(&bodyDef); ! ! // Define another box shape for our dynamic body. ! b2PolygonShape dynamicBox; ! dynamicBox.SetAsBox(boxDimensions.x, boxDimensions.y); ! // Define the dynamic body fixture. ! b2FixtureDef fixtureDef; ! fixtureDef.shape = &dynamicBox;! ! fixtureDef.density = boxDensity; ! fixtureDef.friction = 0.3f; ! fixtureDef.restitution = 0.5f; // 0 is a lead ball, 1 is a super bouncy ball ! body->CreateFixture(&fixtureDef);Thursday, August 2, 12
  • 49. -(void) update: (ccTime) dt { ! //It is recommended that a fixed time step is used with Box2D for stability ! //of the simulation, however, we are using a variable time step here. ! //You need to make an informed choice, the following URL is useful ! //http://gafferongames.com/game-physics/fix-your-timestep/ ! ! int32 velocityIterations = 8; ! int32 positionIterations = 1; Simulating the world(of Box2D) ! ! // Instruct the world to perform a single step of simulation. It is ! // generally best to keep the time step and iterations fixed. ! world->Step(1.0f/60.0f, velocityIterations, positionIterations); ! //Iterate over the bodies in the physics world ! for (b2Body* b = world->GetBodyList(); b; b = b->GetNext()) ! { ! ! if (b->GetUserData() != NULL) { ! ! ! //Synchronize the AtlasSprites position and rotation with the corresponding body ! ! ! CCSprite *myActor = (CCSprite*)b->GetUserData(); ! ! ! myActor.position = CGPointMake( b->GetPosition().x * PTM_RATIO, b- >GetPosition().y * PTM_RATIO); ! ! ! myActor.rotation = -1 * CC_RADIANS_TO_DEGREES(b->GetAngle()); ! ! }! ! }! }Thursday, August 2, 12
  • 50. Touch events setp 3Thursday, August 2, 12
  • 51. - (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { ! ! ! 1 for( UITouch *touch in touches ) { if (dist > 10.0f) { ! ! ! // Create the object and add impulse ! ! ! 2 ! CCSprite *sprite = [CCSprite spriteWithFile:SNOWBALL_FILENAME]; ! ! ! b2CircleShape circleShape; ! ! ! b2FixtureDef fd; ! ! ! b2Vec2 initVel; ! ! ! b2BodyDef circleBodyDefinition; ! ! ! ! 3 ! circleBodyDefinition.type = b2_dynamicBody; ! circleBodyDefinition.position.Set(startPoint.x/PTM_RATIO, startPoint.y/PTM_RATIO); ! ! ! ! 4 ! circleBodyDefinition.angle = 0.000000f; ! circleBodyDefinition.userData = sprite; ! ! ! b2Body *body = world->CreateBody(&circleBodyDefinition); ! ! ! ! 5 ! initVel.Set(0.000000f, 0.000000f); ! body->SetLinearVelocity(initVel); ! ! ! ! ! ! circleShape.m_radius = 0.5f; ! ! ! fd.shape = &circleShape; ! ! ! fd.userData = sprite; ! ! ! body->CreateFixture(&fd); ! ! ! ! ! ! // 2. Add an impulse on the direction of the flick and with the flick force ! ! ! CGPoint forceVector = CGPointMake((endPoint.x-startPoint.x)/PTM_RATIO,(endPoint.y- ! ! ! forceVector = CGPointMake(forceVector.x*2, forceVector.y*2); ! ! ! ! ! 6 ! b2Vec2 blockImpulse = b2Vec2(forceVector.x,forceVector.y); ! ! ! body->ApplyLinearImpulse(blockImpulse, body->GetPosition()); ! ! } else { ! ! ! //NSLog(@"No Flick occured"); ! ! } ! } }Thursday, August 2, 12
  • 52. Penguin animation setp 4Thursday, August 2, 12
  • 53. CCSpriteFrame *frame0 = [CCSpriteFrame frameWithTextureFilename:@"penguino1.png" rect:CGRectMake(0, 0, 64, 64)]; CCSpriteFrame *frame1 = [CCSpriteFrame frameWithTextureFilename:@"penguino2.png" rect:CGRectMake(0, 0, 64, 64)]; CCSpriteFrame *frame2 = [CCSpriteFrame frameWithTextureFilename:@"penguino3.png" rect:CGRectMake(0, 0, 64, 64)]; CCSpriteFrame *frame3 = [CCSpriteFrame frameWithTextureFilename:@"penguino4.png" rect:CGRectMake(0, 0, 64, 64)]; sprite = [CCSprite spriteWithSpriteFrame:frame1]; [sprite setPosition:ccp(p.x,p.y)]; // Remember ccp() is macro for CGPointMake() [self addChild:sprite]; NSMutableArray *animFrames = [NSMutableArray array]; [animFrames addObject:frame0]; [animFrames addObject:frame1]; [animFrames addObject:frame2]; [animFrames addObject:frame3]; CCAnimation *animation = [CCAnimation animationWithSpriteFrames:animFrames delay:0.2f]; CCAnimate *animate = [CCAnimate actionWithAnimation:animation]; CCCallFunc *actionCall = [CCCallFunc actionWithTarget:self selector:@selector(playRandomArcticSqueakSound:)]; CCSequence *seq = [CCSequence actions: animate,actionCall,nil]; [sprite stopAllActions]; [sprite runAction:[CCRepeatForever actionWithAction:seq]];Thursday, August 2, 12
  • 54. Fun with Particle Systems setp 5Thursday, August 2, 12
  • 55. music & effect [[SimpleAudioEngine sharedEngine] playBackgroundMusic:@"Penguino.mp3"]; [[SimpleAudioEngine sharedEngine] playEffect:@"PenguinSqueak3.mp3"]; setp 6Thursday, August 2, 12
  • 56. Labels and Fonts Particle system Tiled maps Draw & update Effects & Grid & Camera Transitions DrawingPrimitives RenderTexture Shader (2.0) ...... more featuresThursday, August 2, 12
  • 57. Thursday, August 2, 12
  • 58. THANK YOU ElvisQin@me.com weibo.com/hielvis Now, how about this game?Thursday, August 2, 12

×