public CharacterCollision() { // Ground body { BodyDef bd = new BodyDef(); Body ground = m_world.CreateBody(bd); EdgeShape shape = new EdgeShape(); shape.Set(new Vec2(-20.0f, 0.0f), new Vec2(20.0f, 0.0f)); shape.Density = 0; ground.CreateFixture(shape); } // Collinear edges with no adjacency information. // This shows the problematic case where a box shape can hit // an internal vertex. { BodyDef bd = new BodyDef(); Body ground = m_world.CreateBody(bd); EdgeShape shape = new EdgeShape(); shape.Density = 0; shape.Set(new Vec2(-8.0f, 1.0f), new Vec2(-6.0f, 1.0f)); ground.CreateFixture(shape); shape.Set(new Vec2(-6.0f, 1.0f), new Vec2(-4.0f, 1.0f)); ground.CreateFixture(shape); shape.Set(new Vec2(-4.0f, 1.0f), new Vec2(-2.0f, 1.0f)); ground.CreateFixture(shape); } // Chain shape { BodyDef bd = new BodyDef(); bd.angle = 0.25f * (float)Math.PI; Body ground = m_world.CreateBody(bd); Vec2[] vs = new Vec2[4]; vs[0].Set(5.0f, 7.0f); vs[1].Set(6.0f, 8.0f); vs[2].Set(7.0f, 8.0f); vs[3].Set(8.0f, 7.0f); ChainShape shape = new ChainShape(); shape.CreateChain(vs, 4); shape.Density = 0; ground.CreateFixture(shape); } // Square tiles. This shows that adjacency shapes may // have non-smooth collision. There is no solution // to this problem. { BodyDef bd = new BodyDef(); Body ground = m_world.CreateBody(bd); PolygonShape shape = new PolygonShape(); shape.Density = 0; shape.SetAsBox(1.0f, 1.0f, new Vec2(4.0f, 3.0f), 0.0f); ground.CreateFixture(shape); shape.SetAsBox(1.0f, 1.0f, new Vec2(6.0f, 3.0f), 0.0f); ground.CreateFixture(shape); shape.SetAsBox(1.0f, 1.0f, new Vec2(8.0f, 3.0f), 0.0f); ground.CreateFixture(shape); } // Square made from an edge loop. Collision should be smooth. { BodyDef bd = new BodyDef(); Body ground = m_world.CreateBody(bd); Vec2[] vs = new Vec2[4]; vs[0].Set(-1.0f, 3.0f); vs[1].Set(1.0f, 3.0f); vs[2].Set(1.0f, 5.0f); vs[3].Set(-1.0f, 5.0f); ChainShape shape = new ChainShape(); shape.CreateLoop(vs, 4); shape.Density = 0; ground.CreateFixture(shape); } // Edge loop. Collision should be smooth. { BodyDef bd = new BodyDef(); bd.Position.Set(-10.0f, 4.0f); Body ground = m_world.CreateBody(bd); Vec2[] vs = new Vec2[10]; vs[0].Set(0.0f, 0.0f); vs[1].Set(6.0f, 0.0f); vs[2].Set(6.0f, 2.0f); vs[3].Set(4.0f, 1.0f); vs[4].Set(2.0f, 2.0f); vs[5].Set(0.0f, 2.0f); vs[6].Set(-2.0f, 2.0f); vs[7].Set(-4.0f, 3.0f); vs[8].Set(-6.0f, 2.0f); vs[9].Set(-6.0f, 0.0f); ChainShape shape = new ChainShape(); shape.CreateLoop(vs, 10); shape.Density = 0; ground.CreateFixture(shape); } // Square character 1 { BodyDef bd = new BodyDef(); bd.Position.Set(-3.0f, 8.0f); bd.type = BodyType._dynamicBody; bd.fixedRotation = true; bd.allowSleep = false; Body body = m_world.CreateBody(bd); PolygonShape shape = new PolygonShape(); shape.SetAsBox(0.5f, 0.5f); FixtureDef fd = new FixtureDef(); fd.shape = shape; fd.Density = 20.0f; body.CreateFixture(fd); } // Square character 2 { BodyDef bd = new BodyDef(); bd.Position.Set(-5.0f, 5.0f); bd.type = BodyType._dynamicBody; bd.fixedRotation = true; bd.allowSleep = false; Body body = m_world.CreateBody(bd); PolygonShape shape = new PolygonShape(); shape.SetAsBox(0.25f, 0.25f); FixtureDef fd = new FixtureDef(); fd.shape = shape; fd.Density = 20.0f; body.CreateFixture(fd); } // Hexagon character { BodyDef bd = new BodyDef(); bd.Position.Set(-5.0f, 8.0f); bd.type = BodyType._dynamicBody; bd.fixedRotation = true; bd.allowSleep = false; Body body = m_world.CreateBody(bd); float angle = 0.0f; float delta = (float)Math.PI / 3.0f; Vec2[] vertices = new Vec2[6]; for (int i = 0; i < 6; ++i) { vertices[i].Set(0.5f * (float)Math.Cos(angle), 0.5f * (float)Math.Sin(angle)); angle += delta; } PolygonShape shape = new PolygonShape(); shape.Set(vertices, 6); FixtureDef fd = new FixtureDef(); fd.shape = shape; fd.Density = 20.0f; body.CreateFixture(fd); } // Circle character { BodyDef bd = new BodyDef(); bd.Position.Set(3.0f, 5.0f); bd.type = BodyType._dynamicBody; bd.fixedRotation = true; bd.allowSleep = false; Body body = m_world.CreateBody(bd); CircleShape shape = new CircleShape(); shape.m_radius = 0.5f; FixtureDef fd = new FixtureDef(); fd.shape = shape; fd.Density = 20.0f; body.CreateFixture(fd); } // Circle character { BodyDef bd = new BodyDef(); bd.Position.Set(-7.0f, 6.0f); bd.type = BodyType._dynamicBody; bd.allowSleep = false; m_character = m_world.CreateBody(bd); CircleShape shape = new CircleShape(); shape.m_radius = 0.25f; FixtureDef fd = new FixtureDef(); fd.shape = shape; fd.Density = 20.0f; fd.friction = 1.0f; m_character.CreateFixture(fd); } }
public Pinball() { // Ground body Body ground = null; { BodyDef bd = new BodyDef(); ground = m_world.CreateBody(bd); Vec2[] vs = new Vec2[5]; vs[0].Set(0.0f, -2.0f); vs[1].Set(8.0f, 6.0f); vs[2].Set(8.0f, 20.0f); vs[3].Set(-8.0f, 20.0f); vs[4].Set(-8.0f, 6.0f); ChainShape loop = new ChainShape(); loop.CreateLoop(vs, 5); FixtureDef fd = new FixtureDef(); fd.shape = loop; fd.Density = 0.0f; ground.CreateFixture(fd); } // Flippers { Vec2 p1 = new Vec2(-2.0f, 0.0f); Vec2 p2 = new Vec2(2.0f, 0.0f); BodyDef bd = new BodyDef(); bd.type = BodyType._dynamicBody; bd.Position = p1; Body leftFlipper = m_world.CreateBody(bd); bd.Position = p2; Body rightFlipper = m_world.CreateBody(bd); PolygonShape box = new PolygonShape(); box.SetAsBox(1.75f, 0.1f); FixtureDef fd = new FixtureDef(); fd.shape = box; fd.Density = 1.0f; leftFlipper.CreateFixture(fd); rightFlipper.CreateFixture(fd); RevoluteJointDef jd = new RevoluteJointDef(); jd.bodyA = ground; jd.localAnchorB.SetZero(); jd.enableMotor = true; jd.maxMotorTorque = 1000.0f; jd.enableLimit = true; jd.motorSpeed = 0.0f; jd.localAnchorA = p1; jd.bodyB = leftFlipper; jd.lowerAngle = -30.0f * (float)Math.PI / 180.0f; jd.upperAngle = 5.0f * (float)Math.PI / 180.0f; m_leftJoint = (RevoluteJoint)m_world.CreateJoint(jd); jd.motorSpeed = 0.0f; jd.localAnchorA = p2; jd.bodyB = rightFlipper; jd.lowerAngle = -5.0f * (float)Math.PI / 180.0f; jd.upperAngle = 30.0f * (float)Math.PI / 180.0f; m_rightJoint = (RevoluteJoint)m_world.CreateJoint(jd); } // Circle character { BodyDef bd = new BodyDef(); bd.Position.Set(1.0f, 15.0f); bd.type = BodyType._dynamicBody; bd.bullet = true; m_ball = m_world.CreateBody(bd); CircleShape shape = new CircleShape(); shape.m_radius = 0.2f; FixtureDef fd = new FixtureDef(); fd.shape = shape; fd.Density = 1.0f; m_ball.CreateFixture(fd); } m_button = false; }
private void DrawShape(Fixture fixture, Transform xf, Color color) { switch (fixture.GetShapeType()) { case ShapeType.Circle: { CircleShape circle = (CircleShape)fixture.GetShape(); Vec2 center = Utilities.Mul(xf, circle.m_p); float radius = circle.m_radius; Vec2 axis = Utilities.Mul(xf.q, new Vec2(1.0f, 0.0f)); m_debugDraw.DrawSolidCircle(center, radius, axis, color); } break; case ShapeType.Edge: { EdgeShape edge = (EdgeShape)fixture.GetShape(); Vec2 v1 = Utilities.Mul(xf, edge.m_vertex1); Vec2 v2 = Utilities.Mul(xf, edge.m_vertex2); m_debugDraw.DrawSegment(v1, v2, color); } break; case ShapeType.Chain: { ChainShape chain = (ChainShape)fixture.GetShape(); int count = chain.m_count; List <Vec2> vertices = chain.m_vertices; Vec2 v1 = Utilities.Mul(xf, vertices[0]); for (int i = 1; i < count; ++i) { Vec2 v2 = Utilities.Mul(xf, vertices[i]); m_debugDraw.DrawSegment(v1, v2, color); m_debugDraw.DrawCircle(v1, 0.05f, color); v1 = v2; } } break; case ShapeType.Polygon: { PolygonShape poly = (PolygonShape)fixture.GetShape(); int vertexCount = poly.m_count; Utilities.Assert(vertexCount <= Settings._maxPolygonVertices); Vec2[] vertices = new Vec2[Settings._maxPolygonVertices]; for (int i = 0; i < vertexCount; ++i) { vertices[i] = Utilities.Mul(xf, poly.m_vertices[i]); } m_debugDraw.DrawSolidPolygon(vertices, vertexCount, color); } break; default: break; } }