I have an Agar.io like test game where the square player touches the "bit"s and grows. The problem is the bit generation. The bit generates every second and has its own surface. But, the program will not blit the bit (no pun intended) into the initial surface.
Here is the code:
import pygame
import random
pygame.init()
clock = pygame.time.Clock()
display = pygame.display
screen = display.set_mode([640,480])
rect_x = 295
rect_y = 215
display.set_caption("Agar")
d = False
bits = []
size = 50
steps = 0
class Bit:
cscreen = display.set_mode([640,480])
circ = pygame.draw.circle(cscreen, (65, 76, 150), (random.randrange(40, 600), random.randrange(40, 440)), 5)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
d = True
if d == True:
break
# Fill background
screen.fill((5, 58, 0))
# Create player object
player = pygame.draw.rect(screen, (250, 197, 255), [rect_x, rect_y, size, size])
# Moving
if pygame.key.get_pressed()[pygame.K_UP]:
rect_y -= 2
if pygame.key.get_pressed()[pygame.K_DOWN]:
rect_y += 2
if pygame.key.get_pressed()[pygame.K_RIGHT]:
rect_x += 2
if pygame.key.get_pressed()[pygame.K_LEFT]:
rect_x -= 2
# Bit generation
if steps == 60:
new_bit = Bit()
bits.append(new_bit.circ)
screen.blit(new_bit.cscreen, (0,0))
steps = 0
steps += 1
# Collision detection
collision = player.collidelist(bits)
if collision != -1:
bits[collision].cscreen.fill((0,0,0,0))
# Make player larger
size += 10
# FPS limit
clock.tick(60)
# Refresh
display.flip()
P.S. There is no error message.
Thanks in advance.
To have each Bit
object have different locations and instance variables, you need to have an __init__
method in your bit class. By adding an __init__
, and adding self.
to the variables, the blitting works.
But a word of warning. When you make a separate cscreen
for each object, and then blit that cscreen
to your actual screen, you get rid of every other cscreen
thats been blitted, making only 1 Bit
viewable at a time. Even if you had cscreen
outside of __init__
, you would have an issue erasing older ones now, so I advise you take a different approach.
My recommendation is to find a small picture of a dot, and write these lines in the Bit
's __init__
method.
self.image = pygame.image.load("reddot.png")
self.rect = self.image.get_rect()
Once you create your bit, add it to a pygame.sprite.Group()
. These groups have very handy built in methods. One of them being .draw()
. It will go through your Group of Bits
and use each's self.image
and self.rect
to draw them in the correct place every time, without you having to worry about it. When a Bit
is eaten, you can delete the Bit
from the Group and it is now erased for you.
A random side note: I recommend you change your event loop to just break when it event.type == pygame.QUIT
. That way, Python does not need to check the if d == True
statement on every frame, while making the code slightly more readable. If it only breaks out of the for loop (for me it exited fine), you can use sys.exit()
after importing sys