<<

MASARYK UNIVERSITY FACULTY OF INFORMATICS

Pinball game in engine

BACHELOR’S THESIS

David Kratochv´ıl

Brno, 2017 Declaration

Hereby I declare that this paper is my original authorial work, which I have worked out by my own. All sources, references and literature used or excerpted during elaboration of this work are properly cited and listed in complete reference to the due .

David Kratochv´ıl

Advisor: RNDr. Adam Rambousek, Ph..

ii Acknowledgements

I would like to thank my supervisor RNDr. Adam Rambousek, Ph.D. for leading this thesis, his guidance and advices. Also, I would like to thank Ing. Pavel Tiˇsnovsk´y,Ph.D. for introducing me to this field and helping me to create this work.

iii Abstract

In this bachelor thesis I deal with the Box2D and its port into JBox2D. My goal is to study features of JBox2D library and then use them to create a of a pinball machine.

iv Keywords

JBox2D, Box2D, JavaFX, physics engine,

v Contents

1 Introduction3

2 Box2D and JBox2D5 2.1 LiquidFun...... 5 2.2 Pooling...... 6 2.3 Serialization...... 6 2.4 Phys2D and LibGDX...... 6

3 Features of JBox2D8 3.1 Common module...... 8 3.2 Collision module...... 8 3.2.1 AABB...... 9 3.2.2 Shapes...... 9 3.3 Dynamics module...... 11 3.3.1 Bodies...... 11 3.3.2 Fixtures...... 12 3.3.3 Contacts...... 14 3.3.4 Worlds...... 14 3.3.4.1 AABB Query...... 15 3.3.4.2 Ray Casting...... 15 3.3.4.3 Impulses, forces, torques...... 16 3.3.5 Joints...... 16

4 Application 19 4.1 JavaFX...... 19 4.1.1 Availability...... 19 4.1.2 Coordination system...... 19 4.2 Configuration...... 20 4.3 Objects...... 22 4.4 Contact Listener...... 27 4.5 Sound effects...... 27 4.6 Key Input...... 27 4.7 Frames...... 28

1 5 Conclusion 29

6 Bibliography 30

2 1 Introduction

A simulation is a process, that tries to virtually imitate a situation from the real world and produce the possibly most accurate outcome. are integral part of researches in many scientific fields like engineering, medicine, or economy. It also plays an important role in education and training of a military personnel. Recently, simulations also found usage in entertainment industry. Video games often contain objects, that need to move on the screen and their motion have to look realistically. Physics simulations not only allow to create scenes with these ob- jects, but also add diverse properties to them and calculate their be- haviour in different environments. These calculations are performed by physical engines. There are many physical engines that can simulate either two or three dimensional scenes. Box2D is a physical engine, that allows to create physically accurate two-dimensional simulations. It has been used in many programs on various platforms. Although Box2D itself was written in ++, it has been ported in many other programming languages like Java, , C#, or Java Script. Box2D and it’s ports are still under developement and continuously gain new features. The application, which is a part of this thesis, is written in Java, and therefore uses Java port of Box2D, called JBox2D. The goal of this thesis is to study how to work with JBox2D library and its components and use it to create an accurate simulation of a pinball machine. The written part of the thesis consists of three chapters describing JBox2D and Box2D libraries, features and objects they work with, and the application itself. First chapter focuses on physical library Box2D and it’s Java port JBox2D, components, that these libraries have in common, as well as those, in which they differ. This chapter also offers a preview of some other Java libraries, that are based on Box2D. Second chapter focuses on main features of JBox2D library, it’s modules and their components including bodies, fixtures, joints and

3 collisions, their types, behaviour and how to work with them. Third chapter describes the application, individual objects used in the simulation, and how they were created, as well as some difficulties met during the developement. This chapter also focuses on how to work with the application, how the objects are loaded and how to create custom playfield. This part also mentions used graphical user interface and its combination with JBox2D.

