Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

Is there such a thing as a short answer on how to do a Mode 7 / mario kart type effect in pygame?

I have googled extensively, all the docs I can come up with are dozens of pages in other languages (asm, c) with lots of strange-looking equations and such.

Ideally, I would like to find something explained more in English than in mathematical terms.

I can use PIL or pygame to manipulate the image/texture, or whatever else is necessary.

I would really like to achieve a mode 7 effect in pygame, but I seem close to my wit's end. Help would be greatly appreciated. Any and all resources or explanations you can provide would be fantastic, even if they're not as simple as I'd like them to be.

If I can figure it out, I'll write a definitive how to do mode 7 for newbies page.

edit: mode 7 doc: http://www.coranac.com/tonc/text/mode7.htm

share|improve this question
    
Please post a link to such a doc, so we can guide you through the math. –  Maik Semder Mar 4 '12 at 12:16
3  
there seems to be equations here: en.wikipedia.org/wiki/Mode_7 Although, these days we have 3D acceleration, things like Mode 7, or the whacky way doom worked are more of a curiosity than a solution. –  salmonmoose Mar 4 '12 at 12:27
2  
@2D_Guy this page explain the algorithm very well for me. You want to know how to do it, or you want it already implemented for you? –  Gustavo Maciel Mar 5 '12 at 3:53
1  
@stephelton On the SNES systems, the only layer that could be distorted, rotated..(applied affine transformations with matrices) is the seventh layer. The Background layer. All other layers were used to simple sprites, So if you wanted a 3D effect, you had to use this layer, this is where the name came from :) –  Gustavo Maciel May 8 '12 at 11:02
1  
@GustavoMaciel: That's a bit inaccurate. The SNES had 8 different modes (0-7), in which up to 4 background layers had different functionality, but only one mode (mode 7, hence the name) supported rotation and scaling (and also restricted you to a single layer). You couldn't really combine the modes. –  Michael Madsen May 8 '12 at 15:30

1 Answer 1

Mode 7 is a very simple effect. It projects a 2D x/y texture (or tiles) to some floor/ceiling. Old SNES use hardware to do this, but modern computers are so powerful that you can do this realtime (and no need of ASM as you mention).

Basic 3D math formula to project a 3D point (x, y, z) to a 2D point (x, y) is :

x' = x / z;
y' = y / z; 

When you think about it, it makes sense. Objects that are far in distance are smaller than objects near you. Think about railroad tracks going to nowhere :

enter image description here

If we look back at the formula input values : x and y will be the current pixel we are processing, and z will be distance information about how far the point is. To understand what z should be, look at that picture, it shows z values for image above :

enter image description here

purple = near distance, red = far away

So in this example, z value is y - horizon (assuming (x:0, y:0) is at the center of screen)

If we put everything together, it becomes : (pseudocode)

for (y = -yres/2 ; y < yres/2 ; y++)
  for (x = -xres/2 ; x < xres/2 ; x++)
  {
     horizon = -20; //adjust if needed
     fov = 200; 

     px = x;
     py = y - horizon - fov; 
     pz = y - horizon;      

     //projection 
     sx = px / pz;
     sy = py / pz; 

     scaling = 100; //adjust if needed, depends of texture size
     color = get2DTexture(sx * scaling, sy * scaling);  

     //put (color) at (x, y) on screen
     ...
  }

One last thing : if you want to make a mario kart game, I suppose you also want to rotate the map. Well its also very easy : rotate sx and sy before getting texture value. Here is formula :

  x' = x * cos(angle) - y * sin(angle);
  y' = x * sin(angle) + y * cos(angle);

and if you want to move trough the map, just add some offset before getting texture value :

  get2DTexture(sx * scaling + xOffset, sy * scaling + yOffset);

NOTE : i tested the algorithm (almost copy-paste) and it works. Here is a screen (you should recognize the texture :))

enter image description here

NOTE2 : i use simple math because you said you want something simple (and dont seems familiar with vector math). You can achieve same things using wikipedia formula or tutorials you give. The way they did it is much more complex but you have much more possibilities for configuring the effect (in the end it works the same...).

For more information, i suggest reading : http://en.wikipedia.org/wiki/3D_projection#Perspective_projection

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.