Java for Android で MouseJoint を使いたいです。私は box2d と cocos2d が初めてです。マウスジョイントの使い方がわかりません。
1 に答える
このチュートリアルの例を見ることをお勧めします。それからコピーします(申し訳ありませんが、壊れたリンクは好きではありません:))...
MouseJoint を使用してボディをドラッグすると、ワールド内の他のボディと衝突し、それらに力が適用されます。
Box2d - マニュアル - http://www.box2d.org/manual.html#_Toc258082974
8.10 マウス関節
マウス ジョイントは、マウスでボディを操作するためにテストベッドで使用されます。カーソルの現在の位置に向かってボディ上のポイントを駆動しようとします。回転に制限はありません。
マウス ジョイントの定義には、ターゲット ポイント、最大力、周波数、および減衰比があります。ターゲット ポイントは、最初はボディのアンカー ポイントと一致します。最大の力は、複数のダイナミック ボディが相互作用するときの激しい反応を防ぐために使用されます。これを好きなだけ大きくすることができます。周波数と減衰比は、ディスタンス ジョイントと同様のスプリング/ダンパー エフェクトを作成するために使用されます。
多くのユーザーがマウスの関節をゲームプレイに適応させようと試みてきました。ユーザーは、正確な測位と瞬時の応答を実現したいと考えることがよくあります。そのコンテキストでは、マウスの関節はうまく機能しません。代わりにキネマティック ボディの使用を検討することをお勧めします。
それでは始めましょう..
- PhysicWorld とその中に少なくとも 1 つのボディを作成する必要があります。( 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());