4 2 Box2D and JBox2D

Box2D [1] is a physics engine, that was created by Erin Catto as a part of his presentation on Game Developer Conference in 2006. This engine is distributed under zlib licence, and is therefore available as a on the internet. Although Box2D is written in C++, there are many ports, that allow to use this engine in other programming languages. These ports are created and maintained by the community, which updates them according to the original Box2D engine. JBox2D [2] is a Java port of Box2D. It was created as a combination of Box2D with physics engine LiquidFun [4] and, like Box2D, is also released under zlib licence.

2.1 LiquidFun LiquidFun is a library written in C++, created by as an extention of Box2D with added simulation of soft bodies and particle based fluids. Although JBox2D was created as a port of Box2D, today it is closer to the LiquidFun engine. JBox2D is very close to it’s original and (except different naming conventions in C++ and Java) there are only few differences in these two libraries. Main distinction are few objects that are supported by one engine but not by the other. For example, as stated before, JBox2D can use small particles connected together, allowing them to simulate water and other liquids or soft bodies that can be deformed under pressure. The application uses older version of JBox2D, and therefore misses few objects from present Box2D. These are, for example, two new joints, called motor and rope joint. Box2D also has more shapes. While Box2D can create edge and chain shaped bodies, JBox2D creates edges only as a special type of polygon shapes, and chains aren’t supported at all. All these objects are, however, present in the newest version of JBox2D. JBox2D also, unlike Box2D, features pooling and serialization.

5 2.2 Pooling Pooling [5] allows to manage several instances of one resource in a pool. The pool can store data from the simulation that are not needed in the moment, but could be reused in near future. When the stored object is required, the user can request for it, removing it from the pool. After using it, instead of destroying the object, it can be returned back into the pool again. With this method, it is possible to remove bodies from the simulations and return them back later, instead of creating and destroying them every time they are needed.

2.3 Serialization Serialization [6] is a process, which allows objects to be saved into byte streams. Data stored in these streams have to contain enough in- formation, to recreate the original object. Serialization can be used to make objects persistent, create identical copy of an object, or transfer objects over a network.

2.4 Phys2D and LibGDX Except JBox2D, there are other Java libraries based on Box2D. Phys2D is physics engine based on the earlier version of Box2D, called Box2D Lite. Another option is to use libGDX as a JNI wrapper around Box2D, which allows to work with the library by translating code be- tween two languages. Since Phys2D is based on Box2D Lite, it is much more simple than JBox2D. It isn’t maintained anymore, and therefore lacks many fea- tures introduced in later version of Box2D. Although Phys2D is able to create simulations using bodies with various shapes and mass prop- erties, it isn’t as precise as JBox2D, and isn’t very suitable for more complex simulations. Unlike JBox2D, Phys2D doesn’t use continuous , which causes tunneling effect between objects more often.

6 LibGDX is a Java wrapper around Box2D, and only translates the code between Java and C++. LibGDX is therefore, unlike JBox2D, fully dependable on the native library, and can only use features from Box2D.

7 3 Features of JBox2D

Jbox2D creates scenes by generating rigid bodies, modifying their mass properties by attaching fixtures to them and connecting bodies together with joints. Additionally, it also performs mathematics to compute the movement of objects and solve their collisions. All these functions are separated into three modules: Common, Collision and Dynamics.

3.1 Common module Common module contains settings with various values representing maximums of some variables, and constants used by JBox2D. The sim- ulation uses meters, kilograms, and seconds, or shortly MKS units, for calculations of objects and their properties. In code, the majority of these variables are represented as floating-point numbers. This mod- ule also manages types for vectors called Vec2, for two-dimensional vectors, and Vec3 for three-dimensional vectors and performs vector math using matrix modules. Common module is also responsible for memory management.

