Skip to content

Commit a488917

Browse files
committed
add pong game with bot opponent tutorial
1 parent bcd7d81 commit a488917

File tree

8 files changed

+199
-0
lines changed

8 files changed

+199
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,7 @@ This is a repository of all the tutorials of [The Python Code](https://www.thepy
304304
- [How to Make a Maze Game in Python](https://www.thepythoncode.com/article/build-a-maze-game-in-python). ([code](gui-programming/maze-game))
305305
- [How to Create a Platformer Game in Python](https://www.thepythoncode.com/article/platformer-game-with-pygame-in-python). ([code](gui-programming/platformer-game))
306306
- [How to Make a Flappy Bird Game in Python](https://thepythoncode.com/article/make-a-flappy-bird-game-python). ([code](gui-programming/flappy-bird-game))
307+
- [How to Create a Pong Game in Python](https://thepythoncode.com/article/build-a-pong-game-in-python). ([code](gui-programming/pong-game))
307308

308309

309310
For any feedback, please consider pulling requests.

gui-programming/pong-game/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# [How to Create a Pong Game in Python](https://thepythoncode.com/article/build-a-pong-game-in-python)

gui-programming/pong-game/ball.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import pygame, sys
2+
import random
3+
from settings import WIDTH, HEIGHT
4+
5+
pygame.init()
6+
7+
class Ball:
8+
def __init__(self, x, y, radius):
9+
self.x = x
10+
self.y = y
11+
self.radius = radius
12+
self.rect = pygame.Rect(self.x, self.y, radius, radius)
13+
self.color = pygame.Color("red")
14+
self.direction = None
15+
self.speed_x = 0
16+
self.speed_y = 0
17+
self._random_direction()
18+
19+
def _random_direction(self):
20+
direction = ("right", "left")
21+
self.direction = random.choice(direction)
22+
23+
def _ball_movement(self):
24+
# horizontal handling
25+
if self.direction == "right":
26+
self.speed_x = 18
27+
else:
28+
self.speed_x = -18
29+
30+
# vertical handling
31+
if self.rect.y >= HEIGHT - self.radius:
32+
self.speed_y = -18
33+
elif self.rect.y <= 0 + self.radius:
34+
self.speed_y = 18
35+
36+
# wall bounce handling
37+
self.rect.x += self.speed_x
38+
self.rect.y += self.speed_y
39+
40+
def update(self, screen):
41+
self._ball_movement()
42+
pygame.draw.rect(screen, self.color, self.rect)

gui-programming/pong-game/main.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import pygame, sys
2+
from settings import WIDTH, HEIGHT
3+
from table import Table
4+
5+
pygame.init()
6+
7+
screen = pygame.display.set_mode((WIDTH, HEIGHT))
8+
pygame.display.set_caption("Ping Pong")
9+
10+
class Pong:
11+
def __init__(self, screen):
12+
self.screen = screen
13+
self.FPS = pygame.time.Clock()
14+
15+
def draw(self):
16+
pygame.display.flip()
17+
18+
def main(self):
19+
# start menu here
20+
table = Table(self.screen) # pass to table the player_option saved to table.game_mode
21+
while True:
22+
self.screen.fill("black")
23+
24+
for event in pygame.event.get():
25+
if event.type == pygame.QUIT:
26+
pygame.quit()
27+
sys.exit()
28+
29+
table.player_move()
30+
table.update()
31+
self.draw()
32+
self.FPS.tick(30)
33+
34+
35+
if __name__ == "__main__":
36+
play = Pong(screen)
37+
play.main()

gui-programming/pong-game/player.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import pygame
2+
3+
class Player:
4+
def __init__(self, x, y, width, height):
5+
self.x = x
6+
self.y = y
7+
self.rect = pygame.Rect(self.x, self.y, width, height)
8+
self.color = pygame.Color("gray")
9+
self.player_speed = 16
10+
11+
self.score = 0
12+
13+
def move_up(self):
14+
self.rect.y -= self.player_speed
15+
16+
def move_bottom(self):
17+
self.rect.y += self.player_speed
18+
19+
def update(self, screen):
20+
pygame.draw.rect(screen, self.color, self.rect)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pygame

gui-programming/pong-game/settings.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
WIDTH, HEIGHT = 990, 450
2+
3+
player_width, player_height = 20, 90

gui-programming/pong-game/table.py

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
import pygame, time
2+
import sys
3+
from player import Player
4+
from ball import Ball
5+
from settings import WIDTH, HEIGHT, player_width, player_height
6+
7+
class Table:
8+
def __init__(self, screen):
9+
self.screen = screen
10+
self.game_over = False
11+
self.score_limit = 10
12+
self.winner = None
13+
self._generate_world()
14+
15+
# text info
16+
self.font = pygame.font.SysFont('Bauhaus 93', 60)
17+
self.inst_font = pygame.font.SysFont('Bauhaus 93', 30)
18+
self.color = pygame.Color("white")
19+
20+
# create and add player to the screen
21+
def _generate_world(self):
22+
self.playerA = Player(0, HEIGHT // 2 - (player_height // 2), player_width, player_height)
23+
self.playerB = Player(WIDTH - player_width, HEIGHT // 2 - (player_height // 2), player_width, player_height)
24+
self.ball = Ball(WIDTH // 2 - player_width, HEIGHT - player_width, player_width)
25+
26+
def _ball_hit(self):
27+
# if ball is not hit by a player and pass through table sides
28+
if self.ball.rect.left >= WIDTH:
29+
self.playerA.score += 1
30+
self.ball.rect.x = WIDTH // 2
31+
time.sleep(1)
32+
elif self.ball.rect.right <= 0:
33+
self.playerB.score += 1
34+
self.ball.rect.x = WIDTH // 2
35+
time.sleep(1)
36+
37+
# if ball land in the player
38+
if pygame.Rect.colliderect(self.ball.rect, self.playerA.rect):
39+
self.ball.direction = "right"
40+
if pygame.Rect.colliderect(self.ball.rect, self.playerB.rect):
41+
self.ball.direction = "left"
42+
43+
def _bot_opponent(self):
44+
if self.ball.direction == "left" and self.ball.rect.centery != self.playerA.rect.centery:
45+
if self.ball.rect.top <= self.playerA.rect.top:
46+
if self.playerA.rect.top > 0:
47+
self.playerA.move_up()
48+
if self.ball.rect.bottom >= self.playerA.rect.bottom:
49+
if self.playerA.rect.bottom < HEIGHT:
50+
self.playerA.move_bottom()
51+
52+
def player_move(self):
53+
keys = pygame.key.get_pressed()
54+
55+
# for bot opponent controls
56+
self._bot_opponent()
57+
58+
# for player controls
59+
if keys[pygame.K_UP]:
60+
if self.playerB.rect.top > 0:
61+
self.playerB.move_up()
62+
if keys[pygame.K_DOWN]:
63+
if self.playerB.rect.bottom < HEIGHT:
64+
self.playerB.move_bottom()
65+
66+
def _show_score(self):
67+
A_score, B_score = str(self.playerA.score), str(self.playerB.score)
68+
A_score = self.font.render(A_score, True, self.color)
69+
B_score = self.font.render(B_score, True, self.color)
70+
self.screen.blit(A_score, (WIDTH // 4, 50))
71+
self.screen.blit(B_score, ((WIDTH // 4) * 3, 50))
72+
73+
def _game_end(self):
74+
if self.winner != None:
75+
print(f"{self.winner} wins!!")
76+
pygame.quit()
77+
sys.exit()
78+
79+
def update(self):
80+
self._show_score()
81+
82+
self.playerA.update(self.screen)
83+
self.playerB.update(self.screen)
84+
85+
self._ball_hit()
86+
87+
if self.playerA.score == self.score_limit:
88+
self.winner = "Opponent"
89+
90+
elif self.playerB.score == self.score_limit:
91+
self.winner = "You"
92+
93+
self._game_end()
94+
self.ball.update(self.screen)

0 commit comments

Comments
 (0)