Created
October 26, 2019 10:45
-
-
Save MM-coder/2ce58493ac83f9d62079e2f5e9b37f6c to your computer and use it in GitHub Desktop.
Pythonic implementation of classic arcade game Pong
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Interactive @ http://www.codeskulptor.org/#user46_IEOQH6HNJcnPhI2_1.py | |
# Implementation of classic arcade game Pong | |
import simplegui | |
import random | |
# initialize globals - pos and vel encode vertical info for paddles | |
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 | |
init_pos = [WIDTH / 2, HEIGHT / 2] | |
ball_vel = [0, 3] # pixels per tick | |
time = 0 | |
paddle1_pos = HEIGHT/2 | |
paddle2_pos = HEIGHT/2 | |
paddle1_vel = 0 | |
paddle2_vel = 0 | |
score1 = 0 | |
score2 = 0 | |
def tick(): | |
global time | |
time = time + 1 | |
# initialize ball_pos and ball_vel for new bal in middle of table | |
# if direction is RIGHT, the ball's velocity is upper right, else upper left | |
def spawn_ball(direction): | |
global ball_pos, ball_vel # these are vectors stored as lists | |
ball_pos = [WIDTH/2,HEIGHT/2] | |
ball_vel[1] = -random.randrange(60, 180)/60 | |
if direction == 'right': | |
ball_vel[0] = random.randrange(120, 240)/60 # positive | |
else: | |
ball_vel[0] = -random.randrange(120, 240)/60 # make negative | |
pass | |
# define event handlers | |
def new_game(): | |
global paddle1_pos, paddle2_pos, paddle1_vel, paddle2_vel # these are numbers | |
global score1, score2 # these are ints | |
spawn_two = random.randint(0, 100) | |
if spawn_two <= 50: | |
spawn_ball(random.choice(['left', 'right'])) | |
spawn_ball(random.choice(['left', 'right'])) | |
else: | |
spawn_ball(random.choice(['left', 'right'])) | |
paddle1_pos = HEIGHT/2 | |
paddle2_pos = HEIGHT/2 | |
paddle1_vel = 0 | |
paddle2_vel = 0 | |
score1 = 0 | |
score2 = 0 | |
pass | |
def draw(canvas): | |
global score1, score2, paddle1_vel, paddle2_vel, paddle1_pos, paddle2_pos, ball_pos, ball_vel | |
# update paddle's vertical position, keep paddle on the screen | |
if paddle1_pos < (HALF_PAD_HEIGHT) and paddle1_vel < 0: | |
paddle1_vel = 0 | |
if paddle2_pos < (HALF_PAD_HEIGHT) and paddle2_vel < 0: | |
paddle2_vel = 0 | |
if paddle1_pos > (HEIGHT - (HALF_PAD_HEIGHT)) and paddle1_vel > 0: | |
paddle1_vel = 0 | |
if paddle2_pos > (HEIGHT - (HALF_PAD_HEIGHT)) and paddle2_vel > 0: | |
paddle2_vel = 0 | |
paddle1_pos += paddle1_vel | |
paddle2_pos += paddle2_vel | |
# draw mid line and gutters | |
canvas.draw_line([WIDTH / 2, 0],[WIDTH / 2, HEIGHT], 1, "Green") | |
canvas.draw_line([PAD_WIDTH, 0],[PAD_WIDTH, HEIGHT], 1, "Green") | |
canvas.draw_line([WIDTH - PAD_WIDTH, 0],[WIDTH - PAD_WIDTH, HEIGHT], 1, "Green") | |
# draw paddles | |
canvas.draw_polygon([(0, paddle1_pos-HALF_PAD_HEIGHT), (0, paddle1_pos+HALF_PAD_HEIGHT), (PAD_WIDTH-2, paddle1_pos+HALF_PAD_HEIGHT),(PAD_WIDTH-2,paddle1_pos-HALF_PAD_HEIGHT)], PAD_WIDTH-1, "Green","Green") | |
canvas.draw_polygon([(WIDTH, paddle2_pos-HALF_PAD_HEIGHT), (WIDTH, paddle2_pos+HALF_PAD_HEIGHT), (WIDTH-PAD_WIDTH+2, paddle2_pos+HALF_PAD_HEIGHT),(WIDTH-PAD_WIDTH+2,paddle2_pos-HALF_PAD_HEIGHT)], PAD_WIDTH-1, "Green","Green") | |
# update ball | |
ball_pos[0] += ball_vel[0] | |
ball_pos[1] += ball_vel[1] | |
if ball_pos[1] >= (HEIGHT - BALL_RADIUS) or ball_pos[1] <= (BALL_RADIUS): | |
ball_vel[1] = -ball_vel[1] | |
if ball_pos[0] <= (PAD_WIDTH + BALL_RADIUS): | |
if ball_pos[1] < (paddle1_pos - HALF_PAD_HEIGHT) or ball_pos[1] > (paddle1_pos + HALF_PAD_HEIGHT): | |
spawn_ball('right') | |
score2 += 1 | |
else: | |
ball_vel[0] = -ball_vel[0] * 1.1 | |
if ball_pos[0] >= (WIDTH - PAD_WIDTH - BALL_RADIUS): | |
if ball_pos[1] < (paddle2_pos - HALF_PAD_HEIGHT) or ball_pos[1] > (paddle2_pos + HALF_PAD_HEIGHT): | |
spawn_ball('left') | |
score1 += 1 | |
else: | |
ball_vel[0] = -ball_vel[0] * 1.1 | |
# draw ball and scores | |
canvas.draw_circle(ball_pos, BALL_RADIUS, 2, "Green", "Green") | |
canvas.draw_text(str(score1), (170, 50), 36, "Green") | |
canvas.draw_text(str(score2), (400, 50), 36, "Green") | |
def keydown(key): | |
# Change velocity according to keypresses | |
global paddle1_vel, paddle2_vel | |
if key == simplegui.KEY_MAP['w']: | |
paddle1_vel = -4 | |
elif key == simplegui.KEY_MAP['s']: | |
paddle1_vel = 4 | |
elif key == simplegui.KEY_MAP['up']: | |
paddle2_vel = -4 | |
elif key == simplegui.KEY_MAP['down']: | |
paddle2_vel = 4 | |
def keyup(key): | |
# Set velocity to null when keyup | |
global paddle1_vel, paddle2_vel | |
global paddle1_vel, paddle2_vel | |
if key == simplegui.KEY_MAP['w']: | |
paddle1_vel = 0 | |
elif key == simplegui.KEY_MAP['s']: | |
paddle1_vel = 0 | |
elif key == simplegui.KEY_MAP['up']: | |
paddle2_vel = 0 | |
elif key == simplegui.KEY_MAP['down']: | |
paddle2_vel = 0 | |
# create frame | |
frame = simplegui.create_frame("Pong", WIDTH, HEIGHT) | |
frame.set_draw_handler(draw) | |
frame.set_keydown_handler(keydown) | |
frame.set_keyup_handler(keyup) | |
timer = simplegui.create_timer(50, tick) | |
frame.add_button("Restart", new_game, 100) | |
# start frame | |
new_game() | |
frame.start() | |
timer.start() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment