本文实例为大家分享了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