Archived

This topic is now archived and is closed to further replies.

Dark Star

Making Mario Kart type of games...what's involved??

Recommended Posts

Dark Star    100
Hi everyone, I am interested in making a game like F-Zero and Mario Kart, you know, a 2D racer which uses clever scaling techniques to look like it''s 3d just like F-Zero and had a few questions for you to help me on my journey 1) I need a good web-site for that kinda information. Where can I go to? 2) Does anyone have any idea how to represent a 2D 2x2 map of a level in perspective like in mario kart so that as you look at the road ahead it appears to be converging into the centre of the screen (I hope you know what I mean..you know, perspective view) 3) About artificial intelligence and making other racers follow the track. How would YOU go about coding the AI so that CPU racers appear to be racing and following the track but with a few behavioural differences, so they don''t always take the same path as each. 4) Scaling sprites so that they look like the are infront like in the distance like in Mario Kart of F-Zero when vehicles get smaller as they advance into the distance. 5) Designing the level in a 2D editor and then including racing track attributes like bumps and ramps, which make the car jump up abit. How will I give the illusion of a car bumping up on a ramp or bump. 6) How would you suggest I design a level editor so that it''s very easy to make good race tracks 7) If I use a 2x2 matrix to represent the track and level, then how to I get curved roads as the player turns if all level entities will be orthahonal (that''s the first time I am using that would and I am assuming it means that objects are 90 degrees to each other. Correct me if I am wrong please). F-Zero has curved roads which leads me to wonder how their levels are stored. 8) About spacing with all the race entities and collision detection. The track I create in the track editor may have each road segment or racer spaced by 1 block in the map, but when it comes to translating the spacing when it comes to rendering the screen and all racers. That''s about it.... I have never made a trick 3d type game like doom or Wolfenstien and I know the involve raycasting or ''tracing techniques and I am not too sure about them but my game specific ignores walls and trees and rocks I just wanna know how to translate a 3d map into perspective and make it look kinda 3d well the race track anyway. --CELEBRATE GOOD TIMES --------------------------------------------- I just want every to know that I have finished college and am totally happy that I am free !!!!! (Just like MYA Lol) and I am starting unoversity this September doing a Comnputer Science course in graphics and games I am so happy. I have got a whole holiday of 3 months to begin on this new game YEAAAAAAAAAAH !!!! WHO''S BAD ???!!!!!! ---------------------------------------------------------------------- Sorry enough of that... I sure asked a lot of questions but you don''t need to answer then all just as many as u can or u want to. If you have any helpful source code can I have it. If you know of any interesting sites with this kinda game production please can you tell me? Any help is good help !!! Thanks in (Gameboy) advance Dark Star UK

Share this post


Link to post
Share on other sites
mr_jrt    134
Althought I can't help you much, I'll share what I can.

The scaling on F-Zero and Mario Kart used the SNES's mode 7, which had harware support for rotation and scaling, and this is how the backgroungs were created (another few examples would be the flight sequences in the Secret of Mana and it's sequel as wel as Pilotwings and others...).

A simple method I would have thought would be to render the track as a 2D bitmap (in sections or in whole...but that's irrelevent), and then rotate it to the current angle of the player, and then do the perspective effect.

E.g.


abcd
efgh
ijkl
mnop


becomes....(@45 degrees)


a
e b
i f c
m j g d
n k h
o l
p


and correct the perspective....
(you get the idea...skip more lines from the top half)


i f c
m j g d
n k h
p



The AI would be fairly easy to make different, just give different racers different attributes, and make them competitive. Usually with these things, less is more.

Bumps etc are easy. Notice how the player's kart usually stays in the exact same spot whilst everything else moves....thats cause the road is background being rotated. So to do a jump, just move the sprite up and down again, whilst keeping them moving. Easy peesy physics.

The level editor is up to you, but just do a standard tile editor if you use the 2D bitmap method. Curves are just drawn curved, the display rotation will deal with everything else.

Sorry it's a bit unclear, but my just my first thoughts on reading your post.

Good luck with your game(s).
I'm off to uni in Sept...so more games programming for me hehe!

Waassaap!!

Edited by - mr_jrt on June 19, 2001 12:16:19 PM

Share this post


Link to post
Share on other sites
SlimSpek    122
why not make it totally 3d? it would be much more straighfoward, look better... yes, it probably would take longer, but it would be worth it for both the experience and you''ll end up with a much nicer game. If you do decide to go 2d... you''re pretty much on your own, welcome to the problem solving part of game programming.

Share this post


Link to post
Share on other sites
BoRReL    122
Hey,

Raycasting is the clue I guess.
Find info on free directional planes!

It''s the way wolfenstein and doom ceilings and floors were rendered (probably).

They are also easy to implement and very fast!

Think about spritescaling yourself...It''s not difficult!

Gr,
BoRReL

Share this post


Link to post
Share on other sites
ancientcoder    122
Here is some old code, 1993 very old , that I wrote for Wacky Wheels (1994). http://www.3drealms.com/wacky/index.html

The final version of the Wacky Wheels rendering code was written
in assembler and used a lot of fixed point math. So this C code
was a very rough test. But on todays machines it should in
theory fly :-) It does work though.

