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

news2024/9/24 0:27:05

前言

到目前为止,飞船,子弹,外星人的创建,移动都已经完成。接下来我们需要完成功能主要就是子弹击中外星人和飞船接触到外星人两个中功能。

碰撞

我们需要实现的功能中,子弹击中外星人和飞船接触外星人本质上就是两个对象的边界互相接触。如果是单个对象,我们可以使用外接矩形的坐标来进行对象接触的判定,但是子弹和外星人的数量都是多个的,这要怎么判定它们是否接触呢?

在之前子弹与外星人的代码实现中,因为这两个对象的数量都是多个数量,所以我们使用了精灵组的概念,让对应的类继承sprite,从而实现使用组来控制屏幕中的子弹和外星人。而sprite中,将这种接触定义为碰撞,并带有处理组之间接触碰撞的函数。

pygame.sprite.spritecollideany

pygame.sprite.spritecollideanyPygame 模块中的一个函数,用于检测两个精灵组之间的碰撞。这个函数会检查给定的精灵是否与另一个精灵组中的任何精灵发生碰撞。

参数说明

  • sprite: 你要检测其是否与其他精灵发生碰撞的单个精灵对象。
  • group: 一个精灵组,pygame.sprite.Group 对象,其中包含了多个精灵。
  • collided: 可选参数,一个回调函数,用于自定义碰撞检测逻辑。如果未提供,则使用默认的矩形碰撞检测。

返回值

  • 如果 sprite 与 group 中的任意精灵发生碰撞,则返回第一个发生碰撞的精灵;如果没有发生碰撞,则返回 None。

这个函数是用于单个单个精灵对象与精灵组之间的碰撞。那么在飞船与外星人的碰撞判断中,我们可以使用这个函数。

pygame.sprite.groupcollide

pygame.sprite.groupcollide 是 Pygame 中的一个函数,用于检测两个精灵组之间的碰撞。当你需要检查一组精灵是否与另一组精灵中的任何精灵发生碰撞时,这个函数非常有用。

参数说明

  • group1: 第一个精灵组,通常为 pygame.sprite.Group 类型。
  • group2: 第二个精灵组,同样为 pygame.sprite.Group 类型。
  • dokill1: 布尔值,如果为 True,则在发生碰撞后,group1 中的精灵将被销毁。
  • dokill2: 布尔值,如果为 True,则在发生碰撞后,group2 中的精灵将被销毁。
  • collided: 可选参数,一个回调函数,用于自定义碰撞检测逻辑。如果未提供,则使用默认的矩形碰撞检测。
    返回值
  • 函数返回一个字典,其中键是 group1 中的精灵,值是与该精灵发生碰撞的 group2 中的精灵列表。

看看多贴心,甚至将碰撞的精灵(对象)都给你销毁了。

这个函数很明显,就非常适合于子弹与外星人的碰撞处理。

那么,开始进行我们实际的代码编写吧!

子弹击中外星人

作为子弹与外星人的碰撞,子弹是主动的一方,去撞击外星人,所以我们直接在子弹更新的函数中,对其与外星人进行碰撞处理。

那么我们的代码要作出如下改动:

  • main模块中,更新子弹位置的函数需要增加一个外星人组的参数,用与碰撞。
  • gf模块中,更新子弹的函数中,调用函数 pygame.sprite.groupcollide

main模块修改gf.update_bullets()参数,代码如下:

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():
    """启动游戏"""

  --snip--
  
    while True:
        # 处理监听事件
        gf.check_event(ship, setting, screen, bullets)
        # 移动飞船
        ship.move()
        # 更新子弹位置
        gf.update_bullets(bullets, aliens)
        # 更新外星人
        gf.update_aliens(aliens, setting)
        # 刷新屏幕
        gf.update_screen(setting, screen, ship, bullets, aliens)


if __name__ == '__main__':
    run_game()

gf模块更新子弹函数处理碰撞,代码如下:


  --snip--

