Python 3 - Game of Pong Advanced
11 - Score Multiplier and Bonus Points
Introduction
In this assignment, we'll introduce a score multiplier feature. If a player hits the ball multiple times without missing, their score will increase faster. This concept is similar to a combo multiplier in many games, encouraging players to keep the ball in play to maximize their score.
Task
-
Multiplier Logic:
- Create a multiplier variable starting at 1.
- Every time the ball hits the paddle without the player missing, increase the multiplier by 0.5 (up to a maximum of 3x).
- When the player misses, reset the multiplier to 1.
-
Update Score Function:
- Modify the
update_score()
function to display the current multiplier alongside the score.
- Modify the
Example Code Snippet:
# Initialize the multiplier
multiplier = 1.0
# Update the score function to include the multiplier
def update_score():
pen.clear()
pen.write(f"Score: {score} Levens: {lives} Multiplier: {multiplier}x", align="center", font=("Courier", 24, "normal"))
# Update multiplier in the game loop
if hit_paddle:
multiplier = min(multiplier + 0.5, 3)
score += int(1 * multiplier)
else:
multiplier = 1
Deliverable
A screenshot showing the score, lives, and current multiplier on the screen.
12 - OOP with Turtle
Introduction
To enhance your Python skills, we'll refactor our Pong game using Object-Oriented Programming (OOP). This will help in managing complex codebases and introduce new concepts like classes, objects, methods, and encapsulation.
Task
-
Create a Paddle Class:
- Convert the existing paddle code into a
Paddle
class with attributes for position and size. - Include methods for moving up and down and initializing the paddle.
- Convert the existing paddle code into a
-
Create a Ball Class:
- Convert the ball code into a
Ball
class with attributes for position and velocity. - Include methods to move the ball and check for collisions.
- Convert the ball code into a
Example Code Snippet:
class Paddle:
def __init__(self, x, y):
self.paddle = turtle.Turtle()
self.paddle.shape("square")
self.paddle.color("white")
self.paddle.shapesize(stretch_wid=6, stretch_len=1)
self.paddle.penup()
self.paddle.goto(x, y)
def move_up(self):
y = self.paddle.ycor()
if y < 250:
y += 20
self.paddle.sety(y)
def move_down(self):
y = self.paddle.ycor()
if y > -240:
y -= 20
self.paddle.sety(y)
# Similar refactoring would be done for the Ball class
Deliverable
A .py
file containing the refactored code using classes.
13 - Handling Game State and Pausing
Introduction
Managing game state is crucial in game development. In this assignment, you'll implement a pause functionality, allowing players to pause and resume the game.
Task
-
Game State Variable:
- Introduce a
game_state
variable that can be either "playing" or "paused".
- Introduce a
-
Pause and Resume Functions:
- Create functions to pause and resume the game. When paused, the game loop should not update the ball or paddle positions.
- Bind a keyboard key (e.g., "p") to toggle between "playing" and "paused".
Example Code Snippet:
game_state = "playing"
def toggle_pause():
global game_state
if game_state == "playing":
game_state = "paused"
else:
game_state = "playing"
wn.listen()
wn.onkeypress(toggle_pause, "p")
while True:
if game_state == "playing":
# Game logic updates
wn.update()
else:
# Game is paused; do not update game logic
pass
Deliverable
A .py
file with the pause functionality implemented. Include a comment explaining how the pause feature is beneficial in games.
14 - Power-Ups and Advanced Features
Introduction
Adding power-ups can make games more engaging. In this assignment, you'll introduce a new feature: power-ups that appear randomly and affect the game when collected.
Task
-
Power-Up Implementation:
- Create a new turtle object representing a power-up. Randomly place it on the screen every 20 seconds.
- If the ball hits the power-up, apply a random effect such as increasing the paddle size, slowing down the ball, or adding an extra life.
-
Effect Duration:
- Ensure that power-up effects last only for a certain period (e.g., 10 seconds), after which the game returns to normal.
Example Code Snippet
import random
def spawn_power_up():
power_up = turtle.Turtle()
power_up.shape("circle")
power_up.color("blue")
power_up.penup()
x = random.randint(-350, 350)
y = random.randint(-250, 250)
power_up.goto(x, y)
return power_up
def apply_power_up(effect):
global paddle, ball
if effect == "increase_paddle":
paddle.shapesize(stretch_wid=8)
# Reset after 10 seconds
wn.ontimer(lambda: paddle.shapesize(stretch_wid=6), 10000)
elif effect == "slow_ball":
ball.dx *= 0.5
ball.dy *= 0.5
wn.ontimer(lambda: reset_ball_speed(), 10000)
# Example effect application in the game loop
if ball.distance(power_up) < 20:
apply_power_up(random.choice(["increase_paddle", "slow_ball"]))
Deliverable
A .py
file with the power-up feature implemented. Include comments explaining each power-up and its impact on the game.
15 - Collision Detection and Physics
Introduction
Improving collision detection can make a game feel more realistic. In this assignment, we'll refine the collision detection to account for the ball's velocity and angle, providing a more physics-based gameplay experience.
Task
-
Advanced Collision Detection:
- Adjust the ball’s direction based on where it hits the paddle (top, middle, or bottom). If it hits the top, it should bounce off at a sharper angle; if it hits the middle, it should bounce back more vertically.
-
Implement Angled Bounces:
- Modify the game so that when the ball hits the paddle near its edges, it alters its
dx
anddy
to create an angled bounce.
- Modify the game so that when the ball hits the paddle near its edges, it alters its
Example Code Snippet
def check_collision():
global ball, paddle
if ball.distance(paddle) < 50 and ball.xcor() < -340:
# Calculate where the ball hit the paddle
hit_pos = ball.ycor() - paddle.ycor()
ball.dy = hit_pos * 0.05
ball.dx *= -1
Deliverable
A .py
file with advanced collision detection and physics implemented. Include a brief explanation of how physics enhances gameplay realism.