How to Use Cocos2d

Source: Internet
Author: User
Cn. cocos2d-x.orgtutorialshow? Id1205 introduction program: This tutorial will teach you how to use Cocos2d-x for a tile map-based game, of course, there is a Tiled map editor. (When we were a child, most of the games in the Overlord Elementary School were based on tile maps, such as tank wars, Adventure Island,

Http://cn.cocos2d-x.org/tutorial/show? Id = 1205 introduction program: This tutorial will teach you how to use Cocos2d-x to make a tile-Based Map game, of course, there is a Tiled map editor. (When we were a child, most of the games in the Overlord Elementary School were based on tile maps, such as tank wars, Adventure Island,

Http://cn.cocos2d-x.org/tutorial/show? Id = 1205

Introduction

Program:

This tutorial will teach you how to use Cocos2d-x to make a tile-Based Map game, of course, there is a Tiled map editor. (When we were a child, most of the games in the Overlord Elementary School were based on tile maps, such as tank wars, adventure islands, and heaven and earth) we will create a mini game where ninja finds watermelon in the desert.

In the first part of the tutorial, I will teach you how to use Tile to create a map, how to add a map to the game, how to make the map scroll with players, and how to use the Object layer.

In the second part of the tutorial, I will show you how to create a collision-able area in a map, how to use the tile attribute, how to create a pick-up object, and how to dynamically modify a map, also, make sure that you don't want to accept the support!

If you are not ready yet, you may need to start learning from the tutorials on how to make a simple game with Cocos2d-x3.0, because we use a lot of basic concepts in this tutorial, these concepts can be obtained from the above tutorial.

Okay. Let's play with the tile map!

Create a Project Skeleton

Let's first create the skeleton of the entire project, so that all the files we need in the future can be included and run.

First, the project is named TileGame.

Next, download the game resource file. This resource package contains the following content:

  • Player sprite. This picture is similar to how to make a simple game with a Cocos2d-x3.0.

  • Some sound effects I made using the cxfr tool.

  • Some background music I made using Garage Band. (View this blog post for more information)

  • The tile set we will use -- it will actually be used together with the tile map editor, but here I want to put it, the rest will become easier.

  • Some additional "special" tile will be described later.

Once you have obtained these Resources, decompress it and drag it to the "Resources" group of your project. (Editor's note: The above audio resources are converted into mp3 formats by editors)

If everything goes well, all the files should be in your project. It's time to make our map!

Use Tile to create a map

The Cocos2d-x supports TMX format maps created using the Tile map editor. (We recommend that you select English when installing. In this tutorial, Tile is in English)

After the download is complete, double-click to run the task. Click File \ New. The following dialog box is displayed:

In the orientation section, you can select Orthogonal. For Layer format, we also select the default Base64 (zlib compressed ).

Next, set the map size. Remember, the size is in tile, not pixel. We will create a map as small as possible, so select 50*50.

Finally, you specify the width and height of each tile. The width and height you selected here are based on the size of your actual tile image. In this tutorial, the tile size is 32*32, so select 32*32 in the above options.

Next, we will import the tile set required for creating a map. Click "map" and "New Tileset..." on the menu bar, and the following window will appear:

To obtain the image, click the "Browse..." button, go to the Resources folder of the project, select the tmw_desert_spacing.png file (which we extracted), and add it to the project. It automatically fills in the name based on the file name. Then, the new image is named "effectmw_desert_spacing.png". At the same time, set the following Tile spacing and Margin to 1.

You can retain the width and height of 32*32, because the actual size of tile is also so much. As for margin and spacing, I have not found any good documentation to explain how to set these two values. My personal views are as follows:

  • When the current tile calculates its own pixel, the Margin must subtract the number of pixels (the width and height are included ). (Similar to the margin of word and css)

  • Spacing is the interval between two adjacent tile (considering both width and height) (similar to the spacing of word and css)

  

If you look at tmw_desert_spacing.png, you will see that every tile has a blank pixel boundary surrounding, which means we need to set margin and spacing to 1.

Once you select OK, you will see some tiles in the Tilesets window. Now you can create a map! In the Tilesets window, select a tile and click any position on the map. You will see the selected tile appear in the position.

Therefore, let's continue to make a map-give full play to your talents! Make sure that at least one building is added to the map, because we need something next to it for collision.


Remember some convenient shortcuts:

  • You can drag a box in the Tileset picker to select multiple tile at a time.

  • You can use the "Bucket Fill Tools" button (that is, a Bucket) on the toolbar to draw the entire map based on a reference tile.

  • You can use "View \ Zoom In..." and "View \ Zoom out..." to Zoom In and out the map.

Once you have finished drawing the map, double-click the layer on the Layers tab (now "Layer1") and rename it "Background ". Click "File \ Save" and Save the File to the resource folder of your project, and name it "TileMap. tmx ".

We will use this tmx to do some interesting things later. Well, let's load the map into the game!

Add tile maps to Cocos2d-x scenarios

Open HelloWorldScene. h and add some member variables:

1

2

3

4

cpp

private:

cocos2d::TMXTiledMap *_tileMap;

cocos2d::TMXLayer *_background;

Then, modify the HelloWorldScene. cpp file as follows:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

cpp

// Replace the init method with the following

bool HelloWorld::init()

{

if ( !Layer::init() )

{

return false;

}

std::string file = "TileMap.tmx";

auto str = String::createWithContentsOfFile(FileUtils::getInstance()->fullPathForFilename(file.c_str()).c_str());

_tileMap = TMXTiledMap::createWithXML(str->getCString(),"");

_background = _tileMap->layerNamed("Background");

addChild(_tileMap, -1);

return true;

}

Here, we call some methods of the TMXTiledMap class to load the map file we just created.

Some concise background knowledge about TMXTiledMap. It is a Node. You can set its location and proportion. The child of this map has some layers, and provides a help function that allows you to get the layer object through the layer name-we have obtained the map background through this aspect. Each layer is a subclass of SpriteSheet. The performance is considered here-but this also means that each layer can have only one tile set.


Therefore, all we do here is to point to a tile map, save the reference of the background layer, and add the tile map to the HelloWorld layer.

Okay, that's all! Compile and run the project. You will see the lower left corner of the map in the window.


Not bad! However, this is not a game! We also need three more things: a) the protagonist of the game, B) the initial position of the protagonist, and c) the ability to move the view, which is like the first view.

