摘 要:根据课程要求,以及面向对象程序设计的编程思想,在Windows操作系统环境下,运用PyCharm编译程序,以Python语言为开发语言,最终实现飞机大战游戏相应的游戏操作功能。Python是一种跨平台的、开源的、免费的、解释型的高级编程语言。它具有丰富的、强大的库, 能够把其他语言制作的各种模块很轻松地联结在一起, 所以Python常被称为“胶水”语言。Python语言近几年发展势头迅猛, 应用领域也非常广泛, 在Web编程、图形处理、黑客编程、大数据处理、网络爬虫、科学计算和游戏编程等领域都能找到Python的应用。其中Pygame是Python的一个第三方库, 搭载了基于OpenGL的图形库和优质的音频库, 可以快速上手制作2D游戏的原型。Pygame的API比较偏底层, 开发人员在编程时具有很大的自由度, 同时具有了很强的可定制性。Python语言的研究和发明主要是为了便于学习和应用, 因此Python语言是开源的, 并且语法非常简单、容易编写和理解。本文通过对飞机大战游戏的设计与分析, 掌握Python语言在游戏开发领域的优势。

**关键词:**面向对象程序设计;Pygame模块;Python语言;PyCharm编译程序

1、课程概述

飞机大战游戏设计开发课题是《面向对象程序设计(Python)》中面向对象程序设计的一次运用,主要设计原则如下:
(1)简单性,在实现软件的功能的同时, 尽量让软件操作简单易懂;
(2)针对性,基于Python软件, 实现飞机大战游戏的各种要求;
(3)一致性,类型、变量和其他元素的命名规则保持一致;
完成同样的功能应该尽量使用同样的元素;界面元素的外观风格、摆放位置在同一个界面和不同界面之间是一致的。可以使其基本类库Pygame的基本函数和功能模块的调用操作实现python语言在课程设计中的运用。
通过对飞机大战游戏设计的实现,要求我们进一步理解和掌握课堂上所学各种基本类型的变量、数据类型、类、用户输入和文件操作实现面向对象的游戏开发,以及它们在程序中的使用方法;掌握Python软件设计的基本内容和设计方法,并培养学生进行规范化软件设计的能力;掌握使用各种计算机资料和有关参考资料,提高我们进行程序设计的基本能力,逐步熟悉程序设计的方法,并养成良好的编程习惯。
本次设计为了使飞机大战游戏具有更加丰富的功能,基于面向对象和面向过程的方法,使用Python编程语言提供资源结构,以Pygame模块对游戏进行研发,提出了飞机大战游戏开发方案。通过各种优化调整,实现了飞机的飞行移动、击落,计分等功能,实现了飞机大战的开发,增加游戏体验。

2、需求分析

2.1问题描述
本次课程设计题目是 “飞机大战游戏设计”,实现基于面向对象程序设计的方法,使用Python编程语言,以Pygame模块实时对游戏进行研发,提出飞机大战小游戏开发方案。通过各种优化调整,实现飞机的飞行移动、击落,计分等功能,实现飞机大战的开发,增加游戏体验。
2.2设计目的
这次课程旨在使读者学会分析研究面向对象编程的特性,学会Python编程方法,以便选择合适的数据结构和逻辑结构,以及相应的运算,把现实世界中的问题转化为计算机内部的表示和处理。
《面向对象程序设计(Python)》课程的主要目的是使学生一步理解和掌握课堂上所学各种基本类型的变量、数据类型、类、用户输入、文件操作等,以及它
们在程序中的使用方法;掌握软件设计的基本内容和设计方法,并培养学生进行规范化软件设计的能力;掌握使用各种计算机资料和有关参考资料,提高学生进行程序设计的基本能力。
2.3 系统设计思想
本次设计基于面向对象的程序设计方法,使用Python编程语言提供资源结构,以Pygame模块实时对游戏进行研发,提出了飞机大战小游戏二次开发方案。通过各种优化调整,实现了飞机的飞行移动、击落,计分等功能,而且拓展了游戏的等级提升功能、界面打印功能、游戏奖励机制等等,实现了飞机大战的二次开发,丰富了游戏体验。
Pygame是Python的一个第三方库, 搭载了基于OpenGL的图形库和优质的音频库, 可以快速上手制作2D游戏的原型。Pygame的API比较偏底层, 开发人员在编程时具有很大的自由度, 同时具有了很强的可定制性。
按照游戏工业市场的飞机游戏开发需求,分析游戏的基本功能,在此基础上增加游戏的各类功能模块完善游戏。本设计所用到的编程语言是Python,版本是Python3.9,开发工具为Pycharm,调用Pygame模块,对游戏进行开发、运行及测试。游戏程序编辑、编译、调试、发布所有过程都是基于PC机平台运行。
2.4 开发平台及工具介绍
开发软件:Python 3.9
使用系统:Windows 10

