[LIBGDX学习]LibGDX代码详解(十四)Box2D apply force

package com.mygdx.game.box2d;

import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.physics.box2d.BodyDef;
import com.badlogic.gdx.physics.box2d.BodyDef.BodyType;
import com.badlogic.gdx.physics.box2d.EdgeShape;
import com.badlogic.gdx.physics.box2d.FixtureDef;
import com.badlogic.gdx.physics.box2d.PolygonShape;
import com.badlogic.gdx.physics.box2d.Transform;
import com.badlogic.gdx.physics.box2d.World;
import com.badlogic.gdx.physics.box2d.joints.FrictionJointDef;

public class ApplyForce extends Box2DTest {
	Body m_body;

	@Override
	protected void createWorld (World world) {
		world.setGravity(new Vector2(0, 0));

		float k_restitution = 0.4f;// ori 0.4f 设成4.4好玩了

        Body ground;
		{
			BodyDef bd = new BodyDef();
			bd.position.set(0, 20);
			ground = world.createBody(bd);

			EdgeShape shape = new EdgeShape();

			FixtureDef sd = new FixtureDef();
			sd.shape = shape;
			sd.density = 0;
			sd.restitution = k_restitution;

			//shape.set(new Vector2(-20, -20), new Vector2(-20, 20));
            shape.set(new Vector2(-20, -20), new Vector2(-20, 10));// 移下来不然看不见顶
			ground.createFixture(sd);// 要createFixture以后才会存在到世界中

			//shape.set(new Vector2(20, -20), new Vector2(20, 20));
            shape.set(new Vector2(20, -20), new Vector2(20, 10));
			ground.createFixture(sd);

			//shape.set(new Vector2(-20, 20), new Vector2(20, 20));
			shape.set(new Vector2(-20, 10), new Vector2(20, 10));
			ground.createFixture(sd);

			shape.set(new Vector2(-20, -20), new Vector2(20, -20));
			ground.createFixture(sd);

			shape.dispose();
		}

		{
            // 角度是弧度
            // 正数是逆时针方向转,反之亦然
            // 弧度转角度:180/π×弧度
            // 角度转弧度: π/180×角度 ,这里相当于转63.432度?
            // 角度好算,知道这个三角形的三个角角度让其中那个短边垂直就是旋转角度。
            /**
             public Vector2 mul (Vector2 v) {
                float x = vals[POS_X] + vals[COS] * v.x + -vals[SIN] * v.y;
                float y = vals[POS_Y] + vals[SIN] * v.x + vals[COS] * v.y;
                v.x = x;
                v.y = y;
                return v;
             }
             */
			Transform xf1 = new Transform(new Vector2(), 0.3524f * (float)Math.PI);// ori 0.3524f * (float)Math.PI

            // 注意position是Vector2(1, 0)旋转0,.3524*PI后的结果?
            // 相当于1.0这个坐标逆时针转63度?
            /**
             public void setPosition (Vector2 pos) {
                this.vals[POS_X] = pos.x;
                this.vals[POS_Y] = pos.y;
             }
             */
            xf1.setPosition(xf1.mul(new Vector2(1, 0)));//ori 1
            //System.out.println(xf1.getPosition());// (0.4472596,0.8944042)
            //xf1.setPosition(new Vector2(1, 0));

            // x和y的坐标是反过来的,为何?
			Vector2[] vertices = new Vector2[3];
			vertices[0] = xf1.mul(new Vector2(-1, 0));
			vertices[1] = xf1.mul(new Vector2(1, 0));
			vertices[2] = xf1.mul(new Vector2(0, 0.5f));// ori (0, 0.5f)

            for(Vector2 v: vertices){
                System.out.println(v);
            }

			PolygonShape poly1 = new PolygonShape();

            // 从vertices设置polygon shape 最多八个定点,逆时针设置
            poly1.set(vertices);

			FixtureDef sd1 = new FixtureDef();
			sd1.shape = poly1;
			sd1.density = 4.0f;

			Transform xf2 = new Transform(new Vector2(), -0.3524f * (float)Math.PI);// ori -0.3524
			xf2.setPosition(xf2.mul(new Vector2(-1, 0)));// ori -1

			vertices[0] = xf2.mul(new Vector2(-1, 0));
			vertices[1] = xf2.mul(new Vector2(1, 0));
			vertices[2] = xf2.mul(new Vector2(0, 0.5f));
            for(Vector2 v: vertices){
                System.out.println(v);
            }

			PolygonShape poly2 = new PolygonShape();
			poly2.set(vertices);

			FixtureDef sd2 = new FixtureDef();
			sd2.shape = poly2;
			sd2.density = 2.0f;

			BodyDef bd = new BodyDef();
			bd.type = BodyType.DynamicBody;
			bd.angularDamping = 5.0f;
			bd.linearDamping = 0.1f;

			bd.position.set(0, 2);// ori (0,2)
			bd.angle = (float)Math.PI;
			bd.allowSleep = false;
			m_body = world.createBody(bd);
			m_body.createFixture(sd1);
			m_body.createFixture(sd2);
			poly1.dispose();
			poly2.dispose();
		}

		{
			PolygonShape shape = new PolygonShape();
			shape.setAsBox(0.5f, 0.5f);

			FixtureDef fd = new FixtureDef();
			fd.shape = shape;
			fd.density = 1.0f;
			fd.friction = 0.3f;

			for (int i = 0; i < 10; i++) {
				BodyDef bd = new BodyDef();
				bd.type = BodyType.DynamicBody;

				//bd.position.set(0, 5 + 1.54f * i);
                bd.position.set(0, 5 + 1.6f * i);
				Body body = world.createBody(bd);

				body.createFixture(fd);

				float gravity = 10.0f;
				float I = body.getInertia();
				float mass = body.getMass();

                /**
                 * 转动惯量(Moment of Inertia)是刚体绕轴转动时惯性(
                 * 回转物体保持其匀速圆周运动或静止的特性)的量度,用字母I或J表示。
                 * 在经典力学中,转动惯量(又称质量惯性矩,简称惯距)通常以I 或J表示,
                 * SI 单位为 kg·m²。对于一个质点,I = mr²,其中 m 是其质量,
                 * r 是质点和转轴的垂直距离。转动惯量在旋转动力学中的角色相当于
                 * 线性动力学中的质量,可形式地理解为一个物体对于旋转运动的惯性,
                 * 用于建立角动量、角速度、力矩和角加速度等数个量之间的关系。
                 */
				float radius = (float)Math.sqrt(2 * I / mass);

                /**
                 *
                 Revolute - a hinge or pin, where the bodies rotate about a common point
                 Distance - a point on each body will be kept at a fixed distance apart
                 Prismatic - the relative rotation of the two bodies is fixed, and they can slide along an axis
                 Line - a combination of revolute and prismatic joints, useful for modelling vehicle suspension
                 Weld - holds the bodies at the same orientation
                 Pulley - a point on each body will be kept within a certain distance from a point in the world,
                 where the sum of these two distances is fixed, kinda... (sheesh... there is no succinct way to describe this)
                 Friction - reduces the relative motion between the two bodies
                 Gear - controls two other joints (revolute or prismatic) so that the movement of one affects the other
                 Mouse - pulls a point on one body to a location in the world
                 Wheel - the line joint, renamed
                 Rope - a point on each body will be constrained to a maximum distance apart
                 */
				FrictionJointDef jd = new FrictionJointDef();

				jd.localAnchorA.set(0, 0);
				jd.localAnchorB.set(0, 0);
				jd.bodyA = ground;// 四堵墙,所以是在中心点?
				jd.bodyB = body;
				jd.collideConnected = true;
				jd.maxForce = mass * gravity ;
				jd.maxTorque = mass * radius * gravity;// maxTorque大了就不容易转,反之亦然

				world.createJoint(jd);
			}

			shape.dispose();
		}
	}

	private final Vector2 tmp = new Vector2();

	public boolean keyDown (int keyCode) {
		if (keyCode == Keys.W) {
			//Vector2 f = m_body.getWorldVector(tmp.set(0, -200));// 冲力
            Vector2 f = m_body.getWorldVector(tmp.set(0, -400));
			//Vector2 p = m_body.getWorldPoint(tmp.set(0, 2));// 意思是偏离角?
            Vector2 p = m_body.getWorldPoint(tmp.set(0, 1231));// (0,10)意思是往左飘  (10,0)意思是自己转?
			m_body.applyForce(f, p, true);
		}
		//if (keyCode == Keys.A) m_body.applyTorque(50, true);
		//if (keyCode == Keys.D) m_body.applyTorque(-50, true);
        if (keyCode == Keys.A) m_body.applyTorque(500, true);// 转动速度
        if (keyCode == Keys.D) m_body.applyTorque(-500, true);
		return false;
	}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值