C++ support for Cocos Creator

daily update

  • parsing the sprite frame data
  • parsing the texture data
  • parsing the uuid-to-mtime data (not sure if this is needed yet)
  • guess Node class base on components

The output, for the moment, is not useful yet, but it will be soon. From a very basic .fire scene, the output right now is this:

Scene
--Canvas
--TiledMap
--ParticleSystem
--Sprite('grossini_dance_08')
--Sprite('grossini_dance_08')
--Label('This is a label')
--Label('This is another label')

I’ll add the c++ output in the near future. So far, I think I’m parsing all the needed info to support the “built-in renderer” nodes.

2 Likes

daily update

script generates compilable c++ code. It only supports the Renederer built-in nodes for the moment.
Tomorrow I’ll add support for Canvas and put the resources in the correct place
and on Wednesday start with the UI built-in nodes.

daily update

  • Add design resolution
  • Sprite Frames are being generated.
  • outputs a .cpp / .h file per .fire file
  • each .cpp file has two functions: XXX_setup() and XXX_create().

Example of generated file is here:

3 Likes

daily update

many bug fixes for the Renderer nodes… still a few things to fix regarding positioning… for some reason the positions are not the same as in Cocos Creator. It has to do with the Design resolution. Will fix it tomorrow.

This is a scene renderer in C++ which was created in cocos creator:

7 Likes

daily update:

Well, apparently the issue with the positioning the sprites has to do with some scaling that Cocos Creator does with the canvas, but I haven’t figured out yet how to do it.
Instead, I was able to add better support for label and sprites.

For labels it supports:

  • system fonts
  • ttf fonts
  • bmfonts
  • different alignments
  • colors
  • line height
  • multiline

For sprites it supports:

  • all transformations: rotations, scale, skew, etc.
  • colors
  • .png and atlas

Sprites:

Labels:

5 Likes

Do your plans include being able to export animations created in cocos creator to C++?

quick update
I’ve just fixed the canvas design resolution thing, but that didn’t fix the sprite positioning issue. I think it has to do wit the sprite scales. I’ll ask the Lua guys how they fixed it.

yes, it is in the plan. I don’t know how they work yet, but it is in the plan.

2 Likes

daily update:
I started with UI support. This is not trivial.
Mostly because the API are different: for example, in cocos2d-x you create an EditBox with a scale9sprite, but not in Creator. So I need to figure out how to convert them.
The script has parses most of the UI components, but it doesn’t generate valid c++ for these UI elements. I have to figure out the Scale9Sprite first.

2 Likes

What happened since my last update.

Basically I got stuck because most of the Cocos Creator UI built-in nodes require “Slice 9” features.
In theory I could our class Scale9Sprite, but it is not compatible.
So, what I did was to add Slice 9 features into Sprite. (feature almost finished)

3 Likes

Hey ricardo. Seems like, we’ll have evolved version of cocos2d-x(C++) Api support in Cocos Creator. So, I am just curious to know if this Cocos2d-x (C++) will be v4.0? :smiley: :smiley:

Your efforts are helpful. Thanks for progress :slight_smile:

Sorry, I didn’t understand the question. Do you mean if this feature will be part of v4.0?
Hopefully it will be part of 3.14 or 3.15

daily update:
Finished Slice 9 support for Sprite.
It was tricky to implement it correctly, but it was worth the effort.

I’m still not satisfied with the API.
Right now it works like this:
a)

// in normalized coordinates. it will enable the "slice 9" feature
sprite->setCenterRect(0.4, 0.4, 0.2, 0.2);

// and the you scale the image using setContentSize().
sprite->setContentSize( sprite->getContentSize() * 2);

But I think it is better to just use the scale API. eg:
b)

sprite->setCenterRect(0.4, 0.4, 0.2, 0.2);
sprite->setScale(2);

a) is “compatible” with Scale9Sprite, but b) is more natural. You don’t have learn how to use it. Just scale it
thoughts?

Working example here: https://github.com/ricardoquesada/cocos2d-x/blob/sprite_scale9/tests/cpp-tests/Classes/SpriteTest/SpriteTest.cpp#L5316

Hi, Riq
In JS version, we use these APIs:

  1. setInsetLeft/setInsetRight/setInsetTop/setInsetBottom is used to specify the sliced 9 grids.
  2. setContentSize is used to specify the content size of sprite.

This is used because it is more natural in editor.
The sliced grid is set in pixels, and the content size only consider the size of sprite. Which will be independent with Scale.

1 Like

Yep, i like b).
Should we consider Scale9Sprite? Scale9Sprite is part of UI, but Sprite is not. And i think Scale9Sprite can use Sprite to internally simplify the codes.

yes, I evaluated that API, but it was somewhat complex. So, I replaced it with just one call to setCenterRect (which is also used in SpriteKit and I guess in other engines as well).

It will require some important changes internally, but I think it is a better API.

What do you mean by that? To create a new class called Scale9Sprite? If so, I would do that. This feature is part of Sprite, so there is no need to create a new class.
I think UI::Scale9Sprite supports slices from different images and this new feature doesn’t support that. It only supports “slices” that are part of the same texture.

I just replied it

a) is “compatible” with Scale9Sprite,

I’m for option (b), with a few thoughts.

It’s a little confusing coming from the current API.

I don’t imagine it would be used much, if at all, but do you think someone might want to scale (by transform) “on top” of setting a specific center rect and content size. My gut says this would just look bad [almost] always and no one would want to do this.

Edit: I actually can see pixel art games wanting to use this. Set a base content size and then scale (by 1x,2x,3x transform) so if there’s a 1px border it’d have a width of 3x after a setscale(3).

That said could one change the contentSize and use scale to affect the dimensions?

How does contentSize affect scale in (b)?

I find the use of normalised values for setCenterRect unintuitive. All other functions are implicitly in design resolution space unless explicitly stated (with the exception of anchor point). Instead I propose we expose the functions: setCenterRect and setNormalisedCenterRect.

For the scaling behaviour I think it makes sense to use the 9slice,but this should be configurable. setScaleMode(ScaleMode::NineSlice), setScaleMode(ScaleMode::Normal).

This approach should be taken with 9 slice behaviour too. Allowing the user to control and query the render mode of the sprite using an enumeration. setSpriteMode(SpriteMode::Quad) setSpriteMode(SpriteMode::NineSlice). This allows us to extend functionality easily in the future without changing the API.

1 Like

I prefer option a) and agree with @almax27 about adding non normalized function. Also agree that setting rect region is more convenient than setting four insets.

Setting scale may be confusing because:

  • someone may want to really scale sprite;
  • scale for other UI classes don’t change content size itself. But i think content size of scale9sprite should be equal to intended size. So such scale behaviour may be inconsistent with other engine parts. Also what if scale9sprite will have children (though i usually don’t add children to sprites)?

If we are going to use setScale(), we should not update the transform matrix, otherwise the sprite will be scaled using the traditional scale method I we don’t want that. We should do the scaling manually, so I though of doing something like this:

void Sprite::setScale(float x, float y) override
{
   // if slices are 1, call super and return
   if (_slices == 1)  {
       super::setScale(x,y);
       return
   }
  /* else */
  _stretch_factor  = calculate_factor_x(x,y);
  updateContentSize();
}

So, basically, if slices are 1, then continue with the current model.
If not, update the contentSize and calculate the stretch factor for the slice 9 pieces.

makes sense.

yes, great point. it will be super confusing.
because if we override setScale(), it won’t scale its children when in 9 slice mode. but it will scale them when in non-slice-9 mode.

So, I think the API should be:

  • setContentSize() to change the size of the sprite. Won’t affect the scale of its children.
  • setNormalizedCenterRect() in normalized coords, and setCenterRect() in points coords.

thoughts?