Beispiel #1
0
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()