## Cocos2d-x Tutorial Series: Handling Touch and Mouse Input

3. October 2014

In this part of the Cocos2d-x tutorial series we are going to look at how to handle touch and mouse events .  First you should be aware that by default Cocos2d-x treats a mouse left click as a touch, so if you only have simple input requirements and don’t require multi-touch support ( which is remarkably different to perform with a single mouse! ), you can simply implement just touch handlers.  This part is going to be code heavy, as we actually have 3 different tasks to cover here ( touch, multi-touch and mouse ), although all are very similar in overall behavior.

Let’s jump in with an ultra simple example.  Once again, I assume you’ve done the earlier tutorial parts and already have an AppDelegate.

## Handle Touch/Click Events

TouchScene.h

#pragma once

#include "cocos2d.h"

class TouchScene : public cocos2d::Layer
{
public:
static cocos2d::Scene* createScene();
virtual bool init();

virtual bool onTouchBegan(cocos2d::Touch*, cocos2d::Event*);
virtual void onTouchEnded(cocos2d::Touch*, cocos2d::Event*);
virtual void onTouchMoved(cocos2d::Touch*, cocos2d::Event*);
virtual void onTouchCancelled(cocos2d::Touch*, cocos2d::Event*);
CREATE_FUNC(TouchScene);

private:
cocos2d::Label* labelTouchInfo;
};

TouchScene.cpp

#include "TouchScene.h"

USING_NS_CC;

Scene* TouchScene::createScene()
{
auto scene = Scene::create();
auto layer = TouchScene::create();

return scene;
}

bool TouchScene::init()
{
if ( !Layer::init() )
{
return false;
}

labelTouchInfo = Label::createWithSystemFont("Touch or clicksomewhere to begin", "Arial", 30);

labelTouchInfo->setPosition(Vec2(
Director::getInstance()->getVisibleSize().width / 2,
Director::getInstance()->getVisibleSize().height / 2));

auto touchListener = EventListenerTouchOneByOne::create();

touchListener->onTouchBegan = CC_CALLBACK_2(TouchScene::onTouchBegan, this);
touchListener->onTouchEnded = CC_CALLBACK_2(TouchScene::onTouchEnded, this);
touchListener->onTouchMoved = CC_CALLBACK_2(TouchScene::onTouchMoved, this);
touchListener->onTouchCancelled = CC_CALLBACK_2(TouchScene::onTouchCancelled, this);

return true;
}

bool TouchScene::onTouchBegan(Touch* touch, Event* event)
{
labelTouchInfo->setPosition(touch->getLocation());
labelTouchInfo->setString("You Touched Here");
return true;
}

void TouchScene::onTouchEnded(Touch* touch, Event* event)
{
cocos2d::log("touch ended");
}

void TouchScene::onTouchMoved(Touch* touch, Event* event)
{
cocos2d::log("touch moved");
}

void TouchScene::onTouchCancelled(Touch* touch, Event* event)
{
cocos2d::log("touch cancelled");
}

Then if you run it, when you perform a touch or click:

As you can see, where you touch on the screen a text label is displayed.  Looking in the background of that screenshot you can see touch moved events are constantly being fired and logged.  Additionally touch ended events are fired when the user removes their finger ( or releases the mouse button ).

Now let’s take a quick look at the code.  Our header file is pretty straight forward.  In addition to the normal methods, we add a quartet of handler functions for handling the various possible touch events.  We also add a member variable for our Label used to draw the text on the screen.

In the cpp file, we create the scene like normal.  In init() we create an EventListener of type EventListenerTouchOneByOne, which predictably handles touches, um, one by one ( as opposed to all at once, which we will see later ).  We then map each possible event, touch began, touch end, touch cancelled and touch moved, to their corresponding function handler using the macro CC_CALLBACK_2, passing  the function to execute and the context ( or target ).  This too will make sense later, so hold on there.  One thing to watch out for here, and one point of confusion for me, onTouchBegan has a different signature than every other event, returning a bool.  I am not entirely certain why this one event is handled differently, seems like a bad idea to me personally, but there may be a good design reason I am unaware of.

The last thing we do is register our EventListener to receive events.  This is done with a call to Node’s protected member _eventListener.  We call addEventListenerWithSceneGraphPriority(), which basically means we want this event to be updated as much as possible.  We will see an example of setting a different priority level later on.

What's this CC_CALLBACK_2 black magic?

I'm generally not a big fan of macro usage in C++. I generally believe they lead programmers to eventually turn their libraries into meta-programming languages and ultimately obfuscate the underlying code in the name of clarity. This however, is one of the exceptions to the rule. CC_CALLBACK_2, and the entire CC_CALLBACK_ family is simply a wrapper around some standard C++ code, specifically a call to std::bind. Here is the actual macro code:

#define CC_CALLBACK_0(__selector__,__target__, ...) std::bind(&__selector__,__target__, ##__VA_ARGS__)
#define CC_CALLBACK_1(__selector__,__target__, ...) std::bind(&__selector__,__target__, 
std::placeholders::_1, ##__VA_ARGS__)
#define CC_CALLBACK_2(__selector__,__target__, ...) std::bind(&__selector__,__target__, 
std::placeholders::_1, std::placeholders::_2, ##__VA_ARGS__)
#define CC_CALLBACK_3(__selector__,__target__, ...) std::bind(&__selector__,__target__, 
std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, ##__VA_ARGS__)

Basically std::bind is binding for binding parameters to a function. The std::placeholders are ultimately the number of parameters your function expects. So for example, when you call CC_CALLBACK_2, you are saying that function takes two parameters, in this case a Touch* point and an Event* pointer. Similarly CC_CALLBACK_1 would expect the provided function to take a single parameter. This kind of code is incredibly common in C++11, it's incredibly ugly, hard to read and grok and it's easy to mistype. In these cases, macro use shines. Just be aware of what it is the macro you are calling does. Each time you encounter a macro in code, I recommend you right click and "Go to Definition" or CTRL+Click if in XCode, to see what it actually does, even if it doesn't make complete sense.

In most of the touch handlers, we simply log that the event occurred.  In the event of a touch starting ( or click beginning ) we update the position of the label to where the user clicked and display the string “You Touched Here”.

Now let’s take a look at an example that uses lambda’s instead.  This example also goes into a bit more detail of what’s in that Touch pointer we are being passed.  The header file is basically the same, except there are no onTouch____ functions.

## Handling Touch Events using Lambdas and dealing with Touch coordinates

TouchScene.cpp

#include "TouchScene.h"

USING_NS_CC;

Scene* TouchScene::createScene()
{
auto scene = Scene::create();
auto layer = TouchScene::create();

return scene;
}

bool TouchScene::init()
{
if ( !Layer::init() )
{
return false;
}

auto sprite = Sprite::create("HelloWorld.png");
sprite->setPosition(Vec2(Director::getInstance()->getVisibleSize().width / 2,
Director::getInstance()->getVisibleSize().height / 2));

// Add a "touch" event listener to our sprite
auto touchListener = EventListenerTouchOneByOne::create();
touchListener->onTouchBegan = [](Touch* touch, Event* event) -> bool {

auto bounds = event->getCurrentTarget()->getBoundingBox();

if (bounds.containsPoint(touch->getLocation())){
std::stringstream touchDetails;
touchDetails << "Touched at OpenGL coordinates: " <<
touch->getLocation().x << "," << touch->getLocation().y << std::endl <<
"Touched at UI coordinate: " <<
touch->getLocationInView().x << "," << touch->getLocationInView().y << std::endl <<
"Touched at local coordinate:" <<
event->getCurrentTarget()->convertToNodeSpace(touch->getLocation()).x << "," <<
event->getCurrentTarget()->convertToNodeSpace(touch->getLocation()).y << std::endl <<
"Touch moved by:" << touch->getDelta().x << "," << touch->getDelta().y;

MessageBox(touchDetails.str().c_str(), "Touched");
}
return true;
};

return true;
}

Now when you run it:

In this example, the touch event will only fire if the user clicked on the Sprite in the scene.  Notice the first line in the onTouchBegan handler I call event->getCurrentTarget()?  This is where the context becomes important.  In the line:

Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(touchListener,sprite);

The second parameter, sprite, is what determines the target of the Event.  The target is passed as a Node but can be cast if required.

Lambda?

Lambda's are a new feature of C++ and they are probably something you will love or hate. If you come from C++ or C# you will probably find them long over due, I certainly do!
Lambda is a scary sounding expression coming from the scary looking symbol Λ. In the world of mathematics, Lambda calculus basically gives math the ability to define functions, something we as programmers can certainly appreciate. In the world of programming, it's nowhere near as scary, a lamdba expression can also be thought of as an anonymous function. In simple terms, it allows you to create a nameless function where you need it. As you can see from this example, it allows you to put event handling logic where it makes most sense, instead of spliting it out into a seperate function. It is also a godsend when you want to pass a function as a parameter, a very common task in the C++ standard libraries.
The syntax of C++ lambda's is pretty ugly, but they are certainly a valuable addition to the language. Most importantly, they can often make your code easier to express and as such, easier to comprehend and maintain. Learn to love the lamdba and the lambda will learn to love you. Maybe.

In this example, we use the target node to only handle clicks that happen within the bounds of our Sprite Node.  This is done by testing if the touch location is within the bounding box of the node.  If it is, we display a number of details in a message box.  Remember back in this tutorial part where I said there are multiple coordinate systems, this is a perfect example.  As you can see from the message box above, getLocation() and getLocationInView() return different values, one relative to the top left corner of the screen, while the other is relative to the bottom left corner of the screen.

Sometimes as well you want to know where the click occurred relative to the node.  Such as in the sample above, the local coordinate is the position the click occurred relative to the node’s origin.    In order to calculate this location we use the helper function convertToNodeSpace().  One final thing you may notice is I registered the EventListener with Director() instead of _eventListener.  This was the old way of doing things and I did it this way for a couple reasons.  First, to show that you can.  Second, because _eventListener is a protected member, I would only have access to it if I derived my own Sprite object.

Now let’s take a look at a multi-touch example.

## Dealing with Multi-touch

Multi-touch works pretty much the same way, just with a separate set of event handlers.  There are a few catches however.  The big one is iOS.  Out of the box, Android just works.  iOS however requires you to make a small code change to enable multitouch support.  Don’t worry, it’s a simple process.

In your project, locate the directory /proj.ios_mac/ios and open the file AppController.mm.  Then add the following line:

Simply add the line [eaglView setMultipleTouchEnabled:YES]; somewhere after the creation of eaglView.  Now multitouch should work in your iOS application, let’s look at some code:

MultiTouchScene.h

#pragma once

#include "cocos2d.h"

class MultiTouch : public cocos2d::Layer
{

public:
static cocos2d::Scene* createScene();

virtual bool init();
CREATE_FUNC(MultiTouch);
private:
const static int MAX_TOUCHES = 5;

protected:
cocos2d::Label* labelTouchLocations[MAX_TOUCHES];

};

MultiTouchScene.cpp

#include "MultiTouchScene.h"

USING_NS_CC;

Scene* MultiTouch::createScene()
{
auto scene = Scene::create();
auto layer = MultiTouch::create();

return scene;
}

bool MultiTouch::init()
{
if ( !Layer::init() )
{
return false;
}

// Create an array of Labels to display touch locations and add them to this node, defaulted to invisible
for(int i= 0; i < MAX_TOUCHES; ++i) {
labelTouchLocations[i] = Label::createWithSystemFont("", "Arial", 42);
labelTouchLocations[i]->setVisible(false);
}

auto eventListener = EventListenerTouchAllAtOnce::create();

//  Create an eventListener to handle multiple touches, using a lambda, cause baby, it's C++11
eventListener->onTouchesBegan = [=](const std::vector<Touch*>&touches, Event* event){

// Clear all visible touches just in case there are less fingers touching than last time
std::for_each(labelTouchLocations,labelTouchLocations+MAX_TOUCHES,[](Label* touchLabel){
touchLabel->setVisible(false);
});

// For each touch in the touches vector, set a Label to display at it's location and make it visible
for(int i = 0; i < touches.size(); ++i){
labelTouchLocations[i]->setPosition(touches[i]->getLocation());
labelTouchLocations[i]->setVisible(true);
labelTouchLocations[i]->setString("Touched");
}
};

return true;
}

Here is the code running on my iPad with multiple fingers touched:

Granted, not the most exciting screen shot ever, but as you can see, each location the user touch, a label is printed.  Let’s take a quick look at the code and see what’s happening.  At this point, most of it should be pretty familiar, so let’s just focus on the differences.

First you will notice I added an array of Labels MAX_TOUCH in size.  I chose 5 as frankly, that seems to be the limit of what I could register on iPad.  I had it set to 10, but it never registered more than 5, so 5 it was!  Truth of the matter is, I can’t really imagine a control scheme that used more then 5 touches being all that useful, so 5 touches seems like a reasonable limitation, even though I’m pretty certain the hardware can handle more.

In our init() we start off by allocating each of our labels and setting their initial visibility to invisible.  Then we create our EventListener, this time we create an EventListenerTouchAllAtOnce because we want to, well, get all the touch events at the same time.  Instead of handling onTouchBegan, we instead handle onTouchesBegan, which takes a std::vector ( careful here, as cocos2d has it’s own vector class… the peril of using namespace abuse! ) of Touch* as well as an Event*.

In the event of touch(es), we first loop through all of our labels and set them to invisible.  Then for each touch in the touches vector, we move a label to that position and make it visible.  Once again we register the EventListener with our node’s _eventDispatcher.

So, we’ve covered touch and multi-touch, what about when you want to use the mouse?  Amazingly enough there are users out there with mice with more than a single button after all! ;)

## Handling the Mouse

At this point you can probably guess the code I am about to write, as the process is remarkably similar, but let’s go through it anyways.  I wont bother with the .h file, there’s nothing special in there.

MouseScene.cpp

#include "MouseScene.h"

USING_NS_CC;

cocos2d::Scene* MouseScene::createScene()
{
auto scene = Scene::create();
auto layer = MouseScene::create();

return scene;
}

bool MouseScene::init()
{
if ( !Layer::init() )
{
return false;
}

auto listener = EventListenerMouse::create();
listener->onMouseDown = [](cocos2d::Event* event){

try {
EventMouse* mouseEvent = dynamic_cast<EventMouse*>(event);
mouseEvent->getMouseButton();
std::stringstream message;
message << "Mouse event: Button: " << mouseEvent->getMouseButton() << "pressed at point (" <<
mouseEvent->getLocation().x << "," << mouseEvent->getLocation().y << ")";
MessageBox(message.str().c_str(), "Mouse Event Details");

}
// Not sure what kind of event you passed us cocos, but it was the wrong one
return;
}
};

listener->onMouseMove = [](cocos2d::Event* event){
// Cast Event to EventMouse for position details like above
cocos2d::log("Mouse moved event");
};

listener->onMouseScroll = [](cocos2d::Event* event){
cocos2d::log("Mouse wheel scrolled");
};

listener->onMouseUp = [](cocos2d::Event* event){
cocos2d::log("Mouse button released");
};

return true;
}

Now run it, scroll the mouse wheel a couple times, click and you will see:

Yeah… not really exciting either.  As you can see, when you click a mouse the button is returned as a number.  Left button is 0, middle is 1, right is 2, etc.  The code is all very familiar except we use a EventListenerMouse this time and handle onMouseDown, onMouseUp, onMouseMove and onMouseScroll.  The only other thing of note is you need to cast the provided Event pointer to a EventMouse pointer to get access to the mouse details.

With the exception of gestures, that should pretty much cover all of your mouse and touch needs.  Gesture’s arent actually supported out of the box, but extensions exist.  Additionally, all mouse and touch events contain delta information as well as data on the previous touch/click, which should make rolling your own fairly simple.

## Cocos2d-x Tutorial Series: Basic Sprites, Positioning, Parenting and Coordinate Systems

1. October 2014

Now that we have Cocos2d-x installed and configured and our project created, we are going to take a look at basic graphics operations.  This tutorial assumes you ran through the prior part and created a project already.  I am going to assume you have a working AppDelegate, so I will only focus on creating a new scene object.   The only changes you should have to make are to change your delegate to #include a different file and change the type of scene you call createScene() on.

Ok, let’s jump right in with with a simple example.  First we are going to need an image to draw.  Personally I am going to use this somewhat… familiar image:

It’s 400x360, with a transparent background named decepticon.png.  Of course you can use whatever image you want.  Just be certain to add the image to the resources directory of your project.

Ok, now the code to display it.

GraphicsScene.h

#pragma once

#include "cocos2d.h"

class GraphicsScene : public cocos2d::Layer
{
public:
static cocos2d::Scene* createScene();
virtual bool init();
CREATE_FUNC(GraphicsScene);
};

