
|
Articles >> The 3D Game Engine of WormRaider The 3D Game Engine of WormRaider
When I decided to go back to school to get a Computer Science degree, one of the first classes was Programming in C. Although it was fun to learn C, it was C++ and Windows development that I was really interested in. I picked up a book on the subject and between the C class and the second class that delved into C++ and classes, I started work on Windows development. Not knowing much about classes, I kept my code simple despite the complex object manipulation needed for the Windows API. It was a bit of a steep learning curve, but was able to do some fun things. Once I got into basic graphics routines like lines and polygons, I had an idea. I had grown up playing classic computer games like The Bards Tale and Wizardry. I thought it would be fun to see if I could create a dungeon crawler game like Wizardry, using just the basic graphics routines of lines and polygons. Thus began an endeavor that lasted for months spanning countless nights. The final product was WormRaider, now in version 2.0.0. The new version added a level builder, but was actually put to the side for several months previously. When I got back into it and look at the calculations, it was like looking at Greek. I remember writing the code, but had a hard time recalling my logic. Much of it I recoded and then expanded upon... and renamed it version 2.0.0, expecting to make minor changes and fixes in the future. I haven't... nor will I, probably. A new version will most likely involve a complete redesign of the 3D engine. However, the current game of WormRaider offered a great deal of understanding and experimentation around the heart of any 3D, first-person, environment. This article will delve into the math involved in creating a first-person 3D engine in the spirit of the classic games like Wizardry. Brush off your Geometry and Trigonometry high school books... we're getting medieval on this thing!
So, how do you represent a 3-dimensional world on a 2-dimensional plane? You can throw down some lines at call it perspective... but something just doesn't look right. Depth and proportion... they don't lie. Our eyes and brains know better. Our minds may not know how to duplicate it when logically trying, but we'll know when it's wrong. Our plan is to simulate the environment as best we can. A painter and photographer attempt to duplicate the environment on a 2-dimensional plane... and oddly enough, it's these art forms that give us a clue as to the tools we need. I should mention that I'm a bit of a reinvent-the-wheel kind of guy. There are numerous books and tutorials online about 3D engines, but I didn't look at any of them. In a rather evolutionary, Darwinian, manner, I enjoy starting with the basics and building from there. I enjoy reinventing the wheel. I think it is the only way to truly understand what that wheel is and how it got there. Why? To understand where it is going. To take it there. Too many people nowadays know how to program, yet are lost at some of the most basic concepts. People want the immediate and want it now. They want the tool to do the job for them. Sadly, if that tool is ever taken away, or if that tool is flawed, then they are at a complete loss. I go for the foundation and build from there. Much of what I talk about may seem a little pedestrian for some, but it's that foundation of simplicity that allows for greater discovery. Back to Art. I had taken art classes since I was in 4th grade, and mostly in the form of drawing what you see. One of the most basic techniques is to use a view finder to limit your view and focus on and frame your subject matter. The view finder was simply a 3"x5" card with a rectangle cut out in the center. The rectangle was the same proportions as the canvas you were drawing or painting. The idea is to hold the view finder up between you and the subject matter and frame the scene, allowing your eye to gauge relative size, distance and proportion from the view finder to the canvas. Effectively, duplicating what you see through the view finder onto the canvas, as if it was a larger view finder. In actuality, the geometry is exactly the same for photography. However, where the view finder is in between you and the subject matter, the view finder is behind the lens and the subject matter. Each able to create a smaller version of the view in perfect proportion. ![]() The concept of the view finder is exactly what is implemented for a game engine. The artist sitting in front of the scenery is the character in the game environment. The view finder to canvas is your monitor. Like the rays of light shooting through the lens of a camera to the film, your subject matter will pass through a plane at a smaller proportion... that plane will equate to your monitor... and we will have our photograph. ![]() Mr. Sculpy has agreed to be our model. He is our in-game character and the geometry will be built around what he sees. The proportions will then be duplicated and scaled for our monitor. Lets begin by placing a single cube-shaped block in front of Sculpy. As you can see, it's taller than he is. To see the top of the block, there is an angle, a, that is the offset from his normal line-of-sight. Another angle, b, for the angle offset from the center to look down to the bottom. Important lengths are also the height of Sculpy's point-of-view, h, the distance Sculpy is from the object, d, and the heights of object relative from his central point-of-view, y1 and y2. Given d, y1 and y2, we can determine a and b. tan(a)=y1/d --> a=arctan(y1/d) tan(b)=y2/d --> b=arctan(y2/d) Quick Note: Anytime you work with Sine, Cosine, or Tangent, you need to remember you will be working in Radians, not Degrees of an angle. To convert Degrees to Radians, multiple by Pi/180. To convert Radians to Degrees, multiple by 180/Pi. (Pi being the magic number 3.14159265358979323846...)
![]() The next stage is to create the view finder relative to Sculpy. The view finder will always be a set distance from Sculpy and the dimensions of the view finder window should match the proportions of your monitor, or viewable game area. In a way, you sitting in front of the monitor should duplicate Sculpy standing in front of the view finder. If you are feeling really adventurous, you can pull out a tape measurer and calculate the distance you sit away from the monitor and the relative size and super-impose those dimension on top of Sculpy's virtual reality. The object may be 15 game feet away from Sculpy (d), and the monitor is 1.5 feet away from you. Therefor, the view finder will be 1.5 game feet away from Sculpy. Using the angles we calculated, a and b, we can determine the size of the object framed within the view finder. I will assume v1 and v2 represent the smaller proportioned y1 and y2, dv is the distance from Sculpy to the view finder, and Yv is the total size of the view finder. tan(a)=v1/dv --> v1=dv*tan(a) tan(b)=v2/dv --> v2=dv*tan(b) The ratio of v1 to Yv will therefor be the same as the ratio of the monitor's pixel height to the Y-offset in pixels from the center. I'll use M as the pixel size of the monitor, and P will be the Y-offset in pixels. v1/Yv = M/P --> P = M*Yv/v1 Let's say you're running 600 pixels in height for the monitor. P will be the number of pixels from the center where the top point of the object will be rendered. Remember a pixel on the screen needs both an X and Y coordinate, so you will have to determine both the X and Y dimensions. Luckily, the logic we used for the Y direction, can be applied exactly the same by modelling the scenario from a top-down view. Otherwise, the geometry is exactly the same. The calculations are done for each point of every face of the object. In WormRaider, most of the objects were square blocks, so four points at a time were calculated for each face of the cube. The other thing that made WormRaider easy to develop was the fact that there is no free-form movement. I didn't have to worry about rotating around and having the objects rotate around the point of view. Although this gets a little complex, it is still geometrically based on the simplicity of the above calculations. Quick Note: As much as I love Sine and Cosine, if you have d, y1 and dv, then you really don't need to calculate the angle. I know... I know... why didn't I mention this before? The geometry is too simple. If you followed and understood the above, then the complexity of free-form movement becomes one step closer. No matter how hard it is to model, it can be broken down into simple 2-dimensional Geometry and Trigonometry. So, like your parents would say, "You'll thank me later."
What is the simple version? You should be able to see it. It's just another ratio of the distances and heights... v1 = dv*y1/d. I know. Much easier. (It pains me to not use some Trigonometry) Hopefully, you have a better grasp of how you can model a 3-dimensional environment and how simple the math involved really is at its heart. As long as you know an object's position from your character, you can create a realistic point of view pretty easily. Determining an object's position relative to you and knowing which faces of the object to render and in what order is a whole other subject matter. Looking at the volume of calculations needed for just one pixel, you can see why 3D graphics cards are so vital in today's games of tens of thousands of polygons. For WormRaider, even though the graphics were so simple, I was able to add a couple details to really make it come alive. Knowing the distance objects were away from the player, I created a color pallet that became darker the farther you were. Different hues were also used for the walls, floor and pits, helping add more depth and dimension. Not every 3D game needs to look state-of-the-art... sometimes getting back to basics can be just as enjoyable... and well worth the effort as a learning experience. If you use this info to build your own 3D environment, please send me some code and let me know what you did. I'd love to share it for others to see. --Joby Bednar |
| Copyright © 2005-2006, Joby Bednar. All Rights Reserved Nothing may be reused without my approval. |
You: 38.107.191.99 Now: 9/8/2010 5:20:08 AM |