2 # (c) Copyright 2013 TJ <hacker@iam.tj>
3 # Licensed on the terms of the GNU General Public License version 3 (see COPYING)
5 # 2D platform scrolling game that teaches binary logic
7 import sys, os, time, random, math, pygame
8 import engine, circuits
10 # Use conditionals in the code to print useful information to the console using the form:
11 # if self.debug: engine.debug_pr("some_var=%d, another_var=%s" % (some_var, another_var), somevalue, another_value)
14 background_image = None
15 stepping = 8 # pixels scrolled each flip
16 delay = 0.01 # main loop sleep (100 milliseconds)
17 background_colour = (0, 0, 0)
18 background_image = None
20 flags = pygame.OPENGL & pygame.DOUBLEBUF
22 screen = None # the pygame Screen for the game window
24 def __init__(self, width, height, title, resources={}, debug=False):
25 os.environ['SDL_VIDEO_CENTERED'] = '1'
28 self.myGame = engine.Game(width, height, title, resources, debug=self.debug)
29 if self.myGame.config['sound'] == 1:
30 self.myGame.soundtrack.playlist(self.myGame.resources['soundtrack'])
32 self.background_colour = (20, 20, 64)
33 if 'icon' in self.myGame.resources:
34 if self.debug: engine.debug_pr("pygame.image.get_extended()=%r" % pygame.image.get_extended())
35 self.icon_image = pygame.image.load(self.myGame.resources['icon'])
36 pygame.display.set_icon(self.icon_image)
39 self.screen = pygame.display.set_mode(self.myGame.resolution, self.flags, self.depth)
40 self.screen.fill(self.background_colour)
41 pygame.display.set_caption(self.myGame.config['title'])
42 resolution = self.screen.get_size()
45 self.background_image = engine.SeamlessBackground(self.myGame.resources['background'], debug=self.debug)
46 self.background_image.draw(self.screen, -1, 0) # -1 flags initial background drawing
47 pygame.display.update()
50 blip = pygame.Surface((abs(self.stepping), abs(self.stepping)), pygame.HWSURFACE)
51 blip_colour = (128, 128, 128)
52 blip.fill(blip_colour)
57 self.myGame.config['auto_scroll'] = False
58 movement = 0 # represents number of pixels, and direction, of next scroll
59 x_pos = 0 # coordinate of left side of viewport
61 self.myGame.play = True # start the game
62 while (self.myGame.play):
64 if not self.myGame.paused:
66 if x_pos + movement >= 0:
71 # change colour randomly
72 d_red = random.randrange(-1,2) *8
73 d_green = random.randrange(-1,2) *8
74 d_blue = random.randrange(-1,2) *8
75 # build a modified colour tuple, ensuring all values are valid
76 blip_colour = tuple( b+d if b+d < 256 and b+d >=0 else b for b, d in zip(blip_colour, (d_red, d_green, d_blue)) )
77 blip.fill(blip_colour)
79 # change blip position up or down randomly by one step
80 dy = random.randrange(-1,2) * abs(self.stepping)
81 if((y + dy) < resolution[1] and (y + dy) >= 0):
82 # TODO: no longer need to redraw background colour if using a background image
83 # screen.fill(background_colour, pygame.Rect(resolution[0] - abs(stepping), y, abs(stepping), abs(stepping) ))
87 self.screen.scroll(-movement, 0)
88 self.background_image.draw(self.screen, x_pos, movement)
89 self.screen.blit(blip, (resolution[0] - abs(self.stepping), y))
90 pygame.display.update()
92 # manage the frame-rate
93 time.sleep(self.delay)
96 for event in pygame.event.get():
97 if event.type == pygame.QUIT or (event.type == pygame.KEYUP and event.key == pygame.K_q):
98 self.myGame.play = False
99 if event.type == pygame.ACTIVEEVENT:
100 if self.debug: engine.debug_pr("active=%d, pygame.ACTIVEEVENT:" % pygame.display.get_active(), event)
101 if event.type == pygame.KEYUP:
105 elif k == pygame.K_7:
106 self.myGame.soundtrack.pause()
107 elif k == pygame.K_l:
108 self.myGame.config['auto_scroll'] = True if self.myGame.config['auto_scroll'] == False else False
109 elif k >= pygame.K_F1 and k <= pygame.K_F12:
110 self.stepping = k - (pygame.K_F1 - 1)
111 if self.myGame.config['auto_scroll']:
112 movement = int(math.copysign(self.stepping, movement))
113 if self.debug: engine.debug_pr("Keypress=%d, movement=%d" % (k, movement))
115 if event.type == pygame.USEREVENT:
116 if self.debug: engine.debug_pr("pygame.USEREVENT received; calling playlist_next()")
117 self.myGame.soundtrack.playlist_next()
119 if not self.myGame.config['auto_scroll']:
120 # reset if not auto-scrolling
123 # detect which keys are held down
124 keys_pressed = pygame.key.get_pressed()
125 if sum(keys_pressed):
126 if keys_pressed[pygame.K_6]:
128 self.myGame.soundtrack.volume_down()
129 elif keys_pressed[pygame.K_8]:
131 self.myGame.soundtrack.volume_up()
132 elif keys_pressed[pygame.K_d]:
134 movement = self.stepping
135 elif keys_pressed[pygame.K_a]:
137 movement = -self.stepping
140 self.myGame.soundtrack.fadeout(5000)
142 pygame.display.quit()
145 def main(width, height, title, resources={}, debug=False):
146 game = Base2Runner(width, height, title, resources, debug)
147 time.sleep(10) # keep splash screen up for a little longer
151 if __name__ == '__main__':
153 resources['path'] = 'resources'
154 resources['icon'] = 'base2runner-icon.png'
155 resources['background'] = 'binary-1024x1024.jpg'
156 resources['splash'] = 'base2runner.jpg'
157 resources['copyright'] = '© Copyright 2013 TJ <hacker@iam.tj>'
158 resources['soundtrack'] = 'Music'
159 resources['soundtrack.copyright'] = 'Rolemusic @ The Free Music Archive'
160 resources['soundtrack.license'] = 'Creative Commons Attribution Non-Commercial Share-Alike'
161 resources['soundtrack.url'] = 'http://freemusicarchive.org/music/Rolemusic/'
162 main(900, 600, "Base² Runner", resources, debug=True)