Pygame: strange glittering bug

I worked on a simple main menu in Python 3.1 and PyGame 2.7. When the mouse cursor is in a certain area, the text on the screen should be white. I use functions to light the screen. The first function usually reads the main menu, and the other two functions highlight the menu with highlighted text. Here are the functions:

def draw_main_menu(): #draw main menu normally screen.fill(BLACK) #clears screen #set up text new_text = menu_font.render('NEW GAME', 1, (100, 100, 100)) load_text = menu_font.render('LOAD GAME', 1, (100, 100, 100)) options_text = menu_font.render('OPTIONS', 1, (100, 100, 100)) quit_text = menu_font.render('QUIT', 1, (100, 100, 100)) #blit text screen.blit(new_text, (340, 425)) screen.blit(load_text, (335, 455)) screen.blit(options_text, (350, 485)) screen.blit(quit_text, (373, 515)) def draw_main_menu_ng(): #draw main menu with new game text in white screen.fill(BLACK) new_text = menu_font.render('NEW GAME', 1, (255, 255, 255)) load_text = menu_font.render('LOAD GAME', 1, (100, 100, 100)) options_text = menu_font.render('OPTIONS', 1, (100, 100, 100)) quit_text = menu_font.render('QUIT', 1, (100, 100, 100)) screen.blit(new_text, (340, 425)) screen.blit(load_text, (335, 455)) screen.blit(options_text, (350, 485)) screen.blit(quit_text, (373, 515)) def draw_main_menu_lg(): #draw main menu with load game text in white screen.fill(BLACK) new_text = menu_font.render('NEW GAME', 1, (100, 100, 100)) load_text = menu_font.render('LOAD GAME', 1, (255, 255, 255)) options_text = menu_font.render('OPTIONS', 1, (100, 100, 100)) quit_text = menu_font.render('QUIT', 1, (100, 100, 100)) screen.blit(new_text, (340, 425)) screen.blit(load_text, (335, 455)) screen.blit(options_text, (350, 485)) screen.blit(quit_text, (373, 515)) 

Below I use the x and y variables to check if the mouse cursor is over the buttons. The first set of two numbers is the range of the x coordinate, and the second set of two is the range of the y coordinate.

 x,y = pygame.mouse.get_pos() #set up new game mouse positions if x >= 340 and x <= 465: new_game_x_pos = True if x < 340 or x > 465: new_game_x_pos = False if y >= 425 and y <= 445: new_game_y_pos = True if y < 425 or y > 445: new_game_y_pos = False if new_game_x_pos == True and new_game_y_pos == True: draw_main_menu_ng() if new_game_x_pos == False or new_game_y_pos == False: draw_main_menu() #set up load game mouse positions if x >= 335 and x <= 470: load_game_x_pos = True if x < 335 or x > 470: load_game_x_pos = False if y >= 455 and y <= 475: load_game_y_pos = True if y < 455 or y > 475: load_game_y_pos = False if load_game_x_pos == True and load_game_y_pos == True: draw_main_menu_lg() if load_game_x_pos == False or load_game_y_pos == False: draw_main_menu() 

For some reason, when the mouse is over the "NEW GAME", it will not change color. When the mouse ends "LOAD GAME", it will change color. Before I add a boot game, it will change color, but now only the game will load. Any ideas on why it is not working?

By the way, I have a code in the game loop that updates the screen. I also have code to customize the font.

+2
source share
2 answers

The menu is drawn twice. When the mouse verification code evaluates the cursor over the NEW GAME, draw_main_menu_ng is draw_main_menu_ng . Nevertheless, the verification continues, and when it calculates the cursor does not exceed the LOAD GAME, it also calls draw_main_menu , negating the effects of calling draw_main_menu_ng .

The minimum solution is return after the cursor is inside the option:

 if new_game_x_pos == True and new_game_y_pos == True: draw_main_menu_ng() return 

Alternative solution

I added a complete example of how to make a backlit menu . I understand that this is much more than you ask, but if you just added the return code to the code, you will probably encounter other problems later. I made a complete example so that you can see a good way to avoid using literals and almost identical statements. I feel comfortable posting it because you will need to understand it in order to integrate it into the game.

+1
source

Instead of all if statements, it would be much easier to create a rectangle around the text and use the rect.collidepoint ((x, y)) (return bool) function. This will make your code much shorter and probably faster.

0
source

All Articles