cocos2dx action error: liquid, wave3d and lens3d - c++

Now I'm following article http://www.cocos2d-x.org/wiki/Effects. Examples of the link make errors.
Tested cocos2d-x version is cocos2d-x 3.2beta0.
My code:
auto bgimage = Sprite::create("top.png");
bgimage->setPosition(visibleSize / 2);
// create a Lens3D action
ActionInterval* lens = Lens3D::create(10, Size(32, 24), Vec2(100, 180), 150);
// create a Waved3D action
ActionInterval* waves = Waves3D::create(10, Size(15, 10), 18, 15);
// create a sequence an repeat it forever
bgimage->runAction(RepeatForever::create(Sequence::create(waves, lens, NULL)));
this->addChild(bgimage);
result logs:
Assert failed: GridActions can only used on NodeGrid
Assertion failed!
File: CCActionGrid.cpp
Line: 84
What did I mistake? even I remove liquid action line, wave3d and lens3d also show me same error.

The assertion is clear. You must use NodeGrid if you want use GridActions like Lens3D or Waves3D. If you want use this action, create NodeGride, add your sprite to them, and run action on NodeGrid.
auto bgimage = Sprite::create("top.png");
bgimage->setPosition(visibleSize / 2);
// create a Lens3D action
ActionInterval* lens = Lens3D::create(10, Size(32, 24), Vec2(100, 180), 150);
// create a Waved3D action
ActionInterval* waves = Waves3D::create(10, Size(15, 10), 18, 15);
// create a sequence an repeat it forever
auto nodeGrid = NodeGrid::create();
nodeGrid->addChild(bgimage);
nodeGrid->runAction(RepeatForever::create(Sequence::create(waves, lens, NULL)));
this->addChild(nodeGrid);

Related

Why is my QGraphicsLine in the wrong place

I want to draw a line to connect two circles (QGraphicsEllipseItem), but I find that I don't get the desired result with this way of writing.
//they have been initialized to the correct place
QGraphicsEllipseItem* nodeu;
QGraphicsEllipseItem* nodev;
this->addLine(nodeu->x(), nodeu->y(), nodev->x(), nodev->y());
The result of executing these codes is that only two circles appear, but no lines appear.
like this
My rough inference is the problem of coordinate transformation, but I just can't solve it.
thank you!
you should first add one QGraphicsView in your UI or :
QGraphicsView *graphicsView;
QGridLayout *gridLayout;
gridLayout = new QGridLayout(centralwidget);
gridLayout->setSpacing(0);
gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
graphicsView = new QGraphicsView(centralwidget);
graphicsView->setObjectName(QString::fromUtf8("graphicsView"));
gridLayout->addWidget(graphicsView, 0, 0, 1, 1);
then :
QGraphicsScene *_scene = new QGraphicsScene(this);
ui->graphicsView->setScene(_scene);
ui->graphicsView->setRenderHints(QPainter::Antialiasing);
QGraphicsEllipseItem *nodeu = new QGraphicsEllipseItem;
nodeu->setRect(20, 10, 20, 20);
_scene->addItem(nodeu);
QGraphicsEllipseItem *nodev = new QGraphicsEllipseItem;
nodev->setRect(80, 60, 20, 20);
_scene->addItem(nodev);
QGraphicsLineItem *_lineItem = new QGraphicsLineItem;
_lineItem->setLine(nodeu->rect().x() + nodeu->rect().width() / 2.0, nodeu->rect().y() + nodeu->rect().height() / 2.0,
nodev->rect().x() + nodev->rect().width() / 2.0, nodev->rect().y() + nodev->rect().height() / 2.0);
_scene->addItem(_lineItem);
this is the output:

Cocos2d-x 4.0 Lens3D and Waves3D Animations