def update_bullets(bullets, aliens):
    """更新子弹"""
    bullets.update()
    # 删除已经消失的子弹
    for bullet in bullets.copy():
        # 当子弹矩形底部坐标小于0,说明子弹已经出了上边界
        if bullet.rect.bottom <= 0:
            bullets.remove(bullet)
    pygame.sprite.groupcollide(bullets, aliens, True, True)

  --snip--

在子弹击中后,子弹与外星人同时消失。

此时运行main模块,按下空格发射子弹,等待子弹命中外星人,就能发现外星人与子弹同时消失不见。

效果如下:

在这里插入图片描述

外星人撞击飞船

通常我们这类的游戏设定,是不允许飞船与外星人的接触的,假如接触到,外星人没影响,飞船可能会损害或者直接坠毁。基于这种逻辑,我们在编写外星人与飞船的碰撞给代码时,将碰撞处理编写在外星人的位置变化中,模拟一种外星人主动去撞击飞船的逻辑(类似子弹主动撞击外星人)。

同样,我们要做出如下更改:

  • main模块中,调用外星人移动的函数,需要添加一个飞船的参数
  • gf模块中,外星人移动的函数中进行碰撞处理
  • ship模块中,编写一个居中飞船的函数,废船碰撞后回到底部中央。

main模块修改gf.update_aliens()参数,代码如下:

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():
    """启动游戏"""

  --snip--
  
    while True:
        # 处理监听事件
        gf.check_event(ship, setting, screen, bullets)
        # 移动飞船
        ship.move()
        # 更新子弹位置
        gf.update_bullets(bullets, aliens)
        # 更新外星人
         gf.update_aliens(aliens, setting, ship)
        # 刷新屏幕
        gf.update_screen(setting, screen, ship, bullets, aliens)


if __name__ == '__main__':
    run_game()

gf模块更新外星人函数处理碰撞,代码如下:


  --snip--


 def update_aliens(aliens, setting, ship):
   check_fleet_edges(aliens, setting)
   aliens.update()
   # 碰撞后处理后续逻辑
   if pygame.sprite.spritecollideany(ship, aliens):
       # 飞船回到底部中央
       ship.center_ship()
       # 休眠1帧
       sleep(1)

  --snip--

与子弹与外星人的碰撞不同,外星人撞击到飞船以后,外星人不做处理,但是飞船需要回到底部中央位置,同时游戏暂停1秒。

ps:这里后面可以进行更丰富的处理,比如减少飞船生命值,减少飞船可用数量的等。

ship模块更新重置飞船位置的函数,代码如下:

import pygame


class Ship:
    def __init__(self, setting, screen):
        """初始化飞船"""
        self.screen = screen
        self.setting = setting
        # 加载图片并外接矩形
        self.image = pygame.transform.scale(
            pygame.image.load('E:/python_project/alien_invasion/assets/image/ship.bmp'), (50, 50))
        # 飞船外接的矩形
        self.rect = self.image.get_rect()
        # 窗口矩形
        self.screen_rect = screen.get_rect()
        # 将每艘新飞船放在屏幕底部中央
        self.rect.centerx = self.screen_rect.centerx
        self.rect.bottom = self.screen_rect.bottom
        # 移动标志
        self.moving_right = False
        self.moving_left = False
        self.moving_top = False
        self.moving_bottom = False
        
	--sinp--

    def center_ship(self):
        """飞船居中"""
        self.rect.centerx = self.screen_rect.centerx
        self.rect.bottom = self.screen_rect.bottom

完成这些代码以后,照例启动main模块,这次我们主动驾驶飞船撞击外星人。

在撞击的瞬间,游戏会暂停一秒,然后飞船回到底部中央。

在这里插入图片描述

在这里插入图片描述
如上两图所示。

结尾

子弹击中外星人,外星人撞击飞船的逻辑我们完成了。到这里,游戏的基础功能就算搭建完了。

后续会对游戏功能优化,比如外星人全部击中,飞船数量限制乃至于计分,开始按钮,暂停按钮等等。

背景音乐也可以弄,其实很简单,难的是找到合适的音乐。

今天的内容就到这里,加油大家!!!

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

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

相关文章

Navicat For Mysql连接Mysql8.0报错:客户端不支持服务器请求的身份验证协议

windows通过navicat连接本地mysql时报错:Client does not support authentication protocol requested by server; consider upgrading MySQL client 一、问题原因二、解决方法1--失败1. 连接mysql客户端2. 修改加密方式3.正确的解决方法1.查找my.ini文件2.修改my.ini文件3.重…

【读点论文】Object Detection in 20 Years: A Survey,宏观了解大方向发展,常看常新,这篇越看到后面越泛

Object Detection in 20 Years: A Survey Abstract 目标检测作为计算机视觉领域最基本、最具挑战性的问题之一&#xff0c;近年来受到了极大的关注。在过去的二十年里&#xff0c;我们目睹了目标检测技术的快速演进及其对整个计算机视觉领域的深远影响。如果说今天的目标检测…

关于RAG进展|| RankRAG:在大模型中统一检索增强生成的上下文排序

欢迎了解公众号&#xff1a;AI论文解读 背景&#xff1a;探索RankRAG的创新之处 检索增强生成&#xff08;Retrieval-Augmented Generation, RAG&#xff09;技术已成为提升大型语言模型&#xff08;Large Language Models, LLMs&#xff09;处理知识密集型任务的关键方法。传…

使用AI大模型Kimi轻松助力速通代理IP知识

本文目录 一、 引言二、代理IP介绍2.1 代理IP定义2.2 代理IP的工作原理2.3 代理IP的分类2.4 2.4 为什么需要代理IP&#xff1f; 三、代理IP的使用场景四、如何选择合适的代理IP服务五、使用代理IP的基本步骤六、使用代理IP爬取亚马逊电商信息七、总结八、代码附录 一、 引言 喜…

怎么使用rdma-core进行调用开发?

RDMA (Remote Direct Memory Access) 是一种网络协议,可以在计算节点之间实现高效的内存数据传输,而无需CPU的干预。rdma-core 是 RDMA 的一个用户空间库,提供了一些简单易用的接口来使用 RDMA 功能。 目录: 一、环境准备: 1.1 安装依赖 在安装 rdma-core 之前,确保你的…

token验证

验证客户端传输过来的请求是否合法 try-catch是用来捕获并处理异常的。当你在编写代码时&#xff0c;可能会遇到一些不可预见的情况&#xff0c;这些情况会阻止代码的正常执行&#xff0c;这时就会抛出异常。使用try-catch语句&#xff0c;你可以捕获这些异常并采取相应的措施来…

【OpenCV C++20 学习笔记】形态学变换(morphologyEx)

TOC 理论 开运算 开运算实际上就是腐蚀之后再膨胀&#xff0c;用公式表达就是&#xff1a; d s t o p e n ( s r c , e l e m e n t ) d i l a t e ( e r o d e ( s r c , e l e m e n t ) ) dstopen(src, element) dilate(erode(src, element)) dstopen(src,element)di…

保研408真题练习:2009年全国硕士研究生入学统一考试(单选篇2)

&#x1f9ca;&#x1f9ca;&#x1f9ca;单项选择题&#xff08;共40道&#xff09; &#x1f9ca;操作系统&#xff08;8道&#xff09; &#x1f965;1.进程调度算法 高响应比优先调度&#xff1a;选出响应比最高的进程投入执行&#xff0c;响应比R(等待时间&#xff0b;执…

钉钉 钉钉打卡 钉钉定位 2024 免费试用 保用

打卡助手定位 如图&#xff0c;表示开启成功&#xff0c;软件已定位到钉钉打卡位置。 测试显示&#xff0c;高德地图位置已成功修改。 开启助手定位后&#xff0c;观察效果&#xff0c;打卡按钮由无法打卡变为可打卡状态&#xff0c;照片还显示打卡地点。 伙伴们担心作弊行为会…

如何使用nodejs的fsPromise.access()判断文件权限

