2014-06-25 15 views
5

Tôi đang di chuyển tất cả trò chơi của mình sang cocos2d 3.0. Tôi đã sử dụng SlidingMenuGrid.m với sửa đổi nhỏ.cocos2d 3.0 lưới menu trượt

SlidingMenuGrid.h:

// 
// SlidingMenuGrid 
// 
// Created by Brandon Reynolds on 1/9/11. 

#import "cocos2d.h" 

@interface SlidingMenuGrid : CCLayer 
{ 
    tCCMenuState state; // State of our menu grid. (Eg. waiting, tracking touch, cancelled, etc) 
    CCMenuItem *selectedItem; // Menu item that was selected/active. 

    CGPoint padding; // Padding in between menu items. 
    CGPoint menuOrigin; // Origin position of the entire menu grid. 
    CGPoint touchOrigin; // Where the touch action began. 
    CGPoint touchStop; // Where the touch action stopped. 

    int iPageCount; // Number of pages in this grid. 
    int iCurrentPage; // Current page of menu items being viewed. 

    bool bMoving; // Is the grid currently moving? 
    bool bSwipeOnlyOnMenu; // Causes swiping functionality to only work when siping on top of the menu items instead of entire screen. 
    bool bVerticalPaging; // Disabled by default. Allows for pages to be scrolled vertically instead of horizontal. 

    float fMoveDelta; // Distance from origin of touch and current frame. 
    float fMoveDeadZone; // Amount they need to slide the grid in order to move to a new page. 
    float fAnimSpeed; // 0.0-1.0 value determining how slow/fast to animate the paging. 



    CGPoint pageIndicatorPosition; 

} 


//use this 5: 
-(int) getTotalPage; 
-(int) getCurrentPage; 
-(void) moveToPage: (int) page animated: (BOOL) animated; 
+(id) packWithArray: (NSMutableArray*) items posY: (int) posY indicatorPosY: (int) indiPosY; 
+(id) levelWithArray: (NSMutableArray*) items cols: (int) cols rows: (int) rows leftEdge: (int) leftEdge upperEdge: (int) upperEdge lowerEdge: (int) lowerEdge indicatorPosY: (int) indiPosY; 




+(id) menuWithArray:(NSMutableArray*)items cols:(int)cols rows:(int)rows position:(CGPoint)pos padding:(CGPoint)pad pageIndicatorPosition:(CGPoint)pip; 

-(id) initWithArray:(NSMutableArray*)items cols:(int)cols rows:(int)rows position:(CGPoint)pos padding:(CGPoint)pad verticalPaging:(bool)vertical pageIndicatorPosition:(CGPoint)pip; 

-(void) buildGrid:(int)cols rows:(int)rows; 
-(void) buildGridVertical:(int)cols rows:(int)rows; 
-(CCMenuItem*) GetItemWithinTouch:(UITouch*)touch; 
- (CGPoint) GetPositionOfCurrentPageWithOffset:(float)offset; 
- (CGPoint) GetPositionOfCurrentPage; 

- (bool) IsSwipingOnMenuOnlyEnabled; 
- (void) SetSwipingOnMenuOnly:(bool)bValue; 

- (float) GetSwipeDeadZone; 
- (void) SetSwipeDeadZone:(float)fValue; 

- (bool) IsVerticallyPaged; 
- (void) SetVerticalPaging:(bool)bValue; 

@property (nonatomic, readwrite) CGPoint padding; 
@property (nonatomic, readwrite) CGPoint menuOrigin; 
@property (nonatomic, readwrite) CGPoint touchOrigin; 
@property (nonatomic, readwrite) CGPoint touchStop; 
@property (nonatomic, readwrite) int iPageCount; 
@property (nonatomic, readwrite) int iCurrentPage; 
@property (nonatomic, readwrite) bool bMoving; 
@property (nonatomic, readwrite) bool bSwipeOnlyOnMenu; 
@property (nonatomic, readwrite) bool bVerticalPaging; 
@property (nonatomic, readwrite) float fMoveDelta; 
@property (nonatomic, readwrite) float fMoveDeadZone; 
@property (nonatomic, readwrite) float fAnimSpeed; 

@end 

SlidingMenuGrid.m

#import "SlidingMenuGrid.h" 

#import "Constants.h" 