GraphicsScene.cpp

#include "GraphicsScene.h"

USING_NS_CC;

Scene* GraphicsScene::createScene()
{
auto scene = Scene::create();
auto layer = GraphicsScene::create();

return scene;
}

bool GraphicsScene::init()
{
if ( !Layer::init() )
{
return false;
}

auto sprite = Sprite::create("decepticon.png");
sprite->setPosition(0, 0);

return true;
}

Now when you run this code:

Hmmm, probably not exactly what you expected to happen, but hey, congratulations, you just rendered your first sprite!

So, what exactly is happening here?  Well after we created our sprite we called:

sprite->setPosition(0, 0);

This is telling the sprite to position itself at the pixel location (0,0).  There are two things we can take away from the results.

1- The position (0,0) is at the bottom left corner of the screen.

2- By default, the position of a sprite is relative to it’s own center point.

Which way is up?

One of the most confusing things when working in 2D graphics is dealing with all the various coordinate systems.  There are two major approaches to dealing with locations in 2D, having the location (0,0) at the top left of the screen and having the location (0,0) at the bottom left of the screen.  This point is referred to as the Origin.  It is common for UI systems, the most famous of which being Windows, to set the origin at the top left of the screen.  It is also most common for graphics files to store their image data starting from the top left pixel, but by no means is this universal.  On the other hand OpenGL and most mathematicians treat the bottom left corner of the screen as the origin.  If you stop and think about it, this approach makes a great deal of sense.

Think back to your high school math lessons ( unless of course you are in high school, in which case pay attention to your math lessons! ) and you will no doubt have encountered this graphic.

This is a graphic of the Cartesian plane and it is pretty much the foundation of algebra.  As you can clearly see, the positive quadrant ( the quarter of that graph with both positive x and y values ) is in the top right corner.  Quite clearly then, to a mathematician the value (0,0) is at the bottom left corner of the top right quadrant.

There are merits to both approaches of course, otherwise there would be only one way of doing things!

This will of course lead to some annoying situations, where one API for example delivers touch coordinates in UI space, relative to the top left corner, or when you load a texture that is inverted to what you actually wanted.

Fortunately, Cocos2d-x provides functionality to make these annoyances a little bit less annoying.  Just be aware going forward, that coordinate systems can and do change!  Also be aware, unlike some frameworks, Cocos2d-x does *NOT* allow you to change the coordinate system.  The origin in Cocos2d-x is always at the bottom left corner.

Sometimes positioning relative to the middle can be ideal, especially when dealing with rotations.  However, sometimes you want to position relative to another point, generally using the top left or bottom left corner.  This is especially true if for example you want to, say… align the feet of a sprite to the top of a platform.  Changing the way a sprite ( or any Node ) is positioned is extremely simple in Cocos2d-x.  This is done using something called an Anchor Point.  Simply change the code like so:

   auto sprite = Sprite::create("decepticon.png");
sprite->setAnchorPoint(Vec2(0, 0));
sprite->setPosition(0, 0);

And presto!

Now our sprite is positioned relative to it’s bottom left corner.  However, setAnchorPoint() might not take the parameters you expect it to.  Yes, you are passing it in x and y coordinates that represent the location on the sprite to perform transforms relative to.  However, we are dealing with yet another coordinate system here, sometimes referred to as Normalized Device Coordinates (NDC).  These values are represented by two numbers, one for x and one for y, from 0 to 1, and they are a position within the sprite.

Sprite?

If you are new to game programming, the expression "sprite" might be new to you.   The expression was termed way back in 1981 by a Texas Instruments engineer describing the functionality of the TMS9918 chip.  Essentially a sprite was a bitmap image with hardware support to be movable.  Early game hardware could handle a few sprites, often used to represent the player and enemies in the world.  In real world examples, in Super Mario Brothers, Mario, the mushrooms, coins and such would be sprites.

These days, “Sprite” is basically a bitmap image ( or portion of a bitmap, we’ll see this later ) along with positional information.  These days the concept of hardware sprites doesn’t really exist anymore.

I am making this sound entirely more complicated than it actually is.  Just be aware the value (0,0) is the bottom left corner of the sprite, (1,1) is the top right of the sprite and (0.5,0.5) would be the mid point of the sprite.  These coordinate system is extremely common in computer graphics and is used heavily in shaders.  You may have heard of UV coordinates, for positioning textures on 3D objects.  UV coordinates are expressed this way.

Therefore, if you want to position the sprite using it’s mid point, you would instead do:

sprite->setAnchorPoint(Vec2(0.5, 0.5));

Another important concept to be aware of is a sprite’s positioning is relative to it’s parent.  Up until now our sprite’s parent was our layer, let’s look at an example with a different Node as a parent.  This time, we are going to introduce another sprite, this one using this image:

It’s a 200x180 transparent image named autobot.png.  Once again, add it to the resources folder of your project.  Now let’s change our code slightly:

bool GraphicsScene::init()
{
if ( !Layer::init() )
{
return false;
}

auto sprite = Sprite::create("decepticon.png");
auto sprite2 = Sprite::create("autobot.png");
sprite->setAnchorPoint(Vec2(0.0,0.0));
sprite2->setAnchorPoint(Vec2(0.0, 0.0));

sprite->setPosition(100, 100);
sprite2->setPosition(0, 0);

return true;
}

And when we run this code:

There’s a couple very important things being shown here.  Until this point, we’ve simply added our Sprite to our Layer, but you can actually parent any Node to any other Node object.  As you can see, both Sprite and Layer inherit from Node, and Node’s form the backbone of a very important concept called a scene graph.

One very important part of this relationship is the child’s position is relative to it’s parent.  Therefore sprite2’s (0,0) position is relative to the origin of sprite1 ( not the anchor, origin and anchor are not the same thing and only anchors can be changed ), so moving sprite2 also moves sprite1.  This is a great way to create hierarchies of nodes, for example you could make a tank out of a sprite for it’s base and another representing it’s turret.  You could then move the base of the tank and the turret would move with it, but the turret itself could rotate independently.

Scenegraph

A scenegraph is a pretty simple concept. It's basically the data structure used to hold the contents of your game. In Cocos2d-x, the scene graph is simply a tree of Node dervived objects. There exists Scene node that is pretty much an empty node with the intention of adding other nodes to it. You then add various nodes to it, nodes to those nodes, etc. An overview of how you can use this system in Cocos2d-x is available here.

So what do you do when you want to get a node’s position in the world, not relative to it’s parent?  Fortunately Node has that functionality built in:

Vec2 worldPosition = sprite2->convertToWorldSpace(sprite2->getPosition());

worldPosition’s value would be (100,100).  There is also an equivalent function for getting a world space coordinate in node space.

So, in summary:

• The world is composed of Node objects, including Scene, Sprite and Layer
• The screen origin is at the bottom left corner of the screen, always
• Nodes are positioned, scaled and rotated relative to their anchor point
• The default anchor point of a sprite is (0.5,0.5), which is it’s mid point
• Anchor points are defined with a value from (0,0) to (1,1), with (0,0) being bottom left corner and (1,1) being the top right
• Nodes can have other nodes as children.  When the parent moves, the child moves with it
• Child node’s origin is the bottom left corner of their parent
• Anchor point and origin are not the same thing
• Sprites can only have other sprites as children ( EDIT – No longer true!  There can however be some performance ramifications. Will discuss later )

So that covers the basics of dealing with graphics.  Now that we know how to position and parent nodes, next time we will look at something a bit more advanced.

## Cocos2d-x Tutorial Series: Installation, Creating a Project and Hello World

29. September 2014

Welcome to the GameFromScratch.com Cocos2d-x tutorial series.  Cocos2d-x is a cross platform, C++ based port of the popular Cocos2D ObjectiveC game development library. Using the most recent version of Cocos2D-x you can target Windows, Mac, Linux, iOS and Android.  Previous versions enabled you to target even more targets including Blackberry and Tizen.  The history of Cocos2D-x is actually very important, as it factored in many of the design decisions that the library has taken.

This series will walk through the all aspects of using Cocos2d-x to create a game.  This particular part covers the process of getting Cocos2d-x installed, creating an initial project and looks at a bare bones Hello World example.

## Cocos2D History

As I mentioned earlier, the history of Cocos2D is fairly important to understanding how it works, so we are going to start of with a quick, hopefully not-boring, history lesson.  I promise you, this will be the only history lesson in this entire series!  Unless of course I do more of them…  If you want a more thorough history, you can always check out the wiki.

Ok… history time.

Way back in 2008, Cocos came to be, named after the town of Los Cocos, Argentina, in case you were wondering where exactly the name came from.  It started from a gathering of Python developers in, you guessed it, Los Cocos.  As you may be able to guess from the fact it was started by a bunch of Python developers, Cocos started off being written in Python.

Then came along this little phone named the iPhone, and a version of Cocos2D was ported to ObjectiveC for use on iOS, the aptly named cocos2d-iphone.  A number of Cocos2d-iphone developed apps started appearing on the iPhone, including StickWars, which hit number 1 on the App Store.  Now we hit the fast forward button on history and see that Cocos2d is ported to a number of platforms.

One of those ports was of course Cocos2d-x, which was a port of Cocos2D to C++, the subject of our tutorial here.  Cocos2d-x itself also spawned a number of ports, including HTML and XNA.  Along the way a number of tools were developed as well, including an editor named CocosStudio (itself the spawn of a number of child projects ) and CocosCodeIDE and IDE for Lua and JavaScript scripting in Cocos2d-x.

So, why does this all matter?

Well, it’s important that you be aware that Cocos2d-x is a port of an Objective-C library which itself was a port of a Python library.  Each language and platform has had an effect on the development of Cocos2d-x, for better or worse.  You will run into some concepts and think “why the hell did they do this?”.  More often than not, it’s Cocos2D’s history that provides the reason.

One final important thing to realize with Cocos2d-x, a number of the most active developers behind the project are not primarily English speakers.  Cocos2D-x is extremely popular in China for example.  This is by no means a negative, but we aware sometimes language can be a bit of a barrier when looking for help and reading documentation.

## What Version are you using?

At the point I am writing this, I am using Version 3.3beta 0 to create tutorials, and as new versions are released I will try to stay with the most recent version.  This is because I am trying to future proof this series as much as possible.  In all honesty, I know this is going to be quite annoying as well, when I created by cocos2d-html5 tutorial series, the number one problem was version changes.  Cocos2d-x is a library that get’s refactored quite a bit, so if you are far in the future and some code I provided doesn’t work, this is probably why.  Always make sure to read the comments at the bottom of each part, it may contains clues to the problem you are facing.

So then, what version should you use?  That answer is a bit trickier.  You have a choice between Cocos2d 2.x, 3.0 or 3.x right now.  The 2.x version is obviously the older version and less actively developed, if at all (edit – according to this thread, 2.x is no longer being supported).  That said, 2.x also supports the most platforms, including Windows Phone, Marmalade, Tizen, Blackberry and more.  Additionally, as of writing, every single book targets 2.x.  3.2 is the (currently) stable release of the most current version, while 3.x is the development version.

Again, I will be using the most current version as I go, and if history has taught me anything, this is going to lead to tons of issues! ;)  Warning, Here be dragons!

## Setting Up Cocos2D-x

In order to get started with Cocos2d-x, you need to have a couple things installed already, depending on platform you are developing on.

Obviously you need a C++ compiler.  If you are working on Windows, Visual Studio 2013 is currently the recommended version.  You can download a free version named Visual Studio Express for Windows Desktop  ( note, there is also a version called Visual Studio Express for Windows, you do NOT want this version… yeah, brilliant naming by Microsoft there eh? ).  Of course if you have a complete version installed it will work fine as well.  You can also use older versions of Visual Studio, back to 2010 I believe, but this series will assume you are using the most recent version.

On Mac OS, Xcode is the obvious solution.  It’s also free, so that’s nice.  As of writing Xcode 6 is currently in late beta, but will work just fine.  Xcode 5 should also work just fine.  Personally I am not a huge Xcode fan and use AppCode for development on Mac, but it is not a free tool.  You may see it on occasion in screenshots, so I figured I would put it out there.  By default Xcode does not install the command line tools, so I would install those as well, you can find instructions here and official documentation here.

You also need to have Python installed.  Don’t worry, Python isn’t used to code in Cocos2d-x, but some of the tools require it, including the tool you use to create your project, so obviously this install is pretty important.  Another important note, so I’m going to use bold and shout at you for a second.  YOU NEED TO INSTALL PYTHON 2.7x!  The newest version, Python 3.x does not work and you will be wasting your time.  So go ahead download Python 2.7.x here.  On Windows you want to make sure Python is added to the PATH environment variable.  If it isn’t, you can get instructions here.

Finally if you are intending to develop for Android, you need to have a version of the Android SDK, ANT and Android NDK installed.  You need at least version 9 of the NDK ( 10 is the current as of writing.  EDIT – NDK 10 currently doesn’t work!  Read here for details.  Here for the ticket.  There is a work-around, but using NDK 9 is probably your easiest bet ) to work with Cocos2d-x.  Now to make life slightly more complicated, if you are on Windows, the Android NDK also requires Cygwin 1.7 or higher to be installed.  Fortunately, Cygwin has no further requirements.  When downloading the Android SDK, do not download the ADT package, but instead scroll further down the page and install using the “Get the SDK for an existing IDE” link.  As an FYI, the SDK is the Java SDK along with the tools needed for Android development, the NDK is the C++ toolchain for Android development, while Ant is a Java build system.

Please note, Cocos2d-x and be used with other IDE’s such as Eclipse or Qt Creator, but I will not be covering the process in this tutorial.

## Creating a Cocos2d-x project

Ok, now that you’ve got everything installed and configured, it’s time to create a project.  Open up a terminal window or command line and change to the directory you extracted cocos2d-x.

#### MacOS  Cocos2d Config and New Project Instructions:

Enter:

./setup.py

source ~/.profile

cocos new -l cpp -p com.gamefromscratch.gamename -d ~/Documents/Projects/cocos2d gamename

#### Windows Cocos2d Config and New Project Instructions:

Open a command prompt and CD to the directory you extracted Cocos2D to.  Run the command:

python setup.py

If you get an error about not being able to find Python, that PATH is not configured correctly.  Depending if you have certain environment variables set or not, the install may now ask you the install directory of your Android NDK, SDK as well as Ant, provide them.  If you’ve not installed the NDK and SDK before now, do so before performing this step.

The next step depends on your operating system version.  If you are running Windows XP ( and possibly Vista ), you now need to restarted your computer for the changes to take effect.  If you are running Windows 7 or 8.x, simply close your command prompt and open a new one.

Now type:

cocos new -l cpp -p com.gamefromscratch.gamename -d C:\path\to\game\here gamename

#### Creating a New Project:

The tool to create cocos projects is “cocos” and it resides in [cocosSDKfolder]/tools/cocos2d-console/bin.  -l is an L by the way, this is where you specify the language for the project you want to create.  The options are cpp and lua currently, in this case we want cpp.  -p is for specifying the package, mostly for Android I assume.  This uses Java’s standard reverse domain name format.  Don’t worry if you don’t have a website, make something up.  The -d parameter is the directory where you want to create the project.

Now that our project is (hopefully!) created, lets take a look at what it’s created for us.

Here you can see it has created a number of key directories for you, we will take a closer look at each one.

Each folder prefixed with proj. is where project files and platform specific code goes, be it android, iOS and Mac, linux, Windows or Windows Metro ( or.. what was previously known as Metro ).

The cocos2d folder however is where the cocos SDK itself is copied.  This is a complete copy of Cocos2d, including docs, libraries, headers, etc.  Just a warning, this folder is 250MB in size and will be created for each cocos2D project you create using cocos new!  You can set up your projects to use a common install of cocos2d-x, by specifying the engine path when calling cocos new.  Just be aware, if you are tight on space and are going to be making a number of cocos2d-x projects, you may want to look into this further.

The resources folder is a common repository for all the various assets that your game will use, such as graphics, sound, etc.  The Classes folder is perhaps most important of all, this is where your non platform specific code goes!  Right now the contents should look like:

These code files create a simple application to get you started, although we are ultimately going to replace the contents.  The expression AppDelegate comes from Mac programming, so if you are a Windows or Linux developer, it might be a bit alien to you.  An AppDelegate is a helper object that goes with the main window and handles events common to applications such as starting up, minimizing and closing.  You won’t really spend much time here, that instead is where the Scene file comes in.  We will look at code shortly so each piece will make a bit more sense.

Now let’s look at the platform specific portions for both win32 and ios_mac.

win32:

ios_mac:

As you can see, each folder contains all the platform specific code, resources and most importantly, project files for each platform.  In the case of ios_mac, it further contains platform specific folders for each platform.

