cocos2d-x-3.0 draw vs onDraw - cocos2d-x

I'm using cocos2d-x v3.0 and in some test project I'm doing some custom drawing by overriding Node's draw method, but in the DrawPrimitives example provided they do something like this:
void DrawPrimitivesTest::draw()
{
_customCommand.init(_globalZOrder);
_customCommand.func = CC_CALLBACK_0(DrawPrimitivesTest::onDraw, this);
Director::getInstance()->getRenderer()->addCommand(&_customCommand);
}
void DrawPrimitivesTest::onDraw()
{
// drawing code here, why?
}
From reading the header and source files it seems like this may be some way of sending render commands straight to the renderer, is that correct?
Should I be using this method to do custom drawing? What's the difference between draw an onDraw?
EDIT:
As #Pedro Soares mentioned, since Cocos2D-X 3.0 you can't override draw() anymore. you have to use draw(Renderer *renderer, const kmMat4 &transform, bool transformUpdated) instead.

There is sample on cocos2d-x RC0 package that shows how to use the DrawPrimitives on top of other layers.
On your Layer .h add the following:
private:
void onDrawPrimitives(const kmMat4 &transform, bool transformUpdated);
CustomCommand _customCommand;
Now in the cpp of the Layer, override the layer draw method and include the onDrawPrimitives method:
void MyLayer::onDrawPrimitives(const kmMat4 &transform, bool transformUpdated)
{
kmGLPushMatrix();
kmGLLoadMatrix(&transform);
//add your primitive drawing code here
DrawPrimitives::drawLine(ccp(0,0), ccp(100, 100));
}
void MyLayer::draw(Renderer *renderer, const kmMat4& transform, bool transformUpdated)
{
_customCommand.init(_globalZOrder);
_customCommand.func = CC_CALLBACK_0(MyLayer::onDrawPrimitives, this, transform, transformUpdated);
renderer->addCommand(&_customCommand);
}

In future, cocos2d-x 3.x renderer will be multithreaded with command pool.
draw method called by visit method, to create new command. When command is performed by command pool, onDraw is called. At this moment, commands are performed in single thread, but in overloaded onDraw method you should assume, that it will be called in another thread to simplify future migration.

I use draw method for debugDraw Like this It may be helpful
void HelloWorld::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags)
{
Layer::draw(renderer, transform, flags);
Director* director = Director::getInstance();
GL::enableVertexAttribs(GL::VERTEX_ATTRIB_FLAG_POSITION );
director->pushMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
world->DrawDebugData();
director->popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
}

The draw() expression should be the same as the base class function.
The draw method of Node for cocos 3.3rc is:
virtual void draw(Renderer *renderer, const Mat4& transform, uint32_t flags);

Related

'Gdiplus::Graphics' : no appropriate default constructor available

Not sure what I am doing wrong.. I have a very muddy idea of how Constructors should be formatted or structured, so any insights would help!
Renderer.h
#pragma once
#include <afxwin.h>
#include <winapifamily.h>
#include <wtypes.h>
#include <gdiplus.h>
class Renderer
{
public:
Renderer();
~Renderer();
void Clear(Gdiplus::Color clearColor);
virtual void Free() = 0;
virtual void LoadFace(int index, char* path) = 0;
void InitFromHDC(HDC dc);
void Shutdown();
// Drawing surface
Gdiplus::Graphics _graphics;
protected:
private:
bool _gdiplusActive;
};
Renderer.cpp
Renderer::Renderer()
: _gdiplusActive(false)
{ // <-error here
}
Renderer::~Renderer() {}
...
I tried many variation of adding variables... but honestly, the error may be obvious who understands what a default constructor is. I dunno.
A default constructor is a construtor that takes no parameters.
You can't create a Gdiplus::Graphics out of thin air, you need to give it something to draw on: a bitmap, a window or a device context.
Here is the list of constructors available:
https://learn.microsoft.com/en-us/windows/win32/api/gdiplusgraphics/nf-gdiplusgraphics-graphics-graphics(constgraphics_)

When would I need a Virtual Function?

I understand that a Virtual Function is a function that can be redefined in classes that inherit that function.
Yet, I do not understand why I would need a Virtual Function. Can someone explain me or show me cases where I would need Virtual Functions?
Thanks!
There is nice explanation with good example
https://en.wikipedia.org/wiki/Virtual_function
Any function can be redefined in a class' inheritors. The key to virtual functions is that they are supposed to be overriden.
Suppose you have a polygon class (in C++):
class Polygon {
protected:
int width, height;
public:
void set_values (int a, int b)
{ width=a; height=b; }
virtual int area ()
{ return 0; }
};
Now it doesn't make sense to define the Polygon.area function inside the polygon class, because at this level you don't know what the polygon is. The existence of the virtual function enforces all inheritors to implement their own version of the function.

