Anda di halaman 1dari 36

PHYSICS AND NOVELTY IN

COMPUTER GAMES
Oisin Akiboye Conolly

BSc in Computer Science


11 May 2010

SCHOOL OF COMPUTING AND MATHEMATICS

Keele University

Keele

Staffordshire

ST5 5BG
Abstract
The aim of this project was to follow an iterative development process which would
arrive at the production of a fun and novel new game using experimental characters,
while also providing the basic knowledge required to create a game using physics
simulation.

Through the use of the Open Dynamics Engine, the Wiiyourself library and
Nintendo’s Wii controller, a sandbox type game demo was created in which the user
controls a small selection of characters to navigate and interact with a world which
displays real-time physics simulation.

Ultimately the experimental characters produced in this game demo, while being
novel and interesting to control, were deemed too in-practical to create a proper game
from. However one of the characters was deemed a success and so the game demo
revolves around this not so novel character. With further experimentation using the
Wii controller and the endless possibilities it provides, a different novel game could
be arrived at in the future.

1
Acknowledgements
I would like to thank my supervisor, Dr. Alastair Channon for all the support he
provided and for helping me find solutions to some very difficult problems. I would
also like to thank Tess Piper for moral support, and for providing the Wii controller
used to develop this project.

2
Contents
1. INTRODUCTION.................................................................................................... 4
1.1 BACKGROUND ....................................................................................................... 4
2. INITIAL PROJECT SPECIFICATIONS AND FEASIBILITY......................... 6
2.1 INITIAL PROJECT SPECIFICATIONS ......................................................................... 6
2.2 PROJECT FEASIBILITY ........................................................................................... 7
3. REQUIREMENTS ................................................................................................... 9
3.1 REQUIREMENT ...................................................................................................... 9
4. INCREMENTS ...................................................................................................... 11
4.1 INCREMENTS PLAN .............................................................................................. 11
4.2 INITIAL PROTOTYPE ............................................................................................ 12
4.3 1ST INCREMENT ................................................................................................. 12
4.4 2ND INCREMENT ................................................................................................. 16
4.5 3RD INCREMENT ................................................................................................. 17
4.6 4TH INCREMENT ................................................................................................. 19
4.7 5TH INCREMENT ................................................................................................. 21
4.8 6TH INCREMENT ................................................................................................. 22
4.9 7TH INCREMENT ................................................................................................. 26
5. FINAL TESTING .................................................................................................. 27
5.1 BUGS ................................................................................................................... 27
6. EVALUATION ...................................................................................................... 28
7. CONCLUSION AND FUTURE WORK ............................................................. 29
7.1 FUTURE WORK .................................................................................................... 29
REFERENCES ........................................................................................................... 31
BIBLIOGRAPHY ...................................................................................................... 32
APPENDIX A: TIME PLAN .................................................................................... 33

3
Chapter 1
Introduction
The gaming industry has become a saturated market, with thousands of individuals,
groups, small and large commercial companies all competing with each other for the
attention of the gaming community. A large amount of games are created every year
however we rarely hear about or see most of these games. The games that usually
don’t make it are the ones that are simply recycling ideas; re-inventing the wheel
essentially.
Thus the only way to make an impact or impression is to have an aspect of novelty in
a game. This can be anything from an impressive use of graphics, to a new and
interesting game concept or a novel control system, the latter combination being the
aim of this project.
This project ultimately aims to be an introduction to the world of game programming,
while exploring novel possibilities which could be used to penetrate the gaming
industry and make an impact. Fundamentally I am trying to achieve something that
has not been seen before. The actual objective is to create a game demo, using a
physics simulator, that displays a certain aspect of novelty.

1.1 Background
Physics Simulation in Games
Physics simulation has become part of almost every game created these days. It could
be something simple like collision detection with gravity in a platformer game, or a
full blown fluid, rigid and soft-body dynamics simulation used in a first-person
shooter. A physics simulator will typically re-create the interactions between objects
one would expect to see in the real world. For rigid body dynamics this could include
simulation of joints (like hinges), contact and collision, friction, gravity etc., while for
fluid dynamics this could be wave simulation, liquids streaming down surfaces and
collision and splashing etc.

Nintendo Wii Controller


Nintendo’s Wii controller (Figure 1) is a revolutionary approach to gaming, allowing
the user more freedom of expression and control within games than standard
controllers. It resembles a standard TV remote but has the buttons and features of a
typical control pad; a direction pad, trigger button, rumble feedback etc. This
controller has become the catalyst for many innovative game concepts seen over the
last couple of years since its release, and is quite often the main source of novelty in
games made for the Wii.

4
The Wii controller incorporates wireless Bluetooth connectivity, a 3-axis
accelerometer for motion-sensing, an optical sensor to determine where the Wii
remote is pointing (requiring an IR Sensor Bar), a 4 direction D-pad, 7 other buttons,
basic audio functionality, and rumble functionality all into a single controller. As well
as this there is an expansion port to connect other devices for increased functionality.

Figure 1: Wii remote

The Nunchuk extension (Figure 2) brings added functionality to the Wii controller as
a whole. It features the same accelerometer as the Wii remote to track movement, and
has an analogue stick, C button and a Z trigger button.

Figure 2: Nunchuk extension

5
Chapter 2
Initial Project Specifications and
Feasibility
2.1 Initial Project Specifications
At the start of this project the initial project specification was decided upon, that is
what the main objective of this project is. This was just a rough idea, leaving plenty of
room for refinement as the project progressed. The whole idea was to create a game
demo where the user can control a character or multiple characters, and explore a
world while interacting with objects in a realistic way. The game demo had to use a
physics engine to realistically simulate real-world physics, and there was the
possibility of incorporating artificial intelligence as well. Essentially a fun and novel
game was what was being sought after in this project.

Due to the nature of this project it was decided that a mixture of incremental and
iterative development would be used. The idea behind incremental development is to
break the work down into smaller pieces, or increments, which are scheduled to be
developed over time and integrated into the whole system once they are completed.
Iterative development then is a strategy in which time is set aside to revise and refine
the various existing parts of the system (Cockburn, 2008).

Figure 3: The incremental development process

6
Using a mixture of these two processes in this project resulted in the integration of
new elements at each increment of the system. At the same time with each increment
came the refinement of existing elements from previous increments.

This strategy of mixing incremental with iterative development works well with
projects such as this one. It allows a learning programmer to take advantage of the
knowledge gained through the development of previous increments, as well as
ongoing research, and to then apply this knowledge to refine the system as a whole.

2.2 Project Feasibility


The overall feasibility of this project was assessed, focusing on two main aspects:

 Technically feasible – Is all the technology required available? Will it be


possible to learn what is needed to use that technology?
 Time-wise feasible – Is it possible to complete the proposed project within the
time limitations?

Technical Feasibility
Programming a game requires certain different technologies, and the knowledge to
use them. Research concluded that all the necessary technology for this project was
easily available, and the learning curve involved with each was not too steep.

Open Dynamics Engine (ODE) became the engine of choice for the physics
simulation. ODE is an open source, well documented and free library making it an
excellent choice for this project. This high performance library is designed for
simulating rigid body dynamics in real-time, featuring advanced joint types and built
in collision detection with friction.

The library has several advantages over other freely available physics engines. Firstly
it is very stable even while trading off accuracy for speed. It is written in C++ with a
C interface provided for cross compatibility between the two languages. On top of this
there are bindings for many other programming languages, a few being Delphi, .NET,
Python, and Java. It can be compiled to run on various systems such as Linux, Mac
OS, and Windows, as well as consoles such as Sony’s PS2 and Microsoft’s Xbox, and
the source code is provided allowing the engine to be customised according to the
needs of the system it is being used in. All of these characteristics of ODE provided a
great deal of freedom in this project, making it possible to....

For the rendering of graphics to the screen, Drawstuff was decided to be the best
option. This library comes integrated with ODE and provides simple graphics as well
as handling mouse and keyboard input. It uses openGL to render, in a window, a 3D
visualisation of the dimensions and positions of the objects used as the simulation
progresses. It supports simple shadow projection, RGB shading, and textures.
However in order to use different textures from the ones supplied requires editing of

7
the source code. As the main focus of this project is not on graphics, this option was
the most viable to use given the short development time available for this project.

As ODE was written in C++ it was decided for simplicity to stick with this language
and write the whole game in C++. This was done despite the fact that all previous
programming experience was with Java. While there are bindings available for ODE
and java, it is a significantly slower language compared to C++ when used for game
programming, especially when it comes to graphics (Davison, 2005). This is mainly
due to features of the language such as Java’s garbage collector and the way in which
objects are handled.

C++ was designed to support data abstraction, object-oriented programming


(Stroustrup, 1985), and generic programming in addition to traditional C
programming techniques, making it a very versatile language for a large array of
different programming uses. As a result C++ has become one of the leading
programming languages in the gaming industry, where a single program will often
need to cover several areas, such as graphics, audio and controller input, at different
levels of abstraction.

C++ is a very large language, and it can take a long time to become proficient in it.
However it was decided that it was perfectly feasible to learn this new language for
this project there are a lot of similarities between Java and C++ which would
ultimately help the learning process along. In addition to this the programming
practices learned over the course of University, while being aimed at Java, are largely
applicable to C++, and there is a large community which writes libraries and provides
supports for this language. This makes it very easy to find a solution to almost any
problem which potentially could be encountered during the coding of this project.
Microsoft’s Visual C++ 2008 express edition was the integrated development
environment (IDE) proposed for the coding of this project, being the most commonly
used and documented free IDE available at the time of this project.

Time Feasibility
Certain aspects which were desired, but not important were left out in order to assure
the completion of this project in the time frame. Artificial intelligence, audio, and the
use of a self written openGL library or DirectX for graphics were cut from the project
plan. With these aspects gone, the project was deemed to be within capabilities.

8
Chapter 3
Requirements
The game concept proposed for this project focused on a sandbox type environment
where the user controls a small selection of characters and navigates their way
through the world interacting with objects present. There is no main aim of is type of
game, you do not win or lose; you just explore and have fun.

3 different characters were designed. The first is a simple car which the user can drive
around the world. The other two are experimental creatures, one being a 4-legged bug,
the other being a sphere with an array of pistons on its surface. These experimental
creatures are an attempt to explore new and novel ways to control characters based on
physical interactions using joints, and to create a fun and challenging game out of it.

3.1 Requirement
System Requirements
1. The physics simulation side of the system must support:
a. Rigid body collisions (for both primitive and custom polygon shapes)
b. Creation and simulation of joints between bodies
c. Motor functions for bodies/joints (applying linear/angular momentum
to bodies, torque to joints etc.)
d. Real-time simulation which is both fast and accurate enough to seem
realistic.
e. Simulation of aspects of real world physics (such as gravity, friction,
momentum etc)
2. The system requires a means for human interaction
a. Mouse input to control a camera and possibly characters in the game.
b. Keyboard input to control characters and other elements of the game.
3. The system requires a graphical representation of the simulation
a. Needs to be 3D drawn either in a window or fullscreen
b. Must support basic shaders (custom textures and colours minimum)
c. Must allow for the view point to be moved around
d. Must be fast with low spec requirements
4. The system must facilitate an automatic camera system
a. The camera must automatically follow the selected character around
b. The character must stay in view
c. The camera must point the same direction as the character
Character Requirements
1. Car character
a. User must be able to control acceleration in 2 directions (forward,
reverse)
b. User must be able to steer the car

9
c. The car needs to be stable enough to go over ramps and other collision
geometry without toppling.
d. The car needs to be stable while turning sharply.
e. If the car becomes stuck then it must be able to be reset.
2. Experimental Character 1: Bug
a. Movement is brought about by 4 legs
b. Legs must be able to move up and down, forward and back
3. Experimental Character 2: Ball
a. Movement is administered by an array of pistons surrounding a sphere
b. The pistons must be arranged radially around the sphere, with
movement along this single axis.
c. Pistons must retract after being fired
d. User must be able to select which pistons to fire
Environment Requirements
1. Static geometry must be present for the characters to navigate around
a. This could be ramps, walls, floors and ceilings making up a level for
the character to move over and collide with.
2. Dynamic geometry must be present for the characters to interact with
a. This could be balls for the character to push around, or walls composed
of bricks that the character can smash through

10
Chapter 4
Increments
4.1 Increments Plan
The proposed game was broken down into several increments which guided the
project through its development. Each increment had a set of requirements which had
to be reached before the next increment could be started. These increments were open
to changes to account for issues found in previous increments or new things which
were learned from the ongoing research. At the end of each increment a working
prototype was produced. Testing was carried out on this prototype to make sure the
requirements were being met and to identify functions and functionality which should
be added or refined in the next increment. The increments had rough due dates fitting
into the time plan (see Appendix A: Time Plan, page: 33), though it was hard to
predict how long a certain increment would take or what extra increments might be
needed so these were expected to change.

Prototype Week Due Objective

Initial Prototype Autumn Integrate the physics simulation, graphics


Semester – rendering, and input capturing together into one
Week 8 whole system. Create a simple environment
composed of static and dynamic geometry with this
system.

1st Increment Autumn Create the basis for the characters – comprised of
Semester - bodies and joints, but with no functionality.
Week 11

2nd Increment Spring Add motor functions to allow the characters to


Semester - move, and use keyboard input to control the
Week 2 characters

3rd Increment Spring Add ‘simulation reset’ capability to the system.


Semester – Integrate a simple camera system that follows the
Week 5 characters around.

4th Increment Spring Create levels for the characters to explore and
Semester – interact with.
Week 8

Figure 4: Prototype Plan

11
4.2 Initial Prototype
The beginnings of the game were created at this stage. ODE and Drawstuff were
integrated in a new project in the IDE, and the necessary steps required in carrying out
physics simulation, input capturing and graphics rendering were coded. These steps
were:

1. Create a dynamics world and a joint group to hold the contact joints.
2. Create dynamics bodies, joints and collision geometry (called geoms) in the
dynamics world.
3. Simulation Loop:
a. Capture input keyboard and change variables accordingly.
b. Apply forces to the bodies and modify joint properties.
c. Call collision detection.
d. Create a contact joint for every collision point, and put it in the contact
joint group.
e. Take a simulation step.
f. Render objects on the screen in their new positions.
g. Remove all joints in the contact joint group.
4. Destroy the dynamics and collision worlds, and close ODE.
A simple world was created with a static box object, and a dynamic sphere object
which dropped and rolled around the environment. This tested object creation and
collision in the system, as well as graphics rendering. Keyboard input was tested by
using the ‘+’ and ‘-‘ keys to increase/decrease gravity in the simulation. The system
was ready to move onto the first increment.

4.3 1st Increment


To cut down on the amount of duplicated code involved in creating the characters,
two custom classes were created: ODESimulationObject and ODECreature.

ODESimulationObject Class
This class encapsulates the process behind creating and rendering primitive objects
(boxes, cylinders, spheres etc.) in ODE along with that object’s attributes. The class
handles:

 Adding a body for dynamics


 Storing collision geometry
 Giving the body a uniformly distributed mass of one of two types (sphere
mass and box mass)
 Setting the body position
 Connecting the stored geom to the body
 Rendering the geom In its current position

12
The collision geometry is created in the main program using ODE’s internal functions,
and then assigned to the class’ geom variable (Figure 5 for example), as is the mass of
the associated body.

ODESimulationObject.geom = dCreateBox(space, x, y, z);

Figure 5: creating a box

Rendering of these primitive objects is handled by the class in a function called


drawSelf(). This function first determines which type of geom has been stored,
then in a switch statement it gets the dimensions particular to that object type (for
example a rendering a box requires the lengths, while a sphere requires the radius),
the position and rotation of the geom, and then the appropriate Drawstuff function is
called to render the object. Drawstuff has an internal drawing function for each of the
primitive types which can be created in ODE, simplifying the rendering process down
to a single function call.

ODECreature Class
This class brings a hierarchical aspect to the design of the user controlled characters.
An ODECreature is a collection of parts (ODESimulationObjects), and Joints which
work together as one whole object. Dynamic arrays contain the different parts and
joints of the creature, with the total number of each stored to facilitate iteration
through these parts. The class allows the entire creature’s position to be translated via
the function changePosition(x, y, z). This function iterates through the
ODESimulationObjects, moving them to the x,y,z position passed as arguments while
maintaining their positions in relation to each other.

Building the Characters


With the classes in place the characters could now be created as single objects with
attributes and useful functions associated with them. The 1st character, the car, was
coded using one of ODE’s included demos as a basis. This was a 3 wheeled buggy
which had a rectangle for the body and subsections of spheres as wheels. The design
was changed to a 4 wheeled car to provide better stability. The body of the car
remained a rectangle, while the wheels were constructed as cylinders attached with
hinge-2 joints (see Figure 6). The front wheels able to rotate around both axes to
allow for steering of the car, while the rear wheels had axis-1 locked in place.

13
Figure 6: A Hinge-2 joint

Construction of the experimental bug character (Figure 7) was straightforward.


Rectangles made up the body and arms. The arms had two sections; the first was fixed
to the body, while the second section was the part that moves. The joints used here
were universal joints which act on 2 axes only (Figure 8).

Figure 7: Bug Creature Figure 8: A Universal joint

The experimental ball creature was significantly more troublesome to construct than
the others, requiring a lot of thought and mathematics to create with ODE. The pistons
(capped cylinders) firstly had to be arranged on the surface of the sphere radially, and
then they had to be rotated such that they were all perpendicular to the surface.

14
The pistons were arranged around the x,y and z axes in 45 degree increments. The x,y
coordinates for these positions were found using the formulas Cosθ = x, Sinθ = y
which were derived from the Unit Circle.

Figure 9: Unit Circle

𝑎𝑑𝑗𝑎𝑐𝑒𝑛𝑡 𝑥
𝐶𝑜𝑠𝜃 = = =𝑥
ℎ𝑦𝑝𝑜𝑡𝑒𝑛𝑢𝑠𝑒 𝑟

𝑜𝑝𝑝𝑜𝑠𝑖𝑡𝑒 𝑦
𝑆𝑖𝑛𝜃 = = =𝑦
ℎ𝑦𝑝𝑜𝑡𝑒𝑛𝑢𝑠𝑒 𝑟

Figure 10: Derived formulae

These x and y values were then also used to create a rotation matrix, using Euler
angles, which was used to rotate the pistons to their appropriate positions. All of this
was put into two different ‘for’ loops:

1. Firstly covering the sphere with 8 pistons around the z axis (Figure 11)
2. Then adding a further 6 around the y axis, skipping the two pistons already
present from the z axis.

15
for(i=0; i<8; i++)
{
int angle = i*45;
dReal x = cos(angle*PI/180)*ballRadius;
dReal y = sin(angle*PI/180)*ballRadius;
dReal z = 0;
ball.parts[i].setPosition(x,y,z);

//rotate pistons
dReal yaw = (90*PI/180);
dReal pitch = ((90+angle)*PI/180);
dReal rotation = 0;
dRFromEulerAngles (R,yaw,pitch,rotation);
dBodySetRotation (ball.parts[i].body, R);
}
Figure 11: arranging pistons around a sphere

The pistons were attached using slider joints. The advantage of these joints was that
all movement was limited to be along one axis. This axis was set using ODE’s
dJointSetSliderAxis() function which took the same x,y,z values used to set
the position of each piston around the sphere.

Prototype Testing
Testing of the prototype produced from this increment showed that the pistons of the
ball creature would slide along their joint to infinity, or until they collided with
something. This would need to be limited to a certain range in the next increment.

4.4 2nd Increment


In this increment motor functions and key bindings were created to provide a way to
move the characters created in the previous increment. There are two steps involved
in moving a creature. Firstly a key press is captured from the keyboard and used to
change a variable such as speed or turning factor. This variable is then used by a
motor function to apply forces to bodies or to modify joint properties.

For the car, the demo from which it was based also provided code which allowed the
car to be steered and to move forward/backwards. Here, steering is carried out by
applying a velocity to the joint of the front wheels until the difference between the
desired angle and the joint angle is zero. Forward and backward motion is then done
by directly applying a velocity to the hinges of the back wheels.

A similar system was applied to the bug creature. To move the legs
up/down/forward/back, a positive or negative velocity is applied to the appropriate
axis of the joint until the difference between the desired angle and the joint angle is
zero.

16
For the ball creature there are two stages involved in the motor function; the piston
must first be fired outwards, using the function dJointAddSliderForce() and
Lo/Hi stops to prevent it from going too far, and then it must be retracted. This is
done in the same way as the firing of the piston except with a negative force.

Prototype Testing
At the end of this increment the prototype produced was tested, resulting in the
conclusion that the ball character needed more pistons to provide better coverage over
the surface. A new control system would also be needed as it was impossible to
organise the firing of 14 pistons individually. It was also found that the force exerted
outwards by firing a piston would cause the whole body to move in a realistic but
undesired way. This would need to be fixed in the following increment.

Furthermore it was decided that a new type of control input would be sought after;
control via a keyboard was limited and not very fun or intuitive, especially with the
bindings for the experimental creatures. A small amount of research into controllers
resulted in the discovery of wiimote libraries which permit the use of a Nintendo Wii
controller (or Wiimote) with a computer. Following a little more research into the
feasibility of incorporating the Wii controller into this project, it was decided to
implement it in an extra increment of the system.

4.5 3rd Increment


In this increment Nintendo’s Wii controller was integrated as a human input device
(HID) for the system. Integration of the Wii controller was no easy task, and took a
significant amount of research to achieve and to solve all issues encountered.

Bluetooth Protocol Stacks


As the Wii remote is not intended for use with windows there are understandably
issues with coupling it via Bluetooth. Certain combinations of Bluetooth Device and
Bluetooth protocol stack will work, while others will fail partially if not fully. During
the integration of the Wii Controller various different stacks were tested. Glovepie
(Kenner, 2010), short for Glove Programmable Input Emulator, was used to test basic
functionality while doing this.

Contrary to the retailer’s description, the Bluetooth device purchased for this project
was identified it to be a Cambridge Silicon Radio device. This device was listed as
‘working’ on the WiiBrew website (WiiBrew, 2010) and was allegedly compatible
with ITV’s Bluesoleil Bluetooth stack. This stack was the most documented and
recommended stack found while researching the connecting of a Wii remote to a PC.

However using the Bluesoleil stack resulted in a connection where only the vibration
and led display on the Wii remote would work. All other functionality didn’t appear

17
to be translating. This was put this down to a hardware incompatibility as this stack
was subsequently tested with a Laptop’s integrated Bluetooth with complete success.

Several different stacks were tested in total. Some installed without problems, while
others required workarounds using unsigned drivers in order to work with the
Bluetooth device. The Microsoft stack was finally used for this project as it was the
only successful Bluetooth stack tested (Note: the project was also occasionally
developed using a Laptop with a different Bluetooth device, in which case the
Widcomm stack was used as it provided full functionality with the Wii remote).

Bluetooth Result
Stack

Bluesoleil stack Wii remote connected as a HID with limited functionality;


vibration and LED display.

Widcomm Wii remote connected as a HID. No functionality displayed.

Toshiba Would not recognise the Wii remote as a HID

Microsoft Wii remote connected as a HID. All features fully functional.

Figure 12 Bluetooth stack testing


Wii Remote and C++
There are several C and C++ libraries available to connect one or more Wii remotes
and to send and receive data from them. These libraries provide an application
programming interface (API) making them easy to incorporate into a system with
little effort or understanding about how the data sent from the Wii remote is encoded.

 Wiim (Boyd, n.d.)


o A simple set of C++ classes allowing the sending and receiving of
commands through Windows' HID interface. Capabilities are limited to
receiving button presses and motion data as well as the ability to set
rumble and LED status. There's no support for IR or any extension
devices yet.
 Wiiuse (Laforest, 2009)
o A library written in C that connects with several Nintendo Wii
remotes. Supports motion sensing, IR tracking, nunchuk extension,
classic controller, and the Guitar Hero 3 controller. Single threaded and
nonblocking makes it a light weight and clean API.

Of the two libraries found, the Wiiuse library was the API used due to its full list of
support. With this library the Wii remote was polled every iteration of the simulation
loop. This checked if any buttons had been pressed or if any acceleration data was
sent from the remote. If so then appropriate functions were called or variables were
changed to handle the different cases.

18
A control system was created for the car where the Wiimote was held horizontally
with the D-Pad under the left hand, and the 1,2 buttons under the right hand. Tilting
the Wii remote left and right steered the car while the 1 and 2 buttons were for
forward and reverse. Bindings for the bug character were created similarly, where
tilting the Will remote forward/back moved the bugs legs forwards/backwards. The
D-Pad and 1 and 2 buttons were used to move the legs up/down.

Also in this increment the ball creature was refined. Another 4 pistons were added to
the ball creature, bringing the total to 18 which provided greater control over the
direction of the creature’s movement. Also the issue highlighted in the previous
increment about the effect firing pistons had on the creature was fixed by increasing
the main body’s mass and decreasing each of the pistons masses, thus decreasing the
effect of the momentum of the pistons on the body to a negligible amount.

The 18 pistons were grouped into 3 groups of 6 and several different methods of
control were created for testing. These methods of control included different ways of
selecting a group (button to select a group, or different orientations of the controller),
and different ways to fire the pistons (a button press, or shaking the remote to fire the
selected group).

Prototype Testing
It was found that the speed of the whole simulation had become jerky due to the
addition of the Wii controller polling in the main simulation loop.

Also 6 groups of 3 pistons for the ball character was still too difficult to control; there
were too many buttons needed to make the selections and this was not easy to map to
the wii controller. Also the ‘select then fire’ method was unintuitive and slow to use.

4.6 4th Increment


Wiiuse’s help document suggested a solution to the jerkiness found with the library
when used in a single thread which was to switch to continuous polling mode. While
this strongly alleviated the issue, it also resulted in a noticeable delay in the creation
of events captured from button presses and from movement of the Wii remote.

This prompted the search for a new library, which arrived at Wiiyourself (Gl.tter,
2010); a fully-featured native C++ library for Windows with support for all
extensions available to the Wii remote. Upon successful integration into the main
program it became apparent that Wiiyourself was a significantly more stable library.
Feedback was instant and had no visible impact on the speed of the simulation. This
was due to the fact that the library implements threading and runs separately from the
main program. It was also easier to code with as the library was written in C++ and
integration simply required the addition of a .cpp and a header file. Wiiuse on the
other hand was written in C and integration required dynamically linked libraries
(DLL) to be built and added to the project, a cumbersome task for a programmer
learning how to use C++. The library itself also provides wider compatibility with

19
different Bluetooth stacks, and supports more of the Wii controller’s functions than
any other library found during the research in this area making it overall the best
choice.

Firstly a callback function is set to notify us when the status of the Wii remote
changes (if an extension was added/removed, and what the extension was).

wiicontroller.ChangedCallback = on_state_change;

Figure 13: wiimote callback function


Then when the program starts, the Wii Remote is connected and an instance of the
wiimote class is initialised. The wiimote object is then polled at the beginning of the
main simulation loop. Polling the wiimote object refreshes its state to see if any
events have occurred. If so then the event is handled where appropriate functions are
called and global variables are changed.

1) initWiimotes(wiimote &remote)

2) wiipolling(wiimote &remote)

3) handle_event(wiimote &remote)
Figure 14: wiimote functions
Finally, when the program is closing the Wii controller is disconnected.

With a new library in place, the existing key bindings for the characters were updated.

The ball character was modified to use 3 groups of 6 pistons now, meaning that only 3
buttons would be needed on the controller. Also the method of control was changed to
direct firing of the group via a single button press.

A simple camera system was implemented in this increment. This system worked by
finding the position of the subject, and then subtracting a certain distance from this to
use to set the camera’s position. The positions were updated in the simulation loop so
that the camera followed its subject and kept it in view at all times. The camera’s
rotation, pitch and heading were locked though, so the camera always faced the same
point on the horizon. A simulation reset function was also added in this increment,
whereby the simulation was deleted and then recreated in its initial state.

Prototype Testing
The results from testing concluded that the camera system needed to be refined in the
next increment so that the heading of the camera matched that of the character and
also so that the camera could be actively controlled by the user.

It was found that the simulation reset function was resulting in memory leaks. After
several resets of the system the simulation slowed down, eventually freezing. Looking
at the memory use of the program it was obvious that objects were not being deleted

20
before being recreated, so the simulation was handling more objects than it should.
The car was also found to be unstable and toppled over when turning suddenly at high
speed.

4.7 5th Increment


In this increment the character selection system was changed so that only one creature
exists in the world at a time. Changing the character deleted the old one, and spawned
the next one in its place. The ‘reset’ function was refined to be cleaner without the
memory leaks, and the car’s centre of gravity was moved to be below the car to make
it more stable. A simple level was created for testing the characters in, comprising of
an arrangement of box objects.

Refinement of the camera system in this increment saw the use of an ODE Joint to
maintain a connection between the camera body and subject while also making sure
the camera body faced the same direction as the subject. Attaching the actual camera
to the body required the conversion of rotational matrices to Euler angles however.
After some research a conversion algorithm for 3x3 matrices to Euler angles was
found (Baker, 2010), however it didn’t work as expected. As the structure of ODE’s
matrices were unknown, and the fact that ODE’s rotation matrices are actually stored
in 4x3 matrices, it was hard to figure out which formulae were needed or how they
should be applied. After some experimentation a combination was found that
correctly obtained the heading value. As this was all that was needed for the camera
system (pitch and roll were to be kept constant.), experimentation and research into
converting matrices was stopped at this point. Figure 15 shows how the equation was
used to find the heading Euler angle.

Initial equation heading = atan2(matrix[0][2], matrix[2][2]);

Final code heading=atan2(rotation[4],rotation[5]);

Figure 15: Conversion formula

As a joint was used to connect the camera to its subject, the camera could now be
controlled and rotated around the subject. This was done by changing angle of the
joint between the two bodies in the same way used for steering with the car character.

Support for the Wii controller’s Nunchuk extension was integrated in this increment,
and the analogue stick was used to control the camera both when it’s locked to a
subject and when it’s in free-roam mode. A second control system was added for the
car for when the Nunchuk is attached. With the Nunchuk attached and held in the left
hand, and the Wii remote held like a remote tilting the remote on it’s Roll-axis steered
the car, while the A and B button accelerated/reversed the car. A second control
system was created for the 4-legged bug as well, similar to that of the car. The

21
Nunchuck controled the camera, while tilting the Wii remote up/down moved the legs
forward/ back and the A and B buttons moved the legs up and down.

Prototype Testing
It was found that the capped cylinders used for the ball character’s pistons result in
inaccurate collisions with other objects. As well as this the system was crashing due
to stack overflow issues with Windows. Also it was decided that level creation using
only primitives is a long and cumbersome task. Using mesh files modelled in an
external 3D program would speed this process up significantly. As ODE supports
trimeshes it was decided that support for mesh files would be added in the next
increment. Development would be stopped for the bug character after this point in
order to focus on the other two characters and the integration of mesh files.

4.8 6th Increment


This increment signifies major changes to the overall system and refinement of
existing elements. A new class was added to encapsulate the process involved in
reading and using mesh files.

meshFile Class
This class handled the converting of a 3D mesh file into a trimesh, which could then
be rendered and used within ODE as a rigid body with collisions. This was possibly
the most difficult task in the development of this project, and took the most time to
test, debug and complete. The countless issues encountered were handled by creating
test cases where the expected outcome was compared with the actual outcome. From
this the source of the bug or problem was worked out and a solution created until this
class worked 100% as expected and required.

3D models, created using 3D Studio Max 2010 [www.autodesk.co.uk], were


converted to a triangle mesh and exported in Wavefront’s .OBJ format. This file
contains 3D geometry details: the position of each vertex and the vertices that make
up each triangle (referred to as the indices).

The .OBJ file, the path of which is passed as an argument to the class’s
loadOBJ()function, is opened by an ifstream in ‘read’ mode. In order to
initialise the dynamic arrays in the right size to hold the vertices and indices, the total
number of vertices and indices had to be known. The file is read line by line, value by
value (separated by a space character), under a set of rules:

22
First value on the How to handle the line
line

v Increase the total vertex count for each value on the line

vn Increase the total normal count for each value on the line

f Increase the total faces count for each value on the line

Figure 16: Rules for counting data

Note: normal data was handled as well in case of a future move to a different graphics
library which might use them.

As the vertices and normals compose of x,y,z values the totals had to be divided by 3
to get the actual number of vertices and normals. The dynamic arrays are initialised,
and then the file is opened again and read in a similar manner under a different set of
rules:

First value on the How to handle the line


line

v Load the next 3 values into vertices

vn Load the next 3 values into normals

f Load the next 3 values into a temp stringstream and


process further before loading into indicies

g Load the next value into meshName

Any other value ignore the succeeding values until one of the cases above

Figure 17: Rules for reading data

Once all the data is loaded into arrays, a triMesh can be built using ODE’s
dGeomTriMeshDataBuildSimple() function. From this a geom can also be
created for collisions.

The class then covers all functions related to this triMesh and geom:

 Addition of a body for dynamics


 Setting a uniformly distributed mass for the body
 Connecting the trimesh geom to the body
 Setting the position of the geom or body
 Setting the colour and transparency of the trimesh
 Setting the texture for the trimesh
 Rendering the trimesh

23
The above functions use standard body and geom functions to fulfil their tasks, with
the exception of the rendering process. Drawstuff doesn’t have any inbuilt function to
draw trimeshes, all it has is the ability to draw a triangular face given the vertices. It
was found that the normal (the direction to render the face) is implicit in the order the
vertices are given in. The drawing function in the class iterates through the total
number of faces, getting the vertices for each face and then drawing them as a triangle.

dGeomTriMeshGetTriangle(geom,index,&V1,&V2,&V3) is an ODE
function which takes a trimesh geom and an index (one for each face in the trimesh),
and copies the coordinates of its vertices into the addresses of the 3 given arrays.

dsDrawTriangle(pos,rot,vertex1,vertex2,vertex3, true) is the


Drawstuff function which renders the triangle’s face. The position, rotation, vertices,
and a Boolean value to draw solid/wireframe are passed as arguments. A very
important point was discovered here after a large amount of issues with drawing the
trimeshes was encountered. Initially the position and rotation of the trimesh geom,
obtained with dGeomGetPosition(geom), was used when drawing a trimesh
which had moved from its initial position. However it was discovered that the vertices
obtained from the trimesh geom are in world coordinates i.e. they are the absolute
positions of the vertices in the world, not the positions of the vertices relative to each
other as described by the mesh data from the file. As a result when the trimesh moved,
its collision geometry was in one place but the trimesh was actually drawn in another.
Fixing this involved passing a zero-rotation matrix and a zero-position array (all
values are zero) to dsDrawTriangle(), and letting the position and rotation of the
geom. be taken care of automatically when getting the triangle information.

The colour, alpha (transparency), and texture which were set earlier are stored in
private data members and used at this stage when drawing each triangle via the
Drawstuff functions:

 dsSetColorAlpha(Red, Green, Blue, Alpha);


 dsSetTexture (texture_number);

An alternative method of drawing was also created, where the mesh file is drawn
straight from the vertex data using a proxy object for position and rotation in the
world. This is useful as it allows a less detailed mesh or maybe even just a primitive
like a box to be used for simple collisions while a high poly mesh is used for
rendering. Trimesh collisions are highly computational, and the more faces present
the slower the simulation becomes. This method of drawing required a different
process from the previous one as there is no trimesh to obtain triangles from. Instead
for each index, the vertices associated with it are taken from the 2 dimension array of
vertices and used to draw that triangle.

24
With the ability to load and use mesh files in place, major changes could now be
made to the game. Mesh files were used to change the look of the car (Figure 19), and
a low poly level was created for the characters to explore.

Figure 18: Car made of primatives Figure 19: Car made using trimeshes

As well as this further refinement was done to some existing elements of the system
also in this increment:

1. Modified the ODECharacter class so that meshFiles were included, and so that
the drawing of all parts of the ODECharacter happened via a single function
call.
2. Modified the ODESimulationObject class so that it also stored colour and
texture data for the object allowing all object to be drawn differently from
each other.
3. Changed simulation step to dWorldQuickStep to fix the stack overflow issues.
This method is less accurate, but uses less memory and is faster.
4. Modified experimental ball creature – changed pistons from capped cylinders
to boxes to fix the unstable collisions with certain geom types.

Prototype Testing
After the testing of this prototype it was decided that more levels could be added now
that it was easier to model and incorporate them. As well as this more items for the
characters to interact with should be added. To make it more fun a shooting ability
would also be added to the car so the user can drive around, shooting spheres at
objects in the world.

25
4.9 7th Increment
For this, the final increment, new levels were created with the ability to cycle through
them using the ‘L’ key. A function was created which could make a wall of bricks
along the x or y axis to smash through. The size and mass of each box could be set, as
well as the width and height of the wall in terms of bricks and the wall’s position. A
couple of these walls were added to the levels for the user to interact with.

A shooting ability was also added to the car, allowing the user to shoot small balls
from the camera viewpoint. This was achieved by moving one of the balls which had
already been created to the same point as the camera body attached to the car. The
orientation of the body was then obtained using dGeomGetRotation() and this
matrix was multiplied with another which had been rotated by 90 degrees. This gave
an orientation which was the same as the direction the camera was facing, and using
this, a force could be applied to the ball to fire it in this direction.

Furthermore, to make the car more fun and interesting the surface settings were
changed. The slip and bounce between surfaces was increased so that car skids and
handles more like a buggy.

A release version of the prototype produced from this increment was created and then
the final system testing was carried out.

26
Chapter 5
Final Testing
Due to the time constraints very little in depth final system testing could be carried
out. Some black box testing was done with a small test group of just 2 people. From
this testing some bugs were found, and the game itself was evaluated.

5.1 Bugs
Most bugs were fixed during the development of the project; however some were
missed and only found during the final system testing.

It was found that when shooting the balls while driving the car, the balls quite often
did not collide with trimeshes but passed straight through them. This seemed to be
related to the speed at which the balls hit the trimeshes.

It was also found that connecting the Wii remote at the start of the game with the
Nunchuk already inserted results in the automatic disconnection of the Wii remote
after a few seconds.

27
Chapter 6
Evaluation
It is hard to evaluate if this project was a complete success or not. While the final
product meets the requirements specified in chapter 3 and the main objective of the
project, to create a game demo using physics simulation, was successfully achieved,
there are shortcomings of the project when it comes to the experimental creatures.
One of the aims of this project was to find a new and novel idea for a game using the
experimental characters; however they cannot be deemed a success as it was found to
be almost impossible to control them in a desired way. The system testing carried out
showed that it was possible to move the creatures around, but difficult to predict
where they were going. While this made for an interesting and novel idea it just
wasn’t practical. The car character on the other hand was a complete success, meeting
all requirements successfully.

Figure 20: Firing a piston group Figure 21: Firing all pistons

Figure 22: Driving in a level Figure 23: Smashing through a wall

28
Chapter 7
Conclusion and Future Work
In conclusion this project saw the creation of a sandbox type game where a user could
explore a world displaying physics simulation using a Nintendo Wii controller and a
small selection of characters. This report explained the aims, objectives, specifications
and development process of this project and highlighted where the result succeeded
and didn’t succeed.

This Project itself has been a massive learning experience, drawing and improving on
skills and knowledge gained from previous and current studies at Keele University.
This project highlighted in particular the importance of knowledge in the area of
‘systems development’, and has improved my understanding of the related concepts
greatly. It has also accomplished one of my aims, which was to gain an introductory
level of knowledge required for game programming. The other aim was to find a new,
novel aspect to gaming through the control of experimental characters, and while this
aim wasn’t successfully accomplished, perhaps with more time and exploration a
workable solution could be found.

In reflection it was quite hard to stick to the proposed time plan. Certain sections took
longer than expected, while others were completed in a couple of days. It was also
found that at the beginning project management was relaxed with an element of chaos
present, however as the project matured different aspects, especially those related to
the system development process, became more fully understood and so project
management and development became smoother and more organised.

7.1 Future Work


There are a lot of possibilities for future work on this project. Drawstuff was clearly
intended as a simple visualisation tool to allow ODE simulations to be view and
explored by a user. It lacks all the advanced options and capabilities seen in graphics
engines these days, and doesn’t use optimisations which would allow it to run faster.
This can be seen when a high detailed mesh is used with the system (with or without
the use of a collision trimesh). The whole program slows down as Drawstuff struggles
to render all the faces. A next step would be to make the move to DirectX (DirectX 9
if developed on Windows XP, otherwise DirectX 10 or DirectX 11 depending on
hardware and operating system). Audio would be another possible addition to the
system, as would a more advanced interface perhaps using Microsoft Foundation
Classes (MFC).

29
With the current system there is plenty more room for experimentation with the Wii
remote. With the increased freedom the controller and its extensions provide there are
so many possibilities and openings for novelty in games using this technology.

In relation to the game concept, the car character could be developed further to create
a multiplayer game where users race against each other while shooting each other
with different types of objects. While this concept doesn’t make for an innovative
game, it certainly is considered to be a fun one and with the Wii controller’s
capabilities the idea could be made more novel quite easily.

The ball character would perhaps perform better in a two dimensional environment.
Limiting the movement to an X and Y axis could lower the complexity of the control
system, while still holding on to the novel aspect of it. A proposed future endeavour
would be to use this character alone to create a puzzle-platformer type game.

Another interesting area where the experimental creatures could be used is in artificial
intelligence. Neural Networks could learn and evolve a method to control the
creatures in an intelligent way. This would open up further possibilities for different
types of games.

30
References
Baker, M.J., 2010. Maths - Conversion Matrix to Euler. [Online] Available at:
http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToEuler
/index.htm [Accessed January 2010].

Boyd, E., n.d. WiiM. [Online] Available at:


http://digitalretrograde.com/projects/wiim/ [Accessed December 2009].

Cockburn, A., 2008. Using Both Incremental and Iterative Development. CrossTalk,
II(5), pp.27-30.

Davison, A., 2005. Killer Game Programming in Java. O'Reilly Media.

Gl.tter, 2010. Wiiyourself. [Online] Available at: http://wiiyourself.gl.tter.org/


[Accessed December 2009].

Kenner, C., 2010. GlovePIE. [Online] Available at: http://glovepie.org/ [Accessed


November 2009].

Laforest, M., 2009. wiiuse. [Online] Available at: http://www.wiiuse.net/ [Accessed


December 2009].

Stroustrup, B., 1985. The C++ Programming Language. 1st ed. Addison-Wesley.

WiiBrew, 2010. List of Working Bluetooth Devices. [Online] Available at:


http://wiibrew.org/wiki/List_of_Working_Bluetooth_Devices [Accessed December
2009].

31
Bibliography
Anon., n.d. WiiM. [Online] Available at: http://digitalretrograde.com/projects/wiim/
[Accessed December 2009].

Bourke, P., 2010. Object Files (.obj). [Online] Available at:


http://local.wasp.uwa.edu.au/~pbourke/dataformats/obj/ [Accessed April 2010].

Corporation, I., 2010. bluesoleil. [Online] Available at: www.bluesoleil.com


[Accessed December 2009].

Hower, C.Z., 2010. Kudzu World. [Online] Available at:


http://www.kudzuworld.com/blogs/Tech/20070817A.en.aspx [Accessed December
2009].

Jelovic, D., n.d. Why Java Will Always Be Slower than C++. [Online] Available at:
http://www.jelovic.com/articles/why_java_is_slow.htm [Accessed 11 April 2010].

Jin, G.B., Jones, B. & Smith, J., 2009. Smoothboard Wiki. [Online] Available at:
http://www.boonjin.com/smoothboard/index.php?title=Main_Page [Accessed
December 2009].

Maas, D., n.d. Rotation matrix to Euler angle conversion. [Online] Available at:
http://vfxbrain.com/questions/5/rotation-matrix-to-euler-angle-conversion

Pressman, R.S., 2001. Software Engineering - A Practitioner's Approach 5th. 5th ed.
Thomas Casson.

Smith, R., 2007. Products That Use ODE. [Online] Available at:
http://www.ode.org/users.html [Accessed 1 April 2010].

Stroustrup., B., 2000. The C++ Programming Language. Addison Wesley.

32
Appendix A: Time Plan

Time Plan Overview


Autumn Semester
Week Holidays Examinations
1 2 3 4 5 6 7 8 9 10 11 12 1 2 3 4 1 2
Charter

Background
Reading,
research, etc
Design

Implementation

Log Book

Supervisor
meetings

Spring Semester
Week
1 2 3 4 5 6 7 8 9 10
Poster

Background
Reading,
research, etc
Design

Implementation

Log Book

Supervisor
meetings
Final Report

Semester Dates
 Autumn Semester
o Week 01: 28/09/2009
o Week 12: 14/11/2009
 Spring Semester
o Week 01: 25/01/2010
o Week 10: 29/03/2010

33
Monthly Planner
November (Shaded days)
Monday Tuesday Wednesday Thursday Friday Saturday Sunday

1 Week 5

2 Week 6 supervisor
meeting

3 Week 7 supervisor
meeting

4 Week 8 Initial
Prototype

5 Week 9 Meeting
cancelled

6 Week 1st
10 Increment

December (Shaded days)


Monday Tuesday Wednesday Thursday Friday Saturday Sunday

1 Week 10 supervisor
meeting

2 Week 11 supervisor
meeting

3 Week 12 2nd End autumn


Increment semester

4 Christmas
day

January (Shaded days)


Monday Tuesday Wednesday Thursday Friday Saturday Sunday

3 Start
autumn
assessment

4 End autumn
assessment

5 Week 1 Start Spring


Semester

3rd
Increment

34
February (Shaded days)
Monday Tuesday Wednesday Thursday Friday Saturday Sunday

1 Week 2 4th Poster talk


Increment

2 Week 3

3 Week 4 supervisor
meeting

4 Week 5 supervisor Poster Poster


meeting Deadline session

March (Shaded days)


Monday Tuesday Wednesday Thursday Friday Saturday Sunday

1 Week 6

2 Week 7 5h supervisor
Increment meeting

3 Week 8

4 Week 9

5 Week 6h
10 Increment

April (Shaded days)


Monday Tuesday Wednesday Thursday Friday Saturday Sunday

1 Meeting
cancelled

4 Final
Exams

5 supervisor 7h
meeting Increment

Deadline: May 11th

35

Anda mungkin juga menyukai