Index
1. Programming Proverbs
- 14. ‘‘Avoid
implementation-dependent features.’’
- Henry
F. Ledgard, ‘‘Programming Proverbs: Principles
of Good Programming with Numerous Examples to Improve
Programming Style and Proficiency’’, (Hayden
Computer Programming Series), Hayden Book Company, 1st
edition, ISBN-13: 978-0810455221, December 1975.
2. PGE Predictive Game Engine
- purpose
- to provide a simple
reference model for predictive collision detection between
simple 2D objects
- as an educational experiment
3. Overview
- a game engine will simulate a 2D
environment which understands and polygons, circles
-
each circle and polygon can be fixed or unfixed
- each
object may be given a mass, velocity and acceleration
-
PGE predicts the time of the next collision
- and draws
the world for each frame
- the game engine is a discrete
event simulator
- so an event is either
a collision event or a draw frame event
4. Limitations
- the game engine does not model
rotation of objects
- collision response has a fixed
inelastic property
- no provision to
have a per object inelastic or elastic property
- easy to
do, just not done yet
- contact resolution code
could be improved
5. Points of note
- designed to be easy to debug
-
version 1 used a macroObject module
which allows more complex objects to be created
- the 2D
world is populated via macroObject s
- uses a fractional data type for the render and
macroObjects
- allows for much easier
debugging
6. Structure
7. Fractions
8. Example of a debugging session with GDB and PGE
- let us assume there is a bug
somewhere in the macroObject_rotate
function
- an obvious way to solve this is to use
gdb and single step the function,
printing out the variable contents as they are created
-
pge/c/macroObjects.c
macroObjects_Macro macroObjects_rotate (macroObjects_Macro m,
Points_Point p, Fractions_Fract r)
{
PolyMatrix3D_Matrix a;
PolyMatrix3D_Matrix b;
PolyMatrix3D_Matrix c;
PolyMatrix3D_Matrix d;
macroObjects_Macro n;
/* a: translate point, p, to the origin. */
a = Transform3D_translate (Points_negatePoint (Points_dupPoint (p)));
b = Transform3D_rotate (r); /* b: rotate, r, radians. */
c = Transform3D_translate (p); /* c: translate from origin to point, p. */
d = PolyMatrix3D_mult3 (a, b, c); /* d: combine a, b and c transforms. */
n = macroObjects_initMacro ();
n = foreachObject (n, m, d); /* n: for every object in m transform using, d. */
return n;
}
-
$ make npn
$ gdb a.out
(gdb) break macroObjects_rotate
(gdb) run
Breakpoint 24, macroObjects_rotate (m=0x6797f0, p=...,
r=0x697ef0) \
at macroObjects.mod:562
(gdb) next
(gdb) print dmat(a)
+-
| 1 0 0
| 0 1 0
| -.1/4 -.1/4 1
+- 1 = void
(gdb) next -
(gdb) print dmat(b)
+-
| cos((pi/2)) -1 0
| sin((pi/2)) cos((pi/2)) 0
| 0 0 1
+- 2 = void
(gdb) next
(gdb) print dmat(c)
+-
| 1 0 0
| 0 1 0
| .1/4 .1/4 1
+- 3 = void -
(gdb) next
(gdb) print dmat(d)
+-
|
((1*((cos((pi/2))*1)+0))+((0*((sin((pi/2))*1)+((cos((pi/2))*0)+0)))+0))
\
((1*((cos((pi/2))*0)+-1))+((0*((sin((pi/2))*0)+((cos((pi/2))*1)+0)))+0))
\
((1*((cos((pi/2))*0)+0))+((0*((sin((pi/2))*0)+((cos((pi/2))*0)+0)))+0))
\
|
((0*((cos((pi/2))*1)+0))+((1*((sin((pi/2))*1)+((cos((pi/2))*0)+0)))+0))
\
((0*((cos((pi/2))*0)+-1))+((1*((sin((pi/2))*0)+((cos((pi/2))*1)+0)))+0))
\
((0*((cos((pi/2))*0)+0))+((1*((sin((pi/2))*0)+((cos((pi/2))*0)+0)))+0))
\
|
((-.1/4*((cos((pi/2))*1)+0))+((-.1/4*((sin((pi/2))*1)+((cos((pi/2))*0)+0)))+.1/4))
\
((-.1/4*((cos((pi/2))*0)+-1))+((-.1/4*((sin((pi/2))*0)+((cos((pi/2))*1)+0)))+.1/4))
\
((-.1/4*((cos((pi/2))*0)+0))+((-.1/4*((sin((pi/2))*0)+((cos((pi/2))*0)+0)))+1))
+- 4 = void -
(gdb) print PolyMatrix3D_eval(d)
4 = (POINTER TO RECORD ... END ) 0x6876e0
(gdb) print dmat(d)
+-
| 0 -1 0
| 1 0 0
| 0 .1/2 1
+- 15 = void
9. Performance testing of a game engine
- let us build
and run snooker
$ make
snooker
gm2 -pg -g -fiso -fextended-opaque -fonlylink snooker.mod
$ ./a.out
notice the
-pg flag to gm2 (the same applies to
gcc) this flag turns on runtime profiling
$ gprof a.out
Flat profile:
Each sample counts as 0.01 seconds.
% cumulative self self total
time seconds seconds calls s/call s/call name
34.22 2.06 2.06 99486 0.00 0.00 initEntity
30.15 3.88 1.82 132186249 0.00 0.00 Indexing_InBounds
29.49 5.65 1.78 132183929 0.00 0.00 Indexing_GetIndice
1.41 5.74 0.09 Indexing_DebugIndex
1.08 5.80 0.07 2320 0.00 0.00 Indexing_PutIndice
0.50 5.83 0.03 236365 0.00 0.00 unMarkEntity
10. Useful to profile version 1 of PGE
- version 1 was
completely implemented in a 3rd generation language
(Modula-2)
- we can profile all this code and optimize
the hotspots
- as above the
InBounds was optimized (removed) and
this gave a 30% performance improvement
- version 1 did
not link up to Pygame and the game had to be written in
Modula-2 as well
- version 2 interacts with Pygame and
has a Python interface
11. Structure of version 2 PGE

12. Conclusion to the construction of version 2 of PGE
- implemented in
Modula-2, C, C++ and Python
- the Modula-2 code is
translated into C or C++ code
- the
translated code conforms to GNU coding standards and is very
neatly formatted
- the
Python interface documentation
is available on line
13. Obtaining and building pge for the coursework
- you can either
obtain pge from the debian package - or from the git
repository
- I’d advise the git
repository as it will contain very minor incremental
improvements
$ cd
$ mkdir -p Sandpit
$ cd Sandpit
$ git clone https://github.com/gaiusm/pge
14. Building PGE
- you can build
a local copy by:
$ cd
$ mkdir -p Sandpit
$ cd Sandpit
$ rm -rf build-pge
$ mkdir build-pge
$ cd build-pge
$ ../pge/configure --prefix=$HOME/opt
--enable-langc
$ make
15. Testing your local copy of PGE
$ cd
$ cd Sandpit/build-pge
$ ./localrun.sh
../pge/examples/breakout/breakout.py
Index
1. Programming Proverbs
2. PGE Predictive Game Engine
3. Overview
4. Limitations
5. Points of note
6. Structure
7. Fractions
8. Example of a debugging session with GDB and PGE
9. Performance testing of a game engine
10. Useful to profile version 1 of PGE
11. Structure of version 2 PGE
12. Conclusion to the construction of version 2 of PGE
13. Obtaining and building pge for the coursework
14. Building PGE
15. Testing your local copy of PGE
Index
This document was
produced using
groff-1.22.