Playthrough Videos

Playthrough videos now available at:

Part 1 of 3:

Part 2 of 3:

Part 3 of 3:

Alternate Ending:

Unfortunately my laptop hates running pygame and recording video from the screen at the same time, so the framerate of the game is reduced to half of what it would normally be :( ... hence sorry about the videos being a bit long. Hope you enjoy!

(log in to comment)


Hi! mit-mit, I saw your video, 3D effect is great, but I run the code came error, I run it on Windows, after the dialogue´╝îthere is no responding black screen and the messages are as follows. How to fix it?

Warning (from warnings module):

  File "C:\Users\Administrator\Desktop\enemys_enemy_pyweek23\enemys_enemy_pyweek23\src\", line 29

    self.x = camera.f*,camera.DCM[1])/self.depth + camera.uv0[0]

RuntimeWarning: divide by zero encountered in divide

Warning (from warnings module):

  File "C:\Users\Administrator\Desktop\enemys_enemy_pyweek23\enemys_enemy_pyweek23\src\", line 30

    self.y = camera.f*,camera.DCM[2])/self.depth + camera.uv0[1]

RuntimeWarning: divide by zero encountered in divide

Traceback (most recent call last):

  File "C:\Users\Administrator\Desktop\enemys_enemy_pyweek23\enemys_enemy_pyweek23\", line 12, in <module>


  File "C:\Users\Administrator\Desktop\enemys_enemy_pyweek23\enemys_enemy_pyweek23\src\", line 74, in main


  File "C:\Users\Administrator\Desktop\enemys_enemy_pyweek23\enemys_enemy_pyweek23\src\", line 47, in loop


  File "C:\Users\Administrator\Desktop\enemys_enemy_pyweek23\enemys_enemy_pyweek23\src\", line 303, in on_update


  File "C:\Users\Administrator\Desktop\enemys_enemy_pyweek23\enemys_enemy_pyweek23\src\", line 48, in Update

    self.range1 = np.linalg.norm(self.vertex_c,axis=1)

TypeError: norm() got an unexpected keyword argument 'axis'

Hi xmzhang1 ... Thanks for the headsup! I believe this is a numpy version issue. The game requires numpy 1.8.0 or above. 

I had a quick look through the numpy docs and it looks like the "axis" keyword argument does not exist in np.linalg.norm in numpy 1.7 and below. To see what version of numpy you have installed, open python "import numpy" and then "print numpy.__version__". You need 1.8.0 or above.

Are you using windows 7? If you have pip installed, you can just do "pip install --upgrade numpy". If you don't have pip installed, see here for windows instructions using "":

Apologies for not being compatible with old versions of numpy: I needed that features in "np.linalg.norm" to run the rendering of the "motion dust" (little bits of grit that give you a sense of which way you are travelling).

If you really can't upgrade numpy for some reason, there is a very small change in the code you could apply: comment out line 48 in "" and change line 130 in "" from:

"if self.motiondust.depth1[i] > 0.0 and self.motiondust.depth2[i] > 0.0 and self.motiondust.range1[i] < (self.motiondust.gridsize/2):"


"if self.motiondust.depth1[i] > 0.0 and self.motiondust.depth2[i] > 0.0 and self.motiondust.depth1[i] < (self.motiondust.gridsize/2):"

This will remove the dependance on this, with a slight change in the quality of this visual effect, but otherwise does not change the gameplay. I'm pretty sure you wouldn't run into any more troubles because of lower version numpys after this, but can't guarantee.

Good luck! Please let me know how you go.

yeah, follow your instructions, I get it run, by the way, how do you do the the 3d effect. I check your, it seemed that you do not set the display mode to OPENGL, do you project the 3d model into 2d surface? if that, how do you do the light, render etc. I am really suprised that you can do it without opengl, are these transition matrix complicated? All in all, great works!
Good to hear it works :).

Yes, I am projecting the 3D model to a 2D view (using a lot of numpy) and rendering it to a standard 2D pygame surface (no opengl). 

Rendering per-polygon (triangles) is achieved using pygame's "pygame.draw.polygon" function, and everything is flat shaded, so the pixel colour within any given polygon is constant. The colour is calculated based on natural object colour/albedo (built into the model faces) and two lights, a fixed ambient "glow" and a directional light (from the sun) using a Lambertian reflection model, the calculations of which are performed using numpy. I found from performance testing on my laptop I could render approximately 300 triangles at 30 fps and 500 triangles at about 20-25 fps and this is enough for the coarse 3D models used in the game.

I also implemented separate 3D effects for points/particles (projectiles and stars), using "" with radius calculated based on camera depth, and effects for a 3D texture mapped background (the milky way sort of galaxy looking thing) using a per-scanline texture mapping that uses pygame surfarrays to pull the surfaces into numpy arrays. I didn't get this feature to work all that well (some distortion around the edges of the field of view), but it suffices.

If I made a 3D game like this again, I would definitely use opengl/hardware 3D rendering instead of this approach, because of the work required to get it going and poor computational performance. I kind of got stuck on the idea of doing it this way early in the process, as a bit of an experiment :).