Coming up on the finish line, you got enough juice to go on?

Alright, so you know a bit about how to program or at least some of the details, but how much work went into getting various aspects of a game to function? Scott mentioned that one of the hardest aspects in R.C. Grand Prix, aside from the 'staggered brick' method he used for the track layout, was the problem with in-game car collisions. You might think it would be rather easy, but then again probably not after he just hit you with terms you probably never even heard before, so regardless let's see now what programming car collisions entailed. Here is a basic explanation, and the code, for inter-car collision in R.C. Grand Prix. First, check out the code by downloading this text file here:

In case you're confused the second you look at it, don't worry, and keep in mind that all programming functions off of basic math and symbols to get the computer to function, so you'll notice references to stuff like X and Y in there. Little symbols like ; are just part of the code and get things to function properly. So, to give an example from html that I'm using to put this together, if you want to make something bold you simply put the letter 'b' in brackets like this (without the spaces): < b > and then when you want to end the bold effect, just place a / in front of the b and place it in brackets at the end of what you wanted to put in bold. That's what all of those weird symbols and weird text are doing in the document, telling the computer what to do just like you do in html. It's impossible and unnecessary to explain every bit of code because you'd essentially be receiving a course in programming, but the following should be enough to give you an idea of how things work. Any tech heads who understand assembly language should be able to just glance at it and have a clue what's going on. For those who wouldn't, let's hear what Scott has to say about the file above.

"Most video games from the 8-bit era ran on computers that were small and slow compared to today. 8 bits and 1 megahertz (one hertz is one cycle per second) to today's 32 bits and 1 GigaHertz. Therefore it was almost always necessary to cut corners and use some finesse to make these systems do what you needed them to do." The program code he's about to describe reflects this.

"To get the smoothest motion in an action game like R.C. Grand Prix you need to update the screen at the full rate, or 60 times a second (50 in some other countries, so there's where hertz comes in, you know, like 50hz or 60hz you hear on the forums at times). So the basic game 'cycle' of reading the joystick, updating the status of the game, modeling physics, and rendering the image has to be performed in 1/60 of a second. Detecting collisions between cars is one of those tasks done 60 times a second. It's a complex task, so a lot of shortcuts are necessary. It nevertheless results in some pretty spectacular and realistic looking multicar collisions with minimal load on the SMS processor. The submitted code shows a single main routine 'InterCarCollisions' and its subroutines (just a portion of code that's part of a larger program, so again, this is just one part of the game itself) and data which is performed as part of the physics modeling of the cars. The first task is to obtain the position and rotation of every car and copy this to the local data structure we can work with conveniently. Then, each possible collision is tested for:

car #1 with car #2,
car #1 with car #3,
car #1 with car #4,
car #2 with car #3,
car #2 with car #4,
car #3 with car #4.


Each test starts with an 'early out' in which we disregard any possible collision involving a car not visible on the screen. This is to save computation time and keep the game running smoothly. If both cars tested are onscreen, then they are tested for collision in the subroutine 'Detect Collision', which Scott will describe further below. If a collision is detected, the car's vectors (just the primitive lines, polygons and so forth that are used to represent objects, ie to create images on-screen) are swapped by the subroutine in the macro called 'SwapVectors', and you go on to check for other collisions until all are checked."

"Swapping vectors satisfactorily models collisions of moving solid objects. Take for example colliding balls on a pool table. A cue ball is moving directly towards the eight ball. If it's a direct hit, the cue ball will stop moving after impact and the eight ball will move in the direction and speed the cue ball was moving in. Thus, the cue ball took on the movement vector of the eight ball (zero vector, or standing still) and the eight ball inherits the cue ball's vector (moving forward). Similarly, if you rear-end a car, your car stops and the car you hit goes in the direction and speed you were going in. This simplification of collision physics (swapping vectors) results in satisfactory inter-car collisions and isn't too taxing to the SMS' puny computer."

"The subroutine to detect collisions starts with its first early-out test, which is to see if the graphical rectangle of the two cars, each a 32x32 pixel square, overlaps. This is done by simple subtraction, and if they don/t overlap, the routine returns a flag indicating the cars are not colliding. If the cars are within 32 pixels of each other then they had to do a precision detection in the subroutine 'DetectCollision' to see if the cars are not just near each other but are actually touching. For this, special collision bitmaps have been crafted by hand so that cars can overlap visually but not in fact touch physically, like when one car is behind (above) another. Each car can point in a total of 24 possible directions. The table 'Rot2BitImage' is used to locate the collision bit map that corresponds to the car's rotation. Then the bitmaps for the two colliding cars are offset and shifted vertically and horizontally, and a logical 'and' (a binary operation) is performed on each overlapping byte of bitmap data. If any logical 'and' results in any non-zero bit (binary code, remember), then the cars have been determined to have collided."

"In addition to swapping vectors, one fudge must be performed to make sure the cars do not stick to each other. It's possible, while time slicing movement only 60 times per second, for two cars to become embedded together. When this happens the car's vectors are swapped 60 times every second, and the cars end up stuck to each other. To prevent this, the cars are bounced off of each other with a little extra force in a function called 'MagnifyVector'." So to go back to the cue ball example, you're just artifically increasing the amount of force put into the other object. If you hit the eight ball and throw the function 'MagnifyVector' on it (I guess with your mind perhaps), it goes faster than what the initial speed of the cue ball was. This all being said, even if you're not a tech freak, you should now be able to go through that code above and have a pretty clear, though basic, understanding of what you're looking at. So all that assembly language, followed by a slew of binary bits ones and zeros coming at you, is all for how the cars collide in R.C. Grand Prix, that's it, not for which level, graphical designs for the crowd or anything else, just for their collision. You should be able to see the different cars being tested and so forth, though some of the code and commands may still be alien. I asked him if he happened to have the full code for some of you to look at and understand, but unfortunately he no longer has it. As it is, I'm happy he spent his time explaining just this bit. So I hope you didn't have too much trouble, but one thing that should be clear, however, is where the program, and this article, end!

A huge, incredibly, ridiculously huge thanks to Scott for being so generous with his information, pictures and data, I don't think you'll ever find a programmer so willing to share their experiences and I almost can't believe how much he put up with my stupidity and inane questions through the whole thing. Hey, I even got a free shirt out of it that he printed out during the development of R.C. Grand Prix for his friends to wear at Imagineering. Sure, it's just a simple, printed shirt, but it's pretty cool to receive something like this from the actual guy who put both it, and the game it represents, together. Check it out, drool if you want, and reread if you didn't get it the first time! Hopefully I'll be able to have something as cool as this in the future, but I have to say it's going to be hard to match everything Scott provided, and with the amount of space I had here and time, it came out much better than the NES article ever would have. Got to hate elitism when people don't post pictures or text you want, so when I have control, I make the most of it, sometimes... Thanks again, Scott, and I hope all of our members had a great read! Go gab about it at the forum by clicking on the OFFICIAL Sega8Bit super model below.


 
Copyright © 2024 Sega8bit. All Rights Reserved.
Contact Us