Introduction
This article describes the development of a small, but extensible bridge design game. It presents the user with a series of design challenges that require them to build increasingly larger bridges that span longer distances under a tight budget. The designer must create the bridge out of small structural components such as beams, cables, and pins. The bridge must span a gap using a limited number of support points. To provide a hint to the user and make it more visually pleasing, a background picture can be specified for each puzzle.
Background
There are a few bridge design games available that are provided with a set of free trial levels. These games are fun, but you have to pay for additional levels, and I prefer the challenge of writing software myself. Also, this project gave me a chance to try out the new features in .NET 2.0 such as generics and the new TabStrip
UI control.
Using the code
The entire source code is provided as a starting point for your own modifications or versions of it. I would like to expand it with the help of others' contributions.
Elements of the design
The first design element used in this project is the springs. Every structural element in the simulation is either a spring or a pin (used to connect springs). Steel is just a very, very stiff spring (it has a high spring constant). Cable is another form of spring that can only support tension. As my college Physics professor quipped, "You can't push on a rope." So I started by creating the Spring
class, giving it some properties, and defining a few methods for it. Then, I subclassed it to provide the concrete classes for LightSteel
, HeavySteel
, and Cable
:
Some of the more interesting properties of the Spring
object are defined in the following code.
public virtual float MaxSpringLength { get { return 90.0f; } }
public virtual float MaximumForce { get { return 1.0f; } }
public virtual float CostPerFoot { get { return 10.0f; } }
public virtual float SpringConstant { get { return 5.0f; } }
public virtual float WeightPerFoot { get { return 1.0f; } }
Each of these properties, being virtual, can be overridden in subclasses to specialize the behavior of the different building components. HeavySteel
, for instance, is similar to LightSteel
except that it is heavier (higher WeightPerFoot
), stronger (higher SpringConstant
), and more expensive (higher CostPerFoot
).
Pins are created as needed to provide connection points between springs. Each pin is simply a 2D location on the game board. It is defined as a generic collection of 2D points as follows:
System.Collections.Generic.List< System.Drawing.PointF > m_pins;
The entire bridge is stored in the Bridge
class. It contains, notably, the collection of pins, the collection of springs, the current interaction mode, and the anchor pins. The anchor pins help to define the puzzle problem by providing the only solid connection points in the environment. No matter how many other springs are connected to an anchor point, it supports their weight without moving. The Bridge
class also supports methods for:
- Clearing the bridge structure
- Loading a new puzzle
- Adding a new spring or pin to the structure
- Removing a spring or pin from the structure
- Calculating the cost of a structure
- Calculating the forces in the structure
- Deflecting the bridge (moving the pin locations)
- Painting the bridge
The various puzzle levels are supported by the Level
class. They are defined by XML, and stored in a level folder in a certain folder on disk. This allows the user to define their own levels just by adding a level folder. To make this process more convenient, there is a simple level editor that manages the creation of the level folder. Each level defines the list of anchor points, the background image, and the budget (the total cost of materials allowed).
Simulation
The physical simulation is perhaps the most interesting part. It occurs in a separate thread in order to allow graphical updates (an interactive user experience) and user control of the simulation process. The main simulation loop follows this iterative algorithm in order to provide a dynamic response to the weights and gravity:
white ( simulating )
calculate all the forces for all the springs
find the maximum force
scale all the forces to prevent moving to quickly or too slowly
apply the forces to all the pins to move them
Future plans
The plan for this project is to refine the design of the game more according to reader comments, then provide a central online location where users can upload and download game levels. To make it easy, it should be integrated into the user interface, making it more fun and dynamic. Another interesting thing would be to allow extensible components, perhaps definable, especially for each level.
History
- 12/22/06 - Initial submission to CodeProject.