2012-04-26 18 views
5

Edytowanie: przy przepisywaniu wystarczającej ilości tekstu i komentowaniu, uruchomię go, zostanie opublikowany poniżej dla innych.CCScrollView dla cocos2d-x, który działa?

Edit2: ja już więcej aktualizacji własną wersję, a ja nauczyłem oryginalny koder nie było bardzo dobre z C++, może chcesz przejść nad wszystkim tam przed jej użyciem, sprawdź poniżej komentarze post

Aktualnie dostępny CCScrollView dla cocos2d-x ma jedną poważną wadę: jest pomieszany.

W szczególności nagłówki funkcji cpp nie pasują do plików .h. Plik cpp odnosi się do UIEvent i NSMutableArray, a nie X-Platform.

Sam widok przewijania musi mieć dodaną tablicę, co ogranicza możliwość korzystania z pętli for w celu tworzenia pozycji menu (jeśli tworzysz elementy menu), ponieważ nie można użyć zmiennej, a nie podklasy nawzajem jak iOS, więc nie można po prostu użyć mutable, a następnie powiedzieć CCArray * array = mutable-> getMutableArray() lub podobne.

Ponadto, definicje są nieaktualne (choć można je naprawić poprzez dodanie CCX_SAFE_DELETE za pośrednictwem reguł translacji na stronie cocos2d-x) oraz wiele losowych szablonów próbujących utworzyć obiekty NS i UI, które nie są nawet objęte projektem Nie mam pojęcia dlaczego.

Podstawową ideą jest to, że oprócz dodawania tablic zmiennoprzecinkowych, ta klasa jest zbyt zawiediona, aby zawracać sobie głowę tłumaczeniem na język C++. Nie wierzę, że autor skompilował wersję, którą ma, ponieważ nagłówki nie pasują do siebie. Myślałem, że pobrałem obie (jest ich po 2) pliki cpp i .h, i oba mają UIEvent zamiast CC wraz z innymi problemami.

Uwaga: Naprawiłem różne powyższe opcje i zmieniłem SelectorProtocol na CCObject w różnych miejscach, ale to po prostu przytłaczające.

Może powinienem zamiast tego użyć węzła Parallax?

To jest po prostu śmieszne, być może jest dobre dla Cocos2d, ale nie działa na c2d-X. W każdym razie, będę przekodowywania i wyszukiwania, dzięki za wszelkie sugestie!

Edytuj: Oto klasy, z których teraz korzystam. Nie zakończeniu edycji, ale to dostanie ktoś zaczął i kompilowania na więcej niż tylko iPhone

Nagłówek:

#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

Nie mogę jeszcze odpowiedzieć na własne pytanie, przeniesię odpowiedź, gdy będzie to możliwe. –

+0

PAMIĘTAJ, ABY PRZESUWAĆ definicję dla CCX_SAFE_DELETE() OD TUTAJ http://www.cocos2d-x.org/projects/cocos2d-x/wiki/Rules_of_translating_objc_to_cpp na twoje ccMacros.h obszar –

+0

W pliku cpp, w initWithLayers(), będziesz chciał usunąć lub skomentować // l-> setAnchorPoint (ccp (0,0)); i // l-> setPosition (ccp ((i * scrollWidth), 0)); aby pozycjonowanie działało. Usuń także jeśli! WidthOffset, albo resetuje się do 0, albo jest to, co jest, że czek nie ma wartości. Prawdopodobnie problem z portowaniem z Obj> po tym, zacznie wyglądać dobrze. Usuwam też elementy stronicowania, jeśli chcesz tylko przewijanego widoku. –

Odpowiedz

4

Zapoznaj się z forum na stronie Cocos2d-X za okres ostatnie. Są one teraz ponownie opracowywane przez autora na podstawie tego. http://www.cocos2d-x.org/boards/18/topics/1090?r=10835#message-10835

+0

Ostatnia rzecz: widok przewijania 2d-x faktycznie oczekuje tablicy stron (węzłów najwyższego poziomu). Miej to na uwadze, jeśli przerobisz to lub użyjesz tego, co znajduje się na stronie (innej niż moja wersja). Chociaż moja wersja działa tak, jak jest, nie nadaje się do złożoności. –

9

Ożywienie stary wątek, aby dodać nowe informacje, dla każdego, kto znalazł to za pośrednictwem wyszukiwarki: CCScrollView jest obecnie częścią rozszerzenia GUI i wydaje się dość dobrze. Nie powinno być więcej potrzeby implementacji wymienionych powyżej.

+0

Ah, miło. Dzięki! –

+0

@StephenJ Czy możesz oznaczyć to jako zaakceptowaną odpowiedź? To rozwiązuje problem, o którym wspomniałeś. Ponadto łączy się z czymś natywnym do 2d-x. – Waseem

+0

Jest wiele problemów z tym związanych, nawet jeśli obecnie masz rację. Po pierwsze, odrzucono mnie wcześniej, ponieważ "nowsza odpowiedź" jest teraz poprawna. Po drugie, mogę być członkiem w dowolnym momencie, od śmierci, obrażeń lub po prostu iść dalej. Każdy może, więc uważam, że moderatorzy powinni znaleźć bardziej odpowiednie rozwiązanie, gdy takie rzeczy się zdarzają. Powiem tu jednak, to jest aktualna poprawna odpowiedź! –

Powiązane problemy