def enter_chapter(screen, chapter, hero): map_setting = util.load_map_setting(chapter) camera = Camera(screen, map_size=map_setting["size"]) game_map = GameMap(chapter, map_setting) static_objects = StaticObjectGroup() allsprites = GameSpritesGroup() enemies = EnemyGroup(map_setting["monsters"], allsprites, hero, static_objects, game_map) game_world = GameWorld() # load hero hero.place(map_setting["hero"]["pos"], map_setting["hero"]["direction"]) hero.activate(allsprites, enemies, static_objects, game_map) # load ambush game_world.init_ambush_list(map_setting.get("ambush_list", [])) # load static objects chapter_static_objects = map_setting["static_objects"] for static_obj_init in chapter_static_objects: t, p = static_obj_init["id"], static_obj_init["pos"] static_obj = StaticObject(sfg.STATIC_OBJECT_SETTING_MAPPING[t], p) static_objects.add(static_obj) allsprites.add(hero) allsprites.add(enemies) game_world.batch_add(allsprites) game_world.batch_add(static_objects) game_director = GameDirector(chapter, hero, enemies) if COMMAND_DEBUG_MODE: # skip the init status in command debug mode game_director.status = cfg.GameStatus.IN_PROGRESS clock = pygame.time.Clock() running = True battle_keys= {} for k in sfg.UserKey.ONE_PRESSED_KEYS: battle_keys[k] = {"pressed": False, "cd": 0, "full_cd": sfg.UserKey.ONE_PRESSED_KEY_CD} for k in sfg.UserKey.CONTINUE_PRESSED_KEYS: battle_keys[k] = {"pressed": False} battle_keys["last_direct_key_up"] = {"key": None, "time": None} while running: for event in pygame.event.get(): if event.type == pygame.QUIT: return {"status": cfg.GameControl.QUIT} if event.type == KEYDOWN: if event.key == sfg.UserKey.PAUSE: if game_director.status == cfg.GameStatus.IN_PROGRESS: game_director.status = cfg.GameStatus.PAUSE bg_box.pause() game_director.menu.index = 0 elif game_director.status == cfg.GameStatus.PAUSE: game_director.status = cfg.GameStatus.IN_PROGRESS bg_box.unpause() if event.key == sfg.UserKey.OK: if game_director.status == cfg.GameStatus.HERO_WIN: util.save_chapter_win_screen_image(chapter, camera.screen) dat = util.load_auto_save() or {} dat["current_chapter"] = chapter dat["level"] = hero.level dat["exp"] = hero.exp util.auto_save(dat) return {"status": cfg.GameControl.NEXT} elif game_director.status == cfg.GameStatus.HERO_LOSE: return {"status": cfg.GameControl.AGAIN, "chapter": chapter} elif game_director.status == cfg.GameStatus.PAUSE: mark = game_director.menu.get_current_mark() if mark == "continue": game_director.status = cfg.GameStatus.IN_PROGRESS bg_box.unpause() elif mark == "main": return {"status": cfg.GameControl.MAIN} elif mark == "quit": return {"status": cfg.GameControl.QUIT} if event.key in sfg.UserKey.ONE_PRESSED_KEYS and battle_keys[event.key]["cd"] == 0: battle_keys[event.key]["pressed"] = True battle_keys[event.key]["cd"] = battle_keys[event.key]["full_cd"] if game_director.status == cfg.GameStatus.PAUSE: game_director.menu.update(event.key) if event.type == KEYUP: if event.key in sfg.UserKey.DIRECTION_KEYS: battle_keys["last_direct_key_up"]["key"] = event.key battle_keys["last_direct_key_up"]["time"] = time() pressed_keys = pygame.key.get_pressed() for k in sfg.UserKey.CONTINUE_PRESSED_KEYS: battle_keys[k]["pressed"] = pressed_keys[k] hero.event_handle(battle_keys, external_event=game_director.status) for enemy in enemies: if enemy_in_one_screen(hero, enemy): enemy.event_handle(external_event=game_director.status) time_passed = clock.tick(sfg.FPS) passed_seconds = time_passed * 0.001 for k in sfg.UserKey.ONE_PRESSED_KEYS: battle_keys[k]["pressed"] = False battle_keys[k]["cd"] = max(battle_keys[k]["cd"] - passed_seconds, 0) for k in sfg.UserKey.CONTINUE_PRESSED_KEYS: battle_keys[k]["pressed"] = False # update hero, enemies, game_director in sequence hero.update(passed_seconds, external_event=game_director.status) for enemy in enemies: if enemy_in_one_screen(hero, enemy): enemy.update(passed_seconds, external_event=game_director.status) game_world.update(passed_seconds, game_director.status) game_world.update_ambush(passed_seconds, game_director, hero, allsprites, enemies, static_objects, game_map) game_director.update(passed_seconds) camera.screen_follow(hero.pos) # 3 layers from bottom to top: floor -> sprites in the playground -> game info(player hp, ep etc) game_map.draw(camera) game_world.draw(camera) game_director.draw(camera) if COMMAND_DEBUG_MODE or sfg.DEBUG_MODE: debug_tools.run_debug_by_option_list(COMMAND_DEBUG_OPTIONS, camera, game_world, game_map, clock) if COMMAND_DEBUG_OPTIONS["god"]: hero.hp = hero.setting.HP hero.mp = hero.setting.MP hero.sp = hero.setting.SP hero.hp_status = hero.cal_sprite_status(hero.hp, hero.setting.HP) hero.attacker.refresh_skill() pygame.display.update()
def enter_dead_mode(screen, hero): # pre_loading sprite for mnstr_id in sfg.COMMON_MONSTER_ID_LIST: mnstr_sfg = sfg.SPRITE_SETTING_MAPPING[mnstr_id] mnstr = ENEMY_CLASS_MAPPING[mnstr_id](mnstr_sfg, (0, 0), cfg.Direction.SOUTH) map_setting = util.load_map_setting(sfg.DeadMode.MAP_CHAPTER) camera = Camera(screen, map_size=map_setting["size"]) game_map = GameMap(sfg.DeadMode.MAP_CHAPTER, map_setting) static_objects = StaticObjectGroup() allsprites = GameSpritesGroup() enemies = EnemyGroup(map_setting["monsters"], allsprites, hero, static_objects, game_map) game_world = GameWorld() # load hero hero.place(map_setting["hero"]["pos"], map_setting["hero"]["direction"]) hero.activate(allsprites, enemies, static_objects, game_map) # load static objects chapter_static_objects = map_setting["static_objects"] for static_obj_init in chapter_static_objects: t, p = static_obj_init["id"], static_obj_init["pos"] static_obj = StaticObject(sfg.STATIC_OBJECT_SETTING_MAPPING[t], p) static_objects.add(static_obj) allsprites.add(hero) allsprites.add(enemies) game_world.batch_add(allsprites) game_world.batch_add(static_objects) game_director = GameDirector(sfg.DeadMode.MAP_CHAPTER, hero, enemies) add_enemy_timer = util.Timer(sfg.DeadMode.ADD_ENEMY_TIME_DELTA) enemy_add_num = sfg.DeadMode.ENEMY_ADD_INIT_NUM enemy_add_delta = sfg.DeadMode.ENEMY_ADD_DELTA current_round = 1 clock = pygame.time.Clock() running = True battle_keys= {} for k in sfg.UserKey.ONE_PRESSED_KEYS: battle_keys[k] = {"pressed": False, "cd": 0, "full_cd": sfg.UserKey.ONE_PRESSED_KEY_CD} for k in sfg.UserKey.CONTINUE_PRESSED_KEYS: battle_keys[k] = {"pressed": False} battle_keys["last_direct_key_up"] = {"key": None, "time": None} while running: for event in pygame.event.get(): if event.type == pygame.QUIT: return {"status": cfg.GameControl.QUIT} if event.type == KEYDOWN: if event.key == sfg.UserKey.PAUSE: if game_director.status == cfg.GameStatus.IN_PROGRESS: game_director.status = cfg.GameStatus.PAUSE bg_box.pause() game_director.menu.index = 0 elif game_director.status == cfg.GameStatus.PAUSE: game_director.status = cfg.GameStatus.IN_PROGRESS bg_box.unpause() if event.key == sfg.UserKey.OK: if game_director.status == cfg.GameStatus.HERO_WIN: pass elif game_director.status == cfg.GameStatus.HERO_LOSE: return {"status": cfg.GameControl.DEAD_MODE} elif game_director.status == cfg.GameStatus.PAUSE: mark = game_director.menu.get_current_mark() if mark == "continue": game_director.status = cfg.GameStatus.IN_PROGRESS bg_box.unpause() elif mark == "main": return {"status": cfg.GameControl.MAIN} elif mark == "quit": return {"status": cfg.GameControl.QUIT} if event.key in sfg.UserKey.ONE_PRESSED_KEYS and battle_keys[event.key]["cd"] == 0: battle_keys[event.key]["pressed"] = True battle_keys[event.key]["cd"] = battle_keys[event.key]["full_cd"] if game_director.status == cfg.GameStatus.PAUSE: game_director.menu.update(event.key) if event.type == KEYUP: if event.key in sfg.UserKey.DIRECTION_KEYS: battle_keys["last_direct_key_up"]["key"] = event.key battle_keys["last_direct_key_up"]["time"] = time() pressed_keys = pygame.key.get_pressed() for k in sfg.UserKey.CONTINUE_PRESSED_KEYS: battle_keys[k]["pressed"] = pressed_keys[k] hero.event_handle(battle_keys, external_event=game_director.status) for enemy in enemies: if enemy_in_one_screen(hero, enemy): enemy.event_handle(external_event=game_director.status) time_passed = clock.tick(sfg.FPS) passed_seconds = time_passed * 0.001 for k in sfg.UserKey.ONE_PRESSED_KEYS: battle_keys[k]["pressed"] = False battle_keys[k]["cd"] = max(battle_keys[k]["cd"] - passed_seconds, 0) for k in sfg.UserKey.CONTINUE_PRESSED_KEYS: battle_keys[k]["pressed"] = False # update hero, enemies, game_director in sequence hero.update(passed_seconds, external_event=game_director.status) for enemy in enemies: if enemy_in_one_screen(hero, enemy): enemy.update(passed_seconds, external_event=game_director.status) game_world.update(passed_seconds, game_director.status) game_director.update(passed_seconds) # judge enenmy nums if len(enemies) == 0: if add_enemy_timer.is_begin(): if add_enemy_timer.exceed(): add_enemy_timer.clear() hero.set_emotion(cfg.SpriteEmotion.ALERT) for _a_useless_var in xrange(enemy_add_num): monster_id = choice(sfg.COMMON_MONSTER_ID_LIST) monster_setting = sfg.SPRITE_SETTING_MAPPING[monster_id] monster = ENEMY_CLASS_MAPPING[monster_id](monster_setting, (randint(int(game_map.size[0] * 0.3), int(game_map.size[0] * 0.7)), randint(int(game_map.size[1] * 0.3), int(game_map.size[1] * 0.7))), choice(cfg.Direction.ALL)) monster_ai_setting = ai.AI_MAPPING[monster_id] monster.activate(monster_ai_setting, allsprites, hero, static_objects, game_map) monster.brain.set_target(hero) monster.brain.set_active_state(cfg.SpriteState.CHASE) enemies.add(monster) game_world.add_object(monster) allsprites.add(enemies) enemy_add_num = min(enemy_add_num + enemy_add_delta, sfg.DeadMode.ENEMY_ADD_MAX) else: add_enemy_timer.begin() current_round += 1 new_foods = [] for _is_a_useless_var in xrange(3): food = StaticObject(sfg.STATIC_OBJECT_SETTING_MAPPING[ choice(sfg.FOOD_ID_LIST)], (randint(int(game_map.size[0] * 0.2), int(game_map.size[0] * 0.5)), randint(int(game_map.size[1] * 0.3), int(game_map.size[1] * 0.6))) ) new_foods.append(food) static_objects.add(food) game_world.batch_add(new_foods) camera.screen_follow(hero.pos) # 3 layers from bottom to top: floor -> sprites in the playground -> game info(player hp, ep etc) game_map.draw(camera) game_world.draw(camera) game_director.draw(camera) # say how many enemies left enemy_left_info = sfg.Font.MSYH_32.render(u"Ê£Óà¹ÖÎïÊý£º%s" % len(enemies), True, pygame.Color("white")) screen.blit(enemy_left_info, sfg.DeadMode.ENEMY_LEFT_INFO_BLIT_POS) # say current round current_round_info = sfg.Font.MSYH_32.render(u"µÚ%s²¨" % current_round, True, pygame.Color("white")) screen.blit(current_round_info, sfg.DeadMode.CURRENT_ROUND_INFO_BLIT_POS) if len(enemies) == 0 and add_enemy_timer.is_begin() and (not add_enemy_timer.exceed()): game_director.draw_count_down_number(camera, add_enemy_timer, sfg.DeadMode.ADD_ENEMY_TIME_DELTA) if COMMAND_DEBUG_MODE or sfg.DEBUG_MODE: debug_tools.run_debug_by_option_list(COMMAND_DEBUG_OPTIONS, camera, game_world, game_map, clock) if COMMAND_DEBUG_OPTIONS["god"]: hero.hp = hero.setting.HP hero.mp = hero.setting.MP hero.sp = hero.setting.SP hero.hp_status = hero.cal_sprite_status(hero.hp, hero.setting.HP) hero.attacker.refresh_skill() pygame.display.update()
def run(chapter): clock = pygame.time.Clock() map_setting = util.load_map_setting(chapter) screen = pygame.display.set_mode(sfg.Screen.SIZE) pygame.display.set_caption("Renne Map Editor") camera = Camera(screen, map_size=map_setting["size"]) game_world = GameWorld() game_map = GameMap(chapter, map_setting) # load hero hero = Renne(sfg.Renne, map_setting["hero"]["pos"], map_setting["hero"]["direction"]) game_world.add_object(hero) # load monsters monster_init_list = map_setting.get("monsters", []) for monster_init in monster_init_list: monster_id, pos, direct = monster_init["id"], monster_init["pos"], monster_init["direction"] monster = Enemy(sfg.SPRITE_SETTING_MAPPING[monster_id], pos, direct) game_world.add_object(monster) # load static objects chapter_static_objects = map_setting.get("static_objects", []) for static_obj_init in chapter_static_objects: t, p = static_obj_init["id"], static_obj_init["pos"] static_obj = StaticObject(sfg.STATIC_OBJECT_SETTING_MAPPING[t], p) game_world.add_object(static_obj) # hack an attrbute ambush into game_world for easy saving game_world.ambush_list = [] # some monsters is in ambush list ambush_init_list = map_setting.get("ambush_list", []) for ambush_init in ambush_init_list: ambush = Ambush(ambush_init["ambush"]["pos"], sfg.Ambush.SURROUND_AREA_WIDTH, sfg.Ambush.ENTER_AREA_WIDTH, ambush_init["ambush"]["type"]) for monster_init in ambush_init["monsters"]: monster_id, pos, direct = monster_init["id"], monster_init["pos"], monster_init["direction"] monster = Enemy(sfg.SPRITE_SETTING_MAPPING[monster_id], pos, direct) game_world.add_object(monster) ambush.add(monster) game_world.ambush_list.append(ambush) running = True key_vec = Vector2() selected_object = None while running: mouse_pos = pygame.mouse.get_pos() map_pos_for_mouse = get_map_pos_for_mouse(camera.rect, mouse_pos) for event in pygame.event.get(): if event.type == pygame.QUIT: running = False if event.type == KEYDOWN: if event.key == K_ESCAPE: if object_can_be_shift(selected_object) \ and put_down_selected_object(selected_object, game_world): selected_object = None elif isinstance(selected_object, Ambush) \ and put_down_ambush(selected_object, game_world): selected_object = None if event.key == sfg.MapEditor.KEY_STATIC_OBJECT: # static object selected_object = selected_object_shift(selected_object, cfg.GameObject.TYPE_STATIC) elif event.key == sfg.MapEditor.KEY_ENEMY: # enemy selected_object = selected_object_shift(selected_object, cfg.GameObject.TYPE_DYNAMIC) elif event.key == sfg.MapEditor.KEY_AMBUSH: # ambush selected_object = mouse_ambush_toggle(selected_object) if event.key == sfg.MapEditor.KEY_ERASE_SELECTED_OBJECT: selected_object = None if event.key == sfg.MapEditor.KEY_TURN_DIRECTION: if isinstance(selected_object, GameSprite): selected_object = turn_sprite_direction(selected_object) key_mods = pygame.key.get_mods() if key_mods & KMOD_CTRL and event.key == sfg.MapEditor.KEY_CTRL_SAVE: # ctrl+s to save map setting change_map_setting(map_setting, game_world, game_map) util.save_map_setting(chapter, map_setting) print "save chapter %s map setting" % chapter if key_mods & KMOD_ALT: # debug draw switch if event.key == sfg.MapEditor.KEY_ALT_SWITCH_POS: DEBUG_DRAW["pos"] = not DEBUG_DRAW["pos"] elif event.key == sfg.MapEditor.KEY_ALT_SWITCH_AREA: DEBUG_DRAW["area"] = not DEBUG_DRAW["area"] elif event.key == sfg.MapEditor.KEY_ALT_SWITCH_WAYPOINT: DEBUG_DRAW["waypoints"] = not DEBUG_DRAW["waypoints"] elif event.key == sfg.MapEditor.KEY_ALT_SWITCH_BLOCK_POINT: DEBUG_DRAW["block_points"] = not DEBUG_DRAW["block_points"] elif event.type == MOUSEBUTTONDOWN: if event.button == 1: # left click if selected_object is None: # pick up "this" unit if the mouse is over it selected_object = select_unit(map_pos_for_mouse, game_world) else: # put down the current selected unit if no "collision" happen if (isinstance(selected_object, GameSprite) or \ isinstance(selected_object, StaticObject)) \ and put_down_selected_object(selected_object, game_world): if pygame.key.get_mods() & KMOD_CTRL: selected_object = create_new_instance(selected_object) else: selected_object = None elif isinstance(selected_object, Ambush) \ and put_down_ambush(selected_object, game_world): selected_object = None change_map_setting(map_setting, game_world, game_map) pressed_keys = pygame.key.get_pressed() key_vec.x = key_vec.y = 0.0 if pressed_keys[K_LEFT]: key_vec.x -= 1.0 if pressed_keys[K_RIGHT]: key_vec.x += 1.0 if pressed_keys[K_UP]: key_vec.y -= 1.0 if pressed_keys[K_DOWN]: key_vec.y += 1.0 time_passed = clock.tick(sfg.FPS) passed_seconds = time_passed * 0.001 camera.screen_move(key_vec, sfg.MapEditor.SCREEN_MOVE_SPEED, passed_seconds) if selected_object is not None: if isinstance(selected_object, GameSprite) \ or isinstance(selected_object, StaticObject): set_selected_object_follow_mouse(map_pos_for_mouse, selected_object) elif isinstance(selected_object, Ambush): set_ambush_follow_mouse(map_pos_for_mouse, selected_object) game_map.draw(camera) # draw ambush before all objects, because they are "close" to the floor for ambush in game_world.ambush_list: ambush.draw(camera) for sp in sorted(game_world.yield_all_objects(), key=lambda sp: sp.pos.y): if sp.setting.GAME_OBJECT_TYPE == cfg.GameObject.TYPE_DYNAMIC: sp.animation.adjust_rect() # select current image for corresponding direction sp.animation.image = sp.animation.sprite_image_contoller.get_surface( cfg.SpriteAction.STAND)[sp.direction] sp.animation.draw_shadow(camera) sp.draw(camera) if selected_object is not None: if isinstance(selected_object, GameSprite) \ or isinstance(selected_object, StaticObject): # render selected_object selected_object_name = sfg.Font.ARIAL_32.render( selected_object.setting.NAME, True, pygame.Color("black")) camera.screen.blit(selected_object_name, (5, 5)) if isinstance(selected_object, GameSprite): selected_object.animation.draw_shadow(camera) selected_object.animation.image = selected_object.animation.sprite_image_contoller.get_surface( cfg.SpriteAction.STAND)[selected_object.direction] selected_object.draw(camera) draw_block_points_for_selected_object(camera, selected_object) elif isinstance(selected_object, Ambush): camera.screen.blit(sfg.Font.ARIAL_32.render("Ambush", True, pygame.Color("black")), (5, 5)) selected_object.draw(camera) # debug drawings for sp in game_world.yield_all_objects(): if DEBUG_DRAW["pos"]: debug_tools.draw_pos(camera, sp) if DEBUG_DRAW["area"]: debug_tools.draw_area(camera, sp) if DEBUG_DRAW["waypoints"]: debug_tools.draw_waypoins(camera, game_map.waypoints) if DEBUG_DRAW["block_points"]: debug_tools.draw_block_points(camera, game_map.block_points) pygame.display.update()