Friday, March 13, 2015

Handle Touch Input in Cocos2D-X Mobile Game

cocos2d-x-ontoucheventhandler-example

In this post I am going to show you how to handle touches on a phone or tablet screen, same method works for PC mouse clicks.
First of all go ahead and create a new project as shown here.
I named my project "TouchMe", since that's what we are going to demonstrate in this article.

Next we will go inside the automatically generated code of HelloWorld class.
Inside the function bool HelloWorld::init() find the following line

addChild(rootNode);

Comment this line and use the code given below to create a root node with a string name so that we will be able to grab it for use later on.

addChild(rootNode, 0, "mainscene");

Next we will instantiate and draw a label object, I've defined constants for starting points.

const float STARTX = 150;
const float STARTY = 500;

The code for creating a label,

auto lblHello = Label::create
 ("Hello World!", "Times", 48.0, cocos2d::Size::ZERO,
cocos2d::TextHAlignment::CENTER,
cocos2d::TextVAlignment::CENTER);

lblHello ->setPosition(STARTX,STARTY);
 
rootNode ->addChild(lblHello, 1, "lblHello");
// CODE PRETTY PRINTING WITH http://tohtml.com/cpp/

Listening For Touch Events

We will use EventListenerTouchOneByOne to listen for screen touch events. Make sure you have appropriate namespaces added, to be exact following macro statement right after include files:

USING_NS_CC;

You don't need to add any special include file.

Next we will define a touchListener object in following manner.

auto touchListener = EventListenerTouchOneByOne::create(); touchListener ->setSwallowTouches(true);

We will supply some methods of HelloWorld class to the touchListener object. First of we will define these methods in header file, open HelloWorldScene.h file.

Add Touch Function Definitions to Class

Add following section right before closing of your HelloWorld class,

private: virtual bool onTouchBegan(Touch *touch, Event *event); virtual void onTouchMoved(Touch *touch, Event *event); virtual void onTouchEnded(Touch *touch, Event *event);

Important: Even if we are not interested in onTouchBegan method, we won't be able to receive onTouchEnded without handling the former.

Now go back to the HelloWorldScene.cpp file, and go inside HelloWorld::init() method. Right after ->setSwallowTouches(true); line add code shown below:

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

CC_CALLBACK_2 macro is used to define a callback.

Add touch handling method definitions

Inside the HelloWorldScene.cpp file, we will add method definitions for touch callbacks. The code will be added after HelloWorld::init() method.









void HelloWorld::onTouchEnded(Touch *touch, Event *event)
{
 Vec2 posCurr = event -> getCurrentTarget() ->getPosition();
 auto mainScene =  getChildByName("mainscene");
 auto lblHello = mainScene ->getChildByName("lblHello");

 auto delta =  touch ->getDelta();
 auto a = touch ->getLocation();
 auto b = touch ->getPreviousLocation();
 auto c = touch ->getStartLocation();

 CCLOGERROR("onTouchEnded x: %f y: %f", posCurr.x, posCurr.y);

 lblHello ->setPosition(a);


}

bool HelloWorld::onTouchBegan(Touch *touch, Event *event)
{ 
    return true;
}
void HelloWorld::onTouchMoved(Touch *touch, Event *event)
{

}

You can see that only onTouchEnded method contains some code, including a CCLOGERROR line to show x and y coordinates of the touch. It will show text log in debug view.

Explaining logic for touch event handling

We are getting hold of x,y coordinates of the touch event as Vec2 object using Event * event method getPosition().
After that we got hold of the main scene using getChildByName("mainscene"). 
Next we will use the returned value to reach the label object.
Once the label object is reached, its position will be set using setPosition(a) statement.

No comments:

Post a Comment

Feel free to talk back...