Increase the ball speed as Pong game progress - python

I am writing a Pong clone and I want to make the game get harder as the game progress. For every point (or few points), increase the speed of the ball.
My code is as follows:
import pygame
import sys
import math
class Ball(object):
def __init__(self, x, y, width, height, vx, vy, colour):
self.x = x
self.y = y
self.width = width
self.height = height
self.vx = vx
self.vy = vy
self.colour = colour
def render(self, screen):
pygame.draw.ellipse(screen, self.colour, self.rect)
def update(self):
self.x += self.vx
self.y += self.vy
#property
def rect(self):
return pygame.Rect(self.x, self.y, self.width, self.height)
class Paddle(object):
def __init__(self, x, y, width, height, speed, colour):
self.x = x
self.y = y
self.width = width
self.height = height
self.vx = 0
self.speed = speed
self.colour = colour
def render(self, screen):
pygame.draw.rect(screen, self.colour, self.rect)
def update(self):
self.x += self.vx
def key_handler(self, event):
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
self.vx = -self.speed
elif event.key == pygame.K_RIGHT:
self.vx = self.speed
elif event.key in (pygame.K_LEFT, pygame.K_RIGHT):
self.vx = 0
#property
def rect(self):
return pygame.Rect(self.x, self.y, self.width, self.height)
class Pong(object):
COLOURS = {"BLACK": ( 0, 0, 0),
"WHITE": (255, 255, 255),
"RED" : (255, 0, 0)}
def __init__(self):
pygame.init()
(WIDTH, HEIGHT) = (640, 480)
self.screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("smach ball hit")
self.ball = Ball(5, 5, 50, 50, 5, 5, Pong.COLOURS["BLACK"])
self.paddle = Paddle(WIDTH / 2, HEIGHT - 50, 100,
10, 3, Pong.COLOURS["BLACK"])
self.score = 0
def play(self):
clock = pygame.time.Clock()
while True:
clock.tick(50)
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type in (pygame.KEYDOWN, pygame.KEYUP):
self.paddle.key_handler(event)
self.collision_handler()
self.draw()
def collision_handler(self):
if self.ball.rect.colliderect(self.paddle.rect):
self.ball.vy = -self.ball.vy
self.score += 1
if self.ball.x + self.ball.width >= self.screen.get_width():
self.ball.vx = -(math.fabs(self.ball.vx))
elif self.ball.x <= 0:
self.ball.vx = math.fabs(self.ball.vx)
if self.ball.y + self.ball.height >= self.screen.get_height():
pygame.quit()
sys.exit()
elif self.ball.y <= 0:
self.ball.vy = math.fabs(self.ball.vy)
if self.paddle.x + self.paddle.width >= self.screen.get_width():
self.paddle.x = self.screen.get_width() - self.paddle.width
elif self.paddle.x <= 0:
self.paddle.x = 0
def draw(self):
self.screen.fill(Pong.COLOURS["WHITE"])
font = pygame.font.Font(None, 48)
score_text = font.render("Score: " + str(self.score), True,
Pong.COLOURS["RED"])
self.screen.blit(score_text, (0, 0))
self.ball.update()
self.ball.render(self.screen)
self.paddle.update()
self.paddle.render(self.screen)
pygame.display.update()
if __name__ == "__main__":
Pong().play()
I am pretty new to programming and I don't know much of how it works. For the code that is already there, I had a friend who is more experienced to help me.

I suggest you to add one method that updates the ball speed depending on the score, and you can call it just after the collision detection (because there is where you increase the score). You can include a call to that method like this, inside your play method:
# (...) all your current code
self.collision_handler()
self.speed_up()
self.draw()
And, in the method implementation, you can divide your score, for example by 10, and add it as extra speed. Tweak this value to more or less, so it will fit your game better.
def speed_up(self):
delta = self.score // 10
if self.ball.vx > 0:
self.ball.vx += delta
else:
self.ball.vx -= delta
if self.ball.vy > 0:
self.ball.vy += delta
else:
self.ball.vy -= delta

Related

Pygame collisions is wierd [duplicate]

