python box2d模拟平抛运动_论述如何基于Box2D模拟星球重力效果

作者:Emanuele Feronato

随着《Angry Birds Space》的问世,我想你定非常疑惑要如何通过Box2D模拟星球重力。

基本原理非常简单。

首先,太空没有重力,所以你将通过如下方式创建没有重力的b2World世界:

private var world:b2World=new b2World(new b2Vec2(0,0),true);

abspace from emanueleferonato.com

接着就是根据主体和球体位置落实Force。

参考如下脚本:

package {

import flash.display.Sprite;

import flash.events.Event;

import flash.events.MouseEvent;

import Box2D.Dynamics.*;

import Box2D.Collision.*;

import Box2D.Collision.Shapes.*;

import Box2D.Common.Math.*;

import Box2D.Dynamics.Joints.*;

public class Main extends Sprite {

private var world:b2World=new b2World(new b2Vec2(0,0),true);

private var worldScale:Number=30;

private var planetVector:Vector.=new Vector.();

private var debrisVector:Vector.=new Vector.();

private var orbitCanvas:Sprite=new Sprite();

public function Main() {

addChild(orbitCanvas);

orbitCanvas.graphics.lineStyle(1,0xff0000);

debugDraw();

addPlanet(180,240,90);

addPlanet(480,120,45);

addEventListener(Event.ENTER_FRAME,update);

stage.addEventListener(MouseEvent.CLICK,createDebris);

}

private function createDebris(e:MouseEvent):void {

addBox(mouseX,mouseY,20,20);

}

private function addPlanet(pX:Number,pY:Number,r:Number):void {

var fixtureDef:b2FixtureDef = new b2FixtureDef();

fixtureDef.restitution=0;

fixtureDef.density=1;

var circleShape:b2CircleShape=new b2CircleShape(r/worldScale);

fixtureDef.shape=circleShape;

var bodyDef:b2BodyDef=new b2BodyDef();

bodyDef.userData=new Sprite();

bodyDef.position.Set(pX/worldScale,pY/worldScale);

var thePlanet:b2Body=world.CreateBody(bodyDef);

planetVector.push(thePlanet);

thePlanet.CreateFixture(fixtureDef);

orbitCanvas.graphics.drawCircle(pX,pY,r*3);

}

private function addBox(pX:Number,pY:Number,w:Number,h:Number):void {

var polygonShape:b2PolygonShape = new b2PolygonShape();

polygonShape.SetAsBox(w/worldScale/2,h/worldScale/2);

var fixtureDef:b2FixtureDef = new b2FixtureDef();

fixtureDef.density=1;

fixtureDef.friction=1;

fixtureDef.restitution=0;

fixtureDef.shape=polygonShape;

var bodyDef:b2BodyDef = new b2BodyDef();

bodyDef.type=b2Body.b2_dynamicBody;

bodyDef.position.Set(pX/worldScale,pY/worldScale);

var box:b2Body=world.CreateBody(bodyDef);

debrisVector.push(box);

box.CreateFixture(fixtureDef);

}

private function debugDraw():void {

var debugDraw:b2DebugDraw = new b2DebugDraw();

var debugSprite:Sprite = new Sprite();

addChild(debugSprite);

debugDraw.SetSprite(debugSprite);

debugDraw.SetDrawScale(worldScale);

debugDraw.SetFlags(b2DebugDraw.e_shapeBit|b2DebugDraw.e_jointBit);

debugDraw.SetFillAlpha(0.5);

world.SetDebugDraw(debugDraw);

}

private function update(e:Event):void {

world.Step(1/30, 10, 10);

world.ClearForces();

for (var i:int=0; i

var debrisPosition:b2Vec2=debrisVector[i].GetWorldCenter();

for (var j:int=0; j

var planetShape:b2CircleShape=planetVector[j].GetFixtureList().GetShape() as b2CircleShape;

var planetRadius:Number=planetShape.GetRadius();

var planetPosition:b2Vec2=planetVector[j].GetWorldCenter();

var planetDistance:b2Vec2=new b2Vec2(0,0);

planetDistance.Add(debrisPosition);

planetDistance.Subtract(planetPosition);

var finalDistance:Number=planetDistance.Length();

if (finalDistance<=planetRadius*3) {

planetDistance.NegativeSelf();

var vecSum:Number=Math.abs(planetDistance.x)+Math.abs(planetDistance.y);

planetDistance.Multiply((1/vecSum)*planetRadius/finalDistance);

debrisVector[i].ApplyForce(planetDistance,debrisVector[i].GetWorldCenter());

}

}

}

world.DrawDebugData();

}

}

}