3.2 Collision module Collision module contains shapes, as well as functions and queries used by them. Before two shapes collide, JBox2D detects these shapes using collision detection. The collision detection system is responsible for calculating when and where the collision takes place and the normal vector between the touching objects [9]. JBox2D computes their points of contact and normal vector, and stores them into a contact manifold. Data from contact manifold are then used by contact solver to calculate the outcome of the collision. During a collision, JBox2D uses method called narrow-phase, to recieve contact points between two shapes. In scenes with a lot of shapes, there could be a lot of narrow-phase calls. JBox2D therefore features a broad-phase method, that uses dynamic

8 tree for pair management, and enables to reduce the number of narrow- phase calls. Collision module also allows to calculate distance between two shapes and time of their impact. The time of impact serves mainly to prevent tunneling effect, which causes two shapes to overlap, instead of colliding.

3.2.1 AABB For better organization of shapes, collision module uses a dynamic tree. This binary tree uses axis-aligned bounding boxes instead of actual objects.

Figure 1: Two polygons shapes and their AABB (Figure 8.5 in Intro- duction to with Box2D).

Every bounding box is larger than the object it contains, so it often expects a collision falsely (picture 3.1), but thanks to fewer edges the detection is much faster [7].

3.2.2 Shapes JBox2D supports polygonal and circular shapes, and in new version also edges and chains.

9 CircleShape cs = new CircleShape(); cs.m radius= radius;

Circle shape is defined by its radius and position. Polygon shapes can be created in few different ways.

PolygonShape ps = new PolygonShape(); ps.setAsBox(width, height);

To create a simple rectangle the shape can be set as box. This method requires two values. These are width and height of the rect- angle. JBox2D, however, measures the size of rectangles from center, and therefore both values need to be halved.

PolygonShape ps = new PolygonShape(); ps.set(vertices, vertices.length);

Any other convex polygon can be created by providing an array of at least three vertices. These vertices have to be in the counterclock- wise order for JBox2D to ensure that the polygon is convex. With vertices in wrong order the polygon would be created inside out, which could result in some undesirable behaviour. Any contact with a dy- namic body wouldn’t lead to a collision, but the dynamic body would get stuck in place instead.

PolygonShape ps = new PolygonShape(); ps.setAsEdge(vertex1, vertex2);

In this version of JBox2D, polygon can be also set as edge to create a line between provided initial and terminal vertices. In the newest version of JBox2D edges are now stand-alone shapes. It is now also possible to create a chain shape using array of vertices, that are con- nected by edges into one line.

10 3.3 Dynamics module Dynamic module contains classes of objects that user creates and works with in the simulation. These objects are bodies, fixtures, worlds, contacts and joints.

3.3.1 Bodies BodyDef bd = new BodyDef(); bd.type = BodyType.STATIC; bd.position.set(posX, posY);

Rigid bodies represent physical objects from real world. Bodies are undeformable and are defined by their position, angle, and velocity. The shape of a body, as well as all its physical properties are dependent on a fixtures attached to it. Based on the required behaviour, bodies can be dynamic, static or kinematic. Static bodies don’t move and are considered to have infinite mass. Kinematic bodies also have infinite mass. Unlike static bodies, however, they move according to their velocity, while external forces can’t influence them. Dynamic bodies have finite, non- mass and are moving accord- ing to it. They can also be affected by external forces. It isn’t possible for static and kinematic bodies to collide with each other. Only bodies that can collide with them are dynamic. As stated before, when creating a body, it is possible to set its position, angle, and linear and angular velocities. Beside these, bodies are also influenced by linear and angular damping. Damping controls, how much velocity can body lose while moving. It acts in similar way as friction. Damping, however, reduces velocity constantly, while friction only during collisions. It is possible to completely prevent rotation using fixed rotation parameter.

11 Figure 2: A circle tunelling through a polygon.

