Reuse Box2D objects in LibGDX game (pooling) - java

I'm working in a game in which I spawn an object every 1-3 seconds. This game object contains some assets for renderization purposes and a Box2D body. The thing is that I don't want to create thousands of objects. Instead, I would like to reuse them, resetting its properties (position, friction, etc.) and not creating a brand new object. I think that the best way to do this is implementing a pool of this objects but I'm concerned about it because after search for some info I've found several developers reporting memory leaks because all the objects created by Box2D internally.
What do you think is the best way to do this?
This is the class that I use to represent each game object:
public class GameObject extends Box2dGameObject {
private static final float WIDTH = 0.85f;
private static final float HEIGHT = 1;
private Animation animationDying;
private Animation animationFalling;
private Animation animationIdle;
private Animation animationJumping;
private Animation animationRunning;
private Body body;
public GameObject(Vector2 position, World world) {
super(position, world);
init();
}
private void init() {
super.init();
dimensions.set(WIDTH, HEIGHT);
/* Get assets */
animationDying = Assets.instance.pirate.animationDying;
animationFalling = Assets.instance.pirate.animationFalling;
animationIdle = Assets.instance.pirate.animationIdle;
animationJumping = Assets.instance.pirate.animationJumping;
animationRunning = Assets.instance.pirate.animationRunning;
/* Set default animation */
setAnimation(animationIdle);
body = createBox2dBody();
}
private Body createBox2dBody() {
BodyDef bodyDef = new BodyDef();
bodyDef.fixedRotation = true;
bodyDef.position.set(position);
bodyDef.type = BodyType.DynamicBody;
PolygonShape shape = new PolygonShape();
shape.setAsBox(WIDTH / 2, HEIGHT / 2);
FixtureDef fixtureDef = new FixtureDef();
fixtureDef.density = 1;
fixtureDef.friction = 1;
fixtureDef.shape = shape;
Body body = world.createBody(bodyDef);
fixture = body.createFixture(fixtureDef);
shape.dispose();
return body;
}
/* More code omitted */
}

This seems like a case of early optimization and may not yield the results you are looking for.
Consider:
All those objects sitting your "pool" are still registered internally in Box2D as objects. Will collision checking be performed on them? Will collision response? Will their usertag be pointing to an object in the "pool" (user tags are often used to reference the "owner" of the body)?
There are life cycle issues associated with all the values in an
object...you will have to be careful to manage the values (position is easy, but collision flags etc. gets deeper) for each object you take into and pull out of the pool. That sounds error prone.
If you are really only creating/destroying a single object every second, that does not seem like much of a performance/memory hit. If you are creating hundreds, that is a different story. I wrote a game where I had bullets being generated at a rate of 10-20 per second...each was derived from an "Entity" base class which is a composite (I called the class "Slug" I think). The "Slug" class held the body, the sprite, the collision handling logic, etc. When it collided or after a few seconds, it "died" and went into the pool. Pulling it from the pool caused it to re-create the body and I did not see this as a performance or memory bottleneck.
It did not recreate the parts that may cause larger allocation or were not necessary (e.g. the sprite). These don't need to be reclaimed until it is actually deleted from the pool because it is really just a reference to a sprite sheet that is shared. A specific "Init(...)" method was associated with the class so that the memory allocation could be separate from the initialization.
Your mileage may vary, of course. But I think you should look to see if it is really a problem (i.e. prototype it) before you build infrastructure to fix it.

Related

Is enumeration the right tool for generating creatures in a roguelike game?