@implementation SlidingMenuGrid 

@synthesize padding; 
@synthesize menuOrigin; 
@synthesize touchOrigin; 
@synthesize touchStop; 
@synthesize bMoving; 
@synthesize bSwipeOnlyOnMenu; 
@synthesize fMoveDelta; 
@synthesize fMoveDeadZone; 
@synthesize iPageCount; 
@synthesize iCurrentPage; 
@synthesize bVerticalPaging; 
@synthesize fAnimSpeed; 


-(int) getTotalPage { 
    return iPageCount; 
} 
-(int) getCurrentPage { 
    return iCurrentPage; 
} 

+(id) packWithArray: (NSMutableArray*) items posY: (int) posY indicatorPosY: (int) indiPosY { 


    CGSize size = [CCDirector sharedDirector].winSize; 
    BOOL vertical = NO; 
    //pos, padding, pageindicatorpos 
    CGPoint pos = ccp(size.width/2, posY); 
    CGPoint posIndicator = ccp(size.width/2, indiPosY); 
    //padding no matter 

    return [SlidingMenuGrid menuWithArray:items cols:1 rows:1 position:pos padding:ccp(0, 0) verticalPaging:vertical pageIndicatorPosition:posIndicator]; 

} 
+(id) levelWithArray: (NSMutableArray*) items cols: (int) cols rows: (int) rows leftEdge: (int) leftEdge upperEdge: (int) upperEdge lowerEdge: (int) lowerEdge indicatorPosY: (int) indiPosY { 

    CGSize screen = [CCDirector sharedDirector].winSize; 
    BOOL vertical = NO; 

    CGSize itemSize = [[items objectAtIndex:0] boundingBox].size; 
    //pos, padding, pageindipos 
    CGPoint posIndicator = ccp(screen.width/2, indiPosY); 

    int posx = leftEdge + itemSize.width/2; 
    int posy = screen.height - (upperEdge + itemSize.height/2); 
    int padx = (screen.width - itemSize.width - 2 * leftEdge)/(cols - 1); 
    int pady = (screen.height - upperEdge - lowerEdge - itemSize.height)/(rows - 1); 

    return [SlidingMenuGrid menuWithArray:items cols:cols rows:rows position:ccp(posx, posy) padding:ccp(padx, pady) verticalPaging:vertical pageIndicatorPosition:posIndicator]; 
} 



+(id) menuWithArray:(NSMutableArray*)items cols:(int)cols rows:(int)rows position:(CGPoint)pos padding:(CGPoint)pad pageIndicatorPosition:(CGPoint)pip 
{ 
    return [[[self alloc] initWithArray:items cols:cols rows:rows position:pos padding:pad verticalPaging:false pageIndicatorPosition:pip] autorelease]; 
} 

+(id) menuWithArray:(NSMutableArray*)items cols:(int)cols rows:(int)rows position:(CGPoint)pos padding:(CGPoint)pad verticalPaging:(bool)vertical pageIndicatorPosition: (CGPoint) pip 
{ 
    return [[[self alloc] initWithArray:items cols:cols rows:rows position:pos padding:pad verticalPaging:vertical pageIndicatorPosition:pip] autorelease]; 
} 

-(id) initWithArray:(NSMutableArray*)items cols:(int)cols rows:(int)rows position:(CGPoint)pos padding:(CGPoint)pad verticalPaging:(bool)vertical pageIndicatorPosition:(CGPoint)pip 
{ 
    if ((self = [super init])) 
    { 
     self.isTouchEnabled = YES; 

     int z = 1; 
     for (id item in items) 
     { 
      [self addChild:item z:z tag:z]; 
      ++z; 
     } 

     padding = pad; 
     iCurrentPage = 0; 
     bMoving = false; 
     bSwipeOnlyOnMenu = false; 
     menuOrigin = pos; 
     fMoveDeadZone = 10; 
     bVerticalPaging = vertical; 
     fAnimSpeed = 0.6f; 
     (bVerticalPaging) ? [self buildGridVertical:cols rows:rows] : [self buildGrid:cols rows:rows]; 
     self.position = menuOrigin; 


     pageIndicatorPosition = pip; 
    } 

    return self; 
} 

-(void) dealloc 
{ 
    [super dealloc]; 
} 

