0

I'm playing around with pygame for the first time, trying to make multiple rectangles move across the screen. Here's my code:

import pygame

pygame.init()

scrWidth = 1200
scrHeigth = 900
done = False
rectangles = []

screen = pygame.display.set_mode((scrWidth, scrHeigth))
clock = pygame.time.Clock()

class Rectangle:
    speed = [1,1]
    colourSpeed = 300
    colourID = 0
    colour = (0, 0, 255)
    size = 60

    def __init__(self, name = "", x=0, y=0, speed=False, colour=False, size=False):
        self.name = name
        self.x = x
        self.y = y
        self.doesSpeed = speed
        self.doesColour = colour
        self.doesSize = size

    def draw(self):
        pygame.draw.rect(screen, self.colour, pygame.Rect(self.x, self.y, self.size, self.size))

    def checkCollision(self):
        if self.x < 0 or self.x > scrWidth-self.size:
            self.speed[0] = -self.speed[0]
        if self.y < 0 or self.y > scrHeigth-self.size:
            self.speed[1] = -self.speed[1]

    def move(self):
        self.x += self.speed[0]
        self.y += self.speed[1]

    def changeColour(self):
        self.colourID = (self.colourID+1)%self.colourSpeed
        if 0 <= self.colourID < (self.colourSpeed/3):
            self.colour = (0, 0, 255)
        elif (self.colourSpeed/3) <= self.colourID < (2*self.colourSpeed/3):
            self.colour = (0, 255, 0)
        elif (2*self.colourSpeed/3) <= self.colourID < self.colourSpeed:
            self.colour = (255, 0, 0)




rect1 = Rectangle("rect1", 30, 30, False, True, False)
rectangles.append(rect1)
rect2 = Rectangle("rect2", 300, 300)
rectangles.append(rect2)


while not done:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            done=True

    screen.fill((0, 0, 0))
    for obj in rectangles:
        obj.checkCollision()
        if obj.doesColour: obj.changeColour()
        obj.move()
        obj.draw()

    pygame.display.flip()
    clock.tick(60)

The problem is that when a rectangle collides with the edge of the screen all rectangles change direction(speed). However if I make rectangles with different speeds this doesn't happen.

ex: rect1 has speed [1,1] and rect2 has speed [2,2].

What's causing this and how can I fix it?

2
  • I don't know why you have a class variable for speed, but I would recommend you to get rid of it. You need to also adjust it in every method... Commented Dec 2, 2016 at 7:16
  • speed is a class attribute, mutable value shared across all instances. You have to create individual list in each instance __init__ method. Commented Dec 2, 2016 at 7:21

1 Answer 1

1

Move the speed, colourSpeed, colourID, colour, size to the init method.

At that moment that fields are defined as class fields, so they are changed globally for all rectangles.

Solution:

def __init__(self, name = "", x=0, y=0, speed=False, colour=False, size=False):
        self.name = name
        self.x = x
        self.y = y
        self.doesSpeed = speed
        self.doesColour = colour
        self.doesSize = size
        # here it comes
        self.speed = [1,1]
        self.colourSpeed = 300
        self.colourID = 0
        self.colour = (0, 0, 255)
        self.size = 60
Sign up to request clarification or add additional context in comments.

4 Comments

thanks, that worked. How come it did work when I changed the speed to an absolute value? (rect1.speed = [2,2])
@SJ_WTF I would like to see your code now, because with this solution really nothing changes
@LPK yeah answered before the code block showed up in this answer for me. You should have self.speed etc inside the init
Sorry, I just copied lines straight to initializator. Now it should work.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.