章节演示2#

sections_demo_2.py#
1"""
2Section Example 2:
3
4In this Section example we develop a very basic Pong game playable by two
5persons in the same computer (hot seat!).
6
7Each Player is abstracted as a Section that consists of a space in the screen
8where the player paddle can move.
9
10Note:
11 - Sections can live along with Views. Sections do not need to occupy 100%
12 of the screen.
13 - View methods can interact with Sections by storing a reference to each
14 one.
15 - How keyboard events can be redirected to each section depending on the
16 pressed key automatically.
17
18If Python and Arcade are installed, this example can be run from the command line with:
19python -m arcade.examples.sections_demo_2
20"""
21import random
22
23import arcade
24from arcade.color import BLACK, BLUE, RED, BEAU_BLUE, GRAY
25from arcade.key import W, S, UP, DOWN
26
27PLAYER_SECTION_WIDTH = 100
28PLAYER_PADDLE_SPEED = 10
29
30
31class Player(arcade.Section):
32 """
33 A Section representing the space in the screen where the player
34 paddle can move
35 """
36
37 def __init__(self, left: int, bottom: int, width: int, height: int,
38 key_up: int, key_down: int, **kwargs):
39 super().__init__(left, bottom, width, height, accept_keyboard_keys={key_up, key_down}, **kwargs)
40
41 # keys assigned to move the paddle
42 self.key_up: int = key_up
43 self.key_down: int = key_down
44
45 # the player paddle
46 self.paddle: arcade.SpriteSolidColor = arcade.SpriteSolidColor(30, 100, color=BLACK)
47
48 # player score
49 self.score: int = 0
50
51 def setup(self):
52 # reset the player paddle position to the middle of the screen
53 self.paddle.position = self.left + 50, self.height / 2
54
55 def on_update(self, delta_time: float):
56 # update the paddle position
57 self.paddle.update()
58
59 def on_draw(self):
60 # draw sections info and score
61 if self.name == 'Left':
62 keys = 'W and S'
63 start_x = self.left + 5
64 else:
65 keys = 'UP and DOWN'
66 start_x = self.left - 290
67 arcade.draw_text(
68 f'Player {self.name} (move paddle with: {keys})',
69 start_x, self.top - 20, BLUE, 9,
70 )
71 arcade.draw_text(
72 f'Score: {self.score}', self.left + 20,
73 self.bottom + 20, BLUE,
74 )
75
76 # draw the paddle
77 self.paddle.draw()
78
79 def on_key_press(self, symbol: int, modifiers: int):
80 # set the paddle direction and movement speed
81 if symbol == self.key_up:
82 self.paddle.change_y = PLAYER_PADDLE_SPEED
83 else:
84 self.paddle.change_y = -PLAYER_PADDLE_SPEED
85
86 def on_key_release(self, _symbol: int, _modifiers: int):
87 # stop moving the paddle
88 self.paddle.stop()
89
90
91class Pong(arcade.View):
92
93 def __init__(self):
94 super().__init__()
95
96 # a sprite list that will hold each player paddle to
97 # check for collisions
98 self.paddles: arcade.SpriteList = arcade.SpriteList()
99
100 # we store each Section
101 self.left_player: Player = Player(
102 0, 0, PLAYER_SECTION_WIDTH, self.window.height, key_up=W,
103 key_down=S, name='Left')
104 self.right_player: Player = Player(
105 self.window.width - PLAYER_SECTION_WIDTH, 0, PLAYER_SECTION_WIDTH,
106 self.window.height, key_up=UP, key_down=DOWN, name='Right')
107
108 # add the sections to the SectionManager so Sections start to work
109 self.add_section(self.left_player)
110 self.add_section(self.right_player)
111
112 # add each paddle to the sprite list
113 self.paddles.append(self.left_player.paddle)
114 self.paddles.append(self.right_player.paddle)
115
116 # create the ball
117 self.ball: arcade.SpriteCircle = arcade.SpriteCircle(20, RED)
118
119 def setup(self):
120 # set up a new game
121
122 # set ball position in the middle
123 self.ball.position = self.window.width / 2, self.window.height / 2
124
125 # randomize ball direction and speed
126 self.ball.change_x = random.choice([-3, -2, 3, 2])
127 self.ball.change_y = random.choice([-3, -2, 3, 2])
128
129 # setup player paddles
130 self.left_player.setup()
131 self.right_player.setup()
132
133 def on_update(self, delta_time: float):
134 self.ball.update() # update the ball
135
136 # bounce the ball either at the top or at the bottom
137 if self.ball.bottom <= 0:
138 self.ball.change_y *= -1
139 elif self.ball.top >= self.window.height:
140 self.ball.change_y *= -1
141
142 # check if the ball has collided with a paddle
143 collided_paddle = self.ball.collides_with_list(self.paddles)
144 if collided_paddle:
145 # adjust ball coordinates to simplify the game
146 if collided_paddle[0] is self.left_player.paddle:
147 self.ball.left = self.left_player.paddle.right
148 else:
149 self.ball.right = self.right_player.paddle.left
150
151 # bounce the ball from the paddle
152 self.ball.change_x *= -1
153
154 # check if the ball has exited the screen in either side and
155 # end the game
156 if self.ball.right <= 0:
157 self.end_game(self.right_player)
158 elif self.ball.left >= self.window.width:
159 self.end_game(self.left_player)
160
161 def end_game(self, winner: Player):
162 """ Called when one player wins """
163 winner.score += 1 # increment the winner score
164 self.setup() # prepare a new game
165
166 def on_draw(self):
167 self.clear(color=BEAU_BLUE) # clear the screen
168
169 self.ball.draw() # draw the ball
170
171 half_window_x = self.window.width / 2 # middle x
172
173 # draw a line diving the screen in half
174 arcade.draw_line(half_window_x, 0, half_window_x, self.window.height, GRAY, 2)
175
176
177def main():
178 # create the window
179 window = arcade.Window(title='Two player simple Pong with Sections!')
180
181 # create the custom View
182 game = Pong()
183
184 # set up the game (start a game)
185 game.setup()
186
187 # show the view
188 window.show_view(game)
189
190 # run arcade loop
191 window.run()
192
193
194if __name__ == '__main__':
195 main()