-(void) buildGrid:(int)cols rows:(int)rows 
{ 
    CGSize winSize = [[CCDirector sharedDirector] winSize]; 

    int col = 0, row = 0; 
    for (CCMenuItem* item in self.children) 
    { 
     // Calculate the position of our menu item. 
     item.position = CGPointMake(self.position.x + col * padding.x + (iPageCount * winSize.width), self.position.y - row * padding.y); 

     // Increment our positions for the next item(s). 
     ++col; 
     if (col == cols) 
     { 
      col = 0; 
      ++row; 

      if(row == rows) 
      { 
       iPageCount++; 
       col = 0; 
       row = 0; 
      } 
     } 
    } 

    if([self children].count > rows * cols * iPageCount) iPageCount++; 

} 



-(void) buildGridVertical:(int)cols rows:(int)rows 
{ 
    CGSize winSize = [[CCDirector sharedDirector] winSize]; 

    int col = 0, row = 0; 
    for (CCMenuItem* item in self.children) 
    { 
     // Calculate the position of our menu item. 
     item.position = CGPointMake(self.position.x + col * padding.x , self.position.y - row * padding.y + (iPageCount * winSize.height)); 

     // Increment our positions for the next item(s). 
     ++col; 
     if (col == cols) 
     { 
      col = 0; 
      ++row; 

      if(row == rows) 
      { 
       iPageCount++; 
       col = 0; 
       row = 0; 
      } 
     } 
    } 


    if([self children].count > rows * cols * iPageCount) iPageCount++; 



} 

-(void) addChild:(CCMenuItem*)child z:(int)z tag:(int)aTag 
{ 
    return [super addChild:child z:z tag:aTag]; 
} 

-(CCMenuItem*) GetItemWithinTouch:(UITouch*)touch 
{ 
    // Get the location of touch. 
    CGPoint touchLocation = [[CCDirector sharedDirector] convertToGL: [touch locationInView: [touch view]]]; 

    // Parse our menu items and see if our touch exists within one. 
    for (CCMenuItem* item in [self children]) 
    { 
     //only deal with the item 
     if ([item isKindOfClass:[CCMenuItem class]]) { 
      CGPoint local = [item convertToNodeSpace:touchLocation]; 

      CGRect r = [item rect]; 
      r.origin = CGPointZero; 

      // If the touch was within this item. Return the item. 
      if (CGRectContainsPoint(r, local)) 
      { 
       return item; 
      } 
     } 
    } 

    // Didn't touch an item. 
    return nil; 
} 

-(void) registerWithTouchDispatcher 
{ 
    [[CCDirector sharedDirector].touchDispatcher addTargetedDelegate:self priority:kCCMenuHandlerPriority swallowsTouches:NO]; 
} 

-(BOOL) ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event 
{ 
    // Convert and store the location the touch began at. 
    touchOrigin = [[CCDirector sharedDirector] convertToGL:[touch locationInView:[touch view]]]; 

    // If we weren't in "waiting" state bail out. 
    if (state != kCCMenuStateWaiting) 
    { 
     return NO; 
    } 

    // Activate the menu item if we are touching one. 
    selectedItem = [self GetItemWithinTouch:touch]; 
    [selectedItem selected]; 

    // Only track touch if we are either in our menu system or dont care if they are outside of the menu grid. 
    if (!bSwipeOnlyOnMenu || (bSwipeOnlyOnMenu && selectedItem)) 
    { 
     state = kCCMenuStateTrackingTouch; 
     return YES; 
    } 

    return NO; 
} 

// Touch has ended. Process sliding of menu or press of menu item. 
-(void) ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event 
{ 
    // User has been sliding the menu. 
    if(bMoving) 
    { 
     bMoving = false; 

     // Do we have multiple pages? 
     if(iPageCount > 1 && (fMoveDeadZone < abs(fMoveDelta))) 
     { 
      // Are we going forward or backward? 
      bool bForward = (fMoveDelta < 0) ? true : false; 

      // Do we have a page available? 
      if(bForward && (iPageCount>iCurrentPage+1)) 
      { 
       // Increment currently active page. 
       iCurrentPage++; 
      } 
      else if(!bForward && (iCurrentPage > 0)) 
      { 
       // Decrement currently active page. 
       iCurrentPage--; 
      } 
     } 

     // Start sliding towards the current page. 
     [self moveToCurrentPage];   

    } 
    // User wasn't sliding menu and simply tapped the screen. Activate the menu item. 
    else 
    { 
     [selectedItem unselected]; 
     [selectedItem activate]; 
    } 

    // Back to waiting state. 
    state = kCCMenuStateWaiting; 
} 