All platforms have their own unique entry point ( main, WinMain, etc ) and different ways of handling different things.  Most of this is just relevant on start up and cocos2d-x takes care of this for you.  However at some point in the future you may need to add platform specific code, such as perhaps an ad network that only works on iOS.  This is where you would add platform specific code.  That said, 99% of your game logic should be put in the common Classes folder.  This make’s it so you can write your code in one platform, then simply open up the project files for another platform and run your game.  This is how you are able to handle many platforms with a single code base using cocos2d-x.

#### Getting Started — MacOS/XCode

To get started developing on MacOS, double click the .xcodeproj in the folder proj.ios_mac.  This should automatically load Xcode for you.  Now at the top bar you should be able to select which project you want, iOS or Mac.  As iOS requires the simulator or a device to execute, initially developing on the Mac can be a great deal quicker.

#### Getting Started — Windows/Visual Studio

To get started developing on Windows, double click the .sln file in the folder proj.win32.  This will load Visual Studio for you.  Simply press Play (Local Windows Debugger) to start the compilation process:

Once you’ve selected, simply click the Play icon.  Your project will now compile and a few minutes later you should see:

If you are new to C++, don’t worry, the first compilation is always the nastiest.  From now on when you press play, the compilation should be many times faster.

You can also run directly from the terminal using the cocos utility, like so:

Use -p ios to run iOS.  This command requires you to have installed the command line tools mentioned earlier.  Running from the terminal makes it so you don’t have to open the Xcode IDE if you prefer.

## Hello World

Now let’s take a look at the minimal useful cocos2d-x application.  While the cocos new created project creates a Hello World application of sorts, it’s a pretty sloppy starting point.  First, it has needlessly complications for an app that is supposed to be a minimum example, it’s commented in a manner that only makes sense if you come from an Objective-C background and finally, it even uses deprecated methods.

Therefore we are going to look at a cleaner Hello World sample.  We simply replace the code in each file with the code I provide below.  Don’t worry, all of the functionality we hack out will be covered in future tutorials.

AppDelegate.h

#pragma once

#include "cocos2d.h"

class  AppDelegate : private cocos2d::Application
{
public:
AppDelegate();
virtual ~AppDelegate();

virtual bool applicationDidFinishLaunching();
virtual void applicationDidEnterBackground();
virtual void applicationWillEnterForeground();
};

AppDelegate.cpp

#include "AppDelegate.h"
#include "HelloWorldScene.h"

USING_NS_CC;

AppDelegate::AppDelegate() {

}

AppDelegate::~AppDelegate()
{
}

bool AppDelegate::applicationDidFinishLaunching() {
auto director = Director::getInstance();
auto glview = director->getOpenGLView();
if(!glview) {
glview = GLViewImpl::create("Hello World");
glview->setFrameSize(640, 480);
director->setOpenGLView(glview);
}

auto scene = HelloWorld::createScene();
director->runWithScene(scene);

return true;
}

void AppDelegate::applicationDidEnterBackground() {
}

void AppDelegate::applicationWillEnterForeground() {
}

The biggest change I have made from the default implementation is to remove all but the barest requirements of an application.  You may notice I’ve also replaced the include guards with pragma once statements.  Some people will find this controversial because pragma once isn’t standard and therefore unportable.  This may be true, if you are using a compiler from 1985.  If on the other hand you are using any modern C++ compiler, pragma once is supported.  Include guards and pragma once perform the same task, except pragma once is more concise and less error prone.  If you want to switch back to include guards, feel free.  From this point on, I will however, not be using them.

OK, back to the code itself.  Our AppDelegate header is pretty straight forward, it declares a constructor, destructor and three methods, applicationDidFinishLaunching, applicationDidEnterBackground and applicationWillEnterForeground.  All three of these methods are pure virtual functions from ApplicationProtocol, from which Application ( and in turn AppDelegate ) inherit, so we must provide an implementation of each, even if it’s empty.

Now onto AppDelegate.cpp.  First we start off with the macro USING_NS_CC; which is just short for “using namespace cocos2d”.  Personally I don’t see a big win in using a macro over typing using namespace cocos2d, but generally I find many uses of macros unagreeable.  This however is the style the cocos team went with, so I will follow along.  As you can see, both or constructor, destructor, applicationDidEnterBackground and applicationWillEnterForeground all have empty implementations, so applicationDidFinishLaunching is where all of our logic resides.

If these names seem a bit long winded to you, they have been taken directly from the iOS world.  Basically the enterBackground/enterForeground methods are called when your application gains and loses focus, while applicationDidFinishLaunching is called when your application is loaded ( at the end of the loading process ).  Here we get an instance of the Director singleton, then use it to either get the GLView, or create a GLViewImpl, which is a default implementation of GLView.  Basically GLView is the OpenGL representation of your window or screen, depending on what kind of device you are running.  We then set the resolution of the window ( this is not required, I just wanted a smaller resolution for screen shots ) by calling setFrameSize() then set the view as active by calling Director’s setOpenGLView().  Now that we have a window, we create an instance of our scene calling createScene() and once again, use the Director to set this scene active using runWithScene().

You may notice in the above code that Director is very important to the operation of Cocos2d-x.  Director is an implementation of a design pattern known as a Singleton, or as some would say, an anti-pattern.  If you’ve spent much time on programming forums, you will see thread after thread calling Singletons evil.  In a nutshell, a singleton is a delayed, but guaranteed to be instantiated global variable in a pretty dress.  Sometimes too, a global variable is just what you need, which is why you will find a number of game engines make use of singletons to provide globally available interfaces.  At this point the matter is pretty much moot, if you use Cocos2d-x, you use Director, or you don’t use Cocos2d-x.

One of the major source of bugs with Singletons, especially in C++, is multithreading.  When you have this global instance being access from all kinds of locations and controlling so many things, how do you handle concurrent requests?  Well have I got good news for you!  You don’t. :)

That’s because Cocos2d-x isn’t thread safe.  Or more accurately, Cocos2d-x’s memory management ( anything derived from cocos2d::Ref ) and OpenGL rendering aren’t thread safe.  To make this clear, you can use threads in a Cocos2d-x application, but you need to be very careful what those threads interact with.  Other than the threading problems, some of the biggest problems that come from using Singletons are related to code maintenence, as you are coupling so many systems together.  Fortunately, this is the cocos2d-x team’s problem to deal with, not yours.  Unless of course you are on the Cocos2d-x team that is.

Now let's take a look at our scene, HelloWorldScene.

HelloWorldScene.h

#pragma once

#include "cocos2d.h"

class HelloWorld : public cocos2d::Layer
{
public:
static cocos2d::Scene* createScene();
virtual bool init();

CREATE_FUNC(HelloWorld);
};

HelloWorldScene.cpp

#include "HelloWorldScene.h"

USING_NS_CC;

Scene* HelloWorld::createScene()
{
// 'scene' is an autorelease object
auto scene = Scene::create();
auto layer = HelloWorld::create();

return scene;
}

bool HelloWorld::init()
{
if ( !Layer::init() )
{
return false;
}

auto label = Label::createWithSystemFont("Hello World", "Arial", 96);
label->setAnchorPoint(cocos2d::Vec2(0.0, 0.0));

return true;
}

In our header once again I’ve replaced the header guard with pragma pack.  We are declaring our scene class HelloWorld, which inherits from Layer which is a Node which can receive input events, such as touch, keys and motion.  We declare createScene() which returns a static Scene pointer.  As you may recall, we called this method earlier in AppDelegate to create our scene.  We also override the method init that we inherited from Node and is where we do our initialization logic.  Finally there is a bit of macro magic in the form of CREATE_FUNC(HelloWorld).

Let’s take a quick look at exactly what this macro is doing:

#define CREATE_FUNC(__TYPE__) \
static __TYPE__* create() \
{ \
__TYPE__ *pRet = new __TYPE__(); \
if (pRet && pRet->init()) \
{ \
pRet->autorelease(); \
return pRet; \
} \
else \
{ \
delete pRet; \
pRet = NULL; \
return NULL; \
} \
}

Granted, it’s not always the easiest code to read, as this is code for generating code, but essentially after this macro runs, we’ve got:

static HelloWorld* create(){
HelloWorld *pRet = new HelloWorld();
if (pRet && pRet->init())
{
pRet->autorelease();
return pRet;
}
else
{
delete pRet;
pRet = NULL;
return NULL;
}
} 

So, essentially, the macro is creating a create() function that allocates an instance of our class, calls the init method that we provided and then, most importantly, calls autorelease() we inherited from Ref.  I will cover why this is important in a few minutes, depending of course on how fast you read. :)

Now on to HelloWorldScene.cpp.  The createScene() method is pretty straight forward.  We create a Scene object, then an instance of our HelloWorld class ( which inherits from Layer ) and add our layer to the scene then return the scene ( which our AppDelegate then passed to Director->runScene() ).

In init() we perform the bulk of our logic.  First we call our base classes init function ( which is very important to do ), then create a Label using createWithSystemFont(), which predictably enough, using the built in system font (in this case Arial ) to create the Label’s text.  We then set the Labels anchor point to the bottom left, which means this node will be positioned relative to it’s bottom left corner.  I will cover anchor points in more detail in the next tutorial, so ignore this for now.  Finally we add the freshly created Label to our layer.  Finally we return true to indicate that initialization worked as expected.

Now if run our “game”, we should see:

Aren't we leaking memory like mad?

So you may have noticed we create all kinds of pointers using create() calls, but never once called delete.  As you can see in the code generated by the CREATE_FUNC, we are creating a new instance of our class, but we never do delete it.  Aren’t we leaking memory here?  Thankfully the answer is no and the reason is in the call to init() and autorelease() that the macro made and why it was so important we called our base classes init() in our own init method.

This is another legacy of Cocos2d-x’s Objective-C roots.  Objective-C provides a form of memory management via ARC, Automatic Reference Counting.  Basically each time something references an object, it’s count is increased, each time something reference an object goes away, the count is decreased, when the count hits zero, the object is released.  In many ways, this is pretty much the same functionality C++ smart pointers provide, but Cocos2d predates the standardization of smart pointers.

There is more to their usage that we will cover later on.  For now though, you can safely assume any cocos2d object created with a create() function, that inherits from Ref, does not need to be delete.  In fact, such objects must not be deleted!

In the next part we will take a look at working with graphics in Cocos2d-x.  Don’t worry, it will be much less verbose and much heavier in code!

## LibGDX LibGDX Tutorial 13: Physics with Box2D Part 4: Controlling collisions using filters

25. September 2014

Remember in our earlier example where we used a ContactListener to check for a collision between two types of FixtureDef and how ungainly the check was?  Remember when I said there was a much better way of doing this?  Well, welcome the the better way, Filters.

Filters are actually rather simple, except they use bitmasking, a concept that might be somewhat new to you.  I actually went into some detail on the use of bitmasks in this tutorial if you need some details.  Basically its about using individual bits in a number as “on/off” flags.  Basically it allows you to track multiple values in a single variable.  In Box2D, there are a pair of bitmask, the categoryBits and maskBits.  Those names can be a bit confusing but don’t worry about that.

Basically you can think of categoryBits as saying “This is what I am” and maskBits as “This is what I collide with”.  Keep in mind, you can set multiple bits for either, so you can both be multiple things and collide with multiple things.  That may still sound somewhat confusing, so let’s look at an example.  This is a modification of the code from the previous tutorial.  In this case, we want our two sprites to NOT collide with each other, but to collide with the edge that represents the ground in the world.

package com.gamefromscratch;

public class Physics4 extends ApplicationAdapter {
SpriteBatch batch;
Sprite sprite,sprite2;
Texture img;
World world;
Body body,body2;
Body bodyEdgeScreen;

Matrix4 debugMatrix;
OrthographicCamera camera;

final float PIXELS_TO_METERS = 100f;

final short PHYSICS_ENTITY = 0x1;    // 0001
final short WORLD_ENTITY = 0x1 << 1; // 0010 or 0x2 in hex

@Override
public void create() {
batch = new SpriteBatch();

// Create two identical sprites slightly offset from each other vertically
sprite = new Sprite(img);
sprite.setPosition(-sprite.getWidth()/2,-sprite.getHeight()/2 +200);
sprite2 = new Sprite(img);
sprite2.setPosition(-sprite.getWidth()/2 + 20,-sprite.getHeight()/2 + 400);

world = new World(new Vector2(0, -1f),true);

// Sprite1's Physics body
BodyDef bodyDef = new BodyDef();
bodyDef.type = BodyDef.BodyType.DynamicBody;
bodyDef.position.set((sprite.getX() + sprite.getWidth()/2) /
PIXELS_TO_METERS,
(sprite.getY() + sprite.getHeight()/2) / PIXELS_TO_METERS);

body = world.createBody(bodyDef);

// Sprite2's physics body
BodyDef bodyDef2 = new BodyDef();
bodyDef2.type = BodyDef.BodyType.DynamicBody;
bodyDef2.position.set((sprite2.getX() + sprite2.getWidth()/2) /
PIXELS_TO_METERS,
(sprite2.getY() + sprite2.getHeight()/2) / PIXELS_TO_METERS);

body2 = world.createBody(bodyDef2);

// Both bodies have identical shape
PolygonShape shape = new PolygonShape();
shape.setAsBox(sprite.getWidth()/2 / PIXELS_TO_METERS, sprite.getHeight()
/2 / PIXELS_TO_METERS);

// Sprite1
FixtureDef fixtureDef = new FixtureDef();
fixtureDef.shape = shape;
fixtureDef.density = 0.1f;
fixtureDef.restitution = 0.5f;
fixtureDef.filter.categoryBits = PHYSICS_ENTITY;

// Sprite2
FixtureDef fixtureDef2 = new FixtureDef();
fixtureDef2.shape = shape;
fixtureDef2.density = 0.1f;
fixtureDef2.restitution = 0.5f;
fixtureDef2.filter.categoryBits = PHYSICS_ENTITY;

body.createFixture(fixtureDef);
body2.createFixture(fixtureDef2);

shape.dispose();

// Now the physics body of the bottom edge of the screen
BodyDef bodyDef3 = new BodyDef();
bodyDef3.type = BodyDef.BodyType.StaticBody;

float w = Gdx.graphics.getWidth()/PIXELS_TO_METERS;
float h = Gdx.graphics.getHeight()/PIXELS_TO_METERS;

bodyDef3.position.set(0,0);
FixtureDef fixtureDef3 = new FixtureDef();
fixtureDef3.filter.categoryBits = WORLD_ENTITY;

EdgeShape edgeShape = new EdgeShape();
edgeShape.set(-w/2,-h/2,w/2,-h/2);
fixtureDef3.shape = edgeShape;

bodyEdgeScreen = world.createBody(bodyDef3);
bodyEdgeScreen.createFixture(fixtureDef3);
edgeShape.dispose();

camera = new OrthographicCamera(Gdx.graphics.getWidth(),Gdx.graphics.
getHeight());
}

@Override
public void render() {
camera.update();
// Step the physics simulation forward at a rate of 60hz
world.step(1f/60f, 6, 2);

sprite.setPosition((body.getPosition().x * PIXELS_TO_METERS) - sprite.
getWidth()/2 ,
(body.getPosition().y * PIXELS_TO_METERS) -sprite.getHeight()/2 );

sprite.setRotation((float)Math.toDegrees(body2.getAngle()));
sprite2.setPosition((body2.getPosition().x * PIXELS_TO_METERS) - sprite2.
getWidth()/2 ,
(body2.getPosition().y * PIXELS_TO_METERS) -sprite2.getHeight()/2 );
sprite2.setRotation((float)Math.toDegrees(body.getAngle()));

Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

batch.setProjectionMatrix(camera.combined);
batch.begin();

batch.draw(sprite, sprite.getX(), sprite.getY(),sprite.getOriginX(),
sprite.getOriginY(),
sprite.getWidth(),sprite.getHeight(),sprite.getScaleX(),sprite.
getScaleY(),sprite.getRotation());
batch.draw(sprite2, sprite2.getX(), sprite2.getY(),sprite2.getOriginX(),
sprite2.getOriginY(),
sprite2.getWidth(),sprite2.getHeight(),sprite2.getScaleX(),sprite2.
getScaleY(),sprite2.getRotation());
batch.end();
}

@Override
public void dispose() {
img.dispose();
world.dispose();
}
}

When a collision occurs, the collider will check it’s categoryBits against the collided’s maskBits.  If both are true, a collision occurs.  So in this example, both sprites will fall, completely ignoring each other.  However when they run in to the WORLD_ENTITY, a collision will occur.

Now, taking the same scenario, if you wanted to have the sprites collide with each other AND WORLD_ENTITY objects, you would simply change to

