I am making pong in pygame, and I currently have both paddles and their movements done. I am trying to create the ball, but when the ball is rendered on the screen it is as a rectangle, not a circle. Here is my code:
import pygame
pygame.init()
from pygame.locals import (
K_UP,
K_DOWN,
K_s,
K_w,
QUIT
)
class Ball(pygame.sprite.Sprite):
def __init__(self, color, left, top): # circle is getting drawn in this constructor
pygame.sprite.Sprite.__init__(self)
radius = 40
self.surface = pygame.Surface((radius, radius))
self.surface.fill(color)
self.rect = pygame.draw.circle(self.surface, color, (left, top), radius)
self.rect.update(left, top, radius, radius)
# a temporary implementation of the move function that keeps the ball displayed on the screen
def move(self, screen):
screen.blit(self.surface, self.rect, self.rect)
screen.blit(self.surface, self.rect)
class Paddle(pygame.sprite.Sprite):
# initializes the paddle surface, rect, pos_y
def __init__(self, color, left, top):
pygame.sprite.Sprite.__init__(self)
width, height = 40, 120
self.surface = pygame.Surface((width, height))
self.surface.fill(color)
self.rect = self.surface.get_rect()
self.rect.update(left, top, width, height)
self.pos_y = self.rect.top
# updates the paddles position based on key presses
def move(self, pressed_keys, keys, screen):
dy = 0
screen.blit(self.surface, self.rect, self.rect)
l_bound, u_bound = 5, 750 - self.rect.height - 5
if pressed_keys[keys[0]] and self.rect.top > l_bound:
dy = -.2
if pressed_keys[keys[1]] and self.rect.top < u_bound:
dy = .2
self.pos_y += dy
self.rect.top = self.pos_y
screen.blit(self.surface, self.rect)
class Main:
def __init__(self):
self.height, self.width = 750, 1000
self.screen = pygame.display.set_mode((self.width, self.height))
pygame.display.set_caption("pong")
self.loop()
def loop(self):
blue = [0, 0, 255]
red = [255, 0, 0]
# create the paddles and the ball
paddle1 = Paddle(blue, 30, 30)
paddle2 = Paddle(blue, 930, 30)
ball = Ball(red, self.width // 2, self.height // 2)
# the buffer (I think) expands the area updated at the end of the game loop so that it can delete where the old rectangle was and change where the new rectangle is, but I'm not 100% sure
BUFFER = .01
running = True
while running:
self.screen.fill([0, 0, 0])
for event in pygame.event.get():
if event.type == QUIT:
running = False
pressed_keys = pygame.key.get_pressed()
paddle1.move(pressed_keys, [K_w, K_s], self.screen)
paddle2.move(pressed_keys, [K_UP, K_DOWN], self.screen)
ball.move(self.screen)
update_rect1 = pygame.Rect(30, paddle1.rect.top - BUFFER, 40, paddle1.rect.top + 150 + BUFFER)
update_rect2 = pygame.Rect(930, paddle2.rect.top - BUFFER, 40, paddle2.rect.top + 150 + BUFFER)
pygame.display.update([update_rect1, update_rect2, ball.rect])
pygame.quit()
Main()
I've seen this approach to drawing circles online:
pygame.draw.circle(screen, (0,0,255), (150, 50), 15, 1)
The problem with that is I need an intermediary surface to use when I blit onto the screen, such as with this line of code when I blit the paddle, in this case that surface is self.surface:
screen.blit(self.surface, self.rect)
Because of this, I have to draw the circle on the Ball's surface field as such:
pygame.draw.circle(self.surface, color, (left, top), radius)
and then I can blit self.surface onto the screen. Something in this approach is causing an issue.
In summary, the approach I'm trying to take is to give each game object its own surface, but that (presumably) is causing problems for trying to draw a circle. I'd love some feedback on whether or not this approach is wrong and how to fix the circle problem. Thanks!