示例#1
0
    def _update_label(self):
        self._delete_label()

        if self._label:
            info = LabelWithBackground(
                f"{len(self._cards)} kort",
                colour=CardStackDrawer.TEXT_COLOUR,
                background_colour=CardStackDrawer.LABEL_BG_COLOUR,
                background_padding=CardStackDrawer.LABEL_BG_PADDING,
                pos=self._card_draw.top_centre + CardStackDrawer.LABEL_HOVER,
                anchor_x='center',
                anchor_y='bottom',
                font_name='Source Code Pro',
                font_size=10,
                batch=self._batch,
                group=self._group)

            name = LabelWithBackground(
                self._label,
                colour=CardRowDrawer.TEXT_COLOUR,
                background_colour=CardRowDrawer.LABEL_BG_COLOUR,
                background_padding=CardRowDrawer.LABEL_BG_PADDING,
                pos=info.bounds.top_centre + Vector(0, 5),
                anchor_x='center',
                anchor_y='bottom',
                font_name='Source Code Pro',
                font_size=10,
                batch=self._batch,
                group=self._group)

            self._top_labels = [info, name]
示例#2
0
def main():
    font.add_directory(FONT_DIR)
                
    FPS         = 60
    WINDOW_SIZE = Vector(920, 760)
    
    window = Window(WINDOW_SIZE.x, WINDOW_SIZE.y, caption = "Kort!!!")
    
    sjuan = Sjuan(game, RectangleShape(
        bottom_left = Vector(0, 0), size = WINDOW_SIZE
    ))
    
    @window.event
    def on_draw():
        window.clear()
        sjuan._world.draw()
        
    @window.event
    def on_mouse_motion(*args):
        sjuan._world.mouse_at(*args)

    @window.event
    def on_mouse_drag(*args):
        sjuan._world.mouse_at(*args)
    
    @window.event
    def on_mouse_press(*args):
        sjuan._world.mouse_down(*args)

    @window.event
    def on_mouse_release(*args):
        sjuan._world.mouse_up(*args)
        
    @window.event
    def on_mouse_scroll(*args):
        sjuan._world.mouse_scroll(*args)
        
    def update(dt):
        pass

    pyglet.clock.schedule_interval(update, 1 / FPS)
    pyglet.app.run()
示例#3
0
    def _create_dotted_draws(self):
        pad = 10
        dy = CardDrawer.CARD_SIZE.y + pad

        pos = Vector(0, dy * (len(CardSuit) - 1) / 2)
        for suit in CardSuit:
            self._dotted_draws[suit] = DashedRect(RectangleShape(
                size=CardDrawer.CARD_SIZE, centre=deepcopy(pos)),
                                                  dashes=[16, 8],
                                                  batch=self._batch_sevens)
            pos.y -= dy
示例#4
0
    def __init__(self,
                 size: Vector,
                 bottom_left: Vector = None,
                 centre: Vector = None):
        self.size = size

        if bottom_left is not None:
            self.bottom_left = bottom_left
            self.centre = bottom_left + size // 2
        elif centre is not None:
            self.centre = centre
            self.bottom_left = centre - size // 2
        else:
            raise ValueError("Must provide either centre or bottom_left")

        self.top_right = self.bottom_left + self.size
        self._low_x, self._low_y = self.bottom_left
        self._centre_x, self._centre_y = self.centre
        self._high_x, self._high_y = self.top_right

        self.centre_left = Vector(self.low_x, self.centre_y)
        self.top_left = Vector(self.low_x, self.high_y)
        self.bottom_right = Vector(self.high_x, self.low_y)
        self.centre_right = Vector(self.high_x, self.centre_y)
        self.top_centre = Vector(self.centre_x, self.high_y)
        self.bottom_centre = Vector(self.centre_x, self.low_y)
示例#5
0
    def _update_line(self):
        self._delete_line()

        def div(x, y):
            return math.copysign(1000000000, x) if y == 0 else x / y

        d = self._posB - self._posA
        k = div(d.y, d.x)
        α = math.atan2(d.y, d.x)
        q = Vector(math.cos(α), math.sin(α))
        p = q * self._pad
        o = Vector(math.sin(α), -math.cos(α)) * self._offset
        a = self._posA + p
        b = self._posB - p
        β = Arrow.POINTY_ANGLE
        s = math.sqrt(1 + k**2)
        ka = math.tan(β)
        K1 = div(k + ka, 1 - k * ka)
        K2 = div(k - ka, 1 + k * ka)

        def line(O, m, K):
            pos0 = a + O
            x1 = (pos0.y - pos0.x * k - m) / (K - k)
            y1 = K * x1 + m
            return self._mk_line(pos0, Vector(x1, y1))

        m1 = b.y - b.x * K1
        m2 = b.y - b.x * K2
        self.line1 = line(o, m1, K1)
        self.line2 = line(-o, m2, K2)

        def arrowline(θ):
            return self._mk_line(
                b, b - Vector(math.cos(θ), math.sin(θ)) * self._arrow_size)

        self.arrow1 = arrowline(α + β)
        self.arrow2 = arrowline(α - β)
示例#6
0
    def mouse_scroll(self, mouse_pos, scroll):
        if (self._drawer.bounds_inner.has_point(mouse_pos)
                or self._floating_card):
            self.set_target(None)

            if scroll.y > 0:
                self._drawer.incr_offset()
            else:
                self._drawer.decr_offset()

            if self._floating_card:
                self._floating_card.moves = self.world.parent.moves_for_card(
                    self._floating_origin)
                self._floating_card.origin = (self._drawer.nth_card(
                    self._floating_origin).pos)

            self.mouse_at(mouse_pos, Vector(0, 0), 0, 0)
示例#7
0
    def __init__(
        self, pos: Vector, radius: int,
        segments = 25, angle = math.pi * 2, colour = (255, 255, 255, 255),
        batch = None, group = None
    ):
        self._pos = pos
        self._radius = radius
        self._segments = segments
        self._colour = colour
        self._angle = angle
        self._anchor = Vector(0, 0)

        self._batch = batch or Batch()
        self._group = shp._ShapeGroup(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, group)
        
        self._vertex_list = self._batch.add(
            (self._segments - 1) * 2,
            GL_LINES, self._group, 'v2f', 'c4B'
        )
        self._update_position()
        self._update_color()
示例#8
0
 def position_for(self, mouse_pos: Vector):
     return mouse_pos + Vector(0, 4 - CardDrawer.CARD_SIZE.y // 2)
示例#9
0
文件: sjuan.py 项目: kvackkvack/cards
 def __init__(self, game: SjuanGame, bounds: RectangleShape):
     self._game   = game
     self._bounds = bounds
     
     self._world = World(self)
     
     self._source_stack_manager = CardStackManager(
         game.state.source_stack, bounds.centre,
         label = None, interactable = False
     )
     self._world.add_object(self._source_stack_manager)
     
     self._sjuan_stack_manager = SjuanStackManager(
         game.state.sjuan_stack, bounds.centre
     )
     self._sjuan_stack_manager._drawer.visible = False
     self._world.add_object(self._sjuan_stack_manager)
     
     self._player_managers = []
     for player in game.state.players:
         manager = CardHandManager(
             player, Vector(0, 0), label = "Spelare"
         )
         self._player_managers.append(manager)
         self._world.add_object(manager)
     
     self._advance_turn_button = ButtonManager(
         "Nästa tur", font_size = 11,
         bounds = RectangleShape(
             centre = self._bounds.centre - Vector(0, 80),
             size   = Vector(160, 34)
         ),
         on_click = lambda: self._game.do(self._game.state.queue),
         background_colour   = (126, 224, 239, 190),
         background_colour_2 = (96,  205, 222, 175),
         outline_colour      = (130, 216, 248, 230)
     )
     self._world.add_object(self._advance_turn_button)
     
     self._player_amount_changed()
     self._adjust_player_managers()
     game.state.phase.match(
         do_queue = self._queue_time,
         player_turn = do_nothing, give_cards = do_nothing
     )
     
     # Events
     
     def turn_change(old_phase, new_phase, players_changed):
         if players_changed:
             self._player_amount_changed()
         
         new_phase.match(
             do_queue = lambda next_phase:
                 self._queue_time(next_phase),
             player_turn = lambda i:
                 self._adjust_player_managers(curr_turn = i),
             give_cards  = lambda i, _:
                 self._adjust_player_managers(curr_turn = i)
         )
         
         if not self._ask_cards_button:
             update_ask_cards_button(self._game.state.can_succumb)
     
     self._skip_turn_button = None
     def update_skip_button(skippable):
         if not self._skip_turn_button:
             curr_player  = self._player_managers[self._game.state.turn_index()]
             cards_bounds = curr_player._drawer._bounds_inner
             size         = Vector(130, 18)
             self._skip_turn_button = ButtonManager(
                 "Hoppa över", font_size = 10,
                 bounds = RectangleShape(
                     bottom_left = (
                         cards_bounds.bottom_right
                         + Vector(0, cards_bounds.size.y / 2)
                         - Vector(size.x / 2, size.y / 2)
                         + Vector(0, 60)
                     ), size = size
                  ),
                 on_click = lambda: self._game.do([
                     SjuanRules.Move.THE_ACTION(SjuanAction.SKIP())
                 ]),
                 background_colour   = (126, 224, 239, 220),
                 background_colour_2 = (96,  205, 222, 200),
                 outline_colour      = (130, 216, 248, 255)
             )
                 
         if skippable:
             self._world.add_object(self._skip_turn_button)
         else:
             self._world.remove_object(self._skip_turn_button)
     
     self._ask_cards_button = None
     def update_ask_cards_button(can_ask):
         if not self._ask_cards_button:
             curr_i       = self._game.state.turn_index()
             prev_i       = self._game.state.turn_incr(curr_i, -1)
             prev_player  = self._player_managers[prev_i]
             cards_bounds = prev_player._drawer._bounds_inner
             size         = Vector(130, 18)
             self._ask_cards_button = ButtonManager(
                 "Be om kort", font_size = 10,
                 bounds = RectangleShape(
                     bottom_left = (
                         cards_bounds.bottom_right
                         + Vector(0, -cards_bounds.size.y / 2)
                         - Vector(size.x / 2, -size.y / 2)
                         - Vector(15, 10)
                     ), size = size
                  ),
                 on_click = lambda: self._game.do([
                     SjuanRules.Move.THE_ACTION(SjuanAction.ASK_FOR_CARDS())
                 ]),
                 background_colour   = (244, 174, 169, 220),
                 background_colour_2 = (230,  169, 160, 200),
                 outline_colour      = (255, 146, 158, 255)
             )
         
         if can_ask:
             self._world.add_object(self._ask_cards_button)
         else:
             self._world.remove_object(self._ask_cards_button)
     
     game.state.listen(
         on_turn_change        = turn_change,
         on_skippable_change   = update_skip_button,
         on_succumbable_change = update_ask_cards_button
     )
示例#10
0
 def line(O, m, K):
     pos0 = a + O
     x1 = (pos0.y - pos0.x * k - m) / (K - k)
     y1 = K * x1 + m
     return self._mk_line(pos0, Vector(x1, y1))
示例#11
0
 def arrowline(θ):
     return self._mk_line(
         b, b - Vector(math.cos(θ), math.sin(θ)) * self._arrow_size)
示例#12
0
 def mouse_scroll(self, x, y, scroll_x, scroll_y):
     emit_event(
         self._objects, 'mouse_scroll',
         Vector(x, y), Vector(scroll_x, scroll_y)
     )
示例#13
0
 def mouse_up(self, x, y, button, modifiers):
     emit_event(
         self._objects, 'mouse_up',
         Vector(x, y), button, modifiers
     )
示例#14
0
 def mouse_at(self, x, y, dx, dy, button = 0, modifiers = 0):
     emit_event(
         self._objects, 'mouse_at',
         Vector(x, y), Vector(dx, dy), button, modifiers
     )
示例#15
0
class CardStackDrawer:
    LABEL_HOVER = Vector(0, 14)
    LABEL_BG_PADDING = Vector(10, 1)
    LABEL_BG_COLOUR = (160, 188, 255, 120)
    TEXT_COLOUR = (255, 255, 255, 170)

    def __init__(self,
                 cards: List[Card],
                 pos: Vector,
                 label: str,
                 top_hidden: bool = True,
                 batch=None,
                 group=None):
        self._pos = pos
        self._cards = deepcopy(cards)
        self._label = label
        self._top_hidden = top_hidden
        if batch is None:
            self._batch = Batch()
            self._batch_is_own = True
        else:
            self._batch = batch
            self._batch_is_own = False
        self._group = group

        self._card_draw = None
        self._labels = []
        self._update()

    @property
    def cards(self):
        return self._cards

    @cards.setter
    def cards(self, cards):
        old_cards_len = len(self._cards)
        self._cards = deepcopy(cards)
        lens_diff = old_cards_len != len(cards)

        if lens_diff:
            self._update_label()

        if ((not self._top_hidden and cards[0] != self._cards[0])
                or (lens_diff and (len(cards) == 0 or old_cards_len == 0))):
            self._update_card_draw()

    def _update_card_draw(self):
        self._delete_card_draw()
        if len(self._cards) > 0:
            self._card_draw = CardDrawer(self._cards[0],
                                         self._pos,
                                         hidden=self._top_hidden,
                                         batch=self._batch,
                                         group=self._group)

    def _update_label(self):
        self._delete_label()

        if self._label:
            info = LabelWithBackground(
                f"{len(self._cards)} kort",
                colour=CardStackDrawer.TEXT_COLOUR,
                background_colour=CardStackDrawer.LABEL_BG_COLOUR,
                background_padding=CardStackDrawer.LABEL_BG_PADDING,
                pos=self._card_draw.top_centre + CardStackDrawer.LABEL_HOVER,
                anchor_x='center',
                anchor_y='bottom',
                font_name='Source Code Pro',
                font_size=10,
                batch=self._batch,
                group=self._group)

            name = LabelWithBackground(
                self._label,
                colour=CardRowDrawer.TEXT_COLOUR,
                background_colour=CardRowDrawer.LABEL_BG_COLOUR,
                background_padding=CardRowDrawer.LABEL_BG_PADDING,
                pos=info.bounds.top_centre + Vector(0, 5),
                anchor_x='center',
                anchor_y='bottom',
                font_name='Source Code Pro',
                font_size=10,
                batch=self._batch,
                group=self._group)

            self._top_labels = [info, name]

    def _update(self):
        self._update_card_draw()
        self._update_label()

    def _delete_card_draw(self):
        if self._card_draw:
            self._card_draw.delete()
            self._card_draw = None

    def _delete_label(self):
        for label in self._labels:
            label.delete()
        self._labels = []

    def delete(self):
        self._delete_card_draw()

    def draw(self):
        if self._batch_is_own:
            self._batch.draw()
        else:
            self._card_draw.draw()
            for label in self._labels:
                label.draw()