private void addBaffleX(Body body) { try { if (body.GetUserData() == null) { return; } GizmoComponents myGizmo = (GizmoComponents)body.GetUserData(); //添加Shape addPolygon(body); BodyDef kinematicBodyDef = new BodyDef(); kinematicBodyDef.Position.Set(0, myGizmo.PositionY); Body kinematicBody = myWorld.CreateBody(kinematicBodyDef); PrismaticJointDef jointDef = new PrismaticJointDef(); Vec2 worldAxis = new Vec2(1, 0); jointDef.Initialize(body, kinematicBody, kinematicBody.GetWorldCenter(), worldAxis); jointDef.LowerTranslation = -100f; jointDef.UpperTranslation = 100f; jointDef.EnableLimit = true; PrismaticJoint joint = (PrismaticJoint)myWorld.CreateJoint(jointDef); } catch (Exception e) { MessageBox.Show("PhysicalWorld-addBaffleX函数出错"); } }
/// <summary> /// 获取转换后新的gizmo各顶点的相对坐标 /// </summary> /// <param name="type">0表示放大1表示缩小2表示旋转</param> /// <param name="id"></param> /// <returns></returns> public List <Point> getChangeRelativePoint(int type, int id) { GizmoComponents gizmo = scene.getGizmo(id); if (gizmo != null) { int size = gizmo.GizmoSize; int angle = (int)(gizmo.Angle * 180 / System.Math.PI); FormGizmoType formGizmoType = gizmo.FormGizmoType; switch (type) { case 0: size++; break; case 1: size--; break; case 2: angle = angle + 90; break; } if (size != 0) { return(getRelativePoint(formGizmoType, size, angle)); } } return(null); }
private void addPolygon(Body body) { try { if (body.GetUserData() == null) { return; } GizmoComponents myGizmo = (GizmoComponents)body.GetUserData(); PolygonDef polygonDef = new PolygonDef(); polygonDef.Density = myGizmo.Density; polygonDef.Restitution = myGizmo.Restitution; polygonDef.Friction = myGizmo.Friction; for (int i = 0; i < myGizmo.Polygons.Count; i++) { polygonDef.VertexCount = myGizmo.Polygons[i].Count; for (int j = 0; j < myGizmo.Polygons[i].Count; j++) { polygonDef.Vertices[j].Set(myGizmo.Polygons[i][j].X, myGizmo.Polygons[i][j].Y); } body.CreateFixture(polygonDef); } } catch (Exception e) { MessageBox.Show("PhysicalWorld-addBaffleX函数出错"); } }
public int addBaffleX(float positionX, float positionY, int size, int angle, float interval) { GizmoComponents gizmo = new GizmoComponents(); gizmo.FormGizmoType = FormGizmoType.BaffleX; gizmo.Id = idNum++; gizmo.Shape = GizmoType.BaffleX; gizmo.Attribute = GizmoAttribute.baffle; gizmo.IsStatic = 0; gizmo.Restitution = 1f; gizmo.Friction = 0; gizmo.Density = 1; gizmo.Width = interval * size * 4; gizmo.Height = interval * size; gizmo.PositionX = positionX + interval * (size * 4 - 1); gizmo.PositionY = positionY + interval * (size - 1); gizmo.Polygons = GizmoShape.BaffleX.getPolygons(size, interval); gizmo.Vectors = GizmoShape.BaffleX.getVectors(size, interval); gizmo.GizmoSize = size; gizmos.Add(gizmo); GizmoOperation gizmoOpe = new GizmoOperation(gizmo.Id, "Left", KeyType.Left); gizmoOpera.Add(gizmoOpe); gizmoOpe = new GizmoOperation(gizmo.Id, "Right", KeyType.Right); GizmoOpera.Add(gizmoOpe); return(gizmo.Id); }
void ContactListener.BeginContact(Contact contact) { try { Body bodyA = contact.FixtureA.Body; Body bodyB = contact.FixtureB.Body; GizmoComponents gizmoA = (GizmoComponents)bodyA.GetUserData(); GizmoComponents gizmoB = (GizmoComponents)bodyB.GetUserData(); if (gizmoA.FormGizmoType == FormGizmoType.BaffleX) { bodyA.SetLinearVelocity(new Vec2(bodyA.GetLinearVelocity().X, 0)); } if (gizmoB.FormGizmoType == FormGizmoType.BaffleX) { bodyB.SetLinearVelocity(new Vec2(bodyB.GetLinearVelocity().X, 0)); } switch (gizmoA.Attribute) { case GizmoAttribute.absorber: bodyB.SetLinearVelocity(new Vec2(0, 0)); bodyB.SetStatic(); break; case GizmoAttribute.track: bodyB.SetLinearVelocity(new Vec2(bodyB.GetLinearVelocity().X, 0)); break; case GizmoAttribute.dynamicGizmo: if (gizmoB.Attribute != GizmoAttribute.pineBall) { bodyA.SetLinearVelocity(new Vec2(0, 0)); bodyB.SetLinearVelocity(new Vec2(0, 0)); } break; } switch (gizmoB.Attribute) { case GizmoAttribute.absorber: bodyA.SetLinearVelocity(new Vec2(0, 0)); bodyA.SetStatic(); break; case GizmoAttribute.track: bodyA.SetLinearVelocity(new Vec2(bodyA.GetLinearVelocity().X, 0)); break; case GizmoAttribute.dynamicGizmo: if (gizmoA.Attribute != GizmoAttribute.pineBall) { bodyA.SetLinearVelocity(new Vec2(0, 0)); bodyB.SetLinearVelocity(new Vec2(0, 0)); } break; } }catch (Exception e) { MessageBox.Show("MyContactListener-BeginContact函数出错"); } }
/// <summary> /// 使gizmo变为轨道 /// </summary> /// <param name="id"></param> public void becomeTrack(int id) { GizmoComponents gizmo = getGizmo(id); if (gizmo != null) { gizmo.Attribute = GizmoAttribute.track; gizmo.Friction = 0; } }
/// <summary> /// 使gizmo变为吸收器 /// </summary> /// <param name="id"></param> public void becomeAbsorber(int id) { GizmoComponents gizmo = getGizmo(id); if (gizmo != null) { gizmo.Attribute = GizmoAttribute.absorber; gizmo.Friction = 10; } }
private void addBaffle(Body body) { try { if (body.GetUserData() == null) { return; } GizmoComponents myGizmo = (GizmoComponents)body.GetUserData(); //添加Shape addPolygon(body); //添加旋转关节 BodyDef kinematicBodyDef = new BodyDef(); Vec2 position = GizmoShape.PointRotate(new Vec2(myGizmo.PositionX, myGizmo.PositionY), new Vec2(myGizmo.PositionX + myGizmo.Width, myGizmo.PositionY), System.Math.PI * 2 - myGizmo.Angle / 180 * System.Math.PI); kinematicBodyDef.Position.Set(position.X, position.Y); Body kinematicBody = myWorld.CreateBody(kinematicBodyDef); RevoluteJointDef jointDef = new RevoluteJointDef(); switch ((int)myGizmo.Angle) { case 0: jointDef.LowerAngle = -1.57f; //最小角 jointDef.UpperAngle = 0; //最大角 break; case 90: jointDef.LowerAngle = -1.57f; //最小角 jointDef.UpperAngle = 1.57f; //最大角 break; case 180: jointDef.LowerAngle = 0f; //最小角 jointDef.UpperAngle = 1.57f; //最大角 break; case 270: jointDef.LowerAngle = 0f; //最小角 jointDef.UpperAngle = 1.57f; //最大角 break; } jointDef.EnableLimit = true; jointDef.MaxMotorTorque = 100.0f; jointDef.MotorSpeed = 0.0f; jointDef.EnableMotor = true; jointDef.Initialize(body, kinematicBody, position); RevoluteJoint joint = (RevoluteJoint)myWorld.CreateJoint(jointDef); } catch (Exception e) { MessageBox.Show("PhysicalWorld-addBaffleX函数出错"); } }
/// <summary> /// 使gizmo可动 /// </summary> /// <param name="id"></param> public void becomeDynamic(int id) { GizmoComponents gizmo = getGizmo(id); if (gizmo != null) { gizmo.Attribute = GizmoAttribute.dynamicGizmo; gizmo.IsStatic = 0; gizmo.Friction = 0; gizmo.Density = 1; gizmo.Restitution = 1; } }
public int addCircle(float positionX, float positionY, int size, float interval) { GizmoComponents gizmo = new GizmoComponents(); gizmo.FormGizmoType = FormGizmoType.Circle; gizmo.Shape = GizmoType.Circle; gizmo.Attribute = GizmoAttribute.staticGizmo; gizmo.Id = idNum++; gizmo.PositionX = positionX + interval * (size - 1); gizmo.PositionY = positionY + interval * (size - 1); gizmo.Radius = size * interval; gizmo.GizmoSize = size; gizmos.Add(gizmo); return(gizmo.Id); }
public int addL(float positionX, float positionY, int size, int angle, float interval) { GizmoComponents gizmo = new GizmoComponents(); gizmo.FormGizmoType = FormGizmoType.L; gizmo.Id = idNum++; gizmo.Shape = GizmoType.Polygon; gizmo.Attribute = GizmoAttribute.staticGizmo; gizmo.PositionX = positionX + interval * (size - 1); gizmo.PositionY = positionY + interval * (size - 1); gizmo.Angle = angle; gizmo.Polygons = GizmoShape.L.getPolygons(size, interval); gizmo.Vectors = GizmoShape.L.getVectors(size, interval); gizmo.GizmoSize = size; gizmos.Add(gizmo); return(gizmo.Id); }
public int addPineBall(float positionX, float positionY, int size, float interval) { GizmoComponents gizmo = new GizmoComponents(); gizmo.FormGizmoType = FormGizmoType.PineBall; gizmo.Shape = GizmoType.Circle; gizmo.Attribute = GizmoAttribute.pineBall; gizmo.Id = idNum++; gizmo.PositionX = positionX + interval * (size - 1); gizmo.PositionY = positionY + interval * (size - 1); gizmo.Radius = size * interval; gizmo.GizmoSize = size; gizmo.VelocityX = 0; gizmo.VelocityY = -100; gizmo.IsStatic = 0; gizmos.Add(gizmo); return(gizmo.Id); }
/// <summary> /// 添加四周墙壁 /// </summary> /// <param name="positionX"></param> /// <param name="positionY"></param> /// <param name="wallLength"></param> /// <param name="type">0表示左墙1表示下墙2表示右墙3表示上墙</param> /// <returns></returns> public int addWall(float wallLength, int type, int scale) { GizmoComponents gizmo = new GizmoComponents(); gizmo.Id = idNum++; gizmo.Shape = GizmoType.Rectangle; gizmo.Attribute = GizmoAttribute.staticGizmo; gizmo.IsStatic = 1; gizmo.Restitution = 1f; switch (type) { case 0: gizmo.PositionX = 0; gizmo.PositionY = 0; gizmo.Width = 5.0f / scale; gizmo.Height = wallLength; break; case 1: gizmo.PositionX = 0; gizmo.PositionY = wallLength; gizmo.Width = wallLength; gizmo.Height = 5.0f / scale; break; case 2: gizmo.PositionX = wallLength; gizmo.PositionY = 0; gizmo.Width = 5.0f / scale; gizmo.Height = wallLength; break; case 3: gizmo.PositionX = 0; gizmo.PositionY = 0; gizmo.Width = wallLength; gizmo.Height = 5.0f / scale; break; } gizmos.Add(gizmo); return(gizmo.Id); }
private void addRectangle(Body body) { try { if (body.GetUserData() == null) { return; } GizmoComponents myGizmo = (GizmoComponents)body.GetUserData(); PolygonDef rectangleDef = new PolygonDef(); rectangleDef.SetAsBox(myGizmo.Width, myGizmo.Height); rectangleDef.Density = myGizmo.Density; rectangleDef.Restitution = myGizmo.Restitution; rectangleDef.Friction = myGizmo.Friction; body.CreateFixture(rectangleDef); } catch (Exception e) { MessageBox.Show("PhysicalWorld-addBaffleX函数出错"); } }
public int addBaffle(float positionX, float positionY, int size, int angle, float interval) { GizmoComponents gizmo = new GizmoComponents(); gizmo.FormGizmoType = FormGizmoType.Baffle; gizmo.Id = idNum++; gizmo.Shape = GizmoType.Baffle; gizmo.Attribute = GizmoAttribute.baffle; gizmo.IsStatic = 0; gizmo.Angle = angle; gizmo.Density = 10.0f; gizmo.Width = interval * size; gizmo.Height = interval * size / 3.0f; gizmo.PositionX = positionX + interval * (size - 1); gizmo.PositionY = positionY + interval * (size / 3.0f - 1); gizmo.Polygons = GizmoShape.Rectangle.getPolygons(size, interval); gizmo.Vectors = GizmoShape.Rectangle.getVectors(size, interval); gizmo.GizmoSize = size; gizmos.Add(gizmo); return(gizmo.Id); }
private void addCircle(Body body) { try { if (body.GetUserData() == null) { return; } GizmoComponents myGizmo = (GizmoComponents)body.GetUserData(); CircleDef circleDef = new CircleDef(); circleDef.Radius = myGizmo.Radius; circleDef.Density = myGizmo.Density; circleDef.Restitution = myGizmo.Restitution; circleDef.Friction = myGizmo.Friction; body.CreateFixture(circleDef); } catch (Exception e) { MessageBox.Show("PhysicalWorld-addBaffleX函数出错"); } }
/// <summary> /// 改变gizmo的大小、角度 /// </summary> /// <param name="positionX"></param> /// <param name="positionY"></param> /// <param name="type"></param> /// <param name="id"></param> /// <param name="interval"></param> /// <returns></returns> public int changeGizmo(float positionX, float positionY, int type, int id, float interval) { GizmoComponents gizmo = getGizmo(id); if (gizmo != null) { int size = gizmo.GizmoSize; int angle = (int)gizmo.Angle; FormGizmoType formGizmoType = gizmo.FormGizmoType; switch (type) { case 0: size++; break; case 1: size--; break; case 2: angle = (angle + 90) % 360; break; } if (size != 0) { deleteGizmo(id); int newId = 0; newId = addGizmo(positionX, positionY, size, angle, formGizmoType, interval); for (int i = 0; i < GizmoOpera.Count; i++) { if (gizmoOpera[i].id == id) { gizmoOpera[i].id = newId; } } return(newId); } } return(-1); }
/// <summary> /// 根据UI传过来的用户按键,进行相应操作 /// </summary> /// <param name="Key"></param> public void keyDownOperation(string Key) { //判断按键是否在gizmoSystem中有对应的gizmo操作 for (int i = 0; i < scene.GizmoOpera.Count; i++) { if (Key == scene.GizmoOpera[i].operationKey) { for (Body b = PhysicWorld.MyWorld.GetBodyList(); b != null; b = b.GetNext()) { if (b.GetUserData() != null) { GizmoComponents tmpGizmo = (GizmoComponents)b.GetUserData(); //找到按键对应的box2d物理世界中的body if (scene.GizmoOpera[i].id == tmpGizmo.Id && scene.GizmoOpera[i].operationKey == Key) { PhysicWorld.operateBody(b, Key, scene.GizmoOpera[i].keyType); } } } } } }
/// <summary> /// 根据body和scale找出顶点集合 /// </summary> /// <param name="body">要找顶点的Body对象</param> /// <param name="scale">比例尺</param> /// <returns></returns> static public Queue <Point> getBodyPoint(Body body, double scale) { try { Queue <Point> q = new Queue <Point>(); GizmoComponents gizmo = (GizmoComponents)body.GetUserData(); for (int i = 0; i < gizmo.Vectors.Count; i++) { Vec2 center = new Vec2(0, 0); Vec2 start = new Vec2(gizmo.Vectors[i].X, gizmo.Vectors[i].Y); double angle = body.GetAngle(); Vec2 result = PointRotate(center, start, body.GetAngle()); Point p = new Point((int)((result.X + body.GetPosition().X) * scale), (int)((result.Y + body.GetPosition().Y) * scale)); q.Enqueue(p); } return(q); } catch (Exception e) { MessageBox.Show("GizmoShape-getBodyPoint函数出现错误"); return(null); } }
/// <summary> /// 物理世界根据时间粒度前进一步 /// </summary> public void stepWorld() { try { myWorld.Step(TIMESTEP, VELOCITY_ITERATION, POSITION_ITERATION); Body body = myWorld.GetBodyList(); for (int i = 0; i < myWorld.GetBodyCount(); i++) { if (body.GetUserData() != null) { GizmoComponents gizmo = (GizmoComponents)body.GetUserData(); if (GizmoAttribute.dynamicGizmo == gizmo.Attribute) { body.ApplyForce(body.GetMass() * myWorld.Gravity * -1, body.GetWorldCenter()); } } body = body.GetNext(); } } catch (Exception e) { MessageBox.Show("PhysicalWorld-stepWorld函数出错"); } }
public void draw(World world, Graphics g) { Body b = world.GetBodyList(); int i = 0; do { SolidBrush brush; if (b.GetUserData() == null) { i++; b = b.GetNext(); continue; } GizmoComponents GComp = (GizmoComponents)b.GetUserData(); switch (GComp.Attribute) { case GizmoAttribute.pineBall: brush = new SolidBrush(System.Drawing.Color.LawnGreen); break; case GizmoAttribute.staticGizmo: brush = new SolidBrush(System.Drawing.Color.LightBlue); break; case GizmoAttribute.absorber: brush = new SolidBrush(System.Drawing.Color.Red); break; case GizmoAttribute.dynamicGizmo: brush = new SolidBrush(System.Drawing.Color.Yellow); break; case GizmoAttribute.track: brush = new SolidBrush(System.Drawing.Color.Brown); break; case GizmoAttribute.baffle: brush = new SolidBrush(System.Drawing.Color.Gray); break; default: brush = new SolidBrush(System.Drawing.Color.Black); break; } if (GComp == null) { continue; } switch (GComp.Shape) { case GizmoType.Circle: g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; g.FillEllipse(brush, (b.GetPosition().X - GComp.Radius) * Scale, (b.GetPosition().Y - GComp.Radius) * Scale, GComp.Radius * 2 * Scale, GComp.Radius * 2 * Scale); break; case GizmoType.Rectangle: g.FillRectangle(brush, (b.GetPosition().X - GComp.Width) * Scale + 1, (b.GetPosition().Y - GComp.Height) * Scale + 1, (GComp.Width) * Scale * 2 - 1, (GComp.Height) * Scale * 2 - 1); break; case GizmoType.BaffleX: case GizmoType.Baffle: case GizmoType.Polygon: g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; g.FillPolygon(brush, GizmoShape.getBodyPoint(b, Scale).ToArray()); break; } i++; b = b.GetNext(); } while (i < world.GetBodyCount() - 1); }
/// <summary> /// 初始化世界,根据场景变量,生成box2d物理世界 /// </summary> public void initialWorld(Scene scene) { try { //初始化物理世界 AABB worldAABB = new AABB(); worldAABB.LowerBound.Set(-100f, -100f); worldAABB.UpperBound.Set(100.0f, 100.0f); Vec2 gravity = new Vec2(0, GRAVITY);//物理世界重力 myWorld = new World(worldAABB, gravity, true); MyContactListener contactListener = new MyContactListener(); myWorld.SetContactListener(contactListener); for (int i = 0; i < scene.Gizmos.Count; i++) { GizmoComponents myGizmo = scene.Gizmos[i]; //获取gizmo对象 BodyDef bodyDef = new BodyDef(); bodyDef.Position.Set(myGizmo.PositionX, myGizmo.PositionY); //设置gizmo在物理世界的位置 bodyDef.Angle = (float)(myGizmo.Angle / 180 * System.Math.PI); Body body = myWorld.CreateBody(bodyDef); //在物理世界中添加gizmo body.SetUserData(myGizmo); //添加shape switch (myGizmo.Shape) { case GizmoType.Circle: addCircle(body); break; case GizmoType.Rectangle: addRectangle(body); break; case GizmoType.Polygon: addPolygon(body); break; case GizmoType.Baffle: addBaffle(body); break; case GizmoType.BaffleX: addBaffleX(body); break; } //添加运动状态 if (myGizmo.IsStatic == 0) { switch (myGizmo.Attribute) { case GizmoAttribute.dynamicGizmo: body.SetMassFromShapes(); body.ApplyForce(body.GetMass() * myWorld.Gravity * -1, body.GetWorldCenter()); break; case GizmoAttribute.pineBall: body.SetMassFromShapes(); body.ApplyImpulse(new Vec2(myGizmo.VelocityX * body.GetMass(), myGizmo.VelocityY * body.GetMass()), body.GetWorldCenter()); break; case GizmoAttribute.baffle: body.SetMassFromShapes(); break; } } } } catch (Exception e) { MessageBox.Show("PhysicWorld-initialWorld函数出错"); } }