Now, let's solve these problems.

Tiled Object layer and tile map location

Tiled supports two types of layers: tile layer (the layer we currently use) and Object layer.

The Object layer allows you to circle areas on the map to specify events. For example, you may want to create an area where the monsters will jump out or an area where they will die as long as they enter. In this example, we will create an area to show our game protagonists.


Therefore, find the Tiled menu and click "Layer \ Add Object Group ...", Name it "Objects" and select OK. As shown in, first select the check box before the background layer. Select a rectangle at the top of the toolbar and draw a small rectangle. You will notice that it does not draw a tile, but rather a very ugly gray rectangle, which can be expanded later, so that it can contain multiple tiles or move it. We only want to select a tile for the protagonist to display. Therefore, select a tile on your map. The size of this area (the drawn rectangle) does not actually matter, because we only use the x and y coordinates.


Right-click the rectangle and choose "SpawnPoint". Then, select "OK:

(The following are some tips. To accurately place an object in the blank area of the Background, you only need to adjust the opacity of the Background layer)

We just set this type to null, and finally the Cocos2d-x will create ValueMap for us to save the relevant data, from which we can get various properties of the object, including x, y coordinates.

Save the map and return. Modify HelloWorldScene. h as follows:

1

2

3

cpp

// Inside the HelloWorld class declaration

cocos2d::Sprite *_player;

Similarly, modify HelloWorldScene. cpp with the following code:

1

2

3

4

5

6

7

8

9

10

11

12

cpp

// Inside the init method, after setting "_background ="

TMXObjectGroup *objects = _tileMap->getObjectGroup("Objects");

CCASSERT(NULL != objects, "'Objects' object group not found");

auto spawnPoint = objects->getObject("SpawnPoint");

CCASSERT(!spawnPoint.empty(), "SpawnPoint object not found");

int x = spawnPoint["x"].asInt();

int y = spawnPoint["y"].asInt();

_player = Sprite::create("Player.png");

_player->setPosition(x, y);

addChild(_player);

setViewPointCenter(_player->getPosition());

Well, let's take a moment to explain the object Layer and object group. First, you must use the getObjectGroup method of the TMXTiledMap object to obtain the object Layer (instead of the getObject method ). It returns a special TMXObjectGroup object.

Call the getObject method of the TMXObjectGroup class to obtain a ValueMap. This map contains a large amount of information about the object, including the x and y coordinate values, width, and height. In this example, We only care about the x and y coordinates. Therefore, we extract the two information and set the position of the player.

Finally, I want to set this view as the player's position. Therefore, add the following method to the file:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

cpp

void HelloWorld::setViewPointCenter(Point position) {

auto winSize = Director::getInstance()->getWinSize();

int x = MAX(position.x, winSize.width / 2);

int y = MAX(position.y, winSize.height / 2);

x = MIN(x, (_tileMap->getMapSize().width * this->_tileMap->getTileSize().width) - winSize.width / 2);

y = MIN(y, (_tileMap->getMapSize().height * _tileMap->getTileSize().height) - winSize.height / 2);

auto actualPosition = Point(x, y);

auto centerOfView = Point(winSize.width / 2, winSize.height / 2);

auto viewPoint = centerOfView - actualPosition;

this->setPosition(viewPoint);

}


Okay. Let me explain it. Assume that this function is used to set the center of camera. We allow users to pass in any x and y coordinate values on the map-but if you think about it carefully, we don't want it to be displayed-for example, we don't want the screen to go beyond the border of the map (those areas are just blank areas !)


