編集:十分な書き直しとコメントがあれば、私はそれを実行しています、他の人のために以下に最終を投稿します。
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に変更しましたが、圧倒されています。
おそらく、代わりに視差ノードを使用する必要がありますか?
これはばかげているだけです。おそらく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);
}
}
*/