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

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.csdn.net/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-<
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 开发2D游戏引擎可以使用C++语言和一些常见的游戏开发库,如SDL、SFML、OpenGL等。以下是一个简单的步骤: 1. 确定游戏引擎的功能和特性,例如支持哪些平台、渲染引擎、物理引擎、音频等。 2. 使用C++语言编写游戏引擎的框架,包括游戏循环、资源管理、场景管理、输入输出、碰撞检测等基本功能。 3. 集成游戏开发库,例如SDL或SFML,来处理输入输出、图像和声音。 4. 使用OpenGL或其他可用的图形库来渲染图像,并实现2D图形渲染。 5. 实现物理引擎,例如Box2D,处理游戏中的碰撞和物理效果。 6. 开发游戏编辑器,以便游戏开发者可以轻松创建和编辑游戏世界。 7. 测试和调试游戏引擎,确保它能够正确地处理所有可能的情况。 8. 最后,使用游戏引擎创建游戏,测试游戏并发布。 以上是一个简单的步骤,开发2D游戏引擎需要大量的工作和经验。 ### 回答2: 开发2D游戏引擎是一项需要技术和创造力的任务。首先,作为开发者,我们需要掌握编程语言,如C,这使我们能够编写代码并实现游戏引擎的各种功能。C语言是一种强大的编程语言,广泛用于游戏开发领域,因为它能够提供高性能和灵活性。 在开发2D游戏引擎时,我们需要考虑许多因素。首先是游戏的图形渲染,C语言提供了许多图形库和API,例如OpenGL,我们可以利用这些库来实现游戏中的图形效果和动画。 其次,我们需要处理用户输入和游戏物理仿真。用户输入可以是键盘、鼠标或触摸屏,我们需要编写代码来捕捉和处理用户输入,以便控制游戏角色和操作。 另外,物理仿真是为了进行游戏中的物体运动模拟,例如重力、碰撞等。我们可以使用物理引擎库,如Box2D,来实现这些效果。 游戏的音频处理也是一个重要的方面。我们可以使用C语言提供的音频库,例如OpenAL,来实现游戏中的音效和音乐播放。 最后,考虑到游戏的性能和优化,我们需要进行适当的资源管理和内存管理。这可以通过编写高效的代码和使用合适的数据结构来实现。 总而言之,开发2D游戏引擎需要深入了解C语言编程和游戏开发技术。通过合理设计和实现,我们可以创造出各种精彩的2D游戏,并为玩家带来愉悦的游戏体验。 ### 回答3: C开发2D游戏引擎是一项富有挑战性的任务。2D游戏引擎是开发和运行2D游戏的软件框架,它提供了处理图像、动画、碰撞检测、物理模拟等核心功能。下面将介绍C开发2D游戏引擎的一些关键方面。 首先,需要设计并实现游戏引擎的核心结构。这包括定义场景、实体、碰撞检测等基本概念,并为其编写相应的数据结构和算法。开发者需要具备良好的数据结构和算法设计能力,以确保引擎的高效性和可扩展性。 其次,需要处理图像和动画。2D游戏引擎需要加载、显示和管理游戏中的各种图像资源,并实现动画效果。这需要使用一些图形库和技术,如SDL(Simple DirectMedia Layer)或OpenGL来处理渲染。 第三,碰撞检测是游戏引擎的另一个重要方面。它能够检测到游戏中不同实体之间的碰撞,并触发相应的事件。碰撞检测可以使用各种技术来实现,如动态边界盒、像素级检测或分层检测等。 然后,物理模拟也是2D游戏引擎的一个关键特性。它可以模拟游戏中的物理效果,如重力、摩擦力等,并使游戏更加真实和可交互。为了实现这些效果,开发者需要理解物理学原理,并编写适当的代码实现。 最后,一个成功的2D游戏引擎还需要提供一些工具和接口,以方便开发者使用。这包括编辑器、导航系统、场景管理和资源管理等功能,以及提供一些API和文档来帮助其他开发者使用你的游戏引擎。 总而言之,C开发2D游戏引擎需要开发者具备良好的编程和算法设计能力。这需要对游戏引擎的核心结构、图像处理、碰撞检测、物理模拟等方面有深入理解,并能够将这些概念转化为可工作的代码来实现一个高效、可扩展的2D游戏引擎

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值