-
Notifications
You must be signed in to change notification settings - Fork 17
/
Copy pathplane_main.py
338 lines (283 loc) · 11.4 KB
/
plane_main.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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
import sys
import pygame
pygame.init()
from plane_sprites import *
# **************************************************************
# FileName: plane_main.py***************************************
# Author: Junieson *********************************************
# Version: 2019.8.12 ******************************************
# ****************************************************************
class PlaneGame(object):
"""飞机大战主游戏"""
def __init__(self):
print("游戏初始化")
# 1. 创建游戏的窗口
self.screen = pygame.display.set_mode(SCREEN_RECT.size)
# 创建结束界面
self.canvas_over = CanvasOver(self.screen)
# 2. 创建游戏的时钟
self.clock = pygame.time.Clock()
# 3. 调用私有方法,精灵和精灵组的创建
self.__create_sprites()
# 分数对象
self.score = GameScore()
# 程序控制指针
self.index = 0
# 音乐bgm
self.bg_music = pygame.mixer.Sound("./music/game_music.ogg")
self.bg_music.set_volume(0.3)
self.bg_music.play(-1)
# 游戏结束了吗
self.game_over = False
# 4. 设置定时器事件 - 创建敌机 1s
pygame.time.set_timer(CREATE_ENEMY_EVENT, random.randint(1000, 2000))
pygame.time.set_timer(HERO_FIRE_EVENT, 400)
pygame.time.set_timer(BUFF1_SHOW_UP, random.randint(10000, 20000))
pygame.time.set_timer(BUFF2_SHOW_UP, random.randint(20000, 40000))
pygame.time.set_timer(ENEMY_FIRE_EVENT, 2000)
def __create_sprites(self):
# 创建背景精灵和精灵组
bg1 = Background()
bg2 = Background(True)
self.back_group = pygame.sprite.Group(bg1, bg2)
# 创建敌机的精灵组
self.enemy_group = pygame.sprite.Group()
# 创建英雄的精灵和精灵组
self.hero = Hero()
self.hero_group = pygame.sprite.Group(self.hero)
# 创建敌军子弹组
self.enemy_bullet_group = pygame.sprite.Group()
# 血条列表
self.bars = []
self.bars.append(self.hero.bar)
# 创建buff组
self.buff1_group = pygame.sprite.Group()
# 创建假象boom组
self.enemy_boom = pygame.sprite.Group()
# bomb列表
self.bombs = []
def start_game(self):
print("游戏开始...")
while True:
# 1. 设置刷新帧率
self.clock.tick(FRAME_PER_SEC)
# 2. 事件监听
self.__event_handler()
# 3. 碰撞检测
self.__check_collide()
# 4. 更新/绘制精灵组
self.__update_sprites()
# 是否要结束游戏
if self.game_over:
self.canvas_over.update()
# 5. 更新显示
pygame.display.update()
def __event_handler(self): # 事件检测
if self.score.getvalue() > 200+500*self.index:
self.boss = Boss()
self.enemy_group.add(self.boss)
self.bars.append(self.boss.bar)
self.index += 1
for event in pygame.event.get():
# 判断是否退出游戏
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == CREATE_ENEMY_EVENT:
# 创建敌机精灵将敌机精灵添加到敌机精灵组
if self.score.getvalue() < 20:
enemy = Enemy()
else:
if random.randint(0, 100) % 4:
enemy = Enemy()
else:
enemy = Enemy(2)
self.enemy_group.add(enemy)
self.bars.append(enemy.bar)
elif event.type == HERO_FIRE_EVENT:
for hero in self.hero_group:
hero.fire()
elif event.type == BUFF1_SHOW_UP:
buff1 = Buff1()
self.buff1_group.add(buff1)
elif event.type == BUFF2_SHOW_UP:
if self.hero.bar.color == color_red:#按需分配
buff = Buff3()
else:
buff= Buff2()
self.buff1_group.add(buff)
elif event.type == ENEMY_FIRE_EVENT:
for enemy in self.enemy_group:
if enemy.number >= 2:
enemy.fire()
for bullet in enemy.bullets:
self.enemy_bullet_group.add(bullet)
elif event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE:
self.bomb_throw()
else:
if self.game_over == True:
flag = self.canvas_over.event_handler(event)
if flag == 1:
self.__start__()
elif flag == 0:
pygame.quit()
sys.exit()
# 使用键盘提供的方法获取键盘按键 - 按键元组
keys_pressed = pygame.key.get_pressed()
# 判断元组中对应的按键索引值 1
if keys_pressed[pygame.K_RIGHT]:
self.heros_move(5)
elif keys_pressed[pygame.K_LEFT]:
self.heros_move(-5)
elif keys_pressed[pygame.K_UP]:
self.heros_move(0, -5)
elif keys_pressed[pygame.K_DOWN]:
self.heros_move(0, 5)
else:
self.heros_move(0, 0)
def heros_move(self, x=0, y=0):
self.hero.speedx = x
self.hero.speedy = y
def bomb_throw(self):
music_use_bomb = pygame.mixer.Sound("./music/use_bomb.wav")
if self.hero.bomb > 0:
music_use_bomb.play()
self.hero.bomb -= 1
self.bombs.pop()
for enemy in self.enemy_group:
if enemy.number < 3:
enemy.bar.length = 0
enemy.isboom = True
else:
enemy.injury = 20
enemy.isboom = True
def __check_collide(self):
# 1. 子弹摧毁敌机
for enemy in self.enemy_group:
for hero in self.hero_group:
for bullet in hero.bullets:
if pygame.sprite.collide_mask(bullet, enemy): # 这种碰撞检测可以精确到像素去掉alpha遮罩的那种哦
bullet.kill()
enemy.injury = bullet.hity
enemy.isboom = True
if enemy.bar.length <= 0:
self.enemy_group.remove(enemy)
self.enemy_boom.add(enemy)
# 2. 敌机撞毁英雄
for enemy in self.enemy_group:
if pygame.sprite.collide_mask(self.hero, enemy):
if enemy.number < 3:
enemy.bar.length = 0 # 敌机直接死
self.hero.injury = self.hero.bar.value / 4 # 英雄掉四分之一的血
if self.hero.buff1_num > 0:
self.hero.buff1_num -= 1
self.hero.music_degrade.play()
self.enemy_group.remove(enemy)
self.enemy_boom.add(enemy)
enemy.isboom = True
else:
self.hero.bar.length = 0
self.hero.isboom = True
# 子弹摧毁英雄
for bullet in self.enemy_bullet_group:
if pygame.sprite.collide_mask(self.hero, bullet):
bullet.kill()
self.hero.injury = 1
if self.hero.buff1_num > 0:
self.hero.music_degrade.play()
if self.hero.buff1_num == 5:
self.mate1.kill()
self.mate2.kill()
self.hero.buff1_num -= 1
self.hero.isboom = True
if not self.hero.alive():
self.hero.rect.right = -10 # 把英雄移除屏幕
if self.hero.buff1_num == 5:
self.mate1.rect.right = -10
self.mate2.rect.right = -10
self.game_over = True
# 3.buff吸收
for buff in self.buff1_group:
if pygame.sprite.collide_mask(self.hero, buff):
buff.music_get.play()
if buff.speedy == 1: # 用速度来区分
if self.hero.buff1_num < 6:
self.hero.buff1_num += 1
self.hero.music_upgrade.play()
if self.hero.buff1_num == 5:
self.team_show()
elif buff.speedy==2:
self.hero.bomb += 1
image = pygame.image.load("./images/bomb.png")
self.bombs.append(image)
elif buff.speedy==3:
if self.hero.bar.length < self.hero.bar.weight*self.hero.bar.value:
self.hero.bar.length += self.hero.bar.weight*self.hero.bar.value
buff.kill()
def team_show(self):
self.mate1 = Heromate(-1)
self.mate2 = Heromate(1)
self.mate1.image = pygame.image.load("./images/life.png")
self.mate1.rect = self.mate1.image.get_rect()
self.mate2.image = pygame.image.load("./images/life.png")
self.mate2.rect = self.mate2.image.get_rect()
self.hero_group.add(self.mate1)
self.hero_group.add(self.mate2)
# 各种更新
def __update_sprites(self):
self.back_group.update()
self.back_group.draw(self.screen)
self.enemy_group.update()
self.enemy_group.draw(self.screen)
self.enemy_boom.update()
self.enemy_boom.draw(self.screen)
self.heros_update()
self.hero_group.draw(self.screen)
for hero in self.hero_group:
hero.bullets.update()
hero.bullets.draw(self.screen)
self.buff1_group.update()
self.buff1_group.draw(self.screen)
self.bars_update()
self.bombs_update()
self.enemy_bullet_group.update()
self.enemy_bullet_group.draw(self.screen)
self.score_show()
def heros_update(self):
for hero in self.hero_group:
if hero.number == 1:
hero.rect.bottom = self.hero.rect.bottom
hero.rect.left = self.hero.rect.right
if hero.number == -1:
hero.rect.bottom = self.hero.rect.bottom
hero.rect.right = self.hero.rect.left
hero.update()
def bars_update(self):
for bar in self.bars:
if bar.length > 0:
bar.update(self.screen)
else:
self.bars.remove(bar)
def bullet_enemy_update(self):
for enemy in self.enemy_group:
enemy.bullets.update()
enemy.bullets.draw(self.screen)
def bombs_update(self):
i = 1
for bomb in self.bombs:
self.screen.blit(bomb, (0, 700 - (bomb.get_rect().height) * i))
i += 1
def score_show(self):
score_font = pygame.font.Font("./STCAIYUN.ttf", 33)
image = score_font.render("SCORE:" + str(int(self.score.getvalue())), True, color_gray)
rect = image.get_rect()
rect.bottom, rect.right = 700, 480
self.screen.blit(image, rect)
@staticmethod
def __start__():
# 创建游戏对象
game = PlaneGame()
# 启动游戏
game.start_game()
if __name__ == '__main__':
PlaneGame.__start__()