I used below code to make water like animation for background image
auto background = Sprite::create(TEX_MM_BG);
background->setPosition(Vec2(SW*0.5f, SH*0.5f));
auto nodeGrid = NodeGrid::create();
nodeGrid->addChild(background);
this->addChild(nodeGrid, 0);
ActionInterval* lens = Lens3D::create(10, Size(32, 24), Vec2(100, 180), 150);
ActionInterval* waves = Waves3D::create(10, Size(15, 10), 18, 15);
nodeGrid->runAction(RepeatForever::create(Sequence::create(waves,lens, NULL)));
Animation look is good. But it stops 10 seconds then play 10 seconds then again stops 10 seconds...it repeats. How to avoid stoping in middle ?
It doesn't stop it is applying waves effect followed by lens effect. While applying lens effect the animation of waves stops.
Correct way to code this will be to use a Spawn:
ActionInterval* lens = Lens3D::create(10, Size(32, 24), Vec2(100, 180), 150);
ActionInterval* waves = Waves3D::create(10, Size(15, 10), 18, 15);
// Spawn will run both effects at the same time.
auto lensWaveSpawn = Spawn::createWithTwoActions(lens, waves);
auto seq = Sequence::create(lensWaveSpawn, nullptr);
nodeGrid->runAction(RepeatForever::create(seq));

How to force re-rendering after adding point to a vtkPlot in a qvtkWidget?

In QT I have a qvtkWidget in which I plot a graph.
I use two functions:
The following function initializes the plot with two points (0,0) and (0,1):
bool VTKPlotter::initPlot(){
// Create a table:
plotTable = vtkSmartPointer<vtkTable>::New();
vtkSmartPointer<vtkFloatArray> arrT = vtkSmartPointer<vtkFloatArray>::New();
vtkSmartPointer<vtkFloatArray> arrUSD = vtkSmartPointer<vtkFloatArray>::New();
arrT->SetName("Time");
plotTable->AddColumn(arrT);
arrUSD->SetName("USD");
plotTable->AddColumn(arrUSD);
//Set up the view:
view = vtkSmartPointer<vtkContextView>::New();
view->GetRenderer()->SetBackground(0.8, 0.8, 0.8);
//Set up chart:
vtkSmartPointer<vtkChartXY> chart = vtkSmartPointer<vtkChartXY>::New();
view->GetScene()->AddItem(chart);
//Set renderer, interactor:
view->SetInteractor(plot_qvtkWidget->GetInteractor());
plot_qvtkWidget->SetRenderWindow(view->GetRenderWindow());
plot_qvtkWidget->show();
//Add line and initial values:
vtkPlot *line;
line = chart->AddPlot(vtkChart::LINE);
line->SetInputData(plotTable, 0, 1);
line->SetColor(25, 25, 230, 220);
line->SetWidth(1.5);
int numPoints = 2;
plotTable->SetNumberOfRows(numPoints);
plotTable->SetValue(0, 0, 0);
plotTable->SetValue(1, 0, 1);
plotTable->SetValue(0, 1, 0);
plotTable->SetValue(1, 1, 1);
return true;
}
where plotTable is a vtkSmartPointer<vtkTable>, view is vtkSmartPointer<vtkContextView> and plot_qvtkWidget is a QVTKWidget*.
When the above function is called, the plot is immediately shown in the widget.
Then I have this function which is called when I click a certain button in my QT application:
void VTKPlotter::addValue(double v){
plotTable->InsertNextBlankRow();
int r = plotTable->GetNumberOfRows() - 1;
plotTable->SetValue(r, 0, r);
plotTable->SetValue(r, 1, v);
}
The problem is, when I call the above function, the plot is not immediately updated. If I zoom in and out and pan around the plot, it eventually updates, and I can see the new point.
I've tried these methods:
view->ResetCamera();
view->Update();
view->Render();
view->GetRenderWindow()->Render();
view->GetRenderer()->ResetCamera();
view->ResetCameraClippingRange();
plot_qvtkWidget->update();
How do I force my plot to update?
One of possible solution is to call chart->ClearPlots() with subsequent appropriate calls chart->AddPlot(...)

Implement a scrollview with cocos2d-x 3.6

