patternpythonMinor
Pong game in Pygame
Viewed 0 times
pygamegamepong
Problem
This is my first time trying OOP and I definitely made many stylistic mistakes. Please tell me how I should improve.
Controls:
The player with higher score has shorter paddle. Once the difference in score is bigger than 7, the game quits.
```
import pygame
import random
YELLOW = (255, 255, 100)
BLUE = (50, 50, 255)
RED = (255, 50, 50)
BLACK = (0, 0, 0)
WHITE = (255,255,255)
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
PADDLE_HEIGHT = 100
done = False
class Ball(pygame.sprite.Sprite):
def __init__(self, x, y, xspeed, yspeed):
super().__init__()
self.image = pygame.Surface((16,16))
self.rect = self.image.get_rect()
self.x = x
self.y = y
self.rect.x = x
self.rect.y = y
pygame.draw.circle(self.image,YELLOW,(8,8),8)
self.speed_x = xspeed
self.speed_y = yspeed
self.deathcount_left = None
self.deathcount_right = None
self.walls = None
self.index = 0
def checkdeath(self):
if self.rect.xSCREEN_WIDTH:
self.deathcount_right.plus()
self.rect.x = self.x
self.rect.y = self.y
self.speed_x = random.randint(10,12)
self.speed_y = random.randint(10,12)
def update(self):
self.checkdeath()
self.rect.x += self.speed_x
wall_hit_list = pygame.sprite.spritecollide(self, self.walls, False)
if self.index == 1:
self.rect.y+=self.speed_y
self.index = 0
else:
if wall_hit_list:
self.speed_x = -self.speed_x
self.rect.y += self.speed_y
else:
self.rect.y += self.speed_y
wall_hit_list = pygame.sprite.spritecollide(self, self.walls, False)
if wall_hit_list:
self.speed_y = -self.speed_y
self.index=1
class Wall(pygame.sprit
Controls:
- w and s for player 1
- ↑ and ↓ for player 2
The player with higher score has shorter paddle. Once the difference in score is bigger than 7, the game quits.
```
import pygame
import random
YELLOW = (255, 255, 100)
BLUE = (50, 50, 255)
RED = (255, 50, 50)
BLACK = (0, 0, 0)
WHITE = (255,255,255)
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
PADDLE_HEIGHT = 100
done = False
class Ball(pygame.sprite.Sprite):
def __init__(self, x, y, xspeed, yspeed):
super().__init__()
self.image = pygame.Surface((16,16))
self.rect = self.image.get_rect()
self.x = x
self.y = y
self.rect.x = x
self.rect.y = y
pygame.draw.circle(self.image,YELLOW,(8,8),8)
self.speed_x = xspeed
self.speed_y = yspeed
self.deathcount_left = None
self.deathcount_right = None
self.walls = None
self.index = 0
def checkdeath(self):
if self.rect.xSCREEN_WIDTH:
self.deathcount_right.plus()
self.rect.x = self.x
self.rect.y = self.y
self.speed_x = random.randint(10,12)
self.speed_y = random.randint(10,12)
def update(self):
self.checkdeath()
self.rect.x += self.speed_x
wall_hit_list = pygame.sprite.spritecollide(self, self.walls, False)
if self.index == 1:
self.rect.y+=self.speed_y
self.index = 0
else:
if wall_hit_list:
self.speed_x = -self.speed_x
self.rect.y += self.speed_y
else:
self.rect.y += self.speed_y
wall_hit_list = pygame.sprite.spritecollide(self, self.walls, False)
if wall_hit_list:
self.speed_y = -self.speed_y
self.index=1
class Wall(pygame.sprit
Solution
This is a short and very incomplete list of some small things that could be done differently:
-
Be wary of initializing things to
Alternately, you could add to the constructor for
I'm hesitant to add any more for fear of misleading you, but OOP aside, some small stylistic notes:
-
Instead of using a nested if statement (
-
Be wary of initializing things to
None; it can produce some annoying bugs later on where Python yells at you for using a Nonetype where it expects something else:# In Ball
self.walls = pygame.sprite.Group()
self.deathcount_left = Score(...)
self.deathcount_right = Score(...)
...
# In Paddle
self.my_score = ball.deathcount_left
self.enemy_score = ball.deathcount_rightAlternately, you could add to the constructor for
Paddle to take in 2 Scores--yours and the enemy's.- Do you intend for anything other than
Paddleto inherit fromWall? If not, you don't needWallat all becauseWall.__init__is only ever called inPaddle.__init__. Though not totally necessary, you could do away withWalland copy over its constructor intoPaddle's, though some might cringe at the length of the result.
I'm hesitant to add any more for fear of misleading you, but OOP aside, some small stylistic notes:
- It's generally considered good practice to leave some sort of comment describing your classes/functions/etc., if only so that as your work expands you don't have to read code to figure out what a function does.
Ball.update:- You can move
self.rect.y += self.speed_yjust belowself.rect.x += self.speed_x--it occurs regardless of the condition.
-
Instead of using a nested if statement (
if self.index == 1 etc.) you can rewrite with elifif self.index == 1:
self.index = 0
elif wall_hit_list:
self.speed_x *= -1
else:
wall_hit_list = ...
if wall_hit_list:
self.speed_y *= -1
self.index = 1Code Snippets
# In Ball
self.walls = pygame.sprite.Group()
self.deathcount_left = Score(...)
self.deathcount_right = Score(...)
...
# In Paddle
self.my_score = ball.deathcount_left
self.enemy_score = ball.deathcount_rightif self.index == 1:
self.index = 0
elif wall_hit_list:
self.speed_x *= -1
else:
wall_hit_list = ...
if wall_hit_list:
self.speed_y *= -1
self.index = 1Context
StackExchange Code Review Q#96638, answer score: 5
Revisions (0)
No revisions yet.