同学们可以私信我加入学习群&#xff01; 正文开始 一种错误示范fsPromise.access正确的书写总结 一种错误示范 我们操作文件的时候&#xff0c;经常需要提前判断文件的状态&#xff1a;文件是否存在、文件是否可读、文件是否可写。 查看官网介绍后&#xff0c;按照我们平时的…

WinRAR右键压缩文件功能消失。有什么方法可以恢复吗?

WinRAR作为一款广受欢迎的压缩软件&#xff0c;以其高效、便捷的特点深受用户喜爱。然而&#xff0c;在使用过程中&#xff0c;有时我们可能会遇到右键菜单中WinRAR的压缩文件功能消失的情况&#xff0c;这无疑给我们的文件操作带来了不便。下面小编就来给大家详细介绍当WinRAR…

【C语言】【计算机组成原理】进制转换和原码、反码、补码

目录 一、进制转换 &#xff08;1&#xff09;数字进制的4个概念 &#xff08;2&#xff09;x进制转换成十进制 &#xff08;3&#xff09;十进制转换成x进制&#xff08;除x取余法&#xff09; &#xff08;4&#xff09;二进制与八进制的相互转换 &#xff08;5&#xf…

【AI落地应用实战】DAMODEL深度学习平台部署+本地调用ChatGLM-6B解决方案

ChatGLM-6B是由清华大学和智谱AI开源的一款对话语言模型&#xff0c;基于 General Language Model (GLM)架构&#xff0c;具有 62亿参数。该模型凭借其强大的语言理解和生成能力、轻量级的参数量以及开源的特性&#xff0c;已经成为在学术界和工业界引起了广泛关注。 本篇将介…

成为 Spring Boot + Vue 图书作者的必备素养

个人名片 🎓作者简介:java领域优质创作者 🌐个人主页:码农阿豪 📞工作室:新空间代码工作室(提供各种软件服务) 💌个人邮箱:[2435024119@qq.com] 📱个人微信:15279484656 🌐个人导航网站:www.forff.top 💡座右铭:总有人要赢。为什么不能是我呢? 专栏导…

Python 使用 Detectron2 进行目标检测 (Detectron2, CenterNet2, Detic)

代码说明 代码主要是一个用来演示如何使用 Detectron2 进行目标检测的脚本。它可以从摄像头或视频文件中读取图像&#xff0c;并应用指定的配置文件进行目标检测。其中&#xff0c;Detectron2 结合了 CenterNet2 和 Detic 进行目标检测。 主要库介绍 Detectron2 Detect…

UMG文本控件(UTextBlock)超过边界区域以后显示省略号

测试版本:UE5.4.1 UMG文本控件超过边界区域以后显示省略号

基于springboot+vue+uniapp的校园快递平台小程序

开发语言&#xff1a;Java框架&#xff1a;springbootuniappJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#…

【打家劫舍】python刷题记录

R3-递归篇。第100篇blog. 思路&#xff1a; 和爬楼梯有点相似&#xff0c;每次隔1格&#xff0c;2格&#xff0c;3格----(隔3格就亏了&#xff0c;所以还是类似爬楼梯问题&#xff0c;1格或者2格) class Solution:def rob(self, nums: List[int]) -> int:cur,pre0,0for nu…

科普文:Linux目录详解

在 Linux/Unix 操作系统中&#xff0c;一切都是文件&#xff0c;甚至目录也是文件&#xff0c;文件是文件&#xff0c;鼠标、键盘、打印机等设备也是文件。 这篇文章&#xff0c;我们将一起学习 Linux 中的目录结构及文件。 Linux 的文件类型 Linux系统中的文件系统&#xf…

图片太大怎么压缩变小?图片太大压缩变小的几个方法

图片太大怎么压缩变小&#xff1f;在当今数字化时代&#xff0c;图像的处理和分享已经成为日常工作和生活中不可或缺的一部分。然而&#xff0c;有时我们会遇到一个普遍的问题&#xff1a;图片文件太大&#xff0c;需要压缩以便于存储、传输或发布。为什么要压缩图片呢&#xf…