I never talked about a previous contribution to the libGDX android/desktop OpenGL framework. It’s called Screen Editor. Its main use to use easily place and resize sprites in-game. I made it because I was tired to hard-code values for the design of my UIs.
The strip below explains its usage in images.
However, if I talk about it, it is to present the future of this application: the Physics Level Editor. This application will let people place their images where they want, but will also work together with the box2d-editor to build collision shapes. Camera viewport adjustment will be available too.
I’ll talk a bit more about it once I’ll have something to show. Stay tuned ;-)
I recently released a major update to the Universal Tween Engine (if you wonder what is this lib, see this post). I broke the TweenGroup API, but with a good reason: groups now support nested sequences, and they are pooled (if Tween pool is activated).
Have a look at the following code snippet to understand how groups can be used to create complex and powerful sequences:
// Create some powerful animation sequences! TweenGroup.sequence( TweenGroup.parallel( Tween.set(...), Tween.set(...), Tween.set(...) ), TweenGroup.tempo(1000), Tween.to(...), Tween.to(...), Tween.to(...), TweenGroup.parallel( Tween.to(...), Tween.to(...), Tween.to(...), TweenGroup.sequence( Tween.to(...), Tween.to(...) ) ) ).addToManager(manager);
Otherwise, a ton of useful stuff was added to the Tween API. Besides the .target() method that is used to set the target value(s) of an interpolation, there is now the following ones:
- .target(…): target values are the params
- .targetRelative(…): target values are the params added to the start values (at start time, after delay)
- .targetCurrent(): target values are the values at current time (ie. at method call time)
- .targetCurrentRelative(…): target values are the params added to the values at current time (ie. at call time)
Also, I added a SimpleTweenable interface, that extends Tweenable. It should be used when you don’t care about tween types since there should only be one possible. I added implementations for primitive types, like TweenableInt, TweenableFloat, etc.
Hello again !
Another post, this time to present the recent 1.0 release of the Box2D-Editor application.
The Box2D physics engine, like every other physics engine (Chipmunk, Farseer, etc.), can only check collisions between convex polygons, with at most 8 vertices. Therefore, if you need an Eiffel Tower in your game, you need to decompose it into convex polygons and then to enter their coordinates vertex by vertex. Said “tedious task” ?
I was saying that too, that’s why I made this application (I make every app because I need them). The Box2D-Editor provides a simple yet powerful interface to easily define the outlines of your assets. The decomposition into convex polygons is then automatic, using one of the provided decomposition algorithms (Ewjordan’s, Mark Bayazit’s). Convex polygons with more than 8 vertices are also automatically splitted.
The only things left are to save the result and to load it directly into your games. The output format is simple so you can easily write your own loaders. A loader implementation is provided for the LibGDX Android/Desktop library.
Google code project page:
Demo game (to show off the loader):
Note: if you create a loader implementation for any other library, whatever the platform (iOS, android, PC, …) and whatever the language (C++, C#, Java, objC, …), I would love to include it in the project, so others could use it too. Thanks in advance.
I really hope you will enjoy it as much as I enjoyed making it. Leave me a comment or a message if it helped you ;-)
The main ui, with “show grid” option enabled:
Using the built-in collision tester:
Built-in collision tester ??
Yep, you can test your bodies by throwing balls at them, in order to make sure that the collisions looks like what you were expecting. Said pretty cool ?
How do I use it ?
The steps are described directly in the tool, and help can be spawned by clicking on the “?” buttons that lie everywhere.
Basically, you just need to start by setting the output file (top left button). If the file already exists, the editor will ask you if you want to load its content. Then, you can add assets (images) to the editor and start defining their contour. Everything will be handled for you after that. However, remember to save your result ;-)
I once made a user interface for the libgdx texture packer. Since I never talked about it, here is a post to present it.
When using OpenGL, you usually want to draw models or sprites with some textures. Textures are images, and to draw these textures on screen, OpenGL needs to “bind” the first image, then the second, etc. However, binding a texture is not a cheap operation, especially on limited devices like smartphones (Android, iPhone, etc.). This is way developers tend to combine multiple small images into a bigger one. This way, the big image is bound once, and that’s all. Of course, you can choose to draw only a part of that big image at a time, this is the main interest.
The application I propose is a wrapper around Nate’s Texture Packer java class. I wanted to make that java class a standalone tool for my own usage. The wrapper is a dedicated user interface, but allows command-line support too, for direct inclusion into ant-like build workflows. Various settings can be easily exported and imported back.
Google code project page:
I hope you’ll find this contribution useful ;-)
Screenshot of the ui:
I released the incoming Box2D Editor for a beta-phase. More detailed on the following link, including help, tutorials, etc: http://www.badlogicgames.com/forum/viewtopic.php?f=17&t=1469
Of course, I’ll make a complete and fully detailed post once the beta phase will be over ;-)
I’m currently working on an open-source tool that will allow developers to easily create complex body shapes to use in the Box2D engine (well, actually the output format can let it be used for any physics engine).
I made it because of my own needs, but I’m sure it can help many people around here.
Available soon, stay tuned ;-)
Today I want to make a tutorial about collision filtering in the Box2D engine, because it is something that is not that easy to master, and yet it is a very powerful and useful feature.
Note: examples and source code are related to the LibGDX (Android) implementation of the Box2D API, but the concepts are the same for any other implementation, only the syntax may differ.
There are two ways to deal with collision filtering: by using categories and masks, or by using groups. These parameters can be found in the Filter component of a Fixture. Filtering collisions with any of these attributes will assure you that collision checks between two bodies that should not collide with each other will not be evaluated at all, resulting in a gain of speed.
To illustrate collision filtering, let’s take an example: we have three kinds of objects in a simple platformer game: players, monsters, and scenery.
We want the following rules: players should not collide with each others, neither do monsters, but players should collide with monsters (and vice-versa). Of course, players and monsters have to collide with the scenery. Scenery object will collide with each other (to build pyramids of crates for instance).
Filter categories and masks
Categories and masks are the most powerful way to deal with collision filtering, but also the most complicated for newcomers. The idea is to define a category per object type, and to use the masks to filter collisions between these object types.
Therefore, we start be defining three categories:
final short CATEGORY_PLAYER = 0x0001; // 0000000000000001 in binary final short CATEGORY_MONSTER = 0x0002; // 0000000000000010 in binary final short CATEGORY_SCENERY = 0x0004; // 0000000000000100 in binary
Then we can assign these categories to our objects:
player1FixtureDef.filter.categoryBits = CATEGORY_PLAYER; player2FixtureDef.filter.categoryBits = CATEGORY_PLAYER; monster1FixtureDef.filter.categoryBits = CATEGORY_MONSTER; monster2FixtureDef.filter.categoryBits = CATEGORY_MONSTER; monster3FixtureDef.filter.categoryBits = CATEGORY_MONSTER; monster4FixtureDef.filter.categoryBits = CATEGORY_MONSTER; groundFixtureDef.filter.categoryBits = CATEGORY_SCENERY; crate1FixtureDef.filter.categoryBits = CATEGORY_SCENERY; crate2FixtureDef.filter.categoryBits = CATEGORY_SCENERY;
Wait, 0x001, 0x002 and 0x004 ? Why not 1, 2 and 3 ? Because Box2D categories (and masks) are bit fields (coded as shorts, thus on 16 bits) ! That means that the possible categories are powers of 2 (in decimal: 1, 2, 4, 8, 16, 32, 64, 128…, or in hexadecimal: 0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80…). 16 bits means that there are 16 categories possible, from 0x0001 to 0x8000.
Now, let’s define the filter masks. Masks work as follows:
for each object o1 in the world for each object o2 in the world isCollisionEnabled = (o1.filter.maskBits & o2.filter.collisionBits) ≠ 0
Can you guess the resulting masks in our game ? They are as follows:
final short MASK_PLAYER = CATEGORY_MONSTER | CATEGORY_SCENERY; // or ~CATEGORY_PLAYER final short MASK_MONSTER = CATEGORY_PLAYER | CATEGORY_SCENERY; // or ~CATEGORY_MONSTER final short MASK_SCENERY = -1;
The “~” in front of a category name is a one’s complement in C family languages (including Java). For instance, ~0x0001 = 0xFFFE. In binary, it changes 0 into 1 and vice-versa.
Since the scenery category has to collide with everything, we just set its mask to -1, which also equals to 0xFFFF in a bit field (its due to the representation of signed numbers).
Using a 0xFFFF (or -1) mask will enable collisions with every category. As a contrary, setting a mask to 0x0000 (or 0) will disable collisions with everything !
We can assign these masks to our objects:
player1FixtureDef.filter.maskBits = MASK_PLAYER; player2FixtureDef.filter.maskBits = MASK_PLAYER; monster1FixtureDef.filter.maskBits = MASK_MONSTER; monster2FixtureDef.filter.maskBits = MASK_MONSTER; monster3FixtureDef.filter.maskBits = MASK_MONSTER; monster4FixtureDef.filter.maskBits = MASK_MONSTER; groundFixtureDef.filter.maskBits = MASK_SCENERY; crate1FixtureDef.filter.maskBits = MASK_SCENERY; crate2FixtureDef.filter.maskBits = MASK_SCENERY;
That’s all. Just let the magic of Box2D operates.
You can do everything you need with categories and masks, but sometimes you don’t need their bit-field complexity for some tasks. Groups were specifically introduced to quickly disable or enable collision checks between objects that are somehow related. The Box2D manual says:
Collision groups let you specify an integral group index. You can have all fixtures with the same group index always collide (positive index) or never collide (negative index).
Groups should be used instead of categories and masks when you only need to disable collisions between objects of a same category. Therefore, groups can be used in our illustration example, because everything should collide with everything, except players against players and monsters against monsters. We can shorten the previous setup to:
final short GROUP_PLAYER = -1; final short GROUP_MONSTER = -2; final short GROUP_SCENERY = 1;
And we assign these groups as follows:
player1FixtureDef.filter.groupIndex = GROUP_PLAYER; player2FixtureDef.filter.groupIndex = GROUP_PLAYER; monster1FixtureDef.filter.groupIndex = GROUP_MONSTER; monster2FixtureDef.filter.groupIndex = GROUP_MONSTER; monster3FixtureDef.filter.groupIndex = GROUP_MONSTER; monster4FixtureDef.filter.groupIndex = GROUP_MONSTER; groundFixtureDef.filter.groupIndex = GROUP_SCENERY; crate1FixtureDef.filter.groupIndex = GROUP_SCENERY; crate2FixtureDef.filter.groupIndex = GROUP_SCENERY;
That’s all. That’s two times less code than with categories and masks. However, there is no way to disable collisions between groups. That’s why categories and masks are more powerful than groups.
Collision filters are very valuable tools. Use them with care but use them everywhere. Collisions can also be disabled in the world contact listener, but collisions have to be checked first before a contact is reported, so this kind of filtering won’t remove the computational overhead of the collision check. Go the fixture filter way, always !
Besides Android game and Java/C# application developement, I’m also a Ph.D. candidate working in the fields of digital electronics. Good news, my latest conference paper has been approved for the FDL 2011 conference (IEEE supported).
Just wanted to share ;-)
I recently started to work on a real Android game. It features a little hero who loves to throw ropes at roofs and to balance from one to another.
At first, I want to make a simple game where the hero has to jump from one platform to another. The more precise the landing, the best score you’ll get. But I want to reuse the concept and the hero in a series of different games, from a simple jump-and-land game to a complete platformer.
Therefore, I developed a small prototype of the concept in order to test some gameplay ideas, don’t hesitate to test it ;-) (but I agree, the current control scheme is awful, I need to automatize and tweak many things).
Prototype download link:
Controls are as follows:
- Wait for the hero to be idle and ready.
- Touch and release anywhere once to jump.
- Touch and release once more to throw a rope. The rope is thrown where you release.
- (Optional) Touch and drag left or right to add some velocity to the hero. Release has no action.
- Touch and release to drop the rope.
That’s it, I just got married on 11 june 2011 !
Planning a wedding is the most tedious task that one can have to do, but it totally deserves the time invested. It was the best day of my life, until the next one ;-)