美文网首页
利用pygame制作小游戏

利用pygame制作小游戏

作者: MathCEC | 来源:发表于2019-02-02 14:41 被阅读0次
    Notification:我不是专门写Python的,只是看到这个拓展有点好玩,有什么不规范的地方,还请批评指正

    1. 目录结构

    ├── action
    │   ├── boom.py # 炸弹类
    │   ├── game.py # 游戏全局类
    │   ├── main.py # 实体入口类
    │   ├── plane.py # 飞机类
    │   └── target.py # 目标船只类
    ├── conf 
    │   ├── score.py # 记分板
    │   └── settings.py # 配置文件
    ├── event  
    │   └── event_function.py # 事件监控
    ├── main.py # 入口文件 完成编码后在次页执行run
    └── plugs
        ├── shape_function.py # 在画布上展示图形
        └── text_function.py # 在画布上书写文字
    

    2、前提

    使用python制作小游戏,需要安装 pygame 拓展,我比较懒,所以一般直接使用pip命令安装,这里也是一样

    pip install pygame # 我使用的是anaconda自带的控制台
    

    3、环境

    我比较喜欢用jet brains的产品,于是我这里使用的是pycharm

    4、思路

    此次试水开发的小游戏很简陋,初中的时候,微机课,电脑上只有一个展示平抛运动的小游戏,在这里,我就用最简单的方法重现。

    5、编码

    5.1、首先是入口文件
    # 路径 ./main.py
    import pygame
    import event.event_function as ef
    from conf.settings import Settings
    from action.main import Main
    # 初始化
    pygame.init()
    # 读取基础配置
    settings = Settings() # 配置文件其实也是个python类(5.2)
    # 初始化游戏北京
    screen = pygame.display.set_mode((settings.screen_width,settings.screen_height))
    # 初始化基础背景色
    screen.fill(settings.screen_color)
    # 初始化各种对象 这是我的编码习惯(使用一个对象包容其他对象)(5.3)
    main = Main()
    while True:
        #事件监控
        ef.main_event(main)
        #刷新
        screen.fill(settings.screen_color)
        #动作
        main.action(screen)
        #刷新
        pygame.display.update()
    
    5.2、然后是配置文件
    # 路径 ./conf/settings.py
    class Settings:
        def __init__(self):
            #全局配置
            #游戏名
            self.game_name = 'Plane Boom'
            #游戏屏宽
            self.screen_width = 1200
            #游戏屏高
            self.screen_height = 800
            #游戏主背景色
            self.screen_color = (0,0,0)
    
            #关于飞机的配置
            #飞机水平飞行速度
            self.plane_speed = 5
            #飞机距离上边界的距离
            self.plane_height = 50
    
            #关于飞机投掷炸弹的配置
            #炸弹下落的重力加速度(如果太大 不利于监测爆炸事件)
            self.boom_g = .5
            #系统刷新需要增加的时间
            self.boom_time_add = .5
            #炸弹的爆炸范围
            self.boom_range = 50
    
            #目标船只的配置
            #船距离上边界的距离
            self.boat_top = 650
            #可以生成船的初始水平位置
            self.boot_range_start = 300
            #可以生成船的结束水平位置
            self.boot_range_end = 1200
    
    5.3、所有类的主入口类
    # 路径 ./action/main.py
    from action.game import Game
    from action.target import Target
    from action.plane import Plane
    from action.boom import Boom
    from conf.score import Base
    class Main:
        def __init__(self):
            #初始化所有类 方便对类中属性的修改 同时也保证整个系统之 所有类只有一个对象
            self.game = Game() # (5.4)
            self.target = Target() # (5.5)
            self.plane = Plane()  #(5.6)
            self.boom = Boom() #(5.7)
            self.base = Base() #(5.8)
    
    
        # 供入口文件调用
        def action(self,screen):
            self.game.action(screen)
            self.target.action(screen)
            self.plane.action(screen)
            self.boom.action(screen,self)
            self.base.action(screen)
    
    5.4、全局类
    # 5.4 - 5.7 全部位于action目录下
    import plugs.text_function as tf
    class Game:
        def __init__(self):
            # 游戏是否开始
            self.open = False
        # 主要用来控制游戏的开始与结束
        def action(self,screen):
            if not self.open:
                # 大标题
                tf.draw_main_title(screen,'PLANE BOOM') 
                # 小标题
                tf.draw_sub_title(screen,'press space to continue')
            if self.open:
                # 提示语
                tf.draw_tips(screen,'press esc to end the game')
    
    5.5、目标船只类
    import random
    
    import plugs.shape_function as sf
    from conf.settings import Settings
    
    
    class Target:
        def __init__(self):
            #读取配置文件
            self.settings = Settings()
            # 船的初始位置
            self.left = -100
            self.top = self.settings.boat_top
            #判断是否已经存在一艘船(或者可以理解为本艘船是否存在)
            self.has_one = False
        def action(self,screen):
            # 逻辑:当屏幕上没有小船的时候 则随机一个小船的水平位置 如果有则跳过
            if not self.has_one:
                self.left = random.uniform(self.settings.boot_range_start,self.settings.boot_range_end)
                self.has_one = True
             #出现draw的基本都为plugs中的函数
            sf.draw_boat(screen,self.left,self.top)
    
    
    5.6、飞机类
    import plugs.shape_function as sf
    from conf.settings import Settings
    class Plane:
        def __init__(self):
            #与setting有关的 参考配置文件
            self.settings = Settings()
            self.speed = self.settings.plane_speed
            self.top = self.settings.plane_height
            self.left = 0
        def action(self,screen):
            #逻辑 飞机循环飞行 从左到右
            sf.draw_plane(screen,self.left,self.top)
            if self.left >=  self.settings.screen_width:
                self.left = 0
            else:
                self.left += self.speed
    
    5.7、炸弹类
    # 这个类是最复杂的
    # 此处假设Boom只能有一个
    import plugs.shape_function as sf
    from conf.settings import Settings
    class Boom:
        def __init__(self):
            self.settings = Settings()
            self.left = -100
            self.top = -100
            # 判断是否需要创建一颗炸弹
            self.init_a_boom = False
            # 判断本炸弹是否存在
            self.has_one = False
            # 炸弹的水平速度
            self.speed_x = 0
            # 累计下落时间
            self.time = 0
            # 判断炸弹是否需要爆炸
            self.need_explode = False
        def action(self,screen,main):
            # 初始化一颗炸弹
            if self.init_a_boom and not self.has_one:
                # 出生位置水平跟随飞机
                self.left = main.plane.left
                # 不再需要初始化
                self.init_a_boom = False
                # 已经有了一颗
                self.has_one = True
                # 获取水平速度
                self.speed_x = main.plane.speed
                # 获取竖直高度
                self.top = main.plane.top
                # 后台提示
                print('开始投弹')
            # 判断是否需要移动炸弹
            if self.has_one:
                # 水平位移
                self.left += self.speed_x
                # 竖直位移
                self.top = main.plane.top + 0.5*self.settings.boom_g*self.time*self.time
                # 时间流逝
                self.time += self.settings.boom_time_add
                # print(self.top,self.time)
               # 刷新炸弹
                sf.draw_boom(screen,self.left,self.top)
                # print(main.target.top - self.settings.boom_range,self.top,main.target.top - self.settings.boom_range,main.target.top,self.left,main.target.left)
                # 炸弹是否击中目标
                if (main.target.top - self.settings.boom_range <= self.top <= main.target.top + self.settings.boom_range) and (
                        main.target.left - self.settings.boom_range <= self.left <= main.target.left + self.settings.boom_range):
                    # 引爆
                    self.need_explode = True
                    print('击中目标')
                    # 没了
                    main.target.has_one = False
                    # 加分
                    main.base.score += 1
                # 炸弹越界或者集中目标需要爆炸
                if self.top > self.settings.screen_height or self.need_explode:
                    # 没了
                    self.has_one = False
                    # 等待下一颗炸弹的初始化
                    self.init_a_boom = False
                    # 已经爆炸了 为下一次准备
                    self.need_explode = False
                    # 时间清零
                    self.time = 0
                    print('炸弹爆炸')
    
    
    
    5.8、记分板
    # ./conf/score
    class Base:
        def __init__(self):
            self.score = 0
        def action(self,screen):
            import plugs.text_function as tf
            tf.draw_score(screen,self.score)
    
    5.9、事件监听
    # 监听键盘事件 进行反馈
    import pygame
    import sys
    def main_event(main):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()
            #监控按下按钮事件
            if event.type == pygame.KEYDOWN:
                press_down(event,main)
    
    # 按下事件
    def press_down(event,main):
        # 空格
        if event.key == pygame.K_SPACE:
            print('开始游戏')
            main.game.open = True
            main.boom.init_a_boom = True
        # esc
        if event.key == pygame.K_ESCAPE:
            print('退出游戏')
            main.game.open = False
    

    6、启动

    在./main.py文件中右键 run 就可以跳出一个窗体尽兴玩耍了

    相关文章

      网友评论

          本文标题:利用pygame制作小游戏

          本文链接:https://www.haomeiwen.com/subject/vvpssqtx.html