Spawn bodies on touch - Leakedbits/Codelabs GitHub Wiki

This tutorial tries to explain our SpawnBodiesSample, where rounded figures appear as you touch the screen and bounce off each other.

First off, we need to take into account a couple of concepts learned in our first tutorial, BouncingBall. We are going to need our OrtographicCamera, World, Box2DDebugRenderer objects, and render(), createWalls(), dispose() and show() methods. But for this last one we don't need to create the ramp or the same tiny ball from the previous sample, so forget about it and don't show them neither.

To avoid having a lot of bodies, we set the constant maximum number of them to 20 and we declare the variable to store how many balls we have already spawned.

private static final int MAX_SPAWNED_BALLS = 20;
private int spawnedBalls;

Now we are going to grow some balls. Its the same idea as before but with an obvious change you will understand right away: now the place where our bodies will spawn is not fixed but relative to where we touch the screen, so let's pass its coordinates as a parameter. Also we will increase the radius of the balls. And we end up with this:

private void createBall(float x, float y) {
	/* Ball body definition. */
	BodyDef bodyDef = new BodyDef();
	bodyDef.type = BodyType.DynamicBody;
	bodyDef.position.set(x, y);

	/* Shape definition (the actual shape of the body) */
	CircleShape ballShape = new CircleShape();
	ballShape.setRadius(1f);

	/*
	* Fixture definition. Let us define properties of a body like the
	* shape, the density of the body, its friction or its restitution (how
	* 'bouncy' a fixture is) in a physics scene.
	*/
	FixtureDef fixtureDef = new FixtureDef();
	fixtureDef.shape = ballShape;
	fixtureDef.density = 2.5f;
	fixtureDef.friction = 0.25f;
	fixtureDef.restitution = 0.75f;

	/* Create body and fixture */
	world.createBody(bodyDef).createFixture(fixtureDef);

	/* Dispose shape once the body is added to the world */
	ballShape.dispose();
}

We need the event that triggers the spawning of the bodies. Fortunately, the framework provides us where the user has touched with parameters screenX and screenY. We won't be needing those pointer and button parameters because we are only spawning bodies by touching the screen, not buttons. Remembering our MAX_SPAWNED_BALLS limitation, we create a Vector3 and we set its x and y coordinates to where the user has touched (we don't need the z axis because this is a 2D environment, so it's 0). Then we unproject() that vector, or translate the coordinates into our world's camera, and we create the ball with the coordinates our world understands.

@Override
public boolean touchUp(int screenX, int screenY, int pointer, int button) {
	/* Checks whether the max amount of allowed balls has not been reached */
	if (spawnedBalls < MAX_SPAWNED_BALLS) {
		spawnedBalls++;

		/* Translate camera point to world point */
		Vector3 unprojectedVector = new Vector3();
		camera.unproject(unprojectedVector.set(screenX, screenY, 0));

		createBall(unprojectedVector.x, unprojectedVector.y);
	}

	return true;
}

Yep, we are finished. I'm sure you know how to have some more fun with the restitution of your walls and balls ;)

Remember! You have all this working code in our SpawnBodiesSample class.