Python学习笔记50:游戏篇之外星人入侵(十一)

news2024/11/24 22:44:40

前言

本篇文章接着之前的内容,继续对游戏功能进行优化,主要是优化游戏状态以及对应的处理。

状态

一个游戏包含多种状态,这个状态是一个可以很复杂也可以很简单的内容。条件所限,我们这个游戏的状态就比较简单:

  • 未开始
  • 游戏中
  • 暂停
  • 结束

我们通过一个字段进行控制,并且将这个字段放置到setting模块中。

class Setting:
    """系统设置类"""
    def __init__(self):
       -- snip --
        # 游戏状态:0未开始,1游戏中,2暂停,3结束
        self.game_status = 0

处理状态

根据不同的状态值,我们先对main模块进行简单的处理。

import pygame
from pygame.sprite import Group

import alien_invasion.game_functions as gf
from alien_invasion.setting import Setting
from alien_invasion.ship import Ship


def run_game():
    """启动游戏"""

    # 初始化pygame
    pygame.init()
    # 定义一个系统设置对象
    setting = Setting()
    # 新建窗口
    screen = pygame.display.set_mode((setting.screen_width, setting.screen_height))
    # 窗口命名
    pygame.display.set_caption(setting.caption)
    # 定义一个飞船对象
    ship = Ship(setting, screen)
    # 创建子弹编组
    bullets = Group()
    # 创建外星人编组
    aliens = Group()
    # 创建编组内的外星人
    gf.create_fleet(setting, screen, aliens)

    while True:
        if setting.game_status == 0:
            pass
        elif setting.game_status == 1:
            # 处理监听事件
            gf.check_event(ship, setting, screen, bullets)
            # 移动飞船
            ship.move()
            # 更新子弹位置
            gf.update_bullets(bullets, aliens, setting, screen)
            # 更新外星人
            gf.update_aliens(aliens, setting, ship)
            # 刷新屏幕
            gf.update_screen(setting, screen, ship, bullets, aliens)
        elif setting.game_status == 2:
            pass
        elif setting.game_status == 3:
            pass


if __name__ == '__main__':
    run_game()

状态对应的业务

现在,我们要对状态思考响应的游戏业务。

这里直接描述一下我个人简单预定的功能:

  1. 启动游戏,弹出窗口,显示欢迎来到游戏,按回车键开始游戏。其他所有按键不生效。
  2. 在游戏中,按下回车暂停游戏;暂停游戏时按下回车继续游戏
  3. 开始游戏后,任意时刻按下Esc键退出游戏,回到黑色窗口,显示游戏介绍,暂停一秒关闭游戏。

代码实现

我们在第二步已经简单的对状态值进行了处理,接下来就根据上面的业务在对应的状态处理部分一一填充。

首先我们处理开始游戏的状态。

开始游戏

首先我们需要在setting.game_status == 0的条件下新建一个not_start()函数,传入参数settingscreen。这两个参数一个是要回写状态值到配置模块中,一个是渲染游戏窗口需要的一些属性。

修改main模块中循环处理的部分如下:

-- snip --
   while True:
        # 没啥用,方便编写代码的时候看看代码执行情况
        print(setting.game_status)
        if setting.game_status == 0:
            # 处理没启动的业务逻辑
            gf.not_start(setting, screen)
        -- snip --

main模块处理好以后,我们在gf模块进行实际的业务代码编写。

在函数中,我们需要完成两个功能,一个是渲染文字,一个是监听按键事件,是否有开始游戏,那么代码编写如下:

def not_start(setting, screen):
    # 先渲染文字
    handle_text(screen)
    print("not_start")
    # 处理监听事件
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_RETURN:
                if setting.game_status == 0:
                    setting.game_status = 1
                    print("开始游戏")

这里监听事件的部分没有单独拉函数出来,主要是不影响阅读,不过因为渲染文字的函数有点行数并且也算一个比较独立的功能,所以又单独创建了一个函数,后面的结束也是如此。

另外虽然我们这个时候只监听是否按下回车键的这个事件,但是点击退出窗口的监听事件,在任何地方都不能忘了,不然到时候可能你的窗口关不了,只能去通过停止程序关闭。

