我想在 Java 中为 Android 使用 MouseJoint。我是 box2d 和 cocos2d 的新手。我不知道如何使用鼠标关节。
1 回答
我建议您查看本教程示例。从中复制(对不起,我不喜欢断开的链接:))...
你在 MouseJoint 的帮助下拖动你的身体,它会与世界上的其他身体发生碰撞并对它们施加力。
Box2d - 手册 - http: //www.box2d.org/manual.html#_Toc258082974
8.10 鼠标关节
鼠标关节在测试台中用于用鼠标操纵身体。它试图将身体上的一个点驱动到光标的当前位置。旋转没有限制。
鼠标关节定义有目标点、最大力、频率和阻尼比。目标点最初与身体的锚点重合。当多个动态物体相互作用时,使用最大力来防止剧烈反应。你可以把它放大到你喜欢的大小。频率和阻尼比用于创建类似于距离接头的弹簧/阻尼器效果。
许多用户试图调整鼠标关节以进行游戏。用户往往希望实现精准定位和瞬时响应。在这种情况下,鼠标关节不能很好地工作。您可能希望考虑改用运动学实体。
所以让我们开始吧..
- 你必须在其中创建你的物理世界和至少一个身体。(查看 PhysicExample 如何..)
- MouseJoint 方法
public MouseJoint createMouseJoint(AnimatedSprite box , float x, float y)
{
final Body boxBody =
this.mPhysicsWorld.getPhysicsConnectorManager().findBodyByShape(box);
Vector2 v = boxBody.getWorldPoint(
new Vector2(x/pixelToMeteRatio, y/pixelToMeteRatio)
);
MouseJointDef mjd = new MouseJointDef();
mjd.bodyA = groundBody;
mjd.bodyB = boxBody;
mjd.dampingRatio = 0.2f;
mjd.frequencyHz = 30;
mjd.maxForce = (float) (200.0f * boxBody.getMass());
mjd.collideConnected = true;
mjd.target.set(v);
return (MouseJoint) this.mPhysicsWorld.createJoint(mjd);
}
- 触摸身体
我们必须重写我们的 onAreaTouched 方法来在触摸位置上创建一个 MouseJoint 锚点。
MouseJoint mjActive = null;
private float pixelToMeteRatio = PhysicsConstants.PIXEL_TO_METER_RATIO_DEFAULT;
@Override
public boolean onAreaTouched(
final TouchEvent pSceneTouchEvent,
final ITouchArea pTouchArea ,
final float pTouchAreaLocalX,
final float pTouchAreaLocalY )
{
if(pSceneTouchEvent.getAction() == MotionEvent.ACTION_DOWN) {
this.runOnUpdateThread(new Runnable() {
@Override
public void run() {
final AnimatedSprite face = (AnimatedSprite)pTouchArea; //The touched body
//If we have a active MouseJoint, we are just moving arround don't create an 2nd one.
if( mjActive == null)
{
Vector2 vector = new Vector2(pTouchAreaLocalX/pixelToMeteRatio,pTouchAreaLocalY/pixelToMeteRatio);
//=====================================
// GROUNDBODY - Used for the MouseJoint
//=====================================
BodyDef groundBodyDef = new BodyDef();
groundBodyDef.position.set(vector);
groundBody = mPhysicsWorld.createBody(groundBodyDef);
//====================================
// CREATE THE MOUSEJOINT
//====================================
mjActive = PhysicsJumpExample.this.createMouseJoint(face, pTouchAreaLocalX, pTouchAreaLocalY);
}
}});
return true;
}
return false;
}
- 移动身体
我们在场景上移动手指,所以我们也必须移动 MouseJoint。如果我们松开手指.. 我们必须破坏 MouseJoint..
@Override
public boolean onSceneTouchEvent(final Scene pScene, final TouchEvent pSceneTouchEvent) {
if(this.mPhysicsWorld != null) {
if(pSceneTouchEvent.getAction() == MotionEvent.ACTION_MOVE) {
this.runOnUpdateThread(new Runnable() {
@Override
public void run() {
if( mjActive != null ){ //If the MJ is active move it ..
// =========================================
// MOVE THE MOUSEJOINT WITH THE FINGER..
// =========================================
Vecotr2 vec = new Vector2(pSceneTouchEvent.getX()/pixelToMeteRatio, pSceneTouchEvent.getY()/pixelToMeteRatio);
mjActive.setTarget(vec);
}
}});
return true;
}
//===========================================
// RELEASE THE FINGER FROM THE SCENE..
//===========================================
if( pSceneTouchEvent.getAction() == MotionEvent.ACTION_UP ||
pSceneTouchEvent.getAction() == MotionEvent.ACTION_CANCEL
) {
this.runOnUpdateThread(new Runnable() {
@Override
public void run() {
if( mjActive != null )
{
//======================================
// DESTROY OUR MOUSEJOINT
//======================================
PhysicsJumpExample.this.mPhysicsWorld.destroyJoint(mjActive);
PhysicsJumpExample.this.mPhysicsWorld.destroyBody(groundBody);
mjActive = null;
}
}});
return true;
}
return false;
}
仅供参考:为了满足您的需求,您必须使用此设置(在 createMouseJoint 方法中)
mjd.dampingRatio = 0.2f;
mjd.frequencyHz = 30;
mjd.maxForce = (float) (200.0f * boxBody.getMass());