A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://inventwithpython.com/bigbookpython/project5.html below:

Bouncing DVD Logo

#5
Bouncing DVD Logo

If you are of a certain age, you’ll remember those ancient technological devices called DVD players. When not playing DVDs, they would display a diagonally traveling DVD logo that bounced off the edges of the screen. This program simulates this colorful DVD logo by making it change direction each time it hits an edge. We’ll also keep track of how many times a logo hits a corner of the screen. This creates an interesting visual animation to look at, especially for the magical moment when a logo lines up perfectly with a corner.

You can’t run this program from your integrated development environment (IDE) or editor because it uses the bext module. Therefore, it must be run from the Command Prompt or Terminal in order to display correctly. You can find more information about the bext module at https://pypi.org/project/bext/.

The Program in Action

When you run bouncingdvd.py, the output will look like Figure 5-1.

Figure 5-1: The diagonally moving DVD logos of the bouncingdvd.py program

How It Works

You may remember Cartesian coordinates from your math class in school. In programming, the x-coordinate represents an object’s horizontal position and the y-coordinate represents its vertical position, just like in mathematics. However, unlike in mathematics, the origin point (0, 0) is in the upper-left corner of the screen, and the y-coordinate increases as you go down. The x-coordinate increases as the object moves right, just like in mathematics. Figure 5-2 shows the coordinate system for your screen.

Figure 5-2: The origin point (0, 0) is in the upper left of the screen, while the x- and y-coordinates increase going right and down, respectively.

The bext module’s goto() function works the same way: calling bext.goto(0, 0) places the text cursor at the top left of the terminal window. We represent each bouncing DVD logo using a Python dictionary with the keys 'color', 'direction', 'x', and 'y'. The values for the 'x' and 'y' are integers representing the logo’s position in the window. Since these values get passed to bext.goto(), increasing them will move the logo right and down, while decreasing them will move the logo left and up.

  1. """Bouncing DVD Logo, by Al Sweigart [email protected]
  2. A bouncing DVD logo animation. You have to be "of a certain age" to
  3. appreciate this. Press Ctrl-C to stop.
  4.
  5. NOTE: Do not resize the terminal window while this program is running.
  6. View this code at https://nostarch.com/big-book-small-python-projects
  7. Tags: short, artistic, bext"""
  8.
  9. import sys, random, time
 10.
 11. try:
 12.     import bext
 13. except ImportError:
 14.     print('This program requires the bext module, which you')
 15.     print('can install by following the instructions at')
 16.     print('https://pypi.org/project/Bext/')
 17.     sys.exit()
 18.
 19. # Set up the constants:
 20. WIDTH, HEIGHT = bext.size()
 21. # We can't print to the last column on Windows without it adding a
 22. # newline automatically, so reduce the width by one:
 23. WIDTH -= 1
 24.
 25. NUMBER_OF_LOGOS = 5  # (!) Try changing this to 1 or 100.
 26. PAUSE_AMOUNT = 0.2  # (!) Try changing this to 1.0 or 0.0.
 27. # (!) Try changing this list to fewer colors:
 28. COLORS = ['red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white']
 29.
 30. UP_RIGHT   = 'ur'
 31. UP_LEFT    = 'ul'
 32. DOWN_RIGHT = 'dr'
 33. DOWN_LEFT  = 'dl'
 34. DIRECTIONS = (UP_RIGHT, UP_LEFT, DOWN_RIGHT, DOWN_LEFT)
 35.
 36. # Key names for logo dictionaries:
 37. COLOR = 'color'
 38. X = 'x'
 39. Y = 'y'
 40. DIR = 'direction'
 41.
 42.
 43. def main():
 44.     bext.clear()
 45.
 46.     # Generate some logos.
 47.     logos = []
 48.     for i in range(NUMBER_OF_LOGOS):
 49.         logos.append({COLOR: random.choice(COLORS),
 50.                       X: random.randint(1, WIDTH - 4),
 51.                       Y: random.randint(1, HEIGHT - 4),
 52.                       DIR: random.choice(DIRECTIONS)})
 53.         if logos[-1][X] % 2 == 1:
 54.             # Make sure X is even so it can hit the corner.
 55.             logos[-1][X] -= 1
 56.
 57.     cornerBounces = 0  # Count how many times a logo hits a corner.
 58.     while True:  # Main program loop.
 59.         for logo in logos:  # Handle each logo in the logos list.
 60.             # Erase the logo's current location:
 61.             bext.goto(logo[X], logo[Y])
 62.             print('   ', end='')  # (!) Try commenting this line out.
 63.
 64.             originalDirection = logo[DIR]
 65.
 66.             # See if the logo bounces off the corners:
 67.             if logo[X] == 0 and logo[Y] == 0:
 68.                 logo[DIR] = DOWN_RIGHT
 69.                 cornerBounces += 1
 70.             elif logo[X] == 0 and logo[Y] == HEIGHT - 1:
 71.                 logo[DIR] = UP_RIGHT
 72.                 cornerBounces += 1
 73.             elif logo[X] == WIDTH - 3 and logo[Y] == 0:
 74.                 logo[DIR] = DOWN_LEFT
 75.                 cornerBounces += 1
 76.             elif logo[X] == WIDTH - 3 and logo[Y] == HEIGHT - 1:
 77.                 logo[DIR] = UP_LEFT
 78.                 cornerBounces += 1
 79.
 80.             # See if the logo bounces off the left edge:
 81.             elif logo[X] == 0 and logo[DIR] == UP_LEFT:
 82.                 logo[DIR] = UP_RIGHT
 83.             elif logo[X] == 0 and logo[DIR] == DOWN_LEFT:
 84.                 logo[DIR] = DOWN_RIGHT
 85.
 86.             # See if the logo bounces off the right edge:
 87.             # (WIDTH - 3 because 'DVD' has 3 letters.)
 88.             elif logo[X] == WIDTH - 3 and logo[DIR] == UP_RIGHT:
 89.                 logo[DIR] = UP_LEFT
 90.             elif logo[X] == WIDTH - 3 and logo[DIR] == DOWN_RIGHT:
 91.                 logo[DIR] = DOWN_LEFT
 92.
 93.             # See if the logo bounces off the top edge:
 94.             elif logo[Y] == 0 and logo[DIR] == UP_LEFT:
 95.                 logo[DIR] = DOWN_LEFT
 96.             elif logo[Y] == 0 and logo[DIR] == UP_RIGHT:
 97.                 logo[DIR] = DOWN_RIGHT
 98.
 99.             # See if the logo bounces off the bottom edge:
100.             elif logo[Y] == HEIGHT - 1 and logo[DIR] == DOWN_LEFT:
101.                 logo[DIR] = UP_LEFT
102.             elif logo[Y] == HEIGHT - 1 and logo[DIR] == DOWN_RIGHT:
103.                 logo[DIR] = UP_RIGHT
104.
105.             if logo[DIR] != originalDirection:
106.                 # Change color when the logo bounces:
107.                 logo[COLOR] = random.choice(COLORS)
108.
109.             # Move the logo. (X moves by 2 because the terminal
110.             # characters are twice as tall as they are wide.)
111.             if logo[DIR] == UP_RIGHT:
112.                 logo[X] += 2
113.                 logo[Y] -= 1
114.             elif logo[DIR] == UP_LEFT:
115.                 logo[X] -= 2
116.                 logo[Y] -= 1
117.             elif logo[DIR] == DOWN_RIGHT:
118.                 logo[X] += 2
119.                 logo[Y] += 1
120.             elif logo[DIR] == DOWN_LEFT:
121.                 logo[X] -= 2
122.                 logo[Y] += 1
123.
124.         # Display number of corner bounces:
125.         bext.goto(5, 0)
126.         bext.fg('white')
127.         print('Corner bounces:', cornerBounces, end='')
128.
129.         for logo in logos:
130.             # Draw the logos at their new location:
131.             bext.goto(logo[X], logo[Y])
132.             bext.fg(logo[COLOR])
133.             print('DVD', end='')
134.
135.         bext.goto(0, 0)
136.
137.         sys.stdout.flush()  # (Required for bext-using programs.)
138.         time.sleep(PAUSE_AMOUNT)
139.
140.
141. # If this program was run (instead of imported), run the game:
142. if __name__ == '__main__':
143.     try:
144.         main()
145.     except KeyboardInterrupt:
146.         print()
147.         print('Bouncing DVD Logo, by Al Sweigart')
148.         sys.exit()  # When Ctrl-C is pressed, end the program.

After entering the source code and running it a few times, try making experimental changes to it. The comments marked with (!) have suggestions for small changes you can make. On your own, you can also try to figure out how to do the following:

Exploring the Program

Try to find the answers to the following questions. Experiment with some modifications to the code and rerun the program to see what effect the changes have.

  1. What happens if you change WIDTH, HEIGHT = bext.size() on line 20 to WIDTH, HEIGHT = 10, 5?
  2. What happens if you replace DIR: random.choice(DIRECTIONS) on line 52 with DIR: DOWN_RIGHT?
  3. How can you make the 'Corner bounces:' text not appear on the screen?
  4. What error message do you get if you delete or comment out cornerBounces = 0 on line 57?

RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4