当前位置: 首页 > news >正文

LearnOpenGL学习(碰撞检测,粒子)

完整代码见:zaizai77/OpenGLTo2DGame: 基于OpenGL制作2D游戏

物体本身的数据来检测碰撞会很复杂,一半使用重叠在物体上的更简单的外形来检测。

AABB - AABB 碰撞

AABB代表的是轴对齐碰撞箱(Axis-aligned Bounding Box),碰撞箱是指与场景基础坐标轴(2D中的是x和y轴)对齐的长方形的碰撞外形。

获取左上角和右下角点的位置。

检查两个物体的水平边界是否重合以及垂直边界是否重合。如果水平边界垂直边界都有重叠那么我们就检测到一次碰撞。

将这一概念转化为代码也是很直白的。我们对两个轴都检测是否重叠,如果都重叠就返回碰撞:

GLboolean CheckCollision(GameObject &one, GameObject &two) // AABB - AABB collision
{// x轴方向碰撞?bool collisionX = one.Position.x + one.Size.x >= two.Position.x &&two.Position.x + two.Size.x >= one.Position.x;// y轴方向碰撞?bool collisionY = one.Position.y + one.Size.y >= two.Position.y &&two.Position.y + two.Size.y >= one.Position.y;// 只有两个轴向都有碰撞时才碰撞return collisionX && collisionY;
}  

这样子检测确实有用,但是不是非常准确

AABB - 圆碰撞检测

使用圆形碰撞对于圆球来说更合理

定义球的矢量和半径

我们会找到AABB上距离圆最近的一个点,如果圆到这一点的距离小于它的半径,那么就产生了碰撞。

GLboolean CheckCollision(BallObject &one, GameObject &two) // AABB - Circle collision
{// 获取圆的中心 glm::vec2 center(one.Position + one.Radius);// 计算AABB的信息(中心、半边长)glm::vec2 aabb_half_extents(two.Size.x / 2, two.Size.y / 2);glm::vec2 aabb_center(two.Position.x + aabb_half_extents.x, two.Position.y + aabb_half_extents.y);// 获取两个中心的差矢量glm::vec2 difference = center - aabb_center;glm::vec2 clamped = glm::clamp(difference, -aabb_half_extents, aabb_half_extents);// AABB_center加上clamped这样就得到了碰撞箱上距离圆最近的点closestglm::vec2 closest = aabb_center + clamped;// 获得圆心center和最近点closest的矢量并判断是否 length <= radiusdifference = closest - center;return glm::length(difference) < one.Radius;
} 

粒子

一个微粒,从OpenGL的角度看就是一个总是面向摄像机方向且(通常)包含一个大部分区域是透明的纹理的小四边形。一个微粒本身主要就是一个精灵(sprite)

一个粒子通常有下面的属性:

struct Particle {glm::vec2 Position, Velocity;glm::vec4 Color;GLfloat Life;Particle() : Position(0.0f), Velocity(0.0f), Color(1.0f), Life(0.0f) { }
};

渲染粒子的着色器:

#shader vertex#version 330 core
layout(location = 0) in vec4 vertex; // <vec2 position, vec2 texCoords>out vec2 TexCoords;
out vec4 ParticleColor;uniform mat4 projection;
uniform vec2 offset;
uniform vec4 color;void main()
{float scale = 10.0f;TexCoords = vertex.zw;ParticleColor = color;gl_Position = projection * vec4((vertex.xy * scale) + offset, 0.0, 1.0);
}#shader fragment#version 330 core
in vec2 TexCoords;
in vec4 ParticleColor;
out vec4 color;uniform sampler2D sprite;void main()
{color = (texture(sprite, TexCoords) * ParticleColor);
}

粒子循环函数:

GLuint nr_new_particles = 2;
// Add new particles
for (GLuint i = 0; i < nr_new_particles; ++i)
{int unusedParticle = FirstUnusedParticle();RespawnParticle(particles[unusedParticle], object, offset);
}
// Update all particles
for (GLuint i = 0; i < nr_particles; ++i)
{Particle &p = particles[i];p.Life -= dt; // reduce lifeif (p.Life > 0.0f){   // particle is alive, thus updatep.Position -= p.Velocity * dt;p.Color.a -= dt * 2.5;}
}
GLuint lastUsedParticle = 0;
GLuint FirstUnusedParticle()
{// Search from last used particle, this will usually return almost instantlyfor (GLuint i = lastUsedParticle; i < nr_particles; ++i){if (particles[i].Life <= 0.0f){lastUsedParticle = i;return i;}}// Otherwise, do a linear searchfor (GLuint i = 0; i < lastUsedParticle; ++i){if (particles[i].Life <= 0.0f){lastUsedParticle = i;return i;}}// Override first particle if all others are alivelastUsedParticle = 0;return 0;
}

如果是最后一种情况(返回0),就意味着你粒子的生命值太长了,在每一帧里面需要产生更少的粒子,或者你只是没有保留足够的粒子,

更新消亡的粒子:

void RespawnParticle(Particle &particle, GameObject &object, glm::vec2 offset)
{GLfloat random = ((rand() % 100) - 50) / 10.0f;GLfloat rColor = 0.5 + ((rand() % 100) / 100.0f);particle.Position = object.Position + random + offset;particle.Color = glm::vec4(rColor, rColor, rColor, 1.0f);particle.Life = 1.0f;particle.Velocity = object.Velocity * 0.1f;
}
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
particleShader.Use();
for (Particle particle : particles)
{if (particle.Life > 0.0f){particleShader.SetVector2f("offset", particle.Position);particleShader.SetVector4f("color", particle.Color);particleTexture.Bind();glBindVertexArray(particleVAO);glDrawArrays(GL_TRIANGLES, 0, 6);glBindVertexArray(0);} 
} 
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

这里将glBlendFunc中的因子替换,将 GL_ONE_MINUS_SRC_ALPHA 替换为 GL_ONE

,产生粒子叠加在一起的平滑的发热效果(比如火焰粒子)。

参考:碰撞检测 - LearnOpenGL CN

相关文章:

LearnOpenGL学习(碰撞检测,粒子)

完整代码见&#xff1a;zaizai77/OpenGLTo2DGame: 基于OpenGL制作2D游戏 物体本身的数据来检测碰撞会很复杂&#xff0c;一半使用重叠在物体上的更简单的外形来检测。 AABB - AABB 碰撞 AABB代表的是轴对齐碰撞箱(Axis-aligned Bounding Box)&#xff0c;碰撞箱是指与场景基…...

操作系统(24)提高磁盘I/O速度的途径

前言 操作系统提高磁盘I/O速度的途径多种多样&#xff0c;这些途径旨在减少磁盘访问的延迟和开销&#xff0c;提高数据传输的效率。 一、磁盘高速缓存&#xff08;Disk Cache&#xff09; 磁盘高速缓存是一种在内存中为磁盘数据设置的缓冲区&#xff0c;用于存储磁盘中某些盘块…...

C/C++基础知识复习(45)

1) C 中面向对象编程如何实现数据隐藏&#xff1f; 在 C 中&#xff0c;数据隐藏是通过将类的成员变量和方法的访问权限控制起来实现的。通常&#xff0c;数据隐藏是通过使用 访问控制 机制来实现的&#xff0c;C 提供了三种访问控制修饰符&#xff1a; private: 使成员变量和…...

现代C++锁介绍

文章目录 场景描述&#x1f41e; 初始实现: 非线程安全版本互斥锁: std::mutex使用mutex保护共享资源使用std::lock_guard简化锁的管理 优化读操作: std::shared_mutex多个锁的管理: std::scoped_lock使用std::scoped_lock避免死锁 其他高级锁⏳ 带超时的锁: std::timed_mutex使…...

Squid代理服务器的安装使用

1.简介 Squid代理服务器是一种高效的中间服务器&#xff0c;位于客户端和目标服务器之间&#xff0c;起到了重要的网络中介作用。以下是对Squid代理服务器的详细介绍&#xff1a; 一、功能特点 缓存功能&#xff1a; Squid可以缓存经过它的请求和响应数据。当客户端发起请求时…...

爬虫学习案例8

爬取京东评论信息 采用DrissionPage自动化工具采集&#xff0c;感觉比Selenium工具好&#xff0c;真香。 安装第三方库 pip install DrissionPage pip install pandas pip install pyecharts pip install jieba pip install wordcloud1.安装DrissionPage库 DrissionPage安装…...

深入了解 CouchDB 的 Mango 查询:操作符和限制

CouchDB 是一个基于文档的数据库管理系统,支持 HTTP 协议,拥有强大的同步机制和灵活的数据模型。Mango 查询是 CouchDB 中用于数据检索的现代化查询接口,灵感来自 MongoDB 的查询语法。本文将深入探讨 Mango 查询中的各种操作符和限制,并提供详细的例子和说明,帮助你更好地…...

基于SSM(Spring + Spring MVC + MyBatis)框架搭建一个病人跟踪信息管理系统

基于SSM&#xff08;Spring Spring MVC MyBatis&#xff09;框架搭建一个病人治疗跟踪信息系统是一个相对复杂的项目&#xff0c;涉及到多个模块和功能。以下是一个简要的指导步骤。 1. 环境准备 开发环境&#xff1a;确保安装了Java Development Kit (JDK)&#xff0c;建议…...

U盘文件名变乱码:原因、恢复与预防全解析

一、U盘文件名变乱码现象描述 在日常使用U盘进行数据传输和存储时&#xff0c;我们有时会遇到一个令人头疼的问题&#xff1a;U盘中的文件名突然变成了乱码&#xff0c;无法正常识别或访问。这些乱码文件名可能包含各种奇怪的字符和符号&#xff0c;使得原本有序的文件管理变得…...

EasyGBS国标GB28181公网平台P2P远程访问故障诊断:云端服务端排查指南

随着信息技术的飞速发展&#xff0c;视频监控领域正经历从传统安防向智能化、网络化安防的深刻转变。EasyGBS平台&#xff0c;作为基于国标GB28181协议的视频流媒体平台&#xff0c;为用户提供了强大的视频监控直播功能。然而&#xff0c;在实际应用中&#xff0c;P2P远程访问可…...

一网多平面

“一网多平面”是一种网络架构概念&#xff0c;具体指的是在一张物理网络之上&#xff0c;逻辑划分出“1N”个平面。以下是对“一网多平面”的详细解释&#xff1a; 定义与构成 01一网多平面 指的是在统一的物理网络基础设施上&#xff0c;通过逻辑划分形成多个独立的网络平面…...

animatediff 模型网盘分享

网盘 一、123网盘&#xff0c;不限速 https://www.123pan.com/s/ueQ8jv-OlzPh.html 网盘 网址 animatediff 国外网址https://huggingface.co/guoyww/animatediff/tree/cd71ae134a27ec6008b968d6419952b0c0494cf2 国内镜像在 https://hf-mirror.com/guoyww/animatediff/t…...

ansible play-book玩法

使用ansible-playbook实现安装nginx_ansible 安装nginx-CSDN博客文章浏览阅读1.5k次&#xff0c;点赞14次&#xff0c;收藏19次。本文详细介绍了如何在Linux环境中准备Ansible环境&#xff0c;包括配置主机、下载和安装Ansible&#xff0c;以及使用yum模块和tar包源码安装Nginx…...

MySQL索引-索引的分类和创建

索引类型 数据类型 B树索引Hash索引FullText全文索引 物理存储 聚簇索引二级索引 字段特性 主键索引唯一索引普通索引前缀索引 字段个数 单列索引联合索引 创建索引 创建表时一同创建创建表后单独创建创建表后通过修改表结构创建 可以通过 SHOW INDEX FROM test_table;查看…...

如何给负载均衡平台做好安全防御

在现代网络架构中&#xff0c;负载均衡&#xff08;Load Balancing&#xff09;扮演着至关重要的角色。它不仅负责将流量分配到多个服务器以确保高效的服务交付&#xff0c;还作为第一道防线来抵御外部攻击。为了保护您的应用程序和服务免受潜在威胁&#xff0c;必须对负载均衡…...

HR/TA/HRBP的关系

HR&#xff08;人力资源&#xff09;领域包含 TA&#xff08;人才获取&#xff09;和 HRBP&#xff08;人力资源业务伙伴&#xff09;这两个重要的角色&#xff0c;但它们只是 HR 工作的一部分分支&#xff0c;一般我们说的HR指TA。 1. 人才获取&#xff08;TA&#xff09; 定…...

Docker环境下MySQL数据库持久化部署全攻略

概述 在当今的软件开发领域&#xff0c;Docker容器技术已经成为应用部署和管理的新标准。它不仅简化了应用的部署流程&#xff0c;还为数据管理提供了灵活的解决方案。特别是在涉及到MySQL数据库时&#xff0c;数据持久化是一个不可忽视的重要环节。本文将分享如何在Docker中部…...

如何查看pad的console输出,以便我们更好的进行调试,查看并了解实际可能的问题。

1、以下是baidu AI回复&#xff1a; 2、说明&#xff1a; 1&#xff09;如果小伙伴们经常做android开发的话&#xff0c;这个不陌生&#xff0c;因为调试都是要开启这个开发者模式。并启用USB调试模式。 2&#xff09;需要连上USB线&#xff0c;有的时候会忘记&#xff0c;然…...

react中使用ResizeObserver来观察元素的size变化

在 React 中使用 ResizeObserver 来观察元素的大小变化&#xff0c;可以通过创建一个自定义 Hook 来封装 ResizeObserver 的逻辑&#xff0c;并在组件中使用这个 Hook。以下是一个完整的示例&#xff0c;展示了如何在 React 中使用 ResizeObserver 来观察元素的大小变化。 自定…...

Linux快速入门-Linux文件系统管理

Linux文件系统管理 1. Linux文件系统概述1.1 文件系统概念1.2 用户权限差异1.3 文件命名规范 2. Linux文件系统分类及特点2.1 ext2&#xff08;第二扩展文件系统&#xff09;2.2 ext3&#xff08;第三扩展文件系统&#xff09;2.3 ext4&#xff08;第四扩展文件系统&#xff09…...

19c补丁后oracle属主变化,导致不能识别磁盘组

补丁后服务器重启&#xff0c;数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后&#xff0c;存在与用户组权限相关的问题。具体表现为&#xff0c;Oracle 实例的运行用户&#xff08;oracle&#xff09;和集…...

K8S认证|CKS题库+答案| 11. AppArmor

目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作&#xff1a; 1&#xff09;、切换集群 2&#xff09;、切换节点 3&#xff09;、切换到 apparmor 的目录 4&#xff09;、执行 apparmor 策略模块 5&#xff09;、修改 pod 文件 6&#xff09;、…...

反向工程与模型迁移:打造未来商品详情API的可持续创新体系

在电商行业蓬勃发展的当下&#xff0c;商品详情API作为连接电商平台与开发者、商家及用户的关键纽带&#xff0c;其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息&#xff08;如名称、价格、库存等&#xff09;的获取与展示&#xff0c;已难以满足市场对个性化、智能…...

【JavaEE】-- HTTP

1. HTTP是什么&#xff1f; HTTP&#xff08;全称为"超文本传输协议"&#xff09;是一种应用非常广泛的应用层协议&#xff0c;HTTP是基于TCP协议的一种应用层协议。 应用层协议&#xff1a;是计算机网络协议栈中最高层的协议&#xff0c;它定义了运行在不同主机上…...

FFmpeg 低延迟同屏方案

引言 在实时互动需求激增的当下&#xff0c;无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作&#xff0c;还是游戏直播的画面实时传输&#xff0c;低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架&#xff0c;凭借其灵活的编解码、数据…...

转转集团旗下首家二手多品类循环仓店“超级转转”开业

6月9日&#xff0c;国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解&#xff0c;“超级…...

【Go】3、Go语言进阶与依赖管理

前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课&#xff0c;做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程&#xff0c;它的核心机制是 Goroutine 协程、Channel 通道&#xff0c;并基于CSP&#xff08;Communicating Sequential Processes&#xff0…...

用docker来安装部署freeswitch记录

今天刚才测试一个callcenter的项目&#xff0c;所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...

智能仓储的未来:自动化、AI与数据分析如何重塑物流中心

当仓库学会“思考”&#xff0c;物流的终极形态正在诞生 想象这样的场景&#xff1a; 凌晨3点&#xff0c;某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径&#xff1b;AI视觉系统在0.1秒内扫描包裹信息&#xff1b;数字孪生平台正模拟次日峰值流量压力…...

图表类系列各种样式PPT模版分享

图标图表系列PPT模版&#xff0c;柱状图PPT模版&#xff0c;线状图PPT模版&#xff0c;折线图PPT模版&#xff0c;饼状图PPT模版&#xff0c;雷达图PPT模版&#xff0c;树状图PPT模版 图表类系列各种样式PPT模版分享&#xff1a;图表系列PPT模板https://pan.quark.cn/s/20d40aa…...