For example, look at the figure below:

When will the center of camera be smaller than winSize. width/2 or winSize. height/2, and some views will be outside the screen? Similarly, we need to check the above boundary range, which is the same as what we are doing here.


Therefore, we regard this function as setting the central point of the camera perspective. However... That's not exactly what we want. There is a way in the Cocos2d-x to directly manipulate a Node's camera, but that makes things more complicated. Another alternative is to move the entire layer.


Take a look at the figure below:

Imagine a large map. We can see the coordinates from 0 to winSize. height/width. The center of our view is centerOfView, and we know where we want to set this center (actualPositon ). Therefore, to match the actual location with the view center, we only need to move the map to the lower left corner!

This can be achieved by subtracting the actual position from the central position of the view, and then setting the HelloWorld layer to that point.

Alas! Too many theories-Let's look at the reality! Compile and run the project. If everything goes well, you will see that ninja is in the scenario, but the perspective is also moved.

Make ninja mobile

We already had a good start, but our ninja just stood there! This is not like a real Ninja!

Let's make the ninja work. Just move the ninja to the place where the user clicks it. Add the following code to HelloWorldScene. cpp:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

cpp

// Inside init method

auto listener = EventListenerTouchOneByOne::create();

//lambda expression: advanced feature in C++ 11

listener->onTouchBegan = [&](Touch *touch, Event *unused_event)->bool { return true; };

listener->onTouchEnded = CC_CALLBACK_2(HelloWorld::onTouchEnded, this);

this->_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);

//add following method

void HelloWorld::setPlayerPosition(Point position)

{

_player->setPosition(position);

}

void HelloWorld::onTouchEnded(Touch *touch, Event *unused_event)

{

auto touchLocation = touch->getLocation();

touchLocation = this->convertToNodeSpace(touchLocation);

auto playerPos = _player->getPosition();

auto diff = touchLocation - playerPos;

if (abs(diff.x) > abs(diff.y)) {

if (diff.x > 0) {

playerPos.x += _tileMap->getTileSize().width;

}

else {

playerPos.x -= _tileMap->getTileSize().width;

}

}

else {

if (diff.y > 0) {

playerPos.y += _tileMap->getTileSize().height;

}

else {

playerPos.y -= _tileMap->getTileSize().height;

}

}

if (playerPos.x<=_tileMap->getMapSize().width * _tileMap->getTileSize().width) &&

playerPos.y<=_tileMap->getMapSize().height * _tileMap->getTileSize().height) &&

playerPos.y >= 0 &&

playerPos.x >= 0)

{

this->setPlayerPosition(playerPos);

}

this->setViewPointCenter(_player->getPosition());

}

First, set the event listener in the init method to bind the onTouchesBegan and onTouchEnded methods of the listener. If onTouchEnded can be used, onTouchesBegan must return true. Here we only need onTouchesBegan to play the role of return true, so the new feature of c ++ 11 is directly written to support the lambda expression supported by the Cocos2d-x3.0, not too familiar to search for it. In this case, the listener will call the onTouchBegan anonymous method and the onTouchEnded method (note that the onTouchesBegan and onTouchesEnded methods in the singular form instead of the plural form)

You may ask why I want to talk about this, because we use the onTouchesBegan and onTouchesEnded methods in "How to make a simple game with a Cocos2d-x3.0. You can use either of the two methods in this tutorial. However, I want to introduce a new method because it has two advantages:

  • "You don't need to deal with std: vector &, Division of Touch and scheduling work is all done by the Cocos2d-x framework. You only get one Touch for each method call. "

  • "You can return true in onTouchBegan so that the current layer can receive the touch Event Callback. Besides, the move/ended/canceled callback is returned only when you return true. This frees you from complicated multi-touch judgments.

In any case, in our onTouchEnded, we convert the screen touch coordinates to the local coordinates.

This is because the touch position only tells us the coordinates (such as 100,100) of the screen viewport ). However, we have rolled the map, which may actually correspond to (800,800) of the map ). Therefore, call this method to determine the touch offset based on the position of the current layer.

Next, the difference between the touch point and the player is calculated. We must select a direction based on the touch position. Therefore, first, we need to calculate whether to move up or down or left or right. Then, we compare positive and negative values to determine the specific direction.

Correspondingly, we can adjust the player position and set the player position to the center position of the viewport. This is used in the previous section.

Update: note that we have to add a security check to ensure that our player is not moved out of the map! This is pointed out by Geek & Dad. Thank you!

Compile and run! Now you can click the mouse and move it wherever you want!

Where to go?

This is only part of this tutorial. At this point, you should understand the basics of creating a tile map and how to import it into the game.

Here is the complete source code we have used so far: TileGame1.zip

Next, let's look forward to the second part of the tutorial! There, I will teach you how to add collision detection in the map, if you make our ninja run along the walls happily!

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.