Another option is to set a body as a . When a dynamic body collides with a static one, Box2D uses continuous collision detection to avoid tunneling effect.To improve performance, this collision detec- tion isn’t used when two dynamic bodies collide. This way, when two dynamic bodies collide at fast speed, they can tunnel into each other. This can be prevented by setting one body as a bullet. For bullets, Box2D will perform continuous collision detection, even when collid- ing with other dynamic body. This method can, however, compromise performance. Performance can be, on the other hand, improved using sleep pa- rameters. Bodies that aren’t moving or colliding can enter sleep state, in which case they are no longer simulated. After any manipulation with a sleeping body, the sleep state is terminated and the body is returned back into simulation. Bodies can be removed from simulation completely, using activation parameter. Deactivated bodies no longer participate in simulation as well as collisions or raycasting.

3.3.2 Fixtures The most important part of creating a body is attaching a shape to it. The shape is part of a fixture, that can also alter some material properties and behaviour of the body.

12 FixtureDef fd = new FixtureDef(); fd.shape = circleShape; fd.density = 1; fd.friction = 0.3f; fd.restitution = 0.5f; fd.isSensor = false; fd.filter = filter;

• Density Density, together with shapes, determines the weight of fixtures. Density have to be a non-negative value.

• Friction Friction controls, how much two fixtures slide along each other. The value is usually between 0 and 1 but can be even higher. Fixture with friction equal to 0 is frictionless. The higher is the value, the more velocity bodies lose. Final friction between two fixtures is equal to square root of both frictions combined.

• Restitution Restitution controls the velocity, at which the fixture will be repulsed after collision. Values of restitution range in the same way as values of friction. Fixture with value of 0 will stop after collision. With value of 1 the object after collision will keep the same velocity as it had before the impact. The resulting restitution is equal to the higher restitution of both fixtures.

• Filter Filtering enables to avoid collisions between fixtures. If one fix- ture filters the other. When approached, instead of colliding, both fixtures simply pass through each other.

13 • Sensor By setting fixture as a sensor, it no longer collides with other fixtures, but only detects them. This way the simulation can trigger a reaction on any object appearing in the area of a sensor without any collision taking place. A body can have multiple fixtures attached to it. This way, it is possible to create bodies with complex shapes like concave polygons.

3.3.3 Contacts Contacts manage collision between two fixtures. JBox2D is respon- sible for functionality of contacts, so user doesn’t have to create nor destroy them, but it is possible to access a contact to work with it. One way to reach the contact is to search for it in list of contacts. This can be either a list of contacts in the whole world or just a specific body. Another way to handle behaviour of contacts is creation of a contact listener. Contact listeners serve to override two functions called BeginCon- tact and EndContact. By default, these functions don’t do anything. Begin contact event is called in the moment, when two fixtures start to overlap. End contact event is called, when fixtures cease to overlap. Contact listeners also support other two callbacks called PreSolve and PostSolve. Pre-solve event is called before the collision is resolved so it is pos- sible to modify velocities of fixtures or completely disable the contact. Post-solve event occurs when a collision has been solved, and con- tains information about impulses resulting from the collision [8].

3.3.4 Worlds public static final World WORLD = new World(new Vec2(0.0f, -10f), false);

14 World is an object, that represents the whole scene. It manages all bodies, joints and contacts. To create the world, it requires two parameters. The first is a gravitation force, which is applied on all dy- namic objects. The second parameter determines if objects can sleep.

WORLD.step(stepInSec, velocityIteration, positionIteration);

To run a simulation, the world needs to have also defined a time step, that determines how often is the step called. The number of steps in second affect bodies and their reaction on a gravitation force. The step function has also two attributes for collision accuracy. Setting po- sition and velocity iterations higher creates more accurate simulation, but also decreases performance. As stated before, world manages bodies, joints, and contacts. These are placed in lists, from which they can be accessed. Apart from lists, objects can be also accessed by using either AABB query or raycasting.

3.3.4.1 AABB Query

Axis-aligned bounding boxes query allows to create rectangular box, which detects all fixtures in the area. To create a query, it firstly requires to have its size set using lower and upper bounds. Another part of the query is its callback function, which determines, what to do with the fixture. The callback is called for every fixture, that the query overlaps.