-(void) moveToPage: (int) page animated:(BOOL)animated { 
    float interval = 0; 
    if (animated) { 
     interval = 0.3f * abs(iCurrentPage - page); 
    } 

    iCurrentPage = page; 

    // Perform the action 
    CGPoint position = [self GetPositionOfCurrentPage]; 
    CCMoveTo* action = [CCMoveTo actionWithDuration:interval position:position]; 
    [self runAction:action]; 

} 

// Run the action necessary to slide the menu grid to the current page. 
- (void) moveToCurrentPage 
{ 
    CGSize winSize = [[CCDirector sharedDirector] winSize]; 

    // Perform the action 
    CGPoint position = [self GetPositionOfCurrentPage]; 
    CCMoveTo* action = [CCMoveTo actionWithDuration:fAnimSpeed * 0.3f position:position]; 
    [self runAction:action]; 

} 

-(void) ccTouchCancelled:(UITouch *)touch withEvent:(UIEvent *)event 
{ 
    [selectedItem unselected]; 

    state = kCCMenuStateWaiting; 
} 

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


    // Calculate the current touch point during the move. 
    touchStop = [[CCDirector sharedDirector] convertToGL:[touch locationInView:[touch view]]]; 

    // Distance between the origin of the touch and current touch point. 
    fMoveDelta = (bVerticalPaging) ? (touchStop.y - touchOrigin.y) : (touchStop.x - touchOrigin.x); 

    // Set our position. 
    [self setPosition:[self GetPositionOfCurrentPageWithOffset:fMoveDelta]]; 
    bMoving = true; 

    if (selectedItem) { 
     [selectedItem unselected]; 
     selectedItem = nil; 
    } 

} 

- (CGPoint) GetPositionOfCurrentPage 
{ 
    CGSize winSize = [[CCDirector sharedDirector] winSize]; 

    return (bVerticalPaging) ? 
    CGPointMake(menuOrigin.x,menuOrigin.y-(iCurrentPage*winSize.height)) 
    : CGPointMake((menuOrigin.x-(iCurrentPage*winSize.width)),menuOrigin.y); 
} 

- (CGPoint) GetPositionOfCurrentPageWithOffset:(float)offset 
{ 
    CGSize winSize = [[CCDirector sharedDirector] winSize]; 

    return (bVerticalPaging) ? 
    CGPointMake(menuOrigin.x,menuOrigin.y-(iCurrentPage*winSize.height)+offset) 
    : CGPointMake((menuOrigin.x-(iCurrentPage*winSize.width)+offset),menuOrigin.y); 
} 



// Returns whether or not we should only allow swiping on the actual grid. 
- (bool) IsSwipingOnMenuOnlyEnabled 
{ 
    return bSwipeOnlyOnMenu; 
} 

// Sets the ability to swipe only on the menu or utilize entire screen for swiping. 
- (void) SetSwipingOnMenuOnly:(bool)bValue 
{ 
    bSwipeOnlyOnMenu = bValue; 
} 

// Returns the swiping dead zone. 
- (float) GetSwipeDeadZone 
{ 
    return fMoveDeadZone; 
} 

- (void) SetSwipeDeadZone:(float)fValue 
{ 
    fMoveDeadZone = fValue; 
} 

// Returns wheather or not vertical paging is enabled. 
- (bool) IsVerticallyPaged 
{ 
    return bVerticalPaging; 
} 

// Sets the vertical paging flag. 
- (void) SetVerticalPaging:(bool)bValue 
{ 
    bVerticalPaging = bValue; 
    [self buildGridVertical]; 
} 










