This is an old revision of the document!
Table of Contents
PyGame Framework
This is a lighter version of pygame terminal, without the terminal stuff, mainly used for quickly making a 2d arcade style game. We will quickly go over the main points and then discuss changes and patterns discovered over the past several projects.
main.py
Unchanged from pygame terminal. It is possible to completely minimize main.py into a game = Game(), but that just passes the buck. Main should be the first place someone looks, so let's keep some 'headline information' there– the name of the program, general window information, and so on. We'll pass this information to Game, to keep Game's init as simple as possible.
from Window import Window
from Game import Game
def main():
window = Window()
window.setLogo("logo32x32.png")
window.setCaption("Bullet Game")
window.setSize(Screen.WIDTH, Screen.HEIGHT)
window.setFont("assets/ps2p.ttf", 32)
game = Game(window)
game.start()
if __name__ == "__main__":
main()
Screen and Window
The first thing we always do is have a Screen class and a Window class. The Screen class defines things like WIDTH and HEIGHT, and the Window class holds the pygame screen and other pygame initialization.
Initially, this code would appear at the start of a main.py. Later we moved it into class Game's init. However, to keep things clean we made it into it's own class.
class Screen:
This contains things like the width and height that will be needed by many different classes. This could also be put into window.
class Screen:
WIDTH = 800
HEIGHT = 600
MARGIN = 96
GAMETOP = MARGIN
GAMEBOT = HEIGHT - MARGIN
Here, margin and gametop are used as display boundaries for things like sprites so text can be drawn at the top of the screen and things stay within the edges of the screen. The most important parts are WIDTH and HEIGHT. A big question is, should Screen and Window be merged?
class Window:
| def init | This calls pygame.init(). See main |
| setLogo | this sets the little icon in the corner of the screen. It's the icon for the desktop, usually. Normally we don't care about this. |
| setCaption | This will set the title of the window. Usually the name of the program or game. |
| setFont | This will probably be moved to it's own Font class later. That way we can have multiple fonts if we want and it keeps the code a bit cleaner. |
full code
import pygame
from Screen import *
class Window:
def __init__(self):
pygame.init()
def setLogo(self, filename):
self.logo = pygame.image.load(filename)
pygame.display.set_icon(self.logo)
return self.logo
def setCaption(self, cap):
pygame.display.set_caption(cap)
def setSize(self, width, height):
self.width = width
self.height = height
self.size = (width, height)
self.screen = pygame.display.set_mode(self.size)
return self.screen
def setFont(self, filename, size):
pygame.font.init()
self.font = pygame.font.Font(filename, size)
font_width, font_height = self.font.size("@")
self.fontwidth = font_width
self.fontheight = size
return self.font
game.py
import pygame
import time
class Game:
def __init__(self, window):
self.window = window
self.screen = window.screen
self.logo = window.logo
self.font = window.font
# Clear the screen.
self.screen.fill((0, 0, 0))
# Set up game variables
self.running = True
def start(self):
# Main loop
while self.running == True:
self.checkEvents()
self.screen.fill((0, 0, 0)) # Clear the screen.
self.drawGame()
pygame.display.flip() # update the display.
time.sleep(1 / 60) # Sleep for 1/FPS, or about 60 fps.
def drawGame(self):
self.drawText(0, 2, "it works!", "gray")
def checkEvents(self):
for event in pygame.event.get():
if event.type == pygame.QUIT:
self.running = False
return
if event.type == pygame.KEYDOWN:
# key down event, process keys.
if event.key == pygame.K_LEFT:
pass
elif event.key == pygame.K_RIGHT:
pass
elif event.key == pygame.K_UP:
pass
elif event.key == pygame.K_DOWN:
pass
else:
pass
def drawText(self, at_x, at_y, text, color):
text_surface = self.font.render(text, False, color)
x = self.window.fontwidth * at_x
y = self.window.fontheight * at_y
self.screen.blit(text_surface, (x + 2, y))
