Python学习笔记44:游戏篇之外星人入侵(五)

前言

上一篇文章中,我们成功的设置好了游戏窗口的背景颜色,并且在窗口底部中间位置将飞船加载出来了。

今天,我们将通过代码让飞船移动。

移动飞船

  1. 想要移动飞船,先要明白飞船位置变化的本质是什么。

    通过上一篇文章,我们已经知道了飞船实际上是通过在窗口指定x,y坐标轴位置渲染出的一张外接矩形的图片。外接矩形的图片,就是飞船的"本质",移动飞船的本质,就是移动这张图片。

  2. 怎么移动飞船?

    在理解了移动飞船的本质就是移动图片后,我们要做的就是使用代码,实现图片移动的功能。而图片的渲染是通过图片外接矩形的坐标调用blit函数实现的,所以我们想要移动图片,就要修改飞船图片外接矩形的坐标实现,具体到我们的代码就是通过修改属性self.rect.centerxself.rect.bottom的值,调用blit函数重新加载图片,从而实现图片的移动,展现出飞船移动的效果。

    飞船x,y值变化反馈到飞船移动的方向如下(不要搞混了,窗口左上顶点的坐标是(0,0)):

    • 向右移动x坐标值增加
    • 向左移动x坐标值减少
    • 向上移动y坐标值减少
    • 向下移动y坐标值增加

代码编写

在之前基础模块的编写中,我们已经定义了一个move函数,并且用pass进行占位,那么我们就要对这个函数进行业务代码实现编写。

  1. 首先我们需要定义四个标识字段,这几个字段用于标识飞船当前应该往哪移动。这四个字段属于飞船对象自身的属性。

    python 复制代码
      # 移动标志
            self.moving_right = False
            self.moving_left = False
            self.moving_top = False
            self.moving_bottom = False
  2. 我们在move函数中通过当前移动标志的值判断应该往哪里移动,并且进行坐标值的修改。

    python 复制代码
    def move(self):
        """移动飞船"""
        if self.moving_right:
            self.rect.centerx += 1
        if self.moving_left:
            self.rect.centerx -= 1
        if self.moving_top:
            self.rect.bottom -= 1
        if self.moving_bottom:
            self.rect.bottom += 1
  3. 函数修改好以后,我们需要处理监听事件中按键相关的时候。我们按下对应的方向键按钮以后,需要将对应方向移动标识设置与True,弹起按键时设置移动标识为False。

    python 复制代码
    def check_event(ship):
        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_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_q:
                    pygame.quit()
            elif event.type == pygame.KEYUP:
                if event.key == pygame.K_RIGHT:
                    ship.moving_right = False
                elif event.key == pygame.K_LEFT:
                    ship.moving_left = False
                elif event.key == pygame.K_UP:
                    ship.moving_top = False
                elif event.key == pygame.K_DOWN:
                    ship.moving_bottom = False
  4. 在监听事件之后,屏幕更新之前,调用飞船的move函数。

    python 复制代码
    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)
    
        while True:
            # 处理监听事件
            gf.check_event(ship)
            # 移动飞船
            ship.move()
            # 刷新屏幕
            gf.update_screen(setting, screen, ship)
    
    
    if __name__ == '__main__':
        run_game()

这个时候只要你启动服务,按下方向键,你就可以自由的的控制你的飞船了。

边界问题

当你整开始的移动你的飞船的时候,你会突然发现:

实际上,是你的飞船越过了窗口的边界,导致你的飞船消失不见了。因为pygame所有图形和游戏逻辑都将基于这个窗口大小进行计算和渲染。

这个问题怎么解决呢?很简单,在飞船移动的函数中定义,超过边界不允许移动。

优化代码如下:

python 复制代码
def move(self):
    """移动飞船"""
    if self.moving_right and self.rect.right < self.screen_rect.right:
        self.rect.centerx += 1
    if self.moving_left and self.rect.left > self.screen_rect.left:
        self.rect.centerx -= 1
    if self.moving_top and self.rect.top > self.screen_rect.top:
        self.rect.bottom -= 1
    if self.moving_bottom and self.rect.bottom < self.screen_rect.bottom:
        self.rect.bottom += 1

代码中的修改就是对修改坐标的条件增加了一个对应方向的限制。

代码解释如下:

  • 向右移动时,飞船的 边界要在游戏窗口的 边界边才运行飞船向右移动
  • 向左移动时,飞船的 边界要在游戏窗口的 边界边才运行飞船向左移动
  • 向上移动时,飞船的 边界要在游戏窗口的 边界边才运行飞船向左移动
  • 向下移动时,飞船的 边界要在游戏窗口的 边界边才运行飞船向左移动

重新启动,你就会发现你的飞船在窗口边界不会再移动了。

结尾

那么到目前为止,我们的飞船已经可以在游戏窗口内自由的移动了。

接下来就准备就让我们的飞船发射子弹。

相关推荐
火云洞红孩儿4 小时前
告别界面孤岛:PyMe如何用一站式流程重塑Python GUI开发?
开发语言·python
攻城狮7号4 小时前
不懂代码也能造?TRAE+GLM-4.6 手把手教你搭心理咨询智能客服小程序
python·小程序·uni-app·vue·trae·glm我的编程搭子·glm-4.6
叫我辉哥e14 小时前
新手进阶Python:办公看板集成ERP跨系统同步+自动备份+AI异常复盘
开发语言·人工智能·python
●VON4 小时前
0基础也能行!「Flutter 跨平台开发训练营」1月19日正式启动!
学习·flutter·von·openjiuwen
敲敲了个代码4 小时前
如何优化批量图片上传?队列机制+分片处理+断点续传三连击!(附源码)
前端·javascript·学习·职场和发展·node.js
布局呆星5 小时前
闭包与装饰器
开发语言·python
全栈测试笔记5 小时前
异步函数与异步生成器
linux·服务器·前端·数据库·python
橙河网络5 小时前
橙河网络:海外问卷安全类问卷调查怎么做?
网络·经验分享·笔记·课程设计
木头左5 小时前
基于Backtrader框架的指数期权备兑策略实现与分析
python
知识分享小能手5 小时前
Oracle 19c入门学习教程,从入门到精通,Oracle 其他数据对象 —— 语法详解与综合实践(11)
数据库·学习·oracle