This question already has answers here:
Pygame: Collision by Sides of Sprite
(5 answers)
How can I rewrite my collision logic in my pygame platformer?
(1 answer)
Closed 16 days ago.
So Ive been at this one problem for more than a week now and i feel like Ive tried everything. Nothing works, Ive looked it up, but at the same time I don't want to just copy code i would like to actually understand it.
def x_collision(self):
for tile in tiles:
self.rect = pygame.Rect(self.x, self.y, self.size, self.size)
if tile.colliderect(self.rect):
if self.x_vel > 0:
self.x = tile.right
if self.x_vel < 0:
self.x = tile.left - self.size
def y_collision(self):
for tile in tiles:
self.rect = pygame.Rect(self.x, self.y, self.size, self.size)
if tile.colliderect(self.rect):
if self.y_vel > 0:
self.y = tile.bottom
if self.y_vel < 0:
self.y = tile.top
This is just the two main functions for the collision located inside the player class.
Ive gotten the collisions to work on each axis but when i merge the two together it just goes insane, I'm guessing this has something to do with the position of the player being set in the wrong place but that shouldn't be the problem considering im not checking for the collision in one function but instead in two different for each the x and y.
Just, it's probably because of some stupid reason and it shouldn't be that hard if you're not dumb like me but i just can't seem to figure it out
Also if you're testing the code just delete everything that has something to do with sound!
Here is the entire code for reference (i know it's messy but im very new to this so good luck!)
import pygame
import random
import math
import time
# Initialize Pygame
pygame.init()
pygame.mixer.init()
# Set the size of the window
size = (900, 600)
screen = pygame.display.set_mode(size)
# Set the title of the window
pygame.display.set_caption("Classes testing")
clock = pygame.time.Clock()
fps = 60
pygame.mixer.music.load('PewPewProject/Retro Platform.wav')
pygame.mixer.music.set_volume(0.1)
pygame.mixer.music.play(-1)
pop_sound = pygame.mixer.Sound("PewPewProject/vine-boom.wav")
pop_sound.set_volume(0.5)
level = [
['1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1'],
['1','E','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','1'],
['1','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','1'],
['1','0','0','0','0','0','0','0','0','0','0','0','0','0','0','E','0','0','0','1'],
['1','0','0','0','1','1','1','0','0','0','0','0','0','0','0','0','0','0','0','1'],
['1','0','0','0','0','1','0','0','0','0','0','0','0','0','0','0','0','0','0','1'],
['1','0','0','1','0','1','0','0','0','0','0','0','0','0','E','0','0','0','0','1'],
['1','0','0','1','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','1'],
['1','E','1','1','1','0','0','0','0','0','0','0','0','0','0','0','0','0','0','1'],
['1','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','1'],
['1','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','1'],
['1','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','1'],
['1','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','1'],
['1','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','1'],
['1','0','0','0','0','0','0','0','0','E','0','0','0','0','0','0','0','0','0','1'],
['1','0','0','0','0','0','0','0','0','1','1','1','0','1','0','0','0','0','0','1'],
['1','0','0','0','0','0','0','0','0','1','0','0','0','1','0','0','0','0','0','1'],
['1','0','0','0','0','0','0','0','0','1','0','1','1','1','0','E','0','0','0','1'],
['1','0','0','0','0','0','0','0','0','1','0','1','S','1','0','0','0','0','0','1'],
['1','0','0','0','0','0','0','0','0','1','0','0','0','1','0','0','0','0','0','1'],
['1','0','0','E','0','0','0','0','0','1','1','1','1','1','0','0','0','0','0','1'],
['1','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','1'],
['1','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','1'],
['1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1'],
]
tilex, tiley = [0, 0]
tilex_offset, tiley_offset = [0, 0]
tile_size = 50
tilemap = pygame.image.load('PewPewProject/tilemap.png')
tiles = []
collision_tiles = []
enemy_spawns = []
def build_level():
for tiley, rows in enumerate(level):
for tilex, tile in enumerate(rows):
if tile == '1':
tile_rect = pygame.Rect(tilex*tile_size+tilex_offset, tiley*tile_size+tiley_offset, tile_size, tile_size)
tiles.append(tile_rect)
elif tile == '0':
pass
elif tile == 'E':
enemy_spawns.append([tilex, tiley])
elif tile == 'S':
pass
elif tile == 'R':
pass
else:
print("Wrong Map Input")
def rebuild_level():
global tiles, enemy_spawns
tiles = []
enemy_spawns = []
build_level()
def draw_level():
for tiley, rows in enumerate(level):
for tilex, tile in enumerate(rows):
color = None
if tile == '1':
color = (100, 100, 100)
elif tile == 'S':
color = (50, 255, 100)
elif tile == 'R':
color = (255, 50, 50)
if color:
pygame.draw.rect(screen, color, (tilex*tile_size+tilex_offset, tiley*tile_size+tiley_offset, tile_size, tile_size))
def random_except(start, end, exception_start, exception_end):
num = random.randint(start, end)
while num >= exception_start and num <= exception_end:
num = random.randint(start, end)
return num
class Player:
def __init__(self, x, y):
global projectiles
self.speed = 5
self.x = x
self.y = y
self.x_vel = 0
self.y_vel = 0
self.px_vel = 0
self.py_vel = 0
self.size = tile_size
self.gunsurface = pygame.Surface((90, 25), pygame.SRCALPHA)
self.healthboost = 1
self.health = 100 * 1
self.rotated_gunsurface = self.gunsurface
self.gunsurface.fill((150, 150, 150))
self.gunrect = self.gunsurface.get_rect()
projectiles = [Projectile(-100, 0, 0)]
self.last_shot_time = 0
self.cooldown = 0.5
self.is_slowed = False
dx = 0
dy = 0
self.angle = math.atan2(dy, dx)
self.force = 72
self.forceCounterCuzIAmBadAtPython = self.force
self.rect = pygame.Rect(self.x, self.y, self.size, self.size)
self.alive = True
self.colliding = False
def x_collision(self):
for tile in tiles:
self.rect = pygame.Rect(self.x, self.y, self.size, self.size)
if tile.colliderect(self.rect):
if self.x_vel > 0:
self.x = tile.right
if self.x_vel < 0:
self.x = tile.left - self.size
def y_collision(self):
for tile in tiles:
self.rect = pygame.Rect(self.x, self.y, self.size, self.size)
if tile.colliderect(self.rect):
if self.y_vel > 0:
self.y = tile.bottom
if self.y_vel < 0:
self.y = tile.top
def Movement(self):
global tiley_offset, tilex_offset
self.keys = pygame.key.get_pressed()
tilex_offset += self.x_vel
self.x_collision()
if self.x_vel != 0:
self.x_vel -= self.px_vel
self.forceCounterCuzIAmBadAtPython -= 1
if self.forceCounterCuzIAmBadAtPython <= 0:
self.x_vel = 0
tiley_offset += self.y_vel
self.y_collision()
if self.y_vel != 0:
self.y_vel -= self.py_vel
if self.forceCounterCuzIAmBadAtPython <= 0:
self.y_vel = 0
rebuild_level()
def Alive(self):
if self.health <= 0:
self.alive = False
def GUI(self):
self.empty_health_bar = pygame.draw.rect(screen, (200, 20, 20), (screen.get_width()/4, 10,466, 25))
self.health_bar = pygame.draw.rect(screen, (20, 200, 20), (screen.get_width()/4, 10, self.health*4.66/self.healthboost, 25))
pygame.draw.line(screen, (0, 0, 0), (screen.get_width()/4, 10),(screen.get_width()/4+466, 10), 2)
pygame.draw.line(screen, (0, 0, 0), (screen.get_width()/4, 35),(screen.get_width()/4+466, 35), 2)
pygame.draw.line(screen, (0, 0, 0), (screen.get_width()/4, 10), (screen.get_width()/4, 35), 2)
pygame.draw.line(screen, (0, 0, 0), (screen.get_width()/4+466, 10), (screen.get_width()/4+466, 35), 2)
def Gun(self):
cursor_x, cursor_y = pygame.mouse.get_pos()
dx = cursor_x - (self.x + self.size)
dy = cursor_y - (self.y + self.size)
angle = math.atan2(dy, dx)
self.rotated_gunsurface = pygame.transform.rotate(self.gunsurface, math.degrees(angle * -1))
self.gunrect = self.rotated_gunsurface.get_rect(center = (self.x+self.size/2, self.y+self.size/2))
screen.blit(self.rotated_gunsurface, (self.gunrect.x, self.gunrect.y))
def Shoot(self):
global dx, dy
if pygame.key.get_pressed()[pygame.K_e]:
current_time = time.time()
if current_time - self.last_shot_time > self.cooldown:
self.forceCounterCuzIAmBadAtPython = self.force
pop_sound.play()
cursor_x, cursor_y = pygame.mouse.get_pos()
dx = cursor_x - (self.x + self.size/2)
dy = cursor_y - (self.y + self.size/2)
self.angle = math.atan2(dy, dx)
projectiles.append(Projectile(self.x+self.size/2, self.y+self.size/2, self.angle))
self.last_shot_time = current_time
self.x_vel = math.cos(self.angle) * self.speed
self.y_vel = math.sin(self.angle) * self.speed
self.px_vel = self.x_vel / self.force
self.py_vel = self.y_vel / self.force
def Render(self):
self.rect = pygame.Rect(self.x, self.y, self.size, self.size)
pygame.draw.rect(screen, (230, 100, 100), self.rect)
self.Gun()
class Projectile:
def __init__(self, x, y, angle):
self.x = x
self.y = y
self.angle = angle
self.speed = 8
self.hitbox = pygame.Rect(self.x, self.y, 5,5)
def Move(self):
self.x += math.cos(self.angle) * self.speed
self.y += math.sin(self.angle) * self.speed
def Render(self):
self.hitbox = pygame.draw.circle(screen, (255, 255, 0), (int(self.x), int(self.y)), 7)
class Enemy:
def __init__(self, health, main_speed, tag, size, player, x, y):
self.health = health
#self.main_speed = 3
self.tag = tag
self.size = size
self.player = player
self.speed = 3
self.x = x
self.y = y
self.alive = True
def Destroy(self):
self.alive = False
def Spawning(self):
self.hitbox = pygame.draw.rect(screen, (100, 240, 100), (self.x + tilex_offset, self.y + tiley_offset, self.size, self.size))
def Movement(self):
dx = self.player.x - self.x
dy = self.player.y - self.y
angle = math.atan2(dy - tiley_offset, dx - tilex_offset)
self.x += self.speed * math.cos(angle)
self.y += self.speed * math.sin(angle)
projectiles = [Projectile(-100, 0, 0)]
def main():
player = Player(screen.get_width()/2-tile_size/2, screen.get_height()/2-tile_size/2)
enemies = []
def Spawn_enemies(num_enemies, player):
for i in range(num_enemies):
x, y = random.choice(enemy_spawns)
enemy = Enemy(1, 1, i, 25, player, x*tile_size, y*tile_size)
enemies.append(enemy)
build_level()
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# Main Loop
screen.fill((100, 100, 200))
# usage
spawn_enemies_chance = random.randint(0, 250)
number_of_enemies = len(enemies)
if spawn_enemies_chance == 1 and number_of_enemies <= 4:
Spawn_enemies(1,player)
draw_level()
# enemy
for enemy in enemies:
if enemy.alive:
enemy.Movement()
enemy.Spawning()
for projectile in projectiles:
if enemy.hitbox.colliderect(projectile.hitbox):
enemy.health -= 1
pop_sound.play()
if enemy.health <= 0:
try:
enemy.alive = False
enemies.remove(enemy)
except:
print("list.remove(x): x not in list... Enemy moment")
projectiles.remove(projectile)
# Get Hurt
for enemy in enemies:
if enemy.hitbox.colliderect(player):
player.health -= 10
enemies.remove(enemy)
# Projectiles
for i, projectile in enumerate(projectiles):
projectile.Move()
projectile.Render()
if projectiles != []:
if projectile.x < 0 or projectile.x > screen.get_width() or projectile.y < 0 or projectile.y > screen.get_height():
projectiles.pop(i)
for tile in tiles:
if projectiles != []:
if tile.colliderect(projectile.hitbox):
try:
projectiles.pop(i)
except:
print(i," pop index out of range, don't mind it :)")
# player
player.Alive()
player.Shoot()
player.Movement()
player.Render()
# Renders the UI ontop of everything
player.GUI()
pygame.display.update()
clock.tick(fps)
pygame.quit()
# DO NOT DISTURB!
if __name__ == "__main__":
main()

Why does my pygame program slowdown, when I move my mouse?

So I am trying to program a pong game in pygame, python. Whenever I move my mouse fastly, the ball is slowing down. With my mouseposition, I move my paddle, so I need mouse motion. How can I fix this issue or what might be the problem? Am I doing something wrong? Appreciate any help, or feedback (I am beginner)
import pygame, random
WHITE = (255, 255, 255)
width = 1000
height = 600
window = pygame.display.set_mode((width, height))
pygame.display.set_caption("Pong Game")
Directions = ["negative", "positive"]
DirectionX = random.choice(Directions)
DirectionY = random.choice(Directions)
class classBall():
def __init__(self):
self.BallIMG = pygame.image.load("Ball.png")
self.X = width/2
self.Y = height/2
BallDisplay = window.blit(self.BallIMG, (self.X, self.Y))
self.Vel = 0.25
pass
def display(self):
global DirectionX, DirectionY
if 25 < self.X < 35 and PaddlePlayer.PosY-15 < self.Y < PaddlePlayer.PosY+115:
DirectionX = "positive"
if width-65 < self.X < width-55 and PaddleComp.PosY-15 < self.Y < PaddleComp.PosY+115:
DirectionX = "negative"
if 10 > self.Y:
DirectionY = "positive"
if height-10 < self.Y:
DirectionY = "negative"
if DirectionY == "positive":
self.Y += self.Vel
else:
self.Y -= self.Vel
if DirectionX == "positive":
self.X += self.Vel
else:
self.X -= self.Vel
BallDisplay = window.blit(self.BallIMG, (self.X, self.Y))
Ball = classBall()
class Paddle1Player():
def __init__(self):
self.PosY = height/2
self.PosX = 30
pygame.draw.rect(window, WHITE, [self.PosX, self.PosY, 5, 100])
def display(self):
x, MausPositionY = pygame.mouse.get_pos()
if not MausPositionY > height-100:
self.PosY = MausPositionY
pygame.draw.rect(window, WHITE, [30, self.PosY, 5, 100])
class Paddle2Computer():
def __init__(self):
self.PosY = height/2
self.PosX = width-35
pygame.draw.rect(window, WHITE, [self.PosX, self.PosY, 5, 100])
def display(self):
if Ball.X > width/2 and DirectionX == "positive":
if self.PosY < Ball.Y and DirectionY == "positive":
self.PosY+= Ball.Vel
elif self.PosY > Ball.Y and DirectionY == "negative":
self.PosY-= Ball.Vel
else:
if not height/2 -1 < self.PosY+25 < height/2:
if self.PosY+25 < height/2:
self.PosY+= Ball.Vel-Ball.Vel*3/10
else:
self.PosY-= Ball.Vel-Ball.Vel*3/10
pygame.draw.rect(window, WHITE, [width-35, self.PosY, 5, 100])
PaddlePlayer = Paddle1Player()
PaddleComp = Paddle2Computer()
running = True
pygame.display.flip()
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
window.fill((0,0,0))
Ball.display()
PaddlePlayer.display()
PaddleComp.display()
pygame.display.flip()
You want to be setting up a pygame.time.Clock() and in your event loop be calling clock.tick(60) (for 60fps).
Right now your loop is input-bound and not FPS-bound.
In Pygame, normalizing game-speed across different fps values
pygame clock.tick() vs framerate in game main loop

How to code bounce movement in pong using pygame

I'm a noob in python and I'm trying to recreate the Pong game, and I'm trying to do it by myself as much as possible.
These are the issues I currently have with my code:
I basically coded every possible movement of the ball when it bounces on the edge. I spent hours working on it, and I got it to work, I was just wondering if there was a more efficient way to produce a similar output with my code (coz I know this is supposed to be a beginner project)?
Every time the ball bounces past the edge, the score increments for a split second, and it goes back to 0 every time the ball respawns.
How can I make the ball spawn at random directions? at the start (and restart) of every round?
Here's my code for the class and the main function of the program:
import pygame
import random
from rect_button import Button
pygame.init()
WIDTH = 800
HEIGHT = 500
window = pygame.display.set_mode((WIDTH, HEIGHT))
TITLE = "Pong"
pygame.display.set_caption(TITLE)
# COLORS
black = (0, 0, 0)
white = (255, 255, 255)
red = (255, 0, 0)
green = (0, 255, 0)
# FONTS
small_font = pygame.font.SysFont("courier", 20)
large_font = pygame.font.SysFont("courier", 60, True)
class Paddle:
def __init__(self, x, y, width, height, vel, color):
self.x = x
self.y = y
self.width = width
self.height = height
self.vel = vel
self.color = color
def draw(self, window):
pygame.draw.rect(window, self.color, (self.x, self.y, self.width, self.height), 0)
class Ball:
def __init__(self, x, y, side, vel, color):
self.x = x
self.y = y
self.side = side
self.vel = vel
self.color = color
self.lower_right = False
self.lower_left = True
self.upper_right = False
self.upper_left = False
self.ball_bag = []
self.last_movement = 'ball.lower_right'
def draw(self, window):
pygame.draw.rect(window, self.color, (self.x, self.y, self.side, self.side), 0)
def move_lower_right(self):
self.x += self.vel
self.y += self.vel
def move_upper_right(self):
self.x += self.vel
self.y -= self.vel
def move_upper_left(self):
self.x -= self.vel
self.y -= self.vel
def move_lower_left(self):
self.x -= self.vel
self.y += self.vel
def start(self):
self.lower_right = True
self.lower_left = False
self.upper_right = False
self.upper_left = False
self.last_movement = 'ball.lower_left'
# return random.choice([self.lower_right, self.lower_left, self.upper_left, self.upper_right]) is True
def main():
run = True
fps = 60
clock = pygame.time.Clock()
# Initializing Paddles
left_paddle = Paddle(20, 100, 10, 50, 5, white)
right_paddle = Paddle(770, 350, 10, 50, 5, white)
balls = []
def redraw_window():
window.fill(black)
left_paddle.draw(window)
right_paddle.draw(window)
for ball in balls:
ball.draw(window)
player_A_text = small_font.render("Player A: " + str(score_A), 1, white)
player_B_text = small_font.render("Player B: " + str(score_B), 1, white)
window.blit(player_A_text, (320 - int(player_A_text.get_width() / 2), 10))
window.blit(player_B_text, (480 - int(player_B_text.get_width() / 2), 10))
pygame.draw.rect(window, white, (20, 450, 760, 1), 0)
pygame.draw.rect(window, white, (20, 49, 760, 1), 0)
pygame.draw.rect(window, white, (19, 50, 1, 400), 0)
pygame.draw.rect(window, white, (780, 50, 1, 400), 0)
pygame.display.update()
while run:
score_A = 0
score_B = 0
clock.tick(fps)
if len(balls) == 0:
ball = Ball(random.randrange(320, 465), random.randrange(200, 285), 15, 3, white)
balls.append(ball)
if ball.lower_left:
ball.move_lower_left()
if ball.last_movement == 'ball.lower_right':
if ball.y + ball.side > HEIGHT - 50:
ball.lower_left = False
ball.last_movement = 'ball.lower_left'
ball.upper_left = True
if ball.last_movement == 'ball.upper_left':
if ball.x < 30:
if left_paddle.x < ball.x < left_paddle.x + left_paddle.width:
if left_paddle.y < ball.y + ball.side < left_paddle.y + left_paddle.height:
ball.lower_left = False
ball.last_movement = 'ball.lower_left'
ball.lower_right = True
else:
score_B += 1
balls.remove(ball)
#ball.start()
if ball.y + ball.side > HEIGHT - 50:
ball.lower_left = False
ball.last_movement = 'ball.lower_left'
ball.upper_left = True
if ball.upper_left:
ball.move_upper_left()
if ball.last_movement == 'ball.lower_left':
if ball.x < 30:
if left_paddle.x < ball.x < left_paddle.x + left_paddle.width:
if left_paddle.y < ball.y + ball.side < left_paddle.y + left_paddle.height:
ball.upper_left = False
ball.last_movement = 'ball.upper_left'
ball.upper_right = True
else:
score_B += 1
balls.remove(ball)
#ball.start()
if ball.y < 50:
ball.upper_left = False
ball.last_movement = 'ball.upper_left'
ball.lower_left = True
if ball.last_movement == 'ball.upper_right':
if ball.y < 50:
ball.upper_left = False
ball.last_movement = 'ball.upper_left'
ball.lower_left = True
if ball.upper_right:
ball.move_upper_right()
if ball.last_movement == 'ball.upper_left':
if ball.y < 50:
ball.upper_right = False
ball.last_movement = 'ball.upper_right'
ball.lower_right = True
if ball.last_movement == 'ball.lower_right':
if ball.x + ball.side > WIDTH - 30:
if right_paddle.x + right_paddle.width > ball.x + ball.side > right_paddle.x:
if right_paddle.y < ball.y + ball.side < right_paddle.y + right_paddle.height:
ball.upper_right = False
ball.last_movement = 'ball.upper_right'
ball.upper_left = True
else:
score_A += 1
balls.remove(ball)
#ball.start()
if ball.y < 50:
ball.upper_right = False
ball.last_movement = 'ball.upper_right'
ball.lower_right = True
if ball.lower_right:
ball.move_lower_right()
if ball.last_movement == 'ball.upper_right':
if ball.y + ball.side > HEIGHT - 50:
ball.lower_right = False
ball.last_movement = 'ball.lower_right'
ball.upper_right = True
if ball.x + ball.side > WIDTH - 30:
if right_paddle.x + right_paddle.width > ball.x + ball.side > right_paddle.x:
if right_paddle.y < ball.y + ball.side < right_paddle.y + right_paddle.height:
ball.lower_right = False
ball.last_movement = 'ball.lower_right'
ball.lower_left = True
else:
score_A += 1
balls.remove(ball)
#ball.start()
if ball.last_movement == 'ball.lower_left':
if ball.y + ball.side > HEIGHT - 50:
ball.lower_right = False
ball.last_movement = 'ball.lower_right'
ball.upper_right = True
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
quit()
keys = pygame.key.get_pressed()
if keys[pygame.K_UP] and right_paddle.y > 50:
right_paddle.y -= right_paddle.vel
if keys[pygame.K_w] and left_paddle.y > 50:
left_paddle.y -= left_paddle.vel
if keys[pygame.K_DOWN] and right_paddle.y + right_paddle.height < HEIGHT - 50:
right_paddle.y += right_paddle.vel
if keys[pygame.K_s] and left_paddle.y + left_paddle.height < HEIGHT - 50:
left_paddle.y += left_paddle.vel
if keys[pygame.K_SPACE]:
pass
redraw_window()
quit()
def main_menu():
run = True
play_button = Button(green, 100, 350, 150, 75, "Play Pong")
quit_button = Button(red, 550, 350, 150, 75, "Quit")
pong_text = large_font.render("Let's Play Pong!!!", 1, black)
while run:
window.fill(white)
play_button.draw(window, black)
quit_button.draw(window, black)
window.blit(pong_text, (int(WIDTH / 2 - pong_text.get_width() / 2), 100))
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
quit()
if event.type == pygame.MOUSEMOTION:
if play_button.hover(pygame.mouse.get_pos()):
play_button.color = (0, 200, 0)
else:
play_button.color = green
if quit_button.hover(pygame.mouse.get_pos()):
quit_button.color = (200, 0, 0)
else:
quit_button.color = red
if event.type == pygame.MOUSEBUTTONDOWN:
if play_button.hover(pygame.mouse.get_pos()):
main()
if quit_button.hover(pygame.mouse.get_pos()):
run = False
quit()
main_menu()
Thanks!!!
Answer to
Every time the ball bounces past the edge, the score increments for a split second, and it goes back to 0 every time the ball respawns.
The score is continuously initialized in the main loop. You have to initialize the score before the loop:
def main():
# [...]
score_A = 0 # <--- INSERT
score_B = 0
while run:
# score_A = 0 <--- DELETE
# score_B = 0
Answer to question 1:
Yes. There is definitely a lot more effective way to do things. There is no need to make so many variables for direction. Simply say direction = [True, False], where direction[0] represents left and not direction[0] represents right in x-axis. Similarly, direction[1] represents y axis. This also solves your problem of randomizing the direction at start. You can simply do direction = [random.randint(0, 1), random.randint(0, 1)] in your init method to randomize the direction. The same way, make a list for speed as well. self.speed = [0.5, random.uniform(0.1, 1)]. This way, speed in left and right will always be same, but y will vary depending on the random number chosen, so there is proper randomness and you also don't have to hardcode random directions in. With this, movement becomes really simple.
class Ball:
def __init__(self, x, y, color, size):
self.x = x
self.y = y
self.color = color
self.size = size
self.direction = [random.randint(0, 1), random.randint(0, 1)]
self.speed = [0.5, random.uniform(0.1, 1)]
def draw(self, display):
pygame.draw.rect(display, self.color, (self.x, self.y, self.size, self.size))
def move(self):
if self.direction[0]:
self.x += self.speed[0]
else:
self.x -= self.speed[0]
if self.direction[1]:
self.y += self.speed[0]
else:
self.y -= self.speed[0]
Because we have defined direction directions are Booleans, changing the state also becomes really easy. If the ball hits the paddle, you can simply toggle the bool direction[0] = not direction[0] in x and pick a new random number for y, instead of manually assigning bools.
def switchDirection(self):
self.direction = not self.direction
self.speed[1] = random.uniform(0.1, 1)
Paddle can be improved slightly as well, by giving Paddle class a move function instead of moving in the main loop. It just means you have to write less code.
def move(self, vel, up=pygame.K_UP, down=pygame.K_DOWN):
keys = pygame.key.get_perssed()
if keys[up]:
self.y -= vel
if keys[down]:
self.y += vel
For collisions, I recommend using pygame.Rect() and colliderect since it's a lot more robust and probably more efficient as well.
Example:
import random
import pygame
WIN = pygame.display
D = WIN.set_mode((800, 500))
class Paddle:
def __init__(self, x, y, width, height, vel, color):
self.x = x
self.y = y
self.width = width
self.height = height
self.vel = vel
self.color = color
def move(self, vel, up=pygame.K_UP, down=pygame.K_DOWN):
keys = pygame.key.get_pressed()
if keys[up]:
self.y -= vel
if keys[down]:
self.y += vel
def draw(self, window):
pygame.draw.rect(window, self.color, (self.x, self.y, self.width, self.height), 0)
def getRect(self):
return pygame.Rect(self.x, self.y, self.width, self.height)
left_paddle = Paddle(20, 100, 10, 50, 5, (0, 0, 0))
right_paddle = Paddle(770, 350, 10, 50, 5, (0, 0, 0))
class Ball:
def __init__(self, x, y, color, size):
self.x = x
self.y = y
self.color = color
self.size = size
self.direction = [random.randint(0, 1), random.randint(0, 1)]
self.speed = [0.3, random.uniform(0.2, 0.2)]
def draw(self, window):
pygame.draw.rect(window, self.color, (self.x, self.y, self.size, self.size))
def switchDirection(self):
self.direction[0] = not self.direction[0]
self.direction[1] = not self.direction[1]
self.speed = [0.2, random.uniform(0.1, 0.5)]
def bounce(self):
self.direction[1] = not self.direction[1]
self.speed = [0.2, random.uniform(0.01, 0.2)]
def move(self):
if self.direction[0]:
self.x += self.speed[0]
else:
self.x -= self.speed[0]
if self.direction[1]:
self.y += self.speed[1]
else:
self.y -= self.speed[1]
def getRect(self):
return pygame.Rect(self.x, self.y, self.size, self.size)
def boundaries(self):
if ball.x <= 10:
self.switchDirection()
if ball.x + self.size >= 800:
self.switchDirection()
if ball.y + self.size >= 490:
self.bounce()
if ball.y <= 0:
self.bounce()
ball = Ball(400, 250, (255, 0, 0), 20)
while True:
pygame.event.get()
D.fill((255, 255, 255))
ball.draw(D)
ball.boundaries()
ball.move()
#print(ball.x, ball.y)
left_paddle.draw(D)
right_paddle.draw(D)
right_paddle.move(0.4)
left_paddle.move(0.4, down=pygame.K_s, up=pygame.K_w)
if left_paddle.getRect().colliderect(ball.getRect()):
ball.switchDirection()
if right_paddle.getRect().colliderect(ball.getRect()):
ball.switchDirection()
WIN.flip()
I basically coded every possible movement of the ball when it bounces on the edge. I spent hours working on it, and I got it to work, I was just wondering if there was a more efficient way to produce a similar output with my code (coz I know this is supposed to be a beginner project)?
and
How can I make the ball spawn at random directions? at the start (and restart) of every round?
Rather than implementing "every" direction of the ball you can use float coordinates. these variables are usualy called dx and dy.
This way getting a random or reversed direction for your ball is simple, just use random or inverse values for dx and dy.
Th update for your ball should then look like:
def update(self. dt):
self.x += self.dx * self.speed * time_elapsed
self.y += self.dy * self.speed * time_elapsed # Time elasped is often called dt.
Every time the ball bounces past the edge, the score increments for a split second, and it goes back to 0 every time the ball respawns.
See Rabid76's answer. Ideally you should have a GameState object with scores, lives and other stuff as attributes.
Some food for thought on how to reduce all that ball movement/collision code, and make things a bit more reusable:
import pygame
class Ball:
def __init__(self, bounds, color):
from random import randint, choice
self.bounds = bounds
self.position = pygame.math.Vector2(
randint(self.bounds.left, self.bounds.left+self.bounds.width),
randint(self.bounds.top, self.bounds.top+self.bounds.height)
)
self.velocity = pygame.math.Vector2(choice((-1, 1)), choice((-1, 1)))
self.color = color
self.size = 8
def draw(self, window):
pygame.draw.rect(
window,
self.color,
(
self.position.x-self.size,
self.position.y-self.size,
self.size*2,
self.size*2
),
0
)
def update(self):
self.position.x += self.velocity.x
self.position.y += self.velocity.y
if not self.bounds.left+self.size < self.position.x < self.bounds.left+self.bounds.width-self.size:
self.velocity.x *= -1
if not self.bounds.top+self.size < self.position.y < self.bounds.top+self.bounds.height-self.size:
self.velocity.y *= -1
def main():
from random import randint
window_width, window_height = 800, 500
window = pygame.display.set_mode((window_width, window_height))
pygame.display.set_caption("Pong")
clock = pygame.time.Clock()
black = (0, 0, 0)
white = (255, 255, 255)
padding = 20
bounds = pygame.Rect(padding, padding, window_width-(padding*2), window_height-(padding*2))
ball = Ball(bounds, white)
def redraw_window():
window.fill(black)
pygame.draw.rect(
window,
white,
(
padding,
padding,
window_width-(padding*2),
window_height-(padding*2)
),
1
)
ball.draw(window)
pygame.display.update()
while True:
clock.tick(60)
ball.update()
for event in pygame.event.get():
if event.type == pygame.QUIT:
break
else:
redraw_window()
continue
break
pygame.quit()
return 0
if __name__ == "__main__":
import sys
sys.exit(main())
This isn't a complete drop-in replacement, I've just reimplemented the Ball class. There are no paddles. Essentially, when instantiating a ball, you pass in a pygame.Rect, which describes the bounds in which the ball is allowed to bounce around in. You also pass in a color tuple. The ball then picks a random position within the bounds (the position is a pygame.math.Vector2, as opposed to storing x and y as separate instance variables). A ball also has a velocity, which is also a pygame.math.Vector2, so that you may have independent velocity components - one for x (horizontal velocity) and one for y (vertical velocity). The size of a ball simply describes the dimensions of the ball. If the size is set to 8, for example, then a ball will be 16x16 pixels.
The Ball class also has an update method, which is invoked once per game-loop iteration. It moves the ball to the next position dictated by the velocity, and checks to see if the ball is colliding with the bounds. If it is, reverse the corresponding velocity component.

Shooting tank bullet in python/pygame

I'm working on python project right now using pygame library and I need help with this project I make. I want my tank to shoot bullets and so those bullets ricochet from the walls. What is the best way possible to do this?
I'm sorry that my code looks so messy, I've been watching different youtube tutorials and they all do differently.
Here is my code
import pygame
pygame.init()
# ======================= Variables =======================
# ------------------------ Screen -------------------------
screenWidth = 1060
screenHeight = 798
screenSize = (screenWidth, screenHeight)
display = pygame.display.set_mode((screenWidth, screenHeight))
pygame.display.set_caption("Tank game")
bg = pygame.image.load("sprites/background/background1.png")
bg = pygame.transform.scale(bg, (screenWidth, screenHeight))
# ------------------------ Player -------------------------
# ------------------------ Enemy -------------------------
# ----------------------- Other ---------------------------
red = (155, 0, 0)
clock = pygame.time.Clock()
fps = 60
# ========================= Clases ========================
class player(pygame.sprite.Sprite):
def __init__(self, location, angle, vel, x, y):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load("sprites/player/player_tank.png")
self.x = x
self.y = y
self.vel = vel
self.angle = angle
self.rect = self.image.get_rect()
self.rect.left, self.rect.top = location
if self.angle == 360:
self.angle = 0
def rotate(self):
rot_image = pygame.transform.rotate(self.image, self.angle)
rot_rect = rot_image.get_rect(center=self.rect.center)
return rot_image, rot_rect
def moving_after_angle_change(self):
x = round(math.cos(math.radians(self.angle + 90)), 1) * self.vel
y = round(math.sin(math.radians(self.angle - 90)), 1) * self.vel
return x, y
class enemy(pygame.sprite.Sprite):
def __init__(self, x, y, width, height, end):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load("sprites/enemy/enemy_tank.png")
self.x = x
self.y = y
self.width = width
self.height = height
self.end = end
self.path = [self.x, self.y, self.end]
self.vel = 5
def draw(self, display):
self.move()
display.blit(self.image, (self.x, self.y))
def move(self):
if self.vel > 0:
pass
# Bullet
bullet = pygame.image.load("sprites/bullet/bullet.png")
bullet = pygame.transform.scale(bullet, (16, 16))
bullet_x = 0
bullet_y = 480
bullet_x_change = 0
bullet_y_change = 10
bullet_state = 'ready'
# ======================= Functions =======================
def redrawGameWindow():
display.blit(bg, (0, 0))
display.blit(player_tank.image, player_tank.rect)
display.blit(enemy_tank.image, (enemy_tank.x, enemy_tank.y))
#display.blit(bullet, (player_tank.x + 160, player_tank.y + 100))
pygame.display.flip()
def fireBullet(x, y):
global bullet_state
bullet_state = 'fire'
display.blit(bullet, (x + 16, y + 10))
player_location = [70, 570]
player_angle = 270
player_angle_change = 0
player_vel = 0
player_x_change = 0
player_y_change = 0
player_tank_x_change_store = 0
player_tank_y_change_store = 0
run = True
while run:
clock.tick(fps)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
player_vel = 2
elif event.key == pygame.K_DOWN:
player_vel = -2
elif event.key == pygame.K_LEFT:
player_angle_change = 2
elif event.key == pygame.K_RIGHT:
player_angle_change = -2
if event.key == pygame.K_SPACE:
display.blit(bullet, (player_tank.x + 160, player_tank.y + 100))
if event.type == pygame.KEYUP:
if event.key == pygame.K_UP:
player_vel = 0
elif event.key == pygame.K_DOWN:
player_vel = 0
elif event.key == pygame.K_LEFT:
player_angle_change = 0
elif event.key == pygame.K_RIGHT:
player_angle_change = 0
player_angle += player_angle_change
player_tank = player(player_location, player_angle, player_vel, player_x_change, player_y_change)
enemy_tank = enemy(800, 170, 64, 64, 700)
player_tank.image, player_tank.rect = player_tank.rotate()
player_tank.x_change, player_tank.y_change = player_tank.moving_after_angle_change()
player_tank_x_change_store += player_tank.x_change
player_tank_y_change_store += player_tank.y_change
player_tank.rect.centerx += player_tank_x_change_store
player_tank.rect.centery += player_tank_y_change_store
# Bullet movement
if bullet_state == "fire":
fireBullet(player_tank.x, bullet_y)
bullet_y -= bullet_y_change
redrawGameWindow()
pygame.quit()
quit()
One way to do this is to make the bullets velocity flip when it hits a wall. Now I'm assuming the walls are the edge of the screen so what you need to do is in the loop, check if the bullet is about to hit a wall (the edge of the screen) and if it is, flip its x_change and y_change. So something like this:
if bullet_y <= 0:
bullet_y_change *= -1
bullet_y = 0
if bullet_y >= screenHeight:
bullet_y_change *= -1
bullet_y = screenHeight
if bullet_x <= 0:
bullet_x_change *= -1
bullet_x = 0
if bullet_x >= screenWidth:
bullet_x_change *= 1
bullet_x = screenWidth
Here's a full example, based on an old answer:
import pygame
class Player(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = pygame.Surface((32, 32))
self.image.fill((0, 0, 0))
self.image.set_colorkey((0, 0, 0))
pygame.draw.polygon(self.image, pygame.Color('dodgerblue'), ((0, 0), (32, 16), (0, 32)))
self.org_image = self.image.copy()
self.angle = 0
self.direction = pygame.Vector2(1, 0)
self.rect = self.image.get_rect(center=(200, 200))
self.pos = pygame.Vector2(self.rect.center)
def update(self, events, dt):
for e in events:
if e.type == pygame.KEYDOWN:
if e.key == pygame.K_SPACE:
self.groups()[0].add(Projectile(self.rect.center, self.direction.normalize()))
pressed = pygame.key.get_pressed()
if pressed[pygame.K_a]:
self.angle += 3
if pressed[pygame.K_d]:
self.angle -= 3
self.direction = pygame.Vector2(1, 0).rotate(-self.angle)
self.image = pygame.transform.rotate(self.org_image, self.angle)
self.rect = self.image.get_rect(center=self.rect.center)
class Projectile(pygame.sprite.Sprite):
def __init__(self, pos, direction):
super().__init__()
self.image = pygame.Surface((8, 8))
self.image.fill((0, 0, 0))
self.image.set_colorkey((0, 0, 0))
pygame.draw.circle(self.image, pygame.Color('orange'), (4, 4), 4)
self.rect = self.image.get_rect(center=pos)
self.direction = direction
self.pos = pygame.Vector2(self.rect.center)
self.lives = 15
def update(self, events, dt):
# Bounding box of the screen
screen_r = pygame.display.get_surface().get_rect()
# where we would move next
next_pos = self.pos + self.direction * dt
# we hit a hall
if not screen_r.contains(self.rect):
# after 15 hits, destroy self
self.lives -= 1
if self.lives == 0:
return self.kill()
# horizontal reflection
if next_pos.x > screen_r.right or next_pos.x < screen_r.left:
self.direction.x *= -1
# vertical reflection
if next_pos.y > screen_r.bottom or next_pos.y < screen_r.top:
self.direction.y *= -1
# move after applying reflection
next_pos = self.pos + self.direction * dt
# set the new position
self.pos = next_pos
self.rect.center = self.pos
def main():
pygame.init()
screen = pygame.display.set_mode((500, 500))
sprites = pygame.sprite.Group(Player())
clock = pygame.time.Clock()
dt = 0
while True:
events = pygame.event.get()
for e in events:
if e.type == pygame.QUIT:
return
sprites.update(events, dt)
screen.fill((30, 30, 30))
sprites.draw(screen)
pygame.display.update()
dt = clock.tick(60)
if __name__ == '__main__':
main()
See how using the Vector2 class makes this kind of tasks very easy to solve.
Also, look at the proper usage of the Sprite class. Each Sprite minds its own business: the Player class handles rotating the player and creating projectiles, Projectile handles moving the projectiles and bouncing of the wall.

TypeError: argument 1 must be pygame.Surface, not str

I have a problem, I made a Pong game but I have a problem printing the score to the pygame window.
I get the error 'TypeError: argument 1 must be pygame.Surface, not str
I blit the text but get an error
I know the code is a mess, I'll fix it later
import pygame
from pygame.locals import *
from random import randint
import random
import time
pygame.display.set_caption("PONG!")
myimage = pygame.image.load("lose.png")
middle = pygame.image.load("middle.png")
pygame.init()
screensize = (640,480)
screen = pygame.display.set_mode(screensize)
clock = pygame.time.Clock()
PlayerProp = 0
AiProp = 0
Score = str(PlayerProp)
AiScore = str(AiProp)
game = True
while game == True:
class pong_:
def __init__(self, screensize):
self.screensize = screensize
self.centerx = int(screensize[0]*0.5)
self.centery = int(screensize[1]*0.5)
self.radius = 8
self.rect = pygame.Rect(self.centerx-self.radius,
self.centery-self.radius,
self.radius*2, self.radius*2)
self.color = (255,255,255)
self.direction = [1,1]
self.speedx = 3
self.speedy = 4
#CODE TASK: change speed as game progresses to make it harder mwahaha
self.hit_edge_left = False
self.hit_edge_right = False
def update(self, player_paddle, ai_paddle):
self.centerx += self.direction[0]*self.speedx
self.centery += self.direction[1]*self.speedy
self.rect.center = (self.centerx, self.centery)
#Make new random for each -1
if self.rect.top <= 0:
self.direction[1] = 1
elif self.rect.bottom >= self.screensize[1]-1:
self.direction[1] = -1
if self.rect.right >= self.screensize[0]-1:
self.hit_edge_right = True
elif self.rect.left <= 0:
self.hit_edge_left = True
if self.rect.colliderect(player_paddle.rect):
self.direction[0] = random.randrange(-2, -1)
if self.rect.colliderect(ai_paddle.rect):
self.direction[0] = random.randrange(2, 3)
def render(self, screen):
pygame.draw.circle(screen, self.color, self.rect.center, self.radius, 0)
pygame.draw.circle(screen, (0,0,0), self.rect.center, self.radius, 1)
class AIPaddle(object):
def __init__(self, screensize):
self.screensize = screensize
self.centerx = 4
self.centery = int(screensize[1]*0.5)
self.height = 100
self.width = 10
self.rect = pygame.Rect(0, self.centery-int(self.height*0.5), self.width, self.height)
self.color = (255,255,255)
#CODE TASK: Adjust size of AI paddle as match progresses to make it more difficult
self.speed = random.randrange(3, 4)
def update(self, pong):
if pong.rect.top < self.rect.top:
self.centery -= self.speed
elif pong.rect.bottom > self.rect.bottom:
self.centery += self.speed
self.rect.center = (self.centerx, self.centery)
def render(self, screen):
pygame.draw.rect(screen, self.color, self.rect, 0)
pygame.draw.rect(screen, (0,0,0), self.rect, 1)
class PlayerPaddle(object):
def __init__(self, screensize):
self.screensize = screensize
self.centerx = screensize[0]-5
self.centery = int(screensize[1]*0.5)
self.height = 100
self.width = 10
self.rect = pygame.Rect(0, self.centery-int(self.height*0.5), self.width, self.height)
self.color = (255,255,255)
#CODE TASK: Adjust size of player paddle as match progresses to make it more difficult
self.speed = 3
self.direction = 0
def update(self):
self.centery += self.direction*self.speed
self.rect.center = (self.centerx, self.centery)
if self.rect.top < 0:
self.rect.top = 0
if self.rect.bottom > self.screensize[1]-1:
self.rect.bottom = self.screensize[1]-1
def render(self, screen):
pygame.draw.rect(screen, self.color, self.rect, 0)
pygame.draw.rect(screen, (0,0,0), self.rect, 1)
def main():
pygame.init()
pong = pong_(screensize)
ai_paddle = AIPaddle(screensize)
player_paddle = PlayerPaddle(screensize)
running = True
while running:
#fps limit
clock.tick(64)
#big boy event handling
for event in pygame.event.get():
if event.type == QUIT:
running = False
if event.type == KEYDOWN:
if event.key == K_UP:
player_paddle.direction = -1
elif event.key == K_DOWN:
player_paddle.direction = 1
if event.type == KEYUP:
if event.key == K_UP and player_paddle.direction == -1:
player_paddle.direction = 0
if event.key == K_DOWN and player_paddle.direction == 1:
player_paddle.direction = 0
#object updates
ai_paddle.update(pong)
player_paddle.update()
pong.update(player_paddle, ai_paddle)
screen.fill((0,0,0))
screen.blit(middle, (0,0))
screen.blit(AiScore, (0,0))
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
basicFont = pygame.font.SysFont(None, 48)
#CODE TASK: Make some text on the screen over everything
#code task 2: Make game restart?
if pong.hit_edge_left:
print('You Won!')
running = False
elif pong.hit_edge_right:
print('You lose')
running = False
#rendering phase
ai_paddle.render(screen)
player_paddle.render(screen)
pong.render(screen)
pygame.display.flip()
main()
Use basicFont.render(...) to create surface with text. Then blit that surface.
https://www.pygame.org/docs/ref/font.html#pygame.font.Font.render
btw: don't define classes and main() inside while game:. You don't have to. Put it outside while game:

Categories

Resources