Box2D C++ 教程-物体

2023-11-08

Box2D C++ 教程-物体











  • 物体(Bodies)

物体是物理场景中的基本对象,但是这里的物体并不是你看到的实际互相弹跳碰撞的实物。听起来很费解吗?挺住!马上做解释!

http://ohcoder.com/blog/2012/11/29/bodies/

你可以把物体想象成是一种看不见摸不着的实物的属性。这些不可见的属性是:

-质量(mass)-实物到底有多重 
-速度(velocity)-某方向上实物到底运动多快 
-转动惯量(rotational inertia)-开始或停止转动需要多大的力 
-角速度(angular velocity)-某方向实物转动的速度有多快 
-位置(location)-实物在哪 
-角度(angle)-实物面向哪个方向

即便你知道一个对象的所有这些特性,你仍然不清楚这个对象的长像或者它与其它物体产生碰撞的时候会作出什么样的反应。我们需要使用定制器(fixtures)来定义物体的形状和大小,关于定制器我们会在本教程的下一个话题进行讲解。目前我们还是使用一个简单的盒子来代替随后出现的定制器(fixture)的及其细节。让我们创建一个物体并为它设置一些基本属性,来看看是如何工作的吧。

有三种类型的物体:静态物体(static),动态物体(dynamic)以及运动学物体(kinematic)。前两个顾名思义看起来更好理解一些。最后一个看起来理解起来并不是那么的直观。目前先忽略一些细节,随后再进行解释。首先我们将创建一个动态物体,我们可以在场景中的地面上让其进行移动,然后试着设置速度,等等。让我们开始吧。

  • 创建物体

物体的创建由一些定义组成,通过这些定义来创建物体自身。如果你想创建多个相同或相似的物体,这种方式比较方便(译者注:这里所说的创建物体的定义就是下面代码中的b2BodyDef结构体的定义,以后所创建的物体都可以根据这个结构体做快速初始化)。在Footest类的构造方法里,添加如下代码,来创建物体定义:

1
2
3
4
b2BodyDef myBodyDef;
myBodyDef.type = b2_dynamicBody; //this will be a dynamic body
myBodyDef.position.Set(0, 20); //set the starting position
myBodyDef.angle = 0; //set the starting angle

这对创建一个基本的物体就足够了。记住这里的物体没有大小、形状,这里不会对这些内容进行定义。你可能会想为什么这里还没有质量-通常为物体设置质量的方式是通过为物体添加定制器(fixtrues)来完成的,下面会进行到这一步骤。现在,使用这个定义创建一个活生生的实例对象吧:

1
b2Body* dynamicBody = m_world->CreateBody(&myBodyDef);

这里,我们用到了父类Test中类型为b2World类型的成员变量m_world。world类型的对象就像是Box2D中的老大,它掌管着创建和销毁物理对象。稍后的教程里我们会看到关于world类型更多的细节。好的,现在我们有了一个物体,但是就像本话题开始时提到那样,基本上物体是不可见的,如果现在你运行程序,什么都不会看到(如果你选中右侧控制面板中“质心(Center of Masses)”选项,最多你可以看到物体下落的位置)。

为物体设置大小,形状以及其它更明确的性质,通过为其添加定制器(fixtures)来实现。此外,即便为物体添加默认的定制器也会影响物体的质量。物体可以附加多个定制器,附加的每一个定制器都会影响物体的总质量。目前,我们只为物体添加一个简单的定制器,一个四方形,定制器本来是下一次教程的话题,现在细说有点早。

1
2
3
4
5
6
7
b2PolygonShape boxShape;
boxShape.SetAsBox(1,1);

b2FixtureDef boxFixtureDef;
boxFixtureDef.shape = &boxShape;
boxFixtureDef.density = 1;
dynamicBody->CreateFixture(&boxFixtureDef);

虽然上面这段大部分的代码现在你都可以忽略,但是注意一下密度设置这行代码。定制器的质量是通过其自身面积(area)和密度进行相乘来计算的,最终算为物体的质量。

