Search code examples
pythonpygameattributeerror

Chasing game - Error message: "'module' object has no attribute 'display'"


I am new to programming and am trying to set up a simulation in which one circle is moving in a random pattern and is being chased by a second circle. Eventually I am hoping to add 5 circles as distractors that are moving around randomly.

In the code I called the circle moving about randomly "Mouse" and the circle chasing "Cat".

I researched online and looked at other people's code to get ideas and this is what I came up with so far:

from pygame import *
import random
import sys, pygame, math, random
from pygame.locals import *

pygame.init()
background_colour = (255,255,255)
(width, height) = (1024, 768)
screen = pygame.display.set_mode((width, height),pygame.FULLSCREEN)


class Mouse(pygame.sprite.Sprite):
    def __init__(self, (x, y), size):
        pygame.sprite.Sprite.__init__(self)
        self.x = MX
        self.y = MY
        self.size = 30
        self.colour = (0, 0, 0)
        self.thickness = 2
        self.speed = 2
        self.angle = random.uniform(0, math.pi*2)


    def display(self):
        pygame.draw.circle(screen, self.colour, (int(MX), int(MY)), self.size, self.thickness)

    def move(self):
        self.x += math.sin(self.angle) * self.speed
        self.y -= math.cos(self.angle) * self.speed


class Cat(pygame.sprite.Sprite):
    def __init__(self, (x, y), size):
        pygame.sprite.Sprite.__init__(self)
        self.x = CX
        self.y = CY
        self.size = 30
        self.colour = (0, 0, 0)
        self.thickness = 2
        self.speed = 2
        self.angle = random.uniform(0, math.pi*2)
        pixChangeC = 2

    def display(self):
        pygame.draw.circle(screen, self.colour, (int(CX), int(CY)), self.size, self.thickness)

    def move(self):
        if MX >= CX:
            CX += pixChangeC    
        else:
            CX -= pixChangeC
        if MY >= CY:
            CY += pixChangeC
        else:
            CY -= pixChangeC

def main():

    pygame.display.set_caption('Chase')
    mouse = Mouse()
    cat = Cat()


running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT or (event.type == KEYUP and event.key == K_ESCAPE):
            pygame.quit()
            sys.exit()


    screen.fill(background_colour)

    mouse.display()
    mouse.move()
    cat.display()
    cat.move()

    pygame.display.flip() 

Unfortunately, when I try to run the code like this, I get the following error message:

" File "C:...", line 75, in mouse.display() AttributeError: 'module' object has no attribute 'display'"

I could not find an answer online as to where I am going wrong so if anyone has some advice/ideas, I would appreciate any help!


Solution

  • Pydude was on the right track but stopped way too soon. You're getting a very un-helpful error message because pygame.mouse (with a small m) is imported when you use the from blank import * method of importing for pygame, but it SHOULD overwrite that one where you have mouse = Mouse(). The problem is your indentation is wrong. Everything from running = True down needs to be indented once more, including that line. Then, to get the main() function to run, you need to include this at the end of your file:

    if __name__ == "__main__":
        main()
    

    So what is happening when you run the code as you have it is that it skips right over the main() method (which is never called in your code) and runs the stuff after the indentation goes back, starting with running = True. When it gets to mouse.display() you haven't actually run the line mouse = Mouse() yet so it uses mouse imported from pygame. That mouse doesn't have a display() method, hence your error message.

    You'll have more errors in your code after fixing that, but this change will get you past this one error. The next one has a more helpful error message at least, so you should be able to figure it out.

    Also, some advice: from blank import * is discouraged for EXACTLY this reason. It's much better to either do import pygame and refer to everything as, eg, pygame.sprite (which you're already doing as well...which is odd that you're doing both...) or do from pygame import sprite, foo, bar, ... and explicitly list each specific thing you want out of that module. These two methods prevent you from having unknown stuff cluttering your namespace, and would have prevented you from getting this confusing error message you couldn't figure out.