3.3.4.2 Ray Casting

Rays are lines, that can detect objects they hit. Like AABB query, it needs a callback function as well as an initial and a terminal vector. Whenever an object comes into contact with the ray, the callback func- tion is called. The function contains four attributes. These are fixture that was hit, point of contact, normal vector and fractional distance between the initial point and the point of intersection. Callback func-

15 tion returns floating-point value, which adjust the consecutive length of the ray. Returning 0 cancels the ray, and therefore detects only the first fixture that was hit. When returning 1, the ray keeps its original length and allows to detect all fixtures. Any value between 0 and 1 shortens the ray. When returning the fractional distance, the ray can detect only the closest objects.

3.3.4.3 Impulses, forces, torques

As stated before, dynamic bodies are continously affected by grav- itation force. However, their movement can be also influenced by ap- plying impulses, that immediately change velocity of a body, forces, that affect them over time, or torques, altering angular velocity of a body. When applying forces, it is probable, that more than one force will be affecting the body. In this case, all forces acting on the body are replaced by one single force, which is calculated as a sum of all the forces. It is also possible to change a position of a body, simply by changing its location.

3.3.5 Joints Joints allow to connect bodies to each other, and also reduce their degree of freedom and restrict distance of movement under given bound- aries. To connect two bodies with joint, both bodies need to have a defined anchor point. Anchor point is point on the body, where the joint is created. Some joints can control movement of bodies with limits and motors. Lower and upper limits restrict the range of motion of bodies connected with prismatic and revolute joints. Motors can drive motion of bodies connected with prismatic, revolute and line joints. These bodies can be therefore moved either by using a motor or applying a force or impulse.

PrismaticJointDef prismJoint = new PrismaticJointDef(); prismJoint.bodyA = (Body) bodyA.node.getUserData();

16 prismJoint.bodyB = (Body) bodyB.node.getUserData();

• Prismatic joint allows two connected bodies to move along one axis, while preventing rotation. • Revolute joint allows two connected bodies to rotate around one point. • Distance joint creates connection between two bodies defined by a space between them. After connecting two bodies using this joint, the distance between the anchor points must be always constant. Distance joint also has two variables, frequency, mea- sured in Hz and damping ratio. After setting these variables, the distance between bodies becomes more flexible and joint can behave like a spring. • Friction joint can be used to control friction between two bodies. When connected bodies collide, they are affected by the joint, and their velocities are modified. This joint is suitable for adjusting both directional and rotational friction. • Gear joint can connect revolute and/or prismatic joints. This connection allows two joints to affect each other. Gear joint can also have specified ratio, which adjusts speed of movement of one joint compared to the other. • Line joint (also called wheel joint) is a combination of revolute and prismatic joints. A body can move on one axis closer or further from second body, and also rotate in the same time. • Mouse joint can be used to move objects using mouse. Although the joint needs two bodies to be created the first is never used. The second one has an anchor point which is drawn toward the position of the cursor. • Pulley joint connects two bodies with a pulley. Both bodies are also connected to the ground points, located on the scene. When

17 one body moves closer or further to its ground point, the second body is drawn in the opposite direction. Pulley joint can also have defined ratio which allows one body to move faster than the other.

• Weld joint prevents any relative motion between two bodies.

• Rope joint connects two bodies and defines a maximum distance between them. This joint allows both bodies to move freely, but not further from each other than given maximum distance.

• Motor joint allows to control body by setting a position and an angle that the body will try to reach. The speed of the body can be limited with maximal motor force and . Both motor joint and rope joint are not present in this version of JBox2D but are part of the newer version.

Figure 3: Constant volume joint in the air (left) and on the ground (right).

