IsotopeDoc
From SDL.NET
| Table of contents |
Quick Facts
What is Isotope?
Isotope is an isometric game engine for SDL.NET written using the C# programming language. It provides the framework for constructing an isometric graphics game with actors who can pick up objects and jump onto platforms. Isotope also provides automated actors who can interact with the player or their environment. The screenshot on the right shows Isotope in action. Isotope is similar to the old game engines for the ZX Spectrum.
Code
Isotope Code (http://cs-sdl.svn.sourceforge.net/viewcvs.cgi/cs-sdl/trunk/SdlDotNet/examples/SdlDotNetExamples/Isotope)
What can I use Isotope for?
Isotope is for creating isometric games primarily but can be used for other isometric applications.
Features
- Actors: Used for player and monster game objects. Capable of facing, collision response,jumping, automation and inventory.
- Multiframe animation using images
- Simple physics simulation of velocity, gravity, collision and touch detection.
- All objects can be customised and extended using C#.
- Free commented GPL open source code.
Why should I use Isotope?
You should use Isotope if you need a scripted version of an Isometric engine which is open source and simple. It is useful for understanding how Isometric engines work and for writing C# based applications which need a core engine completely written in C#. Isotope consists of simple light weight code to ensure that it can be easily understood and modified. Its reasonably fast and provides a similar level of speed to the games on the ZX Spectrum (but with no attribute clash).
What do I need to use it?
SDL.NET version 6.0.0 and .NET Framework 2.0. Both can be downloaded from the Internet.
What documentation is there and is the code commented?
The code is commented. This Isotope guide provides an overview, a tutorial, a programmers interface description and a system architecture description of the code itself.
What rights do I have?
The software is licensed under the GPL so you can use the software for no charge and you can add your own extensions. If you modify the original code you must contribute the changes back to the Isotope project.
What support can I get?
No commercial support. An email reply if your query is sensible and the author is available. The intention is to have community support if people become interested in the project.
email: simon.gillespie@btinternet.com
Who created Isotope, why... and how?
Simon Gillespie created Isotope because he could find no other open source Isometric projects available for C# that had clear documentation and simple commented code. There were many great efforts however but they were often focused more on technical achievement.
Simon has dedicated this guide to his family and friends who have helped him so much and to Ian Curtis.
Contents of the guide
- Chapter 1 Continues with the overview : Go here if you want a more detailed overview of Isotope.
- Chapter 2 Installing Isotope and a short tutorial, creating an Isotope world: Go here to get started now.
- Chapter 3 A detailed description of the Isotope programmer interface: its objects, their variables and functions: Go here if you want to know something about how to program Isotope.
- Chapter 4 A System Architecture description for Isotope maintainers and those who want to know how Isotope works.
High level description of Isotope
Isotope is a Isometric engine written only in C# with the aim of being as simple and concise as possible but capable of the key tasks needed for an Isometric game. It provides the Isometric graphic functions needed to present an image of the physical objects on the screen. It also simulates the physical nature of objects: velocity, collisions and what to do if they are touching.
Figure 2: The Isotope classes and the Isotope engine
Isotope has two branches of classes which the programmer uses to talk to Isotope: Object3d and Skin. The Object3d class provides the physical information and the Skin class provide the animation images to plot on the screen. Figure 2 shows a diagram of how the Isotope classes and the Isotope engine fit together.
The Object3d class has been subclassed (specialised) to give an Actor classes. The Actor classes can perform the complex functions associated with a person: Movement, Facing, Jumping, picking up objects (inventory). For example, Actor class has been further subclassed into a Monster class which provides an automated actor. It is programmed to turn away from a collision.
The Skin class has two standard subclasses: Pointing and Anime. Pointing provides a Skin for the Actor class which needs images for its facing directions and also its animation when walking. The Anime class simply cycles through its images like a movie clip.
The Isotope engine itself is based on two subsystems: the physics simulator and the isometric pipeline. The object classes are used by the physics simulator while the Isometric pipeline translates the objects state using the skin classes into sprite information. This sprite information is then passed to pygame to draw on the screen.
The isometric pipeline consists of a translator module and a depth sort algorithm. This produces the coordinates for the screen and sorts the sprites into a drawing order which provides the illusion of 3 dimensional depth. The physics simulator has two components, a touch and a collision processor. The collision processor can deal with multiple objects touching and movement of objects to ensure they dont exist in the same space. The touch processor allows an object to know if its touching on any of its faces and if its not touching anything at all.
How to install and run Isotope
First make sure you have SDL.NET installed. Run the SdlDotNetExamples application.
From the "Large Demos" menu item, select 'Isotope'.
You should see the tutorial world for the next section: The Joy Divsion World. Press keys 'o', 'p', 'a', 'z' and 'm' to move about and jump. 'g' picks up and object and 'd' drops it. 'q' and the escape key quit the demo.
Tutorial: A Joy Division World
Now that you have the demonstation running, its a good time to look at how a world in created in Isotope. The world consists of the Scene, Object3d and Skin definitions. If you open the IsotopeMain.cs file you will see the definitions for the objects after the SDL.NET initialization code. Two main structures are defined: an scene group then a skin group. These are lists of objects of the scenes with their objects and skins.
For the demonstration we create Ian Curtis for the player to control. He can move between two rooms, the bedroom and the lounge. In the bedroom we define a guitar for him to pick up, and a bed to jump onto. In the Lounge we provide a sofa and an amplifier. In both rooms we make some ground and walls so he does not fall into empty space.
Here's the code to set up the scene group : note the scene types 0 and 1 are used to match their background skins.
ArrayList joyWorld = new ArrayList(); Scene bedroom = new Scene(0, new ArrayList()); Scene lounge = new Scene(1, new ArrayList()); joyWorld.Add(bedroom); joyWorld.Add(lounge);
It simply defines a list for the scenes: joyWorld. Two scenes to put the objects into: bedroom and lounge. Now lets focus on the first object definition in the bedroom, the guitar:
ObjectPortable guitar = new ObjectPortable(new int[] { 60, 0, 40 }, new int[] { 20, 12, 20 }, 3, false);
bedroom.AppendObject(guitar);
The first line creates a object named guitar using the subclass of Object3d called an ObjectPortable. Its important because an ObjectPortable class can do more things than the Object3d and its used to represent objects that can be carried. The guitars starting position is defined as the first vector in the initialization parameters:pos. pos is an array based on pixel measurements from the origin point at 0,0,0. The next array is size which defines the size of the object, the space it occupies using its position as an offset. The last value defines the object type, this is a specific code which identifies how the object appears. It is the same number as the skin number in the skin group. The last line places the guitar into the bedroom scene at the end of the list.
An important object which allows the lead actor Ian Curtis to jump between scenes is the Portal object.
Portal door = new Portal(new int[] { 180, 105, 0 }, new int[] { 10, 30, 56 }, 5, lounge, new int[] { 10, 115, 0 });
bedroom.AppendObject(door);
The fourth argument 'lounge', links the door to the next scene from the bedroom. The fifth argument is the coordinate to place the lead actor. You will find another door definition in the lounge for a door which links to the bedroom.
Next we can look at the skin definitions. First we define a skin group using a list:
Skin[] skinGroup = new Skin[8];
Take a look at skin definition number 3, as the skins are numbered starting from 0, its for the guitar object above:
ArrayList guitarImage = SkinsLib.LoadImages(new string[] { Path.Combine(filePath, "guitar.png") });
skinGroup[3] = (new Skin(guitarImage, "Guitar"));
First we load the image for the guitar then append it to the skin group. Note that we can load multiple images at once if the skin has animations or different faces. This is very useful for actors that turn around. You can see this in the skin definition for Ian Curtis.
ArrayList ianCurtisImages = SkinsLib.LoadImages(new string[]
{Path.Combine(filePath, "ian_curtis0.png"),
Path.Combine(filePath, "ian_curtis5.png"),
Path.Combine(filePath, "ian_curtis3.png"),
Path.Combine(filePath, "ian_curtisF4.png"),
Path.Combine(filePath, "ian_curtisF6.png"),
Path.Combine(filePath, "ian_curtisF7.png"),
Path.Combine(filePath, "ian_curtisF0.png"),
Path.Combine(filePath, "ian_curtisF5.png"),
Path.Combine(filePath, "ian_curtisF3.png"),
Path.Combine(filePath, "ian_curtis4.png"),
Path.Combine(filePath, "ian_curtis6.png"),
Path.Combine(filePath, "ian_curtis7.png")});
skinGroup[4] = (Skin)new Pointing(ianCurtisImages, "Ian Curtis");
Finally we create and launch the engine using our scene and skin groups:
Create an isotope engine using the skinGroup and the sceneGroup
Engine joyEngine = new Engine(ianCurtis, skinGroup, surface, joyKeys, Path.Combine(filePath, "titlebar.png"));
Start the isotope engine
joyEngine.Start();
Thats just about it! Continue on to chapter 3 if you want to know more about Programmer Interface for Isotope.
The Isotope Programmer Interface
The Isotope programmer interface is the set of classes used to access and communicate with the Isotope engine. The classes are thoroughly documented in the code comments.
The following page provides a helpful summary sheet of the classes and some details associated with their use.
Interface Files
IsotopeMain.cs The engine is a combines, simulation, isometric view elements with keyboard response and an information display.
Scene.cs A scene or location in a game with objects inside the scene is represented by the scene class. Portals are also defined in the scenes and can represent doors or teleport systems.
Object3d.cs Items with simple behaviour in the game can be represented using definitions in the objects file. They can have gravity and be carried by actors.
Actor.cs Actors which can move about and jump are defined in the actors file. A lead actor and a monster type are also defined. Lead actors can change their scene and carry objects. The monster class is an example of an automated actor with a program to turn around when it hits something. The facing direction is important for actors and is defined using a unit vector. An actor will jump and put down objects in the direction they are facing.
Skin.cs The skins file defines the way an object is represented graphcally in the isometric view. The skin objects match the correct image to the state of the object. Designing graphics for isometric games requires special care as optimisations are used to ensure that object movement is smooth and quick. To calculate the required object size for a graphic you should use a graphics program to measure the x, y and z coordinates of the sprite. The z coordinate is the same but the x and y coordinates must be divided by 1.18.
Color key transparency is also important. Total white is used as the color key. This means that if a pixel with a value of RGB:255,255,255 is found they it is transparent and will show whatever is behind it.
Technical Specification
Required Software: SdlDotNet 6.0.0, .NET Framework 2.0.
Simulation: touch (proximity) and collision detection based on boundary box (aligned to the axes, not direction flexible), no world boundary or false ground plane. Uses objects to define a ground plane. Object tick, collision and touch events simulate velocity and gravity and can be extended by the programmer using the C# class system. Collision detection does not register objects that pass completely through an object in a single frame therefore object speed and size must be controlled.
Animation: multiple images translated to final display using skins. Game time clock provides frame sychronisation. Pygame is used to plot sprites to the display.
Drawing: Isometric representation in a pygame window, fully ordered sprites method. No tilling system. Allows objects to move in all x,y,z.
Isotope Engine Description
The core elements of the Isotope engine are defined in the IsotopeMain.cs file. These elements integrate the functions into classes which can be driven by the engine. The main function files are described below.
Isometric Pipeline
The Isometric pipeline uses two pipelines to process the object information: The Isometric pipeline to draw a view of the objects and a Simulation pipeline which models the movements and actions of the objects.
Isometric pipeline (Drawing the view):
Sprites.UpdateImages(Skin[] skinGroup, Object3d[] objectGroup) Isometric.Order(Object3d[] objectGroup) Isometric.GroupTransform(Object3d[]objectGroup, Sprite[] spriteGroup, int[] offset) Sprites.OrderedDraw(Sprite[] spriteGroup, int[]drawOrder, Surface surface)
The Skin class has a physical body (called an object) and a representation of the body to the computer in the Isometric view (called a Skin). It relates the ideal of the simulation to the practical visual representation on the computer screen. The skin class has a method: GetImage(), to translate the correct image to display based on the state of the object/body. The view position on the screen is calculated from the body/object positions (object group) and size values and the view parameters. The order of drawing the images on the screen is also calculated from the objects position and size values. The final result is an ordered sprite group which can be plotted into the window.
Simulation pipeline: Physics.cs module
Simulation pipeline:
Engine.PlayerControl(LeadActor player) Object3d.Tick() Physics.TouchProcessor(Object3d[]objectGroup) Physics.CollisionProcessor(Object3d[] objectGroup)
The physical world is represented by the objectGroup. It undergoes a movement phase which are AI (Object3d.Tick routine) and key presses for player objects. Then the object group is passed through a collision detection processor to ensure that objects are not overlapping in space and finally a touch detection processor which allows the objects to react to nearby objects.




