【python】10分钟教你⽤Python做个打飞机⼩游戏超详细教程
整体框架
开始之前-精灵类Sprite
⼦弹类class Bullet
玩家飞机类class Player
敌机类class Enemy
游戏主体循环以及帧率设置
让⼦弹飞
刷出敌机 打怪
把飞机敌机⼦弹都画出来
处理键盘事件
分数显⽰ 和 GameOver
最终代码
这次还是⽤python的pygame库来做的游戏。关于这个库的内容,读者可以上⽹了解⼀下。本⽂只讲解⽤到的知识。代码参考⾃⽹上,⾃⼰也做了⼀点代码简化。尽量把最核⼼的⽅⾯⽤最简单的⽅式呈现给⼤家,让⼤家尽快掌握这个游戏的框架。⾄于那些华丽的功能,⼤家在弄懂了核⼼知识以后,再去添加也是⾮常easy的。
这个游戏设计⽤到了⾯向对象的编程思想。
游戏主体划分为三个主要的类:
⼦弹类class Bullet
玩家类class Player
敌机类class Enemy
在屏幕上可见的也就是这三个东西了。⾃⼰的飞机、敌⼈的飞机、⼦弹。因此整个游戏的核⼼就是:
把这三个东西的图像呈现在屏幕上。
判断和处理⼦弹撞击敌机和敌机撞击玩家这两种情况。
下⾯我们会展开为⼤家⼀⼀讲解。
在下⾯的代码中,你们会⼤量见到这个pygame.sprite模块。这⾥就给⼤家介绍⼀下。“sprite”,中⽂翻译“精灵”,在游戏动画⼀般是指⼀个独⽴运动的画⾯元素,在pygame中,就可以是⼀个带有图像(Surface)和⼤⼩位置(Rect)的对象。 简单来说是⼀个会动图
⽚。它的两个成员变量
self.image=要显⽰图⽚的Surface
< = 显⽰Surface的区域
对于,常⽤的设置rect的⽅法: = _rect()。然后设定pleft=(0,0)来设定左上⾓的位置,从⽽设定这个精灵在屏幕上的显⽰位置。精灵特别适合⽤在OO语⾔中,⽐如Python。
pygame.sprite.Sprite是pygame精灵的基类,⼀般来说,你总是需要写⼀个⾃⼰的精灵类继承⼀下它然后加⼊⾃⼰的代码。
关于此类的其他函数,咱们⽤到的时候会详细跟⼤家说的。
先来看代码吧。
1# ⼦弹类
2class Bullet(pygame.sprite.Sprite):
3def __init__(self, bullet_img, init_pos):
4 pygame.sprite.Sprite.__init__(self)
5 self.image = bullet_img
6 = _rect()
7 idbottom = init_pos
8 self.speed = 10
9
10def move(self):
11 p -= self.speed
⼦弹类继承于pygame.sprite.Sprite, 成员主要是⼦弹的图⽚对象和⼦弹刷出来的位置,当然,还有移动速度。⼀个⽅法就是移动,从发出位置直线往屏幕上⽅移动。
⽼样⼦。先看代码
1# 玩家飞机类
2class Player(pygame.sprite.Sprite):
3def __init__(self, plane_img, player_rect, init_pos):
4 pygame.sprite.Sprite.__init__(self)
5 self.image = [] # ⽤来存储玩家飞机图⽚的列表
6for i in range(len(player_rect)):
7 self.image.append(plane_img.subsurface(player_rect[i]).convert_alpha())
8 = player_rect[0] # 初始化图⽚所在的矩形
9 pleft = init_pos # 初始化矩形的左上⾓坐标
10 self.speed = 8# 初始化玩家飞机速度,这⾥是⼀个确定的值
11 self.bullets = pygame.sprite.Group() # 玩家飞机所发射的⼦弹的集合
12 self.is_hit = False# 玩家是否被击中
13
14# 发射⼦弹
15def shoot(self, bullet_img):
16 bullet = Bullet(bullet_img, idtop)
17 self.bullets.add(bullet)
18
19# 向上移动,需要判断边界
20def moveUp(self):
op <= 0:
22 p = 0
23else:
24 p -= self.speed
25
26# 向下移动,需要判断边界
27def moveDown(self):
op >= SCREEN_HEIGHT - height:
29 p = SCREEN_HEIGHT - height
30else:
31 p += self.speed
32
33# 向左移动,需要判断边界
34def moveLeft(self):
left <= 0:
36 left = 0
37else:
38 left -= self.speed
39
40# 向右移动,需要判断边界
41def moveRight(self):
left >= SCREEN_WIDTH - width:
43 left = SCREEN_WIDTH - width
44else:
45 left += self.speed
⽼样⼦,成员变量主要还是那⼏个。图像对象以及矩形参数和刷出位置,当然还会有移动速度和⼦弹集合(⽤来保存飞机射出的⼦弹)。⽅法的话就是上下左右移动了,不过需要做好边界判断。这个直接看代码就能理解了。
好吧,先上代码伺候。
1# 敌机类
2class Enemy(pygame.sprite.Sprite):
3def __init__(self, enemy_img, enemy_down_imgs, init_pos):
4 pygame.sprite.Sprite.__init__(self)
5 self.image = enemy_img #正常的图像
6 = _rect()
7 pleft = init_pos
8 self.down_imgs = enemy_down_imgs # 爆炸的图像
9 self.speed = 2
10
11# 敌机移动,边界判断及删除在游戏主循环⾥处理
12def move(self):
13 p += self.speed
需要注意的时候,该类保存了两个图像对象,⼀个是正常情况下的敌机图像。⼀个是爆炸的敌机图像。以便在撞击时能把撞击效果显⽰出来。⼀个⽅法就是和⼦弹差不多的移动了,不过它是从屏幕上⽅往底下移动的⽽已。然后刷出位置的话,后⾯我们会⽤⼀个随机函数⽣成的。
游戏主体的话,我们直接开⼀个死循环来不断刷新显⽰上⾯介绍的三个对象。代码设计如下:
1# 游戏循环帧率设置
2clock = pygame.time.Clock()
3
4# 判断游戏循环退出的参数
5running = True
6
7# 游戏主循环
8while running:
9# 控制游戏最⼤帧率为 60
10 clock.tick(60)
11
12 ……游戏运⾏部分
关于pygame.time.Clock(),贪吃蛇那篇已经介绍过了。就是⽤来控制游戏帧率的。只要我们的玩家飞机没有被敌机撞到,即属于存活状态时。running将⼀直为真。
在running循环⾥⾯,我们要做的是不断⾃动刷出⼦弹。当然,⼦弹是从玩家飞机上射出来的。
⾸先是发射⼦弹
1# ⽣成⼦弹,需要控制发射频率
2# ⾸先判断玩家飞机没有被击中
3# 循环15次发射⼀个⼦弹
4if not player.is_hit:
5if shoot_frequency % 15 == 0:
6 player.shoot(bullet_img)
7 shoot_frequency += 1
8if shoot_frequency >= 15:
9 shoot_frequency = 0
shoot_frequency变量的作⽤就是控制⼦弹发射的频率,它控制在running每循环15次发射⼀个⼦弹。
接着是⼦弹移动
1for bullet in player.bullets:
2# 以固定速度移动⼦弹
4# 移动出屏幕后删除⼦弹
bottom < 0:
6 ve(bullet)
⼦弹移动的话,running每循环⼀次,就move⼀下。不过要注意当⼦弹移动出屏幕后删除。不然可能会爆电脑内存。
和⼦弹类似的,在running循环⾥,随机刷出敌机。
先是刷怪
1# ⽣成敌机,需要控制⽣成频率
2# 循环50次⽣成⼀架敌机
3if enemy_frequency % 50 == 0:
4 enemy1_pos = [random.randint(0, SCREEN_WIDTH - enemy1_rect.width), 0]
5 enemy1 = Enemy(enemy1_img, enemy1_down_imgs, enemy1_pos)
6 enemies1.add(enemy1)
7enemy_frequency += 1
8if enemy_frequency >= 100:
9 enemy_frequency = 0
enemy_frequency变量的作⽤同样是控制刷怪的频率。running每循环50次就刷⼀个怪出来,位置是randint函数随机⽣成的。
接着让怪移动
1for enemy in enemies1:
2#2. 移动敌机
3 ve()
4#4. 移动出屏幕后删除敌⼈
op < 0:
6 ve(enemy)
移动的话也很简单,每running循环⼀次就move⼀次就⾏。但是还是注意。敌机移出屏幕后要删除,避免爆内存啊。
然后是碰撞检测
1#3. 敌机与玩家飞机碰撞效果处理
2if llide_circle(enemy, player):
3 enemies_down.add(enemy)
4 ve(enemy)
5 player.is_hit = True
6break
这⾥介绍⼀下llide_circle,这个函数的作⽤是判断两个精灵对象有没有碰撞。如果敌机和玩家飞机装上了,那很明显GameOver了。直接把running循环给break就⾏了。
前⾯说了这么多,最终我们还是要把这三个主要的对象画到屏幕上显⽰出来,然后通过每⼀次running循环更新它们的状态(正常?撞击?爆炸?)。
1#敌机被⼦弹击中效果处理
2#将被击中的敌机对象添加到击毁敌机 Group 中
3enemies1_down = upcollide(enemies1, player.bullets, 1, 1)
4for enemy_down in enemies1_down:
5 enemies_down.add(enemy_down)
6
7# 绘制背景
8screen.fill(0)
9screen.blit(background, (0, 0))
10
11# 绘制玩家飞机
12if not player.is_hit:
13 screen.blit(player.image[0], ) #将正常飞机画出来
14else:
15# 玩家飞机被击中后的效果处理
16 screen.blit(player.image[1], ) #将爆炸的飞机画出来
17 running = False
18
19# 敌机被⼦弹击中效果显⽰
20for enemy_down in enemies_down:
21 ve(enemy_down)
22 score += 1
23 screen.blit(enemy_down.down_imgs, ) #将爆炸的敌机画出来
24
25
26# 显⽰⼦弹
27 player.bullets.draw(screen)
28# 显⽰敌机
29 enemies1.draw(screen)
python安装教程非常详细
注意的是,玩家飞机和敌机都有两种状态,⼀种是正常状态,另外⼀种是爆炸状态。在画之前要判断清楚再下⼿。然后再介绍⼀下upcollide函数,这个函数是判断两个精灵组⾥⾯的精灵有没有相互碰撞的。它会把A组的精灵逐个和B组的精灵进⾏⽐较判断。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论