update function of Component not called anymore

The update function of Component is not called anymore in Cocos2dx v3 while it was called fine in v2.x
I noticed the CCScheduler is completely different in both versions and that Node::update in v2 is called from CCScheduler::update function but in v3 it is called from Scene::update - which is never called.
Anybody have an idea what is the best way to migrate this from v2 to v3.
My code is as follows
In game scene
layerMoveLeft = ParallaxNode::create();
layerMoveLeft->addComponent(new MoveLeft() );
this->addChild(layerMoveLeft);
In MoveLeft class -
class MoveLeft : public Component
...
void MoveLeft::onEnter()
{
log("- MoveLeft::onEnter");
}
void MoveLeft::update(float delta) {
log("- MoveLeft::update");
}
The update function in v3 is never called
in V 3+ you can call update method on Node class using ScheduleUpdate() function call.
virtual void update(float dt);
I don't know why you want Component class in V 3.0
Make the following changes and i hope that it will work.
MoveLeft.h
void update(float delta);
MoveLeft.cpp
this->scheduleUpdate();
You can add the above code anywhere you want in the class (preferably in the init() method)
Now create the function as you did before:
void MoveLeft::update(float delta) {
log("- MoveLeft::update");
}
P.S: I haven't used it with Component, i have used it with Layer.
class Quizzes: public cocos2d::Layer{
public:
virtual bool init();
}
in V 3+, you can add code above to class parent of component.
this->scheduleUpdate();

Where do I store a function that acts on an array of objects?

I'm trying to create something like the following using c++:
I have a class called particle which will store the position, velocity of each particle. Additionally, a member function will update the particle's position using velocity data.
I'm also trying to write a function that will detect a collision between particles and the boundaries of the box. To do so, this function needs access to each particle's position and velocity. Thus, the function needs to take an entire array of particles as a parameter. However, this function can't exist as a member function of the particle class, because then it won't have access to all the particles.
Question: Where do I include the collision detection function, such that it is an extensible part of the particle class?
I thought about just writing this function inside my main.cpp file, but I haven't the slightest clue whether this adheres to the OOP guidelines. Ideally there might be other functions that also act on an array of particles.
Probably what you want is some sort of "ParticleContainer" object, that holds the array of particles, and performs operations on the particle system as a whole.
(That's also where you would put the code that runs down the array and calls the "Draw" functions.)
I guess that good idea will be to declare a detection function as a friend of class particle: it will have access to all members in class. Then you can fire this function in loop inside of some kind of manager function that will calculate the collision to all particles in array. In this
void CollisionMgr(particleClass *ParticleArrayPtr, int NumOfParticles)
{
while(NumOfParticles)
{
CollisionOfParticle(*ParticleArrayPtr, NumOfParticles);
NumOfParticles--;
}
}
I tend to use a pattern along these lines: Keep all the model state in a single class called Modelor Environment; have a separate class Renderer which knows how to draw the model state; have a System class which ties these together. The following is highly abbreviated, but hopefully gives the idea:
class Box {};
class Location {};
class Particle
{
public:
void updatePosition(double dt);
const Location& getLocation();
};
class Environment
{
public:
void checkForCollisions();
private:
Box box;
std::vector<Particle> particles;
};
class Renderer
{
public:
void render(Environment& environment);
};
class System
{
Environment environment;
Renderer renderer;
};

Is it possible to copy a CCLayer instance in cocos2x?

I created a CCLayer instance, and then I want to create the same layer.
Is it possible to copy a CCLayer instance in cocos2-x?
AFAIK, there is no such possibility in cocos2dx now. So just place creation of your layer to the method that will return result layer and call this method twice.
Copying/deep-copying objects in cocos2d-x is not an option.
The best way is to create a custom class for your layer, and then call the ::create() method twice to have two instances of the same layer, sharing all the initial configuration.
In MyLayer.h:
USING_NS_CC;
class MyLayer : public CCLayer {
public:
CREATE_FUNC(MyLayer);
virtual bool init();
};
In MyLayer.cpp:
bool MyLayer::init() {
if (!CCLayer::init())
return false;
// Insert here all custom initialization logic
return true;
}
Then you can easily do:
MyLayer *layer1 = MyLayer::create();
MyLayer *layer2 = MyLayer::create();
and both layers will share the same initial aspect/configuration/whatelse.