wondering if anyone knows how to implement a scroll view in cocos2d-x 3.6 (C++). All the tutorials I have found are for earlier cocos2d-x versions.
Thanks
I added my code below, I can get the grey scrollview box to show but it cant be scrolled and the buttons don't appear on it:
header files: "CocosGUI.h" and "cocos-ext.h"
//add scroll view
Size scollFrameSize = Size(visibleSize.width, visibleSize.height/4);
auto scrollView = cocos2d::ui::ScrollView::create();
scrollView->setContentSize(scollFrameSize);
scrollView->setBackGroundColorType(cocos2d::ui::Layout::BackGroundColorType::SOLID);
scrollView->setBackGroundColor(Color3B(200, 200, 200));
scrollView->setPosition(Point(0, visibleSize.height/1.5));
scrollView->setDirection(cocos2d::ui::ScrollView::Direction::HORIZONTAL);
scrollView->setBounceEnabled(true);
scrollView->setTouchEnabled(true);
auto containerSize = Size(scollFrameSize.width*2, scollFrameSize.height*2);
scrollView->setInnerContainerSize(containerSize);
this->addChild(scrollView);
auto button1 = cocos2d::ui::Button::create();
button1->setColor(Color3B(250, 200, 50));
button1->setTouchEnabled(true);
button1->setContentSize(Size(100, 100));
button1->setPosition(Point(containerSize.width / 4, containerSize.height / 2));
scrollView->addChild(button1);
auto button2 = cocos2d::ui::Button::create();
button2->setColor(Color3B(250, 200, 50));
button1->setContentSize(Size(100, 100));
button2->setTouchEnabled(true);
button2->setPosition(Point(containerSize.width / 8, containerSize.height / 2));
scrollView->addChild(button2);
I figured it out, It was scrolling but I added my buttons wrong. For anyone who is interested add a button like this
auto button1 = ui::Button::create();
button1->setTouchEnabled(true);
button1->ignoreContentAdaptWithSize(false);
button1->setContentSize(Size(100, 100));
button1->loadTextures("pic1.png", "pic2.png");
button1->setPosition(Point(containerSize.width / 8, containerSize.height / 2));
scrollView->addChild(button1);
Size scroll_size = Director::getInstance()->getWinSize();
Size container_size = Size(scroll_size.width * 2, scroll_size.height);
Layer* container = Layer::create();
container->setContentSize(container_size);
ScrollView* scroll = ScrollView::create(scroll_size, container);
mScroll->setDelegate(this);
mScroll->setDirection(ScrollView::Direction::HORIZONTAL);
1.size of container should be larger than size of scrollview
2.add child to container, not scrollview
3.implement ScrollViewDelegate

cocos2d-x 3 add a Sprite into a Layout

When I do this it works:
Layout* layout = Layout::create();
layout->setLayoutType(Layout::Type::HORIZONTAL);
layout->setContentSize(Size(280, 150));
layout->setPosition(Vec2(visibleOrigin.x + 100, visibleOrigin.y + visibleSize.height - 100));
addChild(layout);
auto jacket = Button::create("jacket.png", "jacket.png", "jacket.png", Widget::TextureResType::PLIST);
layout->addChild(jacket);
But when I do this (add a Sprite instead of the button added in above code):
Layout* layout = Layout::create();
layout->setLayoutType(Layout::Type::HORIZONTAL);
layout->setContentSize(Size(280, 150));
layout->setPosition(Vec2(visibleOrigin.x + 100, visibleOrigin.y + visibleSize.height - 100));
addChild(layout);
auto jacket = Sprite::createWithSpriteFrameName("jacket.png");
layout->addChild(jacket);
Then I get assertion fail on line layout->addChild(jacket); with the message Expression: vector subscript out of range. I suppose sprites are not supported in Layouts? Then what is the right way to add and image into a layout? Should I use ImageView as below?
auto jacket = ImageView::create("jacket.png",TextureResType::PLIST);
layout->addChild(jacket);
If yes then why? and what is the difference of Sprite and Image?
if i understand correctly, the button will try to load the individual file named "jacket.png" whereas the createWithSpriteFrameName initializer will try to get the jacket.png frame from a previously loaded texture atlas
The problem could be as simple as the jacket image not being in a texture atlas or the atlas (frames) not being loaded before running this code