监听事件的代码比较简单的,就是在确认是按下了回车,状态是0的时候,回写状态值即可。

我们看看文字渲染的代码。

文字渲染我们在项目开始之前介绍pygame就提前讲过,相比大家都不陌生,看代码注释即可,代码如下:

def handle_text(screen):
    # 字体颜色
    pink = pygame.Color('#FFFFFF')

    # 使用Arial字体创建一个字体对象,32号,加粗,倾斜
    font = arial_bold = pygame.font.SysFont('Arial', 32, bold=True, italic=True)

    # 渲染文本
    text_surface1 = font.render("Welcome to the Game Of Alien Invasion", True, pink)

    # 获取文件的矩形区域
    text_rect1 = text_surface1.get_rect()

    # 设置文本Y坐标320,居中位置
    text_rect1.midtop = (screen.get_width() // 2, 320)

    # 渲染文本
    text_surface2 = font.render("Press The Enter Key To Start The Game", True, pink)

    # 获取文件的矩形区域
    text_rect2 = text_surface2.get_rect()

    # 设置文本Y坐标420,居中位置
    text_rect2.midtop = (screen.get_width() // 2, 420)

    # 绘制文本
    screen.blit(text_surface1, text_rect1)
    screen.blit(text_surface2, text_rect2)

    # 更新显示
    pygame.display.flip()

运行main模块,按下回车。

在这里插入图片描述
可以看到文字正常渲染,并且输出栏一直在出输出当前状态。

如果你觉得画面单调,可以自己加点东西渲染,pygame渲染图片这些相比也不陌生了。

按下回车,游戏正常开始!

在这里插入图片描述
可以看到,已经进入到游戏页面,并且输出栏的状态值也变成了1。

游戏中

游戏中的处理比较简单,因为我们之前已经完成了游戏中的代码编写,所以我们只需要在游戏中的监听事件中加上回车键的监听事件暂停游戏。

ps: 这里其实也可以结束游戏,代码我先写上,但是不操作。业务代码也不复杂,就是多加一个Esc键的监听事件。

gf模块中的check_keydown_events()函数代码修改如下:

def check_keydown_events(event, ship, setting, screen, bullets):
    """响应按键"""
    if event.key == pygame.K_RIGHT:
        ship.moving_right = True
    elif event.key == pygame.K_LEFT:
        ship.moving_left = True
    elif event.key == pygame.K_UP:
        ship.moving_top = True
    elif event.key == pygame.K_DOWN:
        ship.moving_bottom = True
    elif event.key == pygame.K_SPACE:
        fire(bullets, screen, setting, ship)
    elif event.key == pygame.K_q:
        sys.exit()
    elif event.key == pygame.K_RETURN:
        if setting.game_status == 1:
            setting.game_status = 2
            print("暂停游戏")
    elif event.key == pygame.K_ESCAPE:
        setting.game_status = 3
        print("游戏结束")

启动main模块,开始游戏后再按回车,效果如下:

在这里插入图片描述

可以看到,我们的飞船,子弹,外星人全部暂停住了,输出栏一直打印状态也变成了2(暂停)。

屏幕中显示了一些文字,这些其实是暂停的业务。

我们马上进行暂停的业务代码编写。

暂停游戏

参考开始游戏的实现,我们在暂停的分支下调用一个函数stop()

main模块循环部分代码如下:

	-- snip --
    while True:
        # 没啥用,方便编写代码的时候看看代码执行情况
        print(setting.game_status)
        if setting.game_status == 0:
            # 处理没启动的业务逻辑
            gf.not_start(setting, screen)
        elif setting.game_status == 1:
            # 处理监听事件
            gf.check_event(ship, setting, screen, bullets)
            # 移动飞船
            ship.move()
            # 更新子弹位置
            gf.update_bullets(bullets, aliens, setting, screen)
            # 更新外星人
            gf.update_aliens(aliens, setting, ship)
            # 刷新屏幕
            gf.update_screen(setting, screen, ship, bullets, aliens)
        elif setting.game_status == 2:
            gf.stop(setting, screen)
        -- snip --

同样,我们去到gf模块创建stop()函数并实现相应的功能,代码如下:

-- snip --
def stop(setting, screen):
    handle_stop_text(screen)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_RETURN:
                if setting.game_status == 2:
                    setting.game_status = 1
                    print("继续游戏")
            elif event.key == pygame.K_ESCAPE:
                setting.game_status == 3:
                print("结束游戏")
-- snip --

代码依旧分两部分实现,渲染文字和监听事件。在暂停的监听事件中我们和开始一样,监听关闭窗口,回车和结束,并在回车事件中回写状态值,让游戏继续运行,在Esc时间中结束游戏。

文字渲染部分代码如下:

def handle_stop_text(screen):
    # 字体颜色
    pink = pygame.Color('#000000')

    # 使用Arial字体创建一个字体对象,32号,加粗,倾斜
    font = arial_bold = pygame.font.SysFont('Arial', 32, bold=True, italic=True)

    # 渲染文本
    text_surface1 = font.render("Game Stop", True, pink)

    # 获取文件的矩形区域
    text_rect1 = text_surface1.get_rect()

    # 设置文本Y坐标50,居中位置
    text_rect1.midtop = (screen.get_width() // 2, 320)

    # 渲染文本
    text_surface2 = font.render("Press The Enter Key To restore The Game", True, pink)

    # 获取文件的矩形区域
    text_rect2 = text_surface2.get_rect()

    # 设置文本Y坐标50,居中位置
    text_rect2.midtop = (screen.get_width() // 2, 420)

    # 绘制文本
    screen.blit(text_surface1, text_rect1)
    screen.blit(text_surface2, text_rect2)

    # 更新显示
    pygame.display.flip()

基本上就是复制开始的文字渲染,改了下文字内容。

效果的话这里就不展示了,就是暂停开始,开始暂停这一套。

结束游戏

在游戏中和暂停的时候,我们都可以通过按键Esc实现游戏结束。

main模块的改动依旧是调用一个结束函数,但是结束函数不需要回写状态值,所以我们只需要一个screen参数。

代码如下:

while True:
    # 没啥用,方便编写代码的时候看看代码执行情况
    print(setting.game_status)
    if setting.game_status == 0:
        # 处理没启动的业务逻辑
        gf.not_start(setting, screen)
    elif setting.game_status == 1:
        # 处理监听事件
        gf.check_event(ship, setting, screen, bullets)
        # 移动飞船
        ship.move()
        # 更新子弹位置
        gf.update_bullets(bullets, aliens, setting, screen)
        # 更新外星人
        gf.update_aliens(aliens, setting, ship)
        # 刷新屏幕
        gf.update_screen(setting, screen, ship, bullets, aliens)
    elif setting.game_status == 2:
        gf.stop(setting, screen)
    elif setting.game_status == 3:
        gf.end(screen)

gf模块改动如下:

def end(screen):
    # 重新填充屏幕
    screen.fill((0, 0, 0))
    # 渲染文字
    handle_end_text(screen)
    # 休眠一秒
    sleep(1)
    # 退出
    pygame.quit()
    sys.exit()

和之前比对有一点不同,多了几部,其实没有特别含义,就是看起来流畅好看一点。

文字渲染代码如下:

def handle_end_text(screen):
    # 字体颜色
    pink = pygame.Color('#FFFFFF')

    # 使用Arial字体创建一个字体对象,32号,加粗,倾斜
    font = arial_bold = pygame.font.SysFont('Arial', 48, bold=True, italic=True)

    # 渲染文本
    text_surface1 = font.render("Game Over", True, pink)

    # 获取文件的矩形区域
    text_rect1 = text_surface1.get_rect()

    # 设置文本Y坐标50,居中位置
    text_rect1.midtop = (screen.get_width() // 2, screen.get_height() // 2)

    # 绘制文本
    screen.blit(text_surface1, text_rect1)

    # 更新显示
    pygame.display.flip()

运行效果如下:

在这里插入图片描述

结尾

今天的内容就是这些,设定状态值,并且在对应的状态中处理不同的逻辑,渲染不同的画面。

当然我们是学习,所以内容都比较简单,有兴趣的话可以深入一下加点自己的元素进去。

后面我们继续优化游戏功能,加油!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1986302.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

log4j反序列化-流程分析

分析版本 JDK8u141 依赖 <dependencies><!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core --><dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-core</artifactId><ve…

三、1 一维数组的创建和初始化

数组是一组相同类型元素的集合 1、数组的创建 2、数组的初始化 在创建数组的同时&#xff0c;给数组内容一些合理的值 3、一维数组的使用 4、一维数组在内存中的存储 数组的内容在内存中连续存放

sqli靶场复现(1-8关)

目录 1.sqli-labs第二关 1.判断是否存在sql注入 1.1你输入数字值的ID作为参数&#xff0c;我们输入?id1 1.2在数据库可以查看到users下的对应内容 2.联合注入 2.1首先知道表格有几列&#xff0c;如果报错就是超过列数&#xff0c;如果显示正常就是没有超出列数。 2.2得…

模拟一次XFS故障,分析原因并进行修复

模拟一次XFS故障 在平常处理问题时经常会遇到文件系统损坏的问题&#xff0c;有时候是日志里面出现了报错但文件系统还是可以读写&#xff0c;有时候是文件系统已经无法读写了 分析下不同现象的原因和一些可能出现的情况。 通过直接修改块存储损坏文件系统 1、制作一个xfs文…

Pytorch基础模型,数据加载,优化算法

目录 一.nn.Module 二.优化器类 三.损失函数 四.在GPU上运行代码 五.常见的优化算法 1.梯度下降算法 2.动量法&#xff1a; 3.AdaGrad 4.RMSProp 六.Pytorch中的数据加载 1.数据集类 2.迭代数据集 2.Pytorch自带的数据集 一.nn.Module nn.Modul是torch.nn提供的一个…

嵌入式初学-C语言-十六

形式参数和实际参数 形式参数&#xff08;形参&#xff09; 函数定义时&#xff0c;指定的参数&#xff0c;形参是用来接收数据的&#xff0c;函数定义时&#xff0c;系统不会为形参申请内存&#xff0c;只有当函数调用时&#xff0c;系统才会为形参申请内存&#xff0c;用于存…

信息学奥赛初赛天天练-57-NOIP2018普及组-基础题1-输入输出设备、进制转换、计算机存储单位、 网络地理范围分类、等比数列求和

PDF文档公众号回复关键字:20240806 2019 CSP-J 基础题1 单项选择题&#xff08;共15题&#xff0c;每题2分&#xff0c;共计30分&#xff1a;每题有且仅有一个正确选项&#xff09; 1 以下哪一种设备属于输出设备( ) A 扫描仪 B 键盘 C 鼠标 D 打印机 2 下列四个不同进制的…

PSTNET阅读

ICLR2021 点云序列在空间维度上具有不规则性和无序性&#xff0c;但在时间维度上具有规律性和有序性。 现有的基于网格的卷积不能直接应用于原始点云序列的时空建模。 在时空序列下&#xff0c;基于网格和基于点的卷积对比。 创新点 1.首次尝试在原始点云序列建模中分解空间…

serial靶机教程

靶机下载地址 https://download.vulnhub.com/serial/serial.zip 主机发现 arp-scan -l 端口扫描 nmap 192.168.229.131 -A 根据对⽐可知serial的⼀个ip地址为192.168.47.143 该靶机开启了22端⼝和80端⼝ 对⽹站进⾏⼀个访问&#xff0c;⼤概意思为这是对新的cookie处理程序…

【优秀python案例】基于python爬虫的深圳房价数据分析与可视化实现

现如今&#xff0c;房价问题一直处于风口浪尖&#xff0c;房价的上涨抑或下跌都牵动着整个社会的利益&#xff0c;即便是政府出台各种政策方针也只能是暂时抑制楼市的涨势&#xff0c;对于需要买房的人来说&#xff0c;除了关注这些变化和政策外&#xff0c;还有一个非常头疼的…

工具|阅读PDF时鼠标显示为小手中有向下箭头解决方法

由于工作中&#xff0c;会大量阅读PDF文档&#xff0c;如手册&#xff0c;规格书&#xff0c;各种图纸等&#xff0c;因此好用的PDF工具必不可少。我主要习惯用福昕阅读器&#xff0c;标注比较方便。 所以&#xff0c;本文主要以福昕阅读器为主&#xff0c;当然也适用于其他的阅…

linux文本处理命令:文本搜索工具grep详解

目录 一、概述 二、基本语法 1、语法 2、常用选项 3、获取帮助 三、示例 1. 搜索文件中的字符串 2. 忽略大小写搜索 3. 显示匹配行的行号 4. 反向搜索 5. 递归搜索 6. 使用扩展正则表达式 7. 列出包含匹配项的文件 8. 显示匹配行的上下文 9. 使用正则…

从2013数学建模B题碎纸片拼接问题看递归和迭代思想

目录 1.递归实例说明 2.迭代实例说明 3.迭代思想在碎纸片拼接赛题的运用 1.递归实例说明 斐波那契数列可以使用递归&#xff0c;也可以使用数列的通项公式&#xff0c;但是这个地方建议使用数列的通项公式&#xff0c;因为这个递归的深度过大这个结果很难运行出来&#xff1…

使用WebDAV共享本地文件,轻量易用

特征&#xff1a; 使用 Golang 实现&#xff0c;性能极高。 最终编译成单个二进制文件&#xff0c;不需要 Apache 或类似的环境&#xff0c;依赖性很少。 支持浏览器访问。 可以在同一个端口上启用多个 WebDAV 服务&#xff0c;每个服务具有不同的挂载目录、用户名和密码。 良好…

嵌入式day20

feof&#xff1a; 检测文件是否到达结尾 ferroe&#xff1a; 检测文件是否发生错误 标准IO之文件定位 fseek&#xff08;&#xff09; SEEK_END 指向最后一个字节的后一个&#xff0c;继续加&#xff0c;写文件&#xff0c;会将文件扩大 ftell&#xff08;&#xff09; 获取…

STM32学习笔记1---LED,蜂鸣器

目录 GPIO LED 蜂鸣器 RCC外设 GPIO外设 总概 操作STM32的GPIO 代码 LED闪烁 LED流水灯 蜂鸣器&#xff01; 连接方式 GPIO GPIO输出&#xff1a;向外驱动控制 GPIO输入&#xff1a;读取&#xff0c;捕获&#xff08;信息&#xff09;&#xff08;控制&#xff09…

状压DP,abc359_d - Avoid K Palindrome

一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 D - Avoid K Palindrome 二、解题报告 1、思路分析 数据量&#xff1a;N&#xff1a;1000&#xff0c;K&#xff1a;10 提示我们状态压缩 我们发现长度为K的字符串&#xff0c;我们可以用0表示A&#xff…

vue2项目如何引入element组件库以及如何使用element组件库

目录 一、创建项目二、进入项目1、先进入项目&#xff0c;![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/a1ce9d928fdb4b5d85e6612f458a33db.png)2、路径栏输入cmd&#xff0c;然后回车3、输入code . &#xff0c;然后回车 三、项目启动1、查看启动指令2、启动项目 …

VMwave安装Ubuntu20.04超详细图文教程(附VMwave17.5安装包)

VMwave安装 Ubuntu20.04 超详细图文教程 一、VMwave安装 官网下载 网盘下载 二、Ubuntu下载 三、Ubuntu20.04安装 四、安装VMwave tools 五、更改Ubuntu软件源 注&#xff1a;写教程的时候博主用的是VMware Workstation pro 17(VM17.5) 一、VMwave安装 以下我提供两…

常见中间件漏洞(一、Tomcat合集)

目录 一&#xff0e;Tomcat Tomcat介绍 1.1 CVE-2017-12615 影响范围 环境搭建 漏洞复现 1.2 后台弱口令部署war包 漏洞原理 影响版本 环境搭建 1.3 CVE-2020-1938 漏洞原理 影响版本 环境搭建 漏洞复现 一&#xff0e;Tomcat Tomcat介绍 tomcat是一个开源而且…