#
# 2D platform scrolling game that teaches binary logic
-import sys, os, time, random, pygame
+import sys, os, time, random, math, pygame
import engine
# Use conditionals in the code to print useful information to the console using the form:
screen = None # the pygame Screen for the game window
def __init__(self, width, height, title, resources={}, debug=False):
+ os.environ['SDL_VIDEO_CENTERED'] = '1'
pygame.init()
self.debug = debug
self.myGame = engine.Game(width, height, title, resources, debug=self.debug)
+ if self.myGame.config['sound'] == 1:
+ self.myGame.soundtrack.playlist(self.myGame.resources['soundtrack'])
+
self.background_colour = (20, 20, 64)
if 'icon' in self.myGame.resources:
if self.debug: engine.debug_pr("pygame.image.get_extended()=%r" % pygame.image.get_extended())
# starting position
y = resolution[1] / 2
- if self.myGame.config['sound'] == 1:
- self.myGame.soundtrack.playlist(self.myGame.resources['soundtrack'])
-
self.myGame.config['auto_scroll'] = False
movement = 0 # represents number of pixels, and direction, of next scroll
x_pos = 0 # coordinate of left side of viewport
self.myGame.soundtrack.pause()
elif k == pygame.K_l:
self.myGame.config['auto_scroll'] = True if self.myGame.config['auto_scroll'] == False else False
+ elif k >= pygame.K_F1 and k <= pygame.K_F12:
+ self.stepping = k - (pygame.K_F1 - 1)
+ if self.myGame.config['auto_scroll']:
+ movement = int(math.copysign(self.stepping, movement))
+ if self.debug: engine.debug_pr("Keypress=%d, movement=%d" % (k, movement))
if event.type == pygame.USEREVENT:
if self.debug: engine.debug_pr("pygame.USEREVENT received; calling playlist_next()")
def main(width, height, title, resources={}, debug=False):
game = Base2Runner(width, height, title, resources, debug)
+ time.sleep(10) # keep splash screen up for a little longer
game.play()
exit(0)
resources['background'] = 'binary-1024x1024.jpg'
resources['splash'] = 'base2runner.jpg'
resources['soundtrack'] = 'Music'
+ resources['copyright'] = '© Copyright 2013 TJ <hacker@iam.tj>'
main(900, 600, "Base² Runner", resources, debug=True)
# use integers to control volume which avoids float rounding error issues
MAX = 100
MIN = 0
+ volume = 50
volume_step = 5
- def __init__(self, volume=1.0, channel_id=0, debug=False):
+
+ def __init__(self, volume=50, channel_id=0, debug=False):
""" Constructor.
volume: an SDL/PyGame floating-point with range 0.00 to 1.00. It is stored internally as an
integer with range 0 to 100 to avoid rounding errors when stepping the volume.
self.channel == None indicates this is the Music channel.
"""
- self.volume = int(volume*100)
self.channel_id = 0
self.debug = debug
self.paused = False
self.channel_id = channel_id
self.channel = pygame.mixer.Channel(self.channel_id)
+ self.set_volume(int(volume))
+
def set_volume(self, new_level):
""" Ensure the new level is within legal range and alter the mixer level """
if new_level >= Channel.MIN and new_level <= Channel.MAX:
class Game:
""" Container for all game state and configuration items """
config = dict()
+ fonts = dict()
+ colours = dict()
resources = None
def res_path(self, key):
if key in self.resources:
self.resources[key] = os.path.join(self.resources['path'], self.resources[key])
return True
-
- return False
+ else:
+ return False
def __init__(self, width=0, height=0, title="", resources={}, debug=False):
""" Constructor.
resources: Dictionary containing resources
debug: enable debug messages written to console
"""
+ # define the colour styles we need
+ self.colours['h1'] = (255, 255, 255)
+ self.colours['body'] = (0, 255, 255)
+
+ # store the received values
self.config.update({'width':width, 'height':height})
self.config.update({'title':title})
self.resolution = width, height
self.debug = debug
+ # prefix the resource path to all resource filenames
self.resources = resources
if not self.resources['path']:
self.resources['path'] = ''
self.res_path('soundtrack')
self.res_path('icon')
self.res_path('background')
+ self.res_path('splash')
# default values
+ self.resources['title'] = title
self.config.update({'sound':1}) # default to playing sound
self.play = False # Flag that controls exit from main loop
self.paused = False # Flag controlling pause of game play
self.soundtrack = engine.Channel(channel_id=-1, debug=self.debug)
self.sound_effects = engine.Channel(channel_id=0, debug=self.debug)
+ # splash screen
+ self.splash()
+
+ def splash(self):
+ # draw the splash screen
+ if self.resources['splash']:
+ # find out the image dimensions
+ self.splash_screen = pygame.display.set_mode((0,0), pygame.NOFRAME)
+ self.splash_image = pygame.image.load(self.resources['splash']).convert()
+ resolution = self.splash_image.get_size()
+ # draw a splash screen until the game is ready
+ if self.debug: engine.debug_pr("Splash screen=%s" % self.resources['splash'], resolution)
+ self.splash_screen = pygame.display.set_mode(resolution, pygame.NOFRAME)
+ self.splash_image = pygame.image.load(self.resources['splash']).convert()
+ self.splash_screen.blit(self.splash_image, (0,0))
+ self.fonts['h1'] = pygame.font.Font(None, 80)
+ self.fonts['body'] = pygame.font.Font(None, 30)
+ x, y = 40, 10
+ self.splash_screen.blit(self.fonts['h1'].render(self.resources['title'], True, self.colours['h1']), (x, y))
+ y += 80
+ self.splash_screen.blit(self.fonts['body'].render(self.resources['copyright'], True, self.colours['body']), (x, y))
+ pygame.display.update()
+
def pause(self):
""" Toggle the game's paused state """
self.paused = True if self.paused == False else False