def flip(self, sprite): set_dirty = lambda: setattr(sprite, 'dirty', 1) fx = sprite.rect.centerx - sprite.rect.width ani0 = Animation(rotation=0, duration=350, transition='out_quint') ani0.update_callback = set_dirty ani0.start(sprite) ani1 = Animation(centerx=fx, duration=340, transition='out_quint') ani1.update_callback = set_dirty ani1.start(sprite.rect) self._animations.add(ani0, ani1)
def clear_card(card): sound = choice(self.deal_sounds) sound.set_volume(.6) sound.play() set_dirty = lambda: setattr(card, 'dirty', 1) fx, fy = card.rect.move(-1400, -200).topleft ani0 = Animation(x=fx, y=fy, duration=400, transition='in_out_quint', round_values=True) ani0.update_callback = set_dirty ani0.callback = card.kill ani0.start(card.rect) ani1 = Animation(rotation=180, duration=400, transition='out_quart') ani1.update_callback = set_dirty ani1.start(card) self.animations.add(ani0, ani1)
def make_labels(self): sr = self.screen_rect self.labels = [] self.alpha = 255 self.big_alpha = 255 self.animations = pg.sprite.Group() text = "Free Ride" if self.game.free_ride else "Ante Up" self.big_label = Label(self.font, 320, text, "gold3", {"center": sr.center}, bg=prepare.FELT_GREEN) self.big_label.image.set_colorkey(prepare.FELT_GREEN) left, top = self.big_label.rect.topleft ani = Animation(x=left, y=top - 500, duration=2000, round_values=True) fade = Animation(alpha=0, duration=2000, round_values=True) big_fader = Animation(big_alpha=0, duration=1500, delay=500, round_values=True) fade.start(self) ani.start(self.big_label.rect) big_fader.start(self) self.animations.add(ani, fade, big_fader) if not self.game.free_ride: dest = self.game.pot_label.rect.center for p in self.game.players: pos = p.name_label.rect.center label = Label(self.font, 96, "${}".format(self.game.bet), "darkred", {"center": pos}, bg=prepare.FELT_GREEN) label.image.set_colorkey(prepare.FELT_GREEN) left, top = label.rect.topleft self.labels.append(label) ani = Animation(centerx=dest[0], centery=dest[1], duration=2000, delay=50, round_values=True, transition="in_quart") ani.callback = self.add_bet_to_pot ani.start(label.rect) self.animations.add(ani) fader = Animation(alpha=0, duration=2100, round_values=True) fader.start(self) self.animations.add(fader)
def on_pickup_stack_motion(self, *args): """When mouse is hovering over a stack or moving it """ chips, position = args[0] self.on_snap_stack_motion(*args) # check if mouse is hovering over betting area areas = chain(self.betting_areas.values(), [self.player_chips]) if self._hovered_chip_area is None: for area in areas: if area.drop_rect.collidepoint(position): self._hovered_chip_area = area sprite = getattr(area, 'sprite', None) if sprite is None: sprite = Sprite() sprite.rect = area.drop_rect.copy() sprite.image = pg.Surface(sprite.rect.size) sprite.image.fill((255, 255, 255)) area.sprite = sprite self.hud.add(sprite) self.remove_animations(sprite.image) ani = Animation(set_alpha=48, initial=0, duration=500, transition='out_quint') ani.start(sprite.image) self.animations.add(ani) # handle when mouse moves outside previously hovered area elif not self._hovered_chip_area.drop_rect.collidepoint(position): self.clear_area_highlight()
def make_dealing_animations(self): self.animations = pg.sprite.Group() delay_time = 100 for player in self.game.deal_queue: toggle = 0 for slot in player.card_slots: card = player.draw_from_deck(self.game.deck) fx, fy = slot.topleft ani = Animation(x=fx, y=fy, duration=400, delay=delay_time, transition="in_out_quint", round_values=True) if toggle > 0: if player is self.game.player: ani.callback = player.flip_cards else: ani.callback = player.align_cards ani.start(card.rect) self.animations.add(ani) task = Task(self.play_deal_sound, delay_time + 20) task2 = Task(self.play_flip_sound, delay_time - 20) self.animations.add(task) self.animations.add(task2) delay_time += 100 toggle += 1
def make_labels(self): self.animations = pg.sprite.Group() rules = [ "Players place their ante in the pot", "Two cards are dealt to each player", "Players choose whether to stay or pass", "Players that stayed show their cards", "The player with the best poker hand wins the pot", "Players that stay and lose must match the pot", "If two players lose, the pot doubles", "If three players lose, the pot triples...", "Ties split the pot", "The game ends when there is nothing in the pot", "Good Luck!" ] labels = [] for rule in rules: label = MultiLineLabel(self.font, 72, rule, "gold3", {"center": self.screen_rect.center}, bg=prepare.FELT_GREEN, align="center", char_limit=28) label.alpha = 255 labels.append(label) self.labels = iter(labels) self.label = next(self.labels) ani = Animation(alpha=0, duration=3000, round_values=True) ani.start(self.label) self.animations.add(ani)
def startup(self, game): self.game = game self.alpha = 255 self.showdown_alpha = 255 self.showdown_font_size = 64 self.make_showdown_label() fader = Animation(alpha=0, duration=2500, delay=500, round_values=True) sizer = Animation(showdown_font_size=320, duration=500, round_values=True) fader.start(self) sizer.start(self) quitter = Task(self.end_state, 3000) flipper = Task(self.flip_cards, 1000) self.animations.add(fader, sizer, quitter, flipper)
def next_label(self): try: self.label = next(self.labels) ani = Animation(alpha=0, duration=3000, round_values=True) ani.start(self.label) self.animations.add(ani) except StopIteration: self.label = None
def split_hand(self, *args): """ Split player's hand into two hands, adjust hand locations and deal a new card to both hands. """ player = self.game.player hand = self.game.current_player_hand bet = hand.bet.get_chip_total() hand.slots = hand.slots[:-1] move = ((self.screen_rect.left + 50) - hand.slots[0].left, 0) player.move_hands(move) p_slot = player.hands[-1].slots[0] hand_slot = p_slot.move(int(prepare.CARD_SIZE[0] * 3.5), 0) card = hand.cards.pop() new_hand = Hand(hand_slot.topleft, [card], player.chip_pile.withdraw_chips(bet)) new_hand.slots = [hand_slot] card.rect.topleft = hand_slot.topleft player.hands.append(new_hand) player.add_slot(new_hand) self.play_deal_sound() self.game.player.add_slot(hand) card1 = self.game.deck.draw_card() dest = hand.slots[-1] dest_x, dest_y = dest.topleft card1.face_up = True hand.cards.append(card1) ani = Animation(x=dest_x, y=dest_y, duration=1000, round_values=True) ani.start(card1.rect) card2 = self.game.deck.draw_card() dest = new_hand.slots[-1] dest_x, dest_y = dest.topleft card2.face_up = True new_hand.cards.append(card2) ani2 = Animation(x=dest_x, y=dest_y, duration=1000, delay=500, round_values=True) ani2.start(card2.rect) ani3 = Task(self.play_deal_sound, 1500) self.animations.add(ani, ani2, ani3)
def scroll_page(self, mag): if not self.animations and len(self.game_buttons) > self.per_page: for game in self.game_buttons: self.normalize_scroll(game, mag) fx, fy = game.rect.x+prepare.RENDER_SIZE[0]*mag, game.rect.y ani = Animation(x=fx, y=fy, duration=350.0, transition='in_out_quint', round_values=True) ani.start(game.rect) self.animations.add(ani) prepare.SFX["cardplace4"].play()
def make_card_animations(self): g = self.game self.animations = pg.sprite.Group() deal_delay = 0 for i in range(2): card = g.deck.draw_card() destination = g.current_player_hand.slots[-1] dest_x, dest_y = destination.topleft dur = get_distance(destination.center, card.pos) * 20 // card.speed ani = Animation(x=dest_x, y=dest_y, duration=dur, delay=deal_delay, round_values=True) ani2 = Task(self.play_deal_sound, deal_delay) ani3 = Task(self.flip_card, deal_delay + dur, args=(card, )) g.current_player_hand.cards.append(card) if not i % 2: g.player.add_slot(g.current_player_hand) ani.start(card.rect) self.animations.add(ani, ani2, ani3) deal_delay += dur for i in range(2): card = g.deck.draw_card() destination = g.dealer.hand.slots[-1] dest_x, dest_y = destination.topleft dur = get_distance(destination.center, card.pos) * 20 // card.speed ani = Animation(x=dest_x, y=dest_y, duration=dur, delay=deal_delay, round_values=True) ani2 = Task(self.play_deal_sound, deal_delay) ani.start(card.rect) g.dealer.hand.cards.append(card) g.dealer.add_slot() self.animations.add(ani, ani2) if i: ani3 = Task(self.flip_card, deal_delay + dur, args=(card, )) self.animations.add(ani3) deal_delay += dur
def clear_area_highlight(self): self.remove_animations(self._hovered_chip_area.sprite.image) ani = Animation(set_alpha=0, initial=self._hovered_chip_area.sprite.image.get_alpha, duration=500, transition='out_quint') ani.callback = self._hovered_chip_area.sprite.kill ani.start(self._hovered_chip_area.sprite.image) self.animations.add(ani) self._hovered_chip_area = None
def hit(self, hand): """Draw a card from deck and add to hand.""" self.play_deal_sound() self.game.player.add_slot(hand) card = self.game.deck.draw_card() card.face_up = True destination = hand.slots[-1] dest_x, dest_y = destination.topleft hand.cards.append(card) dur = get_distance(destination.center, card.pos) * 20 // card.speed ani = Animation(x=dest_x, y=dest_y, duration=dur, round_values=True) ani.start(card.rect) self.animations.add(ani)
def animate_pop(self, sprite, initial, final, index=1): """Animate chips moving to popped stack """ # cancel animation that is already running on this sprite ani = self._running_animations.get(sprite, None) if ani is not None: del self._running_animations[sprite] self._animations.remove(ani) ani.kill() shadow = self._shadows_dict.get(sprite, None) if shadow is not None: shadow.rect = sprite.rect.move(0, 5) d = get_distance(sprite.rect.topleft, final) if d == 0: return None fx, fy = final ani = Animation(x=fx, y=fy, duration=self.animation_time, transition='out_quint', round_values=True) def update_sprite(): setattr(sprite, 'dirty', 1) offset = 20 - self.height_offset shadow = self._shadows_dict.get(sprite, None) if shadow is not None: shadow.rect = sprite.rect.move(0, offset) ani.update_callback = update_sprite def finalize(): del self._running_animations[sprite] if d > 1: self.play_chip_sound() ani.callback = finalize ani.start(sprite.rect) self._running_animations[sprite] = ani return ani
def make_city_icons(self): level = self.persist["level"] player = self.persist["player"] self.city_icons = [] for city in player.cities: points = 0 if not city.damaged: points = city.population * 100 cx = city.rect.centerx icon = CityIcon((cx, 300), points, city.image) self.city_icons.append(icon) if points: time_scale = points / 1000. dur = min(1000 + (points * time_scale), 5000) ani = Animation(current_points=points, duration=dur, round_values=True) ani.start(icon) self.animations.add(ani)
def animate_deal(self, sprite, initial, final, index): if hasattr(sprite, '_already_animated'): return None sprite._already_animated = True fx, fy = final ani = Animation(x=fx, y=fy, duration=400., transition='in_out_quint', round_values=True) ani.update_callback = lambda: setattr(sprite, 'dirty', 1) # HACK if 1: sprite.face_up = False ani.callback = partial(self.flip, sprite) ani.start(sprite.rect) return ani
def startup(self, game): self.game = game self.lobby_button.call = self.warn self.toggled = False self.alpha = 255 self.labels = [] self.blinkers = [] self.calculated = False self.animations = pg.sprite.Group() stayers = [x for x in self.game.players if x.stayed] winners = self.game.get_winners() share = self.game.pot // len(winners) ani_duration = 2000 self.free_ride = False for stayer in stayers: pos = stayer.name_label.rect.center dest = pos[0], pos[1] - 120 cards_center = stayer.cards[0].rect.union( stayer.cards[1].rect).center if stayer not in winners: text = "${}".format(self.game.pot) color = "darkred" stayer.lost = self.game.pot self.free_ride = True dest = self.game.pot_label.rect.center if stayer is self.game.player: pos = self.money_icon.rect.center if self.game.player.cash < stayer.lost: amount = stayer.lost - self.game.player.cash self.cash_advance(amount) msg = "You were forced to take a cash advance to cover your loss. Visit the ATM to view your account." self.notice(msg) self.add_player_cash(-stayer.lost) task = Task(self.add_to_pot, ani_duration, args=[stayer.lost]) self.animations.add(task) lose_label = Blinker(self.font, 96, "Loser", color, {"center": cards_center}, 500) self.animations.add( Task(self.blinkers.append, ani_duration, args=[lose_label])) else: text = "${}".format(share) color = "darkgreen" stayer.won = share pos = self.game.pot_label.rect.center if stayer is self.game.player: self.cha_ching.play() dest = self.money_icon.rect.center task = Task(self.add_player_cash, ani_duration, args=[share]) self.animations.add(task) win_label = Blinker(self.font, 96, "Winner", color, {"center": cards_center}, 500) self.animations.add( Task(self.blinkers.append, ani_duration, args=[win_label])) label = Label(self.font, 128, text, color, {"center": pos}, bg=prepare.FELT_GREEN) label.image.set_colorkey(prepare.FELT_GREEN) self.labels.append(label) move = Animation(centerx=dest[0], centery=dest[1], duration=ani_duration, round_values=True, transition="in_quart") move.start(label.rect) self.animations.add(move) fader = Animation(alpha=0, duration=ani_duration + 200, round_values=True) fader.start(self) self.animations.add(fader) self.game.pot = 0 self.make_player_buttons(self.free_ride) self.toggle_buttons(False) if self.free_ride: self.advice_texts = ["Press OK to play the next round"] else: self.advice_texts = [ "Ante Up ${} to play again".format(self.game.bet) ] self.advice_texts.append("Press the Lobby button to exit")
def startup(self, game): self.game = game self.game.result_labels = [] self.fade_labels = [] self.alpha = 255 total_ani_time = 2000 fade_ani = Animation(alpha=0, duration=total_ani_time) fade_ani.start(self) self.animations.add(fade_ani) self.game.tally_hands() payout = self.game.pay_out() if payout: self.coin_sound.play() hands = self.game.player.hands if len(hands) > 2: text_size = 64 elif len(hands) == 2: text_size = 80 else: text_size = 96 win_piles = [] loss_piles = [] self.winnings = [] self.losses = [] for hand in hands: amount = hand.bet.get_chip_total() hand.bet_amount = amount bl = hand.bet.stacks[0].rect.bottomleft if hand.blackjack: text, color = "Blackjack", "gold3" text_size -= 8 chips = cash_to_chips(int(amount * 2.5)) amount = int(amount * 1.5) win_piles.append(BetPile(bl, self.game.chip_size, chips)) elif hand.winner: text, color = "Win", "gold3" chips = cash_to_chips(amount * 2) win_piles.append(BetPile(bl, self.game.chip_size, chips)) elif hand.push: text, color = "Push", "gold3" chips = cash_to_chips(amount) win_piles.append(BetPile(bl, self.game.chip_size, chips)) elif hand.busted: text, color = "Bust", "darkred" chips = cash_to_chips(amount) loss_piles.append(BetPile(bl, self.game.chip_size, chips)) amount *= -1 else: text, color = "Loss", "darkred" chips = cash_to_chips(amount) loss_piles.append(BetPile(bl, self.game.chip_size, chips)) amount *= -1 centerx = (hand.slots[0].left + hand.slots[-1].right) // 2 centery = hand.slots[0].centery label = Blinker(self.font, text_size, text, color, {"center": (centerx, centery)}, 450) self.game.result_labels.append(label) amt_color = "darkgreen" if amount >= 0 else "darkred" bet_label = Label(self.font, 120, "{:+}".format(amount), amt_color, {"bottomleft": bl}, bg=prepare.FELT_GREEN) move_ani = Animation(bottom=bl[1] - 150, duration=total_ani_time, round_values=True) move_ani.start(bet_label.rect) self.animations.add(move_ani) self.fade_labels.append(bet_label) hand.bet.chips = [] hand.bet.stacks = [] payout_duration = 1000 center = self.game.player.chip_pile.rect.center for pile in win_piles: self.winnings.append(pile) for stack in pile.stacks: ani = Animation(left=center[0], bottom=center[1], duration=payout_duration, round_values=True) ani.start(stack.rect) self.animations.add(ani) center = self.game.chip_rack.rect.center for loss_pile in loss_piles: self.losses.append(loss_pile) for stack in loss_pile.stacks: ani = Animation(left=center[0], bottom=center[1], duration=payout_duration, round_values=True) ani.start(stack.rect) self.animations.add(ani) pay_ani = Task(self.game.player.chip_pile.add_chips, payout_duration, args=[payout]) remove_chips = Task(self.remove_chips, payout_duration) end_it = Task(self.end_state, total_ani_time) self.animations.add(pay_ani, remove_chips, end_it)