solitaire_03.py Full Listing#
solitaire_03.py#
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 | """ Solitaire clone. """ import arcade # Screen title and size SCREEN_WIDTH = 1024 SCREEN_HEIGHT = 768 SCREEN_TITLE = "Drag and Drop Cards" # Constants for sizing CARD_SCALE = 0.6 # How big are the cards? CARD_WIDTH = 140 * CARD_SCALE CARD_HEIGHT = 190 * CARD_SCALE # How big is the mat we'll place the card on? MAT_PERCENT_OVERSIZE = 1.25 MAT_HEIGHT = int(CARD_HEIGHT * MAT_PERCENT_OVERSIZE) MAT_WIDTH = int(CARD_WIDTH * MAT_PERCENT_OVERSIZE) # How much space do we leave as a gap between the mats? # Done as a percent of the mat size. VERTICAL_MARGIN_PERCENT = 0.10 HORIZONTAL_MARGIN_PERCENT = 0.10 # The Y of the bottom row (2 piles) BOTTOM_Y = MAT_HEIGHT / 2 + MAT_HEIGHT * VERTICAL_MARGIN_PERCENT # The X of where to start putting things on the left side START_X = MAT_WIDTH / 2 + MAT_WIDTH * HORIZONTAL_MARGIN_PERCENT # Card constants CARD_VALUES = ["A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"] CARD_SUITS = ["Clubs", "Hearts", "Spades", "Diamonds"] class Card(arcade.Sprite): """ Card sprite """ def __init__(self, suit, value, scale=1): """ Card constructor """ # Attributes for suit and value self.suit = suit self.value = value # Image to use for the sprite when face up self.image_file_name = f":resources:images/cards/card{self.suit}{self.value}.png" # Call the parent super().__init__(self.image_file_name, scale, hit_box_algorithm="None") class MyGame(arcade.Window): """ Main application class. """ def __init__(self): super().__init__(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE) # Sprite list with all the cards, no matter what pile they are in. self.card_list = None arcade.set_background_color(arcade.color.AMAZON) # List of cards we are dragging with the mouse self.held_cards = None # Original location of cards we are dragging with the mouse in case # they have to go back. self.held_cards_original_position = None def setup(self): """ Set up the game here. Call this function to restart the game. """ # List of cards we are dragging with the mouse self.held_cards = [] # Original location of cards we are dragging with the mouse in case # they have to go back. self.held_cards_original_position = [] # Sprite list with all the cards, no matter what pile they are in. self.card_list = arcade.SpriteList() # Create every card for card_suit in CARD_SUITS: for card_value in CARD_VALUES: card = Card(card_suit, card_value, CARD_SCALE) card.position = START_X, BOTTOM_Y self.card_list.append(card) def on_draw(self): """ Render the screen. """ # Clear the screen self.clear() # Draw the cards self.card_list.draw() def pull_to_top(self, card: arcade.Sprite): """ Pull card to top of rendering order (last to render, looks on-top) """ # Remove, and append to the end self.card_list.remove(card) self.card_list.append(card) def on_mouse_press(self, x, y, button, key_modifiers): """ Called when the user presses a mouse button. """ # Get list of cards we've clicked on cards = arcade.get_sprites_at_point((x, y), self.card_list) # Have we clicked on a card? if len(cards) > 0: # Might be a stack of cards, get the top one primary_card = cards[-1] # All other cases, grab the face-up card we are clicking on self.held_cards = [primary_card] # Save the position self.held_cards_original_position = [self.held_cards[0].position] # Put on top in drawing order self.pull_to_top(self.held_cards[0]) def on_mouse_release(self, x: float, y: float, button: int, modifiers: int): """ Called when the user presses a mouse button. """ # If we don't have any cards, who cares if len(self.held_cards) == 0: return # We are no longer holding cards self.held_cards = [] def on_mouse_motion(self, x: float, y: float, dx: float, dy: float): """ User moves mouse """ # If we are holding cards, move them with the mouse for card in self.held_cards: card.center_x += dx card.center_y += dy def main(): """ Main function """ window = MyGame() window.setup() arcade.run() if __name__ == "__main__": main() |