Skip to content

Latest commit

 

History

History
190 lines (122 loc) · 6.14 KB

5.md

File metadata and controls

190 lines (122 loc) · 6.14 KB

Chapter 5: Building and Transitioning Scenes

What is a Scene?

A Scene is a container that holds Sprites, Labels, Nodes and other objects that out game needs. A Scene is responsible for running game logic and rendering the content on a per-frame basis. You need at least one Scene to start your game. You can think of this like a movie. The Scene is what is running and users see what is happening in real-time. You can have any number of Scene objects in your game and transition through them easily. Cocos2d-x provides scene transitions and you can even have scene transitions with cool effects.

Creating a Scene

It is very easy to create a Scene

auto myScene = Scene::create();

Remember the Scene Graph?

In Chapter 2 of this guide we learned about a scene graph and how it effects the drawing of our game. The important thing to remember is that this defines the drawing order of the GUI elements. Also remember z-order!

A Simple Scene

Lets's build a simple Scene. Remember that cocos2d-x uses a right handed coordinate system. This means that our 0,0 coordinate is in the bottom left had corner of the screen/display. When you start positioning your game elements this is where you should start your calculations from. Let's create a simple Scene and add a few elements to it:

auto dirs = Director::getInstance();
Size visibleSize = dirs->getVisibleSize();

auto scene1 = Scene::create();

auto label1 = Label::createWithTTF("My Game", "Marker Felt.ttf", 36);
label1->setPosition(Vec2(visibleSize.width / 2, visibleSize.height / 2));

scene->addChild(label1);

auto sprite1 = Sprite::create("mysprite.png");
sprite1->setPosition(Vec2(100, 100));

scene->addChild(sprite1);

When we run this code we shall see a simple Scene that contains a Label and a Sprite. It doesn't do much but it's a start.

Transitioning between Scenes

You might need to move between Scene objects in your game. Perhaps starting a new game, changing levels or even ending your game. Cocos2d-x provides a number of ways to do scene transitions.

Ways to transition between Scenes

There are many ways to transition through your Scenes. Each has specific functionality. Lets go through them. Given:

auto myScene = Scene::create();

runWithScene - use this for the first scene only. This is the way to start your games first Scene.

Director::getInstance()->runWithScene(myScene);

replaceScene - replace a scene outright.

Director::getInstance()->replaceScene(myScene);

pushScene - suspends the execution of the running scene, pushing it on the stack of suspended scenes. Only call this if there is a running scene.

Director::getInstance()->pushScene(myScene);

popScene - This scene will replace the running one. The running scene will be deleted. Only call this if there is a running scene.

Director::getInstance()->popScene(myScene);

Transition Scenes with effects

You can add visual effects to your Scene transitions

auto myScene = Scene::create();

// Transition Fade
Director::getInstance()->replaceScene(TransitionFade::create(0.5, myScene, Color3B(0,255,255)));

// FlipX
Director::getInstance()->replaceScene( TransitionFlipX::create(2, myScene));

// Transition Slide In
Director::getInstance()->replaceScene( TransitionSlideInT::create(1, myScene) );

Converting between coordinate systems

convertToNodeSpace

convertToNodeSpace will be used in, for example, tile-based games, where you have a big map. convertToNodeSpace will convert your openGL touch coordinates to the coordinates of the .tmx map or anything similar.

Example:

The following picture shows that we have node1 with anchor point (0,0) and node2 with anchor point (1,1).

We invoke

Vec2 point = node1->convertToNodeSpace(node2->getPosition());

convert node2’s SCREEN coordinates to node1’s local.As the result, node2 with the position of (-25,-60).

convertToWorldSpace

convertToWorldSpace converts on-node coordinates to SCREEN coordinates. convertToWorldSpace will always return SCREEN position of our sprite, might be very useful if you want to capture taps on your sprite but need to move/scale your layer. Generally, the parent node call this method with the child node position, return the world’s postion of child’s as a result. It seems make no sense calling this method if the caller isn’t the parent.

Example:

Point point = node1->convertToWorldSpace(node2->getPosition());

The above code will convert the node2‘s coordinates to the coordinates on the screen. For example if the anchor position of node1 is which will be the bottom left corner of the node1, but not necessarily on the screen. This will convert the position of the node2 which is to the screen coordinate of the point relative to node1 ). The result shows in the following picture:

convertToWorldSpaceAR

convertToWorldSpaceAR will return the position relative to anchor point: so if our scene - root layer has anchor point of Vec2(0.5f, 0.5f) - default, convertToWorldSpaceAR should return position relative to screen center.

convertToNodeSpaceAR - the same logic as for convertToWorldSpaceAR

Sample code:

Sprite *sprite1 = Sprite::create("CloseNormal.png");

sprite1->setPosition(Vec2(20,40));

sprite1->setAnchorPoint(Vec2(0,0));

this->addChild(sprite1);

Sprite *sprite2 = Sprite::create("CloseNormal.png");

sprite2->setPosition(Vec2(-5,-20));

sprite2->setAnchorPoint(Vec2(1,1));

this->addChild(sprite2);

Vec2 point1 = sprite1->convertToNodeSpace(sprite2->getPosition());

Vec2 point2 = sprite1->convertToWorldSpace(sprite2->getPosition());

Vec2 point3 = sprite1->convertToNodeSpaceAR(sprite2->getPosition());

Vec2 point4 = sprite1->convertToWorldSpaceAR(sprite2->getPosition());

LOG("position = (%f,%f)",point1.x,point1.y);

LOG("position = (%f,%f)",point2.x,point2.y);

LOG("position = (%f,%f)",point3.x,point3.y);

LOG("position = (%f,%f)",point4.x,point4.y);

Result:


    position = (-25.000000,-60.000000)

    position = (15.000000,20.000000)

    position = (-25.000000,-60.000000)

    position = (15.000000,20.000000)