Tuesday 30 July 2013

Handling User Input and Simple Joints in JBox2D

Introduction to handling user input

Sticking with the original theme of a pinball machine, in this post I will demonstrate how we can model a simplified pinball machine plunger that responds to a user's input and how we can use Joints to create flippers for our pinball machine.

In this model, the plunger applies a certain amount of force to a ball based on how long a button is pressed (up to a maximum i.e. modelling the plunger being pulled back as far as it can go). 

With a view to eventually, in the future, transforming a gesture interpreted by the Leap Motion Controller as pulling back the plunger in to input for our pinball machine. 

The code below creates a simple test which responds to the user pressing the 's' key in order to launch the pinball - the longer the key is held down the harder the pinball is fired. The complete code can be found on Github. Let's work through the code and look at the key, new elements.

On lines 72 to 104, we provide our own implementations for the keyPressedkeyReleased and step methods:
  • In the keyPressed method, the simulation acts based on the key which has been pressed (down) by the user. In this case we only handle when 's' is pressed down, but by adding new Cases to the Switch statement we can add more functionality. The logic in the body of the method is based on the knowledge that when a user holds down a key, the keyPressed method will continue to be called. As such, the amount of force that we should apply to the pinball is increased; up to a maximum. 
  • When the user lifts their finger, and the pressed key's contact no longer connects with the underlying circuit, the keyReleased method is called. We use this as the trigger for applying the user-determined force to the pinball.
  • In the step method, we are simply adding a message, with instructions for the users, to the testbed GUI.  

Joints in JBox2d

A problem with the simulation is that the modelled plunger is not attached to anything, so after the pinball has been launched, further interaction from the user (force applied) will cause the plunger to jump up the screen.

Looking at the Box2D documentation, we can see that Joints can be used to solve this problem; by affixing the plunger to the ground. 
  • Joints - "Joints are used to constrain bodies to the world or to each other... Joints can be combined in many different ways to create interesting motions. Some joints provide limits so you can control the range of motion. Some joint provide motors which can be used to drive the joint at a prescribed speed until a prescribed force/torque is exceeded."
  • Distance Joint - "One of the simplest joint is a distance joint which says that the distance between two points on two bodies must be constant."
Another piece of the puzzle is how we can use Joints to "create interesting motions" and "limit the range of motions". Looking back at the documentation on Joints reveals to us a Joint which will be very useful in creating the flipper for our pinball machine: the Revolute Joint:

  • Revolute Joint - "A revolute joint forces two bodies to share a common anchor point, often called a hinge point... A joint limit forces the joint angle to remain between a lower and upper bound."
The joints in the simulation can be seen in blue
I chose to use rectangles as simple representations for the flippers. I positioned them towards the bottom of the canvas, affixed one end of each of the flippers to the canvas using a Revolute Joint to form a hinge and then configured each joint to constrain the range of motion of the flippers - to three quarters of a radian (roughly 42 degrees) which seems like a realistic enough range of motion. 

In the picture you can see the three Joints which I have created depicted with light blue lines; the simple Distance Joint and the two Revolute Joints acting as hinges. It's easiest to see the actual point which forms the Revolute Joint on the right-hand flipper due to the sharp kink in the blue line - the point where the line bends in the pinkish rectangle is the Joint which the flipper rotates about. 

Note: these blue lines are purely aesthetic, for debugging purposes and do not, directly, interfere with the physics in the simulation.

Along with adding in the flippers and the Joints, I also added a small amount of code to allow the user to active the flippers. The code for which can be seen below (The complete code can be found on Github):
With all of these new features in place, the simplified pinball machine simulation looks like this


Prev (Modelling simple physics behaviour)  Next (Creating LeapMotion Gestures)

No comments:

Post a Comment