问候 Stackoverflow,
我目前正在尝试在我正在开发的 cocos2d-x 游戏中实现滚动菜单。问题是项目在我想要的相反方向滚动。例如,如果我将手指从屏幕底部拖动到顶部, Sprite 就会弹回原来的位置。
如果我将手指从顶部拖到底部, Sprite 将跟随我的手指(直到它到达边界)。
这是我的代码:
/////////////////////
//SCROLL VIEW + LAYER
CCLayer *layer = CCLayer::create();
layer->setContentSize( CCSizeMake( winSize.width, winSize.height ) );
layer->addChild( menu );
scrollView = CCScrollView::create();
scrollView->retain();
scrollView->setContentSize( CCSizeMake ( layer->getContentSize().width, layer->getContentSize().height ) );
scrollView->setDirection( CCScrollViewDirectionVertical );
scrollView->setPosition( ccp( 0,0 ) );
scrollView->setContainer( layer );
this->addChild(scrollView);
scrollView->setContentOffset( CCPointZero );
非常感谢任何建议或帮助。如果您有任何其他解决方法来使用其他方法创建滚动菜单,我很乐意听到。
谢谢!
最好的问候 安德烈亚斯
最佳答案
引用:cocos2dx/extensions/GUI/CCScrollView/CCScrollView.cpp
特别是CCScrollView::minContainerOffset
和 CCScrollView::maxContainerOffset
CCScrollView
在 OpenGL 坐标(相对于 窗口坐标)中工作 - 值相对于(左,下)正 Y 轴向上。另外,请记住 ScrollView 的定位和容器 锚定(CCNode::setAnchorPoint
)到(左,下)。
当您向下滚动(向上移动/拉动内容以查看剪切/剪辑下方的内容)时,您会看到屏幕底部边缘下方的内容,但它会在您松开触摸/拖动时弹回,因为maxContainerOffset
返回 (0, 0)
并且您刚刚尝试移动到正内容偏移量。
该图显示了 scrollview 和 container 创建/初始化时的状态。这是在设置和定位子元素 和容器 时“考虑”的状态或坐标。灰色矩形(左下)显示滚动容器 的有效区域。想象容器的 anchor 在其中移动。
要看到容器开始滚动到顶部(您在窗口坐标 中工作时所期望的),请相应地设置内容偏移量(设置后立即)。这将产生预期的结果/行为。
scrollView->setContentOffset(ccp(0.f, (scrollViewHeight-scrollContainerHeight)), false);
下面编辑的代码中有一个更完整的示例。
允许在窗口坐标(正 Y 轴向下)滚动的“修复”可能是为了调整扩展,这将需要您重建 cocos2dx 库并将影响所有项目(甚至其他项目)您可以尝试的示例代码)。/* // (StackOverflow Post Edit: This hack is not required.) CCPoint CCScrollView::maxContainerOffset() { // Default CCPointZero; return ccp(0.0f, m_pContainer->getContentSize().height*m_pContainer->getScaleY() - m_tViewSize.height); } CCPoint CCScrollView::minContainerOffset() { // Default Y = m_tViewSize.height - m_pContainer->getContentSize().height*m_pContainer->getScaleY(); return ccp(m_tViewSize.width - m_pContainer->getContentSize().width*m_pContainer->getScaleX(), 0.f); } */
一个侵入性较小 hack,是将ScrollView 实例缩放到-1 和子级容器节点的也为-1。您还必须重新定位子节点,同时考虑逆比例。在两个级别缩放的结果是内容(子节点)被直接查看(而不是翻转)。将 ScrollView 缩放到 -1 的结果是滚动发生在预期的方向上。请注意,尽管此“修复”也会在 X 轴上翻转滚动,因此仅适合您希望垂直滚动的情况 (CCScrollViewDirectionVertical
)。CCSize winSize = CCDirector::sharedDirector()->getWinSize(); CCLayer* scrollContainer = CCLayer::create(); // Container for the scroll view scrollContainer->setAnchorPoint(CCPointZero); // CCScrollView does this too when it's set as the container. // Content for the container CCSprite *tallContentA = CCSprite::create("TallContentA.png"); tallContentA ->setPosition(ccp(winSize.width*0.5f, winSize.height*0.9f)); CCSprite *tallContentB = CCSprite::create("TallContentB.png"); tallContentB ->setPosition(ccp(winSize.width*0.5f, winSize.height*0.1f)); scrollContainer->addChild(tallContentA, 2); scrollContainer->addChild(tallContentB, 2); float scrollContainerHeight = tallContentA->getContentSize().height + tallContentB->getContentSize().height; scrollContainer->setPosition(CCPointZero); scrollContainer->setContentSize(CCSizeMake(winSize.width, scrollContainerHeight*1.05f)); // Set up scroll view CCScrollView* scrollView = CCScrollView::create(winSize, scrollContainer); scrollView->setPosition(CCPointZero); scrollView->setDirection(CCScrollViewDirectionVertical); // ScrollView initializes at the (left, bottom). The container also gets positioned relative to that and goes Y-up. // Pre-set it to the value CCScrollView::minContainerOffset will return when it's scrolled to the top // (note, this is a negative number, indicating the touch moving downwards, i.e. it's pre-scrolled such that the top of the content is visible when we begin) scrollView->setContentOffset(ccp(0.f, (winSize.height-scrollContainerHeight*1.05f)), false); /* // (StackOverflow Post Edit: This hack is not required.) // Hack: CCScrollView's maxContainerOffset is (0, 0) and minContainerOffset is (difference between view and content size which is negative) // It's designed to be (left, bottom) based and positive scrolling means showing stuff above the top of the screen. // Since we're using it in terms of Window coordinates ((left, top) based), we scale the scroll view // and it's container's children by -1 and position the children differently // (eg. Y position winSize.height*0.1f was changed to winSize.height*0.9f) // We can't just set the scroll view's Y scale to -1 because CCNode::getScale asserts that X and Y scale must be the same. scrollView->setScale(-1.f); tallContentA->setScale(-1.f); tallContentB->setScale(-1.f); */ addChild(scrollView);
另请注意,上面提到的两个修复互斥,不要同时应用。
Answer现在也在 cocos2d-x 论坛上。
关于android - Cocos2d-x CCScrollview 上下滚动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14693302/