Playthrough Videos
Playthrough videos now available at:Part 1 of 3: https://youtu.be/MzEqs0aj1y8
Part 2 of 3: https://youtu.be/bz7x3VbqBMc
Part 3 of 3: https://youtu.be/neNqHciPZXI
Alternate Ending: https://youtu.be/xagWlKJZlB0
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)
Comments
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 "get_pip.py":
http://stackoverflow.com/questions/4750806/how-do-i-install-pip-on-windows
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 "visuals.py" and change line 130 in "model.py" from:
"if self.motiondust.depth1[i] > 0.0 and self.motiondust.depth2[i] > 0.0 and self.motiondust.range1[i] < (self.motiondust.gridsize/2):"
to:
"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.
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 "pygame.draw.circle" 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 :).
xmzhang1 on 2017/02/27 06:51:
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\model.py", line 29
self.x = camera.f*np.dot(self.vertex_c,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\model.py", line 30
self.y = camera.f*np.dot(self.vertex_c,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\run_game.py", line 12, in <module>
main.main(mainpath)
File "C:\Users\Administrator\Desktop\enemys_enemy_pyweek23\enemys_enemy_pyweek23\src\main.py", line 74, in main
dir.loop()
File "C:\Users\Administrator\Desktop\enemys_enemy_pyweek23\enemys_enemy_pyweek23\src\gamedirector.py", line 47, in loop
self.scene.on_update()
File "C:\Users\Administrator\Desktop\enemys_enemy_pyweek23\enemys_enemy_pyweek23\src\game.py", line 303, in on_update
self.motiondust.Update()
File "C:\Users\Administrator\Desktop\enemys_enemy_pyweek23\enemys_enemy_pyweek23\src\visuals.py", line 48, in Update
self.range1 = np.linalg.norm(self.vertex_c,axis=1)
TypeError: norm() got an unexpected keyword argument 'axis'