--- a/AllAboutMonstrs/__main__.py +++ b/AllAboutMonstrs/__main__.py @@ -13,10 +13,9 @@ SCREENRES = (1024,768) -def main(args): +async def main(args): """ Here begins the operation of the analytical engine """ pygame.display.init() - pygame.mixer.init() flags = pygame.FULLSCREEN if args.full else 0 screen = pygame.display.set_mode(SCREENRES, flags) pygame.display.set_caption("Blastosaurus Rex") @@ -24,7 +23,9 @@ current_situation.args = args shepherd = modes.ShepherdOfModes() start_state = args.test_start_state if args.test_start_state else "Introductory" - shepherd.begin(start_state, current_situation) - pygame.quit() + # "Termination" only goes back to the first page: there is nowhere to quit to in the browser + while True: + await shepherd.begin(start_state, current_situation) + start_state = "Introductory" --- a/AllAboutMonstrs/accounting_mode.py +++ b/AllAboutMonstrs/accounting_mode.py @@ -22,13 +22,13 @@ class AccountingMode(ModeOfOperation): """ Whereby the current situation is assessed, and stock is taken of the colony's wealth and population """ - def operate(self, current_situation): + async def operate(self, current_situation): self.situation = current_situation self.initialize() self.assess() self.finished = False while not self.finished: - self.clock.tick(30) + await self.tick(30) self.respond_to_the_will_of_the_operator() if self.defeated: current_situation.reload_game() --- a/AllAboutMonstrs/all_things_known.py +++ b/AllAboutMonstrs/all_things_known.py @@ -7,7 +7,7 @@ ALL_THINGS = {} for m in facilities, units, bestiary: - classes = dict((c.__name__, c) for c in vars(m).values() if hasattr(c, "name")) + classes = dict((c.__name__, c) for c in vars(m).values() if isinstance(c, type) and hasattr(c, "name")) ALL_THINGS.update(classes) def find_by_name(short_name): --- a/AllAboutMonstrs/chapters.py +++ b/AllAboutMonstrs/chapters.py @@ -111,7 +111,7 @@ def random_wave(dino_names, hoard_size): wave = [] - for i in xrange(hoard_size): + for i in range(hoard_size): wave.append((random.choice(dino_names), random.randint(-800, -20), random.randint(grid.NORTHERN_LIMIT + 30, grid.SOUTHERN_LIMIT - 30))) --- a/AllAboutMonstrs/chapterstart_mode.py +++ b/AllAboutMonstrs/chapterstart_mode.py @@ -12,7 +12,7 @@ class ChapterStartMode(ModeOfOperation): """ The mode by which one is informed of the current situation. """ - def operate(self, current_situation): + async def operate(self, current_situation): self.situation = current_situation self.situation.in_game = True self.initialize() @@ -20,7 +20,7 @@ self.finished = False self.next_mode = None while not self.finished: - ms = self.clock.tick(60) + ms = await self.tick(60) self.respond_to_the_will_of_the_operator() self.redraw() return self.next_mode --- a/AllAboutMonstrs/encyclopaedia_mode.py +++ b/AllAboutMonstrs/encyclopaedia_mode.py @@ -33,7 +33,7 @@ class EncyclopaediaMode(ModeOfOperation): """ Whereby the operator of the device can be presented with the fruits of the latest researches in Natural Philosophy """ - def operate(self, current_situation): + async def operate(self, current_situation): self.situation = current_situation self.initialize() self.finished = False @@ -41,7 +41,7 @@ self.backbutton = gui.make_menu((650,600),[("Regress","back")],200) self.draw_current_page() while not self.finished: - ms = self.clock.tick(60) + ms = await self.tick(60) self.respond_to_the_will_of_the_operator() self.draw_current_page() return self.next_mode --- a/AllAboutMonstrs/exposition_mode.py +++ b/AllAboutMonstrs/exposition_mode.py @@ -39,14 +39,14 @@ class ExpositionMode(ModeOfOperation): """ The mode by which the premise is communicated to a new initiate to the entertainment. """ - def operate(self, current_situation): + async def operate(self, current_situation): self.name = current_situation.savename self.initialize() self.redraw() self.finished = False self.next_mode = "ChapterStart" while not self.finished: - ms = self.clock.tick(60) + ms = await self.tick(60) self.exposition.advance(ms) self.respond_to_the_will_of_the_operator() self.redraw() --- a/AllAboutMonstrs/gui.py +++ b/AllAboutMonstrs/gui.py @@ -40,7 +40,7 @@ if not shillings: shillings = "-" if not bence: bence = "-" fmt = "(£{0} / {1} / {2} b)" if debit else "£{0} / {1} / {2} b" - return unicode(fmt.format(pounds, shillings, bence), "utf-8") + return fmt.format(pounds, shillings, bence) def make_menu(position,options,width,prompt=None): contents = [] --- a/AllAboutMonstrs/information_mode.py +++ b/AllAboutMonstrs/information_mode.py @@ -65,14 +65,14 @@ class InformationMode(ModeOfOperation): - def operate(self, current_situation): + async def operate(self, current_situation): self.page = 0 self.finished = False self.backbutton = gui.make_menu((650,600),[("Regress","back")],200) self.next_mode = "Introductory" self.draw_current_page() while not self.finished: - ms = self.clock.tick(60) + ms = await self.tick(60) self.respond_to_the_will_of_the_operator() return self.next_mode --- a/AllAboutMonstrs/introductory_mode.py +++ b/AllAboutMonstrs/introductory_mode.py @@ -11,7 +11,7 @@ class IntroductoryMode(ModeOfOperation): """ The mode serving as an introduction. """ - def operate(self, current_situation): + async def operate(self, current_situation): self.situation = current_situation self.situation.in_game = False self.initialize() @@ -19,7 +19,7 @@ self.finished = False self.next_mode = None while not self.finished: - ms = self.clock.tick(60) + ms = await self.tick(60) self.respond_to_the_will_of_the_operator() self.redraw() return self.next_mode @@ -56,7 +56,7 @@ saves = [os.path.basename(s) for s in saves][:8] savenames = ["%s: Chapter %d"%(s.split("-")[0],int(s.split("-")[1])+1) for s in saves] self.load_menu = gui.make_menu((300,150), - zip(savenames,saves)+[("Regress","back")],400, + list(zip(savenames,saves))+[("Regress","back")],400, prompt="Select Situation") return self.load_menu --- a/AllAboutMonstrs/modes.py +++ b/AllAboutMonstrs/modes.py @@ -8,6 +8,7 @@ result og the operation is a symbolic representation of the succeeding mode. """ +import asyncio import pygame class ModeOfOperation(object): @@ -17,7 +18,12 @@ self.screen = pygame.display.get_surface() self.clock = pygame.time.Clock() - def operate(self, current_situation): + async def tick(self, fps): + """ one frame: yield to the browser and report the milliseconds elapsed """ + await asyncio.sleep(0) + return self.clock.tick() + + async def operate(self, current_situation): return None def clear_screen(self, colour=(0,0,0), image=None): @@ -32,8 +38,6 @@ operator depresses a key, on_keydown(e) will be performed. """ for e in pygame.event.get(): - if e.type == pygame.KEYDOWN and e.key == pygame.K_F11: - pygame.display.toggle_fullscreen() whatkind = pygame.event.event_name(e.type) action = getattr(self, "on_" + whatkind.lower(), None) if action: @@ -43,7 +47,7 @@ class ShepherdOfModes(object): """ That which directs the orderly transition between modes """ - def begin(self, mode_name, current_situation): + async def begin(self, mode_name, current_situation): while mode_name: try: mode = MODES_IN_USE[mode_name] @@ -52,4 +56,4 @@ module = __import__(module_name) mode = getattr(module, mode_name + "Mode")() MODES_IN_USE[mode_name] = mode - mode_name = mode.operate(current_situation) + mode_name = await mode.operate(current_situation) --- a/AllAboutMonstrs/onslaught_mode.py +++ b/AllAboutMonstrs/onslaught_mode.py @@ -17,12 +17,12 @@ """ Wherein reptilian foes descend upon you and you must fight them lest the colony be destroyed. """ - def operate(self, current_situation): + async def operate(self, current_situation): self.situation = current_situation self.initialize() while not self.finished: - ms = self.clock.tick(60) + ms = await self.tick(60) self.respond_to_the_will_of_the_operator() self.move_dinosaurs(ms) self.move_units(ms) @@ -40,7 +40,6 @@ def on_keydown(self, e): if e.key == pygame.K_w: - print "Dinosaurs:", self.dinosaurs self.finished = True def on_quit(self, e): --- a/AllAboutMonstrs/phonographs.py +++ b/AllAboutMonstrs/phonographs.py @@ -6,7 +6,7 @@ VOLUME_LEVEL = 0.5 PHONOGRAPHS = {} -SOUND_ON = True +SOUND_ON = False MUSIC_PLAYING = None def play(phonograph_name): @@ -38,7 +38,7 @@ def enable_sound(): global SOUND_ON - SOUND_ON = True + SOUND_ON = False def orchestrate(phonograph_name, once=False): if not SOUND_ON: --- a/AllAboutMonstrs/preparation_mode.py +++ b/AllAboutMonstrs/preparation_mode.py @@ -23,12 +23,12 @@ """ The mode in which one invests in construction of defenses against impending assault by reptiles. """ - def operate(self, current_situation): + async def operate(self, current_situation): self.situation = current_situation self.initialize() while not self.finished: - ms = self.clock.tick(30) + ms = await self.tick(30) self.respond_to_the_will_of_the_operator() if self.indicate_lot: --- a/AllAboutMonstrs/situation.py +++ b/AllAboutMonstrs/situation.py @@ -135,7 +135,7 @@ self.load_game(savefile) def get_save_dir(self): - savedir = os.path.expanduser("~/.blastosaurusrex") + savedir = "/saves" if os.path.isdir("/saves") else os.path.expanduser("~/.blastosaurusrex") if not os.path.exists(savedir): os.makedirs(savedir) return savedir --- a/AllAboutMonstrs/typefaces.py +++ b/AllAboutMonstrs/typefaces.py @@ -20,7 +20,7 @@ def init(): pygame.font.init() - path = data.filepath("Anaktoria.otf") + path = data.filepath("IMFeENrm28P.ttf") for appelation, size in STYLE_SIZES.items(): FONTS[appelation] = Font(path, size) @@ -44,7 +44,7 @@ numcolumns = len(rows[0]) numrows = len(rows) def u(n): - return n if isinstance(n, unicode) else unicode(n) + return n if isinstance(n, str) else str(n) shapes = [[f.size(u(col)) for col in row] for row in rows] maxheight = max(max(shape[1] for shape in shaperow) for shaperow in shapes) widths = [max(shaperow[i][0] for shaperow in shapes) for i in range(numcolumns)] --- a/AllAboutMonstrs/units.py +++ b/AllAboutMonstrs/units.py @@ -199,8 +199,8 @@ px, py = position[:2] dx = px - cx dy = py - cy - steep = (dx == 0) or abs(dy / dx) > 3 - shallow = (dy == 0) or abs(dx / dy) > 3 + steep = (dx == 0) or abs(dy // dx) > 3 + shallow = (dy == 0) or abs(dx // dy) > 3 if steep: return 0 if dy < 0 else 4 if shallow: --- a/AllAboutMonstrs/victory_mode.py +++ b/AllAboutMonstrs/victory_mode.py @@ -21,14 +21,14 @@ class VictoryMode(ModeOfOperation): """ Whereby the finale situation is assessed, and victory is celebrated """ - def operate(self, current_situation): + async def operate(self, current_situation): self.situation = current_situation self.initialize() self.assess() self.finished = False - self.clock.tick(30) + await self.tick(30) while not self.finished: - ms = self.clock.tick(30) + ms = await self.tick(30) self.credits.advance(ms) self.respond_to_the_will_of_the_operator() self.redraw() @@ -97,7 +97,7 @@ flip() CREDITS = u""" -⸙ Blastosaurus Rex ⸙ +* Blastosaurus Rex * An entertainment in the form of an interactive experience, performed upon the analytical engine. @@ -111,8 +111,7 @@ Our praise and gratitude goes to the following: -☞ Mr George Douros for his superb Anaktoria font. -(http://www.fonts2u.com/anaktoria.font) +☞ Igino Marini, for the IM Fell English typeface. ☞ The Skidmore College Orchestra for their delightful rendition of Tchaikovsky's 1812 Overture. --- a/main.py +++ b/main.py @@ -0,0 +1,18 @@ +import pygame +import asyncio +import os +import sys + +# Browser launcher (replaces run_game.py of the original) +sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) +import AllAboutMonstrs.__main__ + + +class Args(object): + test_start_state = None + debug_rectangles = False + full = False + sheep = False + + +asyncio.run(AllAboutMonstrs.__main__.main(Args()))