• Constant volume joint allows to connect three or more bodies into one object with constant volume. While applying pressure on the object the volume spreads to remain constant. This way, it is possible to simulate soft, deformable bodies. This joint isn’t part of original C++ engine Box2D, but is one of features recieved from the LiquidFun engine.

18 4 Application

4.1 JavaFX Because JBox2D doesn’t have any graphical user interface, and consequently has no way to graphically represent the simulation, it is necessary to use another library, that can create a scene with ob- jects from JBox2D. Graphics used in the application are created with JavaFX [3], which is set of libraries that allows to create applications on various platforms and also ensure compatibility between them.

4.1.1 Availability Since version 2.2 of JavaFX, it is part of the Java SE 7 Runtime Environment and the Java Development Kit, and therefore is available for major desktop platforms like Windows, Mac OS X or .

4.1.2 Coordination system To be visible on the scene, every body in JBox2D needs a corre- sponding shape from GUI. Unfortunately both JBox2D and JavaFX use different coordinate systems. Coordinate system of JavaFX has its origin in upper left corner with x-axis going horizontally from left to right while y-axis goes vertically from top to bottom. JBox2D, on the other hand, uses classical Cartesian coordinate system with it’s origin in the center, x-axis going horizontally from left to right and y-axis vertically from bottom to top. Another difference between JavaFX and Box2D is measurement units. JavaFX uses as units of the mea- surement pixels. Number of pixels on scene depends on scene’s width and height. Box2D measures in meters. Conversion between these two are ensured by methods in Utils class. Units have to be also converted when working with angles. JavaFX uses degrees, while Box2D radians. Radians also have to be negative because of the opposite directions of y-axis. The scene is 800 pixels high and 800 pixels wide. This makes 1

19 meter from Box2D equal to 8 pixels from JavaFX. Box2D also doesn’t work correctly with objects smaller than 0.1 meter. To avoid this problem, objects in simulation are 100 times bigger from real pinball machine.

Figure 4: JBox2D coordinate system (left) and JavaFX coordinate sys- tem (right).

4.2 Configuration The application uses single argument, which is considered to be a configuration file containing objects for pinball playfield. The program searches for the configuration file in the JboxPinBall/src/config folder, from where it is opened and every object is loaded. If there are no arguments used, application uses sample file pinball.config which is already located in the config folder. In this folder, there is also located another sample file pinball2.config and empty file empty.config. If there isn’t configuration file with given name in config folder, or there is an error in the file, the application ends with exception. Lines in the configuration file represent objects, that are loaded from the file, divided into arrays by type and then added into the simulation. This way, the user can create different playfields, by adding triangular or rectangular walls, bumpers and kickers. Every line is composed of one letter, that determines type of the object and numerical attributes divided by colons. These values are

20 stated in meters and degrees. • Triangles start with lowercase letter ’t’ and are defined by their three vertices. Although JBox2D requires vertices in the coun- terclockwise order, it is not necessary in the configuration file, since the order is checked and fixed during the creation of the triangle. Code for triangle is: t:posX:posY:X1:Y1:X2:Y2:X3:Y3 – posX – X coordinate of the triangle – posY – Y coordinate of the triangle – X1 – X coordinate of the first vertex – Y1 – Y coordinate of the first vertex – X2 – X coordinate of the second vertex – Y2 – Y coordinate of the second vertex – X3 – X coordinate of the third vertex – Y3 – Y coordinate of the third vertex • Code for rectangle is: r:posX:posY:W:H:A – posX – X coordinate of the rectangle – posY – Y coordinate of the rectangle – W – Width of the rectangle – H – Height of the rectangle – A – Angle of the rectangle • Code for bumper is: b:posX:posY:V – posX – X coordinate of the bumper – posY – Y coordinate of the bumper – V – Value . Number in interval from 1 to 3 which indicates how many points will player get when it is hit by the ball

21 • Code for kicker is: k:posX:posY:W:A

– posX – X coordinate of the kicker – posY – Y coordinate of the kicker – W – Width of the kicker – A – Angle of the kicker

