cocos2D中实现滑动菜单CCScrollView+CCMenu效果,(注意不是cocos2D-x)!!

本来想着用ScrollView+Menu可以很容易实现类似Angry Bird,滑动菜单选择关卡的效果。结果悲剧了,cocos2D没有CCScrollView,没办法。。。自己实现了一个。

成员变量:

1 startPos_触摸开始时候的触摸点位置,在touchBegan中初始化。

2 endPos_触摸结束时候的触摸点位置,在touchEnd中初始化。

3 menu1_,menu2_, menu3_三个菜单对象

4 beginTouchedItem_ 记录触摸开始时候触摸到的CCMenuItem对象,如果开始没触摸到任何一个Item则不处理

  1. 将本层Layer的触摸优先级设置的比CCMenu的高,并且不吞掉touch事件,使其可以传递到CCMenu层(CCMenu为-128),因为CCMenu继承自CCLayer,它默认会吞掉touch事件。
  2. - (void)registerWithTouchDispatcher {
        [[[CCDirector sharedDirector] touchDispatcher] addTargetedDelegate:self priority:-129 swallowsTouches:NO];
    }

  3. touchBegan的处理:注意触摸点要转换到Menu的坐标系中才能和CCMenuItem的方框比较位置
    - (BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event {
        CGPoint location = [self convertTouchToNodeSpace:touch];
        CGPoint locationInMenu1 = [menu1_ convertToNodeSpace:location];
        CGPoint locationInMenu2 = [menu2_ convertToNodeSpace:location];
        CGPoint locationInMenu3 = [menu3_ convertToNodeSpace:location];
        startPos_ = location;
        [menu1_ stopAllActions];
        [menu2_ stopAllActions];
        [menu3_ stopAllActions];
        
        for (CCMenuItem *item in menu1_.children) {
            if (CGRectContainsPoint([self getMenuCGRect:item], locationInMenu1)) {
                [item setIsEnabled:NO];
                BeginTouchedItem_ = item;
                return YES;
            }
        }
        for (CCMenuItem *item in menu2_.children) {
            if (CGRectContainsPoint([self getMenuCGRect:item], locationInMenu2)) {
                [item setIsEnabled:NO];
                BeginTouchedItem_ = item;
                return YES;
            }
        }
        for (CCMenuItem *item in menu3_.children) {
            if (CGRectContainsPoint([self getMenuCGRect:item], locationInMenu3)) {
                [item setIsEnabled:NO];
                BeginTouchedItem_ = item;
                return YES;
            }
        }
        return YES;
    }

  4. touchEnd的处理
    - (void)ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event {
        CGSize winSize = [[CCDirector sharedDirector] winSize];
        CGPoint centerPoint = CGPointMake(winSize.width/2, winSize.height/2);
        centerPoint = [self convertToNodeSpace:centerPoint];
        endPos_ = [self convertTouchToNodeSpace:touch];
    
        if (startPos_.x == endPos_.x && startPos_.y == endPos_.y) {
            [BeginTouchedItem_ setIsEnabled:YES];
            [BeginTouchedItem_ activate];
            return;
        }
        CGRect menu1Rect = [self getMenuCGRect:menu1_];
        CGRect menu2Rect = [self getMenuCGRect:menu2_];
        CGRect menu3Rect = [self getMenuCGRect:menu3_];
    
        if (CGRectContainsPoint(menu1Rect, centerPoint)) {
            [menu1_ runAction:[CCMoveTo actionWithDuration:0.5 position:ccp(winSize.width/2, winSize.height/2)]];
            [menu2_ runAction:[CCMoveTo actionWithDuration:0.5 position:ccp(winSize.width/2+winSize.width, winSize.height/2)]];
            [menu3_ runAction:[CCMoveTo actionWithDuration:0.5 position:ccp(winSize.width/2+winSize.width*2, winSize.height/2 )]];
        }
        else if (CGRectContainsPoint(menu2Rect, centerPoint)) {
            [menu1_ runAction:[CCMoveTo actionWithDuration:0.5 position:ccp(-winSize.width/2, winSize.height/2)]];
            [menu2_ runAction:[CCMoveTo actionWithDuration:0.5 position:ccp(winSize.width/2, winSize.height/2)]];
            [menu3_ runAction:[CCMoveTo actionWithDuration:0.5 position:ccp(winSize.width/2+winSize.width, winSize.height/2 )]];
        }
        else if (CGRectContainsPoint(menu3Rect, centerPoint)) {
            [menu1_ runAction:[CCMoveTo actionWithDuration:0.5 position:ccp(-winSize.width/2-winSize.width, winSize.height/2)]];
            [menu2_ runAction:[CCMoveTo actionWithDuration:0.5 position:ccp(-winSize.width/2, winSize.height/2)]];
            [menu3_ runAction:[CCMoveTo actionWithDuration:0.5 position:ccp(winSize.width/2, winSize.height/2 )]];
        }
        else if (centerPoint.x <= menu1_.position.x - menu1_.contentSize.width/2) {
            [menu1_ runAction:[CCMoveTo actionWithDuration:0.5 position:ccp(winSize.width/2, winSize.height/2)]];
            [menu2_ runAction:[CCMoveTo actionWithDuration:0.5 position:ccp(winSize.width/2+winSize.width, winSize.height/2)]];
            [menu3_ runAction:[CCMoveTo actionWithDuration:0.5 position:ccp(winSize.width/2+winSize.width*2, winSize.height/2 )]];
        }
        else if (centerPoint.x - menu3_.position.x >= menu3_.contentSize.width/2) {
            [menu1_ runAction:[CCMoveTo actionWithDuration:0.5 position:ccp(-winSize.width/2-winSize.width, winSize.height/2)]];
            [menu2_ runAction:[CCMoveTo actionWithDuration:0.5 position:ccp(-winSize.width/2, winSize.height/2)]];
            [menu3_ runAction:[CCMoveTo actionWithDuration:0.5 position:ccp(winSize.width/2, winSize.height/2 )]];
        }
    }

  5. touchMove的处理
    - (void)ccTouchMoved:(UITouch *)touch withEvent:(UIEvent *)event {
        CGPoint curLocation = [self convertTouchToNodeSpace:touch];
        CGPoint oldLocation = [touch previousLocationInView:touch.view];
        oldLocation = [[CCDirector sharedDirector] convertToGL:oldLocation]; 
        oldLocation = [self convertToNodeSpace:oldLocation];
        
        CGPoint translation = ccpSub(curLocation, oldLocation);
        [self panForTranslation:ccp(translation.x, 0)];
    }

  6. 用到的辅助方法:panForTranslation用来在touchMove的时候移动Menu
    - (void) panForTranslation: (CGPoint)translation {
        menu1_.position = ccpAdd(menu1_.position, translation);
        menu2_.position = ccpAdd(menu2_.position, translation);
        menu3_.position = ccpAdd(menu3_.position, translation);
        
    }
    
    - (CGRect) getMenuCGRect: (CCNode *)node {
        CGRect menuRect = CGRectMake(node.position.x - node.contentSize.width/2, node.position.y - node.contentSize.height/2, node.contentSize.width, node.contentSize.height);
        return menuRect;
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值