Quantcast
Channel: gameit.ro
Viewing all articles
Browse latest Browse all 10

How To Make a Catapult Shooting Game with Cocos2D-x and Box2D

$
0
0

Thanks to some really hard work from Gustavo Ambrozio from raywenderlich.com we now have a new tutorial to explore the intriguing world of Box2D and Cocos2D.

In the first part of his How To Make a Catapult Shooting Game with Cocos2D and Box2D tutorial, Gustavo takes us through the very first steps of setting up the Box2D world, creating the catapult using revolute joints, arming it and launching the projectile. Although this may seem like quite a lot of work, it is actually quite simple to grasp.

As always, I have ported the tutorial code to Cocos2D-x. I tried to keep in line with Gustavo’s naming convention, however, I could not bear to use member variables without marking them in some way. By the way, I went with Cocos2D-x‘s convention of naming the members with m_ as a prefix.

Lessons learned

git tags

I can also say I learned a couple of new tricks with git, namely creating and managing tags. Gone are the days when I created a new project for each tutorial part. With the help of tags I can now manage the chapters in a way that does not spam GitHub‘s project list.

To create a tag you can do the following:

git tag -a BulletCreation

To view the list of existing tags, just do:

git tag

To push the list of tags to the remote server, you can do:

git push --tags

Using std::vector

Gustavo’s tutorial stored references to the bullet in an NSMutableArray. Since bullet is a b2Body object you cannot directly store it into an NSArray, so we employ a trick and store only a reference to it using [NSValue valueWithPointer:bullet]. Trouble is, you don’t have NSValue in Cocos2D-x and CCMutableArray can only store objects derived from CCObject.

So what do we do?

Make use of C++’s standard std::vector!

When you declare a std::vector, similarly to when you declare a CCMutableArray, you need to decide what kind of objects will be stored inside it. For example, in our case, we want to store b2Body objects, therefore we need to declare our vector as

std::vector<b2Body *> m_bullets;

Take note that m_bullets is not a pointer, but a statically allocated vector that stores pointers to b2Body objects.

To add a new object to the vector we do:

m_bullets.push_back(bullet);

bullet, of course, is declared as b2Body *bullet.

Update: push_back will store a copy of your object and not your actual object. See also erase().

To count the number of items in a vector we use the size() function as follows:

m_bullets.size()

To access an item at a given index we use at():

m_bulletBody = (b2Body*)m_bullets.at(index);

And finally, to delete remove objects from the vector we can use the erase() function:

m_bullets.erase(index);

Edit: after Bob’s comment below, I updated the text above to clarify that erasing an element from the vector will not deallocate it, it will merely remove the reference to that object from the vector. Freeing the memory occupied by the object you just removed from the vector is still your responsibility. So, after calling erase() make sure you always deallocate the object if that’s the case (for example, using delete);

Edit edit: After careful re-reading of the documentation, push_back actually stores a COPY of the object you send as a parameter. When you call erase that object is removed from the vector, its destructor called and the memory freed.

You can learn more about std::vector from the C++ Reference.

Project source code

Here are the tags that we have so far, in order:

Part 1

And this is what the project looks like so far after Part 1 was completed:

You can launch one acorn and the camera will follow it all the way to the right when it hits a wall an bounce back to the squirrels. Cute, ain’t it?


Viewing all articles
Browse latest Browse all 10

Trending Articles