4.3 Objects After loading all objects from the configuration file, the rest of dynamic and static bodies, that represent the empty playfield, is also added into the simulation. The simulation uses various objects with different appearance and behaviour. To be visible on the scene, every body has assigned its shape using JavaFX library.

• Ball The ball is a simple dynamic body and the most important part of the simulation of pinball. Both JBox2D and JavaFX uses circle shapes to create circular bodies. The size of the ball is represented as constant in the Util class.

• Wall Walls are rectangular shaped, static bodies with various height and width. Their purpose is to shape the playfield, as well as cre- ate its borders. As stated before, JavaFX can create rectangular polygon using a rectangle shape, but unlike JBox2D, which cre- ates rectangles from center, JavaFX creates them from bottom left corner, and therefore the shape has to be shifted by half of width and height and both dimensions have to be doubled.

22 Figure 5: Two rectangles created with the configuration file.

• Triangle Triangles are static bodies defined by their three vertices. Their main purpose is to shape the playfield in the same way walls do.

Figure 6: Two triangles created with the configuration file.

• Arc Arc is a rounded wall in the upper part of the playfield. Unfortu- nately, JBox2D doesn’t support curved edges, so the rounded side

23 had to be made using a polygon with great number of vertices with small distance between them. As stated before, JBox2D can’t create concave polygons, but one body can have more fix- tures and can be composed of more shapes. The arc consists of group of triangles. Quantity of triangles is defined as a constant POINT COUNT in the Utils class. A position of vertices of ev- ery triangle is calculated using simple trigonometric functions, aligning them into a circular quadrant.

Figure 7: The arc with 5 points (left) and 20 points (right).

• Lever Levers are dynamic, rectangular polygons. Even though they are objects of the same class, they are used for two different roles in the simulation. One is a plunger and the other is a lock. The plunger serves as a spring, that shoots the ball out of the tube on the right side of the playfield. It is connected to a wall beneath it with a prismatic joint. User can control the plunger by altering joint’s lower limit which makes the plunger slowly descend. After that, the motor of the joint pushes the plunger with a great speed to it’s original position, which shoots the ball up, through the tube. The lock is connected to a wall at the end of the tube by a revolute joint. When the ball is shot out, it passes through a ray, which, when itersected, applies an angular

24 impulse on the rectangle and closes the tube’s opening with it. This makes impossible for the ball to fall back into the tube. At the start of every round, the lock is pushed back to it’s original position with another impulse.

• Slingshot Slingshots are two static, triangular objects located above flip- pers. They serve to push the ball back into the playfield after it hit the side facing the center. The shape of slingshot is created by three circles connected by edges. It is possible for more fix- tures of the same object to have different properties, so one edge of the slingshot would have higher restitution than the rest of the body. It would be, however, much more complicated to add sound effects only on one side of the slingshot. This is resolved by adding kickers on the sides facing the center.

• Flipper Flippers are two dynamic objects located on the bottom part of the playfield, connected to walls by revolute joints. Flippers are levers controlled by the user. Their main purpose is to redirect the ball back into playfield, and prevent it to fall through the drain bellow them. A body of the flipper consists of two circles connected by a polygon. First idea, how to create a flipper, was to connect two circles with edges in similiar way that slingshots are created. This solution, however, would often cause a tunneling effect. The ball would approach a moving flipper and instead of being pushed back, the ball would pass through the upper edge and got stuck in the flipper (picture 4.5). This problem is caused because of thin edges on flippers, and the collision detection, that is not very precise with calculation of collisions between two dynamic bodies. This problem was solved by replacing edges with a polygon. Another option was to set the ball as a bullet, which would lead to much precise calculations.

25 Figure 8: The ball tunelling through the flipper created by edges.

• Bumper Bumpers are static, round objects, serving as both obstacles and targets on the playfield. When hit by the ball, a bumper will add points to the final score depending on its level of value.

