计量泵厂家
免费服务热线

Free service

hotline

010-00000000
计量泵厂家
热门搜索:
行业资讯
当前位置:首页 > 行业资讯

论述如何基于Box2D模拟星球重力效果

发布时间:2021-01-22 02:40:15 阅读: 来源:计量泵厂家

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

基本原理非常简单。

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

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

abspace

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

参考如下脚本:

package {

import rite;

import ent;

import useEvent;

import namics.*;

import llision.*;

import aPEs.*;

import th.*;

import ints.*;

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);

neStyle(1,0xff0000);

debugDraw();

addPlanet(180,240,90);

addPlanet(480,120,45);

addEventListener(TER_FRAME,update);

dEventListener(ICK,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();

stitution=0;

nsity=1;

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

ape=circleShape;

var bodyDef:b2BodyDef=new b2BodyDef();

erData=new Sprite();

t(pX/worldScale,pY/worldScale);

var thePlanet:b2Body=eateBody(bodyDef);

sh(thePlanet);

eateFixture(fixtureDef);

awCircle(pX,pY,r*3);

}

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

var polygonShape:b2PolygonShape = new b2PolygonShape();

tAsBox(w/worldScale/2,h/worldScale/2);

var fixtureDef:b2FixtureDef = new b2FixtureDef();

nsity=1;

iction=1;

stitution=0;

ape=polygonShape;

var bodyDef:b2BodyDef = new b2BodyDef();

pe=b2Body.b2_dynamicBody;

t(pX/worldScale,pY/worldScale);

var box:b2Body=eateBody(bodyDef);

sh(box);

eateFixture(fixtureDef);

}

private function debugDraw():void {

var debugDraw:b2DebugDraw = new b2DebugDraw();

var debugSprite:Sprite = new Sprite();

addChild(debugSprite);

tSprite(debugSprite);

tDrawScale(worldScale);

tFlags(b2DebugDraw.e_shapeBit|b2DebugDraw.e_jointBit);

tFillAlpha(0.5);

tDebugDraw(debugDraw);

}

private function update(e:Event):void {

ep(1/30, 10, 10);

earForces();

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=tRadius();

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

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

d(debrisPosition);

btract(planetPosition);

var finalDistance:Number=ngth();

if (finalDistance<=planetRadius*3) {

gativeSelf();

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

ltiply((1/vecSum)*planetRadius/finalDistance);

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

}

}

}

awDebugData();

}

}

}

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

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

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=tRadius();

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

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

设定星球的位置。

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

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

d(debrisPosition);

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

btract(planetPosition);

……扣除星球坐标轴。

var finalDistance:Number=ngth();

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

if (finalDistance<=planetRadius*3) {

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

gativeSelf();

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

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

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

ltiply((1/vecSum)*planetRadius/finalDistance);

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

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

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

下面是最终结果:

debris

至尊传说手游破解版

双彩网app官方版下载送22

魔幻客栈

走出去安卓版