flashburn
flashburn

Reputation: 4508

why I'm getting a square instead of a circle in pygame?

I'm somewhat new to pygame. I'm trying to draw a circle, but for some reason I'm getting a square. My code is below. I'd appreciate any help clarifying the issue.

import sys, pygame
import random

pygame.init()

SCREEN_SIZE = SCREEN_WIDTH, SCREEN_HEIGHT = 800, 600
BACKGROUND_COLOR = pygame.Color("white")
SCREEN_COLOR = BACKGROUND_COLOR

SCREEN = pygame.display.set_mode(SCREEN_SIZE)

class Splatter:
  def __init__(self, (x, y), r, color):
    self.x = x
    self.y = y
    self.r = r
    self.color = color
    self.surface = pygame.Surface((r*2, r*2))
    self.surface.set_alpha(192)
    self.rect = self.surface.get_rect()

  def display(self):
    self.rect.centerx = self.x
    self.rect.centery = self.y
    pygame.draw.circle(self.surface, self.color, (self.x, self.y), self.r)
    SCREEN.blit(self.surface, self.rect)

def main():
  SCREEN.fill(SCREEN_COLOR)

  s = Splatter((SCREEN.get_width()/2, SCREEN.get_height()/2), 10, pygame.Color("black"))
  s.display()
  pygame.display.flip()
  while True:
    for event in pygame.event.get():
      if event.type == pygame.QUIT: sys.exit()

if '__main__' == __name__:
  main()

EDIT

Given the comments and the answer I've changed the code. However I'm still getting a square instead of a circle. My ultimate goal is to have a circle drawn on a surface. So instead of drawing a circle each time, I could simply move the surface on the screen.

import sys, pygame
import random

pygame.init()

SCREEN_SIZE = SCREEN_WIDTH, SCREEN_HEIGHT = 800, 600
SCREEN_COLOR = pygame.Color("white")

SCREEN = pygame.display.set_mode(SCREEN_SIZE)

class Splatter(object):
  def __init__(self, (x, y), r):
    self.x = x
    self.y = y
    self.r = r
    self.surface = pygame.Surface((r*2, r*2))
    self.surface.fill(pygame.Color("red"))
    self.rect = self.surface.get_rect()
    pygame.draw.circle(self.surface, pygame.Color("black"), (self.x, self.y), self.r)

  def display(self):
    self.rect.centerx = self.x
    self.rect.centery = self.y
    SCREEN.blit(self.surface, self.rect)


  SCREEN.fill(SCREEN_COLOR)
  s = Splatter((SCREEN.get_width()/2, SCREEN.get_height()/2), 20)
  s.display()

  pygame.display.flip()

  while True:
    for event in pygame.event.get():
      if event.type == pygame.QUIT: sys.exit()

Upvotes: 3

Views: 1128

Answers (1)

David Mašek
David Mašek

Reputation: 922

You're painting black circle on black Surface and then you put the whole Surface on the SCREEN. The black circle is there but you obviously don't see it.

Try this (tested).

global SCREEN
pygame.draw.circle(SCREEN, self.color, (self.x, self.y), self.r)
pygame.display.flip()

As a side note IMHO a lot of your code is useless. You're overthinking this. For example:

SCREEN_SIZE = SCREEN_WIDTH, SCREEN_HEIGHT = 800, 600
BACKGROUND_COLOR = pygame.Color("white")
SCREEN_COLOR = BACKGROUND_COLOR

Is equivalent to:

SCREEN_SIZE =  800, 600
SCREEN_COLOR  = pygame.Color("white")

EDIT:

You're still getting a square because you're painting the circle outside the Surface that you blit on the screen.

This line is problem because self.x and self.y are outside the self.surface.

pygame.draw.circle(self.surface, pygame.Color("black"), (self.x, self.y), self.r)

Solution:

pygame.draw.circle(self.surface, pygame.Color("black"), 
                           (int(self.surface.get_width()/2),
                            int(self.surface.get_height()/2)), 
                           self.r)

Or IMHO better (but it really depends on how you implement other parts of game):

# ...
class Splatter(object):
    def __init__(self, r):
        self.r = int(r)
        self.surface = pygame.Surface((r*2, r*2))
        self.surface.fill(pygame.Color("red"))
        pygame.draw.circle(self.surface, pygame.Color("black"), 
                           (int(self.surface.get_width()/2),
                            int(self.surface.get_height()/2)), 
                           self.r)

    def display(self, x, y):
        SCREEN.blit(self.surface, (int(x), int(y)))


SCREEN.fill(SCREEN_COLOR)
s = Splatter(20)
s.display(SCREEN.get_width()/2, SCREEN.get_height()/2)
pygame.display.flip()
# ...

You don't need the coordinates when creating the Splatter you need them when you display it.

Upvotes: 3

Related Questions