3、设计要求

3.1 设计目的
(1)实现飞机的移动、子弹发射,对本次游戏有一个初步的编写及认识。
(2)飞机的持续按键移动和飞机自爆优化。
(3)进行基类的抽取,使代码更具有层次性和简化重复代码。
(4)对判断以及删除越界子弹、敌机发射子弹进行扩展优化。
3.2 总体设计
3.2.1系统功能总体设计框图

图3-1 系统功能总体设计框图

3.2.2主要流程图
(1)程序主函数
程序主函数主要进行定义和继承的相关操作,实现成员函数的定义和成员属性的定义,继承相关函数并添加相关的游戏特性。如图3-2所示。

图3-2 程序主函数流程图

(2)子弹模块
子弹实例化中,分成了两种射击模式,一个是普通子弹,另一个是超级子弹,包括了外形、速度、与敌机碰撞的撞击等基本因素,其基本属性方法如图3-3所示。

图3-3 子弹模块

(3)敌机模块
敌军飞机的飞行模式设定为单一向垂直移动飞行模式,设计飞行的速度,调用随机函数,设定敌军飞机的随机高度和随机宽度

(4)本机模块
自身飞机的功能属性如图3-5所示,需要自身飞机的图片加载、飞行速度设置、飞行上下移动等功能。

图3- 5 自身飞机模块
(5)奖励模块
游戏的奖励模块是本设计实现游戏创新的重要组成部分,本文中设计了生命、超级子弹、炸弹3个功能属性的奖励。

图3- 6 奖励模块

4,程序调试

(1) 将程序代码用Python3.9打开

(2)左右移动飞机也能正常移动。

(3)当“死亡”后会掉一次生命值。

(5)按空格键可以全屏“轰炸”。

(6)游戏结束之后有“重新开始”和“退出游戏”。

5 调试分析

5.1 调试
经过反复测试,飞机大战游戏最终可以流畅运行,而且容错能力较好,稳定性很强。下面做一些简单的说明:
(1)print() 方法
第一种方法简单直接粗暴有效,就是用print()把可能有问题的变量打印出来看看,执行后在输出中查找打印的变量值。
(2)断言 assert
凡是用print()来辅助查看的地方,都可以用断言(assert)来替代,assert的意思是,表达式n != 0应该是True,否则,根据程序运行的逻辑,后面的代码肯定会出错。如果断言失败,assert语句本身就会抛出AssertionError。程序中如果到处充斥着assert,和print()相比也好不到哪去。不过,启动Python解释器时可以用-O参数来关闭assert。
(3)logging
把print()替换为logging是第3种方式,和assert比,logging不会抛出错误,而且可以输出到文件,logging.info()就可以输出一段文本。运行,发现除了ZeroDivisionError,没有任何信息。别急,在import logging之后添加一行配置再试试。

5.2 调试中遇到的问题
1.敌机死后,子弹连带的消失
因为子弹组是敌军对象的成员,是在主函数需要敌军的子弹再加到一个组,而且所有敌军的子弹加到一起更更新更加方便,这样不用担心敌机毁掉了,他们的子弹对象也访问不了。
2.子弹和敌机多次撞击
由于播放爆炸动画采用的方法是被撞毁时,先不移除精灵组,然后更改该对象图片,知道图片轮完了才kill(),这就导致进行下一次循环,对象还没kill(),kill()了就不能进行轮播。撞毁的时候新建循环把爆炸图片画在屏幕上,行不通,第循环一次只能更新一帧图片,如果你要更新多帧那么其他精灵就会静止;撞毁时候,先移除精灵组,然后用变量储存,进行最初更新的方法。实验证明可行。
3.进行了update却不显示
混淆draw和display.update。首先一个精灵的update方法让图像有改变,draw方法调用screen的blit方法画到屏幕上,这时候屏幕画面残留在上一帧,只有display更新了才能看到
4. 想方设法把一个Sprite或者rect或者image进行清除操作
想要看不见他,两种方法如果是精灵,skill()从所有精灵组里面删除,如果只是单纯的image和rect,直接从他们的list里面remove,这样就不会被blit,实际上屏幕在更新,如果你想要看到,就要画在在更新的每一帧上面,之后如果不再用到它,python自己会进行回收.
5. 为什么英雄死掉了,还是会发生碰撞检测
这是因为,虽然我们把英雄加入英雄队伍,但是队伍中英雄很少,为了方便我们碰撞的时候不是从队伍中取直接就用该英雄对象进行检测,这时候,英雄skill()了,但是rect并没有丢失。skill()只是把他从需要显示或者操作群体中把他删除了,但是这个对象并没有被立即回收,它的rect还是在,还能用于碰撞检测
6.不知道全局变量如何使用
python里面的全局常量和其他语言一样是没有歧义的,但是全局变量就不一样了,因为python定义变量不用定义类型,只有在赋值的时候才知道,所以在函数里面使用全局变量,无法保证两个变量是一样的,所以在函数里面需要用global声明一下这个变量是我开始设的这个全局变量,不是又重新定义了一个局部变量。
6 总结
6.1功能
1.基本功能
(1)键盘方向键控制英雄移动
(2)英雄自动发射子弹
(3)敌军飞机自动生成,向下运动,发射不同速度炮弹
(4)自动生成补给,有子弹buff,炸弹buff,补血buff子弹。buff最多吃5个,每吃一个子弹数目或者威力提高,吃到第五个召唤"最强形态"。炸弹buff可以无限吃,当然出现几率比较小,吃到的炸弹在屏幕左下角显示,空格键引爆一颗炸弹,毁掉当前所有敌军飞机,boss损血。补血buff,一次补满英雄血条
(5)每种敌军对应不同分数,击爆后,屏幕又下角的总分增加相应的分数。
(6)子弹击中和撞击都会时敌机和英雄损血,且英雄还会debuff,就是buff效果会减弱。
(7)当英雄挂掉,游戏结束,屏幕显示分数,并且可以选择重来或者结束游戏
2.附加功能
(1)英雄吃buff初期子弹威力+1,且子弹排数有序增加,均匀分步。
(2)血条低于某个值会变红,当吃补给增加后又会恢复原色。
(3)敌机出现位置随机,速度随机,发射子弹速度随机,数量排数自定义,低级敌机出场较多,中型后来逐渐增多。
(4)英雄,boss有飞行和爆炸动画,敌机有爆炸动画。
(5)撞击对不同对象效果不同,英雄撞boss,英雄死boss损血,敌机撞英雄,敌机爆,英雄损血,且损血和被子弹击中血量不同。
(6)背景和bgm循环移动,营造飞行感觉。
(7)每个动作都有专属音效,如英雄爆,敌机爆,补习,补子弹,补炸弹,扔炸弹,射击。
(8)boss移动速度慢,慢于最低速度,即1像素每帧,游戏定义为60帧/秒,即速度低于60像素/秒。

源代码:

