Cocos2d-х CCScrollview прокрутки вниз

голоса
4

Привет Stackoverflow,

В настоящее время я пытаюсь реализовать скроллинг меню в cocos2d-х игры, которые я разрабатываю. Проблема заключается в том, что элементы прокрутки в противоположном направлении, что я хочу. Например, если я перетащить пальцем в нижней части экрана, в верхней части, спрайт будет отражаться обратно в исходное положение.

И если я тащу свой палец от верхней части к нижней части, спрайт будет следовать за моим пальцем (пока она не достигнет границы).

Это мой код:

    /////////////////////
    //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 );

Любые предложения или помощь высоко ценится. Если у вас есть какие-либо другие работы вокруг для создания прокрутки меню с другим подходом, я хотел бы услышать.

Спасибо!

С наилучшими пожеланиями Andreas

Задан 04/02/2013 в 16:41
источник пользователем
На других языках...                            


4 ответов

голоса
7

См: cocos2dx / расширения / GUI / CCScrollView / CCScrollView.cpp

В частности CCScrollView::minContainerOffsetиCCScrollView::maxContainerOffset

CCScrollViewработает в OpenGL координат (в отличие от координат окна ) - значения относительно (слева внизу) с положительной осью Y , идущей вверх. Кроме того , имейте в виду позиционирование View скроллинга и контейнер закреплены ( CCNode::setAnchorPoint) до (слева, внизу).

При прокрутке вниз (перемещения / тянуть содержание вверх , чтобы увидеть содержимое ниже вырезать / клип), вы увидите содержимое ниже нижнего края экрана , но он отскакивает обратно в тот момент , вы отпустить сенсорное / сопротивление , потому что maxContainerOffsetвозвращается (0, 0)и вам «ве просто пытался перейти к положительному содержанию смещения.

Координаты CCScrollView и контейнер

На диаграмме показано состояние Scrollview и емкости при их создании / инициализирован. Это состояние или координаты , чтобы «думать» при настройке и позиционирование дочерних элементов и контейнера . Серый прямоугольник (слева, снизу) показывает действительную область для прокрутки контейнера . Представьте себе , узловая точка движется контейнера внутри него.

Чтобы увидеть контейнер прокручивать вверх , чтобы начать с (то , что вы ожидали бы , что при работе в окне координат ), установите содержание смещения соответственно (сразу после установки его). Это даст ожидаемые результаты / поведение.

scrollView->setContentOffset(ccp(0.f, (scrollViewHeight-scrollContainerHeight)), false);

Более полный пример в отредактированной коде ниже.

  1. А «исправить», чтобы прокрутка в окне координат (положительная ось 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);
    }
    */
    
  2. Менее навязчивым взломать , чтобы масштабировать 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);
    

Также обратите внимание , что два исправления , упомянутые выше , являются взаимоисключающими , не не применяются как .

Ответ теперь на cocos2d-х форуме тоже.

Ответил 24/04/2013 в 13:04
источник пользователем

голоса
3

@Zennichimaro,

@ Ответ PAT является правильным и, по сути упрощенная версия

Имея это в виду, обратите внимание, что 3 вещи важны:

  1. CCScrollView::setViewSize() - вы явно пропустили эту, она должна быть ширина и высота вашего видимой области (синее поле, я думаю, что это вся ваша windowSize, если вы хотите в полноэкранном режиме)

  2. CCScrollView::setContentSize()- это отличается от setContentOffset, похоже , вы ошиблись это setContentOffset, во всяком случае, это должно быть установлено в размере всего контейнера (красная коробка, ваш, вероятно , будет ccp(windowSize.width,2496.0f))

  3. CCScrollView::setContentOffset()- если вы хотите расположить его так, чтобы верхний видно изначально, минимальные и максимальный задаются небольшим серым прямоугольником поле в ответе (на сером поле, ваш, вероятно , будет ccp(0.0f, windowSize.height-2496.0f))

Ответил 10/12/2013 в 01:15
источник пользователем

голоса
3

Более короткий ответ был бы:

scrollView->setContentOffset(scrollView->minContainerOffset());

Так как точка привязки находится в нижнем левом углу, начальное смещение не равна нулю, но отрицательное число.

Ответил 15/03/2014 в 15:13
источник пользователем

голоса
0

Если кто-то хочет сделать Scrollview как в многопользовательских онлайн игр чата таблиц (добавляет сообщения в нижней и авто прокручивается вниз от него), то, возможно, кто-то найдет это полезным:

часть кода моего ChatTableView.h

//tableView dataSource is vector of strings
class ChatTableView :public Layer, public TableViewDataSource, public TableViewDelegate
{
public:
    vector<string> n_msglist;
    TableView* pTableView;
    void addMsg(string text);
private:

};

//part of the code of my ChatTableView.cpp
void Init(){
    pTableView = TableView::create(this, VisibleRect::getVisibleRect().size, NULL);
    pTableView->setDirection(ScrollView::Direction::VERTICAL);
    pTableView->setVerticalFillOrder(TableView::VerticalFillOrder::TOP_DOWN);
    pTableView->setDelegate(this);
    pTableView->setBounceable(false);

} 
void ChatTableView::addMsg(string text){

    n_msglist.push_back(text); //adds string to vector
    pTableView->reloadData(); //reloads data with newly updated vector and scroll back to top
    pTableView->setContentOffset(pTableView->maxContainerOffset()); //scrolls to bottom
}
Ответил 03/08/2014 в 16:39
источник пользователем

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more