Search code examples
pythonpygamespritepython-3.4rect

Pygame sprite invalid rectstyle object


I have a classic snake game, Im trying to make the snake bigger, so I started to use printing rects to screen instead of pixels. I tried these codes for that(Im not going to write whole code because it may confused):

class Worm(pygame.sprite.Sprite):
    def __init__(self, surface,seg_width,seg_height):
        self.surface = surface #this is ==> screen=pygame.display.set_mode((w, h))
        self.x = surface.get_width() / 2
        self.y = surface.get_height() / 2
        self.length = 1
        self.grow_to = 50
        self.vx = 0
        self.vy = -seg_width
        self.body = []
        self.crashed = False
        self.color = 255, 255, 0
        self.rect = pygame.Rect(self.x,self.y,seg_width,seg_height)
        self.segment = pygame.Rect(0,0,seg_width,seg_height)
   def move(self):
    """ Move the worm. """
    self.x += self.vx
    self.y += self.vy
    self.rect.topleft = self.x, self.y
    if (self.x, self.y) in self.body:
        self.crashed = True

    self.body.insert(0, (self.x, self.y))   #Func of moving the snake
    new_segment = self.segment.copy() 
    self.body.insert(0, new_segment.move(self.x, self.y)) 
    if len(self.body) > self.length:
        self.body.pop()

    def draw(self):
    for SEGMENT in self.body:    #Drawing the snake
        self.surface.fill((255,255,255), SEGMENT) #This is where I got error <-----

My codes are working perfectly if I use pixels, but I want a bigger snake (not longer, I mean thicker) so I thought I can use rects, I tried this, but It gives me;

self.surface.fill((255,255,255), SEGMENT) 
ValueError: invalid rectstyle object

SEGMENT is actually a tuple of coordinates, why I got this error then? Also after I press f5, I see this screen first, so basically my theory is working but its a weird output, one rect is smaller than other? Why? That "0" is scoreboard, I didnt wrote whole code as I said.

I just don't understand why, what can I do for fixing it?

I want to say this again because it may confuse too, that surface argument is actually representing screen = pygame.display.set_mode((w, h)) this, where w = widht and h = height.

This is with pixels, so I want a thicker snake, builded by rects not pixels.

enter image description here enter image description here

Edit: From nbro's answer, I change this one

self.body.insert(0, (self.x, self.y,self.x, self.y))

So it is a tuple with 4 elements now, but output is very strange.. enter image description here


Solution

  • It's easy to debug your code with a simple print somewhere. I have just put a print under:

    def draw(self):
        for SEGMENT in self.body:
            print(SEGMENT)
            self.surface.fill((255,255,255), SEGMENT) #This is where I got error <-----
    

    and I immediately discovered your problem. SEGMENT has to be a rectangle based shape, which means that you have to specify x, y, width and height, but, at certain point, SEGMENT assumes a tuple value composed of 2 elements, which is not correct, it has to be a tuple of 4 elements!

    Specifically the output when I get the error is this:

    <rect(320, 210, 30, 30)>
    <rect(320, 180, 30, 30)>
    (320.0, 180.0)
    

    Now I think you can try to see why it assumes that third tuple of 2 elements even without my help.