首页 > 编程语言 >Python学习笔记50:游戏篇之外星人入侵(十一)

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

时间:2024-08-02 20:52:58浏览次数:13  
标签:游戏 Python text screen 50 外星人 game setting pygame

前言

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

状态

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

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

我们通过一个字段进行控制,并且将这个字段放置到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()

运行效果如下:

在这里插入图片描述

结尾

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

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

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

标签:游戏,Python,text,screen,50,外星人,game,setting,pygame
From: https://blog.csdn.net/weixin_48668564/article/details/140878741

相关文章

  • python——functools
    好的,我们再详细讲解functools模块的常用工具,包括每个API的语法和参数,并特别详细解释lru_cache的工作原理及其缓存机制。functools简介functools模块提供了许多高阶函数和工具,用于操作或返回其他函数,帮助我们更方便地进行函数式编程。1.partial函数partial函数用于固定......
  • Python中类的三种重要装饰器
    Python中类的三种重要装饰器:classmethod、staticmethod和property。这些装饰器用于定义不同类型的方法和属性,能大大增强类的功能和灵活性。一、classmethod装饰器1.什么是classmethod?classmethod装饰器用于将一个方法绑定到类上,而不是实例上。换句话说,通过classm......
  • Python——继承
    一、继承1.什么是继承?继承是一种面向对象编程的机制,允许一个类(子类)从另一个类(父类)继承属性和方法。子类可以扩展或修改父类的功能。2.如何实现继承?在Python中,实现继承非常简单,只需要在定义子类时将父类作为参数传递即可。示例classAnimal:def__init__(self,......
  • 《从零开始:使用Python构建简单Web爬虫》
    前言随着互联网信息的爆炸性增长,如何高效地获取和处理这些数据变得越来越重要。Web爬虫作为一种自动化工具,可以帮助我们快速抓取所需的网页内容。本文将介绍如何使用Python编写一个简单的Web爬虫,并通过实例演示其基本用法。准备工作Python环境:确保你的计算机上已经安装......
  • NewStarCTF WEEK5|WEB pppython?
    对源码进行简单的分析<?php//检查`hint`请求参数是否等于指定的数组值if($_REQUEST['hint']==["your?","mine!","hint!!"]){//如果条件满足,设置响应内容类型为纯文本header("Content-type:text/plain");//执行系统命令`ls/-la`列出......
  • 【眼疾病识别】图像识别+深度学习技术+人工智能+卷积神经网络算法+计算机课设+Python+
    一、项目介绍眼疾识别系统,使用Python作为主要编程语言进行开发,基于深度学习等技术使用TensorFlow搭建ResNet50卷积神经网络算法,通过对眼疾图片4种数据集进行训练('白内障','糖尿病性视网膜病变','青光眼','正常'),最终得到一个识别精确度较高的模型。然后使用Django框架开发Web网......
  • Python:第三课:重要API - 集合类
    列表-list可以用来存储内容可变长度可变类型可以不同有序的数据的数据结构。类似于java中的List列表的基本使用:##定义列表l1=[1,2,3,"a","b","c",True,False]##访问列表print(l1[4])print(l1[3:6])print(l1[3:])print(l1[:6])print(l1[-2])##更新列表l1[4......
  • python如何获取期权行情数据
    最近几天股指期权日内趋势比较明显,但是期权行情数据不易获得,好在akshare库为提供了一个便捷的途径来获取期权行情数据。本文将介绍如何使用Python和akshare库来获取交易所金融期权标的物当日行情数据、返回品种所有合约以及期权行情分钟数据。1.获取上海证券交易所金融期......
  • 如何更改 python-prompt-toolkit 中聚焦按钮的颜色
    我正在使用python-prompt-toolkit在Python中构建一个音乐播放器。我想改变聚焦按钮的颜色,但我不太明白。为了实现这一点,我尝试查看buttons.py.在其GitHub上给出的示例中,给出的颜色是红色,但是当我将其更改为绿色时,它不会改变,即保持红色。任何帮助,将不胜感激。......
  • 为什么大环境下,建议你去学python?
    在工作中,你应该听过不少这样的话:“我的这份工作太辛苦了,真不是人干的。真羡慕你,你的工作太好了。”他们预设立场,认为自己的工作是天底下最辛苦最委屈的,而别人的工作特别容易。但实际上:没有一份工作不辛苦。辛苦,是每一个人的常态事实上,所有的工作背后,都避免不了辛苦和......