2

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.

ooransoy
  • 785
  • 5
  • 10
  • 25

1 Answers1

3

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

9000
  • 39,899
  • 9
  • 66
  • 104
David Jay Brady
  • 1,034
  • 8
  • 20
  • Thanks, this helped a lot. – ooransoy Mar 05 '16 at 07:13
  • Uhh, it still doesn't work. I have made the Bits sprites, and the group. Here is the code: [gist](https://gist.github.com/nolcay/98789dda60cd129ea322) – ooransoy Mar 05 '16 at 14:49
  • Change the bits.draw to bits.draw(screen) .. After doing that I got the image to show up for me. Check pygame.org/docs if not sure how to use the functions correctly. I took a look at your code and most of it looks good. About collisions, if you have a pygame Group of all your Bits, and wanna check if your player collides with any of them, I recommend using pygame.sprite.spritecollideany(sprite, group). Let me know if you have more questions :D – David Jay Brady Mar 06 '16 at 02:13
  • Also, The randomizer doesn't work properly. All of the bits appear on the same spot. Why is that? – ooransoy Mar 06 '16 at 07:16
  • In your Bit's __init__ class, add this line: self.rect = self.rect.move(randrange(40, 600), randrange(40, 600)) After making your changes, you never put in another line to move things randomly, as you did in the question you posted. By default, image rects are at the top left. This will move them around for you – David Jay Brady Mar 06 '16 at 08:20