Wednesday, January 28, 2015

[Tutorial] Cocos2d-x: The second game - Breakout (Part 1)

In this game, you must do some following tasks:

+ Add objects into game
+ Set physics attributes ( using Chipmunk for ease )
+ Create the movement of the ball
+ Move the paddle

Step 1 - Add objects into game - Set physics attributes

Create a new project with familiar command:

>cocos new breakout -p com.vn.breakout -l cpp -d f:android/project

And remember to add USING_NS_CC; into HelloWorldScene.h 

Open file HelloWorldScene.h add some following commands in public area

Sprite* ball; 
Sprite* paddle;
Sprite* edgeSp;

PhysicsWorld* m_world; 

void setPhyWorld(PhysicsWorld* world){ m_world = world; };
// Touch event
void onTouchMoved(Touch *touch, Event *event);
void onTouchEnded(Touch *touch, Event *event);

bool onTouchBegan(Touch *touch, Event *event);
OK
Open file HelloWorldScene.cpp, edit createScene() function a bit like this:

auto scene = Scene::createWithPhysics();
scene->getPhysicsWorld()->setDebugDrawMask(PhysicsWorld::DEBUGDRAW_ALL);
Vect gravity(0.0f, 0.0f); // Vector gia tốc =0
scene->getPhysicsWorld()->setGravity(gravity);
auto layer = HelloWorld::create();
layer->setPhyWorld(scene->getPhysicsWorld());

 you delete all init() function but this:

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

auto visibleSize = Director::getInstance()->getVisibleSize();
auto origin = Director::getInstance()->getVisibleOrigin();

//---Delete all here

return true;

Add the following long code block into the deleted area

edgeSp = Sprite::create();
auto boundBody = PhysicsBody::createEdgeBox(visibleSize, PHYSICSBODY_MATERIAL_DEFAULT, 3);// Create physics body
boundBody->getShape(0)->setRestitution(1.0f); 
boundBody->getShape(0)->setFriction(0.0f);
boundBody->getShape(0)->setDensity(1.0f);
edgeSp->setPosition(Point(visibleSize.width / 2, visibleSize.height / 2)); // Set the position and the centre of Box in the center of the screen
edgeSp->setPhysicsBody(boundBody); // Set physics Body
boundBody->setContactTestBitmask(0x000001); // This is the important command, if not available, there is nothing happening when colliding
this->addChild(edgeSp); // Add into Layer
edgeSp->setTag(0); // Tag==0, to check object when colliding belongs to some kind

ball = Sprite::create("Ball.png", Rect(0, 0, 52, 52));
ball->setPosition(100, 100);
auto ballBody = PhysicsBody::createCircle(ball->getContentSize().width / 2.); // The physics body circle shape
ballBody->getShape(0)->setRestitution(1.0f);
ballBody->getShape(0)->setFriction(0.0f);
ballBody->getShape(0)->setDensity(1.0f);
ballBody->setGravityEnable(false); // Not set acceleration
Vect force = Vect(1010000.0f, 1010000.0f); // Create a force Vector to act with the direction of 45 degree, because x = y 
ballBody->applyImpulse(force); // Push a force into the ball edge
ball->setPhysicsBody(ballBody); // Set Physics body
ballBody->setContactTestBitmask(0x000001); //
ball->setTag(1);
this->addChild(ball);

// Similar with the ball
paddle = Sprite::create("Paddle.png");
auto paddleBody = PhysicsBody::createBox(paddle->getContentSize(), PHYSICSBODY_MATERIAL_DEFAULT);
paddleBody->getShape(0)->setRestitution(1.0f);
paddleBody->getShape(0)->setFriction(0.0f);
paddleBody->getShape(0)->setDensity(10.0f);
paddleBody->setGravityEnable(false);
paddleBody->setDynamic(false); // Set static when reacting, no restitution, no changing position
paddle->setPosition(visibleSize.width / 2, 50);
paddle->setPhysicsBody(paddleBody);
paddleBody->setContactTestBitmask(0x000001); // With reaction 
ball->setTag(2);
this->addChild(paddle);

Add the code block to create a Listener to catch Touch events ( using to control the paddle ) before the command: Return true;

auto touchListener = EventListenerTouchOneByOne::create();
touchListener->setSwallowTouches(true);
touchListener->onTouchBegan = CC_CALLBACK_2(HelloWorld::onTouchBegan, this);
touchListener->onTouchMoved = CC_CALLBACK_2(HelloWorld::onTouchMoved, this);
touchListener->onTouchEnded = CC_CALLBACK_2(HelloWorld::onTouchEnded, this);

_eventDispatcher->addEventListenerWithSceneGraphPriority(touchListener, this);

Step 2 - Create the movement of the ball

Create the first movement for the ball by the following command ( in the above init() function created)

Vect force = Vect(1010000.0f, 1010000.0f); // Create a force Vector with 45 degree, because x = y

ballBody->applyImpulse(force); // Push a force into the ball edge

Step 3 - Move the paddle

Build 3 Touch functions, because we only use the onTouchMoved function to move so the other Touch functions we leave empty:

bool HelloWorld::onTouchBegan(Touch* touch, Event* event)
{
return true; // Not use but must return True
}

void HelloWorld::onTouchEnded(Touch* touch, Event* event)
{
// Not use
}

// Use to move the paddle simplest
void HelloWorld::onTouchMoved(Touch* touch, Event* event){
Point touchLocation = this->convertToWorldSpace(this->convertTouchToNodeSpace(touch));
// To be simple, use this command: Point touchLocation = touch->getLocation();
paddle->setPositionX(touchLocation.x); // Set the position horizontal of the paddle follow the Touch point
}

OK! Build and run now!





The lesson is done! Very simple, ok? In this lesson, we can study some as follow:

+ Review the knowledge of Chipmunk Physics
+ Create the ball moving by force Vector.
+ Move the object by onTouchMoved.

Download Resource and Class 

In the next lesson, we will study how to create brick, destroy brick, and game Over 




[ttaiit.blogspot.com translated]

1 comments:

  1. I love it. Chipmunk is very easy to use and the bug that was created in version 3.7 it was finally fixed in version 3.90 Thank you for this tutorials :)

    ReplyDelete

Choose an Android item