Basically you set up a viewing height using some Trig, have a look at any math book on similar triangles, and for each scan line I interpolated the map positions.

The map is indeed a two dimensional array with bitmap pointers
to the actual graphics. We used 32x32 bitmaps and a 1024x1024 fine coordinate system.

The karts followed various preset vector lines laid down in the
map. We had several racing lines predetermined but the NPC's would take more aggresive lines if they detected you where getting too good.

The bitmap scaling is based on distance. All the karts where 48x48 so we pre interpolated this matrix for several distances and plugged this into the rendering code. Basically take a square root from the players position and divided this
into your scaling array.

This code does not show you how to plot the map as all I
had back then was Modex. That would have cluttered it up.

However the code interpolates accross the fine coordinate
system of the map. I leave it up to you to convert this
into your grid system and get at the pixels within the bitmap and so on.

I tried to clean the code up as best as possible but you should
be able to fill in the gaps.

Set these up somewhere as you seem fit. I used a cos and sin table with 4096 elements for fine angular movement. Note these cos and sin tables are in Radians.

SCREEN_WIDTH = 320
SCREEN_HEIGHT = 200
HALF_SCREEN_WIDTH = SCREEN_WIDTH/2
HALF_SCREEN_HEIGHT_MINUS_ONE = (SCREEN_HEIGHT/2)-1
BOTTOM_Y = 199
TOP_Y = 126
VH = (TOP_Y-BOTTOM_Y)-1
VIEWDIST = 256
NUMDEG = 4096
LEFT_COL_ANGLE = atan(-HALFSCR_WIDTH / VIEWDIST) * (NUMDEG / 6.28)
RIGHT_COL_ANGLE = atan(((SCREEN_WIDTH-1) - HALFSCR_WIDTH) / VIEWDIST) * (NUMDEG / 6.28)
RD_LEFT = cos_table[LEFT_COL_ANGLE];
RD_RIGHT = cos_table[RIGHT_COL_ANGLE];
ONE_OVER_SCREEN_WIDTH = 1.0/(SCREEN_HEIGHT-1)

---------------------------

/* This takes the player_angle and again because it is a lookup table the
player_angle is an integer pointer to the angle table */

void Draw_Map(void)
{

/* add the left angle to the player angle */

rad_angle=player_angle+LEFT_COL_ANGLE;
if(rad_angle>NUMDEG-1) rad_angle-=NUMDEG;
leftsin = sin_table[rad_angle];
leftcos = cos_table[rad_angle];

/* same for the right hand side of the screen

rad_angle = player_angle+RIGHT_COL_ANGLE;
if(rad_angle>NUMDEG-1) rad_angle-=NUMDEG;
rightsin = sin_table[rad_angle];
rightcos = cos_table[rad_angle];

/* loop for the height of your plot window we chose 74 and a viewdist at
256 because it just looked ok */

for(y_screen = BOTTOM_Y; y_screen >= TOP_Y ; y_screen--)
{

/* get the left and right X,Z positions of the map
we chose Z instead of Y because the karts could jump and
stuff. So actually we where treating it as 3D system */

ratio = VH / (y_screen-HALF_SCREEN_HEIGHT_MINUS_ONE);
ratmult = ratio*VIEWDIST;

dist = -(ratmult / RD_LEFT);
x_map_1 = (dist * leftsin) + map_pos_x;
z_map_1 = (dist * leftcos) + map_pos_z;

dist = -(ratmult / RD_RIGHT);
x_map_2 = (dist * rightsin) + map_pos_x;
z_map_2 = (dist * rightcos) + map_pos_z;

dx = (x_map_2 - x_map_1) * ONE_OVER_SCREEN_WIDTH;
dz = (z_map_2 - z_map_1) * ONE_OVER_SCREEN_WIDTH;

xterp = x_map_1;
zterp = z_map_1;

/* xterp and zterp are the actual fine coords of your world
now you would take these positions and work out where
you are in the map and then do the bitmap plot */

for(x = 0 ; x < SCREEN_WIDTH ; x++ )
{
xterp+=dx;
zterp+=dz;
} /* loop x */

} /* loop y */

}