fixtureDef.filter.maskBits = WORLD_ENTITY|PHYSICS_ENTITY;

Now this object will have collisions with either kind of entity.

There is one other kind of filter in Box2D, and it's confusing as hell in my opinion. It's basically an override for grouping entities together called groupIndex.  I will let someone else explain how it works:

When checking two fixtures to see if they should collide:

• if either fixture has a groupIndex of zero, use the category/mask rules as above
• if both groupIndex values are non-zero but different, use the category/mask rules as above
• if both groupIndex values are the same and positive, collide
• if both groupIndex values are the same and negative, don't collide

The default value for the groupIndex is zero

So, if you want to have fine tune control over which entities interact with each other, Filter is how you do it.  Ok, let’s keep this part short and sweet.

## LibGDX LibGDX Tutorial 13: Physics with Box2D Part 3: Collisions

25. September 2014

So far we’ve covered creating a simple simulation then how to create physics bodies and apply forces to them now we look at dealing with collisions.  Truth of the matter is, most of the work is just done for us.  Let’s just right in with an example, heavily copied and pasted from the previous example.

package com.gamefromscratch;

public class Physics2 extends ApplicationAdapter implements InputProcessor {
SpriteBatch batch;
Sprite sprite;
Texture img;
World world;
Body body;
Body bodyEdgeScreen;
Box2DDebugRenderer debugRenderer;
Matrix4 debugMatrix;
OrthographicCamera camera;
BitmapFont font;

float torque = 0.0f;
boolean drawSprite = true;

final float PIXELS_TO_METERS = 100f;

@Override
public void create() {

batch = new SpriteBatch();
sprite = new Sprite(img);

sprite.setPosition(-sprite.getWidth()/2,-sprite.getHeight()/2);

world = new World(new Vector2(0, -1f),true);

BodyDef bodyDef = new BodyDef();
bodyDef.type = BodyDef.BodyType.DynamicBody;
bodyDef.position.set((sprite.getX() + sprite.getWidth()/2) /
PIXELS_TO_METERS,
(sprite.getY() + sprite.getHeight()/2) / PIXELS_TO_METERS);

body = world.createBody(bodyDef);

PolygonShape shape = new PolygonShape();
shape.setAsBox(sprite.getWidth()/2 / PIXELS_TO_METERS, sprite.getHeight()
/2 / PIXELS_TO_METERS);

FixtureDef fixtureDef = new FixtureDef();
fixtureDef.shape = shape;
fixtureDef.density = 0.1f;
fixtureDef.restitution = 0.5f;

body.createFixture(fixtureDef);
shape.dispose();

BodyDef bodyDef2 = new BodyDef();
bodyDef2.type = BodyDef.BodyType.StaticBody;
float w = Gdx.graphics.getWidth()/PIXELS_TO_METERS;
// Set the height to just 50 pixels above the bottom of the screen so we can see the edge in the
// debug renderer
float h = Gdx.graphics.getHeight()/PIXELS_TO_METERS- 50/PIXELS_TO_METERS;
//bodyDef2.position.set(0,
//                h-10/PIXELS_TO_METERS);
bodyDef2.position.set(0,0);
FixtureDef fixtureDef2 = new FixtureDef();

EdgeShape edgeShape = new EdgeShape();
edgeShape.set(-w/2,-h/2,w/2,-h/2);
fixtureDef2.shape = edgeShape;

bodyEdgeScreen = world.createBody(bodyDef2);
bodyEdgeScreen.createFixture(fixtureDef2);
edgeShape.dispose();

Gdx.input.setInputProcessor(this);

debugRenderer = new Box2DDebugRenderer();
font = new BitmapFont();
font.setColor(Color.BLACK);
camera = new OrthographicCamera(Gdx.graphics.getWidth(),Gdx.graphics.
getHeight());
}

private float elapsed = 0;
@Override
public void render() {
camera.update();
// Step the physics simulation forward at a rate of 60hz
world.step(1f/60f, 6, 2);

body.applyTorque(torque,true);

sprite.setPosition((body.getPosition().x * PIXELS_TO_METERS) - sprite.
getWidth()/2 ,
(body.getPosition().y * PIXELS_TO_METERS) -sprite.getHeight()/2 )
;
sprite.setRotation((float)Math.toDegrees(body.getAngle()));

Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

batch.setProjectionMatrix(camera.combined);
debugMatrix = batch.getProjectionMatrix().cpy().scale(PIXELS_TO_METERS,
PIXELS_TO_METERS, 0);
batch.begin();

if(drawSprite)
batch.draw(sprite, sprite.getX(), sprite.getY(),sprite.getOriginX(),
sprite.getOriginY(),
sprite.getWidth(),sprite.getHeight(),sprite.getScaleX(),sprite.
getScaleY(),sprite.getRotation());

font.draw(batch,
"Restitution: " + body.getFixtureList().first().getRestitution(),
-Gdx.graphics.getWidth()/2,
Gdx.graphics.getHeight()/2 );
batch.end();

debugRenderer.render(world, debugMatrix);
}

@Override
public void dispose() {
img.dispose();
world.dispose();
}

@Override
public boolean keyDown(int keycode) {
return false;
}

@Override
public boolean keyUp(int keycode) {

if(keycode == Input.Keys.RIGHT)
body.setLinearVelocity(1f, 0f);
if(keycode == Input.Keys.LEFT)
body.setLinearVelocity(-1f,0f);

if(keycode == Input.Keys.UP)
body.applyForceToCenter(0f,10f,true);
if(keycode == Input.Keys.DOWN)
body.applyForceToCenter(0f, -10f, true);

// On brackets ( [ ] ) apply torque, either clock or counterclockwise
if(keycode == Input.Keys.RIGHT_BRACKET)
torque += 0.1f;
if(keycode == Input.Keys.LEFT_BRACKET)
torque -= 0.1f;

// Remove the torque using backslash /
if(keycode == Input.Keys.BACKSLASH)
torque = 0.0f;

// If user hits spacebar, reset everything back to normal
if(keycode == Input.Keys.SPACE|| keycode == Input.Keys.NUM_2) {
body.setLinearVelocity(0f, 0f);
body.setAngularVelocity(0f);
torque = 0f;
sprite.setPosition(0f,0f);
body.setTransform(0f,0f,0f);
}

if(keycode == Input.Keys.COMMA) {
body.getFixtureList().first().setRestitution(body.getFixtureList().first().getRestitution()-0.1f);
}
if(keycode == Input.Keys.PERIOD) {
body.getFixtureList().first().setRestitution(body.getFixtureList().first().getRestitution()+0.1f);
}
if(keycode == Input.Keys.ESCAPE || keycode == Input.Keys.NUM_1)
drawSprite = !drawSprite;

return true;
}

@Override
public boolean keyTyped(char character) {
return false;
}

// On touch we apply force from the direction of the users touch.
// This could result in the object "spinning"
@Override
public boolean touchDown(int screenX, int screenY, int pointer, int button) {
body.applyForce(1f,1f,screenX,screenY,true);
//body.applyTorque(0.4f,true);
return true;
}

@Override
public boolean touchUp(int screenX, int screenY, int pointer, int button) {
return false;
}

@Override
public boolean touchDragged(int screenX, int screenY, int pointer) {
return false;
}

@Override
public boolean mouseMoved(int screenX, int screenY) {
return false;
}

@Override
public boolean scrolled(int amount) {
return false;
}
}

Here is the application running

