关于C/C++游戏引擎如何判断碰撞(以SDL2为例)

C++游戏引擎实战:从架构设计到2D物理碰撞系统实现 游戏引擎是游戏开发的核心框架,它通过模块化设计管理游戏循环、资源与对象。其核心原理在于解耦渲染、逻辑与数据,采用如ECS(实体-组件-系统)等架构模式提升可维护性。在技术价值上,自研引擎能深化对内存管理、多线程及性能优化的理解,尤其物理碰撞系统涉及刚体运动、碰撞检测(如AABB、分离轴定理)与响应(冲量法),是模拟真实交互的关键。应用场景涵盖2D/3D游戏、模拟仿真及教育工具开发。本文聚焦C++游戏引擎开发,通过实战构建微型引擎,详解固定时间步长游戏循环、SDL2渲染管线及2D物理碰撞实现,帮助开发者掌握引 阅读详情

Version:alpha 2.4

Information:

代码摘自我自己的一个项目的一段代码

本文是类似日记形式,可以帮助需要的人,我在未来也会回来看(忘了时)

2022.3.18时我还只是12岁,许多公式不知道,故引用了网上许多博主的代码,原博客地址在注释内有所体现

这是建立在SDL2上的游戏引擎,这很低级,大佬勿喷

//精灵定义
class Spirit {
   
   
public:
    void SetPicture(SDL_Texture* image);
    void SetHitBox(const vector<SDL_LFPoint> hit_box);
    void SetDirection(double direction);
    void SetSize(double sz);
    void SetBaseDirection(double _basedir);
    double GetSize();
    void Move(double speed);
    void Update();
    void SetPostion(SDL_LFPoint pos);
    void SetRotatePoint(SDL_LFPoint pos);
    vector<SDL_LFPoint> GetHitBox();
    SDL_Texture* GetPicture();
    double GetDirection();
    SDL_LFPoint GetPos();
    bool Spirit::IsHitWith(const vector<SDL_LFPoint>);
    SDL_LFPoint GetRotatePoint();
    SDL_LFPoint GetPostion();
protected:
    vector<SDL_LFPoint> hitBox;
    vector<SDL_LFPoint> rotateHitBox;
    SDL_LFPoint place, rotatePoint;
    SDL_Texture* picture;
    double dir, basedir; //0~360
    double size = 1.0;//x0 ~ inf
};
以下是一些你可能需要的明白的东西
首先,我们使一个精灵的碰撞箱是一个多边形用"vector<SDL_LFPoint>"来存
(注:如果一个多边形是vector<SDL_LFPoint> poly, 则poly[x]与poly[(x + 1) % poly.size()]连边)
那么你就看懂了bool Spirit::IsHitWith(const vector<SDL_LFPoint> box);的定义,两个多边形碰撞箱是否碰撞
Spirit::rotateHitBox是经过旋转处理(SetDirection())后的碰撞箱
那么我们如下处理:
1.如果两个多边形有边重叠,则它们一定相交
2.如果一条直线向任意方向延伸出一条射线,则如果与另一多边形的交点个数为奇数则一个在另一个里边(如果刚好交点在顶点,则要去掉一次,不然就会多一次)
3.否则不相交
注:这适用于任意多边形(包括凹多边形)

这里使用了qq_41726230::is_intersect()来自https://blog.youkuaiyun.com/qq_41726230/article/details/105037871
和自己推的HitPoint2Line()
SDL_LFPoint HitPoint2Line(SDL_LFPoint a1, SDL_LFPoint b1, SDL_LFPoint a2, SDL_LFPoint b2) {
   
   
    /*
     * y=ax+b
     * x1 y1 x2 y2
     * y1=ax1+b
     * y2=ax2+b
     * y1-y2=a(x1-x2)
     * a=(y1-y2)/(x1-x2)
     * b=y1-a*x1
     */
    double fa1 = (a1.y - b1.y) / (a1.x - b1.x);
    double fa2 = a1.y - fa1 * a1.x;
    double fb1 = (a2.y - b2.y) / (a2.x - b2.x);
    double fb2 = a2.y - fb1 * a2.x;
    /*
     * y=fa1*x+fa2
     * y=fb1*x+fb2
     * x*(fa1-fb1)+(fa2-fb2)=0
     * x*(fa1-fb1)=fb2-fa2
     * x=(fb2-fa2)/(fa1-fb1)
    */
    double x = (fb2 - fa2) / (fa1 - fb1);
    double y = fa1 * x + fa2;
    return {
   
    x, y };
}

bool Spirit::IsHitWith(const vector<SDL_LFPoint> box) {
   
   
	if (box.empty() || this->hitBox.empty()) return false;
	for (int i = 0; i < this->hitBox.size(); i++) {
   
   
		qq_41726230::line la(
			this->rotateHitBox[i].x * this->size + this->place.x, this->rotateHitBox[i].y * this->size + this->place.y,
			this->rotateHitBox[i == this->rotateHitBox.size() - 1 ? 0 : i + 1].x * this->size + this->place.x,
			this->rotateHitBox[i == this->rotateHitBox.size() - 1 ? 0 : i + 1].y * this->size + this->place.y
		);
		for (int j = 0; j < box.size(); j++) {
   
   
			qq_41726230::line lb(
				box[j].x, box[j].y,
				box[j == box.size() - 1 ? 0 : j + 1].x,
				box[j == box.size() - 1 ? 0 : j + 1].y
			);
			if (qq_41726230::is_intersect(la, lb)) {
   
   
				return true;
			}
		}
	}

	//判断我是不是在他里面
	qq_41726230::line l1(this->rotateHitBox[0].x * this->size + this->place.x, this->rotateHitBox[0].y * this->size + this->place.y, -100, -100);
	int cnt[1] = {
   
   };
	for (int j = 0; j < box.size(); j++) {
   
   
		qq_41726230::line lb(
			box[j].x, box[j].y,
			box[j == box.size() - 1 ? 0 : j + 1].x,
			box[j == box.size() - 1 ? 0 : j + 1].y
		);
		int a = 0, b = 0;
		if (qq_41726230::is_intersect(l1, lb)) cnt[0]++;
		auto pos = HitPoint2Line({
   
    l1.xa, l1.ya }, {
   
    l1.xb, l1.yb }, {
   
    lb.xa, lb.ya }, {
   
    lb.xb, lb.yb });
		if (pos.x == lb.xa && pos.y == lb.ya) {
   
   
			cnt[0]--;
		}
	}
	if (cnt[0] & 1) {
   
   
		return true;
	}
	//判断他是不是在我里面
	cnt[0] = 0;
	qq_41726230::line l6(box[0].x, box[0].y, -100, -100);
	for (int i = 0; i < this->hitBox.size(); i++) {
   
   
		qq_41726230::line la(
			this->rotateHitBox[i].x * this->size + this->place.x, this->rotateHitBox[i].y * this->size + this->place.y,
			this->rotateHitBox[i == this->rotateHitBox.
从零构建C++游戏框架:SDL2实战与生皮训练项目解析 游戏开发的核心在于理解其底层运行机制,而游戏循环是实现实时交互程序的基石。它通过持续处理输入、更新状态和渲染输出,驱动着每一帧的画面与逻辑。在技术实现上,跨平台多媒体库SDL2为开发者提供了访问音频、键盘、鼠标和图形硬件的统一接口,是构建轻量级、高性能游戏框架的理想选择。通过实践资源管理、实体组件系统和碰撞检测等关键技术,开发者能够深入掌握C++的内存管理、面向对象设计及性能优化。这种从底层开始的“生皮训练”方式,尤其适合希望夯实C++系统编程能力、并渴望窥见游戏引擎背后原理的学习者与开发者,最终导向一个可 阅读详情

相关推荐

UnrealEngine5游戏引擎实践(C++)

摘要:Unreal Engine 5介绍 ,Unreal Engine C++游戏引擎大全,物品拾取系统核心实现,角色移动控制,游戏门设计,动态光源布置,UI血条绘制,敌人AI巡逻逻辑,动态水面材质,玻璃材质开发,溶解效果材质,角色面部控制,动画蒙太奇攻击,自定义骨骼控制,PCG植被分布规则,模拟破碎建筑物,制作火焰粒子规律,流体模拟,树叶动态摇摆,破坏性武器冲击波效果,高效效果实现

keny-大成的博客 3998

OpenBOR游戏引擎跨平台移植:从Windows到Android的完整实战指南

跨平台开发是现代游戏工程中的重要实践,其核心在于通过抽象层技术实现同一套代码逻辑在不同操作系统和硬件架构上的运行。其原理通常基于C/C++这类高性能语言编写核心引擎,并利用平台抽象库(如SDL2)处理底层系统交互,从而实现“一次编写,多处部署”。这种技术方案的价值在于极大提升了代码复用率,降低了多平台维护成本,尤其对于独立开发者和复古游戏项目意义重大。在应用场景上,它广泛应用于将PC端的自制或经典游戏引擎(例如专注于2D清版动作游戏的OpenBOR引擎)迁移到移动设备。本文将以OpenBOR引擎为例,详细解

CURSED! 434

基于C++与SDL2的超级玛丽游戏源码详解:从环境配置到碰撞检测实现

C++作为高性能编程语言,一直是游戏开发领域的重要基石。横版跳跃游戏的实现涉及渲染、物理、碰撞、动画等多个核心子系统,而理解这些系统的最佳方式,是亲手复现一个完整的工程。通过分析超级玛丽这类经典游戏,我们可以掌握事件驱动架构、AABB碰撞检测、状态机管理等关键技术——这些原理不仅适用于游戏,也是复杂软件工程中数据与逻辑分离的通用实践。SDL2作为轻量级多媒体库,能在不依赖完整引擎的前提下提供窗口、渲染与输入支持,非常适合C++学习者从底层构建游戏逻辑并理解图形API的交互方式。无论是初学者寻找练手项目,还是

weixin_31881651的博客 245

泡泡堂炸弹人C/C++完整源码解析:从地图到碰撞再到音乐集成

游戏开发是检验编程基础的最佳实践场,尤其是碰撞检测、状态管理、资源加载等经典问题,几乎在每个游戏项目中都会遇到。通过拆解一款经典的炸弹人游戏源码,初学者可以直观理解二维数组地图建模、链表管理动态对象、像素级移动与格点判定结合、爆炸波扩散、道具与AI的朴素实现,以及背景音乐和图片资源的调用方式。文章以EasyX图形库为主,兼顾SDL2跨平台方案,完整演示了从环境配置到核心模块编码的工程化思路,适合刚学完C语言想找第一个完整项目的学生,也适合希望快速做出Demo的开发者。掌握这些基础技能,不止能跑通一个游戏,更

weixin_29011395的博客 287

Simple-2D-Game-Engine:用SDL2用C ++编写的基本2D游戏引擎

简单2D游戏引擎 用SDL2用C ++编写的基本2D游戏引擎 作为哈佛大学CS50x在线课程的一部分,我们被要求创建一个最终项目,该项目可以是我们想要的任何东西。 我选择创建的项目是一个简单的2D游戏引擎。 该引擎是用C ++编写的,并使用SDL2处理纹理渲染。 该项目分为引擎和游戏组件,其中引擎能够独立于任何游戏特定文件而独立存在。 与引擎一起,将创建一个示例游戏来展示引擎的功能。 依存关系: 要自己构建此项目,您将需要以下依赖项: SDL2 32位版本2.0.14 SDL_image 32位版本2.0.5 我正在使用SDL_image加载png图像。 要启用png加载,您需要将SDL_image附带的libpng16-16.dll文件放在源目录中。 在上有出色的教程,可以为几种不同的操作系统和IDE设置这些库。 版本历史: 4/15/21 添加了基于发布-订阅模式的游戏事

Fastboi:通过SDL2编写的轻巧简单的C ++ 20游戏引擎。 它实现了基本的组件模型和事件系统

Fastboi:通过SDL2编写的轻巧简单的C ++ 20游戏引擎。 它实现了基本的组件模型和事件系统

GEngine-R:基于SDL2的2D游戏引擎

GEngine | 关于 基于SDL2构建的2D游戏引擎。 重写了我的一个旧项目。 这是一个进行中的项目,请不要提供支持。 重要笔记: 没什么值得一提的。 去做: 基本引擎循环 帧/逻辑时序 输入处理程序 基于对象/场景的渲染 对象/实例 音讯模组 资源/纹理加载 资源/音频加载 资源经理 GameObject事件系统 场景实例化 物理系统

RetroGear:基于SDL的通用2D游戏引擎-开源

RetroGear是一种通用的2D游戏引擎,专为80年代的简单,快速的复古游戏开发而设计。 该项目旨在基于已知的最常见的游戏编程和设计实践,为2D游戏的快速开发创建通用组件,从而使程序员能够使用标准组件,并易于与自己的项目集成。 该游戏引擎提供的一些功能包括:基本但实用的游戏状态管理(屏幕标题,赛前游戏,游戏,游戏结束等)。2D地图的管理以及用于管理图形的实用工具,滚动和碰撞。 用于以高和低级别处理图形的功能,以及以全自动方式向游戏实体的动画管理添加功能。 基本音频的管理游戏动态范围,由于具有专用功能,因此可以轻松,快速地用于各种游戏类型。

XEffect2D:基于OpenGL和SDL的2D游戏引擎,支持Windows和Linux-开源

This is a 2D game engine,base on OpenGL & SDL,support Windows & Linux. 这是一款基于OpenGL与SDL的2D游戏开发库,可以支持Windows与linux。 You can download some examples from https://github.com/xiajiaonly/XEffect2D

从零到一:Abaqus与Matlab联合仿真的自动化流程构建指南

本文详细介绍了如何构建Abaqus与Matlab联合仿真的自动化流程,涵盖基础架构设计、关键接口技术实现、结果提取与处理技术以及高级参数化优化流程。通过Python脚本作为桥梁,实现数据传递和任务控制,帮助工程师提升仿真效率。特别强调了版本兼容性、异常处理和性能监控等实用技巧。

weixin_29090089的博客 611

OpenFOAM收敛问题排查指南:从参数设置到网格优化

本文系统性地介绍了OpenFOAM计算中收敛问题的排查方法。从理解收敛本质出发,详细讲解了如何通过调优求解控制参数(如松弛因子、离散格式)、合理设置时间步长与耦合算法,以及优化网格质量来解决发散难题。文章提供了从软件设置到硬件网格的完整排查路径,帮助用户实现稳定高效的计算流体力学模拟。

fern8的博客 790

智能车新手必看:如何用PID和差速转弯让小车跑得更稳(附代码示例)

本文详细介绍了智能车控制系统中PID算法和差速转弯的实现方法,包括位置式与增量式PID的选择、参数整定技巧以及编码器反馈的关键作用。通过代码示例和实战经验,帮助新手快速掌握智能车稳定行驶的核心技术,提升赛道表现。

mmm90的博客 122

AJ-Report开源数据大屏存在远程命令执行漏洞

该平台可以通过post方式在validationRules参数对应值中进行命令执行,可以获得服务器权限,登陆管理后台接管大屏。如果被攻击者利用,危害后果十分严重。

swordheart的博客 387

矩阵管理:一人100账号霸屏小红书,保姆级教程经验技巧

同时,如果你的账号表现很正常,很OK,它也增加账号权重。手机环境:一机一卡一号是基本操作,如果你觉得设备成本高,你就要知道WIN的云真机,一键新机,一键随机设备参数,一键还原,一键安装应用,自带批量发布笔记,私信聚合,自带回复私信,一键养号等等,一人批量注册100个小红书账号真的很简单!从流量逻辑来分析,大家有没有发现,从账号粉丝数来看,小红书很难出现类似抖音上超千万粉丝量级的账号,几十万粉丝的博主已经是头部账号了,原因在于,抖音的流量分发机制是80%的流量集中在 20% 的头部账号而。

FDF432DF的博客 5143

头歌MySQL数据库实训答案 有目录

头歌java实训答案集数据库部分一条一条的写,可鼠标手动粘贴,除特定命令外未分大小写。 第1关:创建数据库 第2关创建表 第3关:使用主键约束 第4关:外键约束 第5关:添加常用约束 MySQL数据库 - 数据库和表的基本操作(一) 第1关:查看表结构与修改表名 第2关:修改字段名与字段数据类型 第3关:添加与删除字段 第4关:修改字段的排列位置 第5关:删除表的外键约束 MySQL数据库 - 数据库和表的基本操作(二) 第1关:插入数据 第2关:更新数据 第3关:删除数据 MySQL数据库 - 单表查询(

m0_67401761的博客 4万+

【RK3588 NPU性能调优实战】多线程异步推理YOLOv5,榨干6TOPS算力

本文详细解析了如何在RK3588 NPU上通过多线程异步推理优化YOLOv5目标检测性能,实现6TOPS算力的最大化利用。通过线程池设计、流水线化帧处理及避开内存带宽瓶颈等技巧,将NPU利用率从30%提升至82%,帧率显著提高至61.2FPS。文章还提供了环境配置、代码实现及性能对比数据,助力开发者高效部署AI模型。

weixin_29034963的博客 340

【AI大模型:认知升级】1、全面解析AI大模型:从起源到发展脉络与应用价值

AI大模型是具备超大规模参数(千亿至万亿级)、海量训练数据(TB级)和强迁移学习能力的基础模型。其技术特征包括Transformer架构革新、大数据预训练范式及参数规模超过临界值后的能力涌现。发展历程经历了语言模型突破(2018-2020)、多模态融合(2021-2023)和架构创新(2023至今)三波浪潮,遵循数据、算力、算法协同进化规律。底层驱动因素包括能力涌现机制、算力基础设施突破和应用场景拓展,正在重构产业价值链。通过"知识星系""认知

2025博客之星Top81。专注AI工程化与架构实战。从分布式思维到模型部署,用工程化视角为你厘清AI落地的真实路径。 2292

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

DSCS2009
博客等级 码龄6年 1粉丝 1原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值