Showing posts with label Touch screen event and shoot bullets. Show all posts
Showing posts with label Touch screen event and shoot bullets. Show all posts

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
listener1->setSwallowTouches(true);

//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
this->addChild(projectile,1);

//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
projectile->runAction(run);

You should review the lesson Basic Actions of Sprite

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



Posted By Live Blog8:57 AM

Choose an Android item