Question

I'm building a relatively simple programme to test collision detection, it's all working fine at the moment except one thing, I'm trying to make the background colour change randomly, the only issue is that it appears to be completely skipping the function to do this;

import pygame
from pygame.locals import *
import random, math, time, sys
pygame.init()

Surface = pygame.display.set_mode((800,600))

backgroundr = int(random.random()*255)+1
backgroundg = int(random.random()*255)+1
backgroundb = int(random.random()*255)+1

Circles = []
class Circle:
    def __init__(self):
        self.radius = int(random.random()*50) + 1
        self.x = random.randint(self.radius, 800-self.radius)
        self.y = random.randint(self.radius, 600-self.radius)
        self.speedx = 0.5*(random.random()+1.0)
        self.speedy = 0.5*(random.random()+1.0)
        self.r = int(random.random()*255)+1
        self.g = int(random.random()*255)+1
        self.b = int(random.random()*255)+1
##        self.mass = math.sqrt(self.radius)

for x in range(int(random.random()*30) + 1):
    Circles.append(Circle())

def CircleCollide(C1,C2):
    C1Speed = math.sqrt((C1.speedx**2)+(C1.speedy**2))
    XDiff = -(C1.x-C2.x)
    YDiff = -(C1.y-C2.y)
    if XDiff > 0:
        if YDiff > 0:
            Angle = math.degrees(math.atan(YDiff/XDiff))
            XSpeed = -C1Speed*math.cos(math.radians(Angle))
            YSpeed = -C1Speed*math.sin(math.radians(Angle))
        elif YDiff < 0:
            Angle = math.degrees(math.atan(YDiff/XDiff))
            XSpeed = -C1Speed*math.cos(math.radians(Angle))
            YSpeed = -C1Speed*math.sin(math.radians(Angle))
    elif XDiff < 0:
        if YDiff > 0:
            Angle = 180 + math.degrees(math.atan(YDiff/XDiff))
            XSpeed = -C1Speed*math.cos(math.radians(Angle))
            YSpeed = -C1Speed*math.sin(math.radians(Angle))
        elif YDiff < 0:
            Angle = -180 + math.degrees(math.atan(YDiff/XDiff))
            XSpeed = -C1Speed*math.cos(math.radians(Angle))
            YSpeed = -C1Speed*math.sin(math.radians(Angle))
    elif XDiff == 0:
        if YDiff > 0:
            Angle = -90
        else:
            Angle = 90
        XSpeed = C1Speed*math.cos(math.radians(Angle))
        YSpeed = C1Speed*math.sin(math.radians(Angle))
    elif YDiff == 0:
        if XDiff < 0:
            Angle = 0
        else:
            Angle = 180
        XSpeed = C1Speed*math.cos(math.radians(Angle))
        YSpeed = C1Speed*math.sin(math.radians(Angle))
    C1.speedx = XSpeed
    C1.speedy = YSpeed
    C1.r = int(random.random()*255)+1
    C1.g = int(random.random()*255)+1
    C1.b = int(random.random()*255)+1
    C2.r = int(random.random()*255)+1
    C2.g = int(random.random()*255)+1
    C2.b = int(random.random()*255)+1

def ColourCheck():
    checknumber = int(random.random()*50)+1
    if checknumber == 50:
        backgroundr = int(random.random()*255)+1
        backgroundg = int(random.random()*255)+1
        backgroundb = int(random.random()*255)+1

def Move():
    for Circle in Circles:
        Circle.x += Circle.speedx
        Circle.y += Circle.speedy
def CollisionDetect():
    for Circle in Circles:
        if Circle.x < Circle.radius or Circle.x > 800-Circle.radius:
            Circle.speedx *= -1
            Circle.r = int(random.random()*255)+1
            Circle.g = int(random.random()*255)+1
            Circle.b = int(random.random()*255)+1
        if Circle.y < Circle.radius or Circle.y > 600-Circle.radius:
            Circle.speedy *= -1
            Circle.r = int(random.random()*255)+1
            Circle.g = int(random.random()*255)+1
            Circle.b = int(random.random()*255)+1
    for Circle in Circles:
        for Circle2 in Circles:
            if Circle != Circle2:
                if math.sqrt(  ((Circle.x-Circle2.x)**2)  +  ((Circle.y-Circle2.y)**2)  ) <= (Circle.radius+Circle2.radius):
                    CircleCollide(Circle,Circle2)
def Draw():
    Surface.fill((backgroundr,backgroundg,backgroundb))
    for Circle in Circles:
        pygame.draw.circle(Surface,(Circle.r,Circle.g,Circle.b),(int(Circle.x),int(600-Circle.y)),Circle.radius)
    pygame.display.flip()

def GetInput():
    keystate = pygame.key.get_pressed()
    for event in pygame.event.get():
        if event.type == QUIT or keystate[K_ESCAPE]:
            pygame.quit(); sys.exit()

def main():
    while True:
        ColourCheck()
        GetInput()
        Move()
        CollisionDetect()
        Draw()
if __name__ == '__main__': main()

it's the ColourCheck function that's being ignored, any ideas why?

Was it helpful?

Solution

I believe backgroundr, backgroundg, and backgroundb are local variables to your ColourCheck() function.

If you're determined to use global variables, try this at the top of your file:

global backgroundr;
global backgroundg;
global backgroundb;
backgroundr = int(random.random()*255)+1
backgroundg = int(random.random()*255)+1
backgroundb = int(random.random()*255)+1

and this in your function:

def ColourCheck():
    global backgroundr;
    global backgroundg;
    global backgroundb;
    checknumber = int(random.random()*50)+1
    if checknumber == 50:
        backgroundr = int(random.random()*255)+1
        backgroundg = int(random.random()*255)+1
        backgroundb = int(random.random()*255)+1

OTHER TIPS

Move(), CollisionDetect(), and Draw() all refer to Circles, but don't declare it global. Try adding a global Circles line to the beginning of each function. Also, I'd recommend changing your variables to lower-case; not only does an initial cap typically indicate a class in Python, but you're actually generating (insignificant) collisions between the Circle variable and the Circle class.

For example:

circles = []

# ...

for x in range(int(random.random()*30) + 1):
    circles.append(Circle())

# ...

def Move():
    global circles

    for circle in circles:
        circle.x += circle.speedx
        circle.y += circle.speedy

# ...

Edit:

And as Nathan notes, your backgroundX variables also need to be declared global in ColorCheck() and Draw().

You might consider wrapping all of these functions into a Game class (or some such), to avoid working with so many globals.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top