2012-04-26 7 views
5

編集:十分な書き換えとコメントで、私はそれを実行して、他の人のために最終的に投稿します。CCScrollView for cocos2d-xは動作しますか?

Edit2:自分のバージョンをさらに更新していますが、オリジナルのコーダーはC++であまりよくないと知っています。使用する前にすべてを調べてみてください。ポスト

現在利用可能なcocos2d-x用のCCScrollViewには、大きな欠陥が1つあります。

特に、cpp関数ヘッダーは.hファイルと一致しません。 cppファイルは、X-PlatformではなくUIEventおよびNSMutableArrayを参照します。

スクロールビュー自体に配列が追加されている必要があります。これにより、forループを使用してメニュー項目を作成する機能が制限されます(メニュー項目を作成する場合)。変更可能なループを使用できないためiOSのようにお互いをサブクラス化するので、単にCCArray * array = mutable-> getMutableArray()などのように、変更可能なものを使うことはできません。

また、定義は古いです(ただし、cocos2d-xサイトの翻訳ルールを使用してCCX_SAFE_DELETEを追加することで修正可能です)。また、プロジェクト内でさえもNSおよびUIオブジェクトを作成しようとするさまざまなランダムテンプレート私は理由を知りません。

基本的な考え方は、変更可能な配列を使用することを除いて、このクラスはC++に変換するのも面倒です。私はヘッダーが一致しないので、作者が彼が持っているバージョンを編集したとは思わない。私はcppと.hファイルの両方を(それぞれ2つずつ)ダウンロードし、両方とも他の問題と一緒にCCの代わりにUIEventを持っていると思った。

注:私は上記の様々な問題を解決し、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

私自身の質問にまだ答えることはできません。可能であれば回答を移動します。 –

+0

CCX_SAFE_DELETE()の定義を、http://www.cocos2d-x.org/projects/cocos2d-x/wiki/Rules_of_translating_objc_to_cppからccMacrosに移動することを覚えておいてください。h area –

+0

cppファイルのinitWithLayers()の下で、// l-> setAnchorPoint(ccp(0,0));を消去またはコメントしたいと思うでしょう。 // l-> setPosition(ccp((i * scrollWidth)、0));ポジショニングを得るまた、if!widthOffsetを削除すると、それ自体が0にリセットされるか、それが何であるかのチェックには価値がありません。おそらくObj>からの移植で問題が発生すると、それは正しく見えるようになります。また、スクロール表示をしたいだけならページングの内容を消去します –

答えて

4

ためCocos2d-Xのサイト上のフォーラムをチェックします最新のもの。彼らはこれに基づいて作者によって今修正されています。検索エンジンを介してこれを見つけた人のために、新たな情報を追加するために、古いスレッドを復活 http://www.cocos2d-x.org/boards/18/topics/1090?r=10835#message-10835

+0

最後に1つ目のこと:実際には2d-xスクロールビューにはページの配列(最上位ノード)が必要です。これを書き直すか、サイトにあるもの(私のバージョン以外)を使用する場合は、そのことを覚えておいてください。私のバージョンはそのまま動作しますが、それは複雑さには適していません –

9

CCScrollViewは現在、GUI拡張の一部であり、かなりうまく動作するようです。上で参照されている実装はもう必要ありません。

+0

ああ、いいです。ありがとう! –

+0

@StephenJそれを受け入れられた回答としてマークできますか?これはあなたが言及した問題を解決します。さらに、2d-xにネイティブなものにリンクします。 – Waseem

+0

あなたは現在正しいですが、それには複数の問題があります。 1つ目は、以前は「もっと新しい答え」が正しいことを前に、私はdownvotedされています。第二に、私は、死亡、傷害、または単に動き出すことから、任意の時点でメンバーになることができます。誰でもできるので、モデレータはこのようなことが起こったときに、より適切な解決策を見つけるべきだと思います。私はここで言うだろう、これは現在の正解です! –

関連する問題