Source Code Makeover: Square Shooter, Part 1

One final thing about converting magic numbers to constants. Note that on line 560 and 561, you see the float values 480.0 instead of the integer values 480. This is because in Python 2, dividing two integer values does integer division (e.g. 22 / 7 is 3), which is too imprecise for what we want. This is why Felix used floats, which will force the / operator to do float division (e.g. 22 / 7.0 is 3.142857142857143). One of the improvements of Python 3 was to always make the / do float division.

But if we put MAP_WIDTH and MAP_HEIGHT on these lines, the integer in these constants will cause this to do integer division and cause a weird bug where the ship can only thrust and shoot towards the top left corner of the map. So we wrap them in float() calls to convert them to float values, which ensures that the / operator does float division.

model.shoot_at(x / float(MAP_WIDTH), y / float(MAP_HEIGHT))

model.thrust_at(x / float(MAP_WIDTH), y / float(MAP_HEIGHT))

Also, there are a few places where the magic number 500 is used that I will replace with MAP_WIDTH + 20. At this point, we should be able to modify the MAP_WIDTH, MAP_HEIGHT, WINDOW_WIDTH, and WINDOW_HEIGHT variables and the rest of the program scales automatically. (Though the font sizes are based on the window height, so they make look a bit awkward. We can deal with that later.)

I’m going to commit my changes now to git source control with the log message, “Replaced the magic numbers for the map and window dimensions with constant variables.”

Improve scale_and_round()

(These changes can be seen in the github history.)

The scale_and_round() function can be improved again. First, we’ll add a comment saying what it does. Then we can shorten it into a return statement one-liner. (The one liner is just my own preference.)

def scale_and_round(x, y):

"""Returns x and y coordinates from 0.0 to 1.0 scaled to 0 to MAP_WIDTH or MAP_HEIGHT."""

return int(round(x * MAP_WIDTH)), int(round(y * MAP_HEIGHT))

Also, at this time I’m going to go ahead and convert all the tabs to 4 spaces with my editor’s Find-and-Replace. (See github.) And then I will make some other magic number replacements also. (See github.)

Add comments to the Bubble2D class

(These changes can be seen in the github history.)

The Vector2D class looks good, and is straightforward enough that it doesn’t need comments. I’ll be lazy and skip them.

The Bubble2D class is used for every object in this game: asteroids, the player’s ship, bullets, powerups, and explosions. Maybe “bubble” isn’t the best name to use. Anyway, this fact should be made more apparent in the comments. The methods also need commenting.

class Bubble2D:

"""Represents a circular object on the game map with position, radius, and velocity."""

I’ll check in these changes with the log message, “Added some comments for the Bubble2D class’s methods.”

Rename position to pos

(These changes can be seen in the github history.)

The Bubble2D class’s position member can be shortened to pos. The word “pos” is generally accepted as a short form of “position” (or, less often, “positive”). You can see in the wrap_around() and is_out() methods that Felix creates a shorter-named pos variable to stand in the place of self.position. Let’s cut this middle man out.

def __init__(self, radius):

self.pos = Vector2D(0, 0)

Page 3 of 8 | Previous page | Next page