前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >实战项目:飞机大战

实战项目:飞机大战

作者头像
佛系编程人
发布2020-02-25 11:42:59
1.8K0
发布2020-02-25 11:42:59
举报
文章被收录于专栏:佛系编程人佛系编程人

实战项目:飞机大战

项目目标:

实现基本的飞机大战

项目描述:

运行程序,英雄飞机出现在屏幕底边的中央区域,飞机中央每隔一秒会自动发射一枚子弹。随着游戏的开始,敌机会在屏幕上方随机不定时的出现在屏幕内向下飞行。英雄飞机需要通过移位躲避敌机或用子弹消灭敌机,避免碰撞导致游戏结束。

项目实现环境:

  • 编辑器:vscode编辑器
  • 操纵系统:win10
  • 编辑语言:python3.7

项目中所使用的库或模块:

  • pygame:第三方模块,用于编写游戏
  • random:python自带的模块,在指定的数字范围内随机产生相应结果

项目需求:

  • 绘制游戏背景图并实现背景图滚动
  • 绘制敌机并实现出现的时间随机
  • 绘制英雄飞机,并实现上下左右移动
  • 实现英雄飞机自动发射子弹
  • 实现英雄飞机与敌机、子弹与敌机的碰撞检测

项目准备:创建文件

  • 创建专门调用功能实现飞机大战的主文件main.py
  • 创建为飞机大战提供功能的类文件tools.py,包含的内容有:
    • 精灵类
    • 背景类
    • 敌机类
    • 子弹类
    • 英雄飞机类

代码编写

如何创建屏幕

代码语言:javascript
复制
# 导入第三方模块
import pygame
# 导入pygame库中的所有模块并进行初始化
pygame.init()

# 创建屏幕,设置屏幕大小(应根据背景图大小设置)
surface = pygame.display.set_mode((480,580))

# 卸载所有模块,退出程序
pygame.quit()

以上代码必须写入,否则无法正常运行

如何导入图片,创建图片对象

代码语言:javascript
复制
image = pygame.image.load('图片的地址')

如何将图片绘制到屏幕上

代码语言:javascript
复制
surface.blit(image,(0,0))
  • 第一个参数为图片对象
  • 第二个参数为绘制的初始位置

如何更新屏幕

代码语言:javascript
复制
pygame.display.update()

每次绘制完所有图片后一定要更新屏幕

如何创建精灵组

代码语言:javascript
复制
group = pygame.sprite.Group(精灵1对象,精灵2对象)

精灵组的三个方法

代码语言:javascript
复制
# 同时调用精灵组中所有精灵的update方法
group.update()
# 同时绘制精灵组中所有精灵的位置,需要传入屏幕对象
group.draw(屏幕对象)
# 向精灵组中添加精灵的方法
group.add(精灵)

如何碰撞检测

代码语言:javascript
复制
# 精灵组与精灵组之间的碰撞检测,比如子弹与敌机之间
pygame.sprite.groupcollide('精灵组1','精灵组2',True,True)

# 精灵与精灵组之间的碰撞检测,比如敌机与英雄飞机
pygame.sprite.spritecollide('精灵','精灵组',True)

其中,True代表碰撞的精灵或精灵组内的精灵会消失

编写tools.py文件代码

常量部分

代码语言:javascript
复制
# 480\580是图片的宽高SCREEN = pygame.Rect(0,0,480,580)# 创建敌机事件
CREAT_EVENT = pygame.USEREVENT
# 发射子弹事件
FIRE_BULLET = pygame.USEREVENT+1

pygame.Rect可以用来描述矩形区域,从左到右的参数分别代表 x、y、矩形区域的宽、矩形区域的高

pygame.USEREVENT代表定时事件的编号,通过后面+1、+2、+3.....的方式添加多个事件

编写精灵类

