iphone游戏开发之cocos2d

一、 CCNode官方API翻译
  CCNode是cocos2d中最重要的一个基类,是一个抽象类,定义了所有节点的公共属性和方法,因为其重要性,所以这里把官方API对CCNode的属性方法描述粗略了翻译下,方便日后查询使用,也希望能帮到大家,如果有的地方描述不准确,大家可以直接参考官方英文原版的说明:点击打开链接

     CCNode是一个重要的元素,所有我们看到绘制下来的东西都是CCNode,最常见的CCNode有:CCScene,CCLayer,CCSprite,CCMenu; 

        CCNode的主要特征有:每个节点都可以包含子节点、可以定时执行回调、可以执行动作;

        部分CCNode子类提供了一些独特的功能;

        子类化一个CCNode通常意味着下面这些操作:重写初始化方法以初始化资源或回调、创建回调来控制时间、重写绘制着色;

         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 position

默认值为:rotation:0、position:(x=0,y=0)、scale:(x=1,y=0)、contentSize:(x=0,y=0)、anchorPoint:(x=0,y=0).

成员方法描述:

- (void) addChild:
(CCNode *) node
      以z轴为0在当前容器中添加一个子节点,如果该子节点添加到了一个自在运行的节点,“onEnter"和"onEnterTransitionDidFinish"会直接运行;

- (void) addChild:
(CCNode *) node
z:
(NSInteger) z 
     同上,不过z轴可手动设置; 

- (void) addChild:(CCNode *) nodez:(NSInteger) ztag:(NSInteger) tag 

同上,除了可设置z轴,可给要添加到子节点添加tag,方便在父节点中取;

- (CGRect) boundingBox


返回一个CGRect格式的边界范围,该范围仅与父节点相关; 该范围以坐标形式存在;

补充一下:该方法用来补充getContentSize方法,boundingBox可以获得节点缩放或者旋转之后的范围,getContentSize获取原始节点的大小;

- (void) cleanup
当一个正在运行的节点不再运行时(比如其所依附的场景被切换掉了),这时会发生cleanup事件,这时你要中断所有相关的循环引用,该方法移除所有可能的定时方法,动作等;

- (CGPoint) convertToNodeSpace:(CGPoint) worldPoint

将参数worldPoint转换为node的空间坐标

  补充一下:基本的两个坐标系:屏幕坐标系和GL坐标系。屏幕坐标系x轴朝右,y轴朝下。默认原点在左上角。GL坐标系x轴朝右,y轴朝上。默认原点在左下角。

- (CGPoint) convertToNodeSpaceAR:(CGPoint) worldPoint 

将参数以节点锚点为原点,转换为世界坐标;

- (void) draw
重写该方法以绘制自定义节点,需要用到cocos2d的 GL API,详细信息查看ccGLstate.h;另外,[super draw]不可调用; 

- (CCAction*) getActionByTag:
(NSInteger) tag

通过tag从当前正在运行的动作列表中获取动作;

- (CCNode*) getChildByTag:
(NSInteger) tag
通过tag从容器中取到一个子节点;

- (id) init

初始化节点; 

+ (id) node
声明并初始化一个节点,该节点以autorelease方式创建;

- (CGAffineTransform) nodeToParentTransform


节点的矩阵变换方法,返回在父节点中的空间矩阵坐标;

- (CGAffineTransform) nodeToWorldTransform

同上相反;

- (NSUInteger) numberOfRunningActions
返回当前正在运行的动作个数,包括正在运行的和计划运行的,动作组视为一个动作;例如:运行7个动作组成的动作序列,返回1;运行2个动作组成的七个动作序列,返回7;

- (void) onEnter
当节点进入"stage"时调用,如果伴随着transition,则在transition开始时调用;

- (void) onEnterTransitionDidFinish

当节点进入"stage"时调用,如果节点伴随着transition,则在transition结束后调用; 

- (void) onExit
当节点离开"stage"时调用,如果节点离开时伴随着transition,则在transition结束后调用;

- (void) onExitTransitionDidStart

当节点离开"stage"时调用,如果节点离开时伴随着transition,则在transition开始时调用; 

- (CGAffineTransform) parentToNodeTransform


将父节点中的空间坐标系转换为当前节点坐标系;

- (void) pauseSchedulerAndActions

暂停节点的所有调动和动作,被onExit内部调用;

- (void) removeAllChildrenWithCleanup:
(BOOL) cleanup

移除所有子节点,并根据参数决定是否清空所有动作;

- (void) removeChild:(CCNode *) node cleanup:(BOOL) cleanup 

移除指定的子节点,并根据cleanup参数决定是否清除所有的动作;

- (void) removeChildByTag:(NSInteger) tag cleanup:(BOOL) cleanup 

同上差不多;

- (void) removeFromParentAndCleanup:
(BOOL) cleanup
由本身调用,将其从父节点上移除,并根据cleanup决定是否清空所有动作; 
- (void) reorderChild:
(CCNode *) child
z:
(NSInteger) zOrder
将已存在的子节点重新插入,用于发变z轴;
- (void) resumeSchedulerAndActions


恢复节点的序列方法和动作,可以由onEnter内部调用;

- (CCAction*) runAction:(CCAction *) action

执行动作;

- (void) schedule:(SEL) s

执行一个SEL方法,该方法在每帧时都会调用;

- (void) schedule:
(SEL) s
interval:
(ccTimeseconds 
以seconds参数为判断定时执行一个SEL方法s,如果seconds为0,则该方法会在每一帧都运行,这时我们建议以“scheduleUpdate"方法来代替;

如果方法s已经被定义了,then the interval parameter will be updated without scheduling it again(不太明白);

- (void) schedule:
(SEL) selector
interval:
(ccTimeinterval
repeat:
(uint) repeat
delay:
(ccTimedelay 
重复执行方法repeat+1次,每次执行前会等待delay个时间;

- (void) scheduleOnce:
(SEL) selector
delay:
(ccTimedelay 
延迟delay个时间,执行方法一次;

- (void) scheduleUpdate

check whether a selector is scheduled. schedules the "update" method. It will use the order number 0. This method will be called every frame. Scheduled methods with a lower order value will be called before the ones that have a higher order value. Only one "udpate" method could be scheduled per node.

这个方法我怕我翻译不好,大家看下官方说法吧;相当于自动生成的每帧都会执行的方法;
- (void) scheduleUpdateWithPriority:(NSInteger) priority

schedules the "update" selector with a custom priority. This selector will be called every frame. Scheduled selectors with a lower priority will be called before the ones that have a higher value. Only one "udpate" selector could be scheduled per node (You can't have 2 'update' selectors).
带优先级的update,并且强调了每个节点上只能定义一个update方法(官方文档上也有错字,哇哈哈);

- (void) sortAllChildren


性能改进,在绘制前对子节点进行排序
- (void) stopAction:
(CCAction *) action
从动作运行序列中移除一个动作;
- (void) stopActionByTag:
(NSInteger) tag

同上
- (void) stopAllActions
从动作运行序列中移除所有动作;

- (void) transform
 position, scale, rotation and other attributes为基础,执行openGL 矩阵坐标转换;
- (void) transformAncestors
同上
- (void) unschedule:(SEL) s
停止指定selector
- (void) unscheduleAllSelectors
停止所有selector方法;
- (void) visit
用于访问并绘制children的递归方法;
- (CGAffineTransform) worldToNodeTransform
用于反转世界矩阵坐标;

二、
cocos2d中的常用类及使用方法粗览,导演,场景,层,精灵;

CCDirector

        CCDirector是整个cocos2d引擎的核心,游戏之中的一些常用操作控制,比如场景的转换,游戏的暂停继续控制,世界坐标和GL坐标之间的切换,对于精灵(游戏元素)的控制等,还有一些游戏数据的保存调用,屏幕尺寸的获取等;

        CCDirector是游戏项目的总导演,会经常调用进行一些控制,所以该CCDirector利用了单件设计模式,也就是项目里取到的director都是同一个;

        CCDirector的生成方法为[CCDirector sharedDirector],包含的方法如下

(CGSize) winSize
(CGSize) winSizeInPixels
(void) reshapeProjection:
(CGPoint) convertToGL:
(CGPoint) convertToUI:
(float) getZEye
  XXX: missing description. 
(void) runWithScene:
(void) pushScene:
(void) popScene
(void) replaceScene:
(void) end
(void) pause
(void) resume
(void) stopAnimation
(void) startAnimation
(void) drawScene
(void) purgeCachedData
(void) setGLDefaultValues
(void) setAlphaBlending:
(void) setDepthTest:
(void) createStatsLabel
由上可见,CCDirector最主要的还是对场景(Scene)的控制

Scene

        Scene场景也是cocos2d中的重要元素,我们可以理解为场景是一个舞台,游戏中最重要的就是构建一个一个的舞台,游戏中关卡,版块的切换就是一个一个场景的切换;CCDirector控制对场景的切换,pushScene,popScene等director中的方法就是控制场景的切换的~有点类似于UINavigationController中的切换方法;

        director切换场景的常用方法有

1、(void)runWithScene:(CCScene *)scene

第一次进入场景时调用,如果已有正在运行的场景则不能调用该方法;会调用pushScene-->startAnimation;

2、(void)pushScene:(CCScene *)scene 

挂起当前正在运行的场景插入到堆中,执行新场景,只有存在正在运行的场景时才调用该方法;

3、(void)popScene

停止当前正在运行的场景,执行场景队列中之前的场景,只有存在正在运行的场景时才能调用该方法;

4、(void)replaceScene:(CCScene *)scene

用参数场景替代当前正在运行的场景,正在运行的场景被终止;

5、(void)end

终止当前执行效果,释放所有场景,但不会改变场景构成关系;

6、(void)pause

暂停当前运行的场景,场景图被绘制但定时方法等暂停,每秒传输帧率降为4,CPU占用率下降;

7、(void)resume;

恢复暂停的场景,schedule方法继续;

        Scene是CCNode的子类,因为场景的特殊性,所以决定了场景是由一个一个的其他元素构建的,精灵和层,菜单(特殊的层)等,通过addChild等方法,这也是继承自CCNode的一些特性;

层Layer

层是依附于场景之上的图层,可以响应用户的操作事件,一个场景常常是由多个层组成的~cocos2d官网上的一张场景分解图可以很形象地说明;

        左上的场景由三个layer组成,背景层,精灵动画层,菜单层,三个层有顺序地叠加形成了一个scene,该scene由director,在适当的时候用push或pop等方式来控制游戏场景切换;与用户交互的事件也在层之上进行定义,比如菜单层上定义的点击事件,另外层还可以响应加速计;

        层是节点CCNode的子类,所以可以被手动控制翻转或用动作(Action)来进行控制,并可以在其上面添加其他层或者精灵等(addChild);

        层的创建由继承自CCNode的node方法来进行,通常在场景的init方法中进行,如下

        CCLayer *backgroundLayer = [GameBackground node];

        [[CCScene node] addChild:backgroundLayer];

        层的叠加顺序取决于z轴(z-order)的值;

        层的本质是对节点进行分组(iPhone&iPad cocos2d 游戏开发实战);

精灵Scripte

         精灵CCSprite继承自CCNode,可以认为是一个可以被手动控制,执行动作的2D图片,我们在游戏中看到的人物形象等基本上全是精灵;精灵可以在其身上添加子精灵,并且运动时,附着的其他精灵会跟着一齐运动;精灵常常与美术相关;

 三、 游戏中的动作CCAction
CCAction是游戏的一个和重要组成部分,游戏之所以区别于应用就是因为形象鲜明,趣味性交互性强,如果游戏元素没有动作,那就很无聊了;

        之前我们已经介绍过,CCNode节点中有一个(void)runAction:(CCAction *)action 方法,所以,所有继承自CCNode的类,比如精灵,层,甚至菜单都可以执行动作;

        CCAction有很庞大的层次关系,如图所示


        其中主要的为CCAction-->CCFiniteTimeAction

        其中CCFiniteTimeAction下的两个子类CCActionInstant和CCActionInterval分别为瞬时动作和延时动作;

瞬时动作更接近于节点属性的设置,有的时候是为了更方便地组成动作序列,延时动作则是我们经常看到的一些动画画面;

        动作的返回值类型为id,所以,你会经常看到这种写法

        CCMoveTo *move = [CCMoveTo actionWithDuration:3 position:CGPointMake(100,200)];

        [sprite runAction :move];

        瞬时动作我们会在介绍动作序列时再作详细说明,下面归纳一下延时动作,常用的延时动作有

CCMoveTo 

        移动到参数position位置

        示例:CCMoveTo *move = [CCMoveTo actionWithDuration:3 position:CGPointMake(100,200)];//该动作移动到position参数位置;


CCMoveBy

        精灵移动参数个位置

        示例:[sprite runAction:[CCMoveBy actionWithDuration:3 position:pos]];//该动作使节点移动pos个位置;


CCFadeTo

        节点色调透明度变化

        示例: [sprite runAction:[CCFadeTo actionWithDuration:3 opacity:opa]]; //节点透明度渐变为opa(0~255);


CCFadeIn

        节点亮度从0渐变为最高

        示例: [sprite runAction:[CCFadeIn actionWithDuration:3 ]; //节点在3秒内从黑暗变为最亮;


CCFadeOut

        同上相反;


CCBlink

        节点闪烁,需设置闪烁次数;

        示例:[sprite runAction:[CCBlink actionWithDuration:3 blinks:t]]; //节点在3秒内闪烁t次;如果持续时间变长,闪烁频率会自动调低;


CCRotateTo

        节点旋转,需设置旋转角度

        示例:[sprite runAction:[CCRotateTo actionWithDuration:3 angle:180]]; //节点在3秒内旋转180度;


CCRotateBy

        节点旋转,经试验没发现与CCRotateTo有何区别;

        示例:[sprite runAction:[CCRotateBy actionWithDuration:3 angle:180]];      //效果同上一样;


CCScaleTo

        节点放大,有两个方法

        示例:[sprite runAction:[CCScaleTo actionWithDuration:3 scale :2]];//节点在3秒内放大到原来的2倍;

 [sprite runAction:[CCScaleTo actionWithDuration:3 scaleX:2 scaleY:3]];//节点在3秒内横方向放大到原来的2倍,纵方向放大到原来的3倍;


CCScaleBy 

        节点放大,经试验没发现与上述效果有何区别(大家发现后告诉我);


CCTintTo

        节点调色

        示例:[sprite runAction:[CCTintTo actionWithDuration:3 red:110 green:110 blue:110]]; //节点在三秒内着色为RGB颜色如参数所示


CCTintBy

        节点渐变

        示例:[sprite runAction:[CCTintBy actionWithDuration:3 red:110 green:110 blue:110]]; //节点在三秒内以RGB参数逐渐加深;


CCSkewTo

        节点斜率变化

        示例:[sprite runAction:[CCSkewTo actionWithDuration:3 skewX:30 skewY:5]];//将一个节点按横坐标30,纵坐标5的大小倾斜;该参数效果见图

 


CCSkewBy

        效果同上一样;


CCBezierTo

        使节点按贝塞尔曲线移动,需先生成一个贝塞尔参数,见示例

        示例:

ccBezierConfig bezier;//创建贝塞尔曲线

        bezier.controlPoint_1 =ccp(sprite.position.x, sprite.position.y);//起始点

        bezier.controlPoint_2 =ccp(sprite.position.x+5,sprite.position.y+20);//控制点

        bezier.endPosition =ccp(sprite.position.x+50, sprite.position.y+100);//结束位置

        [sprite runAction:[CCBezierToactionWithDuration:3bezier:bezier]];

关于贝塞尔曲线,主要作用是通过点确定准确的曲线图形,建议大家百度一下点击打开链接


CCBezierBy

        每次移动贝塞尔曲线个距离;用法同上;


        通过上面这些主流的动作行为,我们可以实现一些很有视觉冲击力的动画效果,常用到的常常有放大(远近景拉伸),旋转,跳越等;

        cocos2d中的动作远比上面这些要灵活的多,下回就介绍一下动作的一些修饰,动作序列,和动作序列中怎样加入一些回调方法;

 四、 动作的修饰、动作序列和动作序列中调用方法

用CCActionEase来对动作进行修饰

CCActionEase继承自CCActionInterval,层次图如图所示:


该类用于更灵活的使用动作,所以我习惯称为对动作的修饰类,之所以这样叫也是因为CCActionEase在生成时是在已有的action上又包了一层(actionWithAction),而节点调用时也是直接将其作为动作来调用的;大家随便怎么叫吧,知道有这么个玩意儿就行了;

CCEaseBackIn

在正常runAction前会有一个拉后的动作;

示例:

CCEaseBackIn *ease = [CCEaseBackInactionWithAction:[CCMoveByactionWithDuration:3position:ccp(200,0)]];

 [sprite runAction:ease];

//效果为精灵在往向移动200之前先向左移动一部分;


CCEaseBackInOut

修饰前的动作运行前向后,运行结束后回弹,注意,这里回弹是超过设定的移动距离再弹回;

CCEaseBackIn *ease = [CCEaseBackInOut actionWithAction:[CCMoveBy actionWithDuration:3 position:ccp(200,0)]];

 [sprite runAction:ease];


CCEaseBackOut

修饰前的动作运行结束后弹回

CCEaseBackOut *ease = [CCEaseBackOut actionWithAction:[CCMoveBy actionWithDuration:3 position:ccp(200,0)]];

 [sprite runAction:ease];


CCEaseBounceIn

修饰前的动作结束前有三次回到起点的跳跃(自己总结的,大家还是自己看看效果好)

 CCEaseBounceIn *ease = [CCEaseBounceInactionWithAction:[CCMoveByactionWithDuration:10position:ccp(200,0)]];

  [sprite runAction:ease];


CCEaseBounceOut

修饰前的动作结束后往之前的运行轨迹上跳跃三次

 CCEaseBounceOut *ease = [CCEaseBounceOutactionWithAction:[CCMoveByactionWithDuration:10position:ccp(200,0)]];

        [sprite runAction:ease];


CCEaseBounceInOut

结合了上面两种效果

 CCEaseBounceInOut *ease = [CCEaseBounceInOutactionWithAction:[CCMoveByactionWithDuration:10position:ccp(200,0)]];

        [sprite runAction:ease];


CCEaseElasticIn

与CCEaseBounceIn效果类似,不过不是跳跃,是渐快的移动;

CCEaseElasticIn *ease = [CCEaseElasticInactionWithAction:[CCMoveByactionWithDuration:10position:ccp(200,0)]];

        [sprite runAction:ease];


CCEaseElasticOut

与CCEaseBounceOut效果类似,依然是渐快的弹性移动;

CCEaseElasticOut *ease = [CCEaseElasticOutactionWithAction:[CCMoveByactionWithDuration:10position:ccp(200,0)]];

        [sprite runAction:ease];


CCEaseElasticInOut

结合了上面两种效果;


CCEaseIn

这是比较早的版本就存在的类库了,在运动的结尾突然加速


CCEaseOut

在运动一开始就突然加速;


CCEaseInOut

由慢到快,再由快到慢,注意这三个是CCEaseRateAction的子类,有一个方法

CCEaseIn actionWithAction:action rate:rate 是可以调节rate作为速率的


还有一些CCEase效果,不过因为不常用,或者我也把握不准,试不出来效果,这里就不列了;



使用动作序列CCSequence将动作组合起来

CCSequence从CCActionInterval继承而来,使用方法类似于一个array,可以在里面添加几个动作,使其动作一个接一个运行(one after another),例如

[plain] view plain copy
  1. CCEaseBounceOut *ease = [CCEaseBounceOut actionWithAction:[CCMoveBy actionWithDuration:3 position:ccp(100,0)]];  
  2.        CCJumpBy *jump = [CCJumpBy actionWithDuration:3 position:ccp(50,0) height:50 jumps:3];  
  3.        CCSequence *sequence = [CCSequence actions:ease,jump, nil];  
  4.        [sprite runAction:sequence];  

上面动作序列的效果为:sprite向右移动100,其中因为CCEaseBounceOut的原因水平方向往回弹三次,之后往向跳三次,每次50,高度为50;

注意添加动作序列时需要以nil为结尾,ios开发同学应该很熟悉这种操作;


使用回调动作CCCallFunc在动作序列中添加方法回调

一个动作序列中一个动作一个动作之间,如果我们想要调用某个方法,可以使用CCCallFunc来进行,使用方法如下:

先添加一个方法(无参数)

[plain] view plain copy
  1. -(void)callBackTest  
  2. {  
  3.     CCLOG(@"!!!!!!");  
  4. }  

然后用CCCallFunc来生成一个可以添加到动作序列里的对象,并放到两个动作之间;
[plain] view plain copy
  1. CCEaseBounceOut *ease = [CCEaseBounceOut actionWithAction:[CCMoveBy actionWithDuration:3 position:ccp(100,0)]];  
  2.         CCJumpBy *jump = [CCJumpBy actionWithDuration:3 position:ccp(50,0) height:50 jumps:3];  
  3.         CCCallFunc *func = [CCCallFunc actionWithTarget:self selector:@selector(callBackTest)];  
  4.         CCSequence *sequence = [CCSequence actions:ease,func,jump, nil];  
  5.           
  6.         [sprite runAction:sequence];  

这样就会在执行完ease动作之后,执行jump动作之前,调用callBackTest方法,输出内容;

除了CCCallFunc,还有CCCallFuncN,CCCallFuncND可以使用,三者之间有一定的区别;CCCallFunc调用的方法没有参数,后两者分别有一个,两个参数且固定的第一个参数都是sender本身;

-(void)onCallFunc

{ }

-(void)onCallFuncN:(id)sender

{ }

-(void)onCallFuncND:(id)sender data:(void *)data

{ }

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
(译)cocos2d里面如何用texture picker和像素格式来优化spritesheet.pdf (译)在cocos2d里如何制作各种按钮.pdf (译)如何使用cocos2d制作基于tilemap的游戏教程 第一部分.pdf (译)如何在cocos2d里面使用动画和spritesheet.pdf (译)如何用cocos2d制作iphone游戏:旋转炮塔.pdf (译)如何用cocos2d制作iphone游戏:更猛的怪物和更多得管卡.pdf (译)如何使用cocos2d制作一个Slide Image Game:第一部分.pdf (译)如何使用cocos2d来制作一个塔防游戏:第一部分.pdf cocos2d 2.0 添加遮罩.pdf iOS Code Signing解惑.pdf iPhone上面的现实增强(Augmented Reality)入门教程.pdf OpenGL ES2.0 – Iphone开发指引.pdf OpenGLES2.0 Iphone开发指引:第二部分,纹理贴图.pdf 使用cocos2d和box2d制作滚动背景.pdf 加入敌人和战斗:如果使用cocos2d制作基于tiled地图的游戏:第三部分.pdf 在cocos2d里面如何使用物理引擎box2d:弹球.pdf 在cocos2d里面如何拖拽精灵.pdf 如何使用box2d来做碰撞检测(且仅用来做碰撞检测).pdf 如何使用CCRenderTexture来创建动态纹理.pdf 如何使用cocos2d1.0来给sprite添加Mask(遮罩).pdf 如何使用cocos2d制作一个塔防游戏:引子.pdf 如何使用cocos2d制作一个太空射击游戏.pdf 如何使用cocos2d制作一个打地鼠的游戏:(第二部分。完).pdf 如何使用cocos2d和box2d来制作一个Breakout游戏:第一部分.pdf 如何使用cocos2d和box2d来制作一个Breakout游戏:第二部分(完).pdf 如何使用cocos2d来制作一个打地鼠的游戏:第一部分.pdf 如何使用GameCenter制作一个简单的多人游戏教程:第一部分.pdf 如何使用GameCenter制作一个简单的多人游戏教程:第二部分.pdf 如何使用NSCoding和NSFileManager来保存你的应用程序数据.pdf 如何制作一个类似tiny wings的游戏:第一部分.pdf 如何制作一个类似tiny wings的游戏:第二部分(完).pdf 如何升级你的cocos2d版本.pdf 如何学好Iphone开发.pdf 如何查找资料.pdf 碰撞检测和收集物品:如何使用cocos2d制作基于tiled地图的游戏:第二部分.pdf (译)cocos2d精灵教程:第一部分.pdf (译)cocos2d精灵教程:第三部分.pdf (译)cocos2d精灵教程:第二部分.pdf (译)cocos2d菜单教程:第一部分.pdf (译)cocos2d菜单教程:第三部分(完).pdf (译)cocos2d菜单教程:第二部分.pdf (译)使用cocos2d和box2d来制作一个platformer游戏.pdf (译)如何使用cocos2d制作一个塔防游戏:第三部分.pdf (译)如何使用cocos2d制作一个塔防游戏:第二部分.pdf (译)如何使用cocos2d制作一个塔防游戏:第四部分(完).pdf (译)如何使用cocos2d制作一个滑动图片游戏教程:第二部分(完).pdf (译)如何用cocos2d制作一款简单的iphone游戏(第一部分).pdf
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值