Monday, January 19, 2015

[Tutorial] Cocos2d-x: Create the first simple game - Touch screen event and shoot bullets (Part 2)

In part 1, we studied how to create a character, and monsters from images through class Sprite. And in adding monsters, you notice a block calculating the appearing position, and the moving speed. It's the simple algorithm.

In this part, we do some following tasks:

+ Catch event when touching screen
+ When touching screen, our character will shoot
+ Process the direction of the bullet flying following the point when touching

Let's Start!

Step 1 - touchscreen event and how to detect

You open file HelloWorldScene.cpp, in function init() find to the end of the function before return true; add the following block:

//Create an object to dispatch event information
auto dispatcher = Director::getInstance()->getEventDispatcher();
//Create an object to listen to touchscreen event follow One by One way
auto listener1 = EventListenerTouchOneByOne::create();
//Set swallow for Touch event when happening, prevent not allow objects catching other events using this event

//Catch Touch event, when Touch event happens, call corresponding function of HelloWorld class
listener1->onTouchBegan = CC_CALLBACK_2(HelloWorld::onTouchBegan, this);
listener1->onTouchMoved = CC_CALLBACK_2(HelloWorld::onTouchMoved, this);
listener1->onTouchEnded = CC_CALLBACK_2(HelloWorld::onTouchEnded, this);

//Send to dispatcher to process
dispatcher->addEventListenerWithSceneGraphPriority(listener1, this);

return true;

* Notice: Although not using onTouchMoved, but we should make Touch event be processed completely.

Step 2 - Process touch event - create the ability to shoot bullets for character

Open file HelloWorldScene.h, add three more prototype functions:

void onTouchEnded (cocos2d::Touch* touches, cocos2d::Event* event);
void onTouchMoved (cocos2d::Touch* touches, cocos2d::Event* event);
//Notice: onTouchBegan must return bool
bool onTouchBegan (cocos2d::Touch* touches, cocos2d::Event* event);

Then open file HelloWorldScene.cpp to define these three functions.

Although we don't use all three functions, but for Touch event to process completely, you must declare all three functions as follow:

bool HelloWorld::onTouchBegan(Touch* touch, Event* event)


return true; // must return True


void HelloWorld::onTouchMoved(Touch* touch, Event* event)

// Not process here


void HelloWorld::onTouchEnded (Touch* touches, Event* event){
// Get coordinator of touch point
Point location =  touches->getLocationInView();
location = Director::getInstance()->convertToGL(location);

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

//Create a bullet as a Sprite, set first position for main character
auto projectile = Sprite::create("Projectile.png");
projectile->setPosition( Point(20, winSize.height/2) );

// This block calculates the end point of the bullet through the first position and the position on Touch, the below picture can demonstrate for this. Here apply some basic formula of math. 

// Coordinator of touch point subtract coordinator of the top of bullet (offX, offY)
int offX = location.x - projectile->getPosition().x;
int offY = location.y - projectile->getPosition().y;

// Not allow to shoot reversely and shoot straightly to the bottom ( below the character )

if (offX <= 0) return;

// If the above condition is satisfied, create the shape of bullet on the screen

//Calculate the coordinator of the end point through the coordinator of the beginning point and the distance offX, offY
// The absolute coordinate realX = screen width + 1/2 bullet width, just right on flying out of screen
int realX = winSize.width  + (projectile->getContentSize().width/2); 

// The ratio between offY and offX
float ratio = (float)offY / (float)offX;

// The absolute coordinator of realY can be calculated based on realX and the above ratio + the beginning coordinator Y of the bullet ( calculate follow Talet in triangle, or follow tang of angle)

int realY = (realX * ratio) + projectile->getPosition().y; // must be: int realY = ((realX-projectile->getPosition().x) * ratio) + projectile->getPosition().y; (realX-projectile->getPosition().x is exactly the length from beginning point to end point on X axis

//The coordinator of end point
auto realDest = Point(realX, realY);

//The length of distance of bullet, calculate follow Pitago a*a = b*b + c*c, a is the subtense of square triangle
int offRealX = realX - projectile->getPosition().x;
int offRealY = realY - projectile->getPosition().y;
float length = sqrtf((offRealX * offRealX)  + (offRealY*offRealY));

// Set the velocity 480 pixels per second
float velocity = 480/1;

// The duration that bullet fly = the distance that bullet fly divide by the above velocity
float realMoveDuration = length/velocity;

// Move the bullet to end point with the time and the coordinate that calculated above. When go through the edge of the screen, it will disappear
projectile->runAction( Sequence::create(
MoveTo::create(realMoveDuration, realDest),
CallFuncN::create(CC_CALLBACK_1(HelloWorld::spriteMoveFinished,this)), NULL) );


The code block runAction seems to be complex but if written explicitly, it will be as follow:

//Move bullet with time and coordinator that calculated above
auto move= MoveTo::create(realMoveDuration,realDest);

//When move to the end poing, you will call the function spriteMoveFinished to remove the image of bullet, if not remove, the bullet fly out but still in the Layer, more and more, and process much more. This block will return an Action*
auto finish=CallFuncN::create(CC_CALLBACK1(HelloWorld::spriteMoveFinished,this));

//Perform in sequence two tasks, Move and then Delete
auto run = Sequence::create(move,finish,NULL);

//Perform the task of processing Sequence

You should review the lesson Basic Actions of Sprite

Here is the image that demonstrate the calculation of the flying distance of bullet

Conclusion in this lesson:

+ Catch the touchscreen events by Listeners
+ Build the function to process when having touchscreen events, shoot bullet, calculate the distance for bullet to fly, coordinator, speed of bullet
+ Create Action to move bullet with speed and coordinator that calculated

You can download source file here

Here is Demo picture

However, you will see that bullet can be shot through monster... In the next lesson, we will set the event for collision between bullet and monsters.


Post a Comment

Choose an Android item