import random
import pygame, sys
def ball_restart():
global ball_speed_x, ball_speed_y
ball.center = (screen_width/2, screen_height/2)
ball_speed_y *= random.choice((1,-1))
ball_speed_x *= random.choice((1,-1))
def ball_animation():
global ball_speed_x, ball_speed_y, player_score, opponent_score
#here is where it is defined
player_score = 0
opponent_score = 0
ball.x += ball_speed_x
ball.y += ball_speed_y
if ball.top <= 0 or ball.bottom >= screen_height:
ball_speed_y *= -1
if ball.left <= 0:
player_score += 1
ball_restart()
if ball.right >= screen_width:
opponent_score += 1
ball_restart()
if ball.colliderect(player) or ball.colliderect(opponent):
ball_speed_x *= -1
pygame.init()
clock = pygame.time.Clock()
screen_width = 1280
screen_height = 960
screen = pygame.display.set_mode((screen_width,screen_height))
pygame.display.set_caption("Pong")
ball = pygame.Rect(screen_width/2 - 15, screen_height/2 - 15, 30,30)
player = pygame.Rect(screen_width - 20, screen_height/2 - 70, 10,140)
opponent = pygame.Rect(10, screen_height/2 - 70, 10,140)
font = pygame.font.Font(None, 100)
# here is where the error comes up
player_score_surf = font.render(str(player_score), False, (10,10,10))
bg_color = pygame.Color("white")
black = pygame.Color("black")
ball_speed_x = 7
ball_speed_y = 7
player_speed = 0
opponent_speed = 7
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
player_speed -=7
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_DOWN:
player_speed +=7
if event.type == pygame.KEYUP:
if event.key == pygame.K_UP:
player_speed +=7
if event.type == pygame.KEYUP:
if event.key == pygame.K_DOWN:
player_speed -=7
ball_animation()
# Player
player.y += player_speed
if player.top <= 0:
player.top = 0
if player.bottom >= screen_height:
player.bottom = screen_height
# Opponent
if opponent.top < ball.y:
opponent.top += opponent_speed
if opponent.bottom > ball.y:
opponent.bottom -= opponent_speed
if opponent.top <= 0:
opponent.top = 0
if opponent.bottom >= screen_height:
opponent.bottom = screen_height
screen.fill(bg_color)
pygame.draw.rect(screen, black, player)
pygame.draw.rect(screen, black, opponent)
pygame.draw.ellipse(screen, black, ball)
pygame.draw.aaline(screen, black, (screen_width/2,0), (screen_width/2, screen_height))
screen.blit(player_score_surf, (200,200))
pygame.display.flip()
clock.tick(60)
Seems like in the meantime you have added parameters to that function ? That seems to change the game a bit.TypeError: ball_animation() missing 2 required positional arguments: 'player_score' and 'opponent_score'
player_score
before you call ball_animation()
so it has no value yet.def myfunc():
global player_score
player_score = 0
print(str(player_score))
def myfunc():
global player_score
player_score = 0
myfunc()
print(str(player_score))
If you're getting the missing positional arguments error, it means that you've also changed the actual ball_animation() function to now accept two parameters. This error is a good indicator that you're taking steps towards removing your use of globals (woop woop!)I tried doing that and this came up.
pygame 2.1.2 (SDL 2.0.18, Python 3.10.9)
Hello from the pygame community. https://www.pygame.org/contribute.html
Traceback (most recent call last):
File "C:\Users\qwegef\PycharmProjects\pygamegames\reference.py", line 78, in <module>
ball_animation()
TypeError: ball_animation() missing 2 required positional arguments: 'player_score' and 'opponent_score'
Process finished with exit code 1
For context I moved them right to the top of the code after the import random and import pygame code.
ball_animation()
take in two parameters (i.e. the player and opponent score), you'll also need to place those two values into any function call that happens.Yes. Although that wasn't actually the solution to the problem. Even if a global is on the global level, you still need to give it a value to avoid the 'not defined' error, as shows this code :If you're getting the missing positional arguments error, it means that you've also changed the actual ball_animation() function to now accept two parameters. This error is a good indicator that you're taking steps towards removing your use of globals (woop woop!)
global player_score
print(str(player_score))
Without a doubt, Python has never been a language I've been fond of, specifically when it comes to how it tries to be unique. Whenever I teach people about Python and how to use it, I'll always slide in the joke that "This is completely different to other languages because Python wants to be special".Yes. Although that wasn't actually the solution to the problem. Even if a global is on the global level, you still need to give it a value to avoid the 'not defined' error, as shows this code :
Python:global player_score print(str(player_score))
IMHO Python is really lame with this error message. If only it had been "Variable not initialized" this whole discussion would have been unnecessary. In Python speak, defining seems to be the same as initializing. Perhaps it makes sense as there is actually no syntax to declare a variable, like in any decent language. They just had to be different, didn't they 🍥
Without a doubt, Python has never been a language I've been fond of, specifically when it comes to how it tries to be unique. Whenever I teach people about Python and how to use it, I'll always slide in the joke that "This is completely different to other languages because Python wants to be special".
The only suitable time I'll use Python is in technical interviews where I need to get a solution as quickly as possible.
System.out.println
, and I am still baffled by their random differences in capitalization (toString
vs ToString
for example). Now that I hardly use Java anymore, I struggle not to write console.log()
in C# 😂# Do the imports
from random import choice
import pygame
# Initiate pygame
pygame.init()
# Setup pygame clock and frame rate
clock = pygame.time.Clock()
fps = 60
# Set screen size
screen_size = (1280, 960)
# Create the screen
screen = pygame.display.set_mode(screen_size)
# Create the window caption
pygame.display.set_caption('Pong')
# Empty list for players
players = []
# Create the player class
class Player:
'''
The player class needs x and y coords for posion
Computer is set for default name for pc player.
'''
def __init__(self, x, y, name='Computer'):
'''
Create player attributes. Create player surface,
x and y coords, name, score (default 0), player speed, get player rect,
and a starting direction.
append player to players list
'''
self.x = x
self.y = y
self.name = name
self.score = 0
self.speed = 7
self.direction = 1
players.append(self)
# Draw the player
def draw(self):
self.player = pygame.Rect(self.x, self.y, 10, 100)
self.rect = pygame.draw.rect(screen, 'black', self.player)
# Show player score
def show_score(self):
font = pygame.font.SysFont(None, 24)
text = font.render(f'{self.name}: {self.score}', True, 'white')
textRect = text.get_rect()
textRect.center = (self.x//2, 10,)
if self.name == 'Computer':
screen.blit(text, (textRect[0]+textRect[0]/2, 10))
else:
screen.blit(text, ((screen_size[0]/4)-textRect[0], 10))
# Update player movement
def update(self):
keys = pygame.key.get_pressed()
# If statement is for human player
if self.name != 'Computer':
if keys[pygame.K_UP]:
self.y -= self.speed
if self.y <= 40:
self.y = 40
if keys[pygame.K_DOWN]:
self.y += self.speed
if self.y >= screen_size[1] - 100:
self.y = screen_size[1] - 100
# Else for computer player
else:
self.y = self.y + self.speed * self.direction
if self.y <= 40:
self.y = 40
self.direction = 1
if self.y >= screen_size[1] - 100:
self.y = screen_size[1] - 100
self.direction = -1
# Create a Ball class
class Ball:
def __init__(self, x, y):
self.x = x
self.y = y
self.velocity = [5, 5]
self.hidden = False
self.hide_timer = pygame.time.get_ticks()
# Hide the ball and set timer if past boundry
def hide(self):
self.hidden = True
self.hide_timer = pygame.time.get_ticks()
# Draw the ball
def draw(self):
self.ball = pygame.Rect(self.x, self.y, 25, 25)
self.rect = pygame.draw.ellipse(screen, 'blue', self.ball)
# Define the ball animations
def animation(self):
# Resets the ball after 3 seconds
if self.hidden and pygame.time.get_ticks() - self.hide_timer > 3000:
self.hidden = False
self.x = screen_size[0]/2-12.5
self.y = screen_size[1]/2
# Set ball velocity for up and down
self.x -= self.velocity[0]
self.y += self.velocity[1]
# Right side of ball is less than 0, hide the ball
if self.ball.right+5 < 0:
self.hidden = True
# Left side of ball has passed screen width, hide ball
if self.ball.left > screen_size[0]+5:
self.hidden = True
self.x += self.velocity[0]
# Bounce ball off the top and bottom walls
if self.ball.top <= 40:
self.velocity[1] = 5
if self.ball.bottom >= screen_size[1]:
self.velocity[1] = -5
# Detect if ball hits player paddle
def collision(self, player):
if self.ball.colliderect(player):
if player.name == 'Computer':
self.velocity[0] = 5
else:
self.velocity[0] = -5
# Create the players. Player could be any name. Set to Player as not to have two Computer players
player1 = Player(10, screen_size[1]/2-50, 'Player')
player2 = Player(screen_size[0]-20, screen_size[1]/2-50)
ball = Ball(screen_size[0]/2-12.5, screen_size[1]/2)
running = True
while running:
screen.fill('white')
event = pygame.event.poll()
if event.type == pygame.QUIT:
running = False
# Create the dark area at top for holding score text
pygame.draw.rect(screen, pygame.Color(90,90,90), pygame.Rect(0, 0, screen_size[0], 40))
# The line in the middle
pygame.draw.aaline(screen, 'black', (screen_size[0]/2, 0), (screen_size[0]/2, screen_size[1]))
# Create and draw the ball
ball.draw()
ball.animation()
# Show all players, data, and updates
for player in players:
player.show_score()
player.draw()
player.update()
ball.collision(player)
pygame.display.flip()
clock.tick(60)
# Do the imports
from random import randint
import pygame
# Initiate pygame
pygame.init()
# Setup pygame clock and frame rate
clock = pygame.time.Clock()
fps = 60
# Set screen size
screen_size = (1280, 960)
# Create the screen
screen = pygame.display.set_mode(screen_size)
# Create the window caption
pygame.display.set_caption('Pong')
# Empty list for players
players = []
# Create the player class
class Player:
'''
The player class needs x and y coords for posion
Computer is set for default name for pc player.
'''
def __init__(self, x, y, name='Computer', ball_pos=0.0):
'''
Create player attributes. Create player surface,
x and y coords, name, score (default 0), player speed, get player rect,
and a starting direction.
append player to players list
'''
self.x = x
self.y = y
self.name = name
self.score = 0
self.speed = 7
self.direction = 1
self.ball_pos = ball_pos
players.append(self)
# Draw the player
def draw(self):
self.player = pygame.Rect(self.x, self.y, 10, 100)
self.rect = pygame.draw.rect(screen, 'black', self.player)
# Show player score
def show_score(self):
font = pygame.font.SysFont(None, 24)
text = font.render(f'{self.name}: {self.score}', True, 'white')
textRect = text.get_rect()
textRect.center = (self.x//2, 10,)
if self.name == 'Computer':
screen.blit(text, (textRect[0]+textRect[0]/2, 10))
else:
screen.blit(text, ((screen_size[0]/4)-textRect[0], 10))
# Update player movement
def update(self):
keys = pygame.key.get_pressed()
# If statement is for human player
# Moves paddle with up and down keys or w and s keys
if self.name != 'Computer':
if keys[pygame.K_UP] or keys[pygame.K_w]:
self.y -= self.speed
if self.y <= 40:
self.y = 40
if keys[pygame.K_DOWN] or keys[pygame.K_s]:
self.y += self.speed
if self.y >= screen_size[1] - 100:
self.y = screen_size[1] - 100
# Else for computer player
else:
# Set speed and direction of computer paddle
self.y = self.y + self.speed * self.direction
# Track ball position and move paddle toward ball if moving down to bottom
if self.y > self.ball_pos:
self.direction = -0.85
# Set boundry for bottom so paddle doesn't leave the playing field
if self.y >= screen_size[1] - 100:
self.y = screen_size[1] - 100
# Track ball position and move paddle toward ball if moving to top
if self.y < self.ball_pos:
self.direction = 0.85
# Set paddle boundry for top of field so paddle doesn't leave playing field
if self.y <= 40:
self.y = 40
# Create a Ball class
class Ball:
def __init__(self, x, y):
self.x = x
self.y = y
self.velocity = [5, 5]
# Draw the ball
def draw(self):
self.ball = pygame.Rect(self.x, self.y, 25, 25)
self.rect = pygame.draw.ellipse(screen, 'blue', self.ball)
# Define the ball animations
def animation(self):
# Set ball velocity for up and down
self.x -= self.velocity[0]
self.y += self.velocity[1]
# If left or right side of ball hits left or right boundry then bounce ball
# randint sets a random speed for ball after bounce
if self.ball.left <= 0:
self.velocity[0] = -randint(5, 8)
if self.ball.right >= screen_size[0]:
self.velocity[0] = randint(5, 8)
# Bounce ball off the top and bottom walls
if self.ball.top <= 40:
self.velocity[1] = randint(5, 8)
if self.ball.bottom >= screen_size[1]:
self.velocity[1] = -randint(5, 8)
# Detect if ball hits player paddle
def collision(self, player):
if self.ball.colliderect(player):
if player.name == 'Computer':
self.velocity[0] = randint(5,8)
else:
self.velocity[0] = -randint(5, 8)
# Create the players. Player could be any name.
# Default name is computer
# Set to Player as not to have two Computer players
player1 = Player(10, screen_size[1]/2-50, 'Player')
player2 = Player(screen_size[0]-20, screen_size[1]/2-50)
ball = Ball(screen_size[0]/2-12.5, screen_size[1]/2)
running = True
while running:
screen.fill('white')
event = pygame.event.poll()
if event.type == pygame.QUIT:
running = False
# Create the dark area at top for holding score text
pygame.draw.rect(screen, pygame.Color(90,90,90), pygame.Rect(0, 0, screen_size[0], 40))
# The line in the middle
pygame.draw.aaline(screen, 'black', (screen_size[0]/2, 0), (screen_size[0]/2, screen_size[1]))
# Create and draw the ball
ball.draw()
ball.animation()
# Show all players, data, and updates
for player in players:
player.show_score()
player.draw()
player.update()
ball.collision(player)
player.ball_pos = ball.y
if ball.x <= -5:
player2.score += 1
if ball.x >= screen_size[0]-20:
player1.score += 1
pygame.display.flip()
clock.tick(60)