2012-04-26 21 views
5

編輯:有了足夠的重寫和評論,我已經運行,將在其他人的最後發佈。編輯2:我已經更新了我自己的版本,並且我已經瞭解到原始編碼器對於C++並不是很好,您可能想在使用它之前仔細閱讀所有內容,查看下面的註釋postCCScrollView for cocos2d-x的工作原理?

目前可用的CCScrollView for cocos2d-x存在一個主要缺陷:它搞砸了。

具體來說,cpp函數頭文件與.h文件不匹配。 cpp文件引用UIEvent和NSMutableArray,而不是X平臺。

滾動視圖本身必須添加一個數組,這限制了您使用for循環創建菜單項(如果創建菜單項)的能力,因爲您不能使用可變項,並且它們不會像iOS這樣的子類相互獨立,所以你不能只使用一個mutable然後說CCArray * array = mutable-> getMutableArray()或類似的東西。

此外,定義已過時(儘管通過在cocos2d-x站點上通過轉換規則添加CCX_SAFE_DELETE可解決),以及各種隨機模板嘗試創建甚至不在項目中的NS和UI對象我不知道爲什麼。

基本的想法是,除了使用可變數組之外,這個類還是太亂了,以致於無法轉化爲C++。我不相信作者編譯他的版本,因爲標題不匹配。我以爲我下載了兩個(每個都有兩個)cpp和.h文件,並且都有UIEvent而不是CC以及其他問題。

注意:我已經修復了上面的各種錯誤,並且在不同的地方將SelectorProtocol更改爲CCObject,但這只是讓人難以接受。

也許我應該使用Parallax節點呢?

這太荒謬了,對Cocos2d來說可能很好,但它不適用於c2d-X。無論如何,我會記錄和搜索,謝謝你的任何建議!

編輯:這裏是我現在使用的類。沒有做過編輯,但這些都會讓任何人開始和編譯的不僅僅是iPhone

頁眉:

#ifndef __CCSCROLLLAYER__ 
#define __CCSCROLLLAYER__ 
// CCScrollLayer.h 
// 
// Copyright 2010 DK101 
// http://dk101.net/2010/11/30/implementing-page-scrolling-in-cocos2d/ 
// 
// Copyright 2010 Giv Parvaneh. 
// http://www.givp.org/blog/2010/12/30/scrolling-menus-in-cocos2d/ 
// 
// Copyright 2011 Stepan Generalov 
// 
// Copyright 2011 Eli Yukelzon 
// 
// Permission is hereby granted, free of charge, to any person obtaining a copy 
// of this software and associated documentation files (the "Software"), to deal 
// in the Software without restriction, including without limitation the rights 
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 
// copies of the Software, and to permit persons to whom the Software is 
// furnished to do so, subject to the following conditions: 
// 
// The above copyright notice and this permission notice shall be included in 
// all copies or substantial portions of the Software. 
// 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 
// THE SOFTWARE. 

// Original source: https://github.com/cocos2d/cocos2d-iphone-extensions/tree/master/Extensions/CCScrollLayer 
// Last updated: October 1, 2011 

#include "cocos2d.h" 

namespace cocos2d { 


    class CCScrollLayer; 


    class CCScrollLayerDelegate 
    { 
    public: 
     /** Called when scroll layer begins scrolling. 
     * Usefull to cancel CCTouchDispatcher standardDelegates. 
     */ 
     virtual void scrollLayerScrollingStarted(CCScrollLayer* sender) {} 

     /** Called at the end of moveToPage: 
     * Doesn't get called in selectPage: 
     */ 
     virtual void scrollLayerScrolledToPageNumber(CCScrollLayer* sender, unsigned int page) {} 
    }; 

    /* 
    It is a very clean and elegant subclass of CCLayer that lets you pass-in an array 
    of layers and it will then create a smooth scroller. 
    Complete with the "snapping" effect. You can create screens with anything that can be added to a CCLayer. 

    */ 
    class CCScrollLayer : public CCLayer 
    { 

     int currentScreen; //added 
     int totalScreens; 
     float scrollWidth; 
     float scrollHeight; 
     float startWidth; 
     float startHeight; 
     int startSwipe; 

    public: 
     //CCScrollLayer(); 
     ~CCScrollLayer(); 

     static CCScrollLayer* nodeWithLayers(CCArray* layers, int widthOffset); 

     bool initWithLayers(CCArray* layers, int widthOffset); 

     /** Updates all pages positions & adds them as children if needed. 
     * Can be used to update position of pages after screen reshape, or 
     * for update after dynamic page add/remove. 
     */ 
     void updatePages(); 

     /** Adds new page and reorders pages trying to set given number for newly added page. 
     * If number > pages count - adds new page to the right end of the scroll layer. 
     * If number <= 0 - adds new page to the left end of the scroll layer. 
     * @attention Designated addPage method. 
     */ 
     void addPage(CCLayer* aPage, unsigned int pageNumber); 

     /** Adds new page to the right end of the scroll layer. */ 
     void addPage(CCLayer* aPage); 

     /** Removes page if it's one of scroll layers pages (not children) 
     * Does nothing if page not found. 
     */ 
     void removePage(CCLayer* aPage); 

     /** Removes page with given number. Doesn nothing if there's no page for such number. */ 
     void removePageWithNumber(unsigned int pageNumber); 

     /* Moves scrollLayer to page with given number & invokes delegate 
     * method scrollLayer:scrolledToPageNumber: at the end of CCMoveTo action. 
     * Does nothing if number >= totalScreens or < 0. 
     */ 
     void moveToPage(unsigned int pageNumber); 

     /* Immedeatly moves scrollLayer to page with given number without running CCMoveTo. 
     * Does nothing if number >= totalScreens or < 0. 
     */ 
     void selectPage(unsigned int pageNumber); 

     CC_SYNTHESIZE(CCScrollLayerDelegate*, m_pDelegate, Delegate); 

     /** Calibration property. Minimum moving touch length that is enough 
     * to cancel menu items and start scrolling a layer. 
     */ 
     CC_SYNTHESIZE(CGFloat, m_fMinimumTouchLengthToSlide, MinimumTouchLengthToSlide); 

     /** Calibration property. Minimum moving touch length that is enough to change 
     * the page, without snapping back to the previous selected page. 
     */ 
     CC_SYNTHESIZE(CGFloat, m_fMinimumTouchLengthToChangePage, MinimumTouchLengthToChangePage); 

     /** If YES - when starting scrolling CCScrollLayer will claim touches, that are 
     * already claimed by others targetedTouchDelegates by calling CCTouchDispatcher#touchesCancelled 
     * Usefull to have ability to scroll with touch above menus in pages. 
     * If NO - scrolling will start, but no touches will be cancelled. 
     * Default is YES. 
     */ 
     CC_SYNTHESIZE(bool, m_bStealTouches, StealTouches); 

     /** Whenever show or not white/grey dots under the scroll layer. 
     * If yes - dots will be rendered in parents transform (rendered after scroller visit). 
     */ 
     CC_SYNTHESIZE(bool, m_bShowPagesIndicator, ShowPagesIndicator); 

     /** Position of dots center in parent coordinates. 
     * (Default value is screenWidth/2, screenHeight/4) 
     */ 
     CC_SYNTHESIZE_PASS_BY_REF(CCPoint, m_tPagesIndicatorPosition, PagesIndicatorPosition); 

     /** Total pages available in scrollLayer. */ 
     unsigned int getTotalScreens() const; 

     /** Current page number, that is shown. Belongs to the [0, totalScreen] interval. */ 
     CC_SYNTHESIZE_READONLY(unsigned int, m_uCurrentScreen, CurrentScreen); 

     /** Offset, that can be used to let user see next/previous page. */ 
     CC_SYNTHESIZE(CGFloat, m_fPagesWidthOffset, PagesWidthOffset); 

     /** Offset that can be used to let user see empty space over first or last page. */ 
     CC_SYNTHESIZE(CGFloat, m_fMarginOffset, MarginOffset); 

     /** Array of pages CCLayer's */ 
     CC_SYNTHESIZE_READONLY(CCArray*, m_pLayers, Pages); 
    protected: 
     // The x coord of initial point the user starts their swipe. 
     CGFloat m_fStartSwipe; 

     // Internal state of scrollLayer (scrolling or idle). 
     int m_iState; 
     bool m_bStealingTouchInProgress; 
     // Holds the touch that started the scroll 
     CCTouch* m_pScrollTouch; 

     //void visit(); 
     //void moveToPageEnded(); 
     unsigned int pageNumberForPosition(const CCPoint& position); 
     CCPoint positionForPageWithNumber(unsigned int pageNumber); 
     void claimTouch(CCTouch* pTouch); 
     void cancelAndStoleTouch(CCTouch* pTouch, CCEvent* pEvent); 

     //void registerWithTouchDispatcher(); 
     bool ccTouchBegan(CCTouch* pTouch, CCEvent* pEvent); 
     void ccTouchMoved(CCTouch* pTouch, CCEvent* pEvent); 
     void ccTouchEnded(CCTouch* pTouch, CCEvent* pEvent); 
     //void ccTouchCancelled(CCTouch* pTouch, CCEvent* pEvent); 
     }; 
} //end namespace 

#endif 

CPP

// CCScrollLayer.cpp 
// Museum 
// 
// Created by GParvaneh on 29/12/2010. 
// Copyright 2010. All rights reserved. 
// Ported to C++ by Lior Tamam on 03/04/2011 
#include "CCScrollLayer.h" 

using namespace cocos2d; 

CCScrollLayer* CCScrollLayer::nodeWithLayers(CCArray* layers, int widthOffset) 
{ 
    CCScrollLayer *pRet = new CCScrollLayer(); 
    if (pRet && pRet->initWithLayers(layers, widthOffset)) 
    { 
     pRet->autorelease(); 
     return pRet; 
    } 
    CCX_SAFE_DELETE(pRet); 
    return NULL; 
} 

bool CCScrollLayer::initWithLayers(CCArray* layers, int widthOffset) 
{ 
    if (CCLayer::init()) 
    {  
     // Make sure the layer accepts touches 
     CCTouchDispatcher::sharedDispatcher()->addTargetedDelegate(this,0,true); 

     // Set up the starting variables 
     //if(!widthOffset) 
     { 
     // widthOffset = 0; 
     } 
     currentScreen = 1; 

     // offset added to show preview of next/previous screens 
     scrollWidth = (int)CCDirector::sharedDirector()->getWinSize().width - widthOffset; 
     scrollHeight = (int)CCDirector::sharedDirector()->getWinSize().height; 
     startWidth = scrollWidth; 
     startHeight = scrollHeight; 

     // Loop through the array and add the screens 
     unsigned int i; 
     for (i=0; i<layers->count(); i++) 
     { 
      CCLayer* l = (CCLayer*)layers->objectAtIndex(i); 
      //l->setAnchorPoint(ccp(0,0)); 
      //l->setPosition(ccp((i*scrollWidth),0)); 
      addChild(l);    
     } 

     // Setup a count of the available screens 
     totalScreens = layers->count(); 
     return true;  
    } 
    else 
    { 
     return false; 
    } 
} 

void CCScrollLayer::setMaximumScrollHeight(float maxHeight) 
{ 
    //Make the offset match expected pixels (include the current screen if at ccp(0,0) 
    maxHeight -= CCDirector::sharedDirector()->getWinSize().height; 
    maximumScrollHeight = maxHeight; 
} 

CCScrollLayer::~CCScrollLayer() 
{ 
    CCTouchDispatcher::sharedDispatcher()->removeDelegate(this); 
    CCLayer::onExit(); 
} 

bool CCScrollLayer::ccTouchBegan(CCTouch *touch, CCEvent *withEvent) 
{ 
// 
// CCPoint touchPoint = touch->locationInView(); 
// touchPoint = CCDirector::sharedDirector()->convertToGL(touchPoint); 
// 
// startSwipe = (int)touchPoint.y; 
    return true; 
} 

void CCScrollLayer::ccTouchMoved(CCTouch *touch, CCEvent *withEvent) 
{ 
    CCPoint touchPoint = touch->locationInView(); 
    CCPoint prevPoint = touch->previousLocationInView(); 

    touchPoint = CCDirector::sharedDirector()->convertToGL(touchPoint); 
    prevPoint = CCDirector::sharedDirector()->convertToGL(prevPoint); 

    CCPoint difference = ccp(touchPoint.x - prevPoint.x , touchPoint.y - prevPoint.y); 
    CCPoint currentPos = this->getPosition(); 

    currentPos = ccp(currentPos.x, currentPos.y+difference.y); 

    if (currentPos.y > maximumScrollHeight) 
    { 
     currentPos.y = maximumScrollHeight; 
     //this->setPositionY(maximumScrollHeight); 
    } 
    else if (currentPos.y < 0) 
    { 
     currentPos.y = 0; 
     // this->setPositionY(0); 
    } 
    this->setPosition(currentPos); 
} 

/* 
void CCScrollLayer::ccTouchEnded(CCTouch *touch, CCEvent *withEvent) 
{ 

    //CCPoint touchPoint = touch->locationInView(); 
    //touchPoint = CCDirector::sharedDirector()->convertToGL(touchPoint); 

    int newX = (int)touchPoint.x; 

    if ((newX - startSwipe) < -scrollWidth/3 && (currentScreen+1) <= totalScreens) 
    { 
    // this->moveToNextPage(); 
    } 
    else if ((newX - startSwipe) > scrollWidth/3 && (currentScreen-1) > 0) 
    { 
    // this->moveToPreviousPage(); 
    } 
    else 
    { 
    // this->moveToPage(currentScreen);   
    } 

} 
*/ 
+0

我不能回答我自己的問題,當有可能的時候會回答我的問題。 – 2012-04-26 21:43:40

+0

記住將CCX_SAFE_DELETE()的定義從這裏http://www.cocos2d-x.org/projects/cocos2d-x/wiki/Rules_of_translating_objc_to_cpp移動到您的ccMacros。h區域 – 2012-04-26 21:45:02

+0

在cpp文件中,在initWithLayers()下,您需要擦除或註釋// l-> setAnchorPoint(ccp(0,0));和// l-> setPosition(ccp((i * scrollWidth),0));找到工作的位置。另外,刪除if!widthOffset,它將自己重置爲0或者它是什麼,該檢查沒有價值。在這之後可能會遇到從Obj移植的問題,它會開始看起來不錯。另外,如果你只是想要一個滾動視圖,刪除分頁內容 – 2012-04-26 22:46:03

回答

4

檢查出的Cocos2D-X的站點的論壇最新的一個。基於此,作者正在對其進行重新設計。 http://www.cocos2d-x.org/boards/18/topics/1090?r=10835#message-10835

+0

最後一件事:2d-x滾動視圖實際上需要一個頁面數組(頂層節點)。請記住,如果你重寫這個或使用網站上的任何一個(除了我的版本)。雖然我的版本可以按原樣工作,但它不適合複雜度 – 2012-05-21 16:40:04

9

回想起一個古老的線程來增加新的信息,任何人誰發現這個通過搜索引擎:CCScrollView現在是GUI擴展的一部分,似乎工作得相當好。應該不再需要上面提到的實現。

+0

啊,真好。謝謝! – 2013-07-29 16:13:25

+0

@StephenJ你能將它標記爲已接受的答案嗎?這解決了你提到的問題。此外,它鏈接到2d-x原生的東西。 – Waseem 2014-03-19 10:56:09

+0

即使您目前正確,但存在多個問題。第一,我之所以被低估,僅僅是因爲「新的答案」現在是正確的。第二,我可能或不會成爲任何時候的成員,無論是死亡,受傷還是繼續前進。任何人都可以,所以我相信主持人應該爲這種事情發生時找到更合適的解決方案。我會在這裏說,這是目前正確的答案! – 2014-03-19 15:20:13