- (void) visit 
{ 
    [super visit];//< Will draw after glPopScene. 

    BOOL showPagesIndicator = YES; 


    ccColor4B pagesIndicatorNormalColor_ = ccc4(180, 180, 180, 255); 
    ccColor4B pagesIndicatorSelectedColor_ = ccc4(255, 255, 255, 255); 
    if (showPagesIndicator) 
    { 
     int totalScreens = iPageCount; 

     // Prepare Points Array 
     CGFloat n = (CGFloat)totalScreens; //< Total points count in CGFloat. 
     CGFloat pY = pageIndicatorPosition.y; //< Points y-coord in parent coord sys. 
     CGFloat d = ph_pad(16.0f, 16.0f * 2); //< Distance between points. 
     CGPoint points[totalScreens]; 
     for (int i=0; i < totalScreens; ++i) 
     { 
      CGFloat pX = pageIndicatorPosition.x + d * ((CGFloat)i - 0.5f*(n-1.0f)); 
      points[i] = ccp (pX, pY); 
     } 

     // Set GL Values 
#if COCOS2D_VERSION >= 0x00020000 
//  ccGLEnable(CC_GL_BLEND); 
     ccPointSize(ph_pad(5.0 * CC_CONTENT_SCALE_FACTOR(), 5.0 * CC_CONTENT_SCALE_FACTOR() * 2)); 
#define DRAW_4B_FUNC ccDrawColor4B 

#else 
     glEnable(GL_POINT_SMOOTH); 
     GLboolean blendWasEnabled = glIsEnabled(GL_BLEND); 
     glEnable(GL_BLEND); 

     // save the old blending functions 
     int blend_src = 0; 
     int blend_dst = 0; 
     glGetIntegerv(GL_BLEND_SRC, &blend_src); 
     glGetIntegerv(GL_BLEND_DST, &blend_dst); 
     glPointSize(ph_pad(5.0 * CC_CONTENT_SCALE_FACTOR(), 5.0 * CC_CONTENT_SCALE_FACTOR() * 2)); 

#define DRAW_4B_FUNC glColor4ub 

#endif 
     ccGLBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 
//  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 

     // Draw Gray Points 
     DRAW_4B_FUNC(pagesIndicatorNormalColor_.r, 
        pagesIndicatorNormalColor_.g, 
        pagesIndicatorNormalColor_.b, 
        pagesIndicatorNormalColor_.a); 

     ccDrawPoints(points, totalScreens); 

     // Draw White Point for Selected Page 
     DRAW_4B_FUNC(pagesIndicatorSelectedColor_.r, 
        pagesIndicatorSelectedColor_.g, 
        pagesIndicatorSelectedColor_.b, 
        pagesIndicatorSelectedColor_.a); 
     ccDrawPoint(points[iCurrentPage]); 

     // Restore GL Values 
#if COCOS2D_VERSION >= 0x00020000 
     ccPointSize(1.0f); 
#else 
     glPointSize(1.0f); 
     glDisable(GL_POINT_SMOOTH); 
     if (! blendWasEnabled) 
      glDisable(GL_BLEND); 

     // always restore the blending functions too 
     ccGLBlendFunc(blend_src, blend_dst); 
//  glBlendFunc(blend_src, blend_dst); 
#endif 
    } 
} 




@end 

Mã nguồn là từ Brandon Reynolds và tôi đã sửa đổi nó một chút để phù hợp hơn với lối chơi của mình. Tôi sử dụng này 5 phương pháp để dễ dàng xây dựng các menu cho gói (hàng duy nhất, cột đa) và cấp (multi hàng, cột đa)

-(int) getTotalPage; 
-(int) getCurrentPage; 
-(void) moveToPage: (int) page animated: (BOOL) animated; 
+(id) packWithArray: (NSMutableArray*) items posY: (int) posY indicatorPosY: (int) indiPosY; 
+(id) levelWithArray: (NSMutableArray*) items cols: (int) cols rows: (int) rows leftEdge: (int) leftEdge upperEdge: (int) upperEdge lowerEdge: (int) lowerEdge indicatorPosY: (int) indiPosY; 

Nhưng mã gl mở không hoạt động nữa cho cocos2d 3,0 (ví dụ ccGLBlendFunc vv). Làm thế nào tôi có thể cập nhật lớp này cho cocos2d 3.x? Hoặc bất kỳ triển khai mới nào cho lưới menu tương tự?

Trả lời

0

Bây giờ tốt hơn là sử dụng CCScrollView.

Nó hỗ trợ phân trang và bạn có thể dễ dàng tạo lưới cấp bằng cách chỉ tạo trước nó dưới dạng nút nội dung.

Các vấn đề liên quan