Figure 9: Three bumpers created using the configuration file.

• Kicker Kickers are static, rectangular objects. Unlike walls, they all have the same height, that makes them only thin platforms. They also have bigger restitution than walls, and therefore can push the ball away with greater force.

26 Figure 10: Two kickers created using the configuration file.

4.4 Contact Listener In this simulation, contact listener is set to identify the fixture, that was hit by the ball, and play a corresponding sound effect. Ad- ditionally, the contact listener adds points to final score when the ball collides with a bumper.

4.5 Sound effects All sound effects were downloaded from Free Sound web page. Dif- ferent sounds are played when the ball hits various objects. The sound played when hitting the walls was created by Reitanna. Sound for hit- ting a kicker was created by qubodup. The rest of the sounds are part of the pinball pack created by relwin.

4.6 Key Input To control bodies on the scene, key events are set to respond to pressing or releasing some keys. Player can control left and right flipper with “S“ and “K“ keys. When these are pressed, an angular impulse is applied to the flipper, which is then pushed up. By pressing the enter key, the plunger changes it’s lower transition and is forced down under it‘s own weight. After releasing the enter key, motor of the plunger pushes it back to its original position.

27 4.7 Frames The application has frame rate of sixty frames per second. In each frame, all dynamic object have their position updated, and impulses generated by key inputs are applied. Additionally, it is checked, if the ball didn’t fall through the drain, in which case it either restarts the game or shows a dialogue with final score, depending on the number of lives left.

28 5 Conclusion

In this Bachelor’s thesis, I studied physical engine JBox2D, its fea- tures and differences with Box2D, which it is based on. Both engines are very similar, as mentioned in the first chapter, and it is possi- ble to learn how to work with JBox2D using Box2D’s official manual, documentation and tutorials. JBox2D allows us to create diverse physics simulations using bodies with big variety of shapes and their combinations, adjustable physical properties and many other ways to alter their behaviour on the scenes. These are described in the second chapter. Although JBox2D has few issues, for example the lack of graphical user interface and consequent necessity of transforming values between two different libraries, it is relatively simple to learn how to work with it. The application, that I created, can help to understand how to use JBox2D library by showing it’s basic functions in combination with JavaFX.

29 6 Bibliography

[1] CATTO, Erin. Box2D v2.3.0 User Manual [online]. Erin Catto, 2007-2013 [cit. 7. 2. 2016]. Retrieved from: http://box2d.org/ma- nual.pdf

[2] JBox2D: A Java Physics Engine [online]. Daniel Murphy 2014 [cit. 7. 2. 2016] Retrieved from: http://www.jbox2d.org/

[3] JavaFX Overview [online]. Oracle 2008 [cit. 8. 11. 2016]. Retrieved from: http://docs.oracle.com/javafx/2/overview/jfxpub-overview.htm

[4] LiquidFun Overview [online]. [cit. 11. 10. 2016]. Retrieved from: http://google.github.io/liquidfun/

[5] KIRCHER, Michael, JAIN, Prashant. Pooling [online]. Michael Kircher, Prashant Jain, 2002 [cit. 12. 12. 2016]. Retrieved from: http://www.kircher-schwanninger.de/michael/publications/Pooling. pdf

[6] SLONNEGER, Ken. Serialization [online]. Ken Slonneger, 2007 [cited 21. 12. 2016]. Retrieved from: http://homepage.divms.uiowa. edu/ slonnegr/wpj/Serialization.pdf

[7] PARBERRY, Ian. Introduction to game physics. CRC Press, 2013. ISBN-13: 978-1466565760.

[8] FERONATO, Emanuele. Box2D for Flash Games. Packt Publish- ing, 2012. ISBN-13: 978-1849519625.

[9] MILLINGTON, Ian. Game Physics Engine Development: How to a Robust Commercial-Grade Physics Engine for your Game. 2nd ed. CRC Press, 2010. ISBN-13: 978-0123819765.

30