Wednesday, January 28, 2015

[Tutorial] Cocos2d-x: The second game - Breakout - Create and destroy brick (Part 2)

Some tasks in this lesson:

+ Create bricks
+ Process physics collision
+ Check the destruction of bricks, if done, it's WINGAME
+ Check GameOver when the ball falls but not colliding with the paddle

- It seems muck work but it's simple because it's rather like the first game

Let's start!

Step 1 - Create bricks

Open file HelloWorldScene.cpp, add the following code block

for (int i = 0; i < 5; i++) {
static int padding = 100;
auto block = Sprite::create("blocks.png");
auto blockBody = PhysicsBody::createBox(block->getContentSize(), PHYSICSBODY_MATERIAL_DEFAULT);
blockBody->getShape(0)->setDensity(10.0f);
blockBody->getShape(0)->setFriction(0.0f);
blockBody->getShape(0)->setRestitution(1.f);
blockBody->setDynamic(false);
// Create the distance even among the bricks
int xOffset = padding + block->getContentSize().width / 2 +
((block->getContentSize().width + padding)*i);
block->setPosition(xOffset, 450);
blockBody->setContactTestBitmask(0x000001);
block->setPhysicsBody(blockBody);
block->setTag(3);
this->addChild(block);
}

Step 2 - Process the collision - Destroy bricks, Game Over

* Add ContactListener

auto dispatcher = Director::getInstance()->getEventDispatcher();
auto contactListener = EventListenerPhysicsContact::create();
contactListener->onContactBegin = CC_CALLBACK_1(HelloWorld::onContactBegin, this);  
dispatcher->addEventListenerWithSceneGraphPriority(contactListener, this);

* Build the function onContactBegin

bool HelloWorld::onContactBegin(PhysicsContact& contact)
{
// Get two collided object
auto spriteA = (Sprite*)contact.getShapeA()->getBody()->getNode();
auto spriteB = (Sprite*)contact.getShapeB()->getBody()->getNode();

// Check kinds of objects
int tagA = spriteA->getTag();
int tagB = spriteB->getTag();

if (tagA == 3) // is brick
{

this->removeChild(spriteA,true); // delete brick

//spriteA->removeFromParentAndCleanup(true);
}

if (tagB == 3)  // is brick
{
this->removeChild(spriteB,true); // delete brick

//spriteB->removeFromParentAndCleanup(true);
}

// If the ball collides with the floor and the coordinate Y of the ball is smaller than the paddle, Game Over happens
if ((tagA == 0 || tagB  == 0 )& (ball->getPositionY() <= paddle->getPositionY()))
{
auto gameOverScene = GameOverScene::create();
gameOverScene->getLayer()->getLabel()->setString("You Lose!");
Director::getInstance()->replaceScene(gameOverScene);
}

return true;
}

This class GameOverScene is similar in the first project

Step 2 - check Win game

Build the function Tick() like this, remember that declare prototype function

void HelloWorld::tick(float dt)
{
// a bool variable confirm Win game and the initial value is true;
bool isWin = true;
// Vector bodies get all bodies of world ( ball, edge, paddle body)
Vector<PhysicsBody*> bodies = m_world->getAllBodies();

// Navigate the items in the above vector, check the kinds of objects by Tag, you should study again the "for" command, it has many variants for each special kind of class, you can read advanced C++ about list, vector, queue,etc.

for each(PhysicsBody* body in bodies) // This command will generate error when building android, you should edit as follow:  for (auto body : bodies) , this is the new standard for C++ v.11
{
if (body->getNode()->getTag() == 3) // If there is still  body of bricks, it means you haven't destroyed all yet.
{
isWin = false; // Not Win yet
}
}
// If navigate all isWin but not change, process Win game
if (isWin == true)
{
auto gameOverScene = GameOverScene::create();
gameOverScene->getLayer()->getLabel()->setString("You Win!");
Director::getInstance()->replaceScene(gameOverScene);
}
}

To call Tick() function, you should add this following command
this->schedule(schedule_selector(HelloWorld::tick),0); into the end of init() function

If you use scheduleUpdate(), you should build update(float dt) function

Build and Run now























In this lesson, we study how to:

+ Create physics world with Chipmunk
+ Move objects by dragging on the screen
+ Process collision
+ Win game, Over Game
+ Know a bit more about Vector

Some disadvantages of this game:

+ Lack of calculating scores
+ Lack of sounds ( you can add like the previous Game )
+ Lack of Levels
+ Lack of menu 
+ Graphics is bad.

* Notice when building Android, you must declare cpp files that is newly created into Android.MK file in prj.android folder, like this, notice the mark "\"








The last line without "\"

The above lines with "\"

GameOverScene.cpp is the Class that is newly created, so you must declare, but not need to declare in .h file

Notice that edit code exactly as new standard C++11, you can build APK successfully.

You can develop yourself if you have time :)

2 comments:

  1. Hi I want to know is there's a difference between using update(float dt)
    or tick(update). I mean for my they're very similar but I don't really know is using one or other is different ?
    Thank you for your answer :D

    ReplyDelete
  2. thanks for your tutorial.It worked for me.But the ball speed is getting slow after a while .How to fix it.I tried some ways but not worked. it would be grateful if you help me.

    ReplyDelete

Choose an Android item