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 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()
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
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)
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(α - β)
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)
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()
def position_for(self, mouse_pos: Vector): return mouse_pos + Vector(0, 4 - CardDrawer.CARD_SIZE.y // 2)
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 )
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))
def arrowline(θ): return self._mk_line( b, b - Vector(math.cos(θ), math.sin(θ)) * self._arrow_size)
def mouse_scroll(self, x, y, scroll_x, scroll_y): emit_event( self._objects, 'mouse_scroll', Vector(x, y), Vector(scroll_x, scroll_y) )
def mouse_up(self, x, y, button, modifiers): emit_event( self._objects, 'mouse_up', Vector(x, y), button, modifiers )
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 )
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()