布局及设定
import random
import pygame
pygame.init()
SCORE = 0
#屏幕大小的常量
SCREEN_RECT = pygame.Rect(0, 0, 480, 700)
#color
color_blue = (30, 144, 255)
color_green = (0, 255, 0)
color_red = (255, 0, 0)
color_purple = (148, 0, 211)
color_gray = (251, 255, 242)
#刷新的帧率
FRAME_PER_SEC = 60  # 刷新率是60hz,即每秒update60次
#创建敌机的定时器常量,自定义用户事件,其实就是int数,不同数表示不同事件
CREATE_ENEMY_EVENT = pygame.USEREVENT
#英雄发射子弹事件
HERO_FIRE_EVENT = pygame.USEREVENT + 1buff1 出现的事件
BUFF1_SHOW_UP = pygame.USEREVENT + 2buff2
BUFF2_SHOW_UP = pygame.USEREVENT + 3
#敌军发射子弹
ENEMY_FIRE_EVENT = pygame.USEREVENT + 4
#发射炸弹
BOMB_THROW = pygame.USEREVENT + 5class GameScore(object):global SCOREdef __init__(self):self.score = 0passdef getvalue(self):self.score = SCOREreturn self.scoreclass GameSprite(pygame.sprite.Sprite):"""飞机大战游戏"""def __init__(self, image_name, speedy=1, speedx=0):# 调用父类的初始化方法super().__init__()# 定义对象的属性self.image = pygame.image.load(image_name)self.rect = self.image.get_rect()self.speedy = speedyself.speedx = speedxself.injury = 1self.index = 0  # 记帧数变量self.bar = bloodline(color_blue, self.rect.x, self.rect.y - 10, self.rect.width)def update(self):# 在屏幕的垂直方向上移动self.rect.y += self.speedyself.rect.x += self.speedxself.bar.x = self.rect.xself.bar.y = self.rect.y - 10class Background(GameSprite):"""游戏背景精灵"""def __init__(self, is_alt=False):# 1. 调用父类方法实现精灵的创建(image/rect/speed)super().__init__("./images/background.png")# 2. 判断是否是交替图像,如果是,需要设置初始位置if is_alt:self.rect.y = -self.rect.heightdef update(self):# 1. 调用父类的方法实现super().update()# 2. 判断是否移出屏幕,如果移出屏幕,将图像设置到屏幕的上方if self.rect.y >= SCREEN_RECT.height:self.rect.y = -self.rect.heightclass Boss(GameSprite):def __init__(self):super().__init__("./images/enemy3_n1.png", 0, 1)self.music_boom = pygame.mixer.Sound("./music/enemy3_down.wav")self.music_fly = pygame.mixer.Sound("./music/enemy3_flying.wav")self.music_fly.play(-1)self.rect.centerx = 240self.y = 200self.isboom = Falseself.number = 3self.index1 = 1  # 控制动画速度self.index2 = 0self.index3 = 0self.index4 = 0self.injury = 1self.bar = bloodline(color_purple, 0, 0, 480, 8, 200)self.bullets = pygame.sprite.Group()def fire(self):for j in range(2, 7):  # 每层5个bullet = Bullet(0, 1)bullet.injury = 1# 2. 设置精灵的位置bullet.rect.centerx = self.rect.centerxbullet.rect.y = self.rect.bottomif j == 2:bullet.speedx = 0else:bullet.speedx = (-1) ** j * ((j - 1) // 2) * 1self.bullets.add(bullet)def update(self):# 左右移global SCOREif self.index4 % 2 == 0:  # 降低帧速率,注意这两个指针不能一样# 内部为左右移动大概50像素if self.index3 % 50 == 0 and (self.index3 // 50) % 2 == 1:self.speedx = -self.speedxself.rect.x += self.speedxself.index3 += 1self.index4 += 1# 发电动画self.image = pygame.image.load("./images/enemy3_n" + str((self.index1 // 6) % 2 + 1) + ".png")self.index1 += 1# 爆炸动画if self.isboom:self.bar.length -= self.injury * self.bar.weightif self.bar.length <= 0:  # 此时满足爆炸的条件了self.music_fly.stop()if self.index2 == 0:self.music_boom.play()if self.index2 < 29:  # 4*7+1self.image = pygame.image.load("./images/enemy3_down" + str(self.index2 // 7) + ".png")# 这个地方之所以要整除4是为了减慢爆炸的速度,如果按照update的频率60hz就太快了self.index2 += 1else:self.kill()SCORE += self.bar.valueelse:self.isboom = False  # 否则还不能死
class Enemy(GameSprite):"""敌机精灵"""def __init__(self, num=1):self.number = num# 1. 调用父类方法,创建敌机精灵,同时指定敌机图片super().__init__("./images/enemy" + str(num) + ".png")# musicif num == 1:self.music_boom = pygame.mixer.Sound("./music/enemy1_down.wav")else:self.music_boom = pygame.mixer.Sound("./music/enemy2_down.wav")# 2. 指定敌机的初始随机速度 1 ~ 3self.speedy = random.randint(1, 3)# 3. 指定敌机的初始随机位置self.rect.bottom = 0max_x = SCREEN_RECT.width - self.rect.widthself.rect.x = random.randint(0, max_x)# 4.爆炸效果self.isboom = Falseself.index = 0# 5.血条if self.number == 1:self.bar = bloodline(color_blue, self.rect.x, self.rect.y, self.rect.width)else:self.bar = bloodline(color_blue, self.rect.x, self.rect.y, self.rect.width, 3, 4)# 6,子弹self.bullets = pygame.sprite.Group()def fire(self):for i in range(0, 2):# 1. 创建子弹精灵bullet = Bullet(0, random.randint(self.speedy + 1, self.speedy + 3))# 2. 设置精灵的位置bullet.rect.bottom = self.rect.bottom + i * 20bullet.rect.centerx = self.rect.centerx# 3. 将精灵添加到精灵组self.bullets.add(bullet)def update(self):global SCORE# 1. 调用父类方法,保持垂直方向的飞行super().update()# 2. 判断是否飞出屏幕,如果是,需要从精灵组删除敌机if self.rect.y > SCREEN_RECT.height:# print("飞出屏幕,需要从精灵组删除...")# kill方法可以将精灵从所有精灵组中移出,精灵就会被自动销毁self.kill()self.bar.length = 0if self.isboom:self.bar.length -= self.bar.weight * self.injuryif self.bar.length <= 0:if self.index == 0:  # 保证只响一次self.music_boom.play()if self.index < 17:  # 4*4+1self.image = pygame.image.load("./images/enemy" + str(self.number) + "_down" + str(self.index // 4) + ".png")# 这个地方之所以要整除4是为了减慢爆炸的速度,如果按照update的频率60hz就太快了self.index += 1else:self.kill()SCORE += self.bar.valueelse:self.isboom = False
class Hero(GameSprite):"""英雄精灵"""def __init__(self):# 1. 调用父类方法,设置image&speedsuper().__init__("./images/me1.png")self.music_down = pygame.mixer.Sound("./music/me_down.wav")self.music_upgrade = pygame.mixer.Sound("./music/upgrade.wav")self.music_degrade = pygame.mixer.Sound("./music/supply.wav")self.number = 0# 2. 设置英雄的初始位置self.rect.centerx = SCREEN_RECT.centerxself.rect.bottom = SCREEN_RECT.bottom - 120# 3. 创建子弹的精灵组self.bullets = pygame.sprite.Group()# 4.爆炸self.isboom = Falseself.index1 = 1  # 控制动画速度self.index2 = 0# 5.buff1加成self.buff1_num = 0# 6,英雄血条self.bar = bloodline(color_green, 0, 700, 480, 8, 10)# 7,炸弹数目self.bomb = 0def update(self):# 英雄在水平方向移动和血条不同步,特殊self.rect.y += self.speedyself.rect.x += self.speedx# 控制英雄不能离开屏幕if self.rect.x < 0:self.rect.x = 0elif self.rect.right > SCREEN_RECT.right:self.rect.right = SCREEN_RECT.rightelif self.rect.y < 0:self.rect.y = 0elif self.rect.bottom > SCREEN_RECT.bottom:self.rect.bottom = SCREEN_RECT.bottom# 英雄喷气动画self.image = pygame.image.load("./images/me" + str((self.index1 // 6) % 2 + 1) + ".png")self.index1 += 1# 英雄爆炸动画if self.isboom:self.bar.length -= self.injury * self.bar.weightif self.bar.length <= 0:  # 此时满足爆炸的条件了if self.index2 == 0:self.music_down.play()if self.index2 < 17:  # 4*4+1self.image = pygame.image.load("./images/me_destroy_" + str(self.index2 // 4) + ".png")# 这个地方之所以要整除4是为了减慢爆炸的速度,如果按照update的频率60hz就太快了self.index2 += 1else:self.kill()else:self.isboom = False  # 否则还不能死# 发射子弹def fire(self):if self.buff1_num == 0:for i in range(0, 1):bullet = Bullet()bullet.rect.bottom = self.rect.y - i * 20bullet.rect.centerx = self.rect.centerxself.bullets.add(bullet)elif self.buff1_num <= 3:for i in (0, 1):for j in range(2, self.buff1_num + 3):bullet = Bullet(2, -3)bullet.rect.bottom = self.rect.y - i * 20if (self.buff1_num % 2 == 1):bullet.rect.centerx = self.rect.centerx + (-1) ** j * 15 * (j // 2)if (self.buff1_num % 2 == 0):if j == 2:bullet.rect.centerx = self.rect.centerxelse:bullet.rect.centerx = self.rect.centerx + (-1) ** j * 15 * ((j - 1) // 2)self.bullets.add(bullet)elif self.buff1_num >= 4:for i in range(0, 1):# 1. 表示有几层for j in range(2, 5):  # 每层三个bullet = Bullet(3, -3)bullet.injury = 2# 2. 设置精灵的位置bullet.rect.bottom = self.rect.yif j == 2:bullet.rect.centerx = self.rect.centerxelse:bullet.rect.centerx = self.rect.centerx + (-1) ** j * (30 + 5 * i)bullet.speedx = (-1) ** j * (i + 1)self.bullets.add(bullet)class Heromate(Hero):def __init__(self, num):super().__init__()self.image = pygame.image.load("./images/life.png")self.number = numdef update(self):if self.rect.right > SCREEN_RECT.right:self.rect.right = SCREEN_RECT.rightif self.rect.x < 0:self.rect.x = 0if self.rect.y < 0:self.rect.y = 0elif self.rect.bottom > SCREEN_RECT.bottom:self.rect.bottom = SCREEN_RECT.bottomdef fire(self):for i in range(0, 1, 2):bullet = Bullet()bullet.rect.bottom = self.rect.y - i * 20bullet.rect.centerx = self.rect.centerxself.bullets.add(bullet)class Bullet(GameSprite):"""子弹"""def __init__(self, color=1, speedy=-2, speedx=0):# 调用父类方法,设置子弹图片,设置初始速度self.hity = color  # 子弹伤害值self.music_shoot = pygame.mixer.Sound("./music/bullet.wav")self.music_shoot.set_volume(0.4)if color > 0:  # 只让英雄发子弹响self.music_shoot.play()super().__init__("./images/bullet" + str(color) + ".png", speedy, speedx)def update(self):# 调用父类方法,让子弹沿垂直方向飞行super().update()# 判断子弹是否飞出屏幕if self.rect.bottom < 0 or self.rect.y > 700:self.kill()class Buff1(GameSprite):def __init__(self):super().__init__("./images/bullet_supply.png", 1)self.music_get = pygame.mixer.Sound("./music/get_bullet.wav")self.rect.bottom = 0max_x = SCREEN_RECT.width - self.rect.widthself.rect.x = random.randint(0, max_x)def update(self):super().update()if self.rect.bottom < 0:self.kill()class Buff2(GameSprite):def __init__(self):super().__init__("./images/bomb_supply.png", 2)self.music_get = pygame.mixer.Sound("./music/get_bomb.wav")self.rect.bottom = random.randint(0, 700)max_x = SCREEN_RECT.width - self.rect.widthself.rect.x = random.randint(0, max_x)self.ran = random.randint(60, 180)  # 在持续1~3s后消失def update(self):super().update()if self.rect.bottom < 0 or self.index == self.ran:self.kill()self.index += 1class Buff3(Buff2):def __init__(self):super().__init__()self.image = pygame.image.load("./images/buff3.png")self.speedy=3class bloodline(object):def __init__(self, color, x, y, length, width=2, value=2):self.color = colorself.x = xself.y = yself.length = lengthself.width = width  # 线宽self.value = value * 1.0  # 血量用浮点数self.weight = length / value  # 每一滴血表示的距离self.color_init = colordef update(self, canvas):if self.length <= self.value * self.weight / 2:self.color = color_redelse:self.color = self.color_initself.bar_rect = pygame.draw.line(canvas, self.color, (self.x, self.y), (self.x + self.length, self.y),self.width)
class CanvasOver():def __init__(self, screen):self.img_again = pygame.image.load("./images/again.png")self.img_over = pygame.image.load("./images/gameover.png")self.rect_again = self.img_again.get_rect()self.rect_over = self.img_over.get_rect()self.rect_again.centerx = self.rect_over.centerx = SCREEN_RECT.centerxself.rect_again.bottom = SCREEN_RECT.centeryself.rect_over.y = self.rect_again.bottom + 20self.screen = screendef event_handler(self, event):if event.type == pygame.MOUSEBUTTONDOWN:pos = pygame.mouse.get_pos()if self.rect_again.left < pos[0] < self.rect_again.right and \self.rect_again.top < pos[1] < self.rect_again.bottom:return 1elif self.rect_over.left < pos[0] < self.rect_over.right and \self.rect_over.top < pos[1] < self.rect_over.bottom:return 0def update(self):self.screen.blit(self.img_again, self.rect_again)self.screen.blit(self.img_over, self.rect_over)score_font = pygame.font.Font("./STCAIYUN.ttf", 50)image = score_font.render("SCORE:" + str(int(SCORE)), True, color_gray)rect = image.get_rect()rect.centerx, rect.bottom = SCREEN_RECT.centerx, self.rect_again.top - 20self.screen.blit(image, rect)
飞机大战主游戏
import sys
import pygame
pygame.init()
from plane_sprites import *
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# 音乐bgmself.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. 设置定时器事件 - 创建敌机 1spygame.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 += 1for 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()# 判断元组中对应的按键索引值 1if 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 = xself.hero.speedy = ydef 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 -= 1self.bombs.pop()for enemy in self.enemy_group:if enemy.number < 3:enemy.bar.length = 0enemy.isboom = Trueelse:enemy.injury = 20enemy.isboom = Truedef __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):  bullet.kill()enemy.injury = bullet.hityenemy.isboom = Trueif 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 -= 1self.hero.music_degrade.play()self.enemy_group.remove(enemy)self.enemy_boom.add(enemy)enemy.isboom = Trueelse:self.hero.bar.length = 0self.hero.isboom = True# 子弹摧毁英雄for bullet in self.enemy_bullet_group:if pygame.sprite.collide_mask(self.hero, bullet):bullet.kill()self.hero.injury = 1if 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 -= 1self.hero.isboom = Trueif not self.hero.alive():self.hero.rect.right = -10  # 把英雄移除屏幕if self.hero.buff1_num == 5:self.mate1.rect.right = -10self.mate2.rect.right = -10self.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 += 1self.hero.music_upgrade.play()if self.hero.buff1_num == 5:self.team_show()elif buff.speedy==2:self.hero.bomb += 1image = 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.valuebuff.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.bottomhero.rect.left = self.hero.rect.rightif hero.number == -1:hero.rect.bottom = self.hero.rect.bottomhero.rect.right = self.hero.rect.lefthero.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 = 1for bomb in self.bombs:self.screen.blit(bomb, (0, 700 - (bomb.get_rect().height) * i))i += 1def 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, 480self.screen.blit(image, rect)@staticmethoddef __start__():# 创建游戏对象game = PlaneGame()# 启动游戏game.start_game()
if __name__ == '__main__':PlaneGame.__start__()

【Python飞机大战课程设计及源代码】相关推荐

  1. Python程序设计,pygame飞机大战课程设计

    *飞机大战游戏设计 摘 要:根据课程要求,以及面向对象程序设计的编程思想,在Windows操作系统环境下,运用PyCharm编译程序,以Python语言为开发语言,最终实现飞机大战游戏相应的游戏操作功 ...

  2. 飞机大战课程设计报告

    飞机大战游戏的设计与开发 摘要:在未来的世界里,地球已经不能使人类居住下去,于是人们开始向月球移民,在移民过程中,发现了比我们快一步的生物居住在那,双方都行驶战斗机开始了一场激烈的战斗,多次战斗无果, ...

  3. Python实验,用pygame做飞机大战游戏设计

    飞机大战游戏设计 摘 要:根据课程要求,以及面向对象程序设计的编程思想,在Windows操作系统环境下,运用PyCharm编译程序,以Python语言为开发语言,最终实现飞机大战游戏相应的游戏操作功能 ...

  4. 基于python的飞机大战游戏设计与实现

    基于python的飞机大战游戏设计与实现,采用MySQL+pygame+Tkinter实现飞机大战游戏,主要功能有注册+登录+游戏初始化(开始游戏+游戏操作说明+版权信息)+游戏主界面[设置敌机种类并 ...

  5. python飞机大战设计思路_python飞机大战pygame游戏背景设计详解

    本文实例讲述了python飞机大战pygame游戏背景设计.分享给大家供大家参考,具体如下: 目标 背景交替滚动的思路确定 显示游戏背景 01. 背景交替滚动的思路确定 运行 备课代码,观察 背景图像 ...

  6. python飞机大战功能模块图_基于Python的飞机大战游戏设计

    第 2 3 卷 第 1 期 2019年 3 月 扬 州 职 业 大 学 学 报 Journal of Yangzhou Polytechnic College Vol .23 No . 1 Mar . ...

  7. 【Python知识点梳理】8.飞机大战(面向对象设计思维)

    8.飞机大战(面向对象设计思维) 文章目录 1.飞机大战效果展示 2.我方飞机类 3.敌方飞机类 4.子弹类 5.补给类 6.主函数 总结 1.飞机大战效果展示   飞机大战(面向对象设计思维),主要 ...

  8. Python“飞机大战”上下左右移动空格发射子弹

    下载点此去 最后面有运行视频 一.项目背景 作为一名学习计算机的学生,在以往,我认为学习计算机要么就是无所不能的黑客,要么就是能制作出各种软件程序的大神.我选择pygame板块,制作一款能随意更改游戏 ...

  9. python飞机大战任务报告_Python飞机大战实战项目案例

    都说实践是检验知识掌握程度的最好测试.随着Python学习者的增长,越来越多的零基础入门课程让人眼花缭乱.虽然说基础理论的学习十分重要,但是如果仅仅只学习理论知识,也是远远不够的.飞机大战的项目实战可 ...

最新文章

  1. 22.调用delay()方法延时执行动画效果
  2. 为什么携程要做好持续交付?
  3. 图像几何变换:旋转,缩放,斜切
  4. ble gatt核心结构
  5. docker 添加端口映射_Docker容器修改端口映射
  6. cp无法获取文件状态stat_Node.js从零开始——文件系统
  7. php函数的严格类型,严格模式
  8. 第一章 1 常用库之time
  9. Drools学习 入门实例
  10. 大型网站的架构演进从一个电商网站开始
  11. Android 频道管理,可拖动item排列,删除,添加
  12. D-News|扎克伯格下月发布人工智能管家,美放宽无人机商用飞行标准
  13. Java_基础—readLine()和newLine()方法
  14. Problem:服务器超过最大中终连接数
  15. linux ubuntukylin和deepin操作系统的比较及改进方向的建议
  16. Linux串口驱动加载过程
  17. 考研日语线上笔记(一):考研日语203大纲陌生、易混词汇本
  18. 服务于win10的telnet的简易聊天服务器(单进程)
  19. hive on spark报错:Client closed before SASL negotiation finished
  20. 氨基酸三字母序列转单字母序列

热门文章

  1. 非三代16S莫“鼠”
  2. postgresql 修改表的字段由NOT NULL修改为NULL
  3. pkr车牌识别系统服务器,车牌识别系统车牌录入的操作步骤
  4. 鲁大师测试软件的算法,鲁大师: 目前尚无满分手机 鲁大师评测安卓版核心算法...
  5. 中国葡萄酒消费者真正的“痛”
  6. 2019杭电多校第一场 HDU 6599
  7. 众昂矿业架构师刘金海:萤石助力氟聚合物全产业链共振
  8. ros kinetic下网口类激光雷达传感器的配置
  9. Vue组件间通信方法总结(父子组件、兄弟组件及祖先后代组件间)
  10. 二分法求凸多边形的外接圆最大半径