代码语言:javascript
复制
# 精灵类
class SpriteParent(pygame.sprite.Sprite):
    def __init__(self,imgae,speed=1)
         super().__init__()
         self.image = pygame.image.load(image)
        self.rect = self.image.get_rect()
        self.speed = speed
        
    def update(self):
         self.rect.y += self.speed
  • 该类继承了精灵类,需要包含两种方法:初始化方法和update()方法。
  • 在初始化方法中要添加三个属性,分别是:加载的图片对象、图片的矩形区域,图片的移动速度。其中图片的矩形区域可以使用图片对象的 get_rect() 来获取,速度自定义设置,这里设置成 每次移动1像素。
  • 这里要注意的是,我们是扩展父类的初始化方法,而不是重写父类的初始化方法
  • update()方法的作用是更新图片的位置
  • self.rect.y 代表矩形区域在y轴的位置

编写背景类

代码语言:javascript
复制
class BackGround(SpriteParent):

    def __init__(self,is_alt=False):
        super().__init__('./images/background.png')
        # 如果is_alt为True,则设置图片的初始位置为图片高度的负值
        if is_alt:
            self.rect.y = -self.rect.height
            
    def update(self):
        # 继承父类的update方法,使图片每次向下移动1像素
        super().update()
        # 当图片顶部的位置等于屏幕的高度时,将该图片返回到屏幕上方,与上方图片进行衔接
        if self.rect.y >= SCREEN.height:
            self.rect.y = -self.rect.height

要实现背景图片循环上下交替滚动,所以需要实例化两个背景图片对象,其中一个对象的初始位置位于y轴的负方向,且y为背景图片的高度的负值

编写敌机类

代码语言:javascript
复制
import random
class Enemy(SpriteParent):
    def __init__(self):
         super().__init__('./images/enemy.png')
         max_x = SCREEN.width - self.rect.width
         # 设置敌机在x轴随机出现的范围
         self.rect.x = random.randint(0,max_x)
         # 固定敌机在y轴出现的位置
         self.rect.y = -self.rect.height
        def update(self):         super().update()
        # 如果敌机飞出屏幕,则杀死该敌机对象,然后会自动调用__del__方法将其从内存中删除
        if self.rect.y >= SCREEN.height:
             self.kill()
            
    def __del__(self):
        print("敌机已经从内存中销毁..")

编写子弹类

代码语言:javascript
复制
class Bullet(SpriteParent):
    def __init__(self):
         super().__init__('./images/bullet.png')
        def update(self):         self.rect.y -= self.speed
         if self.rect.y <= -self.rect.height:
             self.kill()
            
     def __del__(self):
         print("子弹已经从内存中销毁...")

编写英雄飞机类

代码语言:javascript
复制
class Hero(SpriteParent):
     def __init__(self):
         super().__init__('./images/hero1.png')
         # centerx代表矩形区域在x轴的中心位置
         # 这里设置英雄飞机的初始位置为屏幕底端位于x轴的中间
         self.rect.centerx = SCREEN.rect.centerx
         self.rect.y = SCREEN.rect.height - self.rect.height
         self.bullet_group = pygame.sprite.Goup()
    
     def update(self):
         # 获取从键盘上按下的值
           key_down = pygame.key.get_pressed()
         # 判断按下的值,向对应的方向移动
         # 内部是设置英雄飞机上下左右移动的边界
         if key_down[pygame.K_DOWN]:
             if self.rect.bottom >= SCREEN.height:
                 self.rect.bottom = SCREEN.height
             self.rect.y += 2
         elif key_down[pygame.K_UP]:
             if self.rect.y <= 0:
                 self.rect.y = 0
             self.rect.y -= 2
          elif key_down[pygame.K_LEFT]:
             if self.rect.x <= 0:
                 self.rect.x = 0
             self.rect.x -= 2
         elif key_down[pygame.K_RIGHT]:
             if self.rect.right >= SCREEN.width:
                 self.rect.right = SCREEN.width
             self.rect.x += 2
                
     def fire(self):
        bullet = Bullet()
        # 设置子弹出现的初始位置
        bullet.rect.centerx = self.rect.centerx
        bullet.rect.y = self.rect.y-20
        # 向子弹精灵组中添加子弹精灵
        self.bullet_group.add(bullet)

