Many of the games in the book are very simplified versions of classic computer games. LunarLander is an example of that. The original Lunar Lander arcade game was a “vector-graphics” game, where you have to land a lunar module on the moon. There is rocky lunar terrain with a few safe landing spots. You control the rotation and thrust of the lander to make a safe landing. Here’s a screen shot:
The LunarLander in “Hello World!” only moves vertically, not sideways. This was done to show a gravity simulation while keeping the code as simple as possible. After all, the point of the games in the book is to learn, not to make an accurate copy of an old arcade game. We encourage readers to take the games in the book as starting points and extend them in whatever way they like.
I thought it would be fun to take the first step in that direction with LunarLander. So, I made LunarLander2D. This turns LunarLander from a 1-D simulation (vertical only) to a 2-D simulation (vertical and horizontal), more like the arcade version.
To do that, there are two major things that needed to change:
- Need to keep track of both vertical and horizontal speed
- Need a way to rotate the lander, so you can thrust in different directions to steer
Of course, once you start doing rotation and applying thrust at different angles, you need some trigonometry to do the calculations. That’s the main reason we didn’t make LunarLander a 2-D simulation in the first place. We didn’t want to make trigonometry a requirement for the book.
I had to dust the cobwebs off my knowledge of trig. I found the trickiest part was figuring out how to draw the rocket flames at an angle when the lander is rotated. The code to do that is written in an “expanded” form. That is, the code could be made much more compact, but I’m trying to show step-by-step how I’m doing the calculation.
Here are the main differences from LunarLander to LunarLander2:
- The window is wider, to make room for the sideways motion.
- The lander is now a sprite, which makes it easier to do the rotation (using pygame.transform.rotate)
- The thrust is controlled by pressing/holding the spacebar instead of using the mouse to drag a slider (There are no longer any mouse events.)
- The rotation is controlled by the left and right arrow keys
- A good landing now depends on both speed and angle
The code is shown below, and you can easily cut-and-paste it into your favourite Python editor to try it out. (I use SPE.) Don’t forget to put a copy of the image file (lunarlander.png) in the same folder as the code when you try to run it.
Here's a screenshot:
This is still a very simplified version. Here are some ways it could be enhanced:
- Add some animation or different sprites when the lander lands roughly or crashes
- Add different messages depending on how the landing was
- Add more terrain and multiple landing spots
- Have multiple turns, where it gets more difficult each time (steeper terrain, smaller landing spots, less fuel, etc.)