I'm developing a roguelike game as a programming/database excercise and a hobby(and because I want to have my own "Dwarf Fortress" project to lord over as I please). I got stuck quite early while trying to write a robust enough system to generate various creatures in the game. I started simple; lets say I want the game to spit out a wolf somewhere(FXML, so Controller):
public class Controller {
Creature pooch = new Creature(Species.WOLF);
}
Now, I'd like to be able to spawn these ordinary animals by only specifying their species, so that's what enumerations are for, no? I want to specify that wolves only eat meat, their possible body sizes(they're not clones after all, and where else to specify the sizes?), and the body type they have:
public enum Species {
// Canines
WOLF(Diet.CARNIVORE, 1050, 1325, 1600, CANINE.BodyPattern);
// Canine constructor
Species(Diet diet, double bodySizeMultiplierMin, double bodySizeMultiplierAvg, double bodySizeMultiplierMax,
BodyPattern bodyPattern) {
this.diet = diet;
this.bodySizeMultiplierMin = bodySizeMultiplierMin;
this.bodySizeMultiplierAvg = bodySizeMultiplierAvg;
this.bodySizeMultiplierMax = bodySizeMultiplierMax;
}
I want to reuse the same pattern for dogs, jackals, etc., so I only pass the body type, to be defined in another enum.
enum BodyPattern {
CANINE(furryUpperBody, furryLowerBody, canineHead, canineMaw, canineLegs, furryTail);
LinkedList<BodyPart> bodyPartsList;
BodyPattern(BodyPart... args) {
for (BodyPart part : args) {
bodyPartsList.add(part);
}
}
}
This is where I'm getting really lost(I didn't actually define any of those body parts, as I wasn't sure how to proceed). This is what I have for BodyPart so far:
public class BodyPart {
public String name;
private TissueLayer[] tissueLayersUp;
private TissueLayer[] tissueLayersDown;
private TissueLayer[] tissueLayersFront;
private TissueLayer[] tissueLayersBack;
private TissueLayer[] tissueLayersLeft;
private TissueLayer[] tissueLayersRight;
public BodyPart(String name, BodyPart[] appendages, int height, int width, int length, TissueLayer[] tissueLayersUp,
TissueLayer[] tissueLayersDown, TissueLayer[] tissueLayersFront, TissueLayer[] tissueLayersBack,
TissueLayer[] tissueLayersLeft, TissueLayer[] tissueLayersRight) {
this.name = name;
this.appendages = appendages;
this.height = height;
this.width = width;
this.length = length;
this.tissueLayersUp = tissueLayersUp;
this.tissueLayersDown = tissueLayersDown;
this.tissueLayersFront = tissueLayersFront;
this.tissueLayersBack = tissueLayersBack;
this.tissueLayersLeft = tissueLayersLeft;
this.tissueLayersRight = tissueLayersRight;
}
}
Tissue layers are the stuff that makes up the body parts, and are specified for each direction separately so that for example an attack against the front of the head damages the face, while an attack from the back goes against the neck/upper spine first. I want their thickness to be defined in relative terms only, to be multiplied upon generation by the size of the creature to generate the actual size, but as I said, I'm getting a bit lost, So where do I go from here? Should I reassign BodyPart as enum? Should I make another enum entirely? Am I completely off the track and should I use some different tool?
Now, I'd like to be able to spawn these ordinary animals by only
specifying their species, so that's what enumerations are for, no?
I'm afraid not, no.
The best use case for enums is the enumeration of a set of objects which are constants and the identities of all of which are known at compile time. An example of data for which enums are ideal is playing cards or the planets of the solar system. Playing card suits and numbers are fixed, constant, and known in advance. Similarly, the planets in the solar system do not (frequently) change.
Since you want to be able to dynamically create objects at need, you'll want to use ordinary classes with constructors to create new objects (such as animals) when your program needs them. It would be difficult to imagine a game that knows in advance all the animals it needs (with all their properties).

Pooling Box2d Bodies?

I'm trying to spawn chunks by pooling box2d Bodies, I don't know if libgdx pooling is applicable to bodies but if it is please someone explain me how to do it and what's wrong with my code.
first I created the BodyDef and Body on seperate methods:
public BodyDef createDef(){
BodyDef def = new BodyDef();
def.type = BodyDef.BodyType.StaticBody;
def.fixedRotation = true;
def.position.set(6, 6);
return(def);
}
public Body createBody(){
Body body = world.createBody(createDef());
PolygonShape shape = new PolygonShape();
shape.setAsBox(1, 1);
body.createFixture(shape, 1.0f);
shape.dispose();
return(body);
}
public void createPlatform(){
Body platform = Pools.obtain(Body.class); //then use pooling
platform = createBody(); //here I set the value equal to the return value of createBody() method
bodies.add(platform);//adding platform to the ArrayList
}
then to spawn chunks I simply call this method:
public void spawnChunk(){
createPlatform();
}
I'm so new to this I don't know what's the meaning of chunk but I know that is used on side scrolling game for spawning terrain, I get this error message:
Exception in thread "LWJGL Application" java.lang.RuntimeException: Class cannot be created (missing no-arg constructor): com.badlogic.gdx.physics.box2d.Body
at com.badlogic.gdx.utils.ReflectionPool.<init>(ReflectionPool.java:41)
at com.badlogic.gdx.utils.Pools.get(Pools.java:29)
at com.badlogic.gdx.utils.Pools.get(Pools.java:38)
at com.badlogic.gdx.utils.Pools.obtain(Pools.java:48)
at com.nivekbryan.ragingpotato.Physics.createPlatform(Physics.java:53)
at com.nivekbryan.ragingpotato.Physics.spawnChunk(Physics.java:59)
at com.nivekbryan.ragingpotato.WorldController.update(WorldController.java:17)
at com.nivekbryan.ragingpotato.MainClass.render(MainClass.java:27)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication.mainLoop(LwjglApplication.java:215)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication$1.run(LwjglApplication.java:120)
Don't use pooling for box2d bodies or joints, from the box2d wiki:
So when you create a b2Body or a b2Joint, you need to call the factory
functions on b2World. You should never try to allocate these types in
another manner.
So you only should use Body body = world.createBody(bodyDef); to create bodies.
Next you add the bodies in some kind of list, which one should never do! If you need to access all bodies in your world, then do it like this:
// Global field
Array<Body> bodies = new Array<>();
// When you want to access the bodies.
world.getBodies(bodies);
for(Body body : bodies)
{
// Do something
}
The error means that the Body class has no constructor that looks like
public Body() {}
And thus can not be created by the generic pool class implementation, since it tries to call this constructor.
To solve this you could implement the pool yourself, but as stated above, you should not do this.
Another error with your current code is that you seem to misunderstand variable assignment in java.
// gets a body from your pool, arbitrary method
Body pooledBody = getFromPool();
// assigns a new body to pooledBody, so your pooling is "voided".
pooledBody = world.createBody(createDef());
As you can see in this example the getFromPool(); has no effect, since you assign a new value to pooledBody in the next line.
A more simple example, on why it does not work as you wish:
int a = getFromPool(); // lets says this assigns 4 to a
a = 5;
System.out.println(a);
Will always print 5, never 4!
What you can pool is BodyDef, FixutureDef and the Shape classes, since these have no argument constructors.

Is Bitmap object held in memory by reference?

Please forgive me for what is likely an incredibly cringeworthy question (I am quite new to both Java and Android Studio). I come from a C background and am currently developing a mobile app for Google Play using Android Studio. The application will require a number of enemy objects to be created for the game.
Consider the following method of creating a Bitmap for an enemy object;
Within the GamePanel class (parent is SurfaceView, implements SurfaceHolder.Callback);
enemy = new Enemy(BitmapFactory.decodeResource(getResources(), R.drawable.enemy_pic));
Within the Enemy class, our image is declared as an instance variable;
private Bitmap image;
And then we initialise it in the constructor (picResource is the first argument into the constructor);
image = picResource;
My question is the following - if I create a list of enemy objects (there are lots of enemies!), will this result in the duplication of the Bitmap data? I am not sure from the docs whether it's lower level implementation will emulate pointer behaviour in C, and as such result in only minimal overhead from structuring it this way, or whether I am chewing up memory because I am essentially duplicating all the data in the picture file.
I create a list of enemy objects (there are lots of enemies!), will this result in the duplication of the Bitmap data?
Every call to decodeResource() will result in result in a new in-memory bitmap. If you create all your enemies as in your question:
enemy = new Enemy(
BitmapFactory.decodeResource(getResources(), R.drawable.enemy_pic)
);
every Enemy object will have its own unique bitmap.
That is, if you put this in a loop
List<Enemy> enemies = new ArrayList<>();
for (int i = 0; i < nEnemies; ++i) {
enemy = new Enemy(
BitmapFactory.decodeResource(getResources(), R.drawable.enemy_pic)
);
enemies.add(enemy);
}
You will get nEmemies bitmaps, i.e. each Enemy object has its own (in-memory) bitmap.
If you decode your enemy bitmap only once and pass the resulting reference to the Enemy constructor, you just create new reference to the single existing bitmap. That is, rewriting the above as (for example)
List<Enemy> enemies = new ArrayList<>();
Bitmap enemyBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.enemy_pic);
for (int i = 0; i < nEnemies; ++i) {
enemy = new Enemy(enemyBitmap);
enemies.add(enemy);
}
results in only a single bitmap to be shared by all enemies (unless Enemy does something to the bitmap to create a copy).
To refer back to your answer. In Java, assignments of the form
image = picResource;
do not create copies, but only create additional references (to be precise, this is only true for reference types, i.e. objects).
Side note: if you use Context.getDrawable(), you can make use of use of Android's drawable cache and get the same drawable even for repeated calls.

Is this a valid use of the builder pattern in Java (or even good OO design)?

Being fairly new to OO, I often feel I understand a concept until I try to move from a simplified example to actual requirements I am given. I'd appreciate any help understanding how to think about this particular problem.
I have a GUI which has a panel that defines a container and items that go in it. Right now, there are three types of containers. The containers have some properties (like size) and can contain one to three different types of items (two are optional). Once enough information is entered, I use the information to make a graph.
I implemented an Observer pattern. When the user enters information, it updates an observable, which notifies the graph that it has changed.
I'm happy so far. Now the wrinkles. My containers have a size, but sometimes it is entered explicitly and sometimes it is determined by what the container is holding. That is determined by the type of container. How the size is determined, if not entered explicitly, depends on whether one of the optional items is in the container. I'm not sure if the requirements writer just hates me or I am lacking enough OO experience, but those wrinkles are giving me fits. Right now, my observable just has variables to hold all the assorted information and I use a bunch of switch statements to handle the special cases.
I am thinking that I could use the builder pattern. The director would produce the data that was graphed. I would have a concrete builder for each type of container and I would instantiate the class with the container properties and the items inside it. I would have methods of the abstract builder class to return to the director the values needed for the graph, for example getContainerSize() and combine these to produce the actual data points. Also, the director could return null if the user had not yet entered enough data to complete a graph.
Am I getting close to a usable OO design? I'm not sure I didn't just bury the special casing a bit deeper.
One other wrinkle. One of the item types goes in all three containers. Right now, my observable keeps track of the container and items separately and the method that creates the graph decides what to ask for (the graph changes a lot as users play around with the values). How's that work if I have multiple builder patterns?
Maybe I am missing a step? The observable updates the builder of the current container then lets the graph know it should call the director to get its coordinates? Which would then also need to ask what the current container was?
All comments welcome that help me get my head around OO design or this problem in particular. The actual requirements have more special cases, but are variations on this basic theme.
Thanks for the replies. I think I am guilty of mixing two questions together. Here is an attempt to provide a minimal code example focusing on the Builder pattern. Note IE8 I see no identation, FireFox 8, I do- so sorry to anyone reading the code in IE8.
interface MyContainerBuilder
{
void setContents( MyContents contents );
Double myVolume();
Double myDensity();
}
class SmallContainerBuilder implements MyContainerBuilder
{
Double volume = null;
Double density = null;
MyContents contents = null;
public void setVolume()
{
if (contents != null)
{
volume = contents.myDensity() / 3.0;
}
}
public void setContents( MyContents contents )
{
this.contents = contents;
}
public Double myVolume()
{
if (volume == null)
setVolume();
return volume;
}
public Double myDensity()
{
return contents.myDensity();
}
}
class BigContainerBuilder implements MyContainerBuilder
{
Double volume = null;
Double density = null;
MyContents contents = null;
public void setVolume( Double volume )
{
this.volume = volume;
}
public void setContents( MyContents contents )
{
this.contents = contents;
}
public Double myVolume()
{
return volume;
}
public Double myDensity()
{
return contents.myDensity();
}
}
class ContainerDirector
{
Double myResult( MyContainerBuilder container )
{
return container.myVolume() * container.myDensity();
}
}
class MyContents
{
Double density;
MyContents( Double density )
{
this.density = density;
}
public Double myDensity()
{
return density;
}
}
class Test
{
public static void main(String[] args)
{
SmallContainerBuilder smallContainer = new SmallContainerBuilder();
BigContainerBuilder bigContainer = new BigContainerBuilder();
ContainerDirector director = new ContainerDirector();
//
// Assume this comes from the GUI, where an ActionListener knows which Builder
// to use based on the user's action. I'd be having my observable store this.
Double density = 15.0;
MyContents contents = new MyContents( density );
smallContainer.setContents( contents );
//
// Then I would need to tell my observer to do this.
Double results = director.myResult( smallContainer );
System.out.println( "Use this result: " + results );
}
}
I have two types of containers that use a different method to calculate the volume. So let's say I have radiobuttons to select the container type and under each radiobutton a combobox of items that can go in the selected container. The ActionListener on the combobox will put the item in the right container and save it to my observable (there are lots of other things that actually get set) and it tells my observer to use the director to get an appropriate value and the observer then updates some view component of the GUI.
My containers have a size, but sometimes it is entered explicitly and sometimes it is determined by what the container is holding. That is determined by the type of container. [...] if not entered explicitly, depends on whether one of the optional items is in the container.
Sounds like you could have different subclasses of an abstract container, each implementing getContainerSize() in a different way. One for explicitly entered, one for the case with optional item and one without it.
... and I use a bunch of switch statements to handle the special cases.
Does not sound great. Replace Conditional with Polymorphism if applicable.
I am thinking that I could use the builder pattern...
I assume that you need to determine a concrete type of object (or null) based on a set of input variables. The pattern provides a way to build a complex object if it knows what type that is, but the actual problem is to decide which type. So you need conditional code at some place. That place can be a builder but it could be simple factory as well.
Right now, my observable keeps track of the container and items separately[...] observable updates the builder of the current container[...] How's that work if I have multiple builder patterns?
Not really understanding what that Observable is observing and what changes in which case are triggering what, but Observable updating a builder (or multiple) sounds strange. That's more of a gut feeling though :)
Am I getting close to a usable OO design?
If it works, yes. But I actually can't tell you if you have created a good or usable design because I still don't know the details of your problem or your design - after reading your text several times now.
Instead of adding another page of information to your question now, try to break your problem down into smaller pieces and use code snippets / images / graphs or any type of visualization to help people understand your problem and all the connections between those pieces. Just a lot of text is rather scary and a huge OO design like that is as a whole too big and too localized for SO.
Your approach seems fine but it requires IMO quite complex Objects to justify that use.
You create a MyContents instance in your GUI via the observer. That object is then wrapped in a MyContainerBuilder which is then given to a ContainerDirector which then produces a result. That is in my opinion one step too much if MyContents or the result is simple.
Also the way you set the MyContents to the MyContainerBuilder means that you can't reuse the same concrete MyContainerBuilder instance blindly. You either have to make sure that you use it sequentially or you have to construct a new one every time.
I.e this does not work
MyContents content1 = new MyContents( 5 );
MyContents content2 = new MyContents( 6 );
smallContainer.setContents( content1 );
smallContainer.setContents( content2 ); // overwriting old state
Double results1 = director.myResult( smallContainer ); // wrong result
Double results2 = director.myResult( smallContainer );
I assume that MyContents is a generic data holding object that is filled with data in several steps by the user. Once the user is happy with it, it is submitted to be build into a result. As far as I can tell, you know at that point what the result has to be.
Below is an approach using a Strategy Pattern(? - I'm bad with all those names and little differences) which I chose to plug into the MyContents directly so the MyContents object once finalized has all details how it has to be transformed into a result. That way safes one step and you don't need to create / maintain extra builder objects. MyContents is already in a way a Builder now.
interface VolumeStrategy {
Double calculateVolume(Double density);
}
class SmallVolumeStrategy implements VolumeStrategy {
public Double calculateVolume(Double density) {
return density / 3.0;
}
}
class BigVolumeStrategy implements VolumeStrategy {
public Double calculateVolume(Double density) {
return density;
}
}
class ContainerDirector {
Double myResult( MyContents container ) {
Double density = container.myDensity();
VolumeStrategy strategy = container.myStrategy();
return density * strategy.calculateVolume(density);
}
}
class MyContents {
// built via observer
Double density;
MyContents( Double density ) {
this.density = density;
}
public Double myDensity() {
return density;
}
// plugged in at the end.
VolumeStrategy strategy;
public void setStrategy(VolumeStrategy strategy) {
this.strategy = strategy;
}
public VolumeStrategy myStrategy() {
return strategy;
}
}
public class Test {
public static void main(String[] args) {
// all those can be static
VolumeStrategy smallStrategy = new SmallVolumeStrategy();
VolumeStrategy bigStratetgy = new BigVolumeStrategy();
ContainerDirector director = new ContainerDirector();
// from the GUI
Double density = 15.0;
MyContents contents = new MyContents( density );
// building this contents ...
// ... time to submit, we know what strategy to use
contents.setStrategy(smallStrategy);
// can turn contents into result without needing to know anything about it.
Double results = director.myResult( contents );
System.out.println( "Use this result: " + results );
}
}
That's a way what I think should work well for the problem I imagine you have. I can be wrong tough.

The Android draw order for bitmaps, drawables and text?

I'm creating a small game in android. Anything that needs to be drawn on screen extends my VisibleObject class, I then have a Manager class that i can add all my visible game objects to and each frame i tell the manager to call the draw function of everything within it.
Here's were objects are initialised and added to the manager:
#Override
public void surfaceCreated(SurfaceHolder holder) {
fps = new TextDrawable(Color.BLACK, 14, 100, 40, 40);
player = new Player();
map = new Map();
leftTouch = new TouchCircle(Color.GRAY);
manager.add("fpsText", fps);
manager.add("leftTouch", leftTouch);
manager.add("player", player);
manager.add("map", map);
gameloop = new GameLoop(getHolder(), this, fps);
gameloop.setRunning(true);
gameloop.start();
}
Now the problem i'm having is with the draw order, if you look at the order the objects are added to the manager for reference..
I can tell you for certain that the player is being drawn on top of
the map! These are both drawn by drawing there respective bitmaps with drawBitmap(..).
However the fpsText and leftTouch are being drawn underneath the map! These are drawn using drawText(..) and drawOval(..) respectively.
Even though they implement different Canvas.draw.. functions, I would expect them all to be drawn in order as I just pass the canvas object i have to my manager class and then let the manager cycle through each object passing it that canvas to draw with.
Can anyone clear up for me why bitmaps seem to be drawn on top and what the solution should be to get my fps and touch area drawn above the player and map bitmaps? I'd Appreciate it.
EDIT: I am using private ConcurrentSkipListMap<String, VisibleObject> objectMap; within my manager to store the objects and drawing like so..
public void draw(Canvas c){
for (Map.Entry<String, VisibleObject> object : objectMap.entrySet()){
synchronized(object){
object.getValue().draw(c);
}
}
}
Bitmaps are not drawn on top of the text unless you draw Bitmap after you drawn text (and position overlaps).
You haven't disclose onDraw method so I can't be sure, but I suspect that you are not calling drawing methods in right order.
How does you manager stores the values added to it? Maybe you use Map implementation that doesn't maintain order of elements added (most implementations don't, LinkedHashmap does).

Categories