I would suggest using a 3D api these days but you still have to deal with view frustum culling and so on. Oh if only you knew the what it was like back in 1993



Edited by - ancientcoder on June 23, 2001 6:46:07 PM

Share this post


Link to post
Share on other sites
merlin9x9    174
Honestly, there are a number of cases where doing fake 3D with 2D is a lot tougher than just doing 3D for real. So, this is a great project to try. However, doing your perspective and sprite scaling is a bit tricky. You might consider using a 3D API to help you out, though I''m not saying to make the game 3D itself.

For the landscape, simply texture a large plane--or many planes in a tile orientation--and the API will do the perspective stuff for you. Not only will this make the display very quick, but makes effects such as interpolation and fogging trivally simple.

For your objects, use a technique called billboarding. Your objects will be sprites and you''ll still have to "decide" which sprite to display based on the viewing angle and the object''s orientation. To display them, just texture that sprite onto a quad parallel to the camera at the position you need. You can use gluProject and gluUnProject to convert between screen and world coordinates as necessary.

Let me know what you think, and please keep us updated.

Share this post


Link to post
Share on other sites
merlin9x9    174
...which brings me to an important point. THERE IS ABSOLUTELY NOTHING WRONG WITH 2D GAMES! 2D or 3D doesn''t intrinsically make a game any more or less enjoyable. It''s the actual game--the gameplay--that makes it good. People, never forget that, eh? Don''t let the artform die; don''t let it keep decaying to the point where only flashiness matters.

Share this post


Link to post
Share on other sites
ancientcoder    122
I agree. Gameplay,Gameplay and more Gameplay. It is a pity
though that eye candy seems to be the holy grail these
days.

That is why I like the handhelds because of the limited
hardware. But even these will have micro 3D accelerators
in the future so we are all doomed

I got a GameBoy Advanced today and have spent hours on
Super Mario. I must admit the reason I wrote Wacky Wheels
was because when I saw Super Mario Kart on the Super Nintendo
I just said "I have got to learn how to do that game".

Ok I did try to clone it but people kept telling me it
was impossible to do on a 12mhz 386 so I just had to prove
them wrong.






Edited by - ancientcoder on June 23, 2001 8:00:39 PM

Share this post


Link to post
Share on other sites
richardve    122
Oh man, I''ve played Wacky Wheels many many many many times on my 386sx

Thx for making such a great game!

btw. I''d love to see a real 3D version of that game.. :D


Sorry for going offtopic

Share this post


Link to post
Share on other sites
Thrump    169
I think the point of using 3d in this case, is that it would be simpler to emulate the 3d looking 2d mode7 that was done in F-Zero by actually using 3d (looking like 3d was what they were trying to do anyway). Unless you''re programming a system where actual 3d cannot be done easily (ie super nintendo), or, you have an unusual fetish for mode7 (do not read 2d here, i''m talking about mode7 specifically). I''m saying here, you can emulate any mode7 using 3d, and in this case, probably more straight-forward.

And I agree whole-heartedly that 3d does not make a better game. Castlevania SOTN on the PS was the #2 best seller, on a primarily 3d system. The only reason Metal Gear Solid did better was it was on awesome game, regardless of 3d.

Btw, mode7 used a 2D matrix for it''s operations, but I think you''re using it in the wrong frame of reference in some of your questions. There''s no way you''d store your level in a 2x2 matrix. I may be misunderstanding you.

Share this post


Link to post
Share on other sites
merlin9x9    174
I disagree that the game should be made a 3D game, assuming that you''re suggesting that, Thump. If it were fully 3D, levels must be created in full 3D, which is much more complicated than just drawing an image, as you''d do if it were 2D. Collision detection becomes a major, non-trivial task. Issues such as backface and frustum culling become more critical. Etc., etc. 2D is much simpler in the long run, in my opinion. Now, if you''re saying to use a 3D API to accomplish the same look--a textured plane--then I agree 100%.

