• cocos2d 学习 第五章


    当你用CCDirector replaceScene方法替换场景时, 每个节点都会调用CCNode所带的三个方法。

    这三个方法是:onEnter, onEnterTransitionDidFinish和onExit。 

    取决于是否使用了CCTransitionScene, onEnter和onExit会在场景转换过程中的某个时间点被调用。对于这三个方法, 你必须调用它们的super方法以避免触摸输入问题和内存泄漏的问题。 

    -(void) onEnter
    {

      // 节点调用init方法以后将会调用此方法
      // 如果使用了CCTransitionScene,将会在过渡效果开始以后调用此方法

      [super onEnter];

    }

    -(void) onEnterTransitionDidFinish
    {
    

        // 调用onEnter以后将会调用此方法
        // 如果使用了CCTransitionScene,将会在过渡效果结束以后调用此方法

        [super onEnterTransitionDidFinish];

    }
    -(void) onExit

        // 节点调用dealloc方法之前将会调用此方法
        // 如果使用了CCTransitionScene,将会在过渡效果结束以后调用此方法

        [super onExit]; 


    如果你不在onEnter方法里调用它的super方法的话,你的新场景可能不会对触摸或者加速计的输入有任何反应。

    如果你不在onExit方法里调用它的super方法,当前场景可能不会从内存里释放。 

    你可以在场景转换之前或者之后,通过使用上述方法在节点中完成一些特定的 操作。因为在程序进入onEnter方法的时候,场景中的所有节点都已经设置完成 了;同时,在onExit方法中,所有节点都还存在于内存中。 

    1. scene: OtherScene
    2. init: 
    3. onEnter: 
    4. // ......
    5. onExit: 
    6. onEnterTransitionDidFinish: 

    7. dealloc: 

    replaceScene -> Other Scene.

    ===========================================

    scene: OtherScene

    init: <OtherScene = 0x1835e10 | Tag = -1>

    onExit: <FirstScene = 0x436170 | Tag = -1>  // 因为切换到OhterScene时,FirstScene还在内存中,过程是先初始化OhterScene,之后从内存中清空FirstScene

    dealloc: <FirstScene = 0x436170 | Tag = -1>

    onEnter: <OtherScene = 0x1835e10 | Tag = -1>

    onEnterTransitionDidFinish: <OtherScene = 0x1835e10 | Tag = -1>

     

    #import <Foundation/Foundation.h>

    #import "cocos2d.h"

    typedefenum

    {

        TargetSceneINVALID = 0,

        TargetSceneFirstScene,

        TargetSceneOtherScene,

        TargetSceneMAX,

    }

    TargetScenes;

     

    @interface LoadingScene : CCScene

    {

        TargetScenes targetScene_;

    }

    +(id)sceneWithTargetScene:(TargetScenes)targetScene;

    -(id)initWithTargetScene:(TargetScenes)targetScene;

    @end

     

     

    #import "LoadingScene.h"

    #import "FirstScene.h"

    #import "OtherScene.h"

     

    @implementation LoadingScene

    +(id)sceneWithTargetScene:(TargetScenes)targetScene

    {

        return [[[self alloc] initWithTargetScene:targetScene] autorelease];

    }

     

    -(id)initWithTargetScene:(TargetScenes)targetScene

    {

        if((self = [super init]))

        {

            targetScene_ = targetScene;

            CCLabelTTF *label = [CCLabelTTFlabelWithString:@"Loading..."

                                                   fontName:@"Marker Felt"

                                                   fontSize:64];

            CGSize size = [[CCDirectorsharedDirector] winSize];

            label.position = CGPointMake(size.width*0.5, size.height*0.5);

            [self addChild:label];

            [selfscheduleUpdate];

        }

        returnself;

    }

     

    -(void)update:(ccTime)delta

    {

        [selfunscheduleAllSelectors];

        switch (targetScene_) {

            caseTargetSceneFirstScene:

                [[CCDirectorsharedDirector] replaceScene:[FirstScenescene]];

                break;

            caseTargetSceneOtherScene:

                [[CCDirectorsharedDirector] replaceScene:[OtherScenescene]];

                break;

            default:

                NSAssert2(nil, @"%@:unsupported TargetScene %i", NSStringFromSelector(_cmd), targetScene_);

                break;

        }

    }

    @end

     

    因为 LoadingScene 继承自 CCScene,并且要求传递一个新的参数给它,所以仅 仅调用[CCScene node]是不够的。SceneWithTargetScene 方法首先会完成对 self 的内存分配,然后调用 initWithTargetScene 方法,最后返回一个新的自 动释放对象。 

    这里的 init 方法把目标场景储存在一个成员变量里面,接着生成一个 “Loading...”标签,最后运行 scheduleUpdate 这个预约方法。 

    为什么我们不在init方法里直接使用replaceScene方法呢?这里有两条规则需要遵守。规则一:永远不要在一个节点的init方法中调用CCDirector的replaceScene方法。

    规则二:请遵守规则一。不遵守规则的后果是程序崩溃。Director无法容忍一个节点在初始化的同时进行场景替换。 

    在过渡效果中使用LoadingScene可以优化内存的使用:因为你使用了一个简单 的过渡场景用于替换当前场景,然后用最终的目标场景替换这个过渡场景。在 这个替换的过程中,cocos2d将会有足够的时间来释放之前场景所占用的内存。 我们得到的实际效果是:不再会有两个复杂场景同时占用着内存的情况了,因 此在场景转换过程中也就减少了出现内存使用高峰的机会。 

     1 #import <Foundation/Foundation.h>
     2 #import "cocos2d.h"
     3 #import "GameLayer.h"
     4 #import "UserInterfaceLayer.h"
     5 
     6 typedef enum                // 定义二个层的Tag值
     7 {
     8     LayerTagGameLayer,      // 用于标示[游戏层]
     9     LayerTagUILayer,        // 用于标示[用户设置层]
    10 } MultiLayerSceneTags;
    11 
    12 typedef enum                            // 定义动作Tag
    13 {
    14     ActionTagGameLayerMovesBack,
    15     ActionTagGameLayerRotates,
    16 } MultiLayerSceneActionTags;
    17 
    18 @interface MultiLayerScene : CCLayer
    19 {
    20     bool isToucheForUserInterface;      // 判断用户点击的是否为设置界面
    21 }
    22 @property (readonly) GameLayer *gameLayer;
    23 @property (readonly) UserInterfaceLayer *uiLayer;
    24 
    25 +(MultiLayerScene *)sharedLayer;
    26 +(CGPoint)locationFromTouch:(UITouch *)touch;
    27 +(CGPoint)locationFromTouches:(UITouch *)touches;
    28 +(id)scene;
    29 
    30 @end
     1 #import "MultiLayerScene.h"
     2 
     3 @implementation MultiLayerScene
     4 
     5 static MultiLayerScene* multiLayerSceneInstance;    // 定义静态的本场景变量
     6 
     7 +(MultiLayerScene *)sharedLayer     // 返回静态场景变量
     8 {
     9     NSAssert(multiLayerSceneInstance != nil, @"MultiLayerScene not available!");
    10     return multiLayerSceneInstance;
    11 }
    12 
    13 #pragma mark 返回游戏层
    14 - (GameLayer *)gameLayer
    15 {
    16     CCNode *layer = [self getChildByTag:LayerTagGameLayer];
    17     NSAssert([layer isKindOfClass:[GameLayer class]], @"%@: not a GameLayer!",NSStringFromSelector(_cmd));
    18     return (GameLayer *)layer;
    19 }
    20 
    21 #pragma mark 返回用户设置层
    22 - (UserInterfaceLayer*)uiLayer
    23 {
    24     CCNode* layer = [[MultiLayerScene sharedLayer] getChildByTag:LayerTagUILayer];
    25     NSAssert([layer isKindOfClass:[UserInterfaceLayer class]], @"%@: not a UserInterfaceLayer!", NSStringFromSelector(_cmd));
    26     return (UserInterfaceLayer *)layer;
    27 }
    28 
    29 #pragma mark 得到用户点击的坐标并转换为OpenGL坐标
    30 +(CGPoint)locationFromTouch:(UITouch *)touch
    31 {
    32     // locationInView:函数返回一个CGPoint类型的值,表示触摸在view这个视图上的位置,这里返回的位置是针对view的坐标系的。
    33     // 调用时传入的view参数为空的话,返回的时触摸点在整个窗口的位置。
    34     CGPoint touchLocation = [touch locationInView:[touch view]];
    35     
    36     // convertToGL:将ios坐标系转换为OpenGL坐标系,返回类型 CGPoint
    37     return [[CCDirector sharedDirector] convertToGL:touchLocation];
    38 }
    39 
    40 #pragma mark 如果用户是多点触摸,那么返回其中任意一个触摸点的OpenGL坐标
    41 +(CGPoint) locationFromTouches:(NSSet *)touches
    42 {
    43     return [self locationFromTouch:[touches anyObject]];
    44 }
    45 
    46 #pragma mark - 静态构造方法Scene
    47 +(id) scene
    48 {
    49     CCScene* scene = [CCScene node];
    50     MultiLayerScene* layer = [MultiLayerScene node];
    51     [scene addChild:layer];
    52     return scene;
    53 }
    54 
    55 #pragma mark 初始化方法init
    56 -(id) init
    57 {
    58     if ((self = [super init]))
    59     {
    60         NSAssert(multiLayerSceneInstance == nil, @"another MultiLayerScene is already in use!");
    61         multiLayerSceneInstance = self;
    62         
    63         GameLayer* gameLayer = [GameLayer node];
    64         [self addChild:gameLayer z:1 tag:LayerTagGameLayer];        // 将游戏层加入场景中,Z轴位置为 1,
    65         // z:是指添加的ZOrder值,ZOrder是指该成员的层级(也可以说深度),z值大的成员在z值小的成员的上面;
    66         
    67         UserInterfaceLayer* uiLayer = [UserInterfaceLayer node];    // 将用户设置层加入场景中,Z轴位置为 2
    68         [self addChild:uiLayer z:2 tag:LayerTagUILayer];
    69     }
    70     return self;
    71 }
    72 
    73 -(void) dealloc
    74 {
    75     CCLOG(@"%@: %@", NSStringFromSelector(_cmd), self);
    76     multiLayerSceneInstance = nil;
    77     [super dealloc];
    78 }
    79 
    80 @end
     1 #import <Foundation/Foundation.h>
     2 #import "cocos2d.h"
     3 
     4 #pragma mark 游戏内容层
     5 @interface GameLayer : CCLayer
     6 {
     7     CGPoint gameLayerPosition;
     8     CGPoint lastTouchLocation;
     9 }
    10 
    11 @end
      1 #import "GameLayer.h"
      2 #import "cocos2d.h"
      3 #import "MultiLayerScene.h"
      4 
      5 @interface GameLayer (PrivateMethod)
      6 -(void)addRandomThings;
      7 @end
      8 
      9 @implementation GameLayer
     10 -(id)init
     11 {
     12     if((self = [super init]))
     13     {
     14         gameLayerPosition = self.position;                                                      // 返回层的默认坐标(0,0)
     15         CGSize screenSize = [[CCDirector sharedDirector] winSize];
     16         CCSprite *background = [CCSprite spriteWithFile:@"grass.png"];                          // 载入“小草”精灵
     17         background.position = CGPointMake(screenSize.width * 0.5, screenSize.height * 0.5);     // 设置小草精灵的位置
     18         [self addChild:background];                                                             // 将小草加入游戏层中
     19         
     20         CCLabelTTF *label = [CCLabelTTF labelWithString:@"GameLayer"
     21                                              fontName:@"Marker Felt"
     22                                                fontSize:44];
     23         label.color = ccBLACK;
     24         label.position = CGPointMake(screenSize.width*0.5, screenSize.height * 0.5);
     25         //label.anchorPoint = CGPointMake(0.5f, 0.5f);
     26         [self addChild:label];                                                                  // 将文字标签加入游戏层
     27         
     28         [self addRandomThings];                                                             
     29         self.isTouchEnabled = YES;                                                              // 支持触屏
     30     }
     31     return self;
     32 }
     33 
     34 #pragma mark 在游戏层添加一些随机物品
     35 -(void)addRandomThings
     36 {
     37     CGSize screenSize = [[CCDirector sharedDirector] winSize];
     38     
     39     for (int i = 0; i<4; i++)                       // 添加4团随机的火元素
     40     {
     41         CCSprite *firething = [CCSprite spriteWithFile:@"firething.png"];
     42         firething.position = CGPointMake(CCRANDOM_0_1()*screenSize.width, CCRANDOM_0_1()*screenSize.height);
     43         [self addChild:firething];                  // 将火元素添加到游戏层中
     44         [self runRandomMoveSequence:firething];     // 随机移动此火元素
     45     }
     46     
     47     for (int i = 0; i<10; i++)                      // 添加10个随机的蜘蛛
     48     {
     49         CCSprite *spider = [CCSprite spriteWithFile:@"spider.png"];
     50         spider.position = CGPointMake(CCRANDOM_0_1()*screenSize.width, CCRANDOM_0_1()*screenSize.height);
     51         [self addChild:spider];
     52         [self runRandomMoveSequence:spider];        // 随机移动此火元素
     53     }
     54 }
     55 -(void) runRandomMoveSequence:(CCNode*)node
     56 {
     57     float duration = CCRANDOM_0_1() * 5 + 1;
     58     
     59     CCMoveBy *move1 = [CCMoveBy actionWithDuration:duration position:CGPointMake(-180, 0)];     // 在现在位置水平左移180个单位
     60     CCMoveBy* move2 = [CCMoveBy actionWithDuration:duration position:CGPointMake(0, -180)];
     61     CCMoveBy* move3 = [CCMoveBy actionWithDuration:duration position:CGPointMake(180, 0)];
     62     CCMoveBy* move4 = [CCMoveBy actionWithDuration:duration position:CGPointMake(0, 180)];
     63     CCSequence *sequence = [CCSequence actions:move1,move2,move3,move4, nil];                   // 定义一个动作执行序列
     64     CCRepeatForever *repeat = [CCRepeatForever actionWithAction:sequence];                      // 该类的作用就是无限期执行某个动作或动作序列,直到被停止
     65     [node runAction:repeat];
     66 }
     67 
     68 #pragma mark 在CCLayer中经常要注册Touch Dispatcher来让Layer处理Touch事件。 Dispatcher:调度员
     69 -(void)registerWithTouchDispatcher
     70 {
     71     // 设置此层可以接受手触发事件,且priority(优先级)为0,越小优先级越高,越先接受用户触摸事件,swallow(是否可以吞没事件)为YES
     72     [[[CCDirector sharedDirector] touchDispatcher] addTargetedDelegate:self
     73                                                               priority:0
     74                                                        swallowsTouches:YES];
     75 }
     76 
     77 #pragma mark 接受用户触摸事件
     78 -(BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event
     79 {
     80     CCLOG(@"GameLayer: ccTouchBegan");
     81     lastTouchLocation = [MultiLayerScene locationFromTouch:touch];  // 得到用户触摸开始点OpenGL坐标
     82     [self stopActionByTag:ActionTagGameLayerMovesBack];             // 停止此时可能存在加速动作
     83     return YES;                                                     // 如果是NO,那么就结束触摸事件传递,ccTouchMoved、ccTouchEnded将不执行
     84     
     85 }
     86 
     87 #pragma mark 接受用户滑动事件
     88 -(void)ccTouchMoved:(UITouch *)touch withEvent:(UIEvent *)event
     89 {
     90     CCLOG(@"GameLayer: ccTouchMoved");
     91     CGPoint currentTouchLocaion = [MultiLayerScene locationFromTouch:touch];    // 在移动的过程中得到一系列新的目标点位
     92     CGPoint moveTo = ccpSub(lastTouchLocation, currentTouchLocaion);            // 得到二个点相减后的位置
     93     moveTo = ccpMult(moveTo, -1);                                               // 将moveTo的X,Y 都与-1相乘,得到原点将移动到新点位的值
     94     lastTouchLocation = currentTouchLocaion;                                    // 将现在点位更新为已经使用过的点位
     95     self.position = ccpAdd(self.position, moveTo);                              // 将本层原点向moveTo点位移动
     96 }
     97 
     98 #pragma mark 用户触摸事件结束后,本层内容恢复到原点
     99 -(void)ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event
    100 {
    101     CCLOG(@"GameLayer: ccTouchEnded");
    102     CCMoveTo *move = [CCMoveTo actionWithDuration:1 position:gameLayerPosition];        // 返回原点
    103     CCEaseIn *ease = [CCEaseIn actionWithAction:move rate:0.5f];                        // 在0.5秒内完成move动作,且开始运行时是加速状态的
    104     ease.tag = ActionTagGameLayerMovesBack;                                             // 此加速动作的Tag = ActionTagGameLayerMovesBack
    105     [self runAction:ease];
    106 }
    107 @end
     1 #import <Foundation/Foundation.h>
     2 #import "cocos2d.h"
     3 #pragma mark 用户设置层
     4 
     5 typedef enum
     6 {
     7     UIlayerTagFrameSprite,
     8 } UserInterfaceLayerTags;
     9 
    10 @interface UserInterfaceLayer : CCLayer {
    11     
    12 }
    13 -(BOOL) isTouchMe:(CGPoint)touchLocation;
    14 @end
     1 #import "UserInterfaceLayer.h"
     2 #import "MultiLayerScene.h"
     3 
     4 @implementation UserInterfaceLayer
     5 -(id)init
     6 {
     7     if((self = [super init]))
     8     {
     9         CGSize screenSize = [[CCDirector sharedDirector] winSize];
    10         CCSprite *uiframe = [CCSprite spriteWithFile:@"ui-frame.png"];
    11         uiframe.position = CGPointMake(0,screenSize.height);
    12         uiframe.anchorPoint = CGPointMake(0, 1);
    13         [self addChild:uiframe z:0 tag:UIlayerTagFrameSprite];                  // 设置图片Tag = UIlayerTagFrameSprite
    14         
    15         CCLabelTTF *label = [CCLabelTTF labelWithString:@"这里可以显示程序积分" fontName:@"Courier" fontSize:22];
    16         label.color = ccBLACK;
    17         label.position = CGPointMake(screenSize.width * 0.5,screenSize.height);
    18         label.anchorPoint = CGPointMake(0.5f, 1);
    19         [self addChild:label];
    20         self.isTouchEnabled = YES;
    21     }
    22     return self;
    23 }
    24 
    25 -(void) registerWithTouchDispatcher
    26 {
    27     [[[CCDirector sharedDirector] touchDispatcher] addTargetedDelegate:self priority:-1 swallowsTouches:YES];
    28 }
    29 -(BOOL)isTouchMe:(CGPoint)touchLocation
    30 {
    31     CCNode *node = [self getChildByTag:UIlayerTagFrameSprite];              // 查找到tag = UIlayerTagFrameSprite 的精灵对象
    32     return CGRectContainsPoint([node boundingBox], touchLocation);          // 判断用户触摸点是否在node之中
    33 }
    34 
    35 #pragma mark 当用户触摸标题栏时,gameLayer进行一系列操作
    36 -(BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event
    37 {
    38     CGPoint location = [MultiLayerScene locationFromTouch:touch];                       // 得到用户点击的OpenGL坐标
    39     bool isTouchHandled = [self isTouchMe:location];                                    // 判断用户点击的是否为UserInteface层
    40     if(isTouchHandled)                                                                  // 如果 YES那么事件将被吞没不向下层传递了
    41     {
    42         CCNode *node = [self getChildByTag:UIlayerTagFrameSprite];
    43         NSAssert([node isKindOfClass:[CCSprite class]], @"node is not a CCSprite");
    44         ((CCSprite *)node).color = ccRED;                                               // 将UserInterface层显示的字体改为红色
    45         
    46         CCScaleTo *scaleDown = [CCScaleTo actionWithDuration:2 scale:0];                // 在2秒内缩放为0,消失了
    47         CCScaleTo *scaleUp = [CCScaleTo actionWithDuration:2 scale:1];                  // 在2秒内还原为原来大小
    48         CCSequence *sequence = [CCSequence actions:scaleDown,scaleUp, nil];             // 定义包括二种缩放方式的动作序列
    49         sequence.tag = ActionTagGameLayerRotates;                                       // 将此序列的Tag = ActionTagGameLayerRotates
    50         
    51         GameLayer *gameLayer = [MultiLayerScene sharedLayer].gameLayer;                 // 得到gameLayer层
    52         CCRotateBy *rotate = [CCRotateBy actionWithDuration:4 angle:360];               // 在4秒内旋转360度
    53         [gameLayer stopActionByTag:ActionTagGameLayerRotates];                          // 停止可能存在的缩放序列
    54         [gameLayer setRotation:0];                                                      // 初始化gameLayer层旋转角度为0
    55         [gameLayer setScale:1];                                                         // 初始化gameLayer层缩放比例为1倍,既原始大小
    56         [gameLayer runAction:rotate];                                                   // 执行旋转
    57         [gameLayer runAction:sequence];                                                 // 执行缩放
    58     }
    59     return isTouchHandled;
    60 }
    61 
    62 #pragma mark 用户触摸结束后恢复标题字体颜色
    63 -(void)ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event
    64 {
    65     CCNode *node = [self getChildByTag:UIlayerTagFrameSprite];
    66     NSAssert([node isKindOfClass:[CCSprite class]], @"node is not a CCSprite");
    67     ((CCSprite *)node).color = ccWHITE;
    68 }
    69 
    70 -(void)dealloc
    71 {
    72     CCLOG(@"%@: %@",NSStringFromSelector(_cmd),self);
    73     [super dealloc];
    74 }
    75 @end
     1 #import <Foundation/Foundation.h>
     2 #import "cocos2d.h"
     3 
     4 // CCTargetedTouchDelegate,CCStandardTouchDelegate 协议将使对象支持触摸事件
     5 
     6 @interface Spider : NSObject <CCTargetedTouchDelegate>  
     7 {
     8     CCSprite *spiderSprite;         // 蜘蛛对象中有一个精灵对象
     9     int numUpdates;
    10 }
    11 
    12 +(id)spiderWithParentNode:(CCNode *)parentNode;
    13 -(id)initWithParentNode:(CCNode *)parentNode;
    14 @end
     1 #import "Spider.h"
     2 #import "MultiLayerScene.h"
     3 
     4 @implementation Spider
     5 
     6 #pragma mark 一个像 CCNode类一样的静态自动释放的初始化方法。这是在模仿 cocos2d 的内存管理方式。
     7 +(id)spiderWithParentNode:(CCNode *)parentNode
     8 {
     9     return [[[self alloc] initWithParentNode:parentNode] autorelease];
    10 }
    11 
    12 -(id)initWithParentNode:(CCNode *)parentNode
    13 {
    14     if((self = [super init]))
    15     {
    16         CGSize screenSize = [[CCDirector sharedDirector] winSize];
    17         spiderSprite = [CCSprite spriteWithFile:@"spider.png"];
    18         spiderSprite.position = CGPointMake(CCRANDOM_0_1()*screenSize.width,CCRANDOM_0_1()*screenSize.height);
    19         [parentNode addChild:spiderSprite]; // 将预定好随机位置的蜘蛛加入到制定的节点对象(CCNode *)中
    20         
    21         // 自定义使用CCSchedule类手动预约更新方法
    22         [[[CCDirector sharedDirector] scheduler] scheduleUpdateForTarget:self
    23                                                                 priority:0
    24                                                                   paused:NO];
    25         // 让这个类可以接收定向的触摸事件
    26         [[[CCDirector sharedDirector] touchDispatcher] addTargetedDelegate:self
    27                                                                   priority:-1 swallowsTouches:YES];
    28     }
    29     return self;
    30 }
    31 
    32 -(void)update:(ccTime)delta
    33 {
    34     numUpdates ++;
    35     /*if(numUpdates > 50)
    36     {
    37         numUpdates = 0;
    38         [spiderSprite stopAllActions];
    39         CGPoint moveTo = CGPointMake(CCRANDOM_0_1()*200-100,CCRANDOM_0_1()*100 - 50);
    40         CCMoveBy *move = [CCMoveBy actionWithDuration:1 position:moveTo];
    41         [spiderSprite runAction:move];
    42     }*/
    43     if(numUpdates > 50)
    44     {
    45         numUpdates = 0;
    46         CGPoint moveTo = CGPointMake(CCRANDOM_0_1()*200-100,CCRANDOM_0_1()*100 - 50);
    47         [self moveAway:2 postion:moveTo];
    48     }
    49 }
    50 
    51 -(void)moveAway:(float)duration postion:(CGPoint)moveTo
    52 {
    53     [spiderSprite stopAllActions];
    54     CCMoveBy *move = [CCMoveBy actionWithDuration:duration position:moveTo];
    55     [spiderSprite runAction:move];
    56 }
    57 
    58 - (BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event
    59 {
    60     // CCLOG(@"Spride ccTouchBegan");
    61     CGPoint touchLocaion = [MultiLayerScene locationFromTouch:touch];
    62     BOOL isTouchHandled = CGRectContainsPoint([spiderSprite boundingBox], touchLocaion);
    63     if(isTouchHandled)
    64     {
    65         numUpdates = 0;
    66         CGPoint moveTo;
    67         float moveDistance = 60;
    68         float rand = CCRANDOM_0_1();
    69         if(rand < 0.25f)
    70         {
    71             moveTo = CGPointMake(moveDistance, moveDistance);
    72         }
    73         else if (rand < 0.5f)
    74         {
    75             moveTo = CGPointMake(-moveDistance, moveDistance);
    76         }
    77         else if (rand <0.75f)
    78         {
    79             moveTo = CGPointMake(moveDistance, -moveDistance);
    80         }
    81         else
    82         {
    83             moveTo = CGPointMake(-moveDistance, -moveDistance);
    84         }
    85         [self moveAway:0.1f postion:moveTo];
    86     }
    87     return isTouchHandled;
    88 }
    89 
    90 -(void)dealloc
    91 {
    92     // scheduler要求在dealloc方法中手动解除预约的更新方法
    93     [[[CCDirector sharedDirector] scheduler] unscheduleUpdateForTarget:self];
    94     
    95     // CCTouchDispatcher(触摸调度程序) 也需要在dealloc方法中被移除。
    96     [[[CCDirector sharedDirector] touchDispatcher] removeDelegate:self];
    97     [super dealloc];
    98 }
  • 相关阅读:
    three.js: Control gui and play sound set Volume
    Three.js: 显示自定义的中文字体
    P2P学习(四)P2P编程实现
    WebRTC进阶流媒体服务器开发(六)Mediasoup源码分析之Mediasoup主业务流程
    WebRTC进阶流媒体服务器开发(五)Mediasoup源码分析之Mediasoup启动过程
    WebRTC进阶流媒体服务器开发(四)Mediasoup源码分析之底层库
    WebRTC进阶流媒体服务器开发(三)Mediasoup源码分析之应用层(代码组成、Server.js、Room.js)
    WebRTC进阶流媒体服务器开发(二)Mediasoup环境配置
    WebRTC进阶流媒体服务器开发(一)多人互动架构
    WebRTC学习(十一)实时数据传输网络协议详解
  • 原文地址:https://www.cnblogs.com/sell/p/2856649.html
Copyright © 2020-2023  润新知