Android中如何使用鼠标关节?

发布于 2024-12-07 01:12:03 字数 78 浏览 1 评论 0原文

我想在 Android 上使用 Java 中的 MouseJoint。我是 box2d 和 cocos2d 的新手。我不知道如何使用鼠标关节。

I want to use the MouseJoint in Java for Android. I am new in box2d and cocos2d. I don't know how to use the mouse joint.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

海夕 2024-12-14 01:12:03

我建议您查看 这个教程示例。从中复制(抱歉,我不喜欢损坏的链接:))...

你在 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());

i recomend you to see this tutorial example. Copy from it (sorry i don't like broken links :) ) ...

you drag your body with the help of the MouseJoint, it will collide with the other bodys in the world and apply force to them.

Box2d - Manual - http://www.box2d.org/manual.html#_Toc258082974

8.10 Mouse Joint

The mouse joint is used in the testbed to manipulate bodies with the mouse. It attempts to drive a point on a body towards the current position of the cursor. There is no restriction on rotation.

The mouse joint definition has a target point, maximum force, frequency, and damping ratio. The target point initially coincides with the body’s anchor point. The maximum force is used to prevent violent reactions when multiple dynamic bodies interact. You can make this as large as you like. The frequency and damping ratio are used to create a spring/damper effect similar to the distance joint.

Many users have tried to adapt the mouse joint for game play. Users often want to achieve precise positioning and instantaneous response. The mouse joint doesn’t work very well in that context. You may wish to consider using kinematic bodies instead.

So let's start..

  • You have to create your PhysicWorld and at least one body in it. ( Checkout the PhysicExample how to.. )

- MouseJoint method

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

- Touching Body

we have to override our onAreaTouched method to create an MouseJoint anchor-point on the touch position.

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

- Moving the body

We are moving our finger over the scene, so we have to move the MouseJoint too.
If we release the finger.. we must destroy the 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;
}

FYI:
To fit your needs, you have to play with this settings ( in the createMouseJoint method )

mjd.dampingRatio = 0.2f;

mjd.frequencyHz = 30;

mjd.maxForce = (float) (200.0f * boxBody.getMass());
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文