English 中文(简体)
C# XNA Box2d: What kind of joints for a ragdoll?
原标题:
  • 时间:2010-02-14 22:43:11
  •  标签:
  • c#
  • xna
  • box2d

I m trying to make a ragdoll out of a bunch of bodies. What kind of joints do I want to connect them? Distance joints?

最佳回答

The C# API should be pretty similar to the AS3.0 one, have a look at the AS3.0 Flash Implementation Samples:

box2d_as3

Here is the code for the sample ragdoll:

/*
* Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com
*
* This software is provided  as-is , without any express or implied
* warranty.  In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/


package TestBed{



    import Box2D.Dynamics.*;
    import Box2D.Collision.*;
    import Box2D.Collision.Shapes.*;
    import Box2D.Dynamics.Joints.*;
    import Box2D.Dynamics.Contacts.*;
    import Box2D.Common.*;
    import Box2D.Common.Math.*;



    public class TestRagdoll extends Test{

        public function TestRagdoll(){

            // Set Text field
            Main.m_aboutText.text = "Ragdolls";

            var circ:b2CircleShape; 
            var box:b2PolygonShape;
            var bd:b2BodyDef = new b2BodyDef();
            var jd:b2RevoluteJointDef = new b2RevoluteJointDef();
            var fixtureDef:b2FixtureDef = new b2FixtureDef();

            // Add 5 ragdolls along the top
            for (var i:int = 0; i < 2; i++){
                var startX:Number = 70 + Math.random() * 20 + 480 * i;
                var startY:Number = 20 + Math.random() * 50;

                // BODIES
                // Set these to dynamic bodies
                bd.type = b2Body.b2_dynamicBody;

                // Head
                circ = new b2CircleShape( 12.5 / m_physScale );
                fixtureDef.shape = circ;
                fixtureDef.density = 1.0;
                fixtureDef.friction = 0.4;
                fixtureDef.restitution = 0.3;
                bd.position.Set(startX / m_physScale, startY / m_physScale);
                var head:b2Body = m_world.CreateBody(bd);
                head.CreateFixture(fixtureDef);
                //if (i == 0){
                    head.ApplyImpulse(new b2Vec2(Math.random() * 100 - 50, Math.random() * 100 - 50), head.GetWorldCenter());
                //}

                // Torso1
                box = new b2PolygonShape();
                box.SetAsBox(15 / m_physScale, 10 / m_physScale);
                fixtureDef.shape = box;
                fixtureDef.density = 1.0;
                fixtureDef.friction = 0.4;
                fixtureDef.restitution = 0.1;
                bd.position.Set(startX / m_physScale, (startY + 28) / m_physScale);
                var torso1:b2Body = m_world.CreateBody(bd);
                torso1.CreateFixture(fixtureDef);
                // Torso2
                box = new b2PolygonShape();
                box.SetAsBox(15 / m_physScale, 10 / m_physScale);
                fixtureDef.shape = box;
                bd.position.Set(startX / m_physScale, (startY + 43) / m_physScale);
                var torso2:b2Body = m_world.CreateBody(bd);
                torso2.CreateFixture(fixtureDef);
                // Torso3
                box.SetAsBox(15 / m_physScale, 10 / m_physScale);
                fixtureDef.shape = box;
                bd.position.Set(startX / m_physScale, (startY + 58) / m_physScale);
                var torso3:b2Body = m_world.CreateBody(bd);
                torso3.CreateFixture(fixtureDef);

                // UpperArm
                fixtureDef.density = 1.0;
                fixtureDef.friction = 0.4;
                fixtureDef.restitution = 0.1;
                // L
                box = new b2PolygonShape();
                box.SetAsBox(18 / m_physScale, 6.5 / m_physScale);
                fixtureDef.shape = box;
                bd.position.Set((startX - 30) / m_physScale, (startY + 20) / m_physScale);
                var upperArmL:b2Body = m_world.CreateBody(bd);
                upperArmL.CreateFixture(fixtureDef);
                // R
                box = new b2PolygonShape();
                box.SetAsBox(18 / m_physScale, 6.5 / m_physScale);
                fixtureDef.shape = box;
                bd.position.Set((startX + 30) / m_physScale, (startY + 20) / m_physScale);
                var upperArmR:b2Body = m_world.CreateBody(bd);
                upperArmR.CreateFixture(fixtureDef);

                // LowerArm
                fixtureDef.density = 1.0;
                fixtureDef.friction = 0.4;
                fixtureDef.restitution = 0.1;
                // L
                box = new b2PolygonShape();
                box.SetAsBox(17 / m_physScale, 6 / m_physScale);
                fixtureDef.shape = box;
                bd.position.Set((startX - 57) / m_physScale, (startY + 20) / m_physScale);
                var lowerArmL:b2Body = m_world.CreateBody(bd);
                lowerArmL.CreateFixture(fixtureDef);
                // R
                box = new b2PolygonShape();
                box.SetAsBox(17 / m_physScale, 6 / m_physScale);
                fixtureDef.shape = box;
                bd.position.Set((startX + 57) / m_physScale, (startY + 20) / m_physScale);
                var lowerArmR:b2Body = m_world.CreateBody(bd);
                lowerArmR.CreateFixture(fixtureDef);

                // UpperLeg
                fixtureDef.density = 1.0;
                fixtureDef.friction = 0.4;
                fixtureDef.restitution = 0.1;
                // L
                box = new b2PolygonShape();
                box.SetAsBox(7.5 / m_physScale, 22 / m_physScale);
                fixtureDef.shape = box;
                bd.position.Set((startX - 8) / m_physScale, (startY + 85) / m_physScale);
                var upperLegL:b2Body = m_world.CreateBody(bd);
                upperLegL.CreateFixture(fixtureDef);
                // R
                box = new b2PolygonShape();
                box.SetAsBox(7.5 / m_physScale, 22 / m_physScale);
                fixtureDef.shape = box;
                bd.position.Set((startX + 8) / m_physScale, (startY + 85) / m_physScale);
                var upperLegR:b2Body = m_world.CreateBody(bd);
                upperLegR.CreateFixture(fixtureDef);

                // LowerLeg
                fixtureDef.density = 1.0;
                fixtureDef.friction = 0.4;
                fixtureDef.restitution = 0.1;
                // L
                box = new b2PolygonShape();
                box.SetAsBox(6 / m_physScale, 20 / m_physScale);
                fixtureDef.shape = box;
                bd.position.Set((startX - 8) / m_physScale, (startY + 120) / m_physScale);
                var lowerLegL:b2Body = m_world.CreateBody(bd);
                lowerLegL.CreateFixture(fixtureDef);
                // R
                box = new b2PolygonShape();
                box.SetAsBox(6 / m_physScale, 20 / m_physScale);
                fixtureDef.shape = box;
                bd.position.Set((startX + 8) / m_physScale, (startY + 120) / m_physScale);
                var lowerLegR:b2Body = m_world.CreateBody(bd);
                lowerLegR.CreateFixture(fixtureDef);


                // JOINTS
                jd.enableLimit = true;

                // Head to shoulders
                jd.lowerAngle = -40 / (180/Math.PI);
                jd.upperAngle = 40 / (180/Math.PI);
                jd.Initialize(torso1, head, new b2Vec2(startX / m_physScale, (startY + 15) / m_physScale));
                m_world.CreateJoint(jd);

                // Upper arm to shoulders
                // L
                jd.lowerAngle = -85 / (180/Math.PI);
                jd.upperAngle = 130 / (180/Math.PI);
                jd.Initialize(torso1, upperArmL, new b2Vec2((startX - 18) / m_physScale, (startY + 20) / m_physScale));
                m_world.CreateJoint(jd);
                // R
                jd.lowerAngle = -130 / (180/Math.PI);
                jd.upperAngle = 85 / (180/Math.PI);
                jd.Initialize(torso1, upperArmR, new b2Vec2((startX + 18) / m_physScale, (startY + 20) / m_physScale));
                m_world.CreateJoint(jd);

                // Lower arm to upper arm
                // L
                jd.lowerAngle = -130 / (180/Math.PI);
                jd.upperAngle = 10 / (180/Math.PI);
                jd.Initialize(upperArmL, lowerArmL, new b2Vec2((startX - 45) / m_physScale, (startY + 20) / m_physScale));
                m_world.CreateJoint(jd);
                // R
                jd.lowerAngle = -10 / (180/Math.PI);
                jd.upperAngle = 130 / (180/Math.PI);
                jd.Initialize(upperArmR, lowerArmR, new b2Vec2((startX + 45) / m_physScale, (startY + 20) / m_physScale));
                m_world.CreateJoint(jd);

                // Shoulders/stomach
                jd.lowerAngle = -15 / (180/Math.PI);
                jd.upperAngle = 15 / (180/Math.PI);
                jd.Initialize(torso1, torso2, new b2Vec2(startX / m_physScale, (startY + 35) / m_physScale));
                m_world.CreateJoint(jd);
                // Stomach/hips
                jd.Initialize(torso2, torso3, new b2Vec2(startX / m_physScale, (startY + 50) / m_physScale));
                m_world.CreateJoint(jd);

                // Torso to upper leg
                // L
                jd.lowerAngle = -25 / (180/Math.PI);
                jd.upperAngle = 45 / (180/Math.PI);
                jd.Initialize(torso3, upperLegL, new b2Vec2((startX - 8) / m_physScale, (startY + 72) / m_physScale));
                m_world.CreateJoint(jd);
                // R
                jd.lowerAngle = -45 / (180/Math.PI);
                jd.upperAngle = 25 / (180/Math.PI);
                jd.Initialize(torso3, upperLegR, new b2Vec2((startX + 8) / m_physScale, (startY + 72) / m_physScale));
                m_world.CreateJoint(jd);

                // Upper leg to lower leg
                // L
                jd.lowerAngle = -25 / (180/Math.PI);
                jd.upperAngle = 115 / (180/Math.PI);
                jd.Initialize(upperLegL, lowerLegL, new b2Vec2((startX - 8) / m_physScale, (startY + 105) / m_physScale));
                m_world.CreateJoint(jd);
                // R
                jd.lowerAngle = -115 / (180/Math.PI);
                jd.upperAngle = 25 / (180/Math.PI);
                jd.Initialize(upperLegR, lowerLegR, new b2Vec2((startX + 8) / m_physScale, (startY + 105) / m_physScale));
                m_world.CreateJoint(jd);

            }


            // Add stairs on the left, these are static bodies so set the type accordingly
            bd.type = b2Body.b2_staticBody;
            fixtureDef.density = 0.0;
            fixtureDef.friction = 0.4;
            fixtureDef.restitution = 0.3;
            for (var j:int = 1; j <= 10; j++) {
                box = new b2PolygonShape();
                box.SetAsBox((10*j) / m_physScale, 10 / m_physScale);
                fixtureDef.shape = box;
                bd.position.Set((10*j) / m_physScale, (150 + 20*j) / m_physScale);
                head = m_world.CreateBody(bd);
                head.CreateFixture(fixtureDef);
            }

            // Add stairs on the right
            for (var k:int = 1; k <= 10; k++){
                box = new b2PolygonShape();
                box.SetAsBox((10 * k) / m_physScale, 10 / m_physScale);
                fixtureDef.shape = box;
                bd.position.Set((640-10*k) / m_physScale, (150 + 20*k) / m_physScale);
                head = m_world.CreateBody(bd);
                head.CreateFixture(fixtureDef);
            }

            box = new b2PolygonShape();
            box.SetAsBox(30 / m_physScale, 40 / m_physScale);
            fixtureDef.shape = box;
            bd.position.Set(320 / m_physScale, 320 / m_physScale);
            head = m_world.CreateBody(bd);
            head.CreateFixture(fixtureDef);


        }


        //======================
        // Member Data 
        //======================
    }

}
问题回答

暂无回答




相关问题
Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

NSArray s, Primitive types and Boxing Oh My!

I m pretty new to the Objective-C world and I have a long history with .net/C# so naturally I m inclined to use my C# wits. Now here s the question: I feel really inclined to create some type of ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

How to Use Ghostscript DLL to convert PDF to PDF/A

How to user GhostScript DLL to convert PDF to PDF/A. I know I kind of have to call the exported function of gsdll32.dll whose name is gsapi_init_with_args, but how do i pass the right arguments? BTW, ...

Linqy no matchy

Maybe it s something I m doing wrong. I m just learning Linq because I m bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control. ...

热门标签