今天已经初四,舒服的在家躺尸的春节也算过去了,又要开始辛勤的(苦逼的)学习和工作了。说点题外话,今年春节的病毒疫情真的弄的人心惶惶,我也在这为国家和武汉加油,也向一线工作人员致敬,希望早日结束这场疫情。
好了,题外话说的有点多,下面开始介绍用python写的小游戏飞机大战。心急的小伙伴们可以直接到博客底部找链接,我给你们提供了代码源码和开发文档,哈哈。
我用的是编译软件是比较常用的用来写python大型工程的PyCharm,这个软件总体来说是比较好用的。大家可以在网上自行下载,当然一般好用的软件都需要付费。哈哈,PyCharm也不例外,我记得这个软件是有30天的免费体验期,不过经常用破解软件的苦逼码农一般都去网上找秘钥破解。
在这就简单说一下主要用到的一些:
(1)pygame库
Pygame是跨平台Pyth,Pygame 作者是 Pete Shinners, 协议为 GNU Lesser General Public License。Pygame包含图像、声音。建立在SDL基础上,允许实时电子游戏研发而无需被低级语言(如机器语言和汇编语言)束缚。基于这样一个设想,所有需要的游戏功能和理念(主要是图像方面)都完全简化为游戏逻辑本身,所有的资源结构都可以由高级语言提供,如Python。
(2)random库
Random是产生随机数的库,即随机数发生器,random产生的是伪随机数或者说是用一种复杂的方法计算得到的序列值,因此每次运算时需要一个不同的种子值。种子值不同,得到的序列值也不同。
(3) time库
time库是Python中处理时间的标准库,用于计算机时间的表达,提供获取系统时间并格式化输出功能,提供系统级精确计时功能,也可用于程序性能分析。
(4) sys库
sys.exit([ arg ])用于程序的退出,sys.exit(n) 退出程序,正常退出时exit(0)。这是通过引发SystemExit 异常来实现的,因此遵循finally语句的子句所指定的清理操作try ,并且可以拦截外层的退出尝试。可选参数arg可以是一个整数,给出退出状态(默认为零)或其他类型的对象。如果它是整数,则零被认为是“成功终止”,并且任何非零值等视为“异常终止”。
1.游戏操作及游戏规则
(1)通过键盘上下左右键或者WASD键控制飞机的移动方向来射击敌机。
(2)通过键盘空格键释放导弹,将游戏界面的敌机全部击败,初始有三颗导弹,游戏过程中会出现导弹补给对导弹进行补充,最多可获取三颗。
(3)根据击败敌机的等级来获得不同的得分,得分进行累计,对应五个难度等级,分数越高难度越大。
(4)在飞机移动射击过程中,不能碰撞敌机,每次碰撞敌机损失一条生命,飞机共有三条生命,损失三条命后游戏结束。
2.游戏总体设计
(1)定义一个显示窗口(480*700px);根据帧数控制飞机子弹射速,敌机刷新时间和补给刷新时间;
(2)定义玩家控制机、敌机、子弹类和补给类,并在窗口上把玩家控制机、敌机、得分、导弹数量、生命数量、补给和暂停键显示出来;
(3)定义游戏循环;
(4)定义玩家控制机的移动和导弹的触发,通过检测键盘输入来控制飞机的移动和触发导弹效果;
(5)检测游戏结束,显示本局得分、最高得分、重新开始和退出游戏选项。
(1)初始化游戏主界面
#pygame初始化
pygame.init()
pygame.mixer.init()
#设置背景尺寸(根据背景图片尺寸设置)
bg_size = width, height = 480, 700
screen = pygame.display.set_mode(bg_size)
pygame.display.set_caption('飞机大战') #标题
#初始飞机数量,可直接修改
enemy3_num = 12
enemy2_num = 8
enemy1_num = 2
#加载背景图片
background = pygame.image.load('images/background.jpg').convert_alpha()
(2)定义main函数,用于实现玩家控制机、敌机和补给的生成。统计得分并根据得分增加游戏难度,难度共5个等级,分别对应得到50、200、500、1200分时对大中小型敌机数量和速度进行增加。实现游戏的暂停并判断游戏是否结束,并绘制结束界面。
#播放背景音乐,循环播放
pygame.mixer.music.play(-1)
#生成控制机
me = myplane.MyPlane(bg_size)
# 生成敌方飞机
enemies = pygame.sprite.Group()
# 生成大型敌机
big_enemies = pygame.sprite.Group()
add_big_enemies(big_enemies, enemies, enemy3_num)
# 生成中型敌机
mid_enemies = pygame.sprite.Group()
add_mid_enemies(mid_enemies, enemies, enemy2_num
# 生成小型敌机
small_enemies = pygame.sprite.Group()
add_small_enemies(small_enemies, enemies, enemy1_num)
# 生成普通子弹
bullet1 = []
bullet1_index = 0
BULLET1_NUM = 4
for i in range(BULLET1_NUM):
bullet1.append(bullet.Bullet1(me.rect.midtop)) #在飞机顶部中央生成子弹
# 生成超级子弹
bullet2 = []
bullet2_index = 0
BULLET2_NUM = 8
for i in range(BULLET2_NUM // 2):
bullet2.append(bullet.Bullet2((me.rect.centerx - 33, me.rect.centery)))
bullet2.append(bullet.Bullet2((me.rect.centerx + 30, me.rect.centery)))
# 用于延迟
delay = 100
clock = pygame.time.Clock()
#中弹图片索引
e1_destroy_index = 0
e2_destroy_index = 0
e3_destroy_index = 0
me_destroy_index = 0
# 统计得分
score = 0
score_font = pygame.font.Font('font/MSYH.TTF', 36)
# 是否暂停游戏
paused = False
pause_nor_image = pygame.image.load('images/pause_nor.png').convert_alpha()
pause_pressed_image = pygame.image.load('images/pause_pressed.png').convert_alpha()
resume_nor_image = pygame.image.load('images/resume_nor.png').convert_alpha()
resume_pressed_image = pygame.image.load('images/resume_pressed.png').convert_alpha()
pause_rect = pause_nor_image.get_rect()
pause_rect.left, pause_rect.top = width - pause_rect.width - 10, 10
pause_image = pause_nor_image
# 难度级别
level = 1
# 炸弹
bomb_image = pygame.image.load('images/bomb.png').convert_alpha()
bomb_rect = bomb_image.get_rect()
bomb_font = pygame.font.Font('font/MSYH.TTF', 40)
bomb_num = 3
# 生命数量
life_image = pygame.image.load('images/life.png').convert_alpha()
life_rect = life_image.get_rect()
life_font = pygame.font.Font('font/MSYH.TTF', 40)
life_num = 3
# 每30秒发放一个补给包
bullet_supply = supply.Bullet_Supply(bg_size)
bomb_supply = supply.Bomb_Supply(bg_size)
life_supply = supply.Life_Supply(bg_size)
SUPPLY_TIME = USEREVENT # 自定义计时事件
pygame.time.set_timer(SUPPLY_TIME, 30 * 1000)
# 超级子弹定时器
DOUBLE_BULLET_TIME = USEREVENT + 1
# 是否使用超级子弹
is_double_bullet = False
# 无敌时间计时器
INVINCIBLE_TIME = USEREVENT + 2
# 防止重复打开记录文件
recorded = False
running = True
play_fly_sound = False # 是否播放大型敌机fly的音效
(1)定义玩家控制机类,继承pygame中的sprite类,实现对玩家控制机的初始化,将玩家控制机图片的导入,在游戏界面初始位置的设定,速度的设定等。
#导入控制机
self.image = pygame.image.load('images/me1.png').convert_alpha()
self.destroy_images = []
self.destroy_images.extend([\
pygame.image.load('images/me_destroy_1.png'),\
pygame.image.load('images/me_destroy_2.png'),\
pygame.image.load('images/me_destroy_3.png'),\
pygame.image.load('images/me_destroy_4.png'),])
#获取rect
self.rect = self.image.get_rect()
self.width, self.height = bg_size[0], bg_size[1]
#控制机初始位置
self.rect.left, self.rect.top = \
(self.width - self.rect.width) // 2, \
self.height - self.rect.height - 60
self.speed = 10 #控制机速度
self.active = True
self.invincible = False #无敌状态标志
self.mask = pygame.mask.from_surface(self.image) #将传入图片非透明部分标记为mask
(2)定义玩家控制机上下左右移动的函数(类中的函数)。
def moveUp(self): #向上走
if self.rect.top > 0:
self.rect.top -= self.speed
else:
self.rect.top = 0
def moveDown(self): #向下走
if self.rect.bottom < self.height - 60:
self.rect.top += self.speed
else:
self.rect.bottom = self.height - 60
def moveLeft(self): #向左走
if self.rect.left > 0:
self.rect.left -= self.speed
else:
self.rect.left = 0
def moveRight(self): #向右走
if self.rect.right < self.width:
self.rect.left += self.speed
else:
self.rect.right = self.width
(3)重置函数,在玩家控制机飞机损失一条命之后重新初始化玩家控制机的函数(类中的函数)。
def reset(self):
self.rect.left, self.rect.top = \
(self.width - self.rect.width) // 2, \
self.height - self.rect.height - 60
self.active = True
self.invincible = True
(1)定义小型敌机类(SmallEnemy),继承pygame的sprite类,初始化小型敌机。
self.image = pygame.image.load('images/enemy1.png').convert_alpha()
self.active = True
self.rect = self.image.get_rect()
self.width, self.height = bg_size[0], bg_size[1]
self.speed = 2
self.mask = pygame.mask.from_surface(self.image)
#设置小型敌机能够出现范围的矩形大小
self.rect.left, self.rect.top = \
randint(0, self.width - self.rect.width), \
randint(-5 * self.rect.height, 0)
(2)定义小型敌机移动函数(类中的函数),设定其移动方向。
#设置敌机移动
def move(self):
if self.rect.top < self.height:
self.rect.top += self.speed
else:
self.reset()
(3)定义小型敌机重置函数(类中的函数),进行重新初始化。
def reset(self):
self.active = True
self.rect.left, self.rect.top = \
randint(0, self.width - self.rect.width), \
randint(-7 * self.rect.height, 0)
(4)定义中型敌机类(MidEnemy)和大型敌机类(BigEnemy),基本操作与小型敌机类一样。
(1)定义普通子弹类(Bullet1),初始化普通子弹,导入普通子弹图片到程序,设定普通子弹的速度等。
self.image = pygame.image.load('images/bullet1.png').convert_alpha()
self.rect = self.image.get_rect()
self.rect.left, self.rect.top = position
self.speed = 12
self.active = False
self.mask = pygame.mask.from_surface(self.image)
(2)定义普通子弹移动函数(类中的函数),控制子弹的一点方向。
def move(self):
self.rect.top -= self.speed
if self.rect.top < 0:
self.active = False
(3)定义普通子弹重置函数(类中的函数),重新初始化普通子弹。
def reset(self, position):
self.rect.left, self.rect.top = position
self.active = True
(4)定义超级子弹类(Bullet2),继承pygame的sprite类,基本操作与普通子弹类一样。
(1)定义超级子弹补给类(Bullet_Supply),继承pygame的sprite类,初始化超级子弹补给,导入超级子弹补给的图片到程序,设置补给下落速度等。
self.image = pygame.image.load('images/bullet_supply.png').convert_alpha()
self.rect = self.image.get_rect()
self.width, self.height = bg_size[0], bg_size[1]
self.rect.left, self.rect.bottom = randint(0, self.width - self.rect.width), -100
self.speed = 5
self.active = False
self.mask = pygame.mask.from_surface(self.image)
(2)定义超级子弹补给移动函数(类中的函数),规定补给的移动方向。
def move(self):
if self.rect.top < self.height:
self.rect.top += self.speed
else:
self.active = False
(3)定义重置函数(类中的函数),重新初始化超级子弹补给。
def reset(self):
self.active = True
self.rect.left, self.rect.bottom = \
randint(0, self.width - self.rect.width), -100
(4)定义导弹补给类(Bomb_Supply)和生命补给类(Life_Supply),基本操作与超级子弹类类似。
Python编写小游戏–飞机大战
如果下载积分不够,可以加我微信获取(Up_Long_),有偿,私信只能24小时回复5个人,可能看到了但是无法回复消息。