Click to open in new Window (It's probably already run by the time you scrolled down)

You can control it using the following controls:

• Left and Right Arrow:  Apply impulse along X axis
• Up and Down Arrow: Apply force along Y axis.
• [ and ]: Apply torque
• \: Set torque to 0
• SPACEBAR or '2': Reset all
• Click, apply force from point of click
• ESC or '1' toggles display of the sprite graphic on and off

This is basically the same application we created in the previous example, except now there is actually something to collide with.  In this case we created a physics body defined by an edge shape just 50 pixels above the bottom of the screen.  The key difference between our two bodies is bodyEdgeScreen has it’s physics type set to StaticBody.  A static body is exactly what it’s name implies, static, meaning that it doesn’t move.  It participates in the physics simulation ( stuff can hit it ), but it is un affected by the simulation itself.  If this body wasn’t static, gravity would have grabbed it and set it free falling in space.  As you can see, it is created the same way as our other physics body.  The only other major difference is instead of being defined in the physics engine by a box, it is instead represented as an edge defined by two points.  This means our EdgeShape has no volume.

Now that we have collisions occurring a few values became much more important, density, restitution (and not shown, friction).  These are set on the FixtureDef of your Body.  We touched briefly on density in the previous tutorials, it helps determine the overall mass of your object along with the shape.  Restitution can be thought of as, for the lack of a better term, as bounciness.  Restitution helps determine how one body will respond to contact with another physics object.  Rubber for example would have a high restitution, while rock would have a very low restitution.  Friction on the other hand determines how one body slides across another body.

What happens if you want to perform some kind of operation when a collision occurs?  Well fortunately this is quite simple, let’s take a look at another heavily cut and paste example!

package com.gamefromscratch;

public class Physics3 extends ApplicationAdapter {
SpriteBatch batch;
Sprite sprite,sprite2;
Texture img;
World world;
Body body,body2;
Body bodyEdgeScreen;

Matrix4 debugMatrix;
OrthographicCamera camera;

final float PIXELS_TO_METERS = 100f;

@Override
public void create() {
batch = new SpriteBatch();

// Create two identical sprites slightly offset from each other vertically
sprite = new Sprite(img);
sprite.setPosition(-sprite.getWidth()/2,-sprite.getHeight()/2 +200);
sprite2 = new Sprite(img);
sprite2.setPosition(-sprite.getWidth()/2 + 20,-sprite.getHeight()/2 + 400);

world = new World(new Vector2(0, -1f),true);

// Sprite1's Physics body
BodyDef bodyDef = new BodyDef();
bodyDef.type = BodyDef.BodyType.DynamicBody;
bodyDef.position.set((sprite.getX() + sprite.getWidth()/2) /
PIXELS_TO_METERS,
(sprite.getY() + sprite.getHeight()/2) / PIXELS_TO_METERS);

body = world.createBody(bodyDef);

// Sprite2's physics body
BodyDef bodyDef2 = new BodyDef();
bodyDef2.type = BodyDef.BodyType.DynamicBody;
bodyDef2.position.set((sprite2.getX() + sprite2.getWidth()/2) /
PIXELS_TO_METERS,
(sprite2.getY() + sprite2.getHeight()/2) / PIXELS_TO_METERS);

body2 = world.createBody(bodyDef2);

// Both bodies have identical shape
PolygonShape shape = new PolygonShape();
shape.setAsBox(sprite.getWidth()/2 / PIXELS_TO_METERS, sprite.getHeight()
/2 / PIXELS_TO_METERS);

// Sprite1
FixtureDef fixtureDef = new FixtureDef();
fixtureDef.shape = shape;
fixtureDef.density = 0.1f;
fixtureDef.restitution = 0.5f;

// Sprite2
FixtureDef fixtureDef2 = new FixtureDef();
fixtureDef2.shape = shape;
fixtureDef2.density = 0.1f;
fixtureDef2.restitution = 0.5f;

body.createFixture(fixtureDef);
body2.createFixture(fixtureDef2);

shape.dispose();

// Now the physics body of the bottom edge of the screen
BodyDef bodyDef3 = new BodyDef();
bodyDef3.type = BodyDef.BodyType.StaticBody;
float w = Gdx.graphics.getWidth()/PIXELS_TO_METERS;
float h = Gdx.graphics.getHeight()/PIXELS_TO_METERS;

bodyDef3.position.set(0,0);
FixtureDef fixtureDef3 = new FixtureDef();

EdgeShape edgeShape = new EdgeShape();
edgeShape.set(-w/2,-h/2,w/2,-h/2);
fixtureDef3.shape = edgeShape;

bodyEdgeScreen = world.createBody(bodyDef3);
bodyEdgeScreen.createFixture(fixtureDef3);
edgeShape.dispose();

camera = new OrthographicCamera(Gdx.graphics.getWidth(),Gdx.graphics.
getHeight());

world.setContactListener(new ContactListener() {
@Override
public void beginContact(Contact contact) {
// Check to see if the collision is between the second sprite and the bottom of the screen
// If so apply a random amount of upward force to both objects... just because
if((contact.getFixtureA().getBody() == bodyEdgeScreen &&
contact.getFixtureB().getBody() == body2)
||
(contact.getFixtureA().getBody() == body2 &&
contact.getFixtureB().getBody() == bodyEdgeScreen)) {

body.applyForceToCenter(0,MathUtils.random(20,50),true);
body2.applyForceToCenter(0, MathUtils.random(20,50), true);
}
}

@Override
public void endContact(Contact contact) {
}

@Override
public void preSolve(Contact contact, Manifold oldManifold) {
}

@Override
public void postSolve(Contact contact, ContactImpulse impulse) {
}
});
}

@Override
public void render() {
camera.update();
// Step the physics simulation forward at a rate of 60hz
world.step(1f/60f, 6, 2);

sprite.setPosition((body.getPosition().x * PIXELS_TO_METERS) - sprite.
getWidth()/2 ,
(body.getPosition().y * PIXELS_TO_METERS) -sprite.getHeight()/2 );

sprite.setRotation((float)Math.toDegrees(body2.getAngle()));
sprite2.setPosition((body2.getPosition().x * PIXELS_TO_METERS) - sprite2.
getWidth()/2 ,
(body2.getPosition().y * PIXELS_TO_METERS) -sprite2.getHeight()/2 );
sprite2.setRotation((float)Math.toDegrees(body.getAngle()));

Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

batch.setProjectionMatrix(camera.combined);
batch.begin();

batch.draw(sprite, sprite.getX(), sprite.getY(),sprite.getOriginX(),
sprite.getOriginY(),
sprite.getWidth(),sprite.getHeight(),sprite.getScaleX(),sprite.
getScaleY(),sprite.getRotation());
batch.draw(sprite2, sprite2.getX(), sprite2.getY(),sprite2.getOriginX(),
sprite2.getOriginY(),
sprite2.getWidth(),sprite2.getHeight(),sprite2.getScaleX(),sprite2.
getScaleY(),sprite2.getRotation());
batch.end();
}

@Override
public void dispose() {
img.dispose();
world.dispose();
}
}

And when you run it

Click to open in new Window (It's probably already run by the time you scrolled down)

In this example we’ve added another dynamic physics body.  Both bodies fall thanks to gravity, however when the second physics body makes contact with the “ground”, an upward force is applied to both bodies.

The heart of this example is the ContactListener we added to our physics world.  This handler is called for each collision that occurred in the world and allows you to handle the event before and after contact, then before and after the physics engine does the calculations on what to do.  In this example we used the beginContact callback, although truth is, all 4 would have behaved identically.  In each case a Contact object is passed in, which has details on the collision such as the friction, restitution and speed of the collision.  In this case we actually want to check what types of objects collided, which we do using getFixtureA() and getFixtureB() which returns the FixtureDef of the colliding objects.  Since we don’t actually know which collides with which, we test for both directions of collisions.  If the bodies colliding are Body2 and bodyEdgeScreen, we apply our upward force.  Obviously you could handle whatever kind of calculation you wanted at this point.

One very common activity, and something I didn’t cover in this example is tying a physics body back to the object in the real world that this body represents.  In this particular example we’ve simply hard coded things, but in a real life application this isn’t an option.  Fortunately there is an easy elegant solution.  Each physics Body has a property called UserData, which can be basically whatever you want it to be.  Let’s take a quick look at storing the game sprite using UserData of the physics Body.

        //Create the body
body = world.createBody(bodyDef);
//Store the sprite the body represents in UserData
body.setUserData(sprite);
//Access the sprite
((Sprite)body.getUserData()).setPosition(body.getPosition().x,body.getPosition().y);

This provides an easy way to link the object represented with the physics entity itself.

So far we covered dynamic objects, which can be moved and positioned and participate in the physics simulation, and static bodies, that do not move but can participate in the simulation, what what happens if you want a body to be aware of the physics simulation, but not effect it.  For example, what if you wanted to trigger some code when a physics body went off screen, but you didn’t want this to cause a collision.  There is a very simple solution to this, sensors.

        fixtureDef.isSensor = true;

This is all you need to do an now your physics object will no longer cause a reaction when collided with, except whatever you provide in code.  For example, in the earlier example, if you changed fixtureDef3 to be a sensor, the first body will simply fall through it.  However when the second body hits it, it will trigger the code in our ContactListener.

If you thought to yourself, wow, that’s an ugly way to handle tests for collisions between different objects… that whole test in both directions thing will get awfully ugly quickly.  You are 100% correct, fortunately there is a clean solution I will cover shortly.