class MonorailGame: STATE_INTRO, STATE_BEGIN, STATE_GAME, STATE_MENU, STATE_QUIT, STATE_STATS, STATE_TOTAL,\ STATE_DONE = range( 8 ) MOUSE_TIMEOUT = 25 * 3 def __init__( self, game_data ): self.restart( game_data ) self.music_man = MusicManager() # preload clock sounds and big explosion graphic resman.get("game.clock_sound") resman.get("game.clockring_sound") resman.get("game.explosion_sprite") def restart( self, game_data ): """Start a new game with the current game_data""" self.game_data = game_data self.state = MonorailGame.STATE_INTRO self.scenario = self.game_data.get_quest().create_scenario(self.game_data.skill_level.value) self.playfield = self.scenario.playfield self.controller = ctrl.GroundControl( self.playfield ) self.init_goldcars() self.hud = Hud( self.scenario, self.controller, self.game_data ) self.hud.start_intro_screen() self.begin_timeout = 25 * 3 self.ingame_menu = None self.gui_state = GuiState() self.mouse_timeout = MonorailGame.MOUSE_TIMEOUT self.is_paused = False def init_goldcars( self ): goldcar_names = [] controllers = [] for name, controller in self.game_data.goldcars: goldcar_names.append( name ) controllers.append( controller ) for iq in self.game_data.get_quest().get_opponent_iqs(): goldcar_names.append( "" ) controllers.append( ctrl.AiController( None, iq ) ) self.playfield.add_goldcars( goldcar_names ) self.controller.add_controllers( controllers ) def do_tick( self, indev ): if self.ingame_menu is None and not self.is_paused: if self.game_data.is_single_player() or \ self.game_data.is_single_random(): SingleSwitch.feed_keys( indev ) # in singleplayer, all joystick buttons are keypress for joy in indev.joys: if joy.any_went_down(): indev.key.feed_down( K_SPACE ) if joy.any_went_up(): indev.key.feed_up( K_SPACE ) if self.state == MonorailGame.STATE_INTRO: if self.hud.is_ready(): # or self.game_data.is_single_player(): self.hud.end_info() self.state = MonorailGame.STATE_BEGIN self.music_man.play() elif self.state == MonorailGame.STATE_BEGIN: if self.begin_timeout % 50 == 0: random_spawn = not self.game_data.is_single_player(); spawns_left = self.playfield.spawn_next_goldcar( random_spawn ) if spawns_left: self.begin_timeout += 50 self.controller.game_tick( indev ) self.playfield.game_tick() # Start right away in single player if self.game_data.is_single_player(): self.scenario.game_tick() self.begin_timeout -= 1 if self.begin_timeout <= 0: self.state = MonorailGame.STATE_GAME if indev.mouse.has_moved(): self.mouse_timeout = MonorailGame.MOUSE_TIMEOUT else: self.mouse_timeout -= 1 elif self.state == MonorailGame.STATE_GAME: self.controller.game_tick( indev ) self.playfield.game_tick() self.scenario.game_tick() if self.scenario.is_finished(): if not self.game_data.is_single_player(): self.hud.start_end_screen() else: self.game_data.get_quest().save_score( self.scenario ) skill = self.game_data.get_quest().get_skill( self.scenario ) self.game_data.skill_level.update( skill ) self.game_data.save_single_player_progress() if self.scenario.has_won(): self.hud.start_win_screen() else: self.hud.start_lose_screen() self.state = MonorailGame.STATE_STATS self.mouse_timeout = MonorailGame.MOUSE_TIMEOUT self.music_man.stop() if indev.mouse.has_moved(): self.mouse_timeout = MonorailGame.MOUSE_TIMEOUT else: self.mouse_timeout -= 1 elif self.state == MonorailGame.STATE_STATS: if self.hud.is_ready(): if not self.game_data.is_single_player(): self.game_data.add_total_scores( self.playfield ) self.hud.start_total_screen() self.state = MonorailGame.STATE_TOTAL else: if self.scenario.has_won(): self.state = MonorailGame.STATE_DONE else: self.restart( self.game_data ) return elif self.state == MonorailGame.STATE_TOTAL: if self.hud.is_ready(): self.state = MonorailGame.STATE_DONE elif self.state == MonorailGame.STATE_MENU: pass self.hud.game_tick( indev ) self.music_man.game_tick() SingleSwitch.tick( indev, None ) if indev.key.went_down( K_ESCAPE ) or \ self.hud.menu_btn.went_down() or \ SingleSwitch.esc_went_down: resman.get("gui.paper_sound").play() self.ingame_menu = IngameMenu(self.game_data.is_single_player(), self.game_data) elif self.ingame_menu is not None: # Ingame Menu SingleSwitch.feed_keys( indev ) self.gui_state.update( indev, self.ingame_menu ) self.ingame_menu.tick( indev, self.gui_state ) if self.ingame_menu.is_done(): if self.ingame_menu.to_menu: self.music_man.stop() self.state = MonorailGame.STATE_MENU elif self.ingame_menu.should_quit: self.music_man.stop() self.state = MonorailGame.STATE_QUIT elif self.ingame_menu.to_next_level: self.music_man.stop() self.state = MonorailGame.STATE_DONE self.ingame_menu = None self.mouse_timeout = MonorailGame.MOUSE_TIMEOUT # if indev.key.went_down( K_p ): # self.is_paused = not self.is_paused event.Event.update() # for debugging if self.is_paused: self.controller.game_tick( indev ) def draw( self, surface, interpol, time_sec ): #surface.fill( (0,0,0) ) frame = Frame( surface, time_sec, interpol ) if self.ingame_menu is not None or self.is_paused or\ self.state not in [MonorailGame.STATE_BEGIN, MonorailGame.STATE_GAME]: frame.interpol = 0.0 frame.draw( self.playfield ) frame.draw( self.controller ) self.hud.draw( frame ) if self.ingame_menu is not None: self.ingame_menu.draw( surface ) frame.draw( event.Event.instance ) def draw_mouse( self, surface, interpol, time_sec ): if self.mouse_timeout > 0: x, y = pygame.mouse.get_pos() resman.get("gui_surf").draw( surface, Vec2D(x, y), (0,0,32,32) ) def mouse_down( self, button ): pass def is_done( self ): return self.state == MonorailGame.STATE_DONE \ or self.state == MonorailGame.STATE_MENU \ or self.state == MonorailGame.STATE_QUIT
class World: # This is the __init__ # its important. def __init__(self, app, screen): # tock started out random, but now is an important variable. # It is a frames count, used for periodic updates on certain # frames. self.p_max_health = 5 self.won = False self.won_msg = "WINNER!" self.particle_ban = False self.wait_stop_count = -1 # -1 means do not count self.wait_stop_max = 120 # wait this many frames after decay # before showing menu self.tock = 0 self.stage_e_bullet_odds = 15 self.mouse_rect = None self.temp_rect = None self.app = app self.screen = screen self.app.music_name = "intro.ogg" # self.app.continue_music() if self.app.settings['music']: # self.app.music_loaded = self.app.music_name # pygame.mixer.music.load(self.app.resource_find( # self.music_name)) # pygame.mixer.music.play() # plays once PLUS repeats param pass left_border = 50 right_border = 50 w, h = screen.get_size() self.world_rect = pygame.Rect(left_border, 0, w-right_border-left_border, h) self.bg = BackgroundManager(self.world_rect) # Yay spritegroups! They make the world go round, and iterate. # Basically each visible game object resides in its own special # spritegroup & then all one needs to do is go through these & # call functions & stuff. # It makes sense in here *points to brain* self.p_swarm = Swarm(self.world_rect) self.particles = Swarm(self.world_rect) self.explosion_images = self.app.load_seq('ex-medium') self.shield_hit_images = self.app.load_seq('shield_hit-tiny') self.damage_images = self.app.load_seq('ex-tiny') # Load player sprite as image list. self.p_unit_images = self.app.load_seq('pship') # self.p_unit_images = [] # self.p_unit_images.append(self.load_file('pship.png')) # self.p_unit_images.append(self.load_file('pship1.png')) # self.p_unit_images.append(self.load_file('pship2.png')) # self.p_unit_images.append(self.load_file('pship3.png')) # Load enemy ship image. self.e_ship_image = self.load_file('eship.png') if self.app.settings['sounds']: self.p_shoot_sound = self.app.load_file('p-weapon0.wav', file_type='sound') self.p_shoot_sound.set_volume(.3) self.e_ex_sound = self.app.load_file('e-ex.wav', file_type='sound') self.p_ex_sound = self.app.load_file('p-ex.wav', file_type='sound') self.e_damage_sound = self.app.load_file('e-damage.wav', file_type='sound') self.e_shield_sound = self.app.load_file('e-shield.wav', file_type='sound') self.p_shield_sound = self.app.load_file('p-shield.wav', file_type='sound') self.p_damage_sound = self.app.load_file('p-damage.wav', file_type='sound') print("loaded sounds...") self.menus = None self.tock = 0 self.lagcount = 0 self.leftkeydown = 0 self.rightkeydown = 0 # self.enemylist = [] # list of dirty rects self.swarm = Swarm(self.world_rect, shoot_odds=self.stage_e_bullet_odds) self.stage = Stage(self.swarm, self.p_swarm) self.p_shot_image = self.load_file('p-laser.png') self.e_shot_image = self.load_file('e-laser.png') self.p_bullet_swarm = Swarm(self.world_rect) self.e_bullet_swarm = Swarm(self.world_rect) # self.bullet_width = 10 self.hud_rect = pygame.Rect(0, 0, 5, 150) self.hud = Hud() self.hud.generate_blip('player.score', 100, fg_color=(255,243,207), text_color=(192,180,180), caption="SCORE") self.hud.generate_blip('player.health', self.p_max_health, fg_color=(0,255,42), text_color=(192,180,180), caption="SHIELD") self.statcounter = self.hud.get_blip('player.score') def load_file(self, name): return self.app.load_file(name) def on_exit(self): print("on_exit...") # Clears all the variables def clear_vars(self): # print("clear_vars: world_rect: " + str(self.world_rect)) self.p_start_x = self.world_rect.width / 2 self.p_start_y = self.world_rect.height - 60 self.bend_y = float(self.p_start_y) # print("clear_vars: p_start_y: " + str(self.p_start_y)) self.bend_rate = 0.02 self.leftkeydown = 0 self.rightkeydown = 0 if self.p_unit is not None: self.hud.set_blip_value('player.health', self.p_unit.health) else: print("WARNING: clear_vars failed to set bar since no" + " player unit exists") self.statcounter.set_val(0) self.stage.set_stage_number(-1) # hax self.stage_e_bullet_odds = 100 self.swarm.empty() self.p_bullet_swarm.empty() self.p_swarm.empty() self.particles.empty() self.e_bullet_swarm.empty() # Define function to draw player ship on X, Y plane def draw_player_units(self): self.p_swarm.draw(self.screen) # Define function to move the enemy ship def emove(self): self.swarm.draw(self.screen) # use spritegroup draw method # Draws all the enemys you ask it def generate_enemies(self): print("generating enemies...") # Some recursive loops: xmin = self.world_rect.left xmax = self.world_rect.right ymin = self.world_rect.top stage_data = self.stage.get_data() self.e_ship_image = self.app.load_file(stage_data['e']+".png") enemy_width, enemy_height = self.e_ship_image.get_size() enemy_spacing_x = 15 enemy_spacing_y = 10 init_enemy_speed = 3 angle = -90 # cartesian self.app.music_name = stage_data['music'] # if self.app.music_name == 'intro.ogg': # self.app.continue_music() # force song change e_max_health = stage_data['e_h'] for enemycol in range(stage_data['x_e_count']): # Now for the rows for enemyrow in range(stage_data['y_e_count']): # Make a new enemy object: new_enemy = Entity(self.app, 'eship', [self.e_ship_image], init_enemy_speed, angle, self.swarm, e_max_health, self.explosion_images, self.particles, ai_enable=True, value=stage_data['e_h'], ex_sound=self.e_ex_sound) new_enemy.set_xy( xmin + enemycol * (enemy_width + enemy_spacing_x), ymin + enemyrow * (enemy_height + enemy_spacing_y) - 150 ) new_enemy.set_range( xmin + enemycol * (enemy_width + enemy_spacing_x), xmax - (stage_data['x_e_count'] - enemycol) * (enemy_height + enemy_spacing_x) ) # Now add the temp enemy to the array and we're good to # go self.swarm.add(new_enemy) # So I'm trying out having the program check for collisions, instead # of the enemy objects i think i might switch to the objects, but # still keep this function just hand the computing to the object def test_collision(self): part_speed = 1 part_angle = -90 part_health = 1 e_hit = pygame.sprite.groupcollide(self.swarm, self.p_bullet_swarm, 0, 0) for sprite, bullets in e_hit.items(): # print("removed " + str(bullet) for bullet in bullets: was_alive = sprite.get_is_alive() prev_health = sprite.health if sprite.get_is_alive(): sprite.set_hit(1) damage = prev_health - sprite.health poof = self.shield_hit_images temper_sound = self.e_shield_sound if damage > 0: poof = self.damage_images temper_sound = self.e_damage_sound if not was_alive: break point = pygame.sprite.collide_mask(sprite, bullet) if ((point is not None) and (not self.particle_ban)): particle = Entity(self.app, 'particle', poof, part_speed, part_angle, self.particles, part_health, None, None, anim_done_remove=True, temper_sound=temper_sound) particle.temper = 1 # start particle death x1, y1 = sprite.get_pos() # top left x = x1 + point[0] - particle.rect.width / 2 y = y1 + point[1] - particle.rect.height / 2 particle.set_xy(x, y) self.particles.add(particle) if not sprite.get_is_alive(): points = sprite.take_value() # only once & if health 0 if points > 0: self.statcounter.add_value(points) self.p_bullet_swarm.remove(bullets) p_hit = pygame.sprite.groupcollide(self.p_swarm, self.e_bullet_swarm, 0, 0) for sprite, bullets in p_hit.items(): for bullet in bullets: was_alive = sprite.get_is_alive() prev_health = sprite.health if sprite.get_is_alive(): sprite.set_hit(1) damage = prev_health - sprite.health poof = self.shield_hit_images temper_sound = self.p_shield_sound if damage > 0: poof = self.damage_images temper_sound = self.p_damage_sound self.hud.set_blip_value('player.health', self.p_unit.health) # New in pygame 1.8.0: point = pygame.sprite.collide_mask(sprite, bullet) if not was_alive: break if (point is not None) and (not self.particle_ban): particle = Entity(self.app, 'particle', poof, part_speed, part_angle, self.particles, part_health, None, None, anim_done_remove=True, temper_sound=temper_sound) particle.temper = 1 # start particle death x1, y1 = sprite.get_pos() # top left x = x1 + point[0] - particle.rect.width / 2 y = y1 + point[1] - particle.rect.height / 2 particle.set_xy(x, y) self.particles.add(particle) # if pygame.sprite.spritecollideany(self.p_unit, # self.e_bullet_swarm): # self.p_unit.set_hit(1) # self.hud.set_blip_value('player.health', # self.p_unit.health) # if there are no enemys left, go to the next stage def check_done(self): if not self.swarm: if self.stage.is_last_stage(): if not self.won: self.won = True # TODO: make ending screen # self.app.music_name = 'victory.ogg' # if self.app.music_name == 'intro.ogg': # self.app.continue_music() # force song change self.app.music_name = None # stop repeating self.app.check_music() # apply None to loop self.app.queue_music('victory.ogg', 1) if not self.won: self.stage.next_stage() if self.stage_e_bullet_odds > 15: self.stage_e_bullet_odds -= 15 self.generate_enemies() # checks to see if we can expand the ranges of the bots so its nice # and.... umm... nice. def check_rows(self): if self.tock % 20 == 0: # simple sorting algorithm to find the highest values xmin = self.world_rect.left xmax = self.world_rect.right highest = xmin lowest = xmax for enemy in self.swarm: if enemy.get_range()[1] > highest: highest = enemy.get_range()[1] if enemy.get_range()[0] < lowest: lowest = enemy.get_range()[0] highest = xmax - highest lowest = lowest - xmin if highest != 0 or lowest != 0: # makes things |--| this much more efficient for enemy in self.swarm: erange = enemy.get_range() enemy.set_range(erange[0]-lowest, erange[1]+highest) # major hack just to get this thing playable..... sorry def again(self): if self.hud.get_blip_value('player.health') <= 0: self.particle_ban = True if self.p_unit.get_is_decayed(): self.particle_ban = True # also wait for particles to finish for prettier ending if len(self.particles) < 1: if self.wait_stop_count < 0: print("player unit decayed, counting down to menu") self.wait_stop_count = 0 # return False if self.wait_stop_count >= 0: self.wait_stop_count += 1 if self.wait_stop_count > self.wait_stop_max: return False if self.won: if self.wait_stop_count < 0: print("won game, counting down to menu") self.wait_stop_count = 0 return True # this is called if the player initiates shooting def pshoot(self): # sx = self.p_unit.rect.centerx - # self.p_shot_image.rect.width / 2 # sy = self.p_unit.rect.top + # self.p_shot_image.rect.height * .75 if self.p_unit.get_is_alive(): self.p_unit.shoot(self.p_shot_image, self.p_bullet_swarm) # self.p_unit.shoot_from(self.p_shot_image, # self.p_bullet_swarm, # sx, sy, self.p_unit.angle) def draw_bullets(self): self.p_bullet_swarm.draw(self.screen) self.e_bullet_swarm.draw(self.screen) def draw_hud(self): if self.tock % 5 == 0: self.hud.update() self.hud.draw(self.screen) # Goes through all the objects and makes each of them move as # necessary def tick(self): self.bend_y += self.bend_rate bend_max = 5.0 if self.bend_rate < 0.0: self.bend_rate -= .02 else: self.bend_rate += .02 if ((self.bend_y > self.p_start_y + bend_max) or (self.bend_y < self.p_start_y)): if self.bend_rate < 0.0: self.bend_rate = .02 self.bend_y = float(self.p_start_y) else: self.bend_rate = -.02 self.bend_y = float(self.p_start_y) + bend_max self.p_unit.set_xy(self.p_unit.get_pos()[0], int(self.bend_y+.5)) self.p_bullet_swarm.update() self.swarm.update() self.e_bullet_swarm.update() ###################### # Here are a bunch of metafunctions. # I break it up so its really easy to add new features, # like if we ant a counter? add something to check() and draw(). # All of these are called once per frame. def check(self): self.check_done() self.test_collision() self.check_rows() self.bg.update() if self.p_unit.get_is_alive(): self.swarm.shoot(self.e_shot_image, self.e_bullet_swarm) self.p_unit.update() for particle in self.particles: particle.update() def draw(self): self.screen.fill(self.bg.bg_color) # if self.world_rect is not None: # self.screen.fill((64, 64, 64), self.world_rect) self.bg.draw(self.screen) self.draw_bullets() self.draw_player_units() self.emove() self.particles.draw(self.screen) self.draw_hud() # if self.p_unit is not None: # if self.p_unit.rect is not None: # self.screen.fill((128, 128, 128), self.p_unit.rect) # if self.mouse_rect is not None: # self.screen.fill((255, 255, 255), self.mouse_rect) # if self.temp_rect is not None: # self.screen.fill((128, 0, 0), self.temp_rect) # does just what it sounds like..... def clear_screen(self): self.screen.fill(self.bg.bg_color) # pygame.display.flip() # for debugging info mostly def dispvars(self): print("The Enemy SpriteGroup size is:" + str(len(self.swarm.sprites()))) print("The Player Bullet Array size is:" + str(len(self.p_bullet_swarm.sprites()))) print("The Enemy Bullet Array size is:" + str(len(self.e_bullet_swarm.sprites()))) # does lots and lots of stuff, it really needs to be cleaned up def process_events(self, events): # print("input: self.p_unit.rect: " + str(self.p_unit.rect)) xmin = self.world_rect.left xmax = self.world_rect.right smooth_scroll_var1 = 10 smooth_scroll_var2 = 2 pygame.event.pump() # redraw Window so OS knows not frozen self.app.check_music() pause_menu_strings = ["RESUME", "ABOUT", "HELP", "EXIT"] if self.won: pause_menu_strings.insert(0, self.won_msg) for event in events: if event.type == QUIT: self.on_exit() sys.exit(0) if event.type == pygame.MOUSEMOTION: pygame.event.get() prev_pos = self.p_unit.get_pos() tempx = (pygame.mouse.get_pos()[0] - self.p_unit.rect.width / 2) # *Just to make sure we don't get the ship way out: if tempx + self.p_unit.rect.width > xmax: # if its outside the world, # just stick it as far as possible self.p_unit.set_xy(xmax - self.p_unit.rect.width, prev_pos[1]) elif tempx < xmin: self.p_unit.set_xy(xmin, prev_pos[1]) elif abs(tempx-self.p_start_x) > \ smooth_scroll_var1: # smooth scrolling if the mouse gets far # from the ship self.p_unit.set_xy( prev_pos[0] + (tempx-prev_pos[0]) / smooth_scroll_var2, prev_pos[1]) else: # if it gets down to this point, # we've passed all sanity checks so just move it self.p_unit.set_xy(tempx, prev_pos[1]) elif event.type == pygame.MOUSEBUTTONDOWN: self.pshoot() elif event.type == pygame.KEYDOWN: if event.key == pygame.K_q: self.menus.show_dialog(pause_menu_strings) if event.key == pygame.K_p: self.menus.show_dialog(pause_menu_strings) if event.key == pygame.K_ESCAPE: self.menus.show_dialog(pause_menu_strings) # keyboard controls if event.key == pygame.K_LEFT: self.leftkeydown = 1 if event.key == pygame.K_RIGHT: self.rightkeydown = 1 if event.key == pygame.K_SPACE: self.pshoot() elif event.type == pygame.KEYUP: if event.key == pygame.K_LEFT: self.leftkeydown = 0 if event.key == pygame.K_RIGHT: self.rightkeydown = 0 elif event.type == pygame.USEREVENT: if event.code == pygame.USEREVENT_DROPFILE: print("Tried to open file on MacOS (this should" + " never happen:") print(" " + str(event)) else: # should be event.code 0 self.app.continue_music() print("music queue ended in game:") if event.code != 0: print("unknown USEREVENT event.code: " + str(event.code)) if self.leftkeydown: self.p_unit.move_one(-1, self.world_rect) if self.rightkeydown: self.p_unit.move_one(1, self.world_rect) pygame.event.clear() #################################################################### def start(self, menus): self.won = False self.particle_ban = False self.wait_stop_count = -1 # -1 means do not count down to menu self.menus = menus p_speed = 10 self.p_unit = Entity(self.app, 'pship', self.p_unit_images, p_speed, 90.0, self.p_swarm, self.p_max_health, self.explosion_images, self.particles, ex_sound = self.p_ex_sound) self.p_unit.shoot_sound = self.p_shoot_sound print("Clearing vars...") self.clear_vars() # does reset player unit (p_unit) position self.p_swarm.add(self.p_unit) self.p_unit.set_xy(self.p_start_x, self.p_start_y) print("Starting main event loop...") self.loop() # Yeah see this one does all of the work def loop(self): # Start loop REFRESH_TIME = self.app.get_fps() * 3 while (not self.menus.get_bool('exit')) and (self.again()): # Refresh screen periodically if self.tock >= REFRESH_TIME: # self.clear_screen() self.tock = 0 self.tock += 1 # Check everythign and see if changes need to be made self.check() # Draw bullets self.draw() # Move everything self.tick() # Initiate input function self.process_events(pygame.event.get()) # applies the smart screen updating pygame.display.update() # TODO: ? pygame.display.update(self.enemylist) # self.enemylist = [] # Pauses and waits timeittook = self.app.clock.tick(self.app.get_fps())
def run(): pygame.init() random.seed() display_size = 800, 600 viewport_size = display_size[0], 600 black = 0, 0, 0 red = 255, 70, 70 green = 70, 255, 70 blue = 70, 70, 255 white = 255, 255, 255 l_green = 50, 255, 0 screen = pygame.display.set_mode(display_size) screen.fill(black) clock = Clock(readonly=False) dbman = DBManager() dbman.import_db("./db") gfxman = GfxManager() gfxman.import_gfx(dbman.get(), "./gfx") stagemanager = StageManager() stagemanager.import_stages("./stages") stages = stagemanager.get() groupmanager = GroupManager() g_draw = groupmanager.add("draw", "OrderedUpdates") g_ship = groupmanager.add("ship") g_enemies = groupmanager.add("enemies") g_enemy_projectiles = groupmanager.add("enemy_projectiles") g_player_projectiles = groupmanager.add("player_projectiles") g_beams = groupmanager.add("beams") g_explosions = groupmanager.add("explosions") g_shields = groupmanager.add("shields") g_bonuses = groupmanager.add("bonuses") hud = Hud(viewport_size) g_enemies.add(Obstacle((60, 30))) g_enemies.add(MovingObstacle((160, 80))) g_bonuses.add(RechargeBonus((300, 200))) g_bonuses.add(SuperShieldBonus((500, 300))) g_bonuses.add(ShieldUpgradeBonus((500, 500))) g_bonuses.add(ShieldUpgradeBonus((300, 500))) ship = ref(PlayerShip((175, viewport_size[1] - 60), g_ship)) hud.setup_connections(ship()) back = SpaceBackground(viewport_size) for stage_name in sorted(stages.keys()): stage_clock = 0 while True: for spawn_time in stages[stage_name]["spawn"]: if spawn_time <= stage_clock: while stages[stage_name]["spawn"][spawn_time]: spawn = stages[stage_name]["spawn"][spawn_time].pop() pos = spawn["x"], spawn["y"] object_cls = eval(spawn["object_cls_name"]) if spawn["object_base_cls_name"]: if spawn["object_base_cls_name"] == "Projectile": if not spawn.has_key("object_params"): raise ValueError, "Params for projectile '%s' in stage %s \ not set" % ( spawn["object_cls_name"], stage_name, ) if not spawn["object_params"].has_key("dir"): raise ValueError, "Invalid 'dir' for projectile '%s' in \ stage %s" % ( spawn["object_cls_name"], stage_name, ) if not spawn["object_params"].has_key("collision_group"): raise ValueError, "Invalid 'collision_group' for projectile \ '%s' in stage %s" % ( spawn["object_cls_name"], stage_name, ) params = spawn["object_params"] dir = params["dir"] g_coll = groupmanager.get(params["collision_group"]) object = object_cls(pos, dir, g_coll) elif spawn["object_base_cls_name"] == "Bonus": pass else: raise ValueError, "Invalid value '%s' for attrubite \ 'object_base_cls_name' in stage %s" % ( spawn["object_base_cls_name"], stage_name, ) else: object = object_cls(pos) if spawn["bonus_cls_name"]: if isinstance(object, BonusHolder): object.set_bonus(spawn["bonus_cls_name"], spawn["bonus_params"]) else: raise ValueError, "Instances of %s can not hold bonuses." % object.__class__.__name__ if spawn["mover_cls_name"]: mover_cls = eval("mover.%s" % spawn["mover_cls_name"]) m = mover_cls(pos, object.max_speed, spawn["mover_params"]) object.set_mover(m) for g in spawn["groups"]: if g == "enemies": g_enemies.add(object) elif g == "explosions": g_explosions.add(object) elif g == "enemy_projectiles": g_enemy_projectiles.add(object) elif g == "player_projectiles": g_player_projectiles.add(object) # time management clock.tick(40) # clock.tick( float(sys.argv[1]) ) stage_clock += clock.get_time() for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() elif event.type == pygame.KEYDOWN: if event.key == pygame.K_q: sys.exit() elif event.key == pygame.K_s: if ship(): ship().next_weapon() elif event.key == pygame.K_a: if ship(): ship().previous_weapon() elif event.key == pygame.K_x: if ship(): ship().activate_shield(True) elif event.type == pygame.KEYUP: if event.key == pygame.K_UP: if ship(): ship().fly_up(False) elif event.key == pygame.K_x: if ship(): ship().activate_shield(False) pressed_keys = pygame.key.get_pressed() if pressed_keys[pygame.K_UP]: if ship(): ship().fly_up(True) if pressed_keys[pygame.K_DOWN]: if ship(): ship().fly_down(viewport_size[1]) if pressed_keys[pygame.K_LEFT]: if ship(): ship().fly_left() if pressed_keys[pygame.K_RIGHT]: if ship(): ship().fly_right(viewport_size[0]) if pressed_keys[pygame.K_z]: if ship(): ship().shoot() back.clear(screen, clear_bg) back.update() back.draw(screen) # temp # if ship(): # ship().damage(1) # g_draw.clear(screen, clear_bg) hud.clear(screen, clear_bg) g_draw.update() hud.update() g_draw.draw(screen) hud.draw(screen) pygame.display.flip()
class Game(Div, object): """main frame of the game""" def __init__(self, controller): # super(game, self).__init__() self.controller = controller self.initAttr() self.initElement() def setLevel(self, level=6): self.boardWidth, self.boardHeight = self.board.setLevel(level) self.height = self.boardHeight + self.edgeWidth * 2 self.width = self.boardWidth + self.hudWidth self.initContext() def initAttr(self): self.turn = True self.hudWidth = HUD["HUD_WIDTH"] self.edgeWidth = GAME["EDGE_WIDTH"] # 先获取 board 部分的大小,再自适应自己的大小 self.board = Board((self.hudWidth, self.edgeWidth)) Div.__init__(self, (self.board.width + self.hudWidth, self.board.height + self.edgeWidth * 2)) # 根据窗口高度设置 HUD 高度 self.hud = Hud((0, self.height), (0, 0)) self.hud.setMark(self.turn) self.board.setTurn(self.turn) self.gameID = 0 self.order = None def initElement(self): # 背景 self.background = Background((self.width, self.height)) backgroundColor = GAME["GAME_BACKGROUND_COLOR"] self.background.setColor(backgroundColor) # 返回按钮 self.returnButton = TextButton(GAME["RETURN_BUTTON_FONTS"], GAME["RETURN_BUTTON_CONTENT"], (30, 30)) def initContext(self): self.screen = pygame.display.set_mode((self.width, self.height), DOUBLEBUF) pygame.display.set_caption("Boxes") self.clock = pygame.time.Clock() def leaveServer(self, *args): self.controller.gameNet.leaveServer(self.gameID) return STATE.menu def placeLine(self, data): if self.hud.started: self.controller.gameNet.placeLine(data, self.gameID, self.order) def placeLineAnswer(self, turn, x, y, h, point, order): self.setTurn(turn) if order == self.order: self.board.placeLine(x, y, h, point, True) else: self.board.placeLine(x, y, h, point, False) def setTurn(self, turn): self.hud.setMark(turn) self.board.setTurn(turn) def setHome(self): self.order = 0 self.board.setHome() self.background.setColor(GAME["HOME_COLOR"]) def setAway(self): self.order = 1 self.board.setAway() self.background.setColor(GAME["AWAY_COLOR"]) def addScore(self): self.hud.addScore() def enemyAddScore(self): self.hud.enemyAddScore() # 对手玩家进入游戏 def enemyComming(self, turn): self.setTurn(turn) self.board.restart() self.hud.startGame() def newHost(self): self.hud.restart() # 数据清零,重新开始游戏 def restart(self): self.board.restart() self.hud.restart() def draw(self): # self.screen.set_clip(None) self.background.draw(self.screen) ret = self.board.draw(self.screen) if ret != None: self.placeLine(ret) self.hud.draw(self.screen) self.returnButton.draw(self.screen) var = self.returnButton.click(self.leaveServer) if var != None: return var return STATE.game
class GameScreen(Events): """docstring for GameScreen""" def __init__(self, window): super(GameScreen, self).__init__() self.window = window self.camera = Camera(window) self.player = player.Player() self.proj_viewer = ProjectileViewer(self.send_center) self.controls = {} self.controls_old = {} self.map = Map('blank') #self.player.spawn(100, 100) self.time = 0 self.moves = moves(1024) self.index = [0] self.head = [0] #other players self.players = {} self.specs = {} #crosshair self.cross = CrossHair() self.isSpec = True self.hud = Hud() self.gs_view = GameStateViewer(self.players, self.hud.update_prop, self.hud.set_score) def update(self, dt): dt = int(dt * 1000000) / 1000000. if self.controls['esc'] and not self.controls_old['esc']: self.send_message('menu_transition_+', (GameMenu, self.isSpec)) if self.controls['rdy'] and not self.controls_old['rdy']: if not self.isSpec: self.ready_up() if self.controls['chat'] and not self.controls_old['chat']: self.send_message('menu_transition_+', (ChatScreen, self.window)) self.update_keys() self.on_update(dt) def update_physics(self, dt, state=False, input=False): playergen = (player.rect for player in self.players.itervalues()) mapgen = (rect for rect in self.map.quad_tree.retrieve([], self.player.rect)) rectgen = chain(playergen, mapgen) self.player.update(dt, rectgen, state, input) return self.player.state def update_state_only(self, state): self.player.state.update(0, state) def update_keys(self): for key_, value in self.controls.items(): self.controls_old[key_] = value def from_server(self, data): typ, data = data if typ == proto.playerUpdate: ind, time, s_state, inpt, weaponinfo = data smove = move(time, inpt, s_state) if ind == self.player.id: correct_client(self.update_physics, smove, self.moves, self.head, self.index[0], self.update_state_only) self.player.weapons.from_server(weaponinfo) else: #try: self.players[ind].client_update(s_state) self.players[ind].input = inpt #except KeyError: # pass elif typ == proto.projectile: self.proj_viewer.process_proj(data) elif typ == proto.newPlayer: gs, data = data if gs == proto.goesSpec: ind, name, colstring = data new = player.Player() new.name = name new.id = ind new.set_color(colstring) self.specs[ind] = new #if there are existing players on the server elif gs == proto.wantsJoin: ind, name, state, time, colstring = data new = player.Player() new.name = name new.state = state new.time = time new.id = ind new.set_color(colstring) new.rect.update_color(new.color) self.players[ind] = new print 'new player: %s' % name self.gs_view.to_team(ind) elif typ == proto.disconnect: ind = data if ind in self.players: self.gs_view.leave(ind) del self.players[ind] elif ind in self.specs: del self.specs[ind] elif typ == proto.stateUpdate: gametime, data = data gs, ind = data self.gs_view.set_time(gametime) if gs == proto.wantsJoin: if ind == self.player.id: self.send_message('menu_transition_-') self.player.state.isDead = False self.trans_to_game() else: self.players[ind] = self.specs[ind] del self.specs[ind] self.gs_view.to_team(ind) elif gs == proto.goesSpec: if ind == self.player.id and self.isSpec: pass elif ind == self.player.id and not self.isSpec: self.send_message('menu_transition_-') self.trans_to_spec() else: self.specs[ind] = self.players[ind] self.gs_view.leave(ind) del self.players[ind] elif gs == proto.isDead: ind, killer, weapon = ind if ind == self.player.id: self.player.die() else: self.players[ind].die() self.gs_view.score(ind, killer, weapon) elif gs == proto.spawns: ind, pos = ind if ind == self.player.id: self.player.spawn(*pos) else: self.players[ind].spawn(*pos, other=True) elif gs == proto.isReady: ind, name = ind self.gs_view.is_ready(ind, name) elif gs == proto.countDown: self.player.freeze() elif gs == proto.inProgress: self.gs_view.start_game() elif gs == proto.warmUp: self.gs_view.to_warmup() elif typ == proto.mapUpdate: ind, itemid, gt, spawn = data self.gs_view.set_time(gt) if ind == self.player.id: if isinstance(self.map.items[itemid], Triangle): st = self.map.items[itemid].keystr if not st in self.player.weapons.weapons: self.player.weapons.pickup(st) else: self.player.weapons.apply(st, self.player) self.map.serverupdate(itemid, spawn) elif typ == proto.chat: ind, msg = data if ind == self.player.id: name = self.player.name color = self.player.color elif ind in self.players: name = self.players[ind].name color = self.players[ind].color else: name = self.specs[ind].name color = self.specs[ind].color #chatdata = ' '.join((name + ':', '\t', msg)) chatdata = (name, color, msg) self.hud.update_prop(chat=chatdata) def send_to_client(self, dt): temp_input = proto.Input() self.time += int(dt * 1000000) temp_input.CopyFrom(self.player.input) c_move = move(self.time, temp_input, self.player.state.copy()) try: self.moves[self.index[0]] = c_move except IndexError: self.moves.append(c_move) self.moves.advance(self.index) self.send_message('input', (self.player.input, self.time)) def spec_send(self, dt): self.send_message('input', (proto.Input(), self.time)) def draw(self): self.on_draw() def on_connect(self, msg): ind, mapname, name = msg self.player.get_id(ind, name) self.map = Map(mapname) print 'connected with id: ' + str(self.player.id) #self.send_message('input', (self.player.input, 1337)) self.gs_view.init_self(ind) self.trans_to_spec() def try_join(self): msg = proto.Message() msg.type = proto.stateUpdate plr = proto.Player() plr.id = self.player.id msg.player.CopyFrom(plr) if self.isSpec: msg.gameState = proto.wantsJoin else: msg.gameState = proto.goesSpec self.send_message('other', msg) def ready_up(self): msg = proto.Message() msg.type = proto.stateUpdate plr = proto.Player() plr.id = self.player.id msg.player.CopyFrom(plr) msg.gameState = proto.isReady self.send_message('other', msg) def send_chat(self, chatmsg): msg = proto.Message() msg.type = proto.chat plr = proto.Player() plr.id = self.player.id plr.chat = chatmsg msg.player.CopyFrom(plr) self.send_message('other', msg) def on_update(self, dt): pass def on_draw(self): pass def idle_update(self, dt): self.send_to_client(dt) self.gs_view.update(dt) self.hud.update(dt) def trans_to_spec(self): self.on_update = self.spec_update self.on_draw = self.spec_draw self.isSpec = True self.player.state.hook_hud(self.hud.update_prop) self.hud.init_spec() def trans_to_game(self): self.on_update = self.game_update self.on_draw = self.game_draw self.isSpec = False self.player.weapons.hook_hud(self.hud.update_prop) self.player.state.hook_hud(self.hud.update_prop) self.gs_view.add_self(self.player) self.hud.init_player(self.players) def game_update(self, dt): self.update_physics(dt) self.camera.update(dt, self.player.state) self.send_to_client(dt) self.proj_viewer.update(dt) self.gs_view.update(dt) self.hud.update(dt) def game_draw(self): self.camera.set_camera() for plr in self.players.itervalues(): plr.draw() self.player.draw() self.proj_viewer.draw() self.map.draw() self.camera.set_static() self.hud.draw() self.cross.draw(*self.camera.mpos) def spec_update(self, dt): self.player.specupdate(dt) self.camera.update(dt, self.player.state) #self.send_to_client(dt) self.spec_send(dt) self.proj_viewer.update(dt) self.gs_view.update(dt) self.hud.update(dt) def spec_draw(self): self.camera.set_camera() for plr in self.players.itervalues(): plr.draw() self.proj_viewer.draw() self.map.draw() self.camera.set_static() self.hud.draw() def send_center(self, ind): if ind == self.player.id: pl = self.player return pl.rect.center, (pl.input.mx, pl.input.my) else: pl = self.players[ind] return pl.rect.center, (pl.input.mx, pl.input.my)
class Game(object): """this is the Game class""" def __init__(self): pygame.mixer.pre_init(48000,-16,2, 1024) #Sound Settings pygame.init() #sets the screen resolution for the game and sets a rect for the game screen self.screen = pygame.display.set_mode((1024,768)) self.screen_rect = self.screen.get_rect() #initializes a clock for the game self.clock = pygame.time.Clock() #initializes a menu object and HUD object and Score object self.menu = Menu() self.hud = Hud() self.score = Score() #sets a boolean for whether you are still in the menu or not self.inMenu = True #sets a camera for the world self.camBorder = 32 self.cam = Camera(pygame.Rect(100, 100, 1024, 768), pygame.Rect(self.camBorder, self.camBorder, 2048 - self.camBorder, 1536 - self.camBorder)) self.camShakeFactor = 0 #Magnitude of shake self.camShakeDecayFactor = 0.08 #Lerp Amount #Timing self.timer = pygame.time.get_ticks() self.elapsed = 0 #Sound Controller self.soundCon = SoundCon() #Game Values self.backgroundImg = pygame.image.load("Images/Arena/Arena2.png").convert_alpha() self.backgroundImgRect = self.backgroundImg.get_rect() self.player = Player( self.hud ) #Effects self.effectInstances = [] self.spawnSound = pygame.mixer.Sound("Sounds/ShipRev.wav") self.deathSound = pygame.mixer.Sound("Sounds/shipExplo.wav") self.enemyExplo = pygame.mixer.Sound("Sounds/enemyExplo.wav") self.clashSound = pygame.mixer.Sound("Sounds/clash.wav") self.boostSound = pygame.mixer.Sound("Sounds/boostLow.wav") #Game over fade out self.fadeImage = pygame.image.load("Images/HUD/CrackedGlass.png").convert_alpha() self.fadeRect = self.fadeImage.get_rect() self.fadeSurface = pygame.Surface((1024, 768), pygame.SRCALPHA) self.fadeSurfaceAlpha = 0 self.fadeSurfaceRate = 1 self.doFade = False self.restartGame = False #Enemies self.enemyList = [] self.baseNumEnemies = 2 self.spawnTime = 10 self.currentSpawnTime = 30 def process_events(self): """process all game events""" #sets a variable containing the position of the mouse self.mousePos = pygame.mouse.get_pos() for event in pygame.event.get(): if self.inMenu: #passes the current event and mouse position to the menu's 'process_events' function self.inMenu = self.menu.process_events(event, self.mousePos) else: #Run everything else's 'process_events' functions #print("This is where the game would process events") self.readInputs( event ) if event.type == pygame.KEYDOWN: #exits the program if the esc key is pressed if event.key == pygame.K_ESCAPE: sys.exit(0) def readInputs(self, event): if event.type == pygame.KEYDOWN: if event.key == pygame.K_ESCAPE: sys.exit(0) if event.key == pygame.K_w or event.key == pygame.K_UP: self.player.moving[0] = True if event.key == pygame.K_s or event.key == pygame.K_DOWN: self.player.moving[1] = True if event.key == pygame.K_a or event.key == pygame.K_LEFT: self.player.moving[2] = True if event.key == pygame.K_d or event.key == pygame.K_RIGHT: self.player.moving[3] = True if event.key == pygame.K_SPACE or event.key == pygame.K_z: self.player.moving[4] = True self.boostSound.play() if event.key == pygame.K_p: self.soundCon.currentTime = 30 self.currentSpawnTime = 1 self.player.currentInvincTime = 1 if event.type == pygame.KEYUP: if event.key == pygame.K_w or event.key == pygame.K_UP: self.player.moving[0] = False if event.key == pygame.K_s or event.key == pygame.K_DOWN: self.player.moving[1] = False if event.key == pygame.K_a or event.key == pygame.K_LEFT: self.player.moving[2] = False if event.key == pygame.K_d or event.key == pygame.K_RIGHT: self.player.moving[3] = False if event.key == pygame.K_SPACE or event.key == pygame.K_z: self.player.moving[4] = False self.boostSound.stop() def update(self): """updates the game""" if not self.inMenu: self.player.update(self.cam ) self.cam.move_to(self.player.pos[0], self.player.pos[1]) self.soundCon.update() #Enemy Spawning self.elapsed = (pygame.time.get_ticks() - self.timer) / 1000.0 self.currentSpawnTime -= self.elapsed if ( self.currentSpawnTime <= 0 ): self.currentSpawnTime = self.spawnTime self.spawnEnemy() #Enemy update for tempEnemy in self.enemyList: tempEnemy.update(self.cam) self.player.checkColl(tempEnemy, self.cam, self) #Check enemy deaths for tempEnemy in self.enemyList: if tempEnemy.deathFlag: self.score.total += 100 self.makeLineBurst( tempEnemy.rect.centerx, tempEnemy.rect.centery, tempEnemy.deathAngle, 60, 200, 50, (255,255,0), 0.1, True ) self.makeLineBurst( tempEnemy.rect.centerx, tempEnemy.rect.centery, tempEnemy.deathAngle, 60, 200, 50, (255,255,255), 0.1, True ) self.makeLineBurst( self.player.rect.centerx, self.player.rect.centery, 0, 360, 100, 50, (255,255,255), 0.05, True ) self.makeLineBurst( self.player.rect.centerx, self.player.rect.centery, 0, 360, 100, 40, (255,0,0), 0.05, True ) self.enemyExplo.play() self.enemyList.remove( tempEnemy ) self.spawnEnemy() #Effect update for effect in self.effectInstances: if not effect.active: self.effectInstances.remove( effect ) #Shake and Decay self.camShakeFactor = self.camShakeFactor - ( self.camShakeFactor * self.camShakeDecayFactor ) if ( self.camShakeFactor < 1 ): self.camShakeFactor = 0 self.cam.shake(random.random() * self.camShakeFactor, random.random() * self.camShakeFactor) #Player boost effect if ( self.player.boosting ): self.makeLineBurst( self.player.rect.centerx, self.player.rect.centery, -self.player.ang * 180 / math.pi + 180, 30, 3, 30, (255,255,155), 0.1, True ) self.makeLineBurst( self.player.rect.centerx, self.player.rect.centery, -self.player.ang * 180 / math.pi + 180, 30, 3, 30, (255,0,0), 0.1, True ) if ( self.player.thrusting ): self.makeLineBurst( self.player.rect.centerx, self.player.rect.centery, -self.player.ang * 180 / math.pi + 180, 20, 2, 20, (255,255,255), 0.1, True ) #Update Score in HUD self.hud.updateScore(self.score.getTotal()) #Death if self.player.dead and self.player.canMakeDeadEffect: self.player.canMakeDeadEffect = False self.shakeScreen( 64 ) self.soundCon.playDeathSound() self.deathSound.play() #self.makeExplosion( 500, 500, "Images/Effects/Explosion2Spr.png", 200, 200, 8, 8, True) self.makeLineBurst( self.player.rect.centerx, self.player.rect.centery, 0, 360, 200, 30, (255,255,0), 0.1, True ) self.makeLineBurst( self.player.rect.centerx, self.player.rect.centery, 0, 360, 200, 30, (255,0,0), 0.1, True ) self.makeLineBurst( self.player.rect.centerx, self.player.rect.centery, 0, 360, 100, 30, (255,155,0), 0.05, True ) self.makeLineBurst( self.player.rect.centerx, self.player.rect.centery, 0, 360, 100, 40, (255,0,0), 0.05, True ) self.makeLineBurst( self.player.rect.centerx, self.player.rect.centery, 0, 360, 100, 50, (255,255,255), 0.05, True ) self.player.numLives -= 1 if ( self.player.numLives <= 0 ): self.doFade = True self.player.currentDeadTime = 30 if ( self.player.reformEffect ): self.player.reformEffect = False; self.spawnSound.play() self.makeLineBurst( self.player.rect.centerx, self.player.rect.centery, 0, 360, 150, 15, (255,255,255), 0.1, False ) self.makeLineBurst( self.player.rect.centerx, self.player.rect.centery, 0, 360, 150, 30, (255,255,255), 0.1, False ) self.makeLineBurst( self.player.rect.centerx, self.player.rect.centery, 0, 360, 150, 50, (255,255,255), 0.1, False ) self.timer = pygame.time.get_ticks() def shakeScreen(self, magnitude): self.camShakeFactor = magnitude #Magnitude of shake def makeLineBurst(self, x, y, direction, spread, count, maxSpeed, color, lerpPercent, doRandom): newBurst = LineBurst( x, y, direction, spread, count, maxSpeed, color, lerpPercent, doRandom ) self.effectInstances.append( newBurst ) def makeExplosion(self, x, y, imagePath, imageWidth, imageHeight, numFrames, imageSpeed, doLoop): newAnim = EffectAnimation( x, y, imagePath, imageWidth, imageHeight, numFrames, imageSpeed, doLoop ) self.effectInstances.append( newAnim ) def spawnEnemy(self): if ( len(self.enemyList) == 0 ): for i in range( self.baseNumEnemies ): self.enemyList.append(AI(self.player, self.cam, self)) else: self.enemyList.append(AI(self.player, self.cam, self)) def draw(self): """draw the gameworld""" self.screen.fill((0,0,0)) if self.inMenu: #calls the menu's draw function self.menu.draw(self.screen) else: #Draw the regular game backRect = self.backgroundImgRect.move(-self.cam.rect.x + self.camBorder / 2, -self.cam.rect.y + self.camBorder / 2) self.screen.blit(self.backgroundImg, backRect) self.player.draw( self.screen, self.cam ) #Enemy draw for tempEnemy in self.enemyList: tempEnemy.draw(self.screen, self.cam) #Effect draw for effect in self.effectInstances: effect.draw(self.screen, self.cam) #HUD draw self.hud.draw(self.screen) #Game Over fade if self.doFade: self.fadeSurfaceAlpha += self.fadeSurfaceRate if ( self.fadeSurfaceAlpha >= 255 ): self.inMenu = True pygame.mixer.stop() pygame.mixer.music.stop() self.restartGame = True else: self.fadeSurface.fill((0,0,0,self.fadeSurfaceAlpha)) self.fadeSurface.set_alpha( self.fadeSurfaceAlpha ) #tempRect = self.fadeRect.move(-self.cam.rect.x, -self.cam.rect.y) self.fadeSurface.blit(self.fadeImage, (0,0)) self.screen.blit(self.fadeSurface,(-self.cam.rect.x + self.cam.rect.left,-self.cam.rect.y + self.cam.rect.top))
def playGame(character1, character2): pygame.init() pygame.mixer.init() pygame.mixer.music.load("Sound/07 - The Raising Fighting Spirit.ogg") #Background music "The Rising Fighting Spirit":http://downloads.khinsider.com/game-soundtracks/album/naruto-original-soundtrack-1 pygame.mixer.music.play(-1) displaysurf = pygame.display.set_mode((WIDTH, HEIGHT)) clock = pygame.time.Clock() player1=Character(PLAYER1_CONTROLS, IMAGES[character1], SOUNDS[character1], PLAYER1_POSITION) player2=Character(PLAYER2_CONTROLS, IMAGES[character2], SOUNDS[character2], PLAYER2_POSITION) HUD1_IMAGES=HUD_IMAGES.copy() HUD1_IMAGES["icon"]=IMAGES[character1]["icon"] HUD2_IMAGES=HUD_IMAGES.copy() HUD2_IMAGES["icon"]=IMAGES[character2]["icon"] player1_hud=Hud(HUD1_IMAGES, LEFT_HUD_POSITION) player2_hud=Hud(HUD2_IMAGES, RIGHT_HUD_POSITION) player2_hud.flip() background=load_image("Background/training_background.png") #http://spritedatabase.net/game/1889 background=pygame.transform.scale(background, (WIDTH, HEIGHT)) player1_wins=load_image("Background/player1wins.png") #Used the folowing website to generate the win signs: http://www.dafont.com/ninja-naruto.font player2_wins=load_image("Background/player2wins.png") pygame.display.set_caption('Pybrawl') game_over=False while True: # main game loop displaysurf.blit(background, (0,0)) clock.tick(FPS) for event in pygame.event.get(): if event.type == QUIT: pygame.quit() sys.exit() elif event.type == KEYDOWN and event.key == K_RETURN and game_over: return if player1.health==0: game_over=True pygame.mixer.music.stop() displaysurf.blit(player2_wins, (172, 200)) if player2.health==0: game_over=True pygame.mixer.music.stop() displaysurf.blit(player1_wins, (172, 200)) keys_status=pygame.key.get_pressed() if game_over: keys_status=[False for i in keys_status] player1.update(keys_status) player2.update(keys_status) collide(player1, player2) keep_inside(player1) keep_inside(player2) if player1.rect.centerx < player2.rect.centerx: player1.direction="right" player2.direction="left" else: player1.direction="left" player2.direction="right" player1_hud.update(player1.health/player1.max_health, player1.mana/player1.max_mana) player2_hud.update(player2.health/player2.max_health, player2.mana/player2.max_mana) player1.draw(displaysurf) player2.draw(displaysurf) player1_hud.draw(displaysurf) player2_hud.draw(displaysurf) pygame.display.update()
class Main(object): def __init__(self): self.clock = pygame.time.Clock() pygame.mouse.set_visible(0) self.surface = main_surface self.deadline = 120 # for monster :)) self.font = pygame.font.Font(None, 30) self.background = load_image('background.png') pygame.mixer.music.load(load_sound('background.ogg')) self.brushing() self.level_formula = lambda x: (x + random.randint(5, x + 5)) self.MAIN_LOOP = self.MENU_LOOP = self.OPTIONS_LOOP = False pygame.mixer.music.play(-1, 0.0) self.show_menu() self.start() def brushing(self): self.weapons = [] self.spiders = [] self.effects = [] self.dead_spiders = [] self.hud = Hud() self.player = Player() self.bonus_time = 0 self.bonus_timmer = 30 self.double_bonus = False self.tripple_bonus = False self.level = 0 def check_bonus_time(self): if self.double_bonus or self.tripple_bonus: if time.time() - self.bonus_time >= self.bonus_timmer: self.bonus_time = 0 self.double_bonus = False self.tripple_bonus = False def event(self): for event in pygame.event.get(): if event.type == QUIT: self.MAIN_LOOP = False elif event.type == KEYUP: if event.key == K_LCTRL: if self.tripple_bonus: self.weapons.\ append(WhiteSkull(self.player.rect.centerx - 20, self.player.rect.centery + 20, self.player.direction)) self.weapons.\ append(WhiteSkull(self.player.rect.centerx + 20, self.player.rect.centery + 20, self.player.direction)) elif self.double_bonus: self.weapons.\ append(WhiteSkull(self.player.rect.centerx - 20, self.player.rect.centery + 20, self.player.direction)) self.weapons.\ append(WhiteSkull(self.player.rect.centerx, self.player.rect.centery, self.player.direction)) elif event.key == K_SPACE: if self.player.black_skulls: self.weapons.\ append(BlackSkull(self.player.rect.centerx, self.player.rect.centery, self.player.direction)) self.player.black_skulls -= 1 elif event.key == K_ESCAPE: self.brushing() self.show_menu() keys = pygame.key.get_pressed() self.player.update(keys) def event_menu(self): for event in pygame.event.get(): if event.type == QUIT: self.MAIN_LOOP = self.MENU_LOOP = False elif event.type == KEYUP: if event.key == K_UP: self.catch_pos_menu(-1) elif event.key == K_DOWN: self.catch_pos_menu(1) elif event.key == K_RETURN: if self.menu_pos == 2: # exit game self.MAIN_LOOP = self.MENU_LOOP = False elif self.menu_pos == 1: # options self.options_menu() elif self.menu_pos == 0: # start game self.MAIN_LOOP = True self.MENU_LOOP = False def options_menu(self): self.OPTIONS_LOOP = True while self.OPTIONS_LOOP: self.surface.blit(self.background, (0, 0)) text_level = self.font.render("LEVEL {0}".format(self.level + 1), True, SILVER) text_levelR = text_level.get_rect(centerx=SCREEN_WIDTH / 2, centery=SCREEN_HEIGHT / 2) self.surface.blit(text_level, text_levelR) pygame.draw.polygon(self.surface, SILVER, ((text_levelR.centerx - 10, text_levelR.centery - 30), (text_levelR.centerx + 10, text_levelR.centery - 30), (text_levelR.centerx, text_levelR.centery - 40))) pygame.draw.polygon(self.surface, SILVER, ((text_levelR.centerx - 10, text_levelR.centery + 30), (text_levelR.centerx + 10, text_levelR.centery + 30), (text_levelR.centerx, text_levelR.centery + 40))) for event in pygame.event.get(): if event.type == QUIT: self.OPTIONS_LOOP = self.MAIN_LOOP = self.MENU_LOOP = False elif event.type == KEYUP: if event.key == K_UP: self.level += 1 elif event.key == K_DOWN: if not self.level == 0: self.level -= 1 elif event.key in (K_ESCAPE, K_RETURN): self.OPTIONS_LOOP = False pygame.display.update() self.clock.tick(FPS) def catch_pos_menu(self, pos): temp_pos = self.menu_pos + pos if temp_pos < 0: self.menu_pos = 0 elif temp_pos > 2: self.menu_pos = 2 else: self.menu_pos = temp_pos def check_collision_spiders(self): for i in reversed(xrange(len(self.spiders))): # collision with deadline and player spider = self.spiders[i] if spider.rect.top < self.deadline or (spider.rect.colliderect(self.player) and self.player.alive()): self.player.hit() self.spiders[i].get_rect_for_dead_spider() self.dead_spiders.append(self.spiders.pop(i)) continue for i in reversed(xrange(len(self.dead_spiders))): # collision with bottom screen if self.dead_spiders[i].rect_dead.top > SCREEN_HEIGHT: del self.dead_spiders[i] continue def check_collision_weapons(self): for i in reversed(xrange(len(self.weapons))): # collision with spiders index_spider = self.weapons[i].rect.collidelist(self.spiders) if index_spider != -1: (x, y) = self.spiders[index_spider].rect.centerx, self.spiders[index_spider].rect.centery self.effects.append(Effects(x, y)) self.spiders[index_spider].hit(self.weapons[i].hit) if not self.spiders[index_spider].alive(): self.hud.update_score(self.spiders[index_spider].score) # added bonus if not self.double_bonus and not self.tripple_bonus: if random.randint(self.spiders[index_spider].score, 100) >= 90: if random.random() >= 0.8: self.double_bonus = False self.tripple_bonus = True else: self.double_bonus = True self.tripple_bonus = False self.bonus_time = time.time() self.dead_spiders.append(self.spiders.pop(index_spider)) del self.weapons[i] continue # collison with bottom screen if self.weapons[i].rect.bottom > SCREEN_HEIGHT: del self.weapons[i] continue self.weapons[i].update() self.weapons[i].draw(self.surface) def draw_effects(self): for i in reversed(xrange(len(self.effects))): if self.effects[i].alive(): self.effects[i].update() self.effects[i].draw(self.surface) else: del self.effects[i] def draw_spiders(self): for spider in self.spiders: spider.update(self.level) spider.draw(self.surface) def draw_dead_spiders(self): for dead_spider in self.dead_spiders: dead_spider.update_dead() dead_spider.draw_dead(self.surface) def make_spiders(self): lvl_formula = self.level_formula(self.level) for x in xrange(0, lvl_formula): self.spiders.append(Spider()) for x in xrange(0, lvl_formula / 3): self.spiders.append(PoisonSpider()) if self.level >= 5: for x in xrange(0, self.level / 5): self.spiders.append(Tarantula()) if self.level >= 10: for x in xrange(0, self.level / 10): self.spiders.append(GiantSpider()) if self.level >= 20: for x in xrange(0, self.level / 20): self.spiders.append(WailingWidow()) def check_spiders(self): if not self.spiders: self.player.black_skulls += 5 self.level += 1 text_level = self.font.render("LEVEL {0}".format(self.level), True, SILVER) text_level_r = text_level.get_rect(centerx=SCREEN_WIDTH / 2, centery=SCREEN_HEIGHT / 2) self.surface.blit(self.background, (0, 0)) self.surface.blit(text_level, text_level_r) self.player.draw(self.surface) self.hud.draw(self.surface, self.player.health, self.level, self.player.black_skulls, time, self.bonus_time, self.bonus_timmer) self.make_spiders() self.weapons = [] self.effects = [] self.dead_spiders = [] pygame.display.update() self.clock.tick(FPS) pygame.time.delay(1500) def check_health(self): if not self.player.alive(): self.hud.save_highscore() self.animation_game_over() def animation_game_over(self): game_over_text = self.font.render("GAME OVER", 1, SILVER) game_over_text_r = game_over_text.get_rect(centerx=SCREEN_WIDTH / 2, centery=SCREEN_HEIGHT / 2) self.surface.blit(self.background, (0, 0)) self.surface.blit(game_over_text, game_over_text_r) self.player.draw(self.surface) self.hud.draw(self.surface, self.player.health, self.level, self.player.black_skulls, time, self.bonus_time, self.bonus_timmer) pygame.display.update() self.clock.tick(FPS) pygame.time.delay(3000) self.brushing() self.show_menu() def show_menu(self): text_start = self.font.render("START", True, SILVER) text_options = self.font.render("OPTIONS", True, SILVER) text_exit = self.font.render("EXIT", True, SILVER) rect_options = text_options.get_rect(centerx=SCREEN_WIDTH / 2, centery=SCREEN_HEIGHT / 2) rect_start = text_start.get_rect(centerx=rect_options.centerx, centery=rect_options.centery - 50) rect_exit = text_exit.get_rect(centerx=rect_options.centerx, centery=rect_options.centery + 50) # cursors for menu self.cur = self.font.render("||", True, SILVER) self.l_curR = self.cur.get_rect(topleft=(rect_start.left - 20, rect_start.top)) self.r_curR = self.cur.get_rect(right=rect_start.right + 20, top=rect_start.top) self.surface.blit(self.cur, self.l_curR) self.surface.blit(self.cur, self.r_curR) self.menu_pos = 0 # default "START" self.MENU_LOOP = True while self.MENU_LOOP: self.surface.blit(self.background, (0, 0)) self.surface.blit(text_start, rect_start) self.surface.blit(text_options, rect_options) self.surface.blit(text_exit, rect_exit) self.draw_cursor(rect_start, rect_options, rect_exit) self.event_menu() pygame.display.update() self.clock.tick(FPS) def draw_cursor(self, start, options, exit): if self.menu_pos == 0: self.l_curR.left = start.left - 20 self.r_curR.right = start.right + 20 self.l_curR.top = start.top self.r_curR.top = start.top self.surface.blit(self.cur, self.l_curR) self.surface.blit(self.cur, self.r_curR) elif self.menu_pos == 1: self.l_curR.left = options.left - 20 self.r_curR.right = options.right + 20 self.l_curR.top = options.top self.r_curR.top = options.top self.surface.blit(self.cur, self.l_curR) self.surface.blit(self.cur, self.r_curR) elif self.menu_pos == 2: self.l_curR.left = exit.left - 20 self.r_curR.right = exit.right + 20 self.l_curR.top = exit.top self.r_curR.top = exit.top self.surface.blit(self.cur, self.l_curR) self.surface.blit(self.cur, self.r_curR) def start(self): if self.MAIN_LOOP: text_controls_ctrl = self.font.render("CTRL - White Skulls (Power: 1)", True, SILVER) text_controls_space = self.font.render("SPACE - Black Skulls (Power: 5)", True, SILVER) text_info = self.font.render("ONE BLACK SKULL FOR NEXT LEVEL", True, SILVER) text_controls_ctrl_r = text_controls_ctrl.get_rect(centerx=SCREEN_WIDTH / 2, centery=(SCREEN_HEIGHT / 2) + 30) text_controls_space_r = text_controls_space.get_rect(centerx=text_controls_ctrl_r.centerx, centery=text_controls_ctrl_r.centery + 30) text_info_r = text_info.get_rect(centerx=text_controls_space_r.centerx, centery=text_controls_space_r.centery + 60) self.surface.blit(self.background, (0, 0)) self.surface.blit(text_controls_ctrl, text_controls_ctrl_r) self.surface.blit(text_controls_space, text_controls_space_r) self.surface.blit(text_info, text_info_r) pygame.display.update() self.clock.tick(FPS) pygame.time.delay(5000) while self.MAIN_LOOP: pygame.display.set_caption("FPS: {0:.0f}".format(self.clock.get_fps())) self.surface.blit(self.background, (0, 0)) self.draw_dead_spiders() self.check_spiders() self.draw_spiders() self.player.draw(self.surface) self.hud.draw(self.surface, self.player.health, self.level, self.player.black_skulls, time, self.bonus_time, self.bonus_timmer) self.event() self.check_collision_spiders() self.check_collision_weapons() self.check_health() self.draw_effects() self.check_bonus_time() pygame.display.update() self.clock.tick(FPS) pygame.mixer.music.stop() pygame.quit()
class Viewport(): def __init__(self, virtual_width, virtual_height, map_height, map_width): self.v_rect = pygame.Rect(0, 0, virtual_width, virtual_height-config.hud_size) self.map_rect = pygame.Rect(0, 0, map_width, map_height) self.hud_rect = pygame.Rect(0, virtual_height-config.hud_size, virtual_width, config.hud_size) self.map_layer = [] self.map_layer_surf= pygame.Surface((self.map_rect.w, self.map_rect.h)) self.item_layer = [] self.item_layer_surf= pygame.Surface((self.map_rect.w, self.map_rect.h), flags=pygame.SRCALPHA) self.unit_layer = [] self.unit_layer_surf= pygame.Surface((self.map_rect.w, self.map_rect.h), flags=pygame.SRCALPHA) self.unit_action_surf = pygame.Surface((self.map_rect.w, self.map_rect.h), flags=pygame.SRCALPHA) self.hud = Hud(0, virtual_height-config.hud_size, virtual_width, config.hud_size, self) self.hud_surf = pygame.Surface((self.hud_rect.w, self.hud_rect.h)) self.hud_surf.fill(pygame.Color("#737373")) self.hud_font = pygame.font.Font("assets/bitwise/bitwise.ttf", 25) self.dirty = 1 self.font = pygame.font.Font(None, 20) self.mouse_events = [] def south(self): if abs(self.v_rect.y) + 5 < self.map_rect.h - config.window_size[1] + config.hud_size: self.v_rect.y += 5 elif abs(self.v_rect.y) + 1 < self.map_rect.h - config.window_size[1]: self.v_rect.y += 1 def north(self): if abs(self.v_rect.y) - 5 >= 0: self.v_rect.y -= 5 elif abs(self.v_rect.y) - 1 >= 0: self.v_rect.y -= 1 def east(self): if abs(self.v_rect.x) + 5 < self.map_rect.w - config.window_size[0]: self.v_rect.x += 5 elif abs(self.v_rect.x) + 1 < self.map_rect.w - config.window_size[0]: self.v_rect.x += 1 def west(self): if abs(self.v_rect.x) - 5 >= 0: self.v_rect.x -= 5 elif abs(self.v_rect.x) - 1 >= 0: self.v_rect.x -= 1 def handle_keyboard_events(self): keys = pygame.key.get_pressed() if keys[K_UP]: self.north() if keys[K_DOWN]: self.south() if keys[K_LEFT]: self.west() if keys[K_RIGHT]: self.east() def handle_mouse_events(self): mouse_pos = pygame.mouse.get_pos() for y in self.item_layer: for x in y: if x is not None: if isinstance(x, list): for item in x: if item.mouse_collide(mouse_pos): for event in self.mouse_events: if item.mouse_collide(event.pos, side_effect=False): item.toggle_selected() else: if x.mouse_collide(mouse_pos): for event in self.mouse_events: if x.mouse_collide(event.pos, side_effect=False): x.toggle_selected() hovering_unit = False for unit in self.unit_layer: if unit.mouse_collide(): self.hud.hovered_unit = unit self.dirty = 1 hovering_unit = True break if not hovering_unit and self.hud.hovered_unit != None: self.hud.hovered_unit = None self.dirty = 1 hovering_stock_pile = False for y in self.item_layer: for x in y: if isinstance(x, Stockpile): if x.mouse_collide(mouse_pos, side_effect=False) or x.mouse_collide(side_effect=False): self.hud.hovered_stock_pile= x self.dirty = 1 hovering_stock_pile= True break if not hovering_stock_pile and self.hud.hovered_stock_pile != None: self.hud.hovered_stock_pile = None self.dirty = 1 self.mouse_events = [] def render(self): if self.dirty == 1 or self.dirty == 2: if self.dirty == 1: self.dirty = 0 diff_rects = [] for y in range(0, config.world_size[0]): for x in range(0, config.world_size[1]): map_diff = self.map_layer[y][x].draw(self.map_layer_surf) item_diff = None if self.item_layer[y][x] != None: if isinstance(self.item_layer[y][x], list): for item in self.item_layer[y][x]: item_diff = item.draw(self.item_layer_surf) diff_rects.append(item_diff) else: # not a list item_diff = self.item_layer[y][x].draw(self.item_layer_surf) diff_rects.append(item_diff) diff_rects.append(map_diff) for unit in self.unit_layer: unit.draw(self.unit_layer_surf) self.unit_action_surf.fill(pygame.Color(0, 0, 0, 1)) for unit in self.unit_layer: unit.draw_action(self.unit_action_surf) self.hud.draw(self.hud_surf) def draw(self, surf): rects = [ ] # draw map layer rects.append( surf.blit(self.map_layer_surf, (0, 0), area=self.v_rect) ) # item layer rects.append( surf.blit(self.item_layer_surf, (0, 0), area=self.v_rect) ) # unit layer rects.append( surf.blit(self.unit_layer_surf, (0, 0), area=self.v_rect) ) # unit action layer rects.append( surf.blit(self.unit_action_surf, (0, 0), area=self.v_rect) ) # draw hud layer rects.append( surf.blit(self.hud_surf, (self.hud_rect.x, self.hud_rect.y)) ) return rects
class Game(Div, object): """main frame of the game""" def __init__(self, controller): # super(game, self).__init__() self.controller = controller self.initAttr() self.initElement() def setLevel(self, level = 6): self.boardWidth, self.boardHeight = self.board.setLevel(level) self.height = self.boardHeight + self.edgeWidth * 2 self.width = self.boardWidth + self.hudWidth self.initContext() def initAttr(self): self.turn = True self.hudWidth = HUD["HUD_WIDTH"] self.edgeWidth = GAME["EDGE_WIDTH"] # 先获取 board 部分的大小,再自适应自己的大小 self.board = Board((self.hudWidth, self.edgeWidth)) Div.__init__(self, (self.board.width + self.hudWidth, self.board.height + self.edgeWidth * 2)) # 根据窗口高度设置 HUD 高度 self.hud = Hud((0, self.height), (0, 0)) self.hud.setMark(self.turn) self.board.setTurn(self.turn) self.gameID = 0 self.order = None def initElement(self): # 背景 self.background = Background((self.width, self.height)) backgroundColor = GAME["GAME_BACKGROUND_COLOR"] self.background.setColor(backgroundColor) # 返回按钮 self.returnButton = TextButton(GAME["RETURN_BUTTON_FONTS"], GAME["RETURN_BUTTON_CONTENT"], (30, 30)) def initContext(self): self.screen = pygame.display.set_mode((self.width, self.height), DOUBLEBUF) pygame.display.set_caption("Boxes") self.clock = pygame.time.Clock(); def leaveServer(self, *args): self.controller.gameNet.leaveServer(self.gameID) return STATE.menu def placeLine(self, data): if self.hud.started: self.controller.gameNet.placeLine(data, self.gameID, self.order) def placeLineAnswer(self, turn, x, y, h, point, order): self.setTurn(turn) if order == self.order: self.board.placeLine(x, y, h, point, True) else: self.board.placeLine(x, y, h, point, False) def setTurn(self, turn): self.hud.setMark(turn) self.board.setTurn(turn) def setHome(self): self.order = 0 self.board.setHome() self.background.setColor(GAME["HOME_COLOR"]) def setAway(self): self.order = 1 self.board.setAway() self.background.setColor(GAME["AWAY_COLOR"]) def addScore(self): self.hud.addScore() def enemyAddScore(self): self.hud.enemyAddScore() # 对手玩家进入游戏 def enemyComming(self, turn): self.setTurn(turn) self.board.restart() self.hud.startGame() def newHost(self): self.hud.restart() # 数据清零,重新开始游戏 def restart(self): self.board.restart() self.hud.restart() def draw(self): # self.screen.set_clip(None) self.background.draw(self.screen) ret = self.board.draw(self.screen) if ret != None: self.placeLine(ret) self.hud.draw(self.screen) self.returnButton.draw(self.screen) var = self.returnButton.click(self.leaveServer) if var != None: return var return STATE.game
class MonorailGame: STATE_INTRO, STATE_BEGIN, STATE_GAME, STATE_MENU, STATE_QUIT, STATE_STATS, STATE_TOTAL,\ STATE_DONE = range( 8 ) MOUSE_TIMEOUT = 25 * 3 def __init__(self, game_data): self.restart(game_data) self.music_man = MusicManager() # preload clock sounds and big explosion graphic resman.get("game.clock_sound") resman.get("game.clockring_sound") resman.get("game.explosion_sprite") def restart(self, game_data): """Start a new game with the current game_data""" self.game_data = game_data self.state = MonorailGame.STATE_INTRO self.scenario = self.game_data.get_quest().create_scenario( self.game_data.skill_level.value) self.playfield = self.scenario.playfield self.controller = ctrl.GroundControl(self.playfield) self.init_goldcars() self.hud = Hud(self.scenario, self.controller, self.game_data) self.hud.start_intro_screen() self.begin_timeout = 25 * 3 self.ingame_menu = None self.gui_state = GuiState() self.mouse_timeout = MonorailGame.MOUSE_TIMEOUT self.is_paused = False def init_goldcars(self): goldcar_names = [] controllers = [] for name, controller in self.game_data.goldcars: goldcar_names.append(name) controllers.append(controller) for iq in self.game_data.get_quest().get_opponent_iqs(): goldcar_names.append("") controllers.append(ctrl.AiController(None, iq)) self.playfield.add_goldcars(goldcar_names) self.controller.add_controllers(controllers) def do_tick(self, indev): if self.ingame_menu is None and not self.is_paused: if self.game_data.is_single_player() or \ self.game_data.is_single_random(): SingleSwitch.feed_keys(indev) # in singleplayer, all joystick buttons are keypress for joy in indev.joys: if joy.any_went_down(): indev.key.feed_down(K_SPACE) if joy.any_went_up(): indev.key.feed_up(K_SPACE) if self.state == MonorailGame.STATE_INTRO: if self.hud.is_ready( ): # or self.game_data.is_single_player(): self.hud.end_info() self.state = MonorailGame.STATE_BEGIN self.music_man.play() elif self.state == MonorailGame.STATE_BEGIN: if self.begin_timeout % 50 == 0: random_spawn = not self.game_data.is_single_player() spawns_left = self.playfield.spawn_next_goldcar( random_spawn) if spawns_left: self.begin_timeout += 50 self.controller.game_tick(indev) self.playfield.game_tick() # Start right away in single player if self.game_data.is_single_player(): self.scenario.game_tick() self.begin_timeout -= 1 if self.begin_timeout <= 0: self.state = MonorailGame.STATE_GAME if indev.mouse.has_moved(): self.mouse_timeout = MonorailGame.MOUSE_TIMEOUT else: self.mouse_timeout -= 1 elif self.state == MonorailGame.STATE_GAME: self.controller.game_tick(indev) self.playfield.game_tick() self.scenario.game_tick() if self.scenario.is_finished(): if not self.game_data.is_single_player(): self.hud.start_end_screen() else: self.game_data.get_quest().save_score(self.scenario) skill = self.game_data.get_quest().get_skill( self.scenario) self.game_data.skill_level.update(skill) self.game_data.save_single_player_progress() if self.scenario.has_won(): self.hud.start_win_screen() else: self.hud.start_lose_screen() self.state = MonorailGame.STATE_STATS self.mouse_timeout = MonorailGame.MOUSE_TIMEOUT self.music_man.stop() if indev.mouse.has_moved(): self.mouse_timeout = MonorailGame.MOUSE_TIMEOUT else: self.mouse_timeout -= 1 elif self.state == MonorailGame.STATE_STATS: if self.hud.is_ready(): if not self.game_data.is_single_player(): self.game_data.add_total_scores(self.playfield) self.hud.start_total_screen() self.state = MonorailGame.STATE_TOTAL else: if self.scenario.has_won(): self.state = MonorailGame.STATE_DONE else: self.restart(self.game_data) return elif self.state == MonorailGame.STATE_TOTAL: if self.hud.is_ready(): self.state = MonorailGame.STATE_DONE elif self.state == MonorailGame.STATE_MENU: pass self.hud.game_tick(indev) self.music_man.game_tick() SingleSwitch.tick(indev, None) if indev.key.went_down( K_ESCAPE ) or \ self.hud.menu_btn.went_down() or \ SingleSwitch.esc_went_down or \ indev.joys.any_went_down( Joystick.BTN_BACK ): resman.get("gui.paper_sound").play() self.ingame_menu = IngameMenu( self.game_data.is_single_player(), self.game_data) elif self.ingame_menu is not None: # Ingame Menu SingleSwitch.feed_keys(indev) self.gui_state.update(indev, self.ingame_menu) self.ingame_menu.tick(indev, self.gui_state) if self.ingame_menu.is_done(): if self.ingame_menu.to_menu: self.music_man.stop() self.state = MonorailGame.STATE_MENU elif self.ingame_menu.should_quit: self.music_man.stop() self.state = MonorailGame.STATE_QUIT elif self.ingame_menu.to_next_level: self.music_man.stop() self.state = MonorailGame.STATE_DONE self.ingame_menu = None self.mouse_timeout = MonorailGame.MOUSE_TIMEOUT # if indev.key.went_down( K_p ): # self.is_paused = not self.is_paused event.Event.update() # for debugging if self.is_paused: self.controller.game_tick(indev) def draw(self, surface, interpol, time_sec): #surface.fill( (0,0,0) ) frame = Frame(surface, time_sec, interpol) if self.ingame_menu is not None or self.is_paused or\ self.state not in [MonorailGame.STATE_BEGIN, MonorailGame.STATE_GAME]: frame.interpol = 0.0 frame.draw(self.playfield) frame.draw(self.controller) self.hud.draw(frame) if self.ingame_menu is not None: self.ingame_menu.draw(surface) frame.draw(event.Event.instance) def draw_mouse(self, surface, interpol, time_sec): if self.mouse_timeout > 0: x, y = pygame.mouse.get_pos() resman.get("gui_surf").draw(surface, Vec2D(x, y), (0, 0, 32, 32)) def mouse_down(self, button): pass def is_done(self): return self.state == MonorailGame.STATE_DONE \ or self.state == MonorailGame.STATE_MENU \ or self.state == MonorailGame.STATE_QUIT
class World (object): def __init__(self): super(World, self).__init__() self.frames = 1 # this is normal difficulty by default # easy would prolly be .7ish and hard.. 1.3 or so? self.difficulty = 0.7 self.spawnFreq = 10 self.scrollPosition = 0 self.scrollSpeed = 3 self.endPosition = FRAMES_UNTIL_BOSS * self.scrollSpeed self.startScreen = True self.helpScreen = False self.difficultyScreen = False self.bossMode = False self.gameOver = False self.winScreen = False self.score = 0 self.call_popcorn = 0 self.boss_music=False self.holdingLeftMouseButton = False #for keeping track of for the win screen! self.numEnemiesAppeared = 0 self.numEnemiesDestroyed = 0 self.numViruses = 0 self.numWorms = 0 self.numPopUps = 0 self.playerGroup = pygame.sprite.GroupSingle() self.enemies = pygame.sprite.Group() self.pickups = pygame.sprite.Group() self.bullets = pygame.sprite.Group() self.mines = pygame.sprite.Group() self.backgrounds = pygame.sprite.Group() self.spawnBkg() # sprite groups listed in draw order (lowest sprite get drawn first) self.spriteGroups = [self.backgrounds, self.mines, self.pickups, self.bullets, self.enemies, self.playerGroup] self.hud = Hud() def spawnWorld(self): self.StartScreen = False playerPos = (PLAY_WIDTH / 2, SCREEN_HEIGHT - 50) pygame.mouse.set_pos(playerPos) self.player = Player(self, playerPos) self.playerGroup.add(self.player) pygame.mixer.music.load("data/music/Main.mp3") pygame.mixer.music.play() self.hud.createHudElements() self.frames = 1 self.scrollPosition = 0 self.scrollSpeed = 3 def spawnBkg(self): bkg = Bkg() self.backgrounds.add(bkg) def spawnCtrl(self): ctrl = Ctrl() self.pickups.add(ctrl) def spawnAlt(self): alt = Alt() self.pickups.add(alt) def spawnDel(self): d = Del() self.pickups.add(d) def spawnVirus(self, position): self.numEnemiesAppeared += 1 enemy = Virus(position) self.enemies.add(enemy) def spawnDoubleVirus(self, position): self.numEnemiesAppeared += 1 enemy = DoubleVirus(self, position) self.enemies.add(enemy) def spawnTripleVirus(self): self.numEnemiesAppeared += 1 enemy = TripleVirus(self) self.enemies.add(enemy) def spawnWorm(self): self.numEnemiesAppeared += 1 position1 = random.randint(195,PLAY_WIDTH-50) position2 = 10 position = position1, position2 enemy = Worm(position,'head') self.enemies.add(enemy) for i in range(random.randint(1,5)): position1 -= 32 position = position1, position2 enemy = Worm(position,'body') self.enemies.add(enemy) position1 -= 32 position = position1, position2 enemy = Worm(position,'tail') self.enemies.add(enemy) def spawnPopup(self): self.numEnemiesAppeared += 1 enemy = Popup() while len(pygame.sprite.spritecollide(enemy, self.playerGroup, False)) > 0: enemy = Popup() self.enemies.add(enemy) def spawnBoss(self): self.boss_music=True self.numEnemiesAppeared += 1 pygame.mixer.music.load("data/music/Boss.mp3") pygame.mixer.music.play(-1) self.boss = Boss((PLAY_WIDTH / 2, -200)) self.enemies.add(self.boss) for tentacle in self.boss.tentacles: for link in tentacle.links: self.enemies.add(link) def spawnSafe(self): safe = SafeMode() self.pickups.add(safe) def leftMouseButtonDown(self): self.holdingLeftMouseButton = True self.player.shoot(self.bullets) def leftMouseButtonUp(self): self.holdingLeftMouseButton = False def rightMouseButtonDown(self): self.player.quarantine(self.mines) sound = pygame.mixer.Sound("data/sounds/minedeploy.wav") sound.set_volume(.25) sound.play() def enemy_popcorn(self): if len(self.enemy_list)==1: self.call_popcorn=0 else: self.enemy_list[1].takeHit(self.enemy_list[1].health) self.enemy_list.remove(self.enemy_list[1]) def destroy_all_enemies(self): self.enemy_list=[0] if self.player.destroyAllEnemies: self.player.after_destroy_all() sound = pygame.mixer.Sound("data/sounds/destroyall.wav") sound.play() for enemy in self.enemies: if enemy.typeofenemy == 'boss' or enemy.typeofenemy == 'link': enemy.takeHit(1) else: if enemy.typeofenemy is 'virus': self.numViruses += 1 if enemy.typeofenemy is 'worm': self.numWorms += 1 if enemy.typeofenemy is 'pop up window': self.numPopUps += 1 self.numEnemiesDestroyed += 1 self.enemy_list.insert(1,enemy) #enemy.takeHit(enemy.health) self.call_popcorn=self.frames def update(self): if self.holdingLeftMouseButton: if self.frames % 5 == 0: self.player.shoot(self.bullets) for group in self.spriteGroups: group.update() self.hud.update(self) # Test player-enemy collisions for enemy in pygame.sprite.spritecollide(self.player, self.enemies, False): if not enemy.dead and not enemy.animName == 'spawn': if not enemy.typeofenemy == 'boss': enemy.takeHit(enemy.health) if not self.player.invincible: self.player.decrease_life() self.score -= 100 if enemy.dead: if enemy.typeofenemy is 'virus': self.numViruses += 1 self.numEnemiesDestroyed += 1 if enemy.typeofenemy is 'worm': self.numWorms += 1 self.numEnemiesDestroyed += 1 if enemy.typeofenemy is 'pop up window': self.numPopUps += 1 self.numEnemiesDestroyed += 1 # Test player-pickup collisions for pickup in pygame.sprite.spritecollide(self.player, self.pickups, False): pickup.on_collision(self.player) sound = pygame.mixer.Sound("data/sounds/keypickup.wav") sound.play() # Test enemy-playerBullet collisions for enemy, bullets in pygame.sprite.groupcollide(self.enemies, self.bullets, False, False).items(): for bullet in bullets: enemy.collideWithBullet(bullet) if enemy.dead: self.player.increase_powerup(5) if enemy.typeofenemy == "worm": self.numWorms += 1 self.numEnemiesDestroyed += 1 self.score += 25 elif enemy.typeofenemy == "virus": self.numViruses += 1 self.numEnemiesDestroyed += 1 self.score += 10 elif enemy.typeofenemy == "popup": self.numEnemiesDestroyed += 1 self.numPopUps += 1 self.score += 15 # Test enemy-mine collisions for mine in self.mines: if mine.exploding: for enemy in pygame.sprite.spritecollide(mine, self.enemies, False): enemy.takeHit(1) if enemy.dead: if enemy.typeofenemy is 'virus': self.numViruses += 1 self.numEnemiesDestroyed += 1 if enemy.typeofenemy is 'worm': self.numWorms += 1 self.numEnemiesDestroyed += 1 if enemy.typeofenemy is 'pop up window': self.numPopUps += 1 self.numEnemiesDestroyed += 1 # Check enemies offscreen, popups doing damage for enemy in self.enemies: if enemy.rect.top > SCREEN_HEIGHT and not enemy.typeofenemy == 'link': enemy.kill() self.score -= 10 self.player.decrease_health(1) sound = pygame.mixer.Sound("data/sounds/CPUload.wav") sound.play() if enemy.typeofenemy == "popup": if enemy.frame % 20 == 0: self.score -= 1 # Check bullets offscreen for bullet in self.bullets: if bullet.rect.bottom < 0: bullet.kill() # Check backgrounds offscreen for bkg in self.backgrounds: if bkg.rect.top > SCREEN_HEIGHT: bkg.kill() if self.frames % 360 == 0: self.spawnBkg() if self.spawnFreq is not 1: if self.frames % (500) == 0: if self.spawnFreq <= 1: self.spawnFreq = 1 elif self.spawnFreq > 1: self.spawnFreq -= self.difficulty # Spawn more enemies baseSpawnRate = (self.spawnFreq * 5 + random.randint(1, 5)) #print self.difficulty, baseSpawnRate, self.spawnFreq if not self.bossMode: if self.frames % baseSpawnRate < 1: seed = random.randint(1, 10) if(seed < 7): self.spawnVirus(0) elif(seed < 10): self.spawnDoubleVirus(0) else: self.spawnTripleVirus() if self.frames % (baseSpawnRate * random.randint(3, 6)) < 1: self.spawnWorm() if self.frames % (baseSpawnRate * random.randint(2, 5)) < 1: self.spawnPopup() if self.frames % (baseSpawnRate * random.randint(18, 21)) < 1: self.player.destroyAllEnemies = True if self.frames % (baseSpawnRate * random.randint(1, 4)) < 1: self.spawnCtrl() if self.frames % (baseSpawnRate * random.randint(5, 8)) < 1: self.spawnAlt() if self.frames % (baseSpawnRate * random.randint(9, 12)) < 1: self.spawnDel() if self.frames % (baseSpawnRate * random.randint(4, 7)) < 1: self.spawnSafe() # Check if main music has ended, and loop music should start if not pygame.mixer.music.get_busy(): if not self.boss_music: pygame.mixer.music.load("data/music/Mainloop.mp3") pygame.mixer.music.play(-1) elif self.frames == FRAMES_UNTIL_BOSS + MUSIC_LENGTH_BOSS: pygame.mixer.music.load("data/music/Bossloop.mp3") pygame.mixer.music.play(-1) #Check for calling enemy_popcorn if self.call_popcorn != 0 and self.call_popcorn<self.frames-10: self.enemy_popcorn() # Check gameover if self.player.lives == 0: self.gameOver = True pygame.mixer.music.stop() # Check win screen! if self.bossMode and self.boss.dead and self.boss.anim.done: if not self.winScreen: self.numEnemiesDestroyed += 1 self.winScreen = True # Scroll level self.scrollPosition += self.scrollSpeed self.scrollPosition = min(self.scrollPosition, self.endPosition) if self.scrollPosition == self.endPosition and not self.bossMode: self.bossMode = True self.spawnBoss() self.frames += 1 def draw(self, screen): for group in self.spriteGroups: for sprite in group: sprite.draw(screen) self.hud.draw(screen, PLAY_WIDTH)
class Character(Sprite): """Representing a character(toon) with its movements, skills, sound effects and hud. attributes -- dictionary that holds the attribute of each character skill_names -- dictionary that holds the skills of each cahracter """ attributes = {"itachi": ATTRIBUTES[0], "sasuke": ATTRIBUTES[1], "suigetsu": ATTRIBUTES[1], "naruto": ATTRIBUTES[0], "jiraiya": ATTRIBUTES[0]} skill_names = {"itachi": {"throw": "throw_shuriken", "special_1": "amaterasu", "special_2": "katon_goukakyuu"}, "sasuke": {"throw": "throw_lightning", "special_1": "katon_gouryuuka", "special_2": "chidori"}, "suigetsu": {"throw": "throw_explosive_note", "special_1": "suirou", "special_2": "kubikiri_shuriken"}, "naruto": {"throw": "rasengan", "special_1": "rasen_shuriken", "special_2": "kyuubi"}, "jiraiya": {"throw": "throw_kunai", "special_1": "rasengan_original", "special_2": "katon_endan"}} def __init__(self, player, character_name, position=Vec2D(0, 0)): """Initialize all member variables of character. damage -- numeric value, the amount of harm dealt through normal_attack lock -- bool varible, says if the character is currently casting an ability or motion action -- string, the action currently being excecuted by the character """ pygame.sprite.Sprite.__init__(self) self.name = character_name self.damage = 100 self.attribute = self.attributes[self.name] self.lock = True self.action = "introduction" self.enemy_position = pygame.Rect(0, 0, 0, 0) if not isinstance(position, Vec2D): self.position = Vec2D(position) else: self.position = position if player == 1: self.controls = P1_CONTROLS self.direction = "Right" elif player == 2: self.controls = P2_CONTROLS self.direction = "Left" else: raise SystemExit("player argument should be either 1 or 2") self.movements = {} for action in get_all_movements(self.name): self.movements[action] = Movement(self.name, action) self.skills = SkillManager() self.hud = Hud(player, self.name) self.sound_effects = SoundManager(self.name) self.update({}) def update(self, input_list): """Update the current character action, movement, position, sound effect and hud. Character.update(): return None """ self.update_action(input_list) self.movements[self.action].update(pygame.time.get_ticks()) self.image, self.rect = self.movements[self.action].get_image() self._adjust_direction() self._adjust_position() if (self.direction == "Left" and self.action in ["take_damage", "normal_attack"]): self.position -= self.movements[self.action].force else: self.position += self.movements[self.action].force self.rect.topleft = self.position if self.lock: if self.movements[self.action].done: self.movements[self.action].reset() self.lock = False if self.action in self.skill_names[self.name]: skill = Skill(self) self.skills.add(skill) self.hud.mana.value -= skill.mana_cost self.sound_effects.stop() self.sound_effects[self.action].play() self.hud.update() def update_action(self, input_list): """Update character's action given an input list. If a skill is to be cast check the mana bar if it holds enought mana and play the corresponding sound effect. Character.update_action(input_list): return None """ action_taken = False if not self.lock: if input_list[self.controls[0]]: self.action = "move_left" action_taken = True if input_list[self.controls[1]]: self.action = "move_right" action_taken = True if input_list[self.controls[2]]: self.action = "jump" self.lock = True action_taken = True if (input_list[self.controls[3]] and self.hud.mana.value >= Skill.mana_costs["throw"]): self.action = "throw" self.lock = True action_taken = True if input_list[self.controls[4]]: self.action = "normal_attack" self.lock = True action_taken = True if (input_list[self.controls[5]] and self.hud.mana.value >= Skill.mana_costs["special_1"]): self.action = "special_1" self.lock = True action_taken = True if (input_list[self.controls[6]] and self.hud.mana.value >= Skill.mana_costs["special_2"]): self.action = "special_2" self.lock = True action_taken = True if not action_taken: self.action = "stance" def draw(self, surface): """Draw the hud and the character image onto the passed surface. Call the draw methods of Hud and Sprite. Character.draw(surface): return None """ self.hud.draw(surface) super(Character, self).draw(surface) def _adjust_position(self): """Adjust the character position so the bottom side of its rect is at FLOOR_HEIGHT position. Character._adjust_position(): return None Should not be called manually. """ if (self.action != "jump" or self.movements[self.action].current_frame == 0): self.position.y = (DEFAULT_SCREEN_SIZE[1] - FLOOR_HEIGHT - self.rect.height) if self.position.x < 0: self.position.x = 0 elif self.position.x > DEFAULT_SCREEN_SIZE[0] - self.rect.width: self.position.x = DEFAULT_SCREEN_SIZE[0] - self.rect.width elif (self.position.y > (DEFAULT_SCREEN_SIZE[1] - FLOOR_HEIGHT - self.rect.height)): self.position.y = (DEFAULT_SCREEN_SIZE[1] - FLOOR_HEIGHT - self.rect.height) def _adjust_direction(self): """Adjust the character direction so it faces the opponent. This does not hold when the character is moving left or right. Character._adjust_direction(): return None Should not be called manually. """ if (self.direction == "Left" and self.action not in ["move_left", "move_right"]): self.image = pygame.transform.flip(self.image, True, False)
class Engine(object): def __init__(self): self.music = None ika.SetCaption('%s - Mannux' % ika.GetCaption()) video.clear() print >> fonts.big.center(), 'Loading . . .' ika.Video.ShowPage() self.window = Window() self.seconds = 0 self.minutes = 0 self.hours = 0 self.ticks = 0 self.time = '' self.flags = {'notloaded': True, 'shiplanded': False} self.curmap = '' # Not loading a map at this time. self.loading = False # Temporary Things, erased on each mapswitch. self.background_things = [] self.foreground_things = [] # Permanent Things, never erased (not currently used.) self.permanent_things = [] self.fields = [] self.entities = [] self.effects = [] self.add_list = [] self.kill_list = [] self.addeffect_list = [] self.killeffect_list = [] self.messages = [] # Current layer. self.cur_secret = None self.cur_terrain = None #for splash/water effects, mostly # List of layers in map. self.secret_layers = [] self.terrain_layers = [] try: ika.Map.Switch('amap.ika-map') except ImportError: # Probably should do something here. pass self.automap = automap.AutoMap() self.automap.load_automap() #self.meta = ika.Map.GetMetaData() # DO NOT PUT RUN HERE # If run is put here, the engine object is never returned. self.lights=True #lights activated self.lightcanvas=ika.Canvas(320,240) #should use xres and yres self.lightcanvas.Clear(ika.RGB(255,255,255,255)) self.circleimage = ika.Image('%s/circle_gradient.png' % config.image_path) self.circle = ika.Canvas('%s/circle_gradient.png' % config.image_path) self.bigcircle = ika.Canvas('%s/circle320.png' % config.image_path) self.smallcircle = ika.Canvas('%s/circle32.png' % config.image_path) def GetFlag(self, key): return self.flags.get(key, False) def SetFlag(self, key, value): self.flags[key] = value def GetLayers(self): """Creates a listing for all secret/terrain layers.""" s_layers = [] #secret t_layers = [] #terrain lname = '' for l in range(ika.Map.layercount): #complex line for grabbing all layers that start with the word secret :) lname = ika.Map.GetLayerName(l) if lname[:6].lower() == "secret": s_layers.append([l, 0, 255]) elif lname in ("Lava", "Acid", "Water"): #add more later, possibly.. #get the layer height and scroll through it to find where it starts #terrain layers #for i in range(ika.Map.GetLayerProperties(l)[2]): # if ika.Map.GetTile(0, i, l): #find where the layer actually begins... may need to change later t_layers.append( ( lname, l ) ) #name, layer # print "Terrain Detected. Type: " + lname + " "+str(l) #break self.secret_layers = s_layers self.terrain_layers = t_layers self.cur_secret = None self.cur_terrain = None # #Grab terrain layer. # tlayer = ika.Map.layercount - 1 # name = ika.Map.GetLayerName(tlayer) # #Check the last layer's name to see if it's a terrain type. # if name in ("Lava", "Acid", "Water") or name[:4] == "Wind": # print "Terrain Detected. Type: " + name # for i in range(ika.Map.GetLayerProperties(tlayer)[2]): # if ika.Map.GetObs(0, i, tlayer): # ty = i # break # self.cur_terrain = (name, tlayer, ty * 16) # else: # self.cur_terrain = None def initialize(self): self.player = Tabby(0, 0) self.hud = Hud() self.pause = Pause() self.title = TitleScreen() self.camera = Camera(self.player.sprite) self.cameratarget = self.player self.entities.append(self.player) #player should always be the first in the list def newgame(self): self.load('%s/default.save' % config.save_path) def loadgame(self, f='%s/savegame.save' % config.save_path): try: #sf = file(f) #close(f) self.load(f) except: self.newgame() def Run(self): self.title.show() self.newgame() #only comment out if not showing title self.hud.resize() self.automap.update_room() time = ika.GetTime() done = False self.music = ika.Music('%s/00_-_zaril_-_close_to_the_core.xm' % config.music_path) self.music.loop = True self.music.Play() while not done: t = ika.GetTime() while t > time: # Uncomment for slow motion. #ika.Delay(2) self.tick() time += 1 time = ika.GetTime() self.update_time() self.camera.update() self.draw() print >> fonts.one(0, 40), 'FPS:', ika.GetFrameRate() #for i, e in enumerate(self.entities): # print >> fonts.one(0, 50 + 10*i), 'sprite', e.sprite ika.Input.Update() if controls.pause.Pressed(): self.pause.menu() ika.Input.Unpress() # Make sure the engine doesn't have to play 'catchup'. time = ika.GetTime() #screenshot key if False: #controls.confirm.Pressed(): #screenshot #self.text('This is a textbox.') ika.Input.Unpress() time = ika.GetTime() c = ika.Video.GrabCanvas(0, 0, ika.Video.xres, ika.Video.yres) c2 = ika.Image(c) c2.Blit(0, 0) c.Save('blah1.png') ika.Video.ShowPage() def draw(self): for thing in self.background_things: thing.draw() #if self.background: # ika.Video.Blit(self.background, 0, 0) for i in range(ika.Map.layercount): ika.Map.Render(i) for ent in self.entities: if ent.layer == i and ent.visible: ent.draw() #inefficient as it loops through each entity multiple times depending on # of layers, but works for now... #if performance becomes an issue will refactor to multiple lists per layer. for eff in self.effects: if eff.layer == i and eff.visible: eff.draw() #for special effects, may behave differntly for entities so putting them here instead. #video.clear(ika.RGB(0, 255, 0)) #ika.Map.Render() for thing in self.foreground_things: try: thing.draw() except AttributeError: # This is retarded. pass if self.lights: #lightmap check #self.lightcanvas.Clear() p=self.player x=int(p.x + p.width/2 - ika.Map.xwin)# - 320 y=int(p.y + p.height/2 - ika.Map.ywin)# - 240 #print >> fonts.tiny(0,80), 'x: '+str(x) #print >> fonts.tiny(0,90), 'y: '+str(y) #self.bigcircle.Blit(self.lightcanvas, 0, 0, ika.AddBlend) #self.smallcircle.Blit(self.lightcanvas, x-10, y-80, ika.AddBlend) #if controls.confirm.Pressed(): # self.lightcanvas.Save("test.png") #self.lightcanvas.Blit(self.image, x , y, ika.RGB(255, 255, 255, self.opacity), ika.SubtractBlend) #img=ika.Image(self.lightcanvas) #ika.Video.DrawRect(0,0,319,219,ika.RGB(0,0,64,128), ika.SubtractBlend) #ika.Video.TintBlit(img, 0,0, ika.RGB(255,255,255,128), ika.AddBlend) #the one that always works #ika.Video.DrawEllipse(x+160, y+160, 50, 40, ika.RGB(100,100,100,128), 1, ika.AddBlend) #ika.Video.TintBlit(img, 0 , 0, ika.RGB(255, 255, 255, 128)) #ika.Video.TintBlit(img, 0 , 0) self.hud.draw() x = 10 y = 230 for m in self.messages: print >> fonts.one(x, y), m.text y -= 10 #font.Print(0, 80, self.meta['testing']) #font.Print(240, 0, 'xwin: %s' % ika.Map.xwin) #font.Print(240, 10, 'ywin: %s' % ika.Map.ywin) #font.Print(240, 30, 'vx: %s' % self.player.vx) #font.Print(240, 40, 'floor: %s' % self.player.floor) #font.Print(10, 60, 'x: %s' % self.player.x) #font.Print(10, 70, 'y: %s' % self.player.y) #font.Print(10, 80, 'slope: %s' % self.player.in_slope) #font.Print(10, 90, 'floor: %s' % self.player.floor) #font.Print(10, 100, 'jumps: %s' % self.player.jump_count) #font.Print(10, 70, 'vy: %s' % self.player.vy) #font.Print(10, 80, self.player.msg) #font.Print(10, 80, str(ika.Input.joysticks[0].axes[0].Position())) #font.Print(10, 80, str(len(entities))) #x = int(self.player.x + self.player.sprite.hotwidth / 2 + # self.player.vx) #y = int(self.player.y + self.player.sprite.hotheight - 1 + # self.player.vy) #tx = x / 16 #ty = y / 16 #ika.Video.DrawPixel(x - ika.Map.xwin, y - ika.Map.ywin, # color.white) #ika.Video.DrawRect(tx * 16 - ika.Map.xwin, ty * 16 - ika.Map.ywin, # tx * 16 + 16 - ika.Map.xwin, # ty * 16 + 16 - ika.Map.ywin, # ika.RGB(255, 0, 0, 128), True) #font.Print(240, 40, str(self.player.right_wall)) #main engine processing def tick(self): self.UpdateTerrain() for thing in self.background_things: try: thing.update() except AttributeError: pass for thing in self.foreground_things: try: thing.update() except AttributeError: pass for entity in self.add_list: self.entities.append(entity) self.add_list = [] for effect in self.addeffect_list: self.effects.append(effect) self.addeffect_list = [] for entity in self.entities: if entity.active: entity.update() for effect in self.effects: if effect.active: effect.update() for entity in self.kill_list: self.entities.remove(entity) self.kill_list = [] for effect in self.killeffect_list: self.effects.remove(effect) self.killeffect_list = [] for f in self.fields: if f.test(self.player) and not f.runnable: f.fire() mlist = [] for m in self.messages: m.duration -= 1 if m.duration <= 0: mlist.append(m) for m in mlist: self.messages.remove(m) self.ticks += 1 def map_switch(self, x, y, m, direction=0, fadeout=True, fadein=True, scroll=False): # Update the current map. self.curmap = m m = 'maps/%s' % m if fadeout: self.FadeOut(16) video.clear() # Destroy entities. for e in self.entities[:]: if e is not self.player: e._destroy() for e in self.effects[:]: e._destroy() self.background_things = [] self.foreground_things = [] self.player.x = x self.player.y = y ika.Map.Switch(m) self.automap.update_room() self.camera.reset_borders() self.camera.update() self.player.layer = ika.Map.FindLayerByName('Walls') self.player.sprite.layer = self.player.layer moduleName = m[:m.rfind('.')].replace('/', '.') mapModule = __import__(moduleName, globals(), locals(), ['']) self.readZones(mapModule) self.GetLayers() #if True: #check for flag for lighting... eventually.. # self.foreground_things.append(fog.Darkness()) video.clear() if fadein: self.FadeIn(16) def GameOver(self): t = ika.GetTime() while True: self.draw() a = min(100, ika.GetTime() - t) if a == 100: print >> fonts.big.center(), 'G A M E O V E R' video.clear(ika.RGB(10, 10, 10, a)) ika.Video.ShowPage() ika.Input.Update() if controls.confirm.Pressed() or \ controls.cancel.Pressed(): break t = ika.GetTime() while True: self.draw() a = min(255, ika.GetTime() - t + 100) video.clear(ika.RGB(10, 10, 10, a)) ika.Video.ShowPage() ika.Input.Update() if a == 255: break ika.Exit('') def update_time(self): while self.ticks >= 100: self.ticks -= 100 self.seconds += 1 while self.seconds >= 60: self.seconds -= 60 self.minutes += 1 while self.minutes >= 60: self.minutes -= 60 self.hours += 1 self.time = '%01d:%02d:%02d' % (self.hours, self.minutes, self.seconds) def UpdateTerrain(self): #Updates terrain layer. For water effects, currently. should be part of Tabby herself... for l in self.terrain_layers: name, layer = l #going in if ika.Map.GetTile(int(self.player.x+1) / 16, int(self.player.y + 31) / 16, layer): if self.player.cur_terrain == None: self.AddEntity(Splash(int(self.player.x - 12), int(self.player.y), name.lower(), layer)) self.player.cur_terrain = name #globals()[name + "Terrain"](self, self.player) else: #jumping out if self.player.cur_terrain: #should include regular entities too... self.AddEntity(Splash(int(self.player.x - 12), int(self.player.y), name.lower(), layer)) self.player.cur_terrain = None #def UpdateTerrain(self): # # if self.cur_terrain: # name, l = self.cur_terrain # # #jumping out # if ika.Map.GetTile(0, int(self.player.y + 31) / 16, layer): # if self.player.cur_terrain == None: # self.AddEntity(Splash(self.player.x, self.player.y, name.lower(), layer=l )) # self.player.cur_terrain = name # # #globals()[name + "Terrain"](self, self.player) # else: #going in # if self.player.cur_terrain: #should include regular entities too... # self.AddEntity(Splash(self.player.x+self.player.vx, self.player.y, name.lower())) # self.player.cur_terrain = None def text(self, txt): #ooold code... done = 0 state = 0 h = 0 arrow = ika.Image('%s/arrow.png' % config.image_path) lines = wrap(txt, 360, fonts.big) scrolling = 1 scroll = [0] * len(lines) current = 0 offset = 0 t = ika.GetTime() while not done: #ika.Map.Render() self.draw() while t == ika.GetTime(): pass for i in range(ika.GetTime() - t): for entity in self.entities: entity.update() if state == 0: h += 2 if state == 1 and scrolling == 1: scroll[current + offset] += 1 if state == 2: h -= 2 t = ika.GetTime() if state == 0: if h >= 40: h = 40 state = 1 self.window.resize(h * 8, h) else: self.window.resize(h * 8, h) self.window.draw(168 - h * 4, 200 - h / 2) if state == 1: self.window.draw(8, 180) for i in range(len(lines[offset:])): print >> fonts.big(20, 190 + 12 * i), lines[i + offset][:scroll[i + offset]] if scroll[current + offset] >= \ len(lines[current + offset]): if current + offset < len(lines) - 1: current += 1 else: scrolling = 0 if current == 7: scrolling = 0 # Put blinking arrow or whatever here. if ika.GetTime() % 50 < 40: ika.Video.Blit(arrow, 192, 280 + ika.GetTime() % 50 / 10) if state == 2: if h <= 0: done = True else: self.window.resize(h * 8, h) self.window.draw(168 - h * 4, 200 - h / 2) print >> fonts.one(0, 0), 'lines:', '%s' ika.Video.ShowPage() ika.Input.Update() if ika.Input.keyboard['RETURN'].Pressed() and state == 1 and \ scrolling == 0: ika.Input.Unpress() if current + offset < len(lines) - 1: scrolling = 1 offset += 7 current = 0 else: state = 2 def addField(self, field): assert field not in self.fields self.fields.append(field) def destroyField(self, field): self.fields.remove(field) def readZones(self, mapModule): """Read all the zones on the map, and create fields.""" self.fields = [] for layer in range(ika.Map.layercount): zones = ika.Map.GetZones(layer) for x, y, w, h, script in zones: self.addField(Field((x, y, w, h), layer, mapModule.__dict__[script], str(script))) def FadeOut(self, time=50): video.fade_out(time, draw=self.draw, draw_after=self.hud.draw) def FadeIn(self, time=50): video.fade_in(time, draw=self.draw, draw_after=self.hud.draw) def SavePrompt(self, heal=True): if heal: self.player.dhp = self.player.maxhp self.player.dmp = self.player.maxmp selected = 0 while not controls.confirm.Pressed(): self.player.update() self.draw() Window(150, 0).draw(52, 60) print >> fonts.one(68, 80), 'Do you want to save?' x = 100 y = 98 for i, option in enumerate(['Yes', 'No']): f = [fonts.five, fonts.three][i == selected] print >> f(x, y), option x += 100 self.hud.draw() #ika.Video.DrawRect(80 + 110 * selected, 92, 120 + 110 * selected, # 108, ika.RGB(128, 192, 128)) ika.Video.ShowPage() ika.Input.Update() if controls.left.Pressed(): sound.play('Menu') selected -= 1 if selected < 0: selected = 1 if controls.right.Pressed(): sound.play('Menu') selected += 1 if selected > 1: selected = 0 #for c in controls.control_list: # c.Release() if selected == 0: self.Save() return True return False #saving incomplete, does not save map data def Save(self, filename='%s/savegame.save' % config.save_path): flagnode = parser.Node('flags') for key, value in self.flags.iteritems(): flagnode.append(parser.Node(key).append(value)) #mapnode = parser.Node('amap') #for n in self.automap.amap: # mapnode.append(n) foo = (parser.Node('mannux-save') .append(parser.Node('version').append(1)) .append(parser.Node('map').append(self.curmap)) .append(parser.Node('hp').append(self.player.maxhp)) #always save with full health .append(parser.Node('maxhp').append(self.player.maxhp)) .append(parser.Node('mp').append(self.player.maxmp)) .append(parser.Node('maxmp').append(self.player.maxmp)) .append(flagnode) .append(parser.Node('amap1').append(str(self.automap.amap))) ) print >> open(filename, 'wt'), foo self.messages.append(Message("Game saved", 300)) #for some reason misses some flags.. def load(self, filename='%s/default.save' % config.save_path): self.loading = True d = parser.load(filename) self.curmap = d['mannux-save'].get('map') self.player.hp = int(d['mannux-save'].get('hp')) self.player.maxhp = int(d['mannux-save'].get('maxhp')) self.player.mp = int(d['mannux-save'].get('mp')) self.player.maxmp = int(d['mannux-save'].get('maxmp')) self.flags = d['mannux-save']['flags'].todict() a = d['mannux-save'].get('amap1') print 'testing: ' print d['mannux-save'].get('map') print d['mannux-save'].get('amap1') #print a #if 'amap1' in d['mannux-save']: # print 'yes!' # a = d['mannux-save']['amap1'] # b = '' # for c in a: # b+=str(c) # print "Load test:" # # test = eval(b) # self.automap.amap = test #else: # print 'wtf!' #b = d['mannux-save']['amap'] #self.automap.amap = [] #i=0 #for y in range(50): #need to change so it's not just 50x50... # for x in range(50): #self.automap.amap.append(a[i]) #for i in a: # ika.Log('i: '+str(i)) # i+=1 #for i in d['mannux-save']['amap']: # self.automap.amap.append(i) self.hud.resize() #print self.curmap self.map_switch(0, 0, self.curmap, fadeout=False) self.loading = False def AddEntity(self, ent): self.add_list.append(ent) def RemoveEntity(self, ent): self.kill_list.append(ent) def AddEffect(self, effect): self.addeffect_list.append(effect) def RemoveEffect(self, effect): self.killeffect_list.append(effect)