编写main.py文件

代码语言:javascript
复制
from tools import *
import pygame

class PlaneGame(object):
     def __init__(self):
          pygame.init()
          self.surface = pygame.display.set_mode(0,0,SCREEN.size)
         # 设置游戏时钟对象
         self.clock = pygame.time.Clock()
         self.__create_sprite()
         # 设置定时创建敌机和发射子弹的定时器,1000代表1s
         # 第一个参数为事件编号,第二个参数是定时的时间
         pygame.time.set_timer(CREAT_EVENT,1000)
         pygame.time.set_timer(FIRE_BULLET,1000)
        
     def __create_sprite(self):
          bg1 = Background()
         bg2 = Backgroud(True)
         self.bg_group = pygame.sprite.Group(bg1,bg2)
        
         self.enemy_group = pygame.sprite.Group()
        
         self.hero = Hero()
         self.hero_group = pygame.sprite.Group(self.hero)
        
     def startGame(self):
          # 循环代表游戏开始
          while True:
             # 设置屏幕刷新频率为每秒更新60次,这种频率足以使动画流畅运行
              self.clock.tick(60)
               self.__event_handler()
              self.__check_collide()
              self.__update_sprites()
           # 每次绘制完就要更新一次
            pygame.display.update()
            
     def __event_handler(self):
          # 获取屏幕事件
          for event in pygame.event.get():
              # 如果点击屏幕的退出按钮,则结束游戏
             if event.type == pygame.QUIT:
                  PlaneGame.gemeover()
              # 定时创建敌机
             elif event.type == CREAT_EVENT:
                  enemy = Enemy()
                 self.enemy_group.add(enemy)
              # 定时发射子弹,实现自动射击的效果
             elif event.type == FIRE_BULLET:
                  self.hero.fire()
                    def __check_collide(self):        
        '''碰撞检测'''        pygame.sprite.groupcollide(self.enemy_group,self.hero.bullet_group,True,True)
          # 精灵与精灵组内的精灵产生碰撞,会返回与精灵碰撞的精灵对象
         enemies = pygame.sprite.spritecollide(self.hero,self.enemy_group,True)
         # 如果enemies有值,说明敌机与英雄飞机产生碰撞,那么杀死英雄飞机,游戏结束
         if enemies:
             self.hero.kill()
             PlaneGame.gemeover()
                def __update_sprites(self):        # 更新和绘制精灵组中所有精灵的位置
        self.bg_group.update()
         self.bg_group.draw(self.surface)
        
         self.enemy_group.update()
         self.enemy_group.draw(self.surface)
        
         self.hero_group.update()
         self.hero_group.draw(self.surface)
        
         self.hero.bullet_group.update()
         self.hero.bullet_group.draw(self.surface)
        
     # 静态方法,因为该方法内不需要传入任何属性或类对象    
     @ staticmethod
     def gameOver():
          print("游戏结束...")
         pygame.quit()
         exit()
# 主程序的入口    
if __name__ == "__main__":    pg = PlaneGame()    pg.startGame()

总结

虽然这是一个不完整的飞机大战,但是基本功能已经实现,对于刚入门的人(比如我)来说,做完还是会有点小小成就感的。游戏素材可以自行去网上下载,里面有些参数需要根据图片的大小来进行设置。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-02-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 佛系编程人 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 实战项目:飞机大战
    • 项目目标:
      • 项目描述:
        • 项目实现环境:
          • 项目中所使用的库或模块:
            • 项目需求:
              • 项目准备:创建文件
                • 代码编写
                  • 如何创建屏幕
                  • 如何导入图片,创建图片对象
                  • 如何将图片绘制到屏幕上
                  • 如何更新屏幕
                  • 如何创建精灵组
                  • 精灵组的三个方法
                  • 如何碰撞检测
                • 编写tools.py文件代码
                  • 常量部分
                  • 编写精灵类
                  • 编写背景类
                  • 编写敌机类
                  • 编写子弹类
                  • 编写英雄飞机类
                • 编写main.py文件
                  • 总结
                  领券
                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档