Magnet Madness (by Josh Prior) Download
Introduction:
In Magnet Madness there are three types of
objects that you
will encounter, North
magnets, South magnets, and Neutral materials. These
objects take the form of little
magnetic balls and hovering doughnut shaped magnets.
North South Neutral
Objective:
The object of the game is to get all the balls into this goal box.
You accomplish this by turning the doughnut shaped magnets
on or off to push and pull the balls through the maze. To
change the state of a doughnut magnet you must fly close to it,
then on the keyboard press either +,-, or 0. Plus turns the
doughnut magnet into a North magnet, so it will pull South
magnetic balls and repel North magnetic balls. Minus turns the
doughnut magnet into a South magnet, and Zero turns the
magnet off all together. In Magnet Madness neutral
balls (sliver), are attracted to both North and South magnets,
but they exert no force on the North and South balls. Clever
usage of the magnets will allow you to push and pull the
balls through the maze to the goal box. Once all the balls have
been captured you win and the game ends.
Controls:
View Mode:
Pressing 'V' will toggle
between full screen and windowed
view
mode. When in full screen mode you do not need to click
the
mouse in order to rotate the view.
CONTROLS
Movement:
W - Forward
S - Backward
A - Left
D - Right
Magnetism:
+ - North
0 - Off
- - South
Options:
G - New game
H - This help display
V - Toggle full screen mode
U - Toggle texturing
F - Toggle force vectors
N - No clip mode (fly through walls/floor)
Q - Quit
PHYSICS & IMPLEMENTATION:
The Physics:
First of all, I know there’s no such thing as a magnetic mono-poll,
so the whole idea of this game is sort of ridiculous. The game
really isn’t about magnets, it’s about electrons and protons,
because the force equation I used was the electric force equation.
It’s just more fun to make them magnets. Alright, that said, this
isn’t too complicated of a program. The basic idea is:
- create a bunch of balls/magnets
- every time delta calculate the force acting
on a ball by all
the other magnets using the electric force equation:
F = K * Q * q / d^2, where K is the electric force constant,
Q is the charge (in coulombs) of the electric field affecting
the ball, q is the charge (in coulombs) of the ball
its self, and d is the distance from the ball to the
source of the electric field. I used unreal and exaggerated
numbers to tune my system to act in the way I know it should.
- use the force to calculate a the instantaneous change in
velocity, then add this change to the velocity vector for the
ball. F = mass x acceleration and acceleration = dV/dt
:. dV = F * mass * dt, where mass is an arbitrary number,
and dt is the number of times per second that
this calculation
is performed.
- move the ball in the direction of the velocity vector by the
magnitude of the velocity vector.
The only other physics involved is the collision with the walls of
the maze. This is pretty simple
since the walls are parallel
to the x and z axes. All that happens is, if the ball is hitting the
wall that is parallel to the x axis then I flip the sign on the
balls velocity x co-ordinate. Likewise for the z axis.
This causes
the ball to
reflect off of the wall.
The Implementation:
The Ball class has a method called move( ),
not only does it change
the position coordinates for the ball, but it also calculates the
amount of rotation required for the ball to roll to its destination,
based on the circumference of the ball and the distance to be
traveled. The rotation of the ball is stored in a rotation matrix
that is similar in concept to the trackball matrix.
The maze is represented by a vector of wallJoint
objects. Each wall joint
describes the intersection of 0 to 4 walls. The
default play field is
20 by 20 maze cells so that’s potentially 400 wall collisions that
would
have be checked for each ball, every 1/30 th of a
second. To avoid this
massive over head in calculation, I exploited some of the aspects of
the play field geometry. For example, the wall joints are evenly spaced
across the play field, and each joint is capable of describing the walls
near it. So I wrote a transformation function that takes the co-ordinates
of a ball and returns the vector index of the wallJoint
that is closest
to the ball. The vector is not searched to find the joint! Using the
wallJoint obtained from the transformation function, I
can determine
if there is a collision between the ball and one of the walls that is
near
it. Another optimization to speed up wall/ball collision detection, all
the walls are axis aligned, so detecting collisions reduces to comparing
the positions of the wall joint verses the position of the ball. No dot
product is required for this calculation.
Also what makes the wall joints really cool, is that the models for the
walls are actually stored as a meshes of quads that are dynamically
generated at the start of the program based on
constants that describe
height, width, ect. So between runs the dimensions
of the walls can be
adjusted, and during runtime they are still quick to draw to the screen.
References:
Game mode:
Lighthouse 3D
http://www.lighthouse3d.com/opengl/glut/index.php?gameglut
Simple reflection /
alpha blending:
NeHe
Productions!
http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=26
Random maze
generation: (I implemented the recursive division algorithm)
Wikipedia, the free encyclopedia.
http://en.wikipedia.org/wiki/Maze_generation_algorithm
HUD display using ortho projection:
Lighthouse 3D
http://www.lighthouse3d.com/opengl/glut/index.php?bmpfontortho
Electric force
equation:
Wikipedia, the free encyclopedia.
http://en.wikipedia.org/wiki/Electric_force
Textures:
Texture And
Colour
http://local.wasp.uwa.edu.au/~pbourke/texture_colour/