How to stop pygame buttons from overlapping in separate images? - python

I'm making a simple text based RPG game in pygame. I'm using a button class (not mine, but fairly simple to use and integrate) to add buttons with choices in them. However, it seems a button on the second slide, the 'Sit and Wait' choice, is overlapping with the 'No' button on the first slide. Since the No button closes the game, pressing on Sit and Wait seems to close the game also. I've tried ordering the if-else statements in different ways, but every other button seems fine. Any tips? Thank you. Here is my code, sorry I know it's a lot but I'm a beginner and not great at condensing yet:
import pygame
pygame.init()
win=pygame.display.set_mode((800,700))
win.fill((255,255,255))
our_game_display=pygame.Surface((800,700))
font_name = pygame.font.get_default_font()
class button():
def __init__(self, color, x, y, width, height, text=''):
self.color = color
self.x = x
self.y = y
self.width = width
self.height = height
self.text = text
def draw(self, win, outline=None):
# Call this method to draw the button on the screen
if outline:
pygame.draw.rect(win, outline, (self.x - 2, self.y - 2, self.width + 4, self.height + 4), 0)
pygame.draw.rect(win, self.color, (self.x, self.y, self.width, self.height), 0)
if self.text != '':
font = pygame.font.SysFont('comicsans', 30)
text = font.render(self.text, 1, (255, 255, 255))
win.blit(text, (self.x + (self.width / 2 - text.get_width() / 2), self.y + (self.height / 2 - text.get_height() / 2)))
def isOver(self, pos):
# Pos is the mouse position or a tuple of (x,y) coordinates
if pos[0] > self.x and pos[0] < self.x + self.width:
if pos[1] > self.y and pos[1] < self.y + self.height:
return True
return False
def draw_text(text, size, x, y):
pygame.font.init()
font = pygame.font.Font(font_name, size)
text_surface = font.render(text, True, (255,255,255))
text_rect = text_surface.get_rect()
text_rect.center = (x, y)
our_game_display.blit(text_surface, text_rect)
def yell_choice():
our_game_display.fill((0, 0, 0))
draw_text('You yell to see if anyone can hear you.', 20, 800 / 2, 700 / 2 - 100)
win.blit(our_game_display, (0, 0))
pygame.display.update()
def sit_choice():
our_game_display.fill((0,0,0))
draw_text('So you decided to sit and wait', 20, 800 / 2, 700 / 2 - 100)
win.blit(our_game_display,(0,0))
pygame.display.update()
def search_choice():
our_game_display.fill((0,0,0))
draw_text('So you decided to search', 20, 800 / 2, 700 / 2 - 100)
win.blit(our_game_display,(0,0))
pygame.display.update()
def beginning_question():
our_game_display.fill((0, 0, 0))
draw_text('The story of this game depends on your choices. Do you wish to play?', 20, 800 / 2, 700 / 2 - 100)
win.blit(our_game_display, (0, 0))
YesButton.draw(win, (255, 255, 255))
NoButton.draw(win, (255, 255, 255))
pygame.display.update()
def begin_game():
our_game_display.fill((0,0,0))
draw_text("You wake up, or...at least you think you do. Even though your eyes are open,", 20, 800 / 2, 700 / 2 - 300)
draw_text("they still can't detect anything in the complete darkness that surrounds you.", 20, 800 / 2, 700 / 2 - 270)
draw_text("What do you do?", 20, 800 / 2, 700 / 2 - 210)
win.blit(our_game_display,(0,0))
SitWaitButton.draw(win,(255,255,255))
SearchButton.draw(win,(255,255,255))
YellHelpButton.draw(win,(255,255,255))
pygame.display.update()
#game loop
running = True
#color,x,y,width,height
YesButton=button((0,0,0),100,500,250,100,'Yes')
NoButton=button((0,0,0),450,500,250,100,'No')
SitWaitButton=button((0,0,0),500,500,200,50,'Sit and wait..')
SearchButton=button((0,0,0),250,600,600,50,'Get up and try to search your surroundings.')
YellHelpButton=button((0,0,0),250,400,600,50,'Yell to see if anyone is there.')
game_begun='Input' #beginning choice variable
search_option='Input'#search variable
sit_option='Input' #sitting variable
yell_option = 'Input'
while running:
if search_option=='Go':
search_choice()
elif sit_option=='Go':
sit_choice()
elif yell_option=='Go':
yell_choice()
elif game_begun=='Go':
begin_game()
else:
beginning_question()
for event in pygame.event.get():
pos=pygame.mouse.get_pos()
if event.type==pygame.QUIT:
running = False
pygame.quit()
quit()
#yes and no buttons for beginning question
if event.type==pygame.MOUSEBUTTONDOWN:
if SitWaitButton.isOver(pos):
sit_option = 'Go'
print("this button is working")
if SearchButton.isOver(pos):
search_option = 'Go'
print("this button is working")
if YellHelpButton.isOver(pos):
yell_option='Go'
print("this button is working")
if YesButton.isOver(pos):
game_begun='Go'
if NoButton.isOver(pos):
running=False
pygame.quit()
quit()
if event.type==pygame.MOUSEMOTION:
if YellHelpButton.isOver(pos):
YellHelpButton.color = (0, 0, 139)
elif SitWaitButton.isOver(pos):
SitWaitButton.color = (0, 0, 139)
elif SearchButton.isOver(pos):
SearchButton.color = (0, 0, 139)
elif YesButton.isOver(pos):
YesButton.color=(0,0,139)
elif NoButton.isOver(pos):
NoButton.color=(0,0,139)
else:
YesButton.color=(0,0,0)
NoButton.color=(0,0,0)
YellHelpButton.color = (0, 0, 0)
SitWaitButton.color = (0, 0, 0)
SearchButton.color = (0, 0, 0)

You can use an if-elif instruction like below, so that if the user clicks on the mouse while cursor is over the sit and wait button then you don't check if it's also over the quit button (and thus you don't quit the game):
if SitWaitButton.isOver(pos):
sit_option = 'Go'
print("this button is working")
elif NoButton.isOver(pos):
pygame.quit()
quit()
A cleaner solution would however be to remember which buttons are actually currently displayed. For example, you could have a list of visible buttons and check if the cursor is over a button only if this one is in the list.
On a side note, your running variable is useless: your main loop is while running but as soon as running is set to False you just quit the game immediately. So the condition of your loop never evaluates to False.

Related

Where should I place my restart and quit button if the game is frozen by time.sleep() at the end? [duplicate]

This question already has answers here:
Pygame mouse clicking detection
(4 answers)
Closed 1 year ago.
This post was edited and submitted for review 1 year ago and failed to reopen the post:
Duplicate This question has been answered, is not unique, and doesn’t differentiate itself from another question.
So I'm working on a snake game and I ran into some problems with the button class. I would like to implement two buttons at the end of the game. One in order to restart the game, the other one to close the game. I tested the buttons and they should be working. I just don't know where to draw them, because when I draw them at the end, I cannot press the button, because the game freezes due to the game.sleep() command. The game closes on itself, that's why I added a delay. I drew the buttons al the way at the end.
I edited the code, so only the button code is shown below with the gameloop.
clicked = False
font = pygame.font.SysFont('Constantia', 30)
class button():
# colours for button and text
button_col = (255, 0, 0)
hover_col = (75, 225, 255)
click_col = (50, 150, 255)
text_col = BLACK
width = 180
height = 70
def __init__(self, x, y, text):
self.x = x
self.y = y
self.text = text
def draw_button(self):
global clicked
action = False
# get mouse position
pos = pygame.mouse.get_pos()
# create pygame Rect object for the button
button_rect = Rect(self.x, self.y, self.width, self.height)
# check mouseover and clicked conditions
if button_rect.collidepoint(pos):
if pygame.mouse.get_pressed()[0] == 1:
clicked = True
pygame.draw.rect(SCREEN, self.click_col, button_rect)
elif pygame.mouse.get_pressed()[0] == 0 and clicked == True:
clicked = False
action = True
else:
pygame.draw.rect(SCREEN, self.hover_col, button_rect)
else:
pygame.draw.rect(SCREEN, self.button_col, button_rect)
# add shading to button
pygame.draw.line(SCREEN, WHITE, (self.x, self.y),
(self.x + self.width, self.y), 2)
pygame.draw.line(SCREEN, WHITE, (self.x, self.y),
(self.x, self.y + self.height), 2)
pygame.draw.line(SCREEN, BLACK, (self.x, self.y + self.height),
(self.x + self.width, self.y + self.height), 2)
pygame.draw.line(SCREEN, BLACK, (self.x + self.width, self.y),
(self.x + self.width, self.y + self.height), 2)
# add text to button
text_img = font.render(self.text, True, self.text_col)
text_len = text_img.get_width()
SCREEN.blit(text_img, (self.x + int(self.width / 2) -
int(text_len / 2), self.y + 25))
return action
again = button(75, 200, 'Play Again?')
quit = button(325, 200, 'Quit?')
def main():
RUN = True
SNAKE_POS_X = BLOCKSIZE
SNAKE_POS_Y = BLOCKSIZE
SNAKE_POS_X_CHANGE = 0
SNAKE_POS_Y_CHANGE = 0
LENGTH_OF_SNAKE = 1
global FOOD_POS_X, FOOD_POS_Y
FOOD_POS_X = round(random.randrange(
0, WIDTH - BLOCKSIZE) / BLOCKSIZE) * BLOCKSIZE
FOOD_POS_Y = round(random.randrange(
0, HEIGHT - BLOCKSIZE) / BLOCKSIZE) * BLOCKSIZE
while RUN:
for event in pygame.event.get():
if event.type == pygame.QUIT:
RUN = False
# snake_movement
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
SNAKE_POS_X_CHANGE = 0
SNAKE_POS_Y_CHANGE = -BLOCKSIZE
elif event.key == pygame.K_DOWN:
SNAKE_POS_X_CHANGE = 0
SNAKE_POS_Y_CHANGE = BLOCKSIZE
elif event.key == pygame.K_RIGHT:
SNAKE_POS_X_CHANGE = BLOCKSIZE
SNAKE_POS_Y_CHANGE = 0
elif event.key == pygame.K_LEFT:
SNAKE_POS_X_CHANGE = -BLOCKSIZE
SNAKE_POS_Y_CHANGE = 0
if SNAKE_POS_X >= WIDTH or SNAKE_POS_X < 0 or SNAKE_POS_Y >= HEIGHT or SNAKE_POS_Y < 0:
RUN = False
SNAKE_POS_X += SNAKE_POS_X_CHANGE
SNAKE_POS_Y += SNAKE_POS_Y_CHANGE
SCREEN.fill(BISQUE2)
checkerboard()
food()
SNAKE_HEAD = []
SNAKE_HEAD.append(SNAKE_POS_X)
SNAKE_HEAD.append(SNAKE_POS_Y)
SNAKE_LIST.append(SNAKE_HEAD)
if len(SNAKE_LIST) > LENGTH_OF_SNAKE:
del SNAKE_LIST[0]
for x in SNAKE_LIST[:-1]:
if x == SNAKE_HEAD:
RUN = False
snake(BLOCKSIZE, SNAKE_LIST)
score(LENGTH_OF_SNAKE - 1)
# draw_grid()
CLOCK.tick(FPS)
pygame.display.update()
if SNAKE_POS_X == FOOD_POS_X and SNAKE_POS_Y == FOOD_POS_Y:
FOOD_POS_X = round(random.randrange(
0, WIDTH - BLOCKSIZE) / BLOCKSIZE) * BLOCKSIZE
FOOD_POS_Y = round(random.randrange(
0, HEIGHT - BLOCKSIZE) / BLOCKSIZE) * BLOCKSIZE
LENGTH_OF_SNAKE += 1
CRUNCH.play()
game_over_message("Game Over!", BLACK)
GAME_OVER_SOUND.play()
# pygame.display.update()
if again.draw_button():
main()
if quit.draw_button():
pygame.quit()
pygame.display.update()
time.sleep(2)
pygame.quit()
main()
Is it because you do not have FOOD_POS_X, FOOD_POS_Y defined as this I got errors from these when I tried to run your code

Pygame not transitioning to the next image

I am working on my first python project. I have some buttons, 'Yes' and 'No' after the initial question of "do you want to play?". When I press no it closes the game. When I click yes, I'd like it for it to jump to the next function where it displays the text "so you've decided to play", and although I can see it jump to the next text for a little bit, it quickly switches back to the previous question and buttons of "Do you wish to play?" with the Yes and No buttons. How can I fix this? I've tried to order pygame.display.update() in different ways but so far no luck. Any help would be appreciated, thanks guys. Here is my code:
import pygame
pygame.init()
win=pygame.display.set_mode((800,700))
win.fill((255,255,255))
our_game_display=pygame.Surface((800,700))
font_name = pygame.font.get_default_font()
class button():
def __init__(self, color, x, y, width, height, text=''):
self.color = color
self.x = x
self.y = y
self.width = width
self.height = height
self.text = text
def draw(self, win, outline=None):
# Call this method to draw the button on the screen
if outline:
pygame.draw.rect(win, outline, (self.x - 2, self.y - 2, self.width + 4, self.height + 4), 0)
pygame.draw.rect(win, self.color, (self.x, self.y, self.width, self.height), 0)
if self.text != '':
font = pygame.font.SysFont('comicsans', 60)
text = font.render(self.text, 1, (255, 255, 255))
win.blit(text, (
self.x + (self.width / 2 - text.get_width() / 2), self.y + (self.height / 2 - text.get_height() / 2)))
def isOver(self, pos):
# Pos is the mouse position or a tuple of (x,y) coordinates
if pos[0] > self.x and pos[0] < self.x + self.width:
if pos[1] > self.y and pos[1] < self.y + self.height:
return True
return False
def yes_no_choice():
#win.fill((0,0,0))
YesButton.draw(win,(255,255,255))
NoButton.draw(win,(255,255,255))
def draw_text(text, size, x, y):
pygame.font.init()
font = pygame.font.Font(font_name, size)
text_surface = font.render(text, True, (255,255,255))
text_rect = text_surface.get_rect()
text_rect.center = (x, y)
our_game_display.blit(text_surface, text_rect)
def beginning_question():
our_game_display.fill((0, 0, 0))
draw_text('The story of this game depends on your choices. Do you wish to play?', 20, 800 / 2, 700 / 2 - 100)
win.blit(our_game_display, (0, 0))
yes_no_choice()
pygame.display.update()
def begin_game():
our_game_display.fill((0,0,0))
draw_text("So you've decided to play...very well.", 20, 800 / 2, 700 / 2 - 100)
win.blit(our_game_display,(0,0))
pygame.display.update()
#game loop
running = True
YesButton=button((0,0,0),100,500,250,100,'Yes')
NoButton=button((0,0,0),450,500,250,100,'No')
while running:
beginning_question()
for event in pygame.event.get():
pos=pygame.mouse.get_pos()
if event.type==pygame.QUIT:
running = False
pygame.quit()
quit()
if event.type==pygame.MOUSEBUTTONDOWN:
if YesButton.isOver(pos):
begin_game()
if NoButton.isOver(pos):
running=False
pygame.quit()
quit()
if event.type==pygame.MOUSEMOTION:
if YesButton.isOver(pos):
YesButton.color=(0,0,139)
elif NoButton.isOver(pos):
NoButton.color=(0,0,139)
else:
YesButton.color=(0,0,0)
NoButton.color=(0,0,0)
The reason why it only flashes for a second and then switches back is because the drawing for the "So you've decided to play" only happens in frames where you click the yes button. It should happen continuously after you hit the yest button. Here is one potential solution:
Have a boolean variable game_begun to keep track of whether the game has begun or not (initially false):
YesButton = button((0, 0, 0), 100, 500, 250, 100, 'Yes')
NoButton = button((0, 0, 0), 450, 500, 250, 100, 'No')
game_begun = False # New variable
After the user clicks the yes button, set that variable to true:
if event.type == pygame.MOUSEBUTTONDOWN:
if YesButton.isOver(pos):
game_begun = True
if NoButton.isOver(pos):
running = False
pygame.quit()
quit()
Finally, in the game loop (not the event loop), have a condition to check if the game has begun, and if so, then call the begin_game function. If not, then draw the beginning question:
if game_begun:
begin_game()
else:
beginning_question()
This might not be the absolute best solution, but it should suffice for your first python project. As you add more states to your game, you should use a string variable to keep track of you game state instead of a boolean. Happy coding!

Making a button in python using pygame [duplicate]

This question already has answers here:
Pygame mouse clicking detection
(4 answers)
How do I implement option buttons and change the button color in PyGame?
(2 answers)
How can I add an image or icon to a button rectangle in Pygame?
(1 answer)
Closed 1 year ago.
I was trying to make a button, the code works but I was trying to figure out how you can make the rectangle smaller and move it to the top left corner, I was also wondering how you can make multiple buttons. I would recommend if you could run the code in pycharm, and put the in the code to change the position.
Button Code:
import pygame
pygame.init()
win = pygame.display.set_mode((500, 500))
win.fill((255, 255, 255))
#START
class button():
def __init__(self, color, x, y, width, height, text=''):
self.color = color
self.x = x
self.y = y
self.width = width
self.height = height
self.text = text
def draw(self, win, outline=None):
# Call this method to draw the button on the screen
if outline:
pygame.draw.rect(win, outline, (self.x - 2, self.y - 2, self.width + 4, self.height + 4), 0)
pygame.draw.rect(win, self.color, (self.x, self.y, self.width, self.height), 0)
if self.text != '':
font = pygame.font.SysFont('comicsans', 60)
text = font.render(self.text, 1, (0, 0, 0))
win.blit(text, (
self.x + (self.width / 2 - text.get_width() / 2), self.y + (self.height / 2 - text.get_height() / 2)))
def isOver(self, pos):
# Pos is the mouse position or a tuple of (x,y) coordinates
if pos[1] > self.x and pos[1] < self.x + self.width:
if pos[1] > self.y and pos[1] < self.y + self.height:
return True
def redrawWindow ():
win.fill((255, 255, 255))
greenButton.draw(win, (0, 0, 0))
run = True
greenButton = button((0, 255, 0), 150, 225, 250, 100, 'Start')
while run:
redrawWindow()
pygame.display.update()
for event in pygame.event.get():
pos = pygame.mouse.get_pos()
if event.type == pygame.QUIT:
run = False
pygame.quit()
quit()
if event.type == pygame.MOUSEBUTTONDOWN:
if greenButton.isOver(pos):
print('clicked')
if event.type == pygame.MOUSEMOTION:
if greenButton.isOver(pos):
greenButton.color = (0,100,0)
else:
greenButton.color = (0, 255, 0)

My button operation seems to be misbehaving. What to do to fix it or make it better?

I'm using Python 3.7.4 and Pygame 1.9.6. This is kind of my first time with an object oriented in Python; and same with creating buttons. I'm just testing this, because I want to create a button for my Space Invaders game. I'm just unsure if this is an easy way to do it or what. And when I want to create another button. Do I just do what I did with the 'play_again_button'.
I came up with:
import pygame
class button():
def __init__(self, color, x, y, width, height, text=''):
self.color = color
self.x = x
self.y = y
self.width = width
self.height = height
self.text = text
def draw(self, screen, outline=None):
# Call this method to draw the button on the screen
if outline:
pygame.draw.rect(screen, outline, (self.x - 2, self.y - 2, self.width + 4, self.height + 4), 0)
pygame.draw.rect(screen, self.color, (self.x, self.y, self.width, self.height), 0)
if self.text != '':
font = pygame.font.SysFont('freesansbold.ttf', 60)
text = font.render(self.text, 1, (0, 0, 0))
screen.blit(text, (
self.x + (self.width / 2 - text.get_width() / 2), self.y + (self.height / 2 - text.get_height() / 2)))
def isOver(self, pos):
# Pos is the mouse position or a tuple of (x,y) coordinates
if self.x < pos[0] < self.x + self.width:
if self.y < pos[1] < self.y + self.height:
return True
return False
pygame.init()
screen = pygame.display.set_mode((800, 600))
running = True
play_again_button = button((20, 20, 20), (340, 340), 20, 30, 20, 'Play again')
while running:
pygame.display.update()
play_again_button.draw(screen)
screen.fill((255, 255, 255))
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.MOUSEBUTTONDOWN:
if play_again_button.isOver(1):
print("Clicked button")
if event.type == pygame.MOUSEMOTION:
if play_again_button.isOver(0):
play_again_button.color = (255, 0, 0)
else:
play_again_button.color = (0, 255, 0)
Anyways let me know if I should do a button like this or not. I always appreciate the feed back.
Making a button as an object is a good idea because it makes the code easier to understand, as it wraps up all the button properties into a single data structure, with member functions to act on it.
There's a couple of bugs in your code but it's mostly OK.
When you create the button, you're passing too many parameters, and some are tuples rather than individual integers:
play_again_button = button((20, 20, 20), (340, 340), 20, 30, 20, 'Play again') # BROKEN
play_again_button = button((20, 20, 20), 340, 340, 20, 30, 'Play again') # FIXED
Where the code does the mouse-position check, it's passing 1 or 0, and not the mouse event.pos, this is an easy fix:
if play_again_button.isOver( 1 ):
if play_again_button.isOver( event.pos ): # FIXED
Similarly for the mouse click-check.
And Finally the screen-painting is being done in a reverse order, so that the buttons is drawn before the screen is erased, so you never see the button.
Below is code that works. I moved the offset border code inside the button class.
According to Python Style Guide PEP8, class-names Should Be Capitalised too.
Ref:
import pygame
class Button():
def __init__(self, color, x, y, width, height, text='', outline=(0,0,0)):
self.color = color
self.x = x
self.y = y
self.width = width
self.height = height
self.text = text
self.outline = outline
def draw(self, screen):
# Call this method to draw the button on the screen
if self.outline:
pygame.draw.rect(screen, self.outline, (self.x - 2, self.y - 2, self.width + 4, self.height + 4), 0 )
pygame.draw.rect(screen, self.color, (self.x, self.y, self.width, self.height), 0)
if self.text != '':
font = pygame.font.SysFont('freesansbold.ttf', 60)
text = font.render(self.text, 1, (0, 0, 0))
screen.blit(text, (
self.x + int(self.width / 2 - text.get_width() / 2), self.y + int(self.height / 2 - text.get_height() / 2)))
def setColor( self, new_colour ):
self.color = new_color
def isOver(self, pos):
# Pos is the mouse position or a tuple of (x,y) coordinates
if self.x < pos[0] < self.x + self.width:
if self.y < pos[1] < self.y + self.height:
return True
return False
pygame.init()
screen = pygame.display.set_mode((800, 600))
running = True
DARK_GREY= ( 20, 20, 20 )
play_again_button = Button( DARK_GREY, 340, 340, 20, 30, 'Play again')
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.MOUSEBUTTONDOWN:
if play_again_button.isOver( event.pos ):
print("Clicked button")
if event.type == pygame.MOUSEMOTION:
if play_again_button.isOver( event.pos ):
play_again_button.setColor( (255, 0, 0) )
else:
play_again_button.setColor( (0, 255, 0) )
screen.fill((255, 255, 255))
play_again_button.draw(screen)
pygame.display.update()

"Stuttering" StartMenu for Pygame

I've been working on and off on a text-based adventure game for a few years now. It originally started as a way to learn Python, then I moved on to projects more relevant to my career after I became comfortable with the language. I'm now somewhat competent (Still a noob, but you know, progress) and I'd like to go back to the game to add in more complex functionality.
One thing that is annoying me is a visual bug in my start menu. Below is the code:
import pygame
from pygame_functions import setBackgroundImage
import gamefile
pygame.init()
display_width = 1500
display_height = 750
startMenu = pygame.display.set_mode((display_width, display_height))
pygame.display.set_caption("The Woodsman's Tale")
black = (0, 0, 0)
green = (0, 200, 0)
white = (255, 255, 255)
dark_red = (200, 0, 0)
bright_green = (0, 255, 0)
leaf_green = (0, 175, 75)
brown = (102, 51, 0)
red = (255, 0, 0)
clock = pygame.time.Clock()
def text_objects(text, font):
textSurface = font.render(text, True, black)
return textSurface, textSurface.get_rect()
def button(msg, x, y, w, h, ic, ac, action=None):
mouse = pygame.mouse.get_pos()
click = pygame.mouse.get_pressed()
if x + w > mouse[0] > x and y + h > mouse[1] > y:
pygame.draw.rect(startMenu, ac, (x, y, w, h))
if click[0] == 1 and action is not None:
if action == 'play':
gamefile.rungame()
start_menu().intro = False
elif action == 'quit':
pygame.quit()
quit()
else:
pygame.draw.rect(startMenu, ic, (x, y, w, h))
smallText = pygame.font.Font("freesansbold.ttf", 20)
TextSurf, TextRect = text_objects(msg, smallText)
TextRect.center = (x + (w / 2), (y + (h / 2)))
startMenu.blit(TextSurf, TextRect)
def start_menu():
intro = True
while intro:
setBackgroundImage('startScreen.png')
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
largeText = pygame.font.Font('BRADHITC.ttf', 90)
TextSurf, TextRect = text_objects("The Woodsman's Tale", largeText)
TextRect.center = (display_width / 2, display_height / 3)
startMenu.blit(TextSurf, TextRect)
button('Play', 350, 500, 200, 150, green, leaf_green, 'play')
button('Quit', 850, 500, 200, 150, dark_red, red, 'quit')
pygame.display.update()
clock.tick(15)
if __name__ == '__main__':
start_menu()
The setbackgroundimage function being imported is this:
def setBackgroundImage(img):
global bgSurface, backgroundImage
surf = loadImage(img)
backgroundImage = surf
screen.blit(surf, [0, 0])
bgSurface = screen.copy()
updateDisplay()
Now, the start menu works great. Everything functions properly. My issue is that when I click on the title bar, for example to move the window, the start menu begins stuttering visually.
Exactly what is happening is this: Once I click on the title bar, the "buttons" of the start menu and the Title text of the game disappear. Once the click is released, the buttons and Title text reappear, but stutter rapidly.
I'm not really sure if I'm providing enough for anyone to be able to tell what's going wrong, so I apologize if that's the case.
The fist issue is that setBackgroundImage seems to update the display (updateDisplay()).
The display has to be updated once at the end of the main application loop, and should not be updated multiple times. That cause the flickering. Remove the display update from setBackgroundImage:
def start_menu():
intro = True
while intro:
setBackgroundImage('startScreen.png') # draw background but do no update the display
# [...]
pygame.display.update() # the one and only update at the end of the loop
clock.tick(15)
The second issue, that the background image is loaded in setBackgroundImage. That cause that the image is loaded continuously in every frame. That causes a performance impact.
Load the image before the main loop and pass the Surface object to setBackgroundImage:
def start_menu():
surf = loadImage('startScreen.png')
intro = True
while intro:
setBackgroundImage(surf)
# [...]

Categories