Reputation: 15
I am using Pygame and a Buttons Module to replicate the code for a simple elevator program. I am running into the issue not displaying a certain button(created by the Buttons Module) based off of what the currentFloor is.
if currentFloor != maxFloor:#Checks if the currentFloor is not equal to the maxFloor
self.Button3.create_button(self.setDisplay, colcyan, 550, 100, 200, 100,0,"Up",colblack)#Button to add one to currentLevel
This code provided is working for the button to go up. Although, when I attempt to recreate it using a similar line of code for the down button, It yeilds a error.
elif currentFloor != startFloor:#Checks if the currentFloor is not equal to the startFloor
self.Button1.create_button(self.setDisplay, colred, 550, 400, 200, 100,0,"Down",colblack)#Button to subtract one to currentLevel
Error yielded:
Traceback (most recent call last):
File "G:\Python APCSP\Elevator\Example.py", line 72, in <module>
obj = Elevator()
File "G:\Python APCSP\Elevator\Example.py", line 24, in __init__
self.runGame()
File "G:\Python APCSP\Elevator\Example.py", line 66, in runGame
if self.Button1.pressed(pygame.mouse.get_pos()):
File "G:\Python APCSP\Elevator\Buttons.py", line 29, in pressed
if mouse[0] > self.rect.topleft[0]:
AttributeError: Button instance has no attribute 'rect'
I am unsure why a if statement very similar to the first one would provide such error.
The full source code will be provided below.
Elevator Program Source Code:
import pygame, Buttons, sys
from pygame.locals import *
#Color Options
colwhite = (255,255,255)
colblack = (0,0,0)
colgray = (33,33,33)
colblue = (0,61,103)
colred = (103,0,9)
colyellow = (255,229,9)
colgreen = (0,103,42)
colcyan = (0,118,118)
colpurple = (103,0,103)
#Initialize pygame
pygame.init()
currentFloor = 0
maxFloor = 5
startFloor = 0
class Elevator:
def __init__(self):
self.runGame()
#Create a display
def display(self):
width = 800
height = 600
self.setDisplay = pygame.display.set_mode((width,height),0,32)
pygame.display.set_caption("Elevator Program")
#Update the display and show the button
def update_display(self):
global currentFloor
self.setDisplay.fill(colblue)
#Parameters: surface, color, x, y, length, height, width, text, text_color
self.Button2.create_button(self.setDisplay, colblue, 525, 225, 250, 150,0,"Current Floor: "+str(currentFloor),colwhite)#Not a used button, just to display currentFloor
if currentFloor != maxFloor:#Checks if the currentFloor is not equal to the maxFloor
self.Button3.create_button(self.setDisplay, colcyan, 550, 100, 200, 100,0,"Up",colblack)#Button to add one to currentLevel
elif currentFloor != startFloor:#Checks if the currentFloor is not equal to the startFloor
self.Button1.create_button(self.setDisplay, colred, 550, 400, 200, 100,0,"Down",colblack)#Button to subtract one to currentLevel
pygame.display.flip()
#Run the loop
def runGame(self):
global currentFloor
self.Button2 = Buttons.Button()
self.Button1 = Buttons.Button()
self.Button3 = Buttons.Button()
self.display()
while True:
self.update_display()
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
elif event.type == MOUSEBUTTONDOWN:
if currentFloor != maxFloor:
if self.Button3.pressed(pygame.mouse.get_pos()):
print "Going Up"
currentFloor += 1
print currentFloor
if currentFloor != startFloor:
if self.Button1.pressed(pygame.mouse.get_pos()):
print "Going Down"
currentFloor -= 1
print currentFloor
if __name__ == '__main__':
obj = Elevator()
Buttons Module Source Code:
import pygame
from pygame.locals import *
pygame.init()
class Button:
def create_button(self, surface, color, x, y, length, height, width, text, text_color):
surface = self.draw_button(surface, color, length, height, x, y, width)
surface = self.write_text(surface, text, text_color, length, height, x, y)
self.rect = pygame.Rect(x,y, length, height)
return surface
def write_text(self, surface, text, text_color, length, height, x, y):
font_size = int(length//len(text))
myFont = pygame.font.SysFont("Calibri", font_size)
myText = myFont.render(text, 1, text_color)
surface.blit(myText, ((x+length/2) - myText.get_width()/2, (y+height/2) - myText.get_height()/2))
return surface
def draw_button(self, surface, color, length, height, x, y, width):
for i in range(1,10):
s = pygame.Surface((length,height))
s.fill(color)
pygame.draw.rect(s, color, (x-i,y-i,length+i,height+i), width)
surface.blit(s, (x,y))
pygame.draw.rect(surface, (190,190,190), (x,y,length,height), 1)
return surface
def pressed(self, mouse):
if mouse[0] > self.rect.topleft[0]:
if mouse[1] > self.rect.topleft[1]:
if mouse[0] < self.rect.bottomright[0]:
if mouse[1] < self.rect.bottomright[1]:
return True
else: return False
else: return False
else: return False
else: return False
Upvotes: 0
Views: 89
Reputation: 2698
Call the update_display()
function after every update to currentFloor
.
As once up
button is pressed value of currentFloor
is no longer 0
.
As a result the second if
condition (if currentFloor != startFloor
in runGame's while loop) will also be checked but as the update_diplay()
is not called in between so no button for down
is initialised.
Also in update_display()
function make both the condition as if
as you need to check for both buttons
no matter what.
Here is how your while loop should look like:
self.update_display()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
elif event.type == MOUSEBUTTONDOWN:
if currentFloor != maxFloor:
if self.Button3.pressed(pygame.mouse.get_pos()):
print "Going Up"
currentFloor += 1
print currentFloor
self.update_display()
if currentFloor != startFloor:
if self.Button1.pressed(pygame.mouse.get_pos()):
print "Going Down"
currentFloor -= 1
print currentFloor
self.update_display()
Upvotes: 0
Reputation: 42597
The rect
attribute is only initialised when you call Button.create_button()
.
However, you run code in runGame()
that expects this attribute to be present: you call Button.pressed()
before calling Button.create_button()
on button 1 or 3.
You need to ensure that the buttons are properly initialised before trying to use or query them. Or your pressed()
method needs to check whether the button has been initialised, and return False if not.
Upvotes: 4