Streamline the styled text printing code
[base2-runner.git] / engine / Game.py
1 #!/usr/bin/python3
2 # (c) Copyright 2013 TJ <hacker@iam.tj>
3 # Licensed on the terms of the GNU General Public License version 3 (see COPYING)
4 #
5 # Game engine: game state and configuration
6
7 import os.path, pygame, engine
8
9 class Style:
10  """ Encapsulate the attributes required for printing styled text """
11  font = None
12  colour = None
13  height = 0
14  debug = False
15  
16  def __init__(self, font, height, colour, debug=False):
17   self.font = pygame.font.Font(font, height)
18   self.height = height
19   self.colour = colour
20   Style.debug = debug
21   if Style.debug: engine.debug_pr("Style %s, height: %d, colour:" % (font, height), self.colour)
22
23 class Game:
24  """ Container for all game state and configuration items """
25  config = dict()
26  styles = dict()
27  resources = None
28  # text printing origin
29  print_x = 0
30  print_y = 0
31
32  def res_path(self, key):
33   """ Create a complete resource path
34    key:        the item in the resource dictionary to make path for
35   """
36   if key in self.resources:
37    self.resources[key] = os.path.join(self.resources['path'], self.resources[key])
38    return True
39   else:
40    return False
41
42  def __init__(self, width=0, height=0, title="", resources={},  debug=False):
43   """ Constructor.
44    width:      desired width of the game window
45    height:     desired height of the game window
46    title:      Window caption (title-bar)
47    resources:  Dictionary containing resources
48    debug:      enable debug messages written to console
49   """
50   # define the styles for printed text
51   self.styles['h1']   = engine.Style(None,  80, (255, 255, 255))
52   self.styles['body'] = engine.Style(None,  30, (255, 255, 0))
53
54   # store the received values
55   self.config.update({'width':width, 'height':height})
56   self.config.update({'title':title})
57   self.resolution = width, height
58   self.debug = debug
59
60   # prefix the resource path to all resource filenames
61   self.resources = resources
62   if not self.resources['path']:
63    self.resources['path'] = ''
64
65   self.res_path('soundtrack')
66   self.res_path('icon')
67   self.res_path('background')
68   self.res_path('splash')
69
70   # default values
71   self.resources['title'] = title
72   self.config.update({'sound':1}) # default to playing sound
73   self.play = False               # Flag that controls exit from main loop
74   self.paused = False             # Flag controlling pause of game play
75   self.soundtrack = engine.Channel(channel_id=-1, debug=self.debug)
76   self.sound_effects = engine.Channel(channel_id=0, debug=self.debug)
77
78   # splash screen
79   self.splash()
80
81  def print(self, text, style='body'):
82   """ print a line of text and move the text origin to the next line """
83   if not style in self.styles:
84    style = 'body'
85   # don't do a blit operation unless there is some text to render
86   if len(text) > 0:
87    self.splash_screen.blit(self.styles[style].font.render(text, True, self.styles[style].colour), (self.print_x, self.print_y))
88
89   self.print_y += self.styles[style].height # update the text origin
90
91  def splash(self):
92   # draw the splash screen 
93   if self.resources['splash']:
94    # find out the image dimensions
95    self.splash_screen = pygame.display.set_mode((0,0), pygame.NOFRAME)
96    self.splash_image = pygame.image.load(self.resources['splash']).convert()
97    resolution = self.splash_image.get_size()
98    # draw a splash screen until the game is ready
99    if self.debug: engine.debug_pr("Splash screen=%s" % self.resources['splash'], resolution)
100    self.splash_screen = pygame.display.set_mode(resolution, pygame.NOFRAME)
101    self.splash_image = pygame.image.load(self.resources['splash']).convert()
102    self.splash_screen.blit(self.splash_image, (0,0))
103    # print the Game title and copyright
104    self.print_x, self.print_y = 40, 40 # indent
105    self.print(self.resources['title'], 'h1')
106    self.print(self.resources['copyright'])
107    # print the Soundtrack copyright information
108    self.print('Soundtrack:',)
109    self.print_x += 20 # indent
110    for key in ('copyright', 'license', 'url'):
111     text = "%12s: %s" % (key, self.resources["soundtrack.%s" % key])
112     self.print(text)
113
114    pygame.display.update()
115
116   def pause(self):
117    """ Toggle the game's paused state """
118    self.paused = True if self.paused == False else False
119    if self.paused:
120     if self.config['sound']:
121      self.soundtrack.pause()
122      self.sound_effects.pause()
123    else:
124     if self.config['sound']:
125      self.soundtrack.unpause()
126      self.sound_effects.unpause()