整个代码只创造静态主体(星球),让你通过点击鼠标放置动态主体(碎屑)。

脚本的唯一有趣之处在于更新函数的循环语句,下面我将逐行进行解释。

for (var i:int=0; i

检测之前存储于矢量Vector中的所有碎屑的循环语句在第14行代码中呈现,在第54行进行更新。

var debrisPosition:b2Vec2=debrisVector[i].GetWorldCenter();

设定碎屑位置。

for (var j:int=0; j

检测之前存储于矢量Vector中的所有星球的循环语句将在第13行代码中呈现,在第38行进行更新。

var planetShape:b2CircleShape=planetVector[j].GetFixtureList().GetShape() as b2CircleShape;

我需要知道星球的质量,因为质量越大,重力吸引力就越强烈。遗憾的是,Box2D静态主体没有质量,所以我需要得到星球的圆形模型……

var planetRadius:Number=planetShape.GetRadius();

……设定它的半径。所以在这种情况下,半径越大,重力吸引力就越强烈。

var planetPosition:b2Vec2=planetVector[j].GetWorldCenter();

设定星球的位置。

var planetDistance:b2Vec2=new b2Vec2(0,0);

创建新的b2Vec2变量,它将存储星球和碎屑之间的距离。

planetDistance.Add(debrisPosition);

添加碎屑坐标轴,然后……

planetDistance.Subtract(planetPosition);

……扣除星球坐标轴。

var finalDistance:Number=planetDistance.Length();

计算星球和碎屑之间的距离。

if (finalDistance<=planetRadius*3) {

检查碎屑是否受到星球重力的影响(游戏邦注:这里碎屑的半径不能大于星球半径的3倍)。

planetDistance.NegativeSelf();

插入星球距离,这样force会按照星球起点的方向移动碎屑。

var vecSum:Number=Math.abs(planetDistance.x)+Math.abs(planetDistance.y);

合计距离矢量分量。因此碎屑远离星球时,重力吸引力应减弱;碎屑靠近星球时,重力吸引力应增强。

planetDistance.Multiply((1/vecSum)*planetRadius/finalDistance);

这是随着我们逐步远离星球,削弱重力的最后公式。

debrisVector[i].ApplyForce(planetDistance,debrisVector[i].GetWorldCenter());

最终force将被运用至碎屑中。

下面是最终结果:

debris from emanueleferonato.com

(本文为游戏邦/gamerboom.com编译,拒绝任何不保留版权的转载,如需转载请联系:游戏邦)

Simulate radial gravity (also known as “planet gravity”) with Box2D as seen on Angry Birds Space

by Emanuele Feronato

With the launch of Angry Birds Space I am sure you are wondering how to simulate planet gravity with Box2D.

And guess what… the basics are very easy.

First, in space there’s no gravity, so you will create a b2World world without gravity this way:

Then, it’s just a matter of applying Forces according to bodies and planets position.

Look at this script:

The whole code just create static bodies (planets) and let you place dynamic bodies (debris) with the click of the mouse.

The only interesting part of the script is the for loop in the update function, which I’ll explain line by line:

Loop which scans for all debris previously stored in debrisVector Vector declared at line 14 and updated at line 54

Gets debris position

Loop which scans for all planets previously stored in planetVector Vector declared at line 13 and updated at line 38

I need to know the mass of the planet because the bigger the mass, the more intense the gravity attraction. Unfortunately Box2D static bodies do not have mass, so I need to get the circle shape of the planet…

… and get its radius. So in this case the bigger the radius, the more intense the gravity attraction

Gets planet position

Creates a new b2Vec2 variable which will store the distance between the planet and the debris

Adds debris coordinates, then…

… subtracts planet coordinates

Calculates the distance between the planet and the debris

Checks if the debris should be affected by planet gravity (in this case, the debris must be within a radius of three times the planet radius)

Inverts planet distance, so that the force will move the debris in the direction of the planet origin

Gets the sum of distance vector components. I will need this to make gravity attraction weaker when the debris is far from the planet, and stronger when the debris is getting close to the planet

This is the final formula to make the gravity weaker as we move far from the planet

And finally the force can be applied to debris

This is the result:(Source:emanueleferonato)

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

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

相关文章

蚂蚁庄园 php源码,蚂蚁庄园五体投地

蚂蚁庄园五体投地&#xff0c;蚂蚁庄园小课堂的题目你答对了吗&#xff1f;今天题目有点难&#xff0c;大家可能不清楚&#xff0c;人们常常会对极其敬重的人五体投地&#xff0c;五体投地的五体指的是什么意思呢&#xff1f;“五体”又称“五轮”&#xff0c;指双肘、双膝和额…

python与javascript的区别_python与js区别有哪些

数据类型js和python都是动态语言&#xff0c;a 1; a abc&#xff0c;a这个变量是动态的&#xff0c;类型是随时可以被更改的。而在java中就是静态语言变量&#xff0c;int a 1&#xff1b;a abc 就会报错。基本命令1.输出js里面的console.log()、document.write()、window.…

fsk调制解调实验报告 matlab,基于MATLAB的-FSK调制与解调-通信原理实验

《基于MATLAB的-FSK调制与解调-通信原理实验》由会员分享&#xff0c;可在线阅读&#xff0c;更多相关《基于MATLAB的-FSK调制与解调-通信原理实验(2页珍藏版)》请在人人文库网上搜索。1、实验五 FSK调制与解调1实验目的和要求用MATLAB实现二进制序列的fsk调制与解调2实验内容用…

电脑端二维码识别工具_电脑端自签工具更新,多功能软件一键签名

因为苹果后台的调整&#xff0c;电脑端的自签工具 Cydia Impactor 一直无法使用&#xff0c;如今虽然没有等到大胡子对 Cydia Impactor 适配更新&#xff0c;却等到了全新的替代工具。先说下为什么 Cydia Impactor 为什么让那么多人惦记&#xff0c;虽然对于不越狱安装越狱工具…

python列表是顺序表还是链表_顺序表与链表

Python中的顺序表 Python中的list和tuple两种类型采用了顺序表的实现技术&#xff0c;具有前面讨论的顺序表的所有性质。 tuple是不可变类型&#xff0c;即不变的顺序表&#xff0c;因此不支持改变其内部状态的任何操作&#xff0c;而其他方面&#xff0c;则与list的性质类似。…

python只读模式可以打印嘛_只读python属性?无法打印对象

在Python中&#xff0c;使用自定义描述符可以很容易地做到这一点。在看看HOWTO中的Descriptor Example。如果您只需更改__get__方法来引发一个AttributeError就这样了。我们不妨将其重命名&#xff0c;去掉日志记录&#xff0c;使之更简单。在class WriteOnly(object):"&q…

php 查文件sha1 内存不足,SHA是否足以检查文件重复? (PHP中的sha1_file)

sha1_file足够好吗&#xff1f;使用sha1_file就足够了,碰撞的可能性非常小,但这种情况几乎不会发生.为了减少几乎0比较文件大小的几率&#xff1a;function is_duplicate_file( $file1,$file2){if(filesize($file1) ! filesize($file2)) return false;if( sha1_file($file1) s…

js for foreach 快慢_js基本搜索算法实现与170万条数据下的性能测试

前言今天让我们来继续聊一聊js算法&#xff0c;通过接下来的讲解&#xff0c;我们可以了解到搜索算法的基本实现以及各种实现方法的性能&#xff0c;进而发现for循环&#xff0c;forEach&#xff0c;While的性能差异&#xff0c;我们还会了解到如何通过web worker做算法分片&am…

python获取工作日_Python获取一段日期内的工作日和所有日期

Pandas1、获取工作日&#xff1a;bdate_rangeimport pandas as pde pd.bdate_range(8/7/2019, 8/31/2019)e.date #获取日期列表array([datetime.date(2019, 8, 7), datetime.date(2019, 8, 8),datetime.date(2019, 8, 9), datetime.date(2019, 8, 12),datetime.date(2019, 8, …

iterm php,iTerm2笔记

本文是 iTerm2 的使用笔记&#xff0c;不定期更新。1 注释说明对于 Preferences 的修改&#xff0c;> 表示需要切换选项卡&#xff0c;-> 表示在同一选项卡内2 参考3 杂301 如何随时随地一键调用 Quake-like iTerm2首先声明&#xff1a;由于 Mac OS 本身对窗体「最大化」…

python 正则表达式 sub_python 正则表达式 re.sub re.subn

python正则表达式模块简介Python 自1.5版本起增加了re 模块&#xff0c;它提供 Perl 风格的正则表达式模式。Python 1.5之前版本则是通过 regex 模块提供 Emacs 风格的模式。Emacs 风格模式可读性稍差些&#xff0c;而且功能也不强&#xff0c;因此编写新代码时尽量不要再使用 …

清浊音判别 matlab,matlab语音信号处理如何判别清浊音?

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼这是我一个学长给的程序&#xff0c;他说里面要算得基本上已经实现了改一下就可以用了。。。但是i本人不是主攻matlab的说白了就是不怎么会&#xff0c;&#xff0c;想问下该怎么改来实现判断清浊音的功能。%对语音信号采样分帧cle…

python upper_Python 3中的模块级string.upper函数在哪里?

如何让这段代码在3中运行&#xff1f; 请注意&#xff0c;我不是"foo".upper()在字符串实例级别询问。import string try: print("string module, upper function:") print(string.upper) foo string.upper("Foo") print("foo:%s" % …

python数据科学实践 常象宇_Python数据科学实践

章基于Python的数据科学环境搭建1.1Python是数据科学“大势所趋”1.2Anaconda入门——工欲善其事&#xff0c;必先利其器1.3JupyterNotebook入门1.4Markdown单元格的使用1.5Spyder入门1.6小结第2章Python基础2.1“火锅团购数据”简介2.2读写数据2.3Python数据类型与结构2.4控制…

matlab emd功率谱密度,【脑电信号分类】脑电信号提取PSD功率谱密度特征

脑电信号是一种非平稳的随机信号&#xff0c;一般而言随机信号的持续时间是无限长的&#xff0c;因此随机信号的总能量是无限的&#xff0c;而随机过程的任意一个样本函数都不满足绝对可积条件&#xff0c;所以其傅里叶变换不存在。不过&#xff0c;尽管随机信号的总能量是无限…

小甲鱼python课后题简书_Python练习题100道

1.有四个数字&#xff1a;1,2,3,4&#xff0c;能组成多少个互不相同且无重复数字的三位数&#xff1f;各是多少&#xff1f; 方法一&#xff1a;遍历所有可能&#xff0c;把重复的剃掉。 total0 for i in range(1,5): for j in range(1,5): for k in range(1,5): if((i!j)and(j…

决策算法python_GitHub - nxety/MachineLearning_Python: 机器学习算法python实现

机器学习算法Python实现目录1、代价函数其中&#xff1a;下面就是要求出theta&#xff0c;使代价最小&#xff0c;即代表我们拟合出来的方程距离真实值最近共有m条数据&#xff0c;其中代表我们要拟合出来的方程到真实值距离的平方&#xff0c;平方的原因是因为可能有负值&…

php7.1安装mysqli扩展,centos php7 安装mysqli扩展心得

在新配服务器时发现&#xff0c;php无法连接到mysql。通过phpinfo发现。根本没有显示mysqli的相关配置。经过一系列研究。总结了下。&#xff1a;第一步&#xff1a;在phpinfo里没有mysqli配置&#xff0c;原因是安装php7时没有configure mysqli安装php方法&#xff1a;wget ht…

组装服务器配置清单_2020年组装电脑配置清单列表

随着电脑技术的不断革新&#xff0c;越来越多的家庭都有各式各样的电子设备。而电脑现在基本上是家家都有的物品&#xff0c;可是在购买电脑的时候新手小白需要注意那些事项呢&#xff1f;今天我们就给告诉小白如何组装电脑以小白组装电脑配置清单。1、购买电脑&#xff0c;您首…

oracle 关于归档的视图,oracle 与归档日志相关的几个视图

归档日志占据的数据库举足轻重的位置&#xff0c;以下系统视图来了解归档日志情况V$ARCHIVEV$ARCHIVED_LOG 已归档日志详单V$ARCHIVE_GAP 归档日志丢失V$ARCHIVE_PROCESSES 归档进程信息V$ARCHIVE_DEST 查看备份路径情况V$ARCHIVE_DEST_STATUSv$recovery_f…