Testing out JMonkeyEngine

I have been wanting to get back into graphics and (perhaps) game programming, but not on such a low level as earlier. It seems most people these days use some form of engine, or at least a framework, and there are many too choose from, even many free ones. Many people are using Unity, and while I’ve heard great things about that, I’ve been checking out JMonkeyEngine, which seems like an excellent choice for those of us using Java. It also seem to be somewhat lower level than Unity, witch I think fits someone like me, who have more programming than artistic skills.

After going through the tutorials here, I was thinking about how to put it all together, and also get a better feel for the libraries and engine. I decided to implement the easiest real-time game I know: Pong.

Starting and geometries

To begin with, I made a main class extending SimpleApplication, with a main method to start it all. The first step of nitializing is to create meshes for the paddles, and the ball. These are made from simple boxes and spheres. I don’t need any textures or lighting, so the simple “Common/MatDefs/Misc/Unshaded.j3md” material is used. The sizes are based on the window size, so they look good no matter the resolution used. Th. Z axis is not used, but set to 10.0 for physics (more on that later). After creating, the geometries are attached to the GUI node, so it can be rendered in 2D.

Box paddleMesh = new Box(paddleWidth, paddleHeight, 10.0f);
Material paddleMaterial = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
paddleMaterial.setColor("Color", ColorRGBA.Blue);
Geometry leftPaddle = new Geometry("Left paddle", paddleMesh);

Do this for two paddles and a ball, and you end up with:



Next up, I created the physics system. While implementing the physics of pong would be pretty easy, I wanted to learn more about using Bullet, and I thought it was a good idea to do it with a simple project like this. I had never worked with Bullet (or JBullet) before, so it took some experimenting to make things work as I wanted. After creating the bulletAppState and registering it to the application, I created rigid body controls for both the paddles and the ball, so they can collide with each other. Giving the paddles mass zero while the ball has a non-zero mass, will ensure only the ball will change direction on collision, and giving the paddles restitution of 1.1 will make the ball increase speed each collision.After that it’s just a matter of giving the ball a little kick in the x direction.

leftPaddlePhysics = new RigidBodyControl(0.0f);

ballPhysics = new RigidBodyControl(1.0f);
ballPhysics.setPhysicsLocation(new Vector3f(settings.getWidth() / 2, settings.getHeight() / 2, 0f));
ballPhysics.setLinearVelocity(new Vector3f(BALL_SPEED * settings.getWidth() / 10, 0.0f, 0.0f));

To stop the ball disappearing out of the screen, I make some RigidBodyControls to cover the sides. Again, these will have mass 0, but unlike the paddles I don’t add any visible nodes to them. I make them thick enough so the collision detection don’t run into any problems.

RigidBodyControl topCourtPhysics = new RigidBodyControl(0f);
topCourtPhysics.setCollisionShape(new BoxCollisionShape(new Vector3f(settings.getWidth() / 2, 10f, 10f)));
topCourtPhysics.setPhysicsLocation(new Vector3f(settings.getWidth() / 2, settings.getHeight() + 10f, 0f));

I want to make the ball move up or down when hitting the paddle off-centre. To do this, I make my class implement the PhysicsCollisionListener interface and register it as a collision listener. In the collision function, I check if the collision is between a paddle and the ball, and give the ball a kick up or down as apropiate.

if ("Ball".equals(collision.getNodeA().getName())) {
ballPhysics.applyImpulse(new Vector3f(0f, 1.2f * (collision.getNodeA().getLocalTranslation().y - collision.getNodeB().getLocalTranslation().y), 0f), new Vector3f());
} else {
ballPhysics.applyImpulse(new Vector3f(0f, 1.2f * (collision.getNodeB().getLocalTranslation().y - collision.getNodeA().getLocalTranslation().y), 0f), new Vector3f());

You can’t see it in the picture but the ball is moving up after hitting the right paddle.
Ball moving up

I also need to check for collision between the ball and either the left or right side of the screen. In this case, one of the players will be awarded a point, and the game will stop.

if (leftCourtPhysics.getObjectId() == collision.getObjectA().getObjectId() || leftCourtPhysics.getObjectId() == collision.getObjectB().getObjectId()) {
running = false;


The input system is pretty simple, just up and down keys, and a key to start and toggle pause. The only thing to look out for is that I must move the physics objects of the paddles, and they will in turn move the geometries. I also check to make sure the paddles don’t go out of the screen. Because I’m moving the paddles manually, I don’t think it’s possible to use the collision system to do this.

if (name.equals("Up")) {
Vector3f current = rightPaddlePhysics.getPhysicsLocation();
rightPaddlePhysics.setPhysicsLocation(new Vector3f(current.x, current.y + paddleSpeed * value * speed, current.z));
if (rightPaddlePhysics.getPhysicsLocation().y > settings.getHeight() - paddleHeight) {
rightPaddlePhysics.setPhysicsLocation(new Vector3f(current.x, settings.getHeight() - paddleHeight, current.z));


The GUI is really simple, just a couple of BitmapTexts to show the scores. These are updated when the game detects a collision with the left or right wall. Remember to make sure the score board is rendered on top of the ball using the Z position.

guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt");
leftScoreText = new BitmapText(guiFont, false);
leftScoreText.setSize(guiFont.getCharSet().getRenderedSize() * 3);
leftScoreText.setLocalTranslation(100, settings.getHeight() - leftScoreText.getLineHeight(), 10);



Adding audio is very easy with JMonkeyEngine. Just remember that if you use a Maven project, the files should be placed in /src/main/resources. I add one looping AudioNode for music, and others for effect, and I play the effects in the collision callback method.

AudioNode music = new AudioNode(assetManager, "assets/Sounds/Cycles.ogg", DataType.Stream);
AudioNode blopp = new AudioNode(assetManager, "assets/Sounds/blopp.ogg", DataType.Buffer);


I made a very simple AI, that just tries to keep the centre of the paddle in line with the ball. Like the player, the AI can move up, down, or not at all.

int move = 0;
if (ball.getTranslationMatrix().m31 > cpuPaddle.getTranslationMatrix().m31 + 1.5) {
move = 1;
if (ball.getTranslationMatrix().m31 < cpuPaddle.getTranslationMatrix().m31 - 1.5) {
move = -1;
leftPaddlePhysics.setPhysicsLocation(new Vector3f(current.x, current.y + ((paddleSpeed * tpf * speed) * move), current.z));

Originally it looked at the ball and paddle centre, but this caused it to go back and forth a lot, since the paddle can move faster than the ball in the y direction. Giving it some slack makes the movement much more smooth and nice.

Wrapping up

I found that doing a small, but nonetheless complete game like this after going through all the individual tutorials, was very useful. The individual parts of the engine affect each other in ways that is difficult to predict, but it really helpful to experience this with a game which is familiar. Some other things I have learned doing this small project:

  • It seems the input system would not be called every frame if the frame rate is high. This made the player input and the AI input run at different speeds. I locked the game to run at 60 FPS, and that worked fine.
  • It’s inconvenient to mix physics based movement and movement directly from player input. But in a real game, I probably wouldn’t let the player control them self directly, but rather by using forces anyway.
  • While I haven’t tried the JMonkeyEngine SDK/IDE, using it with Maven and Eclipse works just fine.
  • Even for a very small and simple game like this, it’s more work than expected, especially all the small things that pop up. If I also need to invent gameplay, I expect it to be a lot more.

So that’s my experiences with JMonkeyEngine in a full (albeit small) project. In general good experience so far, but I will try to do other more advanced projects in the coming months.


Tags: , ,

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: