![cover](https://img-blog.csdnimg.cn/img_convert/4a80d0f5c62e5bd00e9dd744d62c29e9.png)
用Python开发一个飞机大战游戏(附源码教程)
Python是一门非常简单的语言,快速入门之后可以做很多事情!比如爬虫啊,数据分析啊,自动化运维啊,机器学习,量化分析等等!但是入门到进阶的过程有时会非常痛苦,如果有一些好玩有趣的例子就好了。比如通过游戏来学编程是一个非常好的途径,今天强哥就来写一个非常好玩的打飞机游戏,大概就1000多行,非常不错!打飞机的游戏估计很多人都玩过,雷霆战机相信很多80后的小伙伴都玩过!Python是一门非常简单的语
点击蓝字 关注我们
Python是一门非常简单的语言,快速入门之后可以做很多事情!比如爬虫啊,数据分析啊,自动化运维啊,机器学习,量化分析等等!但是入门到进阶的过程有时会非常痛苦,如果有一些好玩有趣的例子就好了。
比如通过游戏来学编程是一个非常好的途径,今天强哥就来写一个非常好玩的打飞机游戏,大概就1000多行,非常不错!
1、打飞机的游戏
打飞机的游戏估计很多人都玩过,雷霆战机相信很多80后的小伙伴都玩过!
Python是一门非常简单的语言,快速入门之后可以做很多事情!比如爬虫啊,数据分析啊,自动化运维啊,机器学习,量化分析等等!
但是入门到进阶的过程有时会非常痛苦,如果有一些好玩有趣的例子就好了。比如通过游戏来学编程是一个非常好的途径
2、代码讲解
1.代码的结构
2.游戏的角色文件
gameRole 整个游戏分三个角色,下面我一一来解释一下,思路其实非常清晰的。
1)一个是子弹
初始化子弹的图片,然后得到它在画布上的坐标,并控制它的移动速度
2)敌机
会随机出一堆敌人的飞机,直管往前冲,从屏幕的上方往下方蜂拥而至,不需要考虑其他的行为!
敌机有几个重要的属性,比如它的飞行图片和击落的图片,然后获取的屏幕上的坐标。敌机的行为就一个飞,而且是只会往前飞。
3)我方战机
玩家类class Player(pygame.sprite.Sprite):` `def __init__(self, plane_img, player_rect, init_pos):` `pygame.sprite.Sprite.__init__(self)` `self.image = [] # 用来存储玩家对象精灵图片的列表` `for i in range(len(player_rect)):` `self.image.append(plane_img.subsurface(player_rect[i]).convert_alpha())` `self.rect = player_rect[0] # 初始化图片所在的矩形` `self.rect.topleft = init_pos # 初始化矩形的左上角坐标` `self.speed = 8 # 初始化玩家速度,这里是一个确定的值` `self.bullets = pygame.sprite.Group() # 玩家飞机所发射的子弹的集合` `self.img_index = 0 # 玩家精灵图片索引` `self.is_hit = False # 玩家是否被击中
def shoot(self, bullet_img):
bullet = Bullet(bullet_img, self.rect.midtop)
self.bullets.add(bullet) ` `def moveUp(self):` `if self.rect.top <= 0:` `self.rect.top = 0` `else:` `self.rect.top -= self.speed
def moveDown(self):
if self.rect.top >= SCREEN_HEIGHT - self.rect.height:
self.rect.top = SCREEN_HEIGHT - self.rect.height
else:
self.rect.top += self.speed ` `def moveLeft(self):` `if self.rect.left <= 0:` `self.rect.left = 0` `else:` `self.rect.left -= self.speed
def moveRight(self):
if self.rect.left >= SCREEN_WIDTH - self.rect.width:
self.rect.left = SCREEN_WIDTH - self.rect.width
else:
self.rect.left += self.speed
我方的战机稍微复杂一点,它有这么几个主要的属性,飞行的图片,被击落的图片,屏幕坐标,它的子弹等等!然后我们需要控制它的飞机方向,向上,向下,左边和右边,发射子弹。
完整代码请添加小助手获取哦,有什么不懂的问题也可以随时咨询~
请长按扫码添加小助手
3.主游戏部分文件mainGame
1)先是初始化游戏的界面大小,字体等等,读取声音和图片和基本配置:
class HeroPlane(BasePlane):
global supply_size ` `def __init__(self, screen_temp):` `BasePlane.__init__(self, 3, screen_temp, 210, 728, "./feiji/hero1.png", 4, HP_list[3]) # super().__init__()` `BasePlane.crate_images(self, "hero_blowup_n")` `self.key_down_list = [] # 用来存储键盘上下左右移动键` `self.space_key_list = [] # 保存space键` `self.is_three_bullet = False` `self.barrel_2 = [] # 2号炮管(左)` `self.barrel_3 = [] # 3号炮管(右)` `self.three_bullet_stock = 50 # 三管齐发子弹初始值为50
# 单键移动方向
def move_left(self):
self.x -= 7 ` `def move_right(self):` `self.x += 7
def move_up(self):
self.y -= 6 ` `def move_down(self):` `self.y += 6
# 双键移动方向
def move_left_and_up(self):
self.x -= 5
self.y -= 6 ` `def move_right_and_up(self):` `self.x += 5` `self.y -= 6
def move_lef_and_down(self):
self.x -= 5
self.y += 6 ` `def move_right_and_down(self):` `self.x += 5` `self.y += 6
# 控制飞机左右移动范围s
def move_limit(self):
if self.x < 0:
self.x = -2
elif self.x + 100 > 480:
self.x = 380
if self.y > 728:
self.y = 728
elif self.y < 350:
self.y += 6 ` `# 键盘按下向列表添加按键` `def key_down(self, key):` `self.key_down_list.append(key)
# 键盘松开向列表删除按键
def key_up(self, key):
if len(self.key_down_list) != 0: # 判断是否为空
try:
self.key_down_list.remove(key)
except Exception:
pass ` `# 控制hero的持续移动` `def press_move(self):` `if len(self.key_down_list) != 0:` `if len(self.key_down_list) == 2: # 两个键` `if (self.key_down_list[0] == K_LEFT and self.key_down_list[1] == K_UP) or (` `self.key_down_list[1] == K_LEFT and self.key_down_list[` `0] == K_UP): # key_down_list列表存在按键为left,up 或 up,left时调用move_left_and_up()方法` `self.move_left_and_up()` `elif (self.key_down_list[0] == K_RIGHT and self.key_down_list[1] == K_UP) or (` `self.key_down_list[1] == K_RIGHT and self.key_down_list[0] == K_UP):` `self.move_right_and_up()` `elif (self.key_down_list[0] == K_LEFT and self.key_down_list[1] == K_DOWN) or (` `self.key_down_list[1] == K_LEFT and self.key_down_list[0] == K_DOWN):` `self.move_lef_and_down()` `elif (self.key_down_list[0] == K_RIGHT and self.key_down_list[1] == K_DOWN) or (` `self.key_down_list[1] == K_RIGHT and self.key_down_list[0] == K_DOWN):` `self.move_right_and_down()` `else: # 一个键` `if self.key_down_list[0] == K_LEFT:` `self.move_left()` `elif self.key_down_list[0] == K_RIGHT:` `self.move_right()` `elif self.key_down_list[0] == K_UP:` `self.move_up()` `elif self.key_down_list[0] == K_DOWN:` `self.move_down()
# 自爆
def bomb(self):
self.hitted = True
self.HP = 0 ` `# 键盘按下向列表添加space` `def space_key_down(self, key):` `self.space_key_list.append(key)
# 键盘松开向列表删除space
def space_key_up(self, key):
if len(self.space_key_list) != 0: # 判断是否为空
try:
self.space_key_list.pop(0)
except Exception:
raise ` `# 按键space不放,持续开火` `def press_fire(self):` `if len(self.bullet_list) == 0 and len(self.space_key_list):` `self.fire()` `else:` `if len(self.space_key_list) != 0:` `if self.bullet_list[len(self.bullet_list) - 1].y < self.y - 14 - 60:` `self.fire()
# 开火
def fire(self):
global plane_maximum_bullet
hero_fire_music.play()
if not self.is_three_bullet:
if len(self.bullet_list) < plane_maximum_bullet[self.plane_type]: # 单发炮台子弹限制为8
self.bullet_list.append(Bullet(self.screen, self.x + 40, self.y - 14, self))
else: # 没有子弹限制
# 主炮管
self.bullet_list.append(Bullet(self.screen, self.x + 40, self.y - 14, self))
# 创建2,3号炮管子弹
self.barrel_2.append(Bullet(self.screen, self.x + 5, self.y + 20, self))
self.barrel_3.append(Bullet(self.screen, self.x + 75, self.y + 20, self))
self.three_bullet_stock -= 1 # 三管炮弹弹药余量-1
if not self.three_bullet_stock: # 三管齐发弹药用完
self.is_three_bullet = False``
# 是否吃到补给
def supply_hitted(self, supply_temp, width, height): # widht和height表示范围
if supply_temp and self.HP:
# 更加精确的判断是否吃到补给
supply_temp_left_x = supply_temp.x + supply_size[supply_temp.supply_type][“width”] * 0.15
supply_temp_right_x = supply_temp.x + supply_size[supply_temp.supply_type][“width”] * 0.85
supply_temp_top_y = supply_temp.y + supply_size[supply_temp.supply_type][“height”] * 0.4
supply_temp_bottom_y = supply_temp.y + supply_size[supply_temp.supply_type][“height”] * 0.9
if supply_temp_left_x > self.x + 0.05 * width and supply_temp_right_x < self.x + 0.95 * width and supply_temp_top_y < self.y + 0.95 * height and supply_temp_bottom_y > self.y + 0.1 * height:
if supply_temp.supply_type == 0: # 0为血量补给,吃到血量补给
self.HP -= supply_temp.supply_HP # 血量-(-3)
if self.HP > 41: # 血量最大值为41
self.HP = 41
show_score_HP()
else: # 吃到弹药补给
self.is_three_bullet = True
self.three_bullet_stock += 20 # 三管炮弹余量+20
del_supply(supply_temp)
2)游戏的逻辑部分
函数def del_outWindow_bullet(plane):` `"""删除plane的越界子弹"""` `bullet_list_out = [] # 越界子弹` `for bullet in plane.bullet_list:` `bullet.display()` `bullet.move()` `if bullet.judge(): # 判断子弹是否越界` `bullet_list_out.append(bullet)` `# 删除越界子弹` `if bullet_list_out:` `for bullet in bullet_list_out:` `plane.bullet_list.remove(bullet)` `# 如果为hero并且为三管齐发则判断炮管23的子弹是否越界` `if plane.plane_type == 3 and (plane.barrel_2 or plane.barrel_3):` `barrel2_bullet_out = [] # 越界子弹` `barrel3_bullet_out = [] # 越界子弹` `# 判断炮管2` `for bullet in plane.barrel_2:` `bullet.display()` `bullet.move()` `if bullet.judge(): # 判断子弹是否越界` `barrel2_bullet_out.append(bullet)` `# 删除越界子弹` `if barrel2_bullet_out:` `for bullet in barrel2_bullet_out:` `plane.barrel_2.remove(bullet)` `# 判断炮管3` `for bullet in plane.barrel_3:` `bullet.display()` `bullet.move()` `if bullet.judge(): # 判断子弹是否越界` `barrel3_bullet_out.append(bullet)` `# 删除越界子弹` `if barrel3_bullet_out:` `for bullet in barrel3_bullet_out:` `plane.barrel_3.remove(bullet)` `def del_plane(plane):` `"""回收被击中的敌机的对象"""` `global hero` `global hit_score` `global enemy0_list` `global enemy1_list` `global enemy2_list` `if plane in enemy0_list: # 回收对象为enemy0` `enemy0_list.remove(plane)` `elif plane in enemy1_list:` `enemy1_list.remove(plane)` `elif plane in enemy2_list:` `enemy2_list.remove(plane)` `elif plane == hero: # 回收对象为hero` `hit_score = 0` `show_score_HP()` `hero = None` `def del_supply(supply):` `"""回收补给"""` `global blood_supply` `global bullet_supply` `if supply == blood_supply: # 回收对象为血量补给` `blood_supply = None` `elif supply == bullet_supply:` `bullet_supply = None` `def reborn():` `"""Hero重生"""` `global hero` `global window_screen` `global hit_score` `hero = HeroPlane(window_screen)` `show_score_HP()` `hit_score = 0` `# 将最高分写入到文件
def max_score_2_file():
global hit_score
file = None
try:
file = open(“./飞机大战得分榜.txt”, ‘r+’)
except Exception:
file = open(“./飞机大战得分榜.txt”, ‘w+’)
finally:
if file.read(): # 判断文件是否为空
file.seek(0, 0) # 定位到文件开头
file_score = eval(file.read())
if hit_score > file_score:
file.seek(0, 0) # 定位到文件开头
file.truncate() # 清空文件内容
file.write(str(hit_score))
else:
file.write(str(hit_score))
file.close()
def create_enemy_plane():
“”“生成敌机”“”
global window_screen
global hit_score
global enemy0_list
global enemy0_maximum
global enemy1_list
global enemy1_maximum
global enemy2_list
global enemy2_maximum
global HP_list
if hit_score < 40:
random_num = random.randint(1, 70)
HP_list = [1, 20, 100, 20]
elif hit_score < 450:
random_num = random.randint(1, 60)
HP_list = [1, 20, 120, 20]
elif hit_score < 650:
random_num = random.randint(1, 60)
HP_list = [1, 30, 140, 20]
elif hit_score < 850:
random_num = random.randint(1, 55)
HP_list = [2, 36, 160, 20]
else:
random_num = random.randint(1, 50)
HP_list = [2, 40, 180, 20]
random_appear_boss1 = random.randint(18, 28)
random_appear_boss2 = random.randint(80, 100)
# enemy0
if (random_num == 20 or random == 40) and len(enemy0_list) < enemy0_maximum:
enemy0_list.append(Enemy0Plane(window_screen))
# enemy1
if (hit_score >= random_appear_boss1 and (hit_score % random_appear_boss1) == 0) and len(
enemy1_list) < enemy1_maximum:
enemy1_list.append(Enemy1Plane(window_screen))
# enemy2
if (hit_score >= random_appear_boss2 and (hit_score % random_appear_boss2) == 0) and len(
enemy2_list) < enemy2_maximum:
enemy2_list.append(Enemy2Plane(window_screen))
` `
上面这一堆代码其实就是干下面几个事情:
-
先绘制出背景幕布
-
再绘制出玩家的战机,敌机
-
绑定战机和敌机的鼠标和键盘响应事件
-
发射子弹,通过坐标来判断子弹和敌机的碰撞,以及敌机和玩家战机的碰撞
-
最后还要计算得分
点击下方安全链接前往获取
CSDN大礼包:《Python入门&进阶学习资源包》免费分享
👉Python实战案例👈
光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。
👉Python书籍和视频合集👈
观看零基础学习视频,看视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。
👉Python副业创收路线👈
这些资料都是非常不错的,朋友们如果有需要《Python学习路线&学习资料》,点击下方安全链接前往获取
CSDN大礼包:《Python入门&进阶学习资源包》免费分享
本文转自网络,如有侵权,请联系删除。
![Logo](https://devpress.csdnimg.cn/79de2bf0b7994defa4242ef90d5513fa.jpg)
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)