现在,当你运行程序,会看到一个下落的小盒子。如果你足够快,你可以用鼠标捕捉它,然后随意拖拽,如果小盒子丢出屏幕范围可以按restart按钮(R键)重新开始。既然这是个动态物体,那么它可以移动并且旋转,并受到重力的影响。

pic

  • 设置物体属性

现在,我们设置一些文章开始提到的属性,看看会发生什么。比如说,改变初始位置和角度:

1
dynamicBody->SetTransform( b2Vec2( 10, 20 ), 1 );

这将会使物体的初始位置向右移动10个单位,向上移动20个单位,并且逆时针旋转1弧度。Box2D使用弧度作为角度值的单位,如果你像我一样想使用角度值,那么需要多做一些工作,或许会像下面这样:

1
2
3
#define DEGTORAD 0.0174532925199432957f
#define RADTODEG 57.295779513082320876f
dynamicBody->SetTransform(b2Vec2(10, 20), 45 * DEGTORAD ); //45 degrees counter-clockwise

我们也可以设置物体的线速度和角速度:

1
2
dynamicBody->SetLinearVelocity(b2Vec2( -5, 5 ));//moving up and left 5 units per second
dynamicBody->SetAngularVelocity(-90 * DEGTORAD);//90 degrees per second clockwise
  • 静态物体(Static bodies)

现在让我们看看什么是静态物体。既然我们对物体已经有了一些定义和一个定制器,那我们就重用它们,只修改一些必须的特性:

1
2
3
4
myBodyDef.type = b2_staticBody; //this will be a static body
myBodyDef.position.Set(0, 10); //slightly lower position
b2Body* staticBody = m_world->CreateBody(&myBodyDef); //add body to world
staticBody->CreateFixture(&boxFixtureDef); //add fixture to body

注意这里我们根本不需要改变正方形定制器。运行程序,这时你可以在场景中看到另外一个盒子,但是这次它将不会移动。而且你还会发现即便你像上面那样成功使用setTransform方法改变静态物体的位置,设置静态物体的速度属性,也不会有任何效果。

pic

  • 运动学物体(Kinematic bodies)

最后,让我们来看看有关于运动学物体的部分。正如我们之前看到的动态物体可以移动,但静态物体不能移动。当一个静态物体和动态物体发生碰撞的时候,静态物体总能“获胜”并坚挺在地面上,动态物体根据实际情况被弹回,两个物体之间不会发生重叠。运动学物体非常像静态物体,当它与动态物体相撞之后,总能保持自己不动,把动态物体反弹回去,与静态物体唯一不同的是,运动学物体可以被移动。

可以像下面这样创建一个运动学物体:

1
2
3
4
5
6
7
myBodyDef.type = b2_kinematicBody;//this will be a kinematic body
myBodyDef.position.Set(-18, 11); //start from left side,slightly above the static body
b2Body* kinematicBody = m_world->CreateBody(&myBodyDef); //add body to world
kinematicBody->CreateFixture(&boxFixtureDef); //add fixture to body

kinematicBody->SetLinearVelocity( b2Vec2( 1, 0 ) );//move right 1 unit per second
kinematicBody->SetAngularVelocity( 360 * DEGTORAD );//1 turn per second counter-clockwise

pic

新创建的物体在场景中可以被移动或者旋转,但不会被重力所影响,并且当与动态物体发生碰撞的时候也不会受到影响。注意当它与静态物体发生接触的时候,它们之间是没有相互作用的。

在大多数游戏中,动态物体通常被用来创建玩家和其它场景中的角色,静态物体被用来创建墙,地板等等。运动学物体通常用来扮演那些可以移动或旋转但是不能被动态物体所撞动的物体。一个比较恰当的例子是横屏游戏中一个移动的平台,该平台可以使用运动学物体来模拟-这可以保证不论玩家如何跳跃,都不能与之由于相撞而产生位移。

  • 获取物体属性(Getting body properties)

很多情况下你都想知道物体目前在哪儿或者移动有多快,旋转角度等等。实现这个很简单,让我们现在就做一个尝试。为此,我们需要在Step()方法中访问物体变量,所以我们需要声明一个类的成员变量来代替只在构造函数中声明的变量。

1
2
//in the class itself, not inside the constructor!
b2Body* dynamicBody;

..然后使用类的成员变量替换物体类型的局部变量。现在在Step()方法中,我们可以加入如下代码来打印出物体的一些相关信息:

1
2
3
4
5
6
7
8
b2Vec2 pos = dynamicBody->GetPosition();
float angle = dynamicBody->GetAngle();
b2Vec2 vel = dynamicBody->GetLinearVelocity();
float angularVel = dynamicBody->GetAngularVelocity();
m_debugDraw.DrawString(5, m_textLine,"Position:%.3f,%.3f Angle:%.3f", pos.x, pos.y, angle * RADTODEG);
m_textLine += 15;
m_debugDraw.DrawString(5, m_textLine, "Velocity:%.3f,%.3f Angular velocity:%.3f", vel.x, vel.y, angularVel * RADTODEG);
m_textLine += 15;

pic

你可以通过GetPositon()和GetAngle()方法返回SetTransform所设置的值,而且不会发生值的改变。比如说,像下面这行代码根本不会引起物体位置的移动。

1
body->SetTransform( body->GetPosition(), body->GetAngle() );

当然了,这么做并没有什么用处,但是如果你只想改变位置或者角度,你就可以这么做。

  • 遍历世界中的物体

如果你想监视世界中的所有物体,你可以像下面这样做。GetBodyList()方法可以返回物体链表的第一个元素。

1
2
3
4
for ( b2Body* b = m_world->GetBodyList(); b; b = b->GetNext())
{
    //do something with the body 'b'
}
  • 清除

当一个物体完成了它的使命,你可以通过调用世界对象的DestroyBody方法将其移除:

1
m_world->DestroyBody(dynamicBody);

当像上面这样销毁物体之后,物体所附加的所有定制器(fixtures)和连接器(joins)都会被销毁。记住!当使用这个方法之后不要再调用这个已经删除的物体指针!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Box2D C++ 教程-物体 的相关文章

  • 抖音壁纸小程序怎么做?手把手教你开通流量主拥有自己的壁纸小程序

    最近抖音壁纸小程序很火 下面就让小编来给大家分享一下抖音壁纸小程序这套系统的独特之处 往下看 功能介绍如下 1 支持抖音 快手 QQ及微信4端合一 2 带达人入驻功能 3 达人分佣功能 4 独立的达人端后台 各项数据一目了然 5 支持独立达
  • 零知识证明原理

    零知识证明 定义 证明 Prover 向验证者 Verifier 证明一个命题成立 同时不泄露其他任何知识 这种就被称为零知识证明 应该具备以下三个性质 1 完备性 若一个证明方确实掌握了某论断的答案 则他肯定能找到方法向验证方证明他手中掌
  • mysql优化--explain--结果参数--02

    mysql优化 explain 结果参数 02 1 数据准备 DROP TABLE IF EXISTS course CREATE TABLE course id int 0 NOT NULL AUTO INCREMENT COMMENT
  • 那些你不知道的Typescript面试题

    1 面试官 说说你对 TypeScript 中类的理解 应用场景 一 是什么 类 Class 是面向对象程序设计 OOP Object Oriented Programming 实现信息封装的基础 类是一种用户定义的引用数据类型 也称类类型
  • 五笔

    学习五笔新口诀的一点心得 归纳记忆法 近日复习五笔新口诀 如何能便于记忆 有一点心得写出来供参考 若能抛砖引玉 也算没有白费精力 不胜欣慰 新口诀的特点 1 第一部分是中文键名 例如 王 土 大 木 2 第二部分是成字字根 例如 五 夫 一
  • Qt扫盲-QKeyEvent 键盘事件

    QKeyEvent 键盘事件 一 概述 二 事件传播 三 常用属性 1 key 2 modifiers 3 isAutoRepeat 4 text 四 简单组合键代码 一 概述 QKeyEvent 是Qt 里面描述键盘事件的一个属性类 所有
  • 虚拟机隔离

    虚拟机隔离 虚拟机隔离 需求分析 隔离内容 隔离措施 需求分析 背景 多实例的虚拟化环境 目标 通过隔离机制 具有利益关系的用户的虚拟机之间独立运行 互不干扰 风险 如果隔离不有效 当一个虚拟机方式错误时 会影响其他虚拟机 甚至整个系统 当
  • 网络安全-防守-护网

    护网背景 一 什么是护网 网络安全的态势之严峻 迫切需要我们在网络安全领域具备能打硬仗的能力 护网行动 应运而生 护网目标 通过防守工作与技术方案 做好 护网 前期准备 安全自查整改 攻防演练和演练总结等各阶段相关工作 保证护网期间 与相关
  • shell中算术运算、相加减

    前言 在shell脚本中 所有的变量默认都是字符串存储 操作也是按照字符串进行处理的 但我们不可避免的需要对各中数值进行算术运算 如算术的相加减 那么这时怎么处理呢 在shell脚本中 我们要实现对数值的算术运行 就要用到一下三种命令方式
  • payload模块怎Linux,kali linux之Msf-exploit模块,生成payload

    Exploit模块 Active exploit 主动地向目标机器发送payload并执行 使目标交出shell 反连等 msf5 gt use exploit windows smb psexec msf5 exploit windows
  • C语言图形库EasyX安装及基本使用

    本文章介绍C 用EasyX进行C 基础图形编程介绍 EasyX安装 1 点击上方超链接 进入官网 点击右侧下载EasyX 2 点击下载后的可执行文件 3 EasyX安装非常简单 进入可执行文件 直接next 然后会自动检测你的开发工具 针对
  • imx6ull_kernel_移植

    1 文件目录结构 2 顶层Makefile理解 3 kernel启动流程 4 kernel移植 心得 跟着左神一步一步操作 目前没有太多的理解 硬件适配中网络驱动和emmc 8线适配讲解的最多 文件移植部分基本就是拷贝和粘贴 Q 1 如果要

随机推荐

  • [837]如何统计OSS上整个Bucket和每个目录大小和文件数

    如题 这个功能相当实用 通过本文讲解的方法 可以方便的看到整个Bucket所占用的空间大小 以及每个目录下所含目录和文件所占用的空间大小 一目了然 1 一般情况下 我们打开OSS文件管理器 可以看到目录和文件 可以看到每个文件的大小 但是无
  • FISCO BCOS网络端口讲解

    本期文章讲的就是网络端口互通这点事 作者从FISCO BCOS的网络端口 FISCO BCOS 2 0的典型网络配置 设计网络安全组的一些策略等角度进行了解析 Part 1 FISCO BCOS 2 0网络的三类端口 FISCO BCOS
  • 第五届阿里天池中间件比赛经历分享-决赛

    消息持久化存储引擎 题目 实现一个进程内消息持久化存储引擎 要求包含以下功能 发送消息功能 根据一定的条件做查询或聚合计算 包括 A 查询一定时间窗口内的消息 B 对一定时间窗口内的消息属性某个字段求平均 以及求和 例子 t表示时间 时间窗
  • 采用信号量机制实现消费者与生产者的线程同步_经典生产者-消费者问题解析...

    1 生产者 消费者问题 生产者和消费者问题在现实系统中是很普遍的 例如在一个多媒体系统中 生产者编码视频帧 而消费者消费 解码 视频帧 缓冲区的目的就是减少视频流的抖动 又如在图形用户接口设计中 生产者检测到鼠标和键盘事件 并将其插入到缓冲
  • 10.MATLAB方差分析

    更多MATLAB数据分析视频请点击 或者在网易云课堂上搜索 MATLAB数据分析与统计 http study 163 com course courseMain htm courseId 1003615016 方差分析是英国统计学家R A
  • 推荐模块丨前端uniapp微信小程序项目

    小兔鲜儿 推荐模块 主要实现 Tabs 交互 多 Tabs 列表分页加载数据 动态获取数据 参考效果 推荐模块的布局结构是相同的 因此我们可以复用相同的页面及交互 只是所展示的数据不同 外链图片转存失败 源站可能有防盗链机制 建议将图片保存
  • 2021.11.01 c++下 opencv部署yolov5-6.0版本 (四)

    0 写在最前 2022 10 10 更新yolov5 seg实例分割模型 2022 09 29更新 c 下面使用opencv部署yolov5和yolov7实例分割模型 六 爱晚乏客游的博客 CSDN博客 2022 07 25 更新了下yol
  • [JAVAee]IP数据包的组包与分包

    目录 数据包是什么 数据包的结构 数据包 分组与分组交换 分包是什么 为什么需要分包呢 组包是什么 分包组包过程中和哪些 IP 报头字段有关联 本篇文章主要围绕三个问题来展开 为什么要分包 分包组包过程中和哪些 IP 报头字段有关联 组包时
  • matlab怎么显示当前文件夹和工作区

    参考 matlab怎么显示当前文件夹和工作区 云 社区 腾讯云 1 第一步在我们的电脑上打开matlab 可以看到界面上目前没有显示当前文件夹和工作区 如下图所示 2 第二步我们点击主页右侧的布局 可以看到显示下的当前文件夹和工作区没有勾选
  • 遗传算法入门到掌握(一)

    遗传算法入门到掌握 一 心得 把解决方案做染色体 遗传算法的有趣应用很多 诸如寻路问题 8数码问题 囚犯困境 动作控制 找圆心问题 这是一个国外网友的建议 在一个不规则的多边形 中 寻找一个包含在该多边形内的最大圆圈的圆心 TSP问题 在以
  • node.js HTTP模块 URL模块 supervisor工具

    在vscode 上安装一个插件 Node Snippets 创建一个js文件 直接输入node 就能创建一个服务器 node http server var http require http 表示引入一个HTTP模块 request 表示
  • Texture Format全解析

    Texture Format全解析 Texture Format全解析 What internal representation is used for the texture This is a tradeoff between size
  • sqlmap的安装及使用教程

    1 sqlmap简介 sqlmap 是一个开源渗透测试工具 可自动检测和利用 SQL 注入缺陷并接管数据库服务器 支持多种数据库和多种注入技术 2 sqlmap安装 sqlmap是基于python环境的 因此安装前需要安装python环境
  • Vue + element中table来回切换页面显示差异问题

    这次做项目遇到多个table切换页面显示差异的问题 当我切换到上个页面的时候 表格有一列是下个页面的内容 切换到下个页面的时候那一列的内容消失了 就很奇葩 这个问题也是我都一次遇到 问了Baidu阿姨 上面的解决办法好像都不行 这个时候感觉
  • esxi能直通的显卡型号_虚拟黑群也可以NVMe加速?还能万兆?wa!

    之前我发了三篇关于FreeBSD虚拟机安装黑群晖的文章 没有阅读的同学可以看一下 钱乎 如何拥有一台100T容量的NAS Let s do it zhuanlan zhihu com 钱乎 100TB的NAS之后续填坑 虚拟硬件篇 zhua
  • Gradle sync failed: Sync failed: reason unknown

    android项目复制后打开总是报这个错误 打开build查看红色错误提示 比如提示缺少android 23 打开file gt setting 展开后把对应的SDK勾选上再ok
  • 2021计算机考硕复试线,2021考研复试线汇总:国家线+34所中5所院校复试线①

    原标题 2021考研复试线汇总 国家线 34所中5所院校复试线 突如其来 昨天晚上 中国教育发布 公布了2021年硕士研究生考试学术学位类和专业学位类的国家线 随后 34中的5所院校也更新了2021年复试线成绩 包含以下这5所院校 清华大学
  • vue项目Error: Cannot find module ‘xxx’类报错的解决方法

    现发现只要是报错 Error Cannot find module xxx 例如 Error Cannot find module webpack 这类的问题都可以用下面的方法解决 报错内容如下 运行 npm install 没问题 运行
  • 消息队列的两种模式

    Java消息服务 Java Message Service JMS 应用程序接口是一个Java平台中关于面向消息中间件 MOM 的API 用于在两个应用程序之间 或分布式系统中发送消息 进行异步通信 点对点与发布订阅最初是由JMS定义的 这
  • Box2D C++ 教程-物体

    Box2D C 教程 物体 物体 Bodies 物体是物理场景中的基本对象 但是这里的物体并不是你看到的实际互相弹跳碰撞的实物 听起来很费解吗 挺住 马上做解释 http ohcoder com blog 2012 11 29 bodies