Crazy Pong design using Python 3 Game Description: Ball bounces off the top, bot
ID: 3858961 • Letter: C
Question
Crazy Pong design using Python 3
Game Description: Ball bounces off the top, bottom and right edge of the screen … and the paddle. A new ball is added each time the paddle hits another ball. Each ball is randomly positioned inside the buffer zone of the screen and is given random speed between a minimum and maximum value. If the ball gets by the paddle the game is over.
Game Design: Fill in the blanks.
class Ball(games.Sprite):
"""
A bouncing ball.
"""
image - image object for ball
MIN_SPEED – integer for minimum speed
MAX_SPEED – integer for maximum speed
BUFFER – integer for distance from screen boundaries when created
def __init__(self):
""" Initialize Ball object. """
def update(self):
""" Deal with beyond left edge, or hitting top or bottom. """
def bounce(self, paddle_right):
""" Bounce off paddle. """
def end_game(self):
""" End the game. """
class Paddle(games.Sprite):
"""
A paddle controlled by mouse that balls can bounce off.
"""
image – image object for paddle
def __init__(self):
""" Initialize Paddle object. """
def update(self):
""" Move to mouse y-position. """
def check_hit(self):
""" Check for balls hitting paddle. """
def main():
""" Play the game. """
load and set background image
create paddle sprite and add to screen
create first ball sprite and add to screen
set mouse pointer to invisible
grab all input to game screen
start game loop
Explanation / Answer
Answer:
import random
import play, sys
from play.locals import *
play.init()
fps = play.time.Clock()
#colors
WHITE = (255,255,255)
RED = (255,0,0)
GREEN = (0,255,0)
BLACK = (0,0,0)
#globals
WIDTH = 600
HEIGHT = 400
BALL_RADIUS = 20
PAD_WIDTH = 8
PAD_HEIGHT = 80
HALF_PAD_WIDTH = PAD_WIDTH / 2
HALF_PAD_HEIGHT = PAD_HEIGHT / 2
value = [0,0]
read = [0,0]
input1_vel = 0
input2_vel = 0
l_score = 0
r_score = 0
#canvas declaration
window = play.display.set_mode((WIDTH, HEIGHT), 0, 32)
play.display.set_caption('Hello World')
# helper function that spawns a ball, returns a position vector and a velocity vector
# if right is True, spawn to the right, else spawn to the left
def ball_init(right):
global value, read # these are vectors stored as lists
value = [WIDTH/2,HEIGHT/2]
horz = random.randrange(2,4)
vert = random.randrange(1,3)
if right == False:
horz = - horz
read = [horz,-vert]
# define event handlers
def init():
global input1_pos, input2_pos, input1_vel, input2_vel,l_score,r_score # these are floats
global score1, score2 # these are ints
input1_pos = [HALF_PAD_WIDTH - 1,HEIGHT/2]
input2_pos = [WIDTH +1 - HALF_PAD_WIDTH,HEIGHT/2]
l_score = 0
r_score = 0
if random.randrange(0,2) == 0:
ball_init(True)
else:
ball_init(False)
#draw function of canvas
def draw(canvas):
global input1_pos, input2_pos, value, read, l_score, r_score
canvas.fill(BLACK)
play.draw.line(canvas, WHITE, [WIDTH / 2, 0],[WIDTH / 2, HEIGHT], 1)
play.draw.line(canvas, WHITE, [PAD_WIDTH, 0],[PAD_WIDTH, HEIGHT], 1)
play.draw.line(canvas, WHITE, [WIDTH - PAD_WIDTH, 0],[WIDTH - PAD_WIDTH, HEIGHT], 1)
play.draw.circle(canvas, WHITE, [WIDTH//2, HEIGHT//2], 70, 1)
# update input's vertical position, keep input on the screen
if input1_pos[1] > HALF_PAD_HEIGHT and input1_pos[1] < HEIGHT - HALF_PAD_HEIGHT:
input1_pos[1] += input1_vel
elif input1_pos[1] == HALF_PAD_HEIGHT and input1_vel > 0:
input1_pos[1] += input1_vel
elif input1_pos[1] == HEIGHT - HALF_PAD_HEIGHT and input1_vel < 0:
input1_pos[1] += input1_vel
if input2_pos[1] > HALF_PAD_HEIGHT and input2_pos[1] < HEIGHT - HALF_PAD_HEIGHT:
input2_pos[1] += input2_vel
elif input2_pos[1] == HALF_PAD_HEIGHT and input2_vel > 0:
input2_pos[1] += input2_vel
elif input2_pos[1] == HEIGHT - HALF_PAD_HEIGHT and input2_vel < 0:
input2_pos[1] += input2_vel
#update ball
value[0] += int(read[0])
value[1] += int(read[1])
#draw inputs and ball
play.draw.circle(canvas, RED, value, 20, 0)
play.draw.polygon(canvas, GREEN, [[input1_pos[0] - HALF_PAD_WIDTH, input1_pos[1] - HALF_PAD_HEIGHT], [input1_pos[0] - HALF_PAD_WIDTH, input1_pos[1] + HALF_PAD_HEIGHT], [input1_pos[0] + HALF_PAD_WIDTH, input1_pos[1] + HALF_PAD_HEIGHT], [input1_pos[0] + HALF_PAD_WIDTH, input1_pos[1] - HALF_PAD_HEIGHT]], 0)
play.draw.polygon(canvas, GREEN, [[input2_pos[0] - HALF_PAD_WIDTH, input2_pos[1] - HALF_PAD_HEIGHT], [input2_pos[0] - HALF_PAD_WIDTH, input2_pos[1] + HALF_PAD_HEIGHT], [input2_pos[0] + HALF_PAD_WIDTH, input2_pos[1] + HALF_PAD_HEIGHT], [input2_pos[0] + HALF_PAD_WIDTH, input2_pos[1] - HALF_PAD_HEIGHT]], 0)
#ball collision check on top and bottom walls
if int(value[1]) <= BALL_RADIUS:
read[1] = - read[1]
if int(value[1]) >= HEIGHT + 1 - BALL_RADIUS:
read[1] = -read[1]
#ball collison check on gutters or inputs
if int(value[0]) <= BALL_RADIUS + PAD_WIDTH and int(value[1]) in range(input1_pos[1] - HALF_PAD_HEIGHT,input1_pos[1] + HALF_PAD_HEIGHT,1):
read[0] = -read[0]
read[0] *= 1.1
read[1] *= 1.1
elif int(value[0]) <= BALL_RADIUS + PAD_WIDTH:
r_score += 1
ball_init(True)
if int(value[0]) >= WIDTH + 1 - BALL_RADIUS - PAD_WIDTH and int(value[1]) in range(input2_pos[1] - HALF_PAD_HEIGHT,input2_pos[1] + HALF_PAD_HEIGHT,1):
read[0] = -read[0]
read[0] *= 1.1
read[1] *= 1.1
elif int(value[0]) >= WIDTH + 1 - BALL_RADIUS - PAD_WIDTH:
l_score += 1
ball_init(False)
#update scores
myfont1 = play.font.SysFont("Comic Sans MS", 20)
label1 = myfont1.render("Score "+str(l_score), 1, (255,255,0))
canvas.blit(label1, (50,20))
myfont2 = play.font.SysFont("Comic Sans MS", 20)
label2 = myfont2.render("Score "+str(r_score), 1, (255,255,0))
canvas.blit(label2, (470, 20))
#keydown handler
def keydown(event):
global input1_vel, input2_vel
if event.key == K_UP:
input2_vel = -8
elif event.key == K_DOWN:
input2_vel = 8
elif event.key == K_w:
input1_vel = -8
elif event.key == K_s:
input1_vel = 8
#keyup handler
def keyup(event):
global input1_vel, input2_vel
if event.key in (K_w, K_s):
input1_vel = 0
elif event.key in (K_UP, K_DOWN):
input2_vel = 0
init()
#game loop
while True:
draw(window)
for event in play.event.get():
if event.type == KEYDOWN:
keydown(event)
elif event.type == KEYUP:
keyup(event)
elif event.type == QUIT:
play.quit()
sys.exit()
play.display.update()
fps.tick(60)