I have python 3.0 and im trying to get this code to work but I don't believe it is recognizing all the attributes it's supposed to.

import pygame, sys, random 
from pygame.locals import * 
#*******************************************SETUPVAR**************************************************
BLACK = (0, 0, 0) 
WHITE = (255, 255, 255) 
RED = (255, 0, 0)
GREEN = (0, 255, 0) 
BLUE = (0, 0, 255) 
ORANGE = (255,180,0)
YELLOW=(230,230,0)
#***********************************************DEFINE*************************************************
def newscreen():
    pygame.init() 
    mainClock = pygame.time.Clock()
    windowSurface = pygame.display.set_mode((700,600), 0, 32) 
    pygame.display.set_caption('test')
    BLACK = (0, 0, 0) 
    WHITE = (255, 255, 255) 
    RED = (255, 0, 0) 
    GREEN = (0, 255, 0) 
    BLUE = (0, 0, 255) 
    ORANGE = (255,180,0)
    YELLOW=(230,230,0)
    basicFont = pygame.font.SysFont(None, 48)
    Font1 = pygame.font.SysFont('ActionIsShaded', 25)
    windowSurface.fill(BLACK)
    text = basicFont.render ('test,False,WHITE,BLUE)
    textRect = text.get_rect()
    textRect.centerx = windowSurface.get_rect().centerx
    textRect.centery = windowSurface.get_rect().centery-250
    windowSurface.blit(text,textRect)
    pygame.display.update()
    return windowSurface
    return event

def menu():
    windowSurface = newscreen()
    event = newscreen()
    pygame.init()
    basicFont = pygame.font.SysFont(None, 48)
    Font1 = pygame.font.SysFont('ActionIsShaded', 25)
    1 = basicFont.render('1', False, WHITE, RED) 
    2 = basicFont.render('2',False,WHITE,GREEN)
    3 = basicFont.render('3',False,WHITE,ORANGE)
    4 = basicFont.render('4',False,WHITE,YELLOW)
    3Rect = vl.get_rect()
    3Rect.centerx = windowSurface.get_rect().centerx+200
    3Rect.centery = windowSurface.get_rect().centery-100
    2Rect = games.get_rect()
    2Rect.centerx = windowSurface.get_rect().centerx-200
    2Rect.centery = windowSurface.get_rect().centery-100
    1Rect = text.get_rect() 
    1Rect.centerx = windowSurface.get_rect().centerx +200
    1Rect.centery = windowSurface.get_rect().centery+150
    1Rect.size = (100,100)
    4Rect = end.get_rect()
    4Rect.centerx = windowSurface.get_rect().centerx-200
    4Rect.centery = windowSurface.get_rect().centery+150
    windowSurface.blit(1, 1Rect) 
    windowSurface.blit(2,2Rect)
    windowSurface.blit(3,3Rect)
    windowSurface.blit(4,4Rect)
    pygame.display.update()
    #keepgoing = True
    while True: 
    # check for events 
        for event in pygame.event.get(): 
            if event.type == QUIT: 
                pygame.quit() 
                sys.exit() 
            if event.type == KEYUP: 
                if event.key == K_ESCAPE: 
                    pygame.quit() 
                    sys.exit()  
            if event.key == K_RIGHT or event.key == ord('d'): 
                print('yes') 
            if event.key == ord('x'): 
                print('correct')
            if event.type == MOUSEBUTTONUP:
                M = pygame.mouse.get_pos
                if M == textRect.collidepoint:
                    newscreen()
    
#***********************************************START***************************************************
newscreen()
menu()


# run the game loop 
while True: 
    for event in pygame.event.get(): 
        if event.type == QUIT: 
            pygame.quit() 
            sys.exit()

Dani AI

Generated

Quick diagnosis and why that traceback appeared: the code checks event.key without first ensuring the event actually carries a key attribute. Pygame events like QUIT or MOUSEBUTTONUP don’t have .key, so accessing it will raise an AttributeError. Another source of trouble in the posted script is that the screen-setup function only returns the surface, yet menu() expects other things (text/rects). Calling the setup twice and initializing pygame repeatedly only makes debugging harder. and were right to flag the syntax/return problems; the unguarded event.key is the immediate runtime problem.

Practical checklist (apply in order):

  • Fix syntax: strings and parentheses in font.render, and use descriptive names (no names that are only digits).
  • Make the screen/setup function return every object the menu needs (or keep those items as attributes on a Menu object).
  • In the event loop, always test event.type before accessing event.key or event.pos. For example, handle KEYDOWN/KEYUP and MOUSEBUTTONUP in separate branches so attribute access is safe.
  • Use event.pos (or pygame.mouse.get_pos() with parentheses) and call rect.collidepoint(mouse_pos) rather than comparing objects.
  • Initialize pygame and the display once at program start. Avoid unreachable multiple return statements.

A compact pattern that helps is putting menu state and handling into a class so drawing and event logic are grouped. Example skeleton:

class Menu:
    def __init__(self, surface, font):
        self.surface = surface
        self.font = font
        self.items = []     # (label, surface, rect)
        self.clock = pygame.time.Clock()

    def add_item(self, label, center):
        s = self.font.render(label, True, WHITE)
        r = s.get_rect(center=center)
        self.items.append((label, s, r))

    def handle_event(self, event):
        if event.type == pygame.MOUSEBUTTONUP:
            pos = event.pos
            for label, s, r in self.items:
                if r.collidepoint(pos):
                    return label
        if event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
            return 'quit'

    def draw_and_update(self):
        self.surface.fill(BLACK)
        for _, s, r in self.items:
            self.surface.blit(s, r)
        pygame.display.flip()
        self.clock.tick(30)

Turning the menu into a class (as did) is the right move: it keeps surfaces, rects and handlers together and makes it trivial to avoid the unguarded attribute access that caused the crash. Note: Python 3.0 is very old; use a maintained Python 3.x release when possible.

Recommended Answers

All 5 Replies

Hate to say it but there are a lot of problems with your code, but you can only learn from mistakes. First I'm going to address the syntax errors, which should be easy to fix from looking at what the red error text says in your console.

Line 27

text = basicFont.render ('test,False,WHITE,BLUE)

test is a string and has to be enclosed in single or double quotes.

text = basicFont.render ('test',False,WHITE,BLUE) #FIXED

Line 42

1 = basicFont.render('1', False, WHITE, RED)

1 is a variable and variables can not start or be solely a number, change it to something that describes what that varible is going to be used for.

fontSurface1 = basicFont.render('1', False, WHITE, RED) #fontSurface1 works as now you know this is a font surface

**Line line 42 to 58 all have the same problem with a number as the starting character for the variable, which all have to be changed.

Line 33

return windowSurface
return event

A method can not have more than one return statement, both of these variables can be returned as a tuple though.

return windowSurface, event

Line 46

3Rect = vl.get_rect()

If vl is a class that you have written can you please post the code so that we can help with debugging of the rest of the program. Also for games and end.

If you have any more questions just ask.

what if I keep getting this back

Traceback (most recent call last):
  File "C:\Python31\pysoccer.py", line 102, in <module>
    menu()
  File "C:\Python31\pysoccer.py", line 91, in menu
    if event.key == K_RIGHT or event.key == ord('d'):
AttributeError: event member not defined

See this comment is tbone2sk's reply above.

Line 33
Python Syntax (Toggle Plain Text)
return windowSurface
return event
A method can not have more than one return statement, both of these variables can be returned as a tuple though.

The first culprit to check on is to see if "event" is returned because the second return will never execute. Add something like this to statements that expect to receive "execute" from a function.

def menu():
    windowSurface = newscreen()
    event = newscreen()
    print event, type(event)

If you get "None" then something is wrong. I would suggest that you break this program up into small segments/functions and test each one individually before you do any more coding.

woooee is correct in seeing if you even need to return event in the newscreen method, but your problem is not only there but in your event loop. Your program will be more efficient if you use this event method to handle key inputs.

def keyPressed(inputKey):
    keysPressed = pygame.key.get_pressed()
    if keysPressed[inputKey]:
        return True
    else:
        return False

Then in your program change the event loop to something more like this.

for event in pygame.event.get(): 
            if event.type == QUIT: 
                pygame.quit() 
                sys.exit()
            elif event.type == MOUSEBUTTONDOWN:
                M = pygame.mouse.get_pos
                if M == textRect.collidepoint:
                    newscreen()
        if keyPressed(K_ESCAPE): 
                pygame.quit() 
                sys.exit()  
        elif keyPressed(K_RIGHT) or keyPressed(K_d): 
            print('yes') 
        elif keyPressed(K_x): 
            print('correct')

Your program still has many problems after this.

I turned the menu function into a class and it seems to be working better but I really don't no what a class is

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.