To answer one of your questions about editing levels, Dark Star, here''s how I would approach level design, assuming that you choose the textured plane (or multiple planes tiled together to keep individual texture sizes down). Draw your courses in, say, Photoshop using a bird''s-eye view; that''s the obvious bit. Now, you''ll need to make an editor, or you could maybe figure out a way to grab coordinates from your image by hand. Either way, I''d probably use [connected] lines to define the track boundaries--for curves, you just use lots of lines, though you don''t need tons of detail since the lines are just to keep the player inside. The objects will most likely be tracked in 2D or 3D space as points, and you should store a value for radius, so you can test that against the lines. Using the object''s movement vector and the line''s normal (which you''d have pointing toward the inside of the track) you can calculate bouncing and damage and such. That should do it, really.

Now, AI is somewhat of a challenge. Since ancientcoder worked on a similar game, he''s probably a much better authority on such things than I am. I''ve often wondered how programmers implement AI in racing games. Generally, it seems as though they follow a pretty standard path through the course. Perhaps you just make the non-player racers follow a path parallel to the track side, give or take a bit of randomness; there will also be some differences between characters based upon their vehicles'' acceleration curves and handling properties as well.

I hope some of that helps. Again, please keep us posted; I''m always tickled when I actually see people interested in 2D games...

Share this post


Link to post
Share on other sites
ancientcoder    122
For collision each tile was 32x32 and had an associated mask attached to that tile which was essentially a grey scale bitmap of the actual bitmap.

This tile described two things. What kind of surface this
was by assinging each pixel of the bitmap a value. So 1 may
have been grass,2 = water and so on. We kept 0 as non passable.

This was very accurate because one wheel could be on grass and the other could be hitting a boundry pixel. However this
level of accuracy may be over the top and you could easily
use line segments to do much the same thing.

The AI was pretty straightforward. When I studied Mario Kart
I noticed they where following pre set driving lines. However
they would occasionally bump you and follow a different driving
line on certain occasions.

I laid down connected line segments on the map for the other
karts to follow. At certain points in the track I had cross
over points so they could take another line if needed.

At certain stages in the race each opponent would check it''s
status against yours. The karts would get more aggresive (eg
come off there line to bump you) depending on your progress and
they would also speed up slightly in some cases. I was not
happy with the speeding up phase because it could look the
other karts where cheating now and then.

These values took a lot of tweaking and the beta testers gave
valuable feeback on this, all in all Wacky Wheels tries to
give a good fair race.

The hardest part of this game ,and it nearly killed me,was
the multiplayer over the modem. Doom had just come out and
we where in Beta. Everybody was screaming for multiplayer,
I think Apogee wanted to be the next game to have it. It
nearly involved a rewrite. The serial link was pretty
straightforward but packet loss and corruption was a very
real hazard on the modem game. I had to write my own protocol
and most of the code was dedicated to retrieving out of sync/
corrupt packets.

We where two weeks away from release and I did not sleep
one wink in that period. Nearly gave up a few times










Share this post


Link to post
Share on other sites
Thrump    169
"3D API to accomplish the same look--a textured plane"

That''s exactly what I was saying.
Don''t worry, I''m as old-school as they come. "Thank God for GBA!" me says as I reach for F-Zero Maximum Velocity.

Share this post


Link to post
Share on other sites
Thrump    169
Ah, dark star. Just noticed your
"Thanks in (Gameboy) advance"

So thats why you want to know how to do it in 2d using 2x2 matrix...

Share this post


Link to post
Share on other sites
arnero    938
When I read the code right,
Wacky Wheels
did not use surface caching,
but instead first looked uo the tile in the map an then the color in the tile
for every pixel when rendering.

Doom uses the second lookup for lightning stuff.
Maybe this just fits somehow to other timings on those old machines.

Share this post


Link to post
Share on other sites
dmiles96    122
Hey ancientcoder!

Thanks for making that game. There is a significant portion of my life (and my friends lives) that I spent with that game. I loved it.



Edited by - dmiles96 on June 24, 2001 4:36:29 PM

Share this post


Link to post
Share on other sites
merlin9x9    174
Yeah, Thrump, I was pretty sure that''s what you meant. I was jus'' checkin''.

Hey, ancientcoder, what do you think of perhaps merging both the tile and line techniques. Use tiles to describe the terrain--grass, dirt, asphalt, etc., and use lines for track boundaries. Think that''d be good? If I understood correctly, you''re saying that Wacky Wheels used tiles for boundaries as well as attributes, and I imagine that line segments have the potential to give much greater accuracy than tiles (unless, of course, you have one tile per pixel in the terrain image). Lines make it lots easier to do accurate physics such as bouncing. Is this correct? I ask rather than assert because I can''t claim a shipped game as you can...you know...humility. =)

Share this post


Link to post
Share on other sites
arnero    938
About this X-mode thingy:

Because the floor covers only half of the screen
it is possible to arrange video-mem so that the floor
portion in buffer one and two (back and front) are accessible via chain4 mode (13h),
thus x-mode hacking only for sprites and background,
and fast blue sky (writing four pixels at once)

(Not possible for indoor, because of ceiling,
not possible for car racers with hills...
this trick is only for cart)

Share this post


Link to post
Share on other sites
ancientcoder    122
There are a few replies so I lumped them into one.

BoRRel
quote:
How big was your team then?


Myself (coding/design and sound effects!!)
Shaun Gadalla Art and track design.
Mark Klem (Music)

We also purchased Jim Dose''s Sound Engine.The whole game took just under a year. Very intense :-)

Arnero
quote:

Wacky Wheels
did not use surface caching,
but instead first looked uo the tile in the map an then the color in the tile for every pixel when rendering.



Correct there was no surface caching. We could though in theory have used sectors like Doom did. This would have helped on cache misses but because the track needed to be very detailed we traded this. Unrolling the rendering loop helped out quite a bit. Plus I figured the trick of writing everything out in vertical strips because of the mode-x plane switching. In fact I had not even read Abrash had done this. Amazing what a simple mindshift can do sometimes.

dmiles96
quote:

There is a significant portion of my life (and my friends lives) that I spent with that game



Thanks It is so satisfying writing a game that other people enjoy. That is what makes writing games so rewarding. Writing them can be so dammed frustrating though!!!

merlin9x9
quote:

I imagine that line segments have the potential to
give much greater accuracy than tiles (unless, of course,you have one tile per pixel in the terrain image)



This is a typical case of temporary code that stayed in the final release Each collision tile was an exact replica of the ground tile. So we made a collision with the ground tile then dug deeper within it for surface info. So we had in effect true pixel collision. No matter how complicated the surface curve was we had an exact hit.

This was a bit over the top

For performance reasons I was worried about doing a lot of point
in poly and line intersection tests. So I traded memory for the
problem. But in hindsight I would go with line segments /polygons right now for all the reasons you pointed out,so yes you are correct to assert :-)

I think the lesson is that we can always make the code better.
When I look back at the Wacky code I know there are several
areas that could be vastly improved. I think John Carmack
said that Wolfenstein would have been better with a BSP
tree.

Cheers
Andy

Share this post


Link to post
Share on other sites
Royale00    122
Hi AncientCoder Im trying to develope a Fzero type racing game for game boy advanced. Ive tried porting your code that you posted earlier and it doesnt work. I justed wanted to know if there is another way to approach displaying a map with perspective or just the basic equation.

Share this post


Link to post
Share on other sites
DekuTree64    1168
You might want to check out http://www.gbadev.org/. There''s a demo of a Mario Kart-type game there, but it doesn''t include the source so you''ll have to ask the guy that made it if he''ll send it to you.

GBA looks to be a very good thing to me. SNES was the ultimate game system if you ask me, and GBA is quite similar, and with so many more people into programming nowadays, there''ll probably be plenty of great games^^ I''m just starting on an RPG myself, but it''s still mainly in the designing stage, and I''m still working on my PC side-scroller, so it probably won''t be done for a long time.



-Deku-chan

DK Art (my site, which has little programming-related stuff on it, but you should go anyway^_^)

Share this post


Link to post
Share on other sites
lower_case    122
I''m not actually serious about pointing this out, just joking around.. hehe.. but many of you say switch from 2d looking 3d to real 3d.

making 2d graphics that look 3d is exactly what 3d grahpics do, there is no real 3d.

just like there is no spoon. heh.

anyway don''t bitch at me, I know what you really meant.



CrappySoft - game production team with a punk attitude. Mail me if you want to make levels, art etc.

Share this post


Link to post
Share on other sites
TerranFury    142
Given a single vector (the view vector), you can use a modified version of Bresenham''s line-drawing algorithm to move across an array of tiles, in lines perpendicular to the view vector. Then, all you need to think of is this: The size of an object is inversely proportional to the distance from the object, and the length of a 2d scanline on the screen in 3d space on the plane is directly proportional to the distance it is from the camera. Then, there is a corrolation between screen y coordinates (starting at the bottom, not the top, as is normally the case), and that is that the distance on the plane corresponding to a given scanline on the screen equals y * y, where y is the distance from the bottom of the screen.

This technique should be easy to adapt to rendering voxel heightmaps, I think.

Share this post


Link to post
Share on other sites