def test_projectile(self): with self.assertRaises(board_items.base.PglException) as e: board_items.Projectile(range=6, step=4) self.assertEqual(e.exception.error, "incorrect_range_step") p = board_items.Projectile() self.assertFalse(p.has_inventory()) self.assertTrue(p.overlappable()) self.assertTrue(p.restorable()) # Directional animations p.add_directional_animation(constants.DOWN, gfx_core.Animation()) with self.assertRaises(board_items.base.PglInvalidTypeException): p.add_directional_animation("crash", gfx_core.Animation()) with self.assertRaises(board_items.base.PglInvalidTypeException): p.add_directional_animation(constants.DOWN, "crash") with self.assertRaises(board_items.base.PglInvalidTypeException): p.directional_animation("crash") self.assertIsInstance( p.directional_animation(constants.DOWN), gfx_core.Animation ) self.assertIsNone(p.directional_animation(constants.UP)) p.movement_animation = gfx_core.Animation() self.assertIsInstance(p.directional_animation(constants.UP), gfx_core.Animation) with self.assertRaises(board_items.base.PglInvalidTypeException): p.remove_directional_animation("crash") self.assertIsNone(p.remove_directional_animation(constants.DOWN)) # Directional models p.add_directional_model(constants.DOWN, "|") with self.assertRaises(board_items.base.PglInvalidTypeException): p.add_directional_model("crash", "|") with self.assertRaises(board_items.base.PglInvalidTypeException): p.add_directional_model(constants.DOWN, 1) with self.assertRaises(board_items.base.PglInvalidTypeException): p.directional_model("crash") self.assertEqual(p.directional_model(constants.DOWN), "|") self.assertEqual(p.directional_model(constants.UP), "⌁") with self.assertRaises(board_items.base.PglInvalidTypeException): p.remove_directional_model("crash") self.assertIsNone(p.remove_directional_model(constants.DOWN)) with self.assertRaises(board_items.base.PglInvalidTypeException): p.set_direction("crash") self.assertIsNone(p.set_direction(constants.DOWN)) p.animation = gfx_core.Animation() p.hit_model = "*" self.assertIsNone(p.hit([board_items.BoardItemVoid])) def _r(): pass p.hit_animation = gfx_core.Animation(refresh_screen=_r, parent=p) self.assertIsNone(p.hit([board_items.BoardItemVoid])) def _cb(p, o, params): return True p.hit_callback = _cb self.assertIsNone(p.hit([board_items.BoardItemVoid]))
def test_projectile_management(self): def _hit(p, t, ex): if len(ex) > 0: ex[0].stop() def _fake_hit(p, t, ex): pass def _upd(g, i, dt): pass b = engine.Board() g = engine.Game(user_update=_upd) g.player = constants.NO_PLAYER self.assertIsNone(g.add_board(1, b)) g.change_level(1) p = board_items.Projectile(hit_model="*", hit_callback=_fake_hit, callback_parameters=[g]) p.actuator = None p.step = None self.assertIsNone(g.add_projectile(1, p, 1, 1)) self.assertIsNone(g.add_projectile(1, board_items.Projectile(), 1, 100)) b.place_item(board_items.Wall(), 5, 5) b.place_item(board_items.Wall(), 1, 3) p2 = board_items.Projectile(hit_model="*", hit_callback=_fake_hit, callback_parameters=[g]) p2.set_direction(constants.LEFT) g.add_projectile(1, p2, 1, 5) g.add_projectile( 1, board_items.Projectile(hit_model="*", hit_callback=_hit, callback_parameters=[g]), 8, 1, ) g.add_projectile( 1, board_items.Projectile( hit_model="*", hit_callback=_fake_hit, callback_parameters=[g], range=3, is_aoe=True, ), 9, 1, ) self.assertIsNone( g.add_projectile(1, board_items.Projectile(hit_callback=_hit), 5, 5)) self.assertIsNone( g.add_projectile( 1, board_items.Projectile(hit_callback=_hit, is_aoe=True), 5, 5)) with self.assertRaises(base.PglInvalidTypeException): g.add_projectile(1, board_items.Projectile(), "1") with self.assertRaises(base.PglInvalidTypeException): g.add_projectile(1, board_items.Projectile(), None, "1") with self.assertRaises(base.PglInvalidTypeException): g.add_projectile(1, board_items.Projectile(), 1, "1") with self.assertRaises(base.PglInvalidTypeException): g.add_projectile(1, board_items.Projectile(), "1", 1) with self.assertRaises(base.PglInvalidTypeException): g.add_projectile(1, 1) with self.assertRaises(base.PglInvalidTypeException): g.add_projectile("1", board_items.NPC()) self.assertIsNone(g.actuate_projectiles(1)) g.mode = constants.MODE_RT g.start() self.assertIsNone(g.actuate_projectiles(1)) with self.assertRaises(base.PglInvalidLevelException): g.actuate_projectiles(99) with self.assertRaises(base.PglInvalidTypeException): g.actuate_projectiles("1") g.run()
def ui_threaded(g): while g.state != constants.STOPPED: gravity(g) refresh_screen(g) g.actuate_projectiles(g.current_level) sleep(0.1) if g.state == constants.RUNNING: g.timer -= 0.1 for trap in g.current_board().get_immovables(type="trap."): # Only actually fire for traps that are on screen or close if ( trap.pos[1] > g.player.pos[1] + g.partial_display_viewport[1] + 5 or trap.pos[1] < g.player.pos[1] - g.partial_display_viewport[1] - 5 ): continue if trap.type == "trap.hfire": trap.fire_timer -= 0.1 if trap.fire_timer <= 0.0: proj = board_items.Projectile( model=bg_color + base.Text.yellow_bright("\U00002301\U00002301") + graphics.Style.RESET_ALL, name="zap", range=5, hit_model=bg_color + graphics.Models.HIGH_VOLTAGE + graphics.Style.RESET_ALL, hit_callback=zap_callback, ) proj.set_direction(trap.fdir) trap_shoot_wave_obj.play() if trap.fdir == constants.RIGHT: g.add_projectile( g.current_level, proj, trap.pos[0], trap.pos[1] + 1 ) else: g.add_projectile( g.current_level, proj, trap.pos[0], trap.pos[1] - 1 ) trap.fire_timer = 1.5 elif trap.type == "trap.vfire": trap.fire_timer -= 0.1 if trap.fire_timer <= 0.0: proj = board_items.Projectile( model=bg_color + graphics.Models.BOMB + graphics.Style.RESET_ALL, name="boom", range=2, hit_model=bg_color + graphics.Models.COLLISION + graphics.Style.RESET_ALL, hit_callback=boom_callback, is_aoe=True, aoe_radius=1, ) proj.set_direction(trap.fdir) trap_shoot_wave_obj.play() # Right now if the player sits on it, it does nothing. g.add_projectile( g.current_level, proj, trap.pos[0] - 1, trap.pos[1] ) trap.fire_timer = 2.5 if g.player.pos[0] == g.current_board().size[1] - 1: g.timer = 0.0 if round(g.timer, 1) <= 0.0: g.player.model = bg_color + graphics.Models.SKULL + graphics.Style.RESET_ALL g.player.remaining_lives -= 1 refresh_screen(g) if ( g.player.pos[0] == g.current_board().size[1] - 1 and g.player.dy == 0 ) or round(g.timer, 1) <= 0.0: if g.player.remaining_lives == 0: game_over_wave_obj.play() g.stop() g.config("settings")["hiscores"].append([g.player.name, g.score]) if len(g.config("settings")["hiscores"]) > 10: g.config("settings")["hiscores"] = sorted( g.config("settings")["hiscores"], reverse=True, key=lambda x: x[1], )[0:10] raise SystemExit() else: death_wave_obj.play() g.current_board().clear_cell(g.player.pos[0], g.player.pos[1]) potential_respawns = g.neighbors(2, g.player) g.player.model = ( bg_color + graphics.Models.PANDA + graphics.Style.RESET_ALL ) for o in potential_respawns: if o.type == "platform": g.current_board().place_item( g.player, g.current_board().size[1] - 10, o.pos[1] ) g.player.max_y = g.current_board().size[1] - 11 g.player.dy = 0 g.timer = 30 + 10 * g.player.remaining_lives break if len(g.obj_stack) > 0: new_stack = [] for o in g.obj_stack: if isinstance( g.current_board().item(o.pos[0], o.pos[1]), board_items.BoardItemVoid, ): g.current_board().place_item(o, o.pos[0], o.pos[1]) sprouted_trees = g.current_board().get_immovables( type="sprouted_tree" ) # Some times the game hangs and I wonder if it's not coming from # here. I'm trying to put a hard stop here. hard_stop = 0 while ( len(g.current_board().get_immovables(type="sprouted_tree")) > 2 and hard_stop < 20 ): goner = sprouted_trees[0] for i in sprouted_trees: if i.age < goner.age: goner = i g.current_board().clear_cell(goner.pos[0], goner.pos[1]) hard_stop += 1 else: new_stack.append(o) g.obj_stack = new_stack if g.player.inventory.size() > 0: for iname in g.player.inventory.items_name(): item = g.player.inventory.get_item(iname) pickup_wave_obj.play() if item.type == "treasure.scorers": g.score += int(item.value) elif item.type == "treasure.timers": g.timer += int(item.value) elif item.type == "treasure.diamond": g.timer += item.value g.score += int(item.value) elif item.type == "treasure.1UP": g.player.remaining_lives += 1 g.player.inventory.empty()
) wall = board_items.Wall(model=graphics.Models.BRICK) b.place_item(wall, 1, 6) g = engine.Game() g.add_board(1, b) g.player = board_items.Player(model=graphics.Models.MAGE, name="The Maje") g.player.mp = 20 g.player.max_mp = 20 g.change_level(1) key = None black_circle = "-\U000025CF" circle_jot = "-\U0000233E" throw_fireball = False projectile = board_items.Projectile() while True: if key == "Q": break elif key == "1": viewport = [10, 10] g.partial_display_viewport = viewport elif key == "2": viewport = [15, 30] g.partial_display_viewport = viewport elif key == "3": viewport = [20, 20] g.partial_display_viewport = viewport if key == " ": if g.player.mp >= 4:
if g.player.dy == 0 and len(g.neighbors(1, g.player)) > 0: # Jump # Start with sound jump_wave_obj.play() g.player.max_y = g.player.pos[0] - 3 g.player.dy = 1 elif key == "X": g.stop() break elif key in "awsdzq": projectile = board_items.Projectile( name="treeball", direction=constants.RIGHT, range=2, model=base.Text.green_bright( bg_color + " *" + graphics.Style.RESET_ALL ), hit_model=bg_color + graphics.Models.DECIDUOUS_TREE + graphics.Style.RESET_ALL, hit_callback=sprout, ) row = g.player.pos[0] column = g.player.pos[1] + 1 if key == "w" or key == "z": projectile.set_direction(constants.UP) row = g.player.pos[0] - 1 column = g.player.pos[1] elif key == "s": projectile.set_direction(constants.DOWN) row = g.player.pos[0] + 1 column = g.player.pos[1]