PyGame will not work without a screen/window. So your code needs to first initialise PyGame, and then open a window (or full-screen display).
From my understanding of your code, it looks like it should display a menu:
> Play
Quit
Where pressing ↑/↓ (or w/s) moves the >
cursor between the options, and then space runs the option.
One of the issues with your code, is your trying to interpret the key-strokes inside the displaymanu()
function. It's best to keep a function doing a singular thing, so all key handling in processkey()
and only screen drawing in displaymanu()
.
I patched your code to the point where it works. This involved modifying the class so that it initialised the PyGame display. The menu needed to be displayed in the window, so calls to a new function drawTextAt()
were added in place of the print()
. Many of the member variables of class Maingame
had scope issues, but simply specifying self.
variable-name (which made them members of the class) fixed these.
I also added a game state to show how the key handling needs to change depending on what phase the game is currently in. It starts in menu, where Up/Down simply changes the menu option. But then later during the game play, Up/Down needs to do something entirely different.
import pygame
import os
# Window size
WINDOW_WIDTH = 400
WINDOW_HEIGHT = 400
# colours
DARK = ( 50, 50, 50 )
RED = ( 255, 50, 50 )
class Maingame:
def __init__(self):
# Initialise PyGame
pygame.init()
pygame.font.init()
# Initialise a window
pygame.display.set_caption("Main Game")
self.screen = pygame.display.set_mode( ( WINDOW_WIDTH, WINDOW_HEIGHT ), pygame.DOUBLEBUF )
# menu font
self.font = pygame.font.SysFont(None, 20)
self.hotkey = 1
self.crazy = 0
self.y_option = 0
self.game_state = 0 # state=0 -> show menu, 1 => Game, 2-> Game Over
def processkey(self):
# no key pressed yet
self.crazy = 0
dir_code = ''
exit = False
# Detect keys pressed
for event in pygame.event.get():
if event.type == pygame.QUIT:
exit = True
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
dir_code = ' '
self.crazy = 1
elif event.key == pygame.K_s or event.key == pygame.K_DOWN:
dir_code = 's'
self.y_option -= 1
self.hotkey = 2
elif event.key == pygame.K_w or event.key == pygame.K_UP:
dir_code = 'w'
self.y_option += 1
self.hotkey = 1
elif event.key == pygame.K_LEFT:
dir_code = 'a'
elif event.key == pygame.K_RIGHT:
dir_code = 'd'
else:
self.hotkey = 1
self.y_option = 0
self.crazy = 0
print( "DEBUG - game_state=[%d], dir_code is [%s], hotkey is [%d], crazy=[%d]" % ( self.game_state, dir_code, self.hotkey, self.crazy ) )
# Act on the keys pressed (if any)
if self.game_state == 0: # menu mode
if self.hotkey == 1 and self.crazy == 1:
self.game_state = 1 # start the game
elif self.hotkey == 2 and self.crazy == 1:
exit = True
elif self.game_state == 1: # game mode
pass # TODO
elif self.game_state == 2: # game-over mode
pass # TODO
return exit
def drawTextAt( self, text, coord, foreground_colour=(255,255,255) ):
""" Convert the specified text into a font-bitmap, and draw it
onto the screen at the given co-ordinates """
text_bitmap = self.font.render( text, True, foreground_colour )
self.screen.blit( text_bitmap, coord )
def displaymanu( self ):
""" Draw the Menu """
# MENU
self.screen.fill( DARK )
# Draw the menu options
prefix = [ " ", " " ]
prefix[ self.hotkey-1 ] = "> "
self.drawTextAt( prefix[0] + "Play", ( 30, 100 ) )
self.drawTextAt( prefix[1] + "Quit", ( 30, 150 ) )
def displaygame( self ):
""" Draw the Game Screen """
# GAME SCREEN
self.screen.fill( RED )
self.drawTextAt( "GAME - #TODO", ( 30, 180 ) )
def displaygameover( self ):
""" Draw the Game-Over Screen """
# GAME OVER SCREEN
self.screen.fill( RED )
self.drawTextAt( "* GAME OVER *", ( 30, 180 ) )
if __name__ == '__main__':
# Initialise PyGame and the window
displayee = Maingame()
quit = False
while not quit:
#os.system('cls')
# Draw the correct display for the state
if displayee.game_state == 0:
displayee.displaymanu()
elif displayee.game_state == 1:
displayee.displaygame()
elif displayee.game_state == 2:
displayee.displaygameover()
# Push all drawing to the screen
pygame.display.flip()
# Handle keys
quit = displayee.processkey()