Exemple #1
0
class Game:
    
    def __init__(self, world, datadir, configdir):
        self.world = world
        self.datadir = datadir
        self.configdir = configdir
        self.enemies = []

        self.stage = Stage(self)
        self.sprites = Group(self.stage)
        self.screen = world.screen

        # Visor de energia para el enemigo
        self._create_player()
        self.energy = Energy(10, 10, 100, 10)
        self.energy.set_model(self.player.id)

        self.stage.player = self.player
        self.stage.load_level(1)

        if VISIBLE_DEBUG:
            # Visor de rendimiento
            self.text = Text(world.font, world.fps, "FPS: %d")

    def _create_player(self):
        control = Control(0, self.configdir)
        self.player = Player(self, control, self.sprites, self.datadir)
        shadow_player = Shadow(self.player, self.datadir)
        self.sprites.add([self.player, shadow_player])
        
    def update(self):

        self.stage.update()
        self.sprites.update()
        self.energy.update()

        if VISIBLE_DEBUG:
            self.text.update()

        if DEBUG:
            b1, b2, b3 = pygame.mouse.get_pressed()

            if b1:
                self.stage.do_camera_effect()
            elif b2:
                self.stage.do_camera_effect(10)
            elif b3:
                self.world.fps.slow()

    def draw(self):
        self.stage.draw(self.screen)
        self.sprites.draw(self.screen)
        self.screen.blit(self.energy.image, self.energy.rect)

        if VISIBLE_DEBUG:
            self.screen.blit(self.text.image, self.text.rect)

        pygame.display.flip()
Exemple #2
0
    def _set_value(self, record, value, default=False):
        from group import Group

        if not value or (len(value) and isinstance(value[0], (int, long))):
            mode = 'list ids'
        else:
            mode = 'list values'

        group = record.value.get(self.name)
        fields = {}
        if group is not None:
            fields = group.fields.copy()
            # Unconnect to prevent infinite loop
            group.signal_unconnect(group)
            group.destroy()
        elif record.model_name == self.attrs['relation']:
            fields = record.group.fields
        if fields:
            fields = dict((fname, field.attrs)
                for fname, field in fields.iteritems())
        if mode == 'list values' and len(value):
            context = self.context_get(record)
            field_names = set(f for v in value for f in v if f not in fields)
            if field_names:
                try:
                    fields.update(RPCExecute('model', self.attrs['relation'],
                            'fields_get', list(field_names),
                            main_iteration=False, context=context))
                except RPCException:
                    return

        parent_name = self.attrs.get('relation_field', '')
        group = Group(self.attrs['relation'], fields,
            parent=record, parent_name=parent_name,
            child_name=self.name,
            context=self.context,
            parent_datetime_field=self.attrs.get('datetime_field'))
        record.value[self.name] = group
        if mode == 'list ids':
            group.load(value)
        else:
            for vals in value:
                new_record = record.value[self.name].new(default=False)
                if default:
                    new_record.set_default(vals)
                    group.add(new_record)
                else:
                    new_record.id *= -1  # Don't consider record as unsaved
                    new_record.set(vals)
                    group.append(new_record)
        group.signal_connect(group, 'group-changed', self._group_changed)
        group.signal_connect(group, 'group-list-changed',
            self._group_list_changed)
        group.signal_connect(group, 'group-cleared', self._group_cleared)
        group.signal_connect(group, 'record-modified', self._record_modified)
        return group
    def set_default(self, record, value, modified=False):
        from group import Group

        # value is a list of id
        if value and len(value) and isinstance(value[0], (int, long)):
            return self.set(record, value, modified=modified)

        group = record.value.get(self.name)
        fields = {}
        if group is not None:
            fields = group.fields.copy()
            # Unconnect to prevent infinite loop
            group.signal_unconnect(group)
            group.destroy()
        elif record.model_name == self.attrs['relation']:
            fields = record.group.fields
        if fields:
            fields = dict((fname, field.attrs)
                for fname, field in fields.iteritems())
        if value and len(value):
            context = self.context_get(record)
            field_names = []
            for val in value:
                for fieldname in val.keys():
                    if (fieldname not in field_names
                            and fieldname not in fields):
                        field_names.append(fieldname)
            if field_names:
                try:
                    fields.update(RPCExecute('model', self.attrs['relation'],
                            'fields_get', field_names, context=context))
                except RPCException:
                    return False

        parent_name = self.attrs.get('relation_field', '')
        group = Group(self.attrs['relation'], fields,
                parent=record, parent_name=parent_name, child_name=self.name,
                context=self.context,
                parent_datetime_field=self.attrs.get('datetime_field'))
        if record.value.get(self.name):
            group.record_deleted.extend(x for x in record.value[self.name]
                if x.id >= 0)
            group.record_deleted.extend(record.value[self.name].record_deleted)
            group.record_removed.extend(record.value[self.name].record_removed)
        record.value[self.name] = group
        for vals in (value or []):
            new_record = record.value[self.name].new(default=False)
            new_record.set_default(vals, modified=modified)
            group.add(new_record)
        group.signal_connect(group, 'group-changed', self._group_changed)
        group.signal_connect(group, 'group-list-changed',
            self._group_list_changed)
        group.signal_connect(group, 'group-cleared', self._group_cleared)
        group.signal_connect(group, 'record-modified', self._record_modified)
        return True
Exemple #4
0
 def peng(self, player_index, piece):
     first = self.players[player_index].find(piece)
     self.players[player_index].discard(first)
     second = self.players[player_index].find(piece)
     self.players[player_index].discard(second)
     t = Group()
     t.add(piece)
     t.add(piece)
     t.add(piece)
     t.showGroup()
     self.players[player_index].hand.append(t)
    def parse(filename):
        f = codecs.open(filename, 'r', 'utf8')
        lines = f.readlines()
        f.close()

        groups = []
        current_group = Group()
        for i in range(0, len(lines)):
            i += 1
            if i >= len(lines):
                groups.append(current_group)
                break
            if len(lines[i].strip()) == 0:
                i += 1
                groups.append(current_group)
                current_group = Group()
            else:
                current_group.add(AllDupParser.__parse_pubfile(lines[i]))
        return groups
Exemple #6
0
 def _start_battle_hand_animation(self):
     """手を出すアニメーションを開始
     """
     # self.actor_state_group.empty()
     total_frame = 60
     group = Group()
     for actor in [self.actor1, self.actor2]:
         sprite = self.hand_sprites[actor][actor.hand]
         group.add(sprite)
         sprite.image.set_alpha(0)
         props = make_transform_properties(0,
                                           0,
                                           0,
                                           0,
                                           0,
                                           1,
                                           total_frame=int(total_frame *
                                                           0.2))
         self.transform_manager.add_transformer(sprite, props)
     self.timer_group.add_timer_sprite(group,
                                       timer=total_frame,
                                       on_delete_fnc=self._judge,
                                       debug_label="手を表示する")
Exemple #7
0
pygame.init()
pygame.mixer.init()


screen = pygame.display.set_mode((SCREENWIDTH, SCREENHEIGHT))
pygame.display.set_caption("Client")
background = pygame.image.load("../lib/image/map.png")
background = pygame.transform.scale(background, (SCREENWIDTH, SCREENHEIGHT))

all_sprites  = Group()
gun_sprites  = Group()
clip_sprites = Group()

guns = gun.createGuns(number=3)
for i in range(3):
    gun_sprites.add(guns[i])
    all_sprites.add(guns[i])


def main():
    run = True
    n = Network()
    me = n.getP()
    all_sprites.add(me)

    clock = pygame.time.Clock()

    while run:
        clock.tick(60)

        for event in pygame.event.get():
class PlayerStockIcon(Group):
    def __init__(self, left: int, top: int, game_player, image_height: int=50):
        super().__init__()

        self.game_player = game_player

        surface = game_player.character.face_image
        name = game_player.player.name
        stock = game_player.stock

        # キャラ画像
        image_width = image_height
        rect = Rect(left, top, image_width, image_height)
        image = surface_fit_to_rect(surface, rect)
        self.character_sprite = SimpleSprite(rect, image)
        self.add(self.character_sprite)

        # ストックの丸
        self.stock = stock
        self.stock_sprites = [Group() for i in range(stock)]
        x, y = self.character_sprite.rect.bottomright
        stock_radius = int(0.05 * image_height)
        left, top = x, y - stock_radius * 2
        for i in range(stock):
            surface = Surface((stock_radius * 2, stock_radius * 2)).convert_alpha()
            surface.fill((125, 125, 125))
            surface.set_colorkey(surface.get_at((0, 0)))
            pygame.gfxdraw.filled_circle(surface, stock_radius, stock_radius, stock_radius-1, (255, 255, 255))
            stock_sprite = SimpleSprite(Rect(left, top, stock_radius * 2, stock_radius * 2), surface)
            self.stock_sprites[i].add(stock_sprite)
            print(self.stock_sprites[i])
            left += stock_radius * 2

        # プレイヤーネーム
        font_size = int(0.2 * image_height)
        font = pygame.font.Font(None, font_size)
        left, bottom = self.character_sprite.rect.bottomright
        bottom -= stock_radius * 2
        self.player_name_sprite = TextSprite(
            x=left,
            y=bottom,
            align="left",
            vertical_align="bottom",
            text=name,
            font=font,
            color=(255, 255, 255)
        )
        self.add(self.player_name_sprite)

        # プレイヤーネームのbg
        width = self.character_sprite.rect.w + max(stock_radius * 2 * stock, self.player_name_sprite.rect.w) + 10
        height = self.character_sprite.rect.h
        self.base_rect = Rect(*self.character_sprite.rect.topleft, width, height)
        rect = self.base_rect
        bg_image = Surface(rect.size).convert_alpha()
        bg_image.fill((0, 0, 0))
        bg_image.set_alpha(225)
        bg_sprite = SimpleSprite(rect, bg_image)
        self.bg_group = Group()
        self.bg_group.add(bg_sprite)
    
    def change_stock_delta(delta: int):
        self.stock += delta
    
    def draw(self, surface: Surface):
        self.bg_group.draw(surface)
        super().draw(surface)
        for i in range(self.game_player.stock):
            group = self.stock_sprites[i]
            # print(group, end=", ")
            group.draw(surface)
Exemple #9
0
 def possibleChiCombos(self, piece):
     num = piece.number
     suit = piece.suit
     temp = []
     if num - 1 >= 1 and num - 2 >= 1:
         t = Group()
         t.add(Piece(suit, num - 2))
         t.add(Piece(suit, num - 1))
         t.add(Piece(suit, num))
         temp.append(t)
     if num - 1 >= 1 and num + 1 <= 9:
         t = Group()
         t.add(Piece(suit, num - 1))
         t.add(Piece(suit, num))
         t.add(Piece(suit, num + 1))
         temp.append(t)
     if num + 1 <= 9 and num + 2 <= 9:
         t = Group()
         t.add(Piece(suit, num))
         t.add(Piece(suit, num + 1))
         t.add(Piece(suit, num + 2))
         temp.append(t)
     return temp
Exemple #10
0
class Server:
    """Chat server. Listens to requests from any IP on a specific port.
    Instance attributes:
    group - (instance of Group) group of the current chat members.
    accept_soc - the socket used to accept new connections.
    pending_que - queue of newly accepted connections.

    """

    BUFFER_SIZE = 1024
    MANAGER_NAMES = ["Alice", "Menny", "Reem"]  # these names automatically become managers
    COMMANDS = ["/help", "/quit", "/view-managers", "/tell", "/kick", "/promote", "/demote", "/mute", "/unmute"]
    COLORS = ["#aa0000", "#005500", "#00007f", "#aa007f", "#00557f", "#550000", "#b07500", "#00aa00"]

    def __init__(self):
        # Generate AES key to encrypt all communication with clients:
        self.aeskey = get_random_bytes(16)
        print(self.aeskey)
        self.curr_file_desc = 0
        self.group = Group()
        self.accept_soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.pending_que = queue.Queue()

    def start(self, port, ip='0.0.0.0'):
        self.accept_soc.bind((ip, port))
        self.accept_soc.listen(1)
        threading.Thread(target=self.accept_connections).start()
        while True:
            self.add_pending_member()
            self.do()
            time.sleep(0.05)

    def add_pending_member(self):
        try:
            conn = self.pending_que.get_nowait()
        except queue.Empty:  # no pending members to add
            return
        name = self.recv(conn, secure=False)
        time.sleep(0.05)
        pubkey = RSA.import_key(self.recv(conn, secure=False))
        if type(name) == str and name:
            name = name.strip()
            if name in self.group:
                cpp.send(conn, cpp.ServerMsg("Connection Refused: Name is already taken."))
                conn.close()
            else:
                enc_aeskey = PKCS1_OAEP.new(pubkey).encrypt(self.aeskey)
                cpp.send(conn, enc_aeskey)
                print(f"RECEIVED PUBKEY: {pubkey.export_key()}")
                color = choice(Server.COLORS)
                self.group.add(name, pubkey, conn, color, name in self.MANAGER_NAMES)
                self.broadcast(cpp.ServerMsg(f"{self.group[name]} joined the chat."))
                self.unicast(self.group[name], cpp.ServerMsg("Tip: Type /help to display available commands."))
                if len(self.group) == 1:  # make first member to join the chat a manager
                    self.group[name].is_manager = True
                print("#DEBUG# added member " + name + " #members = " + str(len(self.group)))

    def accept_connections(self):
        while True:
            conn, _ = self.accept_soc.accept()
            conn.setblocking(0)
            self.pending_que.put(conn)
            print(
                "#DEBUG# accepted connection. #pending_connections = " + str(self.pending_que.qsize()))
            time.sleep(0.05)

    def unicast(self, member, cpp_msg):
        """send a CPP message to a specific member.
        """
        try:
            cpp.ssend(member.conn, self.aeskey, cpp_msg)
        except socket.error:  # connection has likely been closed
            self.group.kick(member)
            self.broadcast(cpp.ServerMsg(f"{member.name} left the chat."))

    def broadcast(self, cpp_msg, exclude=[]):
        """send a message to all members, possibly excluding some.
        """
        for member in self.group:
            if member not in exclude:
                self.unicast(member, cpp_msg)

    def recv(self, origin, secure=True):
        if type(origin) is Member:
            origin = origin.conn
        if secure:
            return cpp.srecv(origin, self.aeskey)
        else:
            return cpp.recv(origin)

    def handle(self, member, cpp_msg):
        if type(cpp_msg) is cpp.Cmd:
            self.execute_command(member, cpp_msg)
        elif type(cpp_msg) is str and not member.is_muted:
            if cpp_msg.startswith("DOWNLOAD:"):
                file_descriptor = int(cpp_msg.split(':', 1)[1])
                self.send_file(member, file_descriptor)
                return
            if cpp_msg.startswith("FILE:"):
                filepath = cpp_msg.split(':', 1)[1]
                self.curr_file_desc += 1
                cpp_msg = f"FILE:{self.curr_file_desc}:{filepath}"
            self.broadcast(cpp.ServerMsg(cpp_msg, name=member.name), exclude=[member])
            self.unicast(member, cpp.ServerMsg(cpp_msg, name=member.name))
        elif type(cpp_msg) is bytes:
            self.download_file(cpp_msg)
        elif member.is_muted:
            self.unicast(member, cpp.ServerMsg("Error - You are muted, message was not sent."))

    def send_file(self, member, file_descriptor):
        filepath = f"./data/{file_descriptor}"
        with open(filepath, 'rb') as file:
            data = file.read()
            file.close()
        self.unicast(member, data)

    def download_file(self, data):
        Path(f"./data").mkdir(parents=True, exist_ok=True)
        file = open(f"./data/{self.curr_file_desc}", 'wb')
        file.write(data)
        file.close()

    def execute_command(self, executer, cmd):

        if not executer.is_manager and cmd.cmd in [cpp.DataType.CMD_KICK.value, cpp.DataType.CMD_PROMOTE.value, cpp.DataType.CMD_DEMOTE.value,
                                                   cpp.DataType.CMD_MUTE.value, cpp.DataType.CMD_UNMUTE.value]:
            # executer is not a manager but tries to use manager-only commands
            self.unicast(executer, cpp.ServerMsg("Error - Permission denied."))
        elif cmd.cmd == cpp.DataType.CMD_HELP.value:
            self.execute_help(executer)
        elif cmd.cmd == cpp.DataType.CMD_QUIT.value:
            self.execute_quit(executer)
        elif cmd.cmd == cpp.DataType.CMD_VIEW.value:
            self.execute_view_managers(executer)
        elif cmd.name not in self.group:
            self.unicast(executer, cpp.ServerMsg(f"Error - '{cmd.name}' is not in the group."))
        elif cmd.cmd == cpp.DataType.CMD_TELL.value:
            self.execute_tell(executer, cmd.name, cmd.msg)
        elif cmd.cmd == cpp.DataType.CMD_KICK.value:
            self.execute_kick(cmd.name)
        elif cmd.cmd == cpp.DataType.CMD_PROMOTE.value:
            self.execute_promote(cmd.name)
        elif cmd.cmd == cpp.DataType.CMD_DEMOTE.value:
            self.execute_demote(cmd.name)
        elif cmd.cmd == cpp.DataType.CMD_MUTE.value:
            self.execute_mute(cmd.name)
        elif cmd.cmd == cpp.DataType.CMD_UNMUTE.value:
            self.execute_unmute(cmd.name)
        else:
            self.unicast(executer, cpp.ServerMsg("Error - Invalid input, try /help."))

    def execute_help(self, executer):
        self.unicast(executer, cpp.ServerMsg(self.help_html()))

    def execute_quit(self, executer):
        self.broadcast(cpp.ServerMsg(f"{executer.name} left the chat."))
        self.group.kick(executer)

    def execute_view_managers(self, executer):
        manager_list = map(lambda memb: str(memb), filter(lambda memb: memb.is_manager, self.group))
        self.unicast(executer, cpp.ServerMsg("Managers: " + ", ".join(manager_list)))

    def execute_tell(self, executer, name, msg):
        if executer.is_muted:
            self.unicast(executer, cpp.ServerMsg("Error - You are muted, message was not sent."))
        elif name in self.group:
            self.unicast(executer, cpp.ServerMsg(f"{executer.name} -> {self.group[name].name}: {msg}"))
            self.unicast(self.group[name], cpp.ServerMsg(f"{executer.name} -> {self.group[name].name}: {msg}"))

    def execute_kick(self, name):
        if name in self.group:
            self.broadcast(cpp.ServerMsg(f"{self.group[name].name} has been kicked from the group."), exclude=[self.group[name]])
            self.unicast(self.group[name], cpp.ServerMsg("You have been kicked from the group."))
            self.group.kick(name)

    def execute_promote(self, name):
        if name in self.group and not self.group[name].is_manager:
            self.unicast(self.group[name], cpp.ServerMsg("You are now a manager."))
            self.group[name].is_manager = True

    def execute_demote(self, name):
        if name in self.group and self.group[name].is_manager:
            self.unicast(self.group[name], cpp.ServerMsg("You are no longer a manager."))
            self.group[name].is_manager = False

    def execute_mute(self, name):
        if name in self.group and not self.group[name].is_muted:
            self.unicast(self.group[name], cpp.ServerMsg("You have been muted by a manager."))
            self.group[name].is_muted = True

    def execute_unmute(self, name):
        if name in self.group and self.group[name].is_muted:
            self.unicast(self.group[name], cpp.ServerMsg("You are no longer muted."))
            self.group[name].is_muted = False

    def do(self):
        for member in self.group:
            if member.conn.fileno() == -1:
                    self.group.kick(member)
            else:
                cpp_msg = self.recv(member)
                if cpp_msg is not None:
                    self.handle(member, cpp_msg)

    def help_html(self):
        return \
            f'''<html><head /><body>
Exemple #11
0
class GameScreen(BaseScreen):
    class Hand(Enum):
        ROCK = 0
        PAPER = 1
        SCISSORS = 2

    class Actor:
        def __init__(self, game_player):
            self.game_player = game_player
            self.hand = None

        def done(self) -> bool:
            return self.hand is not None

        def set_hand(self, hand):
            print(self, "set hand:", hand)
            self.hand = hand

        def reset(self):
            self.hand = None

        def decrease_stock(self):
            self.game_player.stock -= 1
            return self.game_player.stock

        def __repr__(self):
            return "<Actor: {}>".format(self.game_player)

    def __init__(self, game_player1, game_player2, game_setting):
        """ゲーム画面

        Args:
            game_player1 (GamePlayer): プレイヤー情報(Player, Character, stock(player's rest stock))
            game_player2 (GamePlayer): プレイヤー情報(Player, Character, stock(player's rest stock))
            game_setting (GameSetting): ゲーム情報(stage, stock(先取))
        """
        super().__init__()
        game_config = GameConfig("./jsons/config.json")

        if game_player1 is None:
            game_player1 = get_sample_game_player(game_config, name="sample1")
        else:
            game_player1 = game_player1
            if game_player1.character is None or game_player1.player is None:
                game_player1 = get_sample_game_player(game_config,
                                                      name="sample1")
        if game_player2 is None:
            game_player2 = get_sample_game_player(game_config, name="sample2")
        else:
            game_player2 = game_player2
            if game_player2.character is None or game_player2.player is None:
                game_player2 = get_sample_game_player(game_config,
                                                      name="sample2")
        if game_setting is None:
            self.game_setting = get_sample_game_setting(game_config, stock=5)
        else:
            self.game_setting = game_setting

        self.actor1 = self.Actor(game_player1)
        self.actor2 = self.Actor(game_player2)

        # self.font = pygame.font.Font(None, 60)
        self.font = pygame.font.Font("./fonts/Mplus2-Medium.ttf", 60)

        self.yattane = pygame.mixer.Sound("./sounds/yattane.mp3")
        self.uu = pygame.mixer.Sound("./sounds/uu.mp3")
        self.sokomade = pygame.mixer.Sound("./sounds/sokomade.mp3")

        self.init()

    def init(self):
        """初期化処理を行う
        """
        self._set_area()
        self._set_bg()
        self._init_game()
        self._set_player_icons()
        # self._set_random_btn()
        self._set_key_handler()
        self._set_checker()
        self._set_animation()

        self._reset()

    def _set_area(self):
        """エリア分割を行う
        """
        rect = self.display.get_rect()
        area_rects = layout_rects(rect, 2, 3)
        self.view_area = area_rects[0].union(area_rects[3])
        self.icon_area = area_rects[4].union(area_rects[5])

    def _set_bg(self):
        """背景画像の設置.game_setting.stageを参照.
        """
        print(self.game_setting.stage)
        rect = self.display.get_rect()
        bg_image = self.game_setting.stage.image
        bg_image = surface_fit_to_rect(bg_image, rect)
        self.bg_sprite = SimpleSprite(rect, bg_image)
        self.background_sprites.add(self.bg_sprite)

    def _init_game(self):
        """ゲームの初期化.
        """
        self.actor1.game_player.stock = self.game_setting.stock
        self.actor2.game_player.stock = self.game_setting.stock

    def _set_player_icons(self):
        """プレイヤーアイコンの設置
        """
        rects = layout_rects(self.icon_area,
                             2,
                             1,
                             padding_left=70,
                             padding_right=50,
                             margin_horizontal=50)
        game_players = [self.actor1.game_player, self.actor2.game_player]
        for game_player, rect in zip(game_players, rects):
            player_icon_sprite = PlayerStockIcon(left=rect.left,
                                                 top=rect.top,
                                                 game_player=game_player,
                                                 image_height=100)
            self.middle_sprites.add(player_icon_sprite)

    def _set_random_btn(self):
        """(デバッグ)ランダム勝敗ボタンの設置
        """
        rect = self.display.get_rect()
        surface = self.font.render("random result", True, (255, 255, 255),
                                   (0, 0, 0))
        random_result_btn = RichSprite(rect.w // 2,
                                       rect.h // 3,
                                       image=surface,
                                       press_fnc=self._random_result)
        self.middle_sprites.add(random_result_btn)

    def _random_result(self):
        """ランダムに勝敗をつける関数
        """
        import random
        players = [self.actor1.game_player, self.actor2.game_player]
        win_i = random.randint(0, 1)
        players[win_i].stock = 1
        players[(win_i + 1) % 2].stock = 0

        print("player {} win.".format(players[win_i].player.name))

        self._go_to_result()

    def _set_key_handler(self):
        """プレイヤーの入力を処理するGroupの設置
        """
        self.key_handers = []
        for actor, keys in zip([self.actor1, self.actor2],
                               [(pygame.K_1, pygame.K_2, pygame.K_3),
                                (pygame.K_8, pygame.K_9, pygame.K_0)]):
            key_to_fnc_dic = {
                keys[0]: (self._set_hand, (actor, self.Hand.ROCK)),
                keys[1]: (self._set_hand, (actor, self.Hand.SCISSORS)),
                keys[2]: (self._set_hand, (actor, self.Hand.PAPER)),
            }
            key_hundler = KeyHandler(key_to_fnc_dic)
            self.middle_sprites.add(key_hundler)
            self.key_handers.append(key_hundler)

    def _set_checker(self):
        """チェッカーGroupの設置
        """
        self.checkers = []
        # プレイヤー1, 2が入力完了したかどうかを監視するもの
        key_done_checker = Checker([self.actor1.done, self.actor2.done],
                                   self._start_battle_before_animation,
                                   stop_when_call_fnc=True)
        self.middle_sprites.add(key_done_checker)
        self.checkers.append(key_done_checker)

    def _judge(self):
        """勝ち負け判定
        """
        win_actor = None
        rest = 1
        if self.actor1.hand == self.actor2.hand:
            pass  # あいこ
        elif (self.actor1.hand == self.Hand.ROCK and self.actor2.hand == self.Hand.SCISSORS) or \
            (self.actor1.hand == self.Hand.PAPER and self.actor2.hand == self.Hand.ROCK) or \
            (self.actor1.hand == self.Hand.SCISSORS and self.actor2.hand == self.Hand.PAPER):
            # actor1の勝ち
            rest = self.actor2.decrease_stock()
            win_actor = self.actor1
        else:
            # actor2の勝ち
            rest = self.actor1.decrease_stock()
            win_actor = self.actor2

        self._start_battle_after_animation(win_actor)
        # self._reset()

    def _set_animation(self):
        """アニメーションの設定
        """
        self.timer_group = TimerGroup()
        self.middle_sprites.add(self.timer_group)
        self.transform_manager = SpriteTransformManager()
        self.middle_sprites.add(self.transform_manager)

        rects = layout_rects(self.view_area,
                             2,
                             1,
                             padding=40,
                             margin_vertical=40)
        self.hand_sprites = {
            self.actor1: {
                self.Hand.ROCK:
                SimpleSprite(
                    rects[0],
                    fit_surface(self.actor1.game_player.character.arm_image[0],
                                rects[0])),
                self.Hand.SCISSORS:
                SimpleSprite(
                    rects[0],
                    fit_surface(self.actor1.game_player.character.arm_image[1],
                                rects[0])),
                self.Hand.PAPER:
                SimpleSprite(
                    rects[0],
                    fit_surface(self.actor1.game_player.character.arm_image[2],
                                rects[0])),
            },
            self.actor2: {
                self.Hand.ROCK:
                SimpleSprite(
                    rects[1],
                    fit_surface(self.actor2.game_player.character.arm_image[0],
                                rects[1])),
                self.Hand.SCISSORS:
                SimpleSprite(
                    rects[1],
                    fit_surface(self.actor2.game_player.character.arm_image[1],
                                rects[1])),
                self.Hand.PAPER:
                SimpleSprite(
                    rects[1],
                    fit_surface(self.actor2.game_player.character.arm_image[2],
                                rects[1])),
            }
        }
        # wait_surface = self.font.render("wait", True, (0, 0, 0), (255, 255, 255))
        # ready_surface = self.font.render("ready", True, (0, 0, 0), (255, 255, 255))
        self.actor_state_sprites = {
            self.actor1: {
                True:
                TextSprite(*rects[0].midbottom,
                           align="center",
                           vertical_align="bottom",
                           text="wait",
                           font=self.font,
                           color=(0, 0, 0),
                           bgcolor=(255, 255, 255)),
                False:
                TextSprite(*rects[0].midbottom,
                           align="center",
                           vertical_align="bottom",
                           text="ready",
                           font=self.font,
                           color=(0, 0, 0),
                           bgcolor=(255, 255, 255)),
            },
            self.actor2: {
                True:
                TextSprite(*rects[1].midbottom,
                           align="center",
                           vertical_align="bottom",
                           text="wait",
                           font=self.font,
                           color=(0, 0, 0),
                           bgcolor=(255, 255, 255)),
                False:
                TextSprite(*rects[1].midbottom,
                           align="center",
                           vertical_align="bottom",
                           text="ready",
                           font=self.font,
                           color=(0, 0, 0),
                           bgcolor=(255, 255, 255)),
            }
        }
        self.actor_state_group = Group()
        self.middle_sprites.add(self.actor_state_group)

        # 「さいしょは ぐー」などのセリフスプライト
        self.before_battle_sprite1 = TextSprite(*self.view_area.center,
                                                align="center",
                                                vertical_align="middle",
                                                text="さいしょは ぐー",
                                                font=self.font,
                                                color=(0, 0, 0),
                                                bgcolor=(255, 255, 255))
        self.before_battle_sprite2 = TextSprite(*self.view_area.center,
                                                align="center",
                                                vertical_align="middle",
                                                text="じゃんけん...",
                                                font=self.font,
                                                color=(0, 0, 0),
                                                bgcolor=(255, 255, 255))
        self.before_battle_sprite3 = TextSprite(*self.view_area.center,
                                                align="center",
                                                vertical_align="middle",
                                                text="ぽん",
                                                font=self.font,
                                                color=(0, 0, 0),
                                                bgcolor=(255, 255, 255))
        self.before_battle_sprite4 = TextSprite(*self.view_area.center,
                                                align="center",
                                                vertical_align="middle",
                                                text="あいこで",
                                                font=self.font,
                                                color=(0, 0, 0),
                                                bgcolor=(255, 255, 255))
        self.before_battle_sprite5 = TextSprite(*self.view_area.center,
                                                align="center",
                                                vertical_align="middle",
                                                text="しょ",
                                                font=self.font,
                                                color=(0, 0, 0),
                                                bgcolor=(255, 255, 255))
        self.end_battle_sprite = TextSprite(*self.view_area.center,
                                            align="center",
                                            vertical_align="middle",
                                            text="そこまで",
                                            font=self.font,
                                            color=(0, 0, 0),
                                            bgcolor=(255, 255, 255))

        # あいこ中フラグ
        self.pre_aiko = False

    def _start_battle_before_animation(self):
        """バトルアニメーションを開始
        """
        dummy = Group()
        self.timer_group.add_timer_sprite(
            dummy, timer=30, on_delete_fnc=self.actor_state_group.empty)
        if self.pre_aiko:
            self.timer_group.add_timer_sprite(
                self.before_battle_sprite4,
                timer=60,
                start_delay=30,
                on_delete_fnc=self._start_battle_hand_animation,
                debug_label="あいこで")
            self.timer_group.add_timer_sprite(self.before_battle_sprite5,
                                              timer=30,
                                              start_delay=90,
                                              layer="front",
                                              debug_label="しょ")
        else:
            self.timer_group.add_timer_sprite(self.before_battle_sprite1,
                                              timer=60,
                                              start_delay=30,
                                              debug_label="最初はグー")
            self.timer_group.add_timer_sprite(
                self.before_battle_sprite2,
                timer=60,
                start_delay=90,
                on_delete_fnc=self._start_battle_hand_animation,
                debug_label="じゃんけん")
            self.timer_group.add_timer_sprite(self.before_battle_sprite3,
                                              timer=30,
                                              start_delay=150,
                                              layer="front",
                                              debug_label="ぽん")

    def _start_battle_hand_animation(self):
        """手を出すアニメーションを開始
        """
        # self.actor_state_group.empty()
        total_frame = 60
        group = Group()
        for actor in [self.actor1, self.actor2]:
            sprite = self.hand_sprites[actor][actor.hand]
            group.add(sprite)
            sprite.image.set_alpha(0)
            props = make_transform_properties(0,
                                              0,
                                              0,
                                              0,
                                              0,
                                              1,
                                              total_frame=int(total_frame *
                                                              0.2))
            self.transform_manager.add_transformer(sprite, props)
        self.timer_group.add_timer_sprite(group,
                                          timer=total_frame,
                                          on_delete_fnc=self._judge,
                                          debug_label="手を表示する")

    def _start_battle_after_animation(self, actor):
        """勝者を受け取って何かする

        Args:
            actor (Actor): 勝者Actor
        """
        self.pre_aiko = False
        if actor == self.actor1:
            self.yattane.play()
        elif actor == self.actor2:
            self.uu.play()
        else:
            self.pre_aiko = True

        end = False
        for actor in [self.actor1, self.actor2]:
            if actor.game_player.stock == 0:
                end = True
                break

        dummy = Group()
        self.timer_group.add_timer_sprite(
            dummy,
            timer=90,
            on_delete_fnc=self._start_battle_end_animation
            if end else self._reset,
            debug_label="ボイスの分")

    def _start_battle_end_animation(self):
        """Resultに移る前のアニメーション
        """
        self.sokomade.play()
        self.end_battle_sprite.image.set_alpha(0)
        total_frame = 90
        props = make_transform_properties(0,
                                          0,
                                          0,
                                          0,
                                          0,
                                          1,
                                          total_frame=int(total_frame * 0.3))
        self.transform_manager.add_transformer(self.end_battle_sprite, props)
        self.timer_group.add_timer_sprite(self.end_battle_sprite,
                                          timer=total_frame,
                                          on_delete_fnc=self._go_to_result,
                                          debug_label="result遷移までの間(そこまでボイス分)")

    def _set_hand(self, actor, hand):
        """actorのHandを更新する

        Args:
            actor (Actor): Actor
            hand (Hand): Hand
        """
        actor.set_hand(hand)
        self._update_actor_state_sprites()

    def _update_actor_state_sprites(self):
        """Actorの状態に応じて画像を変化させる
        """
        self.actor_state_group.empty()
        for actor in [self.actor1, self.actor2]:
            self.actor_state_group.add(
                self.actor_state_sprites[actor][actor.done()])

    def _go_to_result(self):
        """結果画面に進む
        """
        self.run = False
        self.next_screen = Screen.RESULT

    def _reset(self):
        """入力待ちに戻す
        """
        self.actor1.reset()
        self.actor2.reset()

        for key_hander in self.key_handers:
            key_hander.resume()

        for checker in self.checkers:
            checker.resume()

        self._update_actor_state_sprites()