Fork me on GitHub

CCScrollLayer (cocos2d中实现的滚动层)

http://labs.ywlx.net/?p=2035

以往在cocos2d中实现此效果都是结合UIScrollView和UIButton来实现, cocos2d与UIView结合需要经过多个步骤,过程繁琐。还有一个缺点就是当选中一个UIButton之后再拖拽,是拖不动的。

所以在此我们使用 自定义CCLayer和CCSprite来实现,脱离和UIView的结合。

*实现思路:

初始化多个CCLayer,把需要的数据添加到每个CCLayer里。把这些CCLayer添加到自己自定义的一个CCLayer里,然后在这个自定义的CCLayer里通过重写方法(void)ccTouchMoved:(UITouch *)touch withEvent:(UIEvent *)event来改变自定义CCLayer的position从而实现滚动效果。

*主要代码:MainScene

//初始化一系列CCLayer后 添加到自定义的CCLayer,并设定翻页之后 改变下方小点状态函数的delegate

- (void)initScrollLayer

{

NSMutableArray *arrLevel=[NSMutableArray arrayWithCapacity:0];

for(int i=0;i<iPageCount;i++){

CCLayer *tempLayer=[CCLayer node];

tempLayer.tag=TAG_LEVEL_LAYER_START+i;

for(int j=0;j<LEVEL_COL*LEVEL_ROW;j++){

if(i*LEVEL_COL*LEVEL_ROW+j<iLevelCount){

//在此添加内容

}

}

[arrLevel addObject:tempLayer];

}

CCScrollLayer *scroller = [[CCScrollLayer alloc] initWithLayers:arrLevel

widthOffset: 0];

// finally add the scroller to your scene

[self addChild:scroller];

// page moved delegate

{

NSMethodSignature* signature =

[[self class] instanceMethodSignatureForSelector:@selector(onPageMoved:)];

NSInvocation* invocation = [NSInvocation invocationWithMethodSignature:signature];

[invocation setTarget:self];

[invocation setSelector:@selector(onPageMoved:)];

scroller.onPageMoved = invocation;

}

}

//初始化下放的小点

- (void)initPageIndex:(int)defaultPage

maxPage:(int)maxPage

{

CGPoint indexPos = ccp(200, 20);

CGPoint offsetPos = ccp(30, 0);

for (int i = 0; i < maxPage; ++i)

{

CCSprite *sprite=[CCSprite spriteWithFile:@"dot1.png"];

sprite.position= ccpAdd(indexPos, ccpMult(offsetPos, i));

CCLabelTTF *lab = [CCLabelTTF labelWithString:[NSString stringWithFormat:@"%i",i+1]

fontName:@”Arial”

fontSize:12];

lab.tag=1;

[sprite addChild:lab];

[self addChild:sprite];

[pageIndexArray addObject:sprite];

}

[self setPageIndex:defaultPage];

}

//翻页之后修改下方小点的状态

- (void)setPageIndex:(int)pageIndex

{

if ([pageIndexArray objectAtIndex:pageIndex] == nil)

{

return;

}

for(CCSprite *sprite in pageIndexArray){

CCLabelTTF *lab=(CCLabelTTF *)[sprite getChildByTag:1];

lab.string=@”";

CCTexture2D  *texture = [[CCTextureCache sharedTextureCache] addImage:@”dot1.png”];

[sprite setTextureRect:CGRectMake(0, 0, texture.contentSize.width, texture.contentSize.height)];

id frame = [CCSpriteFrame frameWithTexture:texture rect:CGRectMake(0, 0, texture.contentSize.width, texture.contentSize.height)];

[sprite setDisplayFrame:frame];

}

CCSprite *sprite=(CCSprite *)[pageIndexArray objectAtIndex:pageIndex];

CCTexture2D  *texture = [[CCTextureCache sharedTextureCache] addImage:@”dot2.png”];

[sprite setTextureRect:CGRectMake(0, 0, texture.contentSize.width, texture.contentSize.height)];

id frame = [CCSpriteFrame frameWithTexture:texture rect:CGRectMake(0, 0, texture.contentSize.width, texture.contentSize.height)];

[sprite setDisplayFrame:frame];

CCLabelTTF *lab=(CCLabelTTF *)[sprite getChildByTag:1];

lab.string=[NSString stringWithFormat:@"%i",pageIndex+1];

lab.position =ccp(sprite.textureRect.size.width/2,sprite.textureRect.size.height/2);

}

*主要代码 :CCScrollLayer

//初始化

-(id) initWithLayers:(NSMutableArray *)layers widthOffset: (int) widthOffset

{

if ( (self = [super init]) )

{

[[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self priority:0 swallowsTouches:YES];

if(!widthOffset){

widthOffset = 0;

}

currentScreen = 1;

scrollWidth = [[CCDirector sharedDirector] winSize].width – widthOffset;

scrollHeight = [[CCDirector sharedDirector] winSize].height;

startWidth = scrollWidth;

startHeight = scrollHeight;

int i = 0;

for (CCLayer *l in layers)

{

l.anchorPoint = ccp(0,0);

l.position = ccp((i*scrollWidth),0);

[self addChild:l];

i=i+1;

}

totalScreens = i;

}

return self;

}

//delegate

- (void)onPageMoved:(id)sender

{

if (self.onPageMoved != nil)

{

[self.onPageMoved setArgument:&self atIndex:2];

[self.onPageMoved invoke];

}

}

//翻到page页

-(void) moveToPage:(int)page

{

id changePage = [CCEaseBounce actionWithAction:[CCMoveTo actionWithDuration:0.3 position:ccp(-((page-1)*scrollWidth),0)]];

id actions = [CCSequence actions:

changePage,

[CCCallFunc actionWithTarget:self selector:@selector(onPageMoved:)],

nil];

[self runAction:actions];

currentScreen = page;

}

//下一页

-(void) moveToNextPage

{

id changePage = [CCEaseBounce actionWithAction:[CCMoveTo actionWithDuration:0.3 position:ccp(-(((currentScreen+1)-1)*scrollWidth),0)]];

id actions = [CCSequence actions:changePage,

[CCCallFunc actionWithTarget:self selector:@selector(onPageMoved:)],nil];

[self runAction:actions];

currentScreen = currentScreen+1;

}

//上一页

-(void) moveToPreviousPage

{

id changePage = [CCEaseBounce actionWithAction:[CCMoveTo actionWithDuration:0.3 position:ccp(-(((currentScreen-1)-1)*scrollWidth),0)]];

id actions = [CCSequence actions:changePage,

[CCCallFunc actionWithTarget:self selector:@selector(onPageMoved:)],

nil];

[self runAction:actions];

currentScreen = currentScreen-1;

}

//触摸开始

-(BOOL) ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event

{

CGPoint touchPoint = [touch locationInView:[touch view]];

startSwipe = touchPoint.x;

for(int i=0;i<LEVEL_COL*LEVEL_ROW;i++){

NSInteger x=i%LEVEL_COL;

NSInteger y=i/LEVEL_COL;

CGRect iRect=CGRectMake(LEVEL_POS_X+x*(LEVEL_ROW_WIDTH+LEVEL_COL_MARGIN),

LEVEL_POS_Y+y*(LEVEL_ROW_HIGHT+LEVEL_ROW_MARGIN),

LEVEL_ROW_WIDTH,

LEVEL_ROW_HIGHT);

//在次实现点击的后的效果

if(CGRectContainsPoint(iRect, touchPoint)){

iLevel=i;

NSInteger iTag=(currentScreen-1)*LEVEL_COL*LEVEL_ROW+iLevel;

CCLayer *layer=(CCLayer *)[self getChildByTag:TAG_LEVEL_LAYER_START+currentScreen-1];

CCSprite *downSprite=(CCSprite *)[layer getChildByTag:iTag];

downSprite.anchorPoint=ccp(0.5, 0.5);

CGPoint posi=ccp(LEVEL_POS_X+x*(LEVEL_ROW_WIDTH+LEVEL_COL_MARGIN)+LEVEL_ROW_WIDTH/2,

LEVEL_POS_Y+y*(LEVEL_ROW_HIGHT+LEVEL_ROW_MARGIN)+LEVEL_ROW_HIGHT/2);

posi= [[CCDirector sharedDirector] convertToGL:posi];

downSprite.position=posi;

CCScaleTo *scaleAction=[CCScaleTo actionWithDuration:0.2 scale:1.2f];

[downSprite runAction:scaleAction];

return YES;

}

}

return YES;

}

//通过修改本Layer的position来实现滚动

- (void)ccTouchMoved:(UITouch *)touch withEvent:(UIEvent *)event

{

CGPoint touchPoint = [touch locationInView:[touch view]];

self.position = ccp((-(currentScreen-1)*scrollWidth)+(touchPoint.x-startSwipe),0);

}

//触摸结束

- (void)ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event

{

CGPoint touchPoint = [touch locationInView:[touch view]];

//取消点击产生的效果

if(iLevel>=0){

NSInteger iTag=(currentScreen-1)*LEVEL_COL*LEVEL_ROW+iLevel;

CCLayer *layer=(CCLayer *)[self getChildByTag:TAG_LEVEL_LAYER_START+currentScreen-1];

CCSprite *downSprite=(CCSprite *)[layer getChildByTag:iTag];

[downSprite stopAllActions];

downSprite.scale=1.0;

NSInteger x=iLevel%LEVEL_COL;

NSInteger y=iLevel/LEVEL_COL;

CGRect iRect=CGRectMake(LEVEL_POS_X+x*(LEVEL_ROW_WIDTH+LEVEL_COL_MARGIN),

LEVEL_POS_Y+y*(LEVEL_ROW_HIGHT+LEVEL_ROW_MARGIN),

LEVEL_ROW_WIDTH,

LEVEL_ROW_HIGHT);

//如果触摸结束时touchPoint所在的rect和触摸开始时touchPoint所在的rect相等,那么就认为点击了此rect对应的sprite

if(CGRectContainsPoint(iRect, touchPoint)){

iapp.iCurLvl=(currentScreen-1)*LEVEL_COL*LEVEL_ROW+iLevel+1+(iapp.iCurScene-1)*SCENE_LEVEL_COUNT;

[[CCDirector sharedDirector] replaceScene:[GameScene scene]];

return;

}

iLevel=-1;

}

int newX = touchPoint.x;

if ( (newX – startSwipe) < -100 && (currentScreen+1) <= totalScreens )

{

[self moveToNextPage];

}

else if ( (newX – startSwipe) > 100 && (currentScreen-1) > 0 )

{

[self moveToPreviousPage];

}

else{

[self moveToPage:currentScreen];

}

}

posted on 2012-06-04 09:55  pengyingh  阅读(2259)  评论(0)    收藏  举报

导航