本文實例為大家分享了pygame實現雷電游戲開發代碼,供大家參考,具體內容如下
源代碼:
stars.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
|
#-*- coding=utf-8 -*- #!/usr/bin/python import pygame from pygame. locals import * from random import randint import math class star( object ): def __init__( self , x, y, speed, color = ( 255 , 255 , 255 )): self .x = x self .y = y self .speed = speed self .color = color class stars( object ): ''' 用于繪制星星背景 ''' def __init__( self , num = 0 , screen_size = ( 800 , 600 ), color = ( 255 , 255 , 255 )): self .stars = [] self .min_speed = 10 self .max_speed = 300 self .screen_size = screen_size if num > 0 : self .create_star(num, color) def set_min_speed( self ,speed): self .min_speed = speed def set_max_speed( self ,speed): self .max_speed = speed def create_star( self ,num = 1 , color = ( 255 , 255 , 255 )): '''創建一個或多個星星,顏色可選''' for i in xrange ( 0 ,num): x = float (randint( 0 , self .screen_size[ 0 ])) y = float (randint( 0 , self .screen_size[ 1 ])) speed = float (randint( self .min_speed, self .max_speed)) self .stars.append( star(x, y, speed, color) ) def move( self ,time_passed_seconds): '''移動星星并過濾''' for star in self .stars: star.y = star.y + time_passed_seconds * star.speed #過濾跑出畫面的星星 self .stars = filter ( lambda one: one.y< = self .screen_size[ 1 ], self .stars) def draw( self , surface): '''將星星畫到指定圖像對象''' for star in self .stars: #pygame.draw.aaline(surface, star.color,\ # (star.x, star.y), (star.x+1., star.y)) surface.set_at(( int (star.x), int (star.y)),star.color) def test(): pygame.init() screen = pygame.display.set_mode(( 800 , 600 )) #, fullscreen) stars = stars() #stars.set_max_speed(1000) #stars.set_min_speed(300) # 在第一幀,畫上一些星星 stars.create_star( 200 ) clock = pygame.time.clock() white = ( 255 , 255 , 255 ) while true: for event in pygame.event.get(): if event. type = = quit: return if event. type = = keydown: return time_passed = clock.tick( 30 ) time_passed_seconds = time_passed / 1000. #update_background(stars, screen, time_passed_seconds) # 增加一顆新的星星 stars.create_star( 1 ) stars.move(time_passed_seconds) screen.fill(( 0 , 0 , 0 )) # 繪制所有的星 stars.draw(screen) pygame.display.update() if __name__ = = "__main__" : test() |
game.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
|
#-*- coding=utf-8 -*- #!/usr/bin/python import pygame from pygame. locals import * from random import randint #from gameobjects import vector2 import math import time screen_rect = pygame.rect( 0 , 0 , 800 , 600 ) class player(pygame.sprite.sprite): '''玩家類''' speed = 10 images = [] def __init__( self ): pygame.sprite.sprite.__init__( self , self .containers) self .image = player.images[ 0 ] self .rect = self .image.get_rect(midbottom = screen_rect.midbottom) self .health = 4 #self.time = 0 #self.reloading = false #def update(self, time_passed_seconds=0.0): if not self.reloading: super(player,self).update(time_passed_seconds) else: self.time += time_passed_seconds if self.time > 1.5: print self.time self.time = 0.0 self.reloading = false self.groups()[0].remove(self) def move( self , directions): '''移動,direction == 'up' or 'down' or 'left' or 'right' ''' for direction in directions: if direction = = 'up' : self .rect.move_ip( 0 , - 1 * player.speed) elif direction = = 'down' : self .rect.move_ip( 0 , 1 * player.speed) elif direction = = 'left' : self .rect.move_ip( - 1 * player.speed, 0 ) elif direction = = 'right' : self .rect.move_ip( 1 * player.speed, 0 ) else : print 'argument error' return none self .rect.clamp_ip(screen_rect) def shoted_and_live( self , harm): '''被攻擊處理,依然存活返回true,否則返回false''' self .health - = harm if self .health < = 0 : return false else : return true def attack_pos( self ): return self .rect.x + self .rect.width / 2 , self .rect.y class shot(pygame.sprite.sprite): '''通用子彈類''' speed_tab = [ 13 , 13 , 26 , 30 ] #子彈攻擊力表 harm_tab = [ 1 , 2 , 3 , 12 ] images = [] #子彈大小表 shot_size = [] def __init__( self , pos, angle, id = 1 ): '''pos為射出位置 angle參數為子彈射出的方向角度,以12點鐘方向為0度,逆時針增大''' pygame.sprite.sprite.__init__( self , self .containers) self . id = id self .angle = angle self .speed = shot.speed_tab[ id - 1 ] self .harm = shot.harm_tab[ id - 1 ] self .image = pygame.transform.scale(shot.images[ id - 1 ], shot.shot_size[ id - 1 ]) self .image = pygame.transform.rotate( self .image, angle) self .rect = self .image.get_rect(midbottom = pos) def update( self ,time_passed_seconds = 0.0 ): radian = self .angle / 180.0 * math.pi self .rect.move_ip(math.sin(radian) * - self .speed,\ - self .speed * math.cos(radian) ) if self .rect.x + self .rect.width < 0 or \ self .rect.x > screen_rect.width or \ self .rect.y + self .rect.height < 0 or \ self .rect.y > screen_rect.height: self .kill() class alienshot(shot): ''' 敵方子彈類 為了對象分組專為敵人的子彈使用一個新類,并定制子彈射速 ''' def __init__( self , pos, angle, id = 1 , speed = 20 ): shot.__init__( self , pos, angle, id ) self .speed = speed def sectorshot(pos, shot_id): '''扇形子彈的封裝''' shot(pos, 0 , shot_id) shot(pos, 15 , shot_id) shot(pos, 30 , shot_id) shot(pos, 45 , shot_id) shot(pos, 315 ,shot_id) shot(pos, 330 ,shot_id) shot(pos, 345 ,shot_id) def commonshot(pos, shot_id): '''常規子彈''' shot(pos, 0 , shot_id) class alien(pygame.sprite.sprite): '''通用敵人類''' #默認速度表,速度為像素/秒 speed_tab = [ 400 , 200 , 200 ] images = [] #用于射擊間隔 times = [ 0.15 , 0.3 , 0.4 ] def __init__( self , id = 1 , health = 5 ): pygame.sprite.sprite.__init__( self , self .containers) self . id = id self .speed = alien.speed_tab[ id - 1 ] self .health = health self .image = alien.images[ id - 1 ] self .rect = self .image.get_rect() self .rect.topleft = (randint( 0 , screen_rect.width - self .rect.width), 0 ) self .move_tab = [ self .move_line, self .move_circle, self .move_curve ] #用于射擊的時間計算 self .time = 0.0 def update( self , time_passed_seconds = 0.0 ): self .move_tab[ self . id - 1 ](time_passed_seconds) if self .rect.x < 0 or self .rect.x > screen_rect.width or self .rect.y < 0 or self .rect.y > screen_rect.height: self .kill() self .time + = time_passed_seconds if self .time > alien.times[ self . id - 1 ]: self .time = 0.0 if self . id = = 1 : alienshot( self .attack_pos(), 180 , 1 , 30 ) elif self . id = = 2 : alienshot( self .attack_pos(), 120 , 1 , 10 ) alienshot( self .attack_pos(), 150 , 1 , 10 ) alienshot( self .attack_pos(), 180 , 1 , 10 ) alienshot( self .attack_pos(), 210 , 1 , 10 ) alienshot( self .attack_pos(), 240 , 1 , 10 ) elif self . id = = 3 : alienshot( self .attack_pos(), 180 , 2 , 10 ) def shoted_and_live( self , harm): '''被攻擊處理,依然存活返回true,否則返回false''' self .health - = harm if self .health < = 0 : return false else : return true def move_line( self , time_passed_seconds): self .rect.move_ip( 0 , self .speed * time_passed_seconds) def move_circle( self , time_passed_seconds): if not hasattr ( self , 'angle' ): self .angle = 180 else : self .angle = self .angle + time_passed_seconds * 360 if not hasattr ( self , 'radius' ): self .radius = 60 if not hasattr ( self , 'center' ): x = self .rect.x + self .radius if self .rect.x < self .radius else self .rect.x - self .radius self .center = [ x, 0 + self .radius] self .center[ 1 ] + = 2 new_pos = self .__circle_next( self .center, self .radius, self .angle) #self.rect.move_ip(new_pos[0], new_pos[1]) self .rect.x, self .rect.y = new_pos[ 0 ], new_pos[ 1 ] def __circle_next( self , center, radius, angle): x = math.sin(angle / 180.0 * math.pi) * radius + center[ 0 ] y = math.cos(angle / 180.0 * math.pi) * radius + center[ 1 ] return x, y def move_curve( self , time_passed_seconds): if not hasattr ( self , 'ray' ): self .ray = self .rect.x if not hasattr ( self , 'angle' ): self .angle = 0 else : self .angle = self .angle + time_passed_seconds * 360 if not hasattr ( self , 'curve_width' ): self .curve_width = 50 x = math.sin( self .angle / 180 * math.pi) * self .curve_width + self .ray y = self .rect.y + self .speed * time_passed_seconds self .rect.x, self .rect.y = x, y def attack_pos( self ): return self .rect.x + self .rect.width / 2 , self .rect.y + self .rect.height class explosion(pygame.sprite.sprite): '''爆炸類''' #用于存儲爆炸圖像每幀的坐標 areas = [\ ( 0 , 0 , 104 , 135 ), ( 104 , 0 , 104 , 135 ), ( 208 , 0 , 104 , 135 ),( 312 , 0 , 104 , 135 ),( 416 , 0 , 94 , 135 ),\ ( 0 , 135 , 102 , 112 ),( 102 , 135 , 102 , 112 ),( 204 , 135 , 102 , 112 ),( 306 , 135 , 102 , 112 ),( 408 , 135 , 102 , 112 ),\ ( 0 , 247 , 108 , 144 ),( 108 , 247 , 100 , 144 ),( 208 , 247 , 102 , 144 ),( 310 , 247 , 100 , 144 ),( 412 , 247 , 98 , 144 ),\ ( 0 , 400 , 95 , 100 ) ] images = [] def __init__( self , pos, id = 1 , areas = none): pygame.sprite.sprite.__init__( self , self .containers) self .pos = pos self .fps = 0 self .image_data = explosion.images[ id - 1 ] if areas is not none: self .areas = areas self .update() def update( self , time_passed_seconds = 0.0 ): self .rect = pygame.rect( self .areas[ self .fps]) self .image = self .image_data.subsurface(rect( self .areas[ self .fps])) self .rect.topleft = self .pos self .fps + = 1 if self .fps > = len ( self .areas): self .kill() class score(pygame.sprite.sprite): score = 0 health = 0 life = 0 def __init__( self , font_type = "文泉驛點陣正黑" ): pygame.sprite.sprite.__init__( self ) self .font = pygame.font.sysfont(font_type, 20 ) self .color = ( 255 , 255 , 255 ) self .msg = u "得分:%d\n生命:%d" self .update() self .rect = self .image.get_rect() self .rect.topleft = ( 10 , 10 ) def update( self , time_passed_seconds = 0.0 ): self .msg = u "生命:%d 得分:%d" % (score.life, score.score) self .image = self .font.render( self .msg, true, self .color) |
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
|
#-*- coding=utf-8 -*- #!/usr/bin/python import os import time import pygame from pygame. locals import * from random import randint import stars from game import * #默認星空的速度 default_stars_speed = ( 50 , 300 ) #子彈種數和當前子彈id,以及對應的子彈大小、發射頻率(個/秒) shot_num = 4 shot_id = 1 shot_size = [( 2 , 9 ), ( 16 , 16 ), ( 19 , 14 ), ( 99 , 120 )] shot_rate = [ 0.15 , 0.3 , 0.10 , 0.7 ] dest_area = [\ ( 0 , 0 , 104 , 135 ), ( 104 , 0 , 104 , 135 ), ( 208 , 0 , 104 , 135 ),( 312 , 0 , 104 , 135 ),( 416 , 0 , 104 , 135 ),\ ( 0 , 135 , 102 , 112 ),( 102 , 135 , 102 , 112 ),( 204 , 135 , 102 , 112 ),( 306 , 135 , 102 , 112 ),( 408 , 135 , 102 , 112 ),\ ( 0 , 247 , 108 , 144 ),( 108 , 247 , 100 , 144 ),( 208 , 247 , 102 , 144 ),( 310 , 247 , 100 , 144 ),( 412 , 247 , 98 , 144 ),\ ( 0 , 400 , 95 , 100 ) ] star_bmg = [] def update_background(stars, screen, time_passed_seconds): '''在指定圖像上生成一些星星并移動,繪制''' stars.create_star( 2 ,(randint( 0 , 255 ),randint( 0 , 255 ),randint( 0 , 255 ))) #stars.create_star(1,(255,255,255)) stars.move(time_passed_seconds) screen.fill(( 0 , 0 , 0 )) stars.draw(screen) #screen.blit(star_bmg[0],(100,100)) #screen.blit(star_bmg[1],(100,100)) def load_image( file , alpha = false): '''加載一張圖片,可指定是否為alpha轉換''' file = 'data/image/' + file try : surface = pygame.image.load( file ) except pygame.error: raise systemexit( '加載圖像 "%s" 失敗 %s' % ( file , pygame.get_error()) ) if alpha: return surface.convert_alpha() return surface.convert() def load_sound( file ): file = 'data/music/' + file try : sound = pygame.mixer.sound( file ) return sound except pygame.error: print ( '加載音樂 "%s" 失敗' % file ) return none def main(): global shot_id global star_bmg pygame.mixer.pre_init( 44100 , - 16 , 2 , 4096 ) pygame.init() screen = pygame.display.set_mode(( 800 , 600 )) #, fullscreen) #加載各種資源數據 image_list = os.listdir( 'data/image' ) image_list.sort() player.images = [ load_image( file ,true) for file in image_list if 'player' in file ] alien.images = [ pygame.transform.rotate(load_image( file ,true), 180 )\ for file in image_list if 'alien' in file ] shot.images = [ load_image( file ,true) for file in image_list if 'shot' in file ] star_bmg = [ load_image( file ,true) for file in image_list if 'star' in file ] shot.shot_size = shot_size shot_sound = load_sound( 'shot2.wav' ) explosion.images = [ load_image( file ,true) for file in image_list if 'explosion' in file ] explosion_sound1 = load_sound( 'explosion1.wav' ) explosion_sound2 = load_sound( 'explosion2.wav' ) change_shot_sound = load_sound( 'change_shot.wav' ) alarm_sound = load_sound( 'alarm.wav' ) #加載并播放bgm pygame.mixer.music.load( 'data/music/bgm01.ogg' ) pygame.mixer.music.play( - 1 ) # 初始化并生成一些星星 world = stars.stars( 200 ) world.set_min_speed(default_stars_speed[ 0 ]) world.set_max_speed(default_stars_speed[ 1 ]) #為各種游戲對象分組,all組存儲了所有游戲對象 shots = pygame.sprite.group() #玩家的子彈和敵人的子彈分成2組 alien_shots = pygame.sprite.group() aliens = pygame.sprite.group() explosions = pygame.sprite.group() all = pygame.sprite.group() player.containers = all alien.containers = aliens, all shot.containers = shots, all alienshot.containers = alien_shots, all explosion.containers = explosions, all player = player() #玩家生命數,重載標志和重載時間 life = 3 reloading = false reloading_time = 1.5 score.score = 0 score.life = life score = score() all .add(score) #無敵標志,重生后需要進入一段無敵時間 iamyourdaddy = false clock = pygame.time.clock() prev_time = 0.0 while life or len (explosions.sprites())> 0 : allkill = none for event in pygame.event.get(): if event. type = = quit: return if event. type = = keydown and event.key = = k_escape: return if event. type = = keydown: #處理子彈切換 if event.key = = k_tab: shot_id = shot_id % shot_num + 1 change_shot_sound.play() elif event.key = = k_x: for alien in aliens: alien.kill() explosion_sound2.play() explosion(alien.rect.topleft) for shot in alien_shots: shot.kill() explosion_sound2.play() explosion(shot.rect.topleft) keystate = pygame.key.get_pressed() time_passed = clock.tick( 30 ) time_passed_seconds = time_passed / 1000. update_background(world, screen, time_passed_seconds) #all.clear(screen, screen) all .update(time_passed_seconds) #處理方向控制 direct = [] if keystate[k_up]: direct.append( 'up' ) #模擬加速星空 world.set_min_speed(default_stars_speed[ 0 ] * 10 ) world.set_max_speed(default_stars_speed[ 1 ] * 2 ) if keystate[k_down]: direct.append( 'down' ) #模擬減速星空 world.set_min_speed( 10 ) world.set_max_speed(default_stars_speed[ 1 ] / 2 ) if keystate[k_left]: direct.append( 'left' ) if keystate[k_right]: direct.append( 'right' ) player.move(direct) #若不是上下則恢復默認速度 if not (keystate[k_up] or keystate[k_down]): world.set_min_speed(default_stars_speed[ 0 ]) world.set_max_speed(default_stars_speed[ 1 ]) #處理攻擊行為,用攻擊間隔控制頻率 if not reloading and keystate[k_space]: if time.time() - prev_time > shot_rate[shot_id - 1 ]: #第二個參數為射出角度,以12點鐘方向為0度逆時針變大 #shot(player.attack_pos(), 45, shot_id) if shot_id = = 1 : sectorshot(player.attack_pos(), shot_id) else : commonshot(player.attack_pos(), shot_id) shot_sound.play() #explosion(player.attack_pos()) prev_time = time.time() #隨機生成敵人,不同敵人血量不同 n = randint( 0 , 100 ) if n = = 1 : alien( 1 , 3 ) elif n = = 2 : alien( 2 , 5 ) elif n = = 3 : alien( 3 , 5 ) #處理玩家子彈與敵方的碰撞,碰撞字典鍵為第一個組的對象,值為第二個組的對象列表 collide_dict = pygame.sprite.groupcollide(aliens,shots,false,false) for alien in collide_dict: for shot in collide_dict[alien]: if shot_id! = 4 : shot.kill() explosion_sound1.play() harm = shot.harm if not alien.shoted_and_live(harm): score.score + = 1 alien.kill() explosion_sound2.play() explosion(alien.rect.topleft) #檢測無敵時間是否結束 if iamyourdaddy: wait + = time_passed_seconds if wait > 1.5 : iamyourdaddy = false wait = 0.0 #如果玩家處于重生中則不檢測玩家碰撞 if not reloading: #處理玩家與敵人的碰撞 for alien in pygame.sprite.spritecollide(player, aliens,true): explosion_sound2.play() explosion(alien.rect.topleft) if iamyourdaddy: pass else : alarm_sound.play( 2 ) explosion(player.rect.topleft) score.score + = 1 score.life - = 1 player.kill() reloading = true wait = 0.0 life - = 1 if not reloading: #處理玩家與敵方子彈的碰撞 for shot in pygame.sprite.spritecollide(player, alien_shots, true): explosion_sound1.play() harm = shot.harm if iamyourdaddy: pass elif not player.shoted_and_live(harm): alarm_sound.play( 2 ) explosion_sound2.play() explosion(player.rect.topleft) score.life - = 1 player.kill() reloading = true wait = 0.0 life - = 1 #處理子彈與子彈的碰撞 if shot_id = = 4 : collide_dict = pygame.sprite.groupcollide(alien_shots,shots,true,false) for alien_shot in collide_dict: explosion_sound2.play() explosion(alien_shot.rect.topleft) #死亡后重置玩家,生命數-1 if reloading: wait + = time_passed_seconds if wait > reloading_time: reloading = false player = player() wait = 0.0 #進入無敵模式 iamyourdaddy = true # 增加一顆新的星星 #stars.create_star(1) #stars.move(time_passed_seconds) #screen.fill((0, 0, 0)) # 繪制所有的星 #stars.draw(screen) #screen.blit(image,(300,300)) all .draw(screen) pygame.display.update() #繪制結束畫面 #設置字體 font = pygame.font.sysfont( "文泉驛點陣正黑" , 80 ) end = font.render(u "you lost!!!" , true, ( 255 , 0 , 0 )) screen.blit(end, ( 180 , 270 )) pygame.display.update() time.sleep( 2.5 ) if __name__ = = "__main__" : main() |
測試畫面:
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。
原文鏈接:https://blog.csdn.net/xiaokint3/article/details/14497733