First Pong game
This is my first pygame project that I've worked on and wanted to start with something simple. Pong was, I think, a pretty good choice now that I'm done with it. I will continue to make improvements to the game and adjustments, but I would like the community to review and give suggestions for improvements. I'm a hobbyist and know next to nothing about computer science.
The improvements I had in mind for the next version would be changing the angle of the ball based on where on the paddle the ball hits and adding sound. I'm also going to work on a simple AI for single player.
I'm looking to see if my code is structured in a way that is not normal or is just bad by design. I'm interested to hear about using this style of coding for larger games and how it scales as the game gets bigger. Let me know what you think.
import pygame
import math
pygame.init()
screensize1 = 1500
screensize2 = 1000
win = pygame.display.set_mode((screensize1, screensize2))
pygame.display.set_caption('Test Environment')
class Player(object):
def __init__(self, color, x, y, width, height, score):
self.color = color
self.x = x
self.y = y
self.width = width
self.height = height
self.vel = 20
self.score = score
self.up = False
self.down = False
class Projectile(object):
def __init__(self, x, y, angle):
self.x = x
self.y = y
self.radius = 6
self.color = (255, 255, 255)
self.angle = angle
self.vel = 20
self.xvel = int(round((math.sin(math.radians(self.angle)) * self.vel), 0))
self.yvel = int(round((math.cos(math.radians(self.angle)) * self.vel), 0))
def redraw_game_window():
global Char2Win, Char1Win, s1_WaitToStart
win.fill((0, 0, 0))
pygame.draw.line(win, (255, 0, 0), (screensize1//2, 0), (screensize1//2, screensize2), 4)
if s1_WaitToStart is True:
win.blit(pygame.font.SysFont('None', 50).render('Press Space To Start', 0, (255, 255, 255)), ((screensize1//2)-180, ((screensize2//2)-25)))
if Char1Win is True:
win.blit(pygame.font.SysFont('None', 50).render('Player 1 Wins', 0, (255, 255, 255)), ((screensize1//4)-160, ((screensize2//2)-25)))
win.blit(pygame.font.SysFont('None', 50).render('Press Space To Start New Game', 0, (255, 255, 255)), ((screensize1//2)-200, ((screensize2//4 + screensize2//2)-25)))
if Char2Win is True:
win.blit(pygame.font.SysFont('None', 50).render('Player 2 Wins', 0, (255, 255, 255)), ((screensize1//4 + screensize1//2)-160, ((screensize2//2)-25)))
win.blit(pygame.font.SysFont('None', 50).render('Press Space To Start New Game', 0, (255, 255, 255)), ((screensize1//2)-200, ((screensize2//4 + screensize2//2)-25)))
win.blit(pygame.font.SysFont('None', 100).render(str(char1.score) + ' ' + str(char2.score), 0, (255, 255, 255)), ((screensize1//2)-85, 20))
pygame.draw.rect(win, char1.color, (char1.x, char1.y, char1.width, char1.height))
pygame.draw.rect(win, char2.color, (char2.x, char2.y, char2.width, char2.height))
pygame.draw.circle(win, ball.color, (ball.x, ball.y), ball.radius)
pygame.display.update()
char1 = Player((255, 0, 0), 25, (screensize2//2) - 90, 25, 160, 0)
char2 = Player((255, 0, 0), screensize1 - 50, (screensize2//2) - 90, 25, 160, 0)
ball = Projectile((screensize1//8) + (screensize1//4), screensize2//4, 315)
s1_WaitToStart = True
s2_BallAtPlayerOne = False
s3_PlayerTwoScore = False
s4_PlayerOneHit = False
s5_HitsWall = False
s6_BallAtPlayerTwo = False
s7_PlayerOneScore = False
s8_PlayerTwoHit = False
Char1Win = False
Char2Win = False
laststate = ''
run = True
while run:
pygame.time.delay(30)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
keys = pygame.key.get_pressed()
if keys[pygame.K_w] and char1.y > char1.vel:
char1.y -= char1.vel
if keys[pygame.K_s] and char1.y < screensize2 - char1.height - char1.vel:
char1.y += char1.vel
if keys[pygame.K_UP] and char2.y > char2.vel:
char2.y -= char2.vel
if keys[pygame.K_DOWN] and char2.y < screensize2 - char2.height - char2.vel:
char2.y += char2.vel
# STATES OF GAME PLAY *************************************************************************************************
if s1_WaitToStart is True:
ball.x = (screensize1//8) + (screensize1//4)
ball.y = screensize2//4
if keys[pygame.K_SPACE]:
s2_BallAtPlayerOne = True
s1_WaitToStart = False
if s1_WaitToStart is False and s7_PlayerOneScore is False and s3_PlayerTwoScore is False and s4_PlayerOneHit is False and s8_PlayerTwoHit is False and s5_HitsWall is False:
ball.x += ball.xvel
ball.y += ball.yvel
if s2_BallAtPlayerOne is True:
ball.xvel = int(round((math.sin(math.radians(ball.angle)) * ball.vel), 0))
ball.yvel = int(round((math.cos(math.radians(ball.angle)) * ball.vel), 0))
if ball.x <= char1.x + char1.width:
if char1.y - (2 * ball.radius) < ball.y or ball.y < char1.y + char1.height:
s4_PlayerOneHit = True
s2_BallAtPlayerOne = False
if ball.x < char1.x + char1.width + ball.radius:
if char1.y + char1.height + ball.radius <= ball.y or ball.y <= char1.y - ball.radius:
s3_PlayerTwoScore = True
s2_BallAtPlayerOne = False
if ball.y >= screensize2 - (2 * ball.radius):
if laststate != 's5':
s5_HitsWall = True
s2_BallAtPlayerOne = False
if ball.y <= 0 + (2 * ball.radius):
if laststate != 's5':
s5_HitsWall = True
s2_BallAtPlayerOne = False
laststate = 's2'
if s3_PlayerTwoScore is True:
char2.score += 1
if char2.score == 4:
Char2Win = True
s3_PlayerTwoScore = False
ball.x = (screensize1 // 8) + (screensize1 // 2)
ball.y = screensize2 // 4
ball.angle = 315
s2_BallAtPlayerOne = True
s3_PlayerTwoScore = False
laststate = 's3'
if s4_PlayerOneHit is True:
ball.xvel = 0
ball.yvel = 0
if 0 < ball.angle > 270:
ball.angle -= 270
ball.x += ball.xvel
ball.y += ball.yvel
s6_BallAtPlayerTwo = True
s4_PlayerOneHit = False
elif 270 > ball.angle > 180:
ball.angle -= 90
ball.x += ball.xvel
ball.y += ball.yvel
s6_BallAtPlayerTwo = True
s4_PlayerOneHit = False
laststate = 's4'
if s5_HitsWall is True:
ball.xvel = 0
ball.yvel = 0
if ball.y < screensize2//2:
if 180 > ball.angle > 90:
ball.angle -= 90
s6_BallAtPlayerTwo = True
s5_HitsWall = False
else:
ball.angle += 90
s2_BallAtPlayerOne = True
s5_HitsWall = False
if ball.y > screensize2//2:
if 0 < ball.angle < 90:
ball.angle += 90
s6_BallAtPlayerTwo = True
s5_HitsWall = False
else:
ball.angle -= 90
s2_BallAtPlayerOne = True
s5_HitsWall = False
laststate = 's5'
if s6_BallAtPlayerTwo is True:
ball.xvel = int(round((math.sin(math.radians(ball.angle)) * ball.vel), 0))
ball.yvel = int(round((math.cos(math.radians(ball.angle)) * ball.vel), 0))
if ball.x >= char2.x - (2 * ball.radius):
if char2.y - (2 * ball.radius) < ball.y or ball.y < char2.y + char2.height + ball.y:
s8_PlayerTwoHit = True
s6_BallAtPlayerTwo = False
if ball.x > char2.x - (2 * ball.radius):
if char2.y + char2.height <= ball.y or ball.y <= char2.y - (2 * ball.radius):
s7_PlayerOneScore = True
s6_BallAtPlayerTwo = False
if ball.y >= screensize2 - (2 * ball.radius):
if laststate != 's5':
s5_HitsWall = True
s6_BallAtPlayerTwo = False
if ball.y <= 0 + (2 * ball.radius):
if laststate != 's5':
s5_HitsWall = True
s6_BallAtPlayerTwo = False
laststate = 's6'
if s7_PlayerOneScore is True:
char1.score += 1
if char1.score == 4:
Char1Win = True
s7_PlayerOneScore = False
ball.x = (screensize1 // 8) + (screensize1 // 4)
ball.y = screensize2 // 4
ball.angle = 45
s6_BallAtPlayerTwo = True
s7_PlayerOneScore = False
laststate = 's7'
if s8_PlayerTwoHit is True:
ball.xvel = 0
ball.yvel = 0
if 0 < ball.angle < 90:
ball.angle += 270
ball.x += ball.xvel
ball.y += ball.yvel
s2_BallAtPlayerOne = True
s8_PlayerTwoHit = False
elif 90 < ball.angle < 180:
ball.angle += 90
ball.x += ball.xvel
ball.y += ball.yvel
s2_BallAtPlayerOne = True
s8_PlayerTwoHit = False
laststate = 's8'
if Char2Win is True:
ball.xvel = 0
ball.yvel = 0
ball.x = (screensize1 // 8) + (screensize1 // 4)
ball.y = screensize2 // 4
if keys[pygame.K_SPACE]:
char2.score = 0
char1.score = 0
Char2Win = False
s1_WaitToStart = True
if Char1Win is True:
ball.xvel = 0
ball.yvel = 0
ball.x = (screensize1 // 8) + (screensize1 // 4)
ball.y = screensize2 // 4
if keys[pygame.K_SPACE]:
char2.score = 0
char1.score = 0
Char1Win = False
s1_WaitToStart = True
redraw_game_window()
pygame.quit()
python pygame
add a comment |
This is my first pygame project that I've worked on and wanted to start with something simple. Pong was, I think, a pretty good choice now that I'm done with it. I will continue to make improvements to the game and adjustments, but I would like the community to review and give suggestions for improvements. I'm a hobbyist and know next to nothing about computer science.
The improvements I had in mind for the next version would be changing the angle of the ball based on where on the paddle the ball hits and adding sound. I'm also going to work on a simple AI for single player.
I'm looking to see if my code is structured in a way that is not normal or is just bad by design. I'm interested to hear about using this style of coding for larger games and how it scales as the game gets bigger. Let me know what you think.
import pygame
import math
pygame.init()
screensize1 = 1500
screensize2 = 1000
win = pygame.display.set_mode((screensize1, screensize2))
pygame.display.set_caption('Test Environment')
class Player(object):
def __init__(self, color, x, y, width, height, score):
self.color = color
self.x = x
self.y = y
self.width = width
self.height = height
self.vel = 20
self.score = score
self.up = False
self.down = False
class Projectile(object):
def __init__(self, x, y, angle):
self.x = x
self.y = y
self.radius = 6
self.color = (255, 255, 255)
self.angle = angle
self.vel = 20
self.xvel = int(round((math.sin(math.radians(self.angle)) * self.vel), 0))
self.yvel = int(round((math.cos(math.radians(self.angle)) * self.vel), 0))
def redraw_game_window():
global Char2Win, Char1Win, s1_WaitToStart
win.fill((0, 0, 0))
pygame.draw.line(win, (255, 0, 0), (screensize1//2, 0), (screensize1//2, screensize2), 4)
if s1_WaitToStart is True:
win.blit(pygame.font.SysFont('None', 50).render('Press Space To Start', 0, (255, 255, 255)), ((screensize1//2)-180, ((screensize2//2)-25)))
if Char1Win is True:
win.blit(pygame.font.SysFont('None', 50).render('Player 1 Wins', 0, (255, 255, 255)), ((screensize1//4)-160, ((screensize2//2)-25)))
win.blit(pygame.font.SysFont('None', 50).render('Press Space To Start New Game', 0, (255, 255, 255)), ((screensize1//2)-200, ((screensize2//4 + screensize2//2)-25)))
if Char2Win is True:
win.blit(pygame.font.SysFont('None', 50).render('Player 2 Wins', 0, (255, 255, 255)), ((screensize1//4 + screensize1//2)-160, ((screensize2//2)-25)))
win.blit(pygame.font.SysFont('None', 50).render('Press Space To Start New Game', 0, (255, 255, 255)), ((screensize1//2)-200, ((screensize2//4 + screensize2//2)-25)))
win.blit(pygame.font.SysFont('None', 100).render(str(char1.score) + ' ' + str(char2.score), 0, (255, 255, 255)), ((screensize1//2)-85, 20))
pygame.draw.rect(win, char1.color, (char1.x, char1.y, char1.width, char1.height))
pygame.draw.rect(win, char2.color, (char2.x, char2.y, char2.width, char2.height))
pygame.draw.circle(win, ball.color, (ball.x, ball.y), ball.radius)
pygame.display.update()
char1 = Player((255, 0, 0), 25, (screensize2//2) - 90, 25, 160, 0)
char2 = Player((255, 0, 0), screensize1 - 50, (screensize2//2) - 90, 25, 160, 0)
ball = Projectile((screensize1//8) + (screensize1//4), screensize2//4, 315)
s1_WaitToStart = True
s2_BallAtPlayerOne = False
s3_PlayerTwoScore = False
s4_PlayerOneHit = False
s5_HitsWall = False
s6_BallAtPlayerTwo = False
s7_PlayerOneScore = False
s8_PlayerTwoHit = False
Char1Win = False
Char2Win = False
laststate = ''
run = True
while run:
pygame.time.delay(30)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
keys = pygame.key.get_pressed()
if keys[pygame.K_w] and char1.y > char1.vel:
char1.y -= char1.vel
if keys[pygame.K_s] and char1.y < screensize2 - char1.height - char1.vel:
char1.y += char1.vel
if keys[pygame.K_UP] and char2.y > char2.vel:
char2.y -= char2.vel
if keys[pygame.K_DOWN] and char2.y < screensize2 - char2.height - char2.vel:
char2.y += char2.vel
# STATES OF GAME PLAY *************************************************************************************************
if s1_WaitToStart is True:
ball.x = (screensize1//8) + (screensize1//4)
ball.y = screensize2//4
if keys[pygame.K_SPACE]:
s2_BallAtPlayerOne = True
s1_WaitToStart = False
if s1_WaitToStart is False and s7_PlayerOneScore is False and s3_PlayerTwoScore is False and s4_PlayerOneHit is False and s8_PlayerTwoHit is False and s5_HitsWall is False:
ball.x += ball.xvel
ball.y += ball.yvel
if s2_BallAtPlayerOne is True:
ball.xvel = int(round((math.sin(math.radians(ball.angle)) * ball.vel), 0))
ball.yvel = int(round((math.cos(math.radians(ball.angle)) * ball.vel), 0))
if ball.x <= char1.x + char1.width:
if char1.y - (2 * ball.radius) < ball.y or ball.y < char1.y + char1.height:
s4_PlayerOneHit = True
s2_BallAtPlayerOne = False
if ball.x < char1.x + char1.width + ball.radius:
if char1.y + char1.height + ball.radius <= ball.y or ball.y <= char1.y - ball.radius:
s3_PlayerTwoScore = True
s2_BallAtPlayerOne = False
if ball.y >= screensize2 - (2 * ball.radius):
if laststate != 's5':
s5_HitsWall = True
s2_BallAtPlayerOne = False
if ball.y <= 0 + (2 * ball.radius):
if laststate != 's5':
s5_HitsWall = True
s2_BallAtPlayerOne = False
laststate = 's2'
if s3_PlayerTwoScore is True:
char2.score += 1
if char2.score == 4:
Char2Win = True
s3_PlayerTwoScore = False
ball.x = (screensize1 // 8) + (screensize1 // 2)
ball.y = screensize2 // 4
ball.angle = 315
s2_BallAtPlayerOne = True
s3_PlayerTwoScore = False
laststate = 's3'
if s4_PlayerOneHit is True:
ball.xvel = 0
ball.yvel = 0
if 0 < ball.angle > 270:
ball.angle -= 270
ball.x += ball.xvel
ball.y += ball.yvel
s6_BallAtPlayerTwo = True
s4_PlayerOneHit = False
elif 270 > ball.angle > 180:
ball.angle -= 90
ball.x += ball.xvel
ball.y += ball.yvel
s6_BallAtPlayerTwo = True
s4_PlayerOneHit = False
laststate = 's4'
if s5_HitsWall is True:
ball.xvel = 0
ball.yvel = 0
if ball.y < screensize2//2:
if 180 > ball.angle > 90:
ball.angle -= 90
s6_BallAtPlayerTwo = True
s5_HitsWall = False
else:
ball.angle += 90
s2_BallAtPlayerOne = True
s5_HitsWall = False
if ball.y > screensize2//2:
if 0 < ball.angle < 90:
ball.angle += 90
s6_BallAtPlayerTwo = True
s5_HitsWall = False
else:
ball.angle -= 90
s2_BallAtPlayerOne = True
s5_HitsWall = False
laststate = 's5'
if s6_BallAtPlayerTwo is True:
ball.xvel = int(round((math.sin(math.radians(ball.angle)) * ball.vel), 0))
ball.yvel = int(round((math.cos(math.radians(ball.angle)) * ball.vel), 0))
if ball.x >= char2.x - (2 * ball.radius):
if char2.y - (2 * ball.radius) < ball.y or ball.y < char2.y + char2.height + ball.y:
s8_PlayerTwoHit = True
s6_BallAtPlayerTwo = False
if ball.x > char2.x - (2 * ball.radius):
if char2.y + char2.height <= ball.y or ball.y <= char2.y - (2 * ball.radius):
s7_PlayerOneScore = True
s6_BallAtPlayerTwo = False
if ball.y >= screensize2 - (2 * ball.radius):
if laststate != 's5':
s5_HitsWall = True
s6_BallAtPlayerTwo = False
if ball.y <= 0 + (2 * ball.radius):
if laststate != 's5':
s5_HitsWall = True
s6_BallAtPlayerTwo = False
laststate = 's6'
if s7_PlayerOneScore is True:
char1.score += 1
if char1.score == 4:
Char1Win = True
s7_PlayerOneScore = False
ball.x = (screensize1 // 8) + (screensize1 // 4)
ball.y = screensize2 // 4
ball.angle = 45
s6_BallAtPlayerTwo = True
s7_PlayerOneScore = False
laststate = 's7'
if s8_PlayerTwoHit is True:
ball.xvel = 0
ball.yvel = 0
if 0 < ball.angle < 90:
ball.angle += 270
ball.x += ball.xvel
ball.y += ball.yvel
s2_BallAtPlayerOne = True
s8_PlayerTwoHit = False
elif 90 < ball.angle < 180:
ball.angle += 90
ball.x += ball.xvel
ball.y += ball.yvel
s2_BallAtPlayerOne = True
s8_PlayerTwoHit = False
laststate = 's8'
if Char2Win is True:
ball.xvel = 0
ball.yvel = 0
ball.x = (screensize1 // 8) + (screensize1 // 4)
ball.y = screensize2 // 4
if keys[pygame.K_SPACE]:
char2.score = 0
char1.score = 0
Char2Win = False
s1_WaitToStart = True
if Char1Win is True:
ball.xvel = 0
ball.yvel = 0
ball.x = (screensize1 // 8) + (screensize1 // 4)
ball.y = screensize2 // 4
if keys[pygame.K_SPACE]:
char2.score = 0
char1.score = 0
Char1Win = False
s1_WaitToStart = True
redraw_game_window()
pygame.quit()
python pygame
add a comment |
This is my first pygame project that I've worked on and wanted to start with something simple. Pong was, I think, a pretty good choice now that I'm done with it. I will continue to make improvements to the game and adjustments, but I would like the community to review and give suggestions for improvements. I'm a hobbyist and know next to nothing about computer science.
The improvements I had in mind for the next version would be changing the angle of the ball based on where on the paddle the ball hits and adding sound. I'm also going to work on a simple AI for single player.
I'm looking to see if my code is structured in a way that is not normal or is just bad by design. I'm interested to hear about using this style of coding for larger games and how it scales as the game gets bigger. Let me know what you think.
import pygame
import math
pygame.init()
screensize1 = 1500
screensize2 = 1000
win = pygame.display.set_mode((screensize1, screensize2))
pygame.display.set_caption('Test Environment')
class Player(object):
def __init__(self, color, x, y, width, height, score):
self.color = color
self.x = x
self.y = y
self.width = width
self.height = height
self.vel = 20
self.score = score
self.up = False
self.down = False
class Projectile(object):
def __init__(self, x, y, angle):
self.x = x
self.y = y
self.radius = 6
self.color = (255, 255, 255)
self.angle = angle
self.vel = 20
self.xvel = int(round((math.sin(math.radians(self.angle)) * self.vel), 0))
self.yvel = int(round((math.cos(math.radians(self.angle)) * self.vel), 0))
def redraw_game_window():
global Char2Win, Char1Win, s1_WaitToStart
win.fill((0, 0, 0))
pygame.draw.line(win, (255, 0, 0), (screensize1//2, 0), (screensize1//2, screensize2), 4)
if s1_WaitToStart is True:
win.blit(pygame.font.SysFont('None', 50).render('Press Space To Start', 0, (255, 255, 255)), ((screensize1//2)-180, ((screensize2//2)-25)))
if Char1Win is True:
win.blit(pygame.font.SysFont('None', 50).render('Player 1 Wins', 0, (255, 255, 255)), ((screensize1//4)-160, ((screensize2//2)-25)))
win.blit(pygame.font.SysFont('None', 50).render('Press Space To Start New Game', 0, (255, 255, 255)), ((screensize1//2)-200, ((screensize2//4 + screensize2//2)-25)))
if Char2Win is True:
win.blit(pygame.font.SysFont('None', 50).render('Player 2 Wins', 0, (255, 255, 255)), ((screensize1//4 + screensize1//2)-160, ((screensize2//2)-25)))
win.blit(pygame.font.SysFont('None', 50).render('Press Space To Start New Game', 0, (255, 255, 255)), ((screensize1//2)-200, ((screensize2//4 + screensize2//2)-25)))
win.blit(pygame.font.SysFont('None', 100).render(str(char1.score) + ' ' + str(char2.score), 0, (255, 255, 255)), ((screensize1//2)-85, 20))
pygame.draw.rect(win, char1.color, (char1.x, char1.y, char1.width, char1.height))
pygame.draw.rect(win, char2.color, (char2.x, char2.y, char2.width, char2.height))
pygame.draw.circle(win, ball.color, (ball.x, ball.y), ball.radius)
pygame.display.update()
char1 = Player((255, 0, 0), 25, (screensize2//2) - 90, 25, 160, 0)
char2 = Player((255, 0, 0), screensize1 - 50, (screensize2//2) - 90, 25, 160, 0)
ball = Projectile((screensize1//8) + (screensize1//4), screensize2//4, 315)
s1_WaitToStart = True
s2_BallAtPlayerOne = False
s3_PlayerTwoScore = False
s4_PlayerOneHit = False
s5_HitsWall = False
s6_BallAtPlayerTwo = False
s7_PlayerOneScore = False
s8_PlayerTwoHit = False
Char1Win = False
Char2Win = False
laststate = ''
run = True
while run:
pygame.time.delay(30)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
keys = pygame.key.get_pressed()
if keys[pygame.K_w] and char1.y > char1.vel:
char1.y -= char1.vel
if keys[pygame.K_s] and char1.y < screensize2 - char1.height - char1.vel:
char1.y += char1.vel
if keys[pygame.K_UP] and char2.y > char2.vel:
char2.y -= char2.vel
if keys[pygame.K_DOWN] and char2.y < screensize2 - char2.height - char2.vel:
char2.y += char2.vel
# STATES OF GAME PLAY *************************************************************************************************
if s1_WaitToStart is True:
ball.x = (screensize1//8) + (screensize1//4)
ball.y = screensize2//4
if keys[pygame.K_SPACE]:
s2_BallAtPlayerOne = True
s1_WaitToStart = False
if s1_WaitToStart is False and s7_PlayerOneScore is False and s3_PlayerTwoScore is False and s4_PlayerOneHit is False and s8_PlayerTwoHit is False and s5_HitsWall is False:
ball.x += ball.xvel
ball.y += ball.yvel
if s2_BallAtPlayerOne is True:
ball.xvel = int(round((math.sin(math.radians(ball.angle)) * ball.vel), 0))
ball.yvel = int(round((math.cos(math.radians(ball.angle)) * ball.vel), 0))
if ball.x <= char1.x + char1.width:
if char1.y - (2 * ball.radius) < ball.y or ball.y < char1.y + char1.height:
s4_PlayerOneHit = True
s2_BallAtPlayerOne = False
if ball.x < char1.x + char1.width + ball.radius:
if char1.y + char1.height + ball.radius <= ball.y or ball.y <= char1.y - ball.radius:
s3_PlayerTwoScore = True
s2_BallAtPlayerOne = False
if ball.y >= screensize2 - (2 * ball.radius):
if laststate != 's5':
s5_HitsWall = True
s2_BallAtPlayerOne = False
if ball.y <= 0 + (2 * ball.radius):
if laststate != 's5':
s5_HitsWall = True
s2_BallAtPlayerOne = False
laststate = 's2'
if s3_PlayerTwoScore is True:
char2.score += 1
if char2.score == 4:
Char2Win = True
s3_PlayerTwoScore = False
ball.x = (screensize1 // 8) + (screensize1 // 2)
ball.y = screensize2 // 4
ball.angle = 315
s2_BallAtPlayerOne = True
s3_PlayerTwoScore = False
laststate = 's3'
if s4_PlayerOneHit is True:
ball.xvel = 0
ball.yvel = 0
if 0 < ball.angle > 270:
ball.angle -= 270
ball.x += ball.xvel
ball.y += ball.yvel
s6_BallAtPlayerTwo = True
s4_PlayerOneHit = False
elif 270 > ball.angle > 180:
ball.angle -= 90
ball.x += ball.xvel
ball.y += ball.yvel
s6_BallAtPlayerTwo = True
s4_PlayerOneHit = False
laststate = 's4'
if s5_HitsWall is True:
ball.xvel = 0
ball.yvel = 0
if ball.y < screensize2//2:
if 180 > ball.angle > 90:
ball.angle -= 90
s6_BallAtPlayerTwo = True
s5_HitsWall = False
else:
ball.angle += 90
s2_BallAtPlayerOne = True
s5_HitsWall = False
if ball.y > screensize2//2:
if 0 < ball.angle < 90:
ball.angle += 90
s6_BallAtPlayerTwo = True
s5_HitsWall = False
else:
ball.angle -= 90
s2_BallAtPlayerOne = True
s5_HitsWall = False
laststate = 's5'
if s6_BallAtPlayerTwo is True:
ball.xvel = int(round((math.sin(math.radians(ball.angle)) * ball.vel), 0))
ball.yvel = int(round((math.cos(math.radians(ball.angle)) * ball.vel), 0))
if ball.x >= char2.x - (2 * ball.radius):
if char2.y - (2 * ball.radius) < ball.y or ball.y < char2.y + char2.height + ball.y:
s8_PlayerTwoHit = True
s6_BallAtPlayerTwo = False
if ball.x > char2.x - (2 * ball.radius):
if char2.y + char2.height <= ball.y or ball.y <= char2.y - (2 * ball.radius):
s7_PlayerOneScore = True
s6_BallAtPlayerTwo = False
if ball.y >= screensize2 - (2 * ball.radius):
if laststate != 's5':
s5_HitsWall = True
s6_BallAtPlayerTwo = False
if ball.y <= 0 + (2 * ball.radius):
if laststate != 's5':
s5_HitsWall = True
s6_BallAtPlayerTwo = False
laststate = 's6'
if s7_PlayerOneScore is True:
char1.score += 1
if char1.score == 4:
Char1Win = True
s7_PlayerOneScore = False
ball.x = (screensize1 // 8) + (screensize1 // 4)
ball.y = screensize2 // 4
ball.angle = 45
s6_BallAtPlayerTwo = True
s7_PlayerOneScore = False
laststate = 's7'
if s8_PlayerTwoHit is True:
ball.xvel = 0
ball.yvel = 0
if 0 < ball.angle < 90:
ball.angle += 270
ball.x += ball.xvel
ball.y += ball.yvel
s2_BallAtPlayerOne = True
s8_PlayerTwoHit = False
elif 90 < ball.angle < 180:
ball.angle += 90
ball.x += ball.xvel
ball.y += ball.yvel
s2_BallAtPlayerOne = True
s8_PlayerTwoHit = False
laststate = 's8'
if Char2Win is True:
ball.xvel = 0
ball.yvel = 0
ball.x = (screensize1 // 8) + (screensize1 // 4)
ball.y = screensize2 // 4
if keys[pygame.K_SPACE]:
char2.score = 0
char1.score = 0
Char2Win = False
s1_WaitToStart = True
if Char1Win is True:
ball.xvel = 0
ball.yvel = 0
ball.x = (screensize1 // 8) + (screensize1 // 4)
ball.y = screensize2 // 4
if keys[pygame.K_SPACE]:
char2.score = 0
char1.score = 0
Char1Win = False
s1_WaitToStart = True
redraw_game_window()
pygame.quit()
python pygame
This is my first pygame project that I've worked on and wanted to start with something simple. Pong was, I think, a pretty good choice now that I'm done with it. I will continue to make improvements to the game and adjustments, but I would like the community to review and give suggestions for improvements. I'm a hobbyist and know next to nothing about computer science.
The improvements I had in mind for the next version would be changing the angle of the ball based on where on the paddle the ball hits and adding sound. I'm also going to work on a simple AI for single player.
I'm looking to see if my code is structured in a way that is not normal or is just bad by design. I'm interested to hear about using this style of coding for larger games and how it scales as the game gets bigger. Let me know what you think.
import pygame
import math
pygame.init()
screensize1 = 1500
screensize2 = 1000
win = pygame.display.set_mode((screensize1, screensize2))
pygame.display.set_caption('Test Environment')
class Player(object):
def __init__(self, color, x, y, width, height, score):
self.color = color
self.x = x
self.y = y
self.width = width
self.height = height
self.vel = 20
self.score = score
self.up = False
self.down = False
class Projectile(object):
def __init__(self, x, y, angle):
self.x = x
self.y = y
self.radius = 6
self.color = (255, 255, 255)
self.angle = angle
self.vel = 20
self.xvel = int(round((math.sin(math.radians(self.angle)) * self.vel), 0))
self.yvel = int(round((math.cos(math.radians(self.angle)) * self.vel), 0))
def redraw_game_window():
global Char2Win, Char1Win, s1_WaitToStart
win.fill((0, 0, 0))
pygame.draw.line(win, (255, 0, 0), (screensize1//2, 0), (screensize1//2, screensize2), 4)
if s1_WaitToStart is True:
win.blit(pygame.font.SysFont('None', 50).render('Press Space To Start', 0, (255, 255, 255)), ((screensize1//2)-180, ((screensize2//2)-25)))
if Char1Win is True:
win.blit(pygame.font.SysFont('None', 50).render('Player 1 Wins', 0, (255, 255, 255)), ((screensize1//4)-160, ((screensize2//2)-25)))
win.blit(pygame.font.SysFont('None', 50).render('Press Space To Start New Game', 0, (255, 255, 255)), ((screensize1//2)-200, ((screensize2//4 + screensize2//2)-25)))
if Char2Win is True:
win.blit(pygame.font.SysFont('None', 50).render('Player 2 Wins', 0, (255, 255, 255)), ((screensize1//4 + screensize1//2)-160, ((screensize2//2)-25)))
win.blit(pygame.font.SysFont('None', 50).render('Press Space To Start New Game', 0, (255, 255, 255)), ((screensize1//2)-200, ((screensize2//4 + screensize2//2)-25)))
win.blit(pygame.font.SysFont('None', 100).render(str(char1.score) + ' ' + str(char2.score), 0, (255, 255, 255)), ((screensize1//2)-85, 20))
pygame.draw.rect(win, char1.color, (char1.x, char1.y, char1.width, char1.height))
pygame.draw.rect(win, char2.color, (char2.x, char2.y, char2.width, char2.height))
pygame.draw.circle(win, ball.color, (ball.x, ball.y), ball.radius)
pygame.display.update()
char1 = Player((255, 0, 0), 25, (screensize2//2) - 90, 25, 160, 0)
char2 = Player((255, 0, 0), screensize1 - 50, (screensize2//2) - 90, 25, 160, 0)
ball = Projectile((screensize1//8) + (screensize1//4), screensize2//4, 315)
s1_WaitToStart = True
s2_BallAtPlayerOne = False
s3_PlayerTwoScore = False
s4_PlayerOneHit = False
s5_HitsWall = False
s6_BallAtPlayerTwo = False
s7_PlayerOneScore = False
s8_PlayerTwoHit = False
Char1Win = False
Char2Win = False
laststate = ''
run = True
while run:
pygame.time.delay(30)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
keys = pygame.key.get_pressed()
if keys[pygame.K_w] and char1.y > char1.vel:
char1.y -= char1.vel
if keys[pygame.K_s] and char1.y < screensize2 - char1.height - char1.vel:
char1.y += char1.vel
if keys[pygame.K_UP] and char2.y > char2.vel:
char2.y -= char2.vel
if keys[pygame.K_DOWN] and char2.y < screensize2 - char2.height - char2.vel:
char2.y += char2.vel
# STATES OF GAME PLAY *************************************************************************************************
if s1_WaitToStart is True:
ball.x = (screensize1//8) + (screensize1//4)
ball.y = screensize2//4
if keys[pygame.K_SPACE]:
s2_BallAtPlayerOne = True
s1_WaitToStart = False
if s1_WaitToStart is False and s7_PlayerOneScore is False and s3_PlayerTwoScore is False and s4_PlayerOneHit is False and s8_PlayerTwoHit is False and s5_HitsWall is False:
ball.x += ball.xvel
ball.y += ball.yvel
if s2_BallAtPlayerOne is True:
ball.xvel = int(round((math.sin(math.radians(ball.angle)) * ball.vel), 0))
ball.yvel = int(round((math.cos(math.radians(ball.angle)) * ball.vel), 0))
if ball.x <= char1.x + char1.width:
if char1.y - (2 * ball.radius) < ball.y or ball.y < char1.y + char1.height:
s4_PlayerOneHit = True
s2_BallAtPlayerOne = False
if ball.x < char1.x + char1.width + ball.radius:
if char1.y + char1.height + ball.radius <= ball.y or ball.y <= char1.y - ball.radius:
s3_PlayerTwoScore = True
s2_BallAtPlayerOne = False
if ball.y >= screensize2 - (2 * ball.radius):
if laststate != 's5':
s5_HitsWall = True
s2_BallAtPlayerOne = False
if ball.y <= 0 + (2 * ball.radius):
if laststate != 's5':
s5_HitsWall = True
s2_BallAtPlayerOne = False
laststate = 's2'
if s3_PlayerTwoScore is True:
char2.score += 1
if char2.score == 4:
Char2Win = True
s3_PlayerTwoScore = False
ball.x = (screensize1 // 8) + (screensize1 // 2)
ball.y = screensize2 // 4
ball.angle = 315
s2_BallAtPlayerOne = True
s3_PlayerTwoScore = False
laststate = 's3'
if s4_PlayerOneHit is True:
ball.xvel = 0
ball.yvel = 0
if 0 < ball.angle > 270:
ball.angle -= 270
ball.x += ball.xvel
ball.y += ball.yvel
s6_BallAtPlayerTwo = True
s4_PlayerOneHit = False
elif 270 > ball.angle > 180:
ball.angle -= 90
ball.x += ball.xvel
ball.y += ball.yvel
s6_BallAtPlayerTwo = True
s4_PlayerOneHit = False
laststate = 's4'
if s5_HitsWall is True:
ball.xvel = 0
ball.yvel = 0
if ball.y < screensize2//2:
if 180 > ball.angle > 90:
ball.angle -= 90
s6_BallAtPlayerTwo = True
s5_HitsWall = False
else:
ball.angle += 90
s2_BallAtPlayerOne = True
s5_HitsWall = False
if ball.y > screensize2//2:
if 0 < ball.angle < 90:
ball.angle += 90
s6_BallAtPlayerTwo = True
s5_HitsWall = False
else:
ball.angle -= 90
s2_BallAtPlayerOne = True
s5_HitsWall = False
laststate = 's5'
if s6_BallAtPlayerTwo is True:
ball.xvel = int(round((math.sin(math.radians(ball.angle)) * ball.vel), 0))
ball.yvel = int(round((math.cos(math.radians(ball.angle)) * ball.vel), 0))
if ball.x >= char2.x - (2 * ball.radius):
if char2.y - (2 * ball.radius) < ball.y or ball.y < char2.y + char2.height + ball.y:
s8_PlayerTwoHit = True
s6_BallAtPlayerTwo = False
if ball.x > char2.x - (2 * ball.radius):
if char2.y + char2.height <= ball.y or ball.y <= char2.y - (2 * ball.radius):
s7_PlayerOneScore = True
s6_BallAtPlayerTwo = False
if ball.y >= screensize2 - (2 * ball.radius):
if laststate != 's5':
s5_HitsWall = True
s6_BallAtPlayerTwo = False
if ball.y <= 0 + (2 * ball.radius):
if laststate != 's5':
s5_HitsWall = True
s6_BallAtPlayerTwo = False
laststate = 's6'
if s7_PlayerOneScore is True:
char1.score += 1
if char1.score == 4:
Char1Win = True
s7_PlayerOneScore = False
ball.x = (screensize1 // 8) + (screensize1 // 4)
ball.y = screensize2 // 4
ball.angle = 45
s6_BallAtPlayerTwo = True
s7_PlayerOneScore = False
laststate = 's7'
if s8_PlayerTwoHit is True:
ball.xvel = 0
ball.yvel = 0
if 0 < ball.angle < 90:
ball.angle += 270
ball.x += ball.xvel
ball.y += ball.yvel
s2_BallAtPlayerOne = True
s8_PlayerTwoHit = False
elif 90 < ball.angle < 180:
ball.angle += 90
ball.x += ball.xvel
ball.y += ball.yvel
s2_BallAtPlayerOne = True
s8_PlayerTwoHit = False
laststate = 's8'
if Char2Win is True:
ball.xvel = 0
ball.yvel = 0
ball.x = (screensize1 // 8) + (screensize1 // 4)
ball.y = screensize2 // 4
if keys[pygame.K_SPACE]:
char2.score = 0
char1.score = 0
Char2Win = False
s1_WaitToStart = True
if Char1Win is True:
ball.xvel = 0
ball.yvel = 0
ball.x = (screensize1 // 8) + (screensize1 // 4)
ball.y = screensize2 // 4
if keys[pygame.K_SPACE]:
char2.score = 0
char1.score = 0
Char1Win = False
s1_WaitToStart = True
redraw_game_window()
pygame.quit()
python pygame
python pygame
edited 13 mins ago
Jamal♦
30.2k11116226
30.2k11116226
asked 1 hour ago
Keizzerweiss
183
183
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
This is a good start. Working from top to bottom here are some things I notice:
Minimal imports is usually a good sign, just make sure you aren't doing unnecessary work because Python is batteries included
Classes are a good way to organize things, but I would suggest that you add some default values to your initializers, and potentially some verification that values are valid (e.g. can
x
/y
/radius
be negative, etc.)if s1_WaitToStart is True:
can just beif s1_WaitToStart:
(this happens a lot in the code you provided)Global variables are (usually) bad. I would consider wrapping them in a
Config
orState
objectI would wrap the
while run:
block in a top-level environment# STATES OF GAME PLAY *************************************************************************************************
oof
At this point we've made it pretty far into your example and things are looking alright. But usually a long comment dividing up some code indicates that things are getting smelly. I would think about how you keep track of the game's state with its own object, and refactor your ball mechanics into reusable functions. Really just breaking up the game logic loop that you have would make this more digestible to the reader, and closer to what someone with software engineering experience would expect. Adding comments is (usually) a good thing as well. To help you think about what behavior lends itself to good code, ask yourself if the code you're writing would scale to 2, 5, 10, 100+ users, and if you would be able to jump back into the block you're in the middle of after a month without looking at it.
Oh nice. yeah the state objects idea could help a lot I think. stackoverflow.com/questions/19702168/… here is a different thread that talks about it a little bit.
– Keizzerweiss
4 mins ago
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
return StackExchange.using("mathjaxEditing", function () {
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
});
});
}, "mathjax-editing");
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "196"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f210089%2ffirst-pong-game%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
This is a good start. Working from top to bottom here are some things I notice:
Minimal imports is usually a good sign, just make sure you aren't doing unnecessary work because Python is batteries included
Classes are a good way to organize things, but I would suggest that you add some default values to your initializers, and potentially some verification that values are valid (e.g. can
x
/y
/radius
be negative, etc.)if s1_WaitToStart is True:
can just beif s1_WaitToStart:
(this happens a lot in the code you provided)Global variables are (usually) bad. I would consider wrapping them in a
Config
orState
objectI would wrap the
while run:
block in a top-level environment# STATES OF GAME PLAY *************************************************************************************************
oof
At this point we've made it pretty far into your example and things are looking alright. But usually a long comment dividing up some code indicates that things are getting smelly. I would think about how you keep track of the game's state with its own object, and refactor your ball mechanics into reusable functions. Really just breaking up the game logic loop that you have would make this more digestible to the reader, and closer to what someone with software engineering experience would expect. Adding comments is (usually) a good thing as well. To help you think about what behavior lends itself to good code, ask yourself if the code you're writing would scale to 2, 5, 10, 100+ users, and if you would be able to jump back into the block you're in the middle of after a month without looking at it.
Oh nice. yeah the state objects idea could help a lot I think. stackoverflow.com/questions/19702168/… here is a different thread that talks about it a little bit.
– Keizzerweiss
4 mins ago
add a comment |
This is a good start. Working from top to bottom here are some things I notice:
Minimal imports is usually a good sign, just make sure you aren't doing unnecessary work because Python is batteries included
Classes are a good way to organize things, but I would suggest that you add some default values to your initializers, and potentially some verification that values are valid (e.g. can
x
/y
/radius
be negative, etc.)if s1_WaitToStart is True:
can just beif s1_WaitToStart:
(this happens a lot in the code you provided)Global variables are (usually) bad. I would consider wrapping them in a
Config
orState
objectI would wrap the
while run:
block in a top-level environment# STATES OF GAME PLAY *************************************************************************************************
oof
At this point we've made it pretty far into your example and things are looking alright. But usually a long comment dividing up some code indicates that things are getting smelly. I would think about how you keep track of the game's state with its own object, and refactor your ball mechanics into reusable functions. Really just breaking up the game logic loop that you have would make this more digestible to the reader, and closer to what someone with software engineering experience would expect. Adding comments is (usually) a good thing as well. To help you think about what behavior lends itself to good code, ask yourself if the code you're writing would scale to 2, 5, 10, 100+ users, and if you would be able to jump back into the block you're in the middle of after a month without looking at it.
Oh nice. yeah the state objects idea could help a lot I think. stackoverflow.com/questions/19702168/… here is a different thread that talks about it a little bit.
– Keizzerweiss
4 mins ago
add a comment |
This is a good start. Working from top to bottom here are some things I notice:
Minimal imports is usually a good sign, just make sure you aren't doing unnecessary work because Python is batteries included
Classes are a good way to organize things, but I would suggest that you add some default values to your initializers, and potentially some verification that values are valid (e.g. can
x
/y
/radius
be negative, etc.)if s1_WaitToStart is True:
can just beif s1_WaitToStart:
(this happens a lot in the code you provided)Global variables are (usually) bad. I would consider wrapping them in a
Config
orState
objectI would wrap the
while run:
block in a top-level environment# STATES OF GAME PLAY *************************************************************************************************
oof
At this point we've made it pretty far into your example and things are looking alright. But usually a long comment dividing up some code indicates that things are getting smelly. I would think about how you keep track of the game's state with its own object, and refactor your ball mechanics into reusable functions. Really just breaking up the game logic loop that you have would make this more digestible to the reader, and closer to what someone with software engineering experience would expect. Adding comments is (usually) a good thing as well. To help you think about what behavior lends itself to good code, ask yourself if the code you're writing would scale to 2, 5, 10, 100+ users, and if you would be able to jump back into the block you're in the middle of after a month without looking at it.
This is a good start. Working from top to bottom here are some things I notice:
Minimal imports is usually a good sign, just make sure you aren't doing unnecessary work because Python is batteries included
Classes are a good way to organize things, but I would suggest that you add some default values to your initializers, and potentially some verification that values are valid (e.g. can
x
/y
/radius
be negative, etc.)if s1_WaitToStart is True:
can just beif s1_WaitToStart:
(this happens a lot in the code you provided)Global variables are (usually) bad. I would consider wrapping them in a
Config
orState
objectI would wrap the
while run:
block in a top-level environment# STATES OF GAME PLAY *************************************************************************************************
oof
At this point we've made it pretty far into your example and things are looking alright. But usually a long comment dividing up some code indicates that things are getting smelly. I would think about how you keep track of the game's state with its own object, and refactor your ball mechanics into reusable functions. Really just breaking up the game logic loop that you have would make this more digestible to the reader, and closer to what someone with software engineering experience would expect. Adding comments is (usually) a good thing as well. To help you think about what behavior lends itself to good code, ask yourself if the code you're writing would scale to 2, 5, 10, 100+ users, and if you would be able to jump back into the block you're in the middle of after a month without looking at it.
answered 56 mins ago
wklock
714
714
Oh nice. yeah the state objects idea could help a lot I think. stackoverflow.com/questions/19702168/… here is a different thread that talks about it a little bit.
– Keizzerweiss
4 mins ago
add a comment |
Oh nice. yeah the state objects idea could help a lot I think. stackoverflow.com/questions/19702168/… here is a different thread that talks about it a little bit.
– Keizzerweiss
4 mins ago
Oh nice. yeah the state objects idea could help a lot I think. stackoverflow.com/questions/19702168/… here is a different thread that talks about it a little bit.
– Keizzerweiss
4 mins ago
Oh nice. yeah the state objects idea could help a lot I think. stackoverflow.com/questions/19702168/… here is a different thread that talks about it a little bit.
– Keizzerweiss
4 mins ago
add a comment |
Thanks for contributing an answer to Code Review Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
Use MathJax to format equations. MathJax reference.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f210089%2ffirst-pong-game%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown