コード例 #1
0
ファイル: PhysicsComponent.cs プロジェクト: SpagAachen/Ballz
        public void LoosenRope(Rope rope)
        {
            if (rope.PhysicsSegments.Count * Rope.SegmentLength >= Rope.MaxLength)
            {
                // Maximum length reached, rope cannot be made any longer
                return;
            }

            var lastSegment = rope.PhysicsSegments.Last();
            var ropeSegmentVector = Vector2.Normalize(rope.AttachedEntity.Position - lastSegment.Position) * Rope.SegmentLength;
            PhysicsWorld.RemoveJoint(rope.PhysicsEntityJoint);

            //var newSegment = BodyFactory.CreateCircle(PhysicsWorld, Rope.SegmentWidth, Rope.SegmentDensity);// BodyFactory.CreateRectangle(PhysicsWorld, 0.05f, Rope.SegmentLength, 0.5f);
            var newSegment = BodyFactory.CreateRectangle(PhysicsWorld, Rope.Diameter, Rope.SegmentLength, Rope.SegmentDensity);
            newSegment.BodyType = BodyType.Dynamic;
            newSegment.AngularDamping = 0.1f;
            newSegment.LinearDamping = 0.1f;
            newSegment.Friction = 0.5f;
            newSegment.Restitution = 0.2f;
            newSegment.CollisionCategories = Category.Cat3;
            newSegment.Position = lastSegment.Position + ropeSegmentVector;

            rope.PhysicsSegments.Add(newSegment);

            var segmentJoint = JointFactory.CreateRevoluteJoint(PhysicsWorld, lastSegment, newSegment, new Vector2(0, Rope.SegmentLength / 2), new Vector2(0, -Rope.SegmentLength / 2));
            segmentJoint.CollideConnected = false;
            rope.PhysicsSegmentJoints.Add(segmentJoint);

            var ballJoint = JointFactory.CreateRevoluteJoint(PhysicsWorld, rope.PhysicsSegments.Last(), rope.AttachedEntity.PhysicsBody, Vector2.Zero, Vector2.Zero);
            ballJoint.CollideConnected = false;
            rope.PhysicsEntityJoint = ballJoint;
        }
コード例 #2
0
ファイル: PhysicsComponent.cs プロジェクト: SpagAachen/Ballz
        public void ShortenRope(Rope rope)
        {
            if (rope.PhysicsSegments.Count <= 2)
            {
                // Rope cannot be any shorter as 2 segments is minimum
                return;
            }

            // Only allow shortening rope if all joints are restful
            for (int i = 0; i < rope.PhysicsSegmentJoints.Count; ++i)
            {
                var joint = rope.PhysicsSegmentJoints[i];
                if (Vector2.Distance(joint.WorldAnchorA, joint.WorldAnchorB) > 0.3f * Rope.SegmentLength)
                    return;
            }

            PhysicsWorld.RemoveJoint(rope.PhysicsEntityJoint);
            PhysicsWorld.RemoveJoint(rope.PhysicsSegmentJoints.Last());
            rope.PhysicsSegmentJoints.Remove(rope.PhysicsSegmentJoints.Last());


            RemoveBody(rope.PhysicsSegments.Last());
            rope.PhysicsSegments.Remove(rope.PhysicsSegments.Last());

            var ballJoint = JointFactory.CreateRevoluteJoint(PhysicsWorld, rope.PhysicsSegments.Last(), rope.AttachedEntity.PhysicsBody, Vector2.Zero, Vector2.Zero);
            ballJoint.CollideConnected = false;
            rope.PhysicsEntityJoint = ballJoint;

        }
コード例 #3
0
ファイル: PhysicsComponent.cs プロジェクト: SpagAachen/Ballz
        public void RemoveRope(Rope rope)
        {
            foreach (var joint in rope.PhysicsSegmentJoints)
            {
                PhysicsWorld.RemoveJoint(joint);
            }

            rope.PhysicsSegmentJoints.Clear();

            foreach (var body in rope.PhysicsSegments)
            {
                RopesByPhysicsBody.Remove(body);
                RemoveBody(body);
            }

            rope.PhysicsSegments.Clear();
            if (rope.AttachedEntity is Ball)
            {
                (rope.AttachedEntity as Ball).PhysicsBody.Mass = 10f;
                (rope.AttachedEntity as Ball).PhysicsBody.FixedRotation = true;
            }
        }
コード例 #4
0
ファイル: PhysicsComponent.cs プロジェクト: SpagAachen/Ballz
        public void AddRope(Rope rope)
        {
            float ropeLength = (rope.AttachedEntity.Position - rope.AttachedPosition).Length();
            int segmentCount = (int)Round(1 + (ropeLength / Rope.SegmentLength));

            if (segmentCount < 2)
                segmentCount = 2;

            var ropeSegmentDir = Vector2.Normalize(rope.AttachedEntity.Position - rope.AttachedPosition);

            // TODO: fix the RotationFromDirection function!
            var ropeRotation = ropeSegmentDir.RotationFromDirection();

            rope.PhysicsSegments.Clear();

            for (int i = 0; i < segmentCount; i++)
            {
                var ropeSegmentLength = i > 0 ? Rope.SegmentLength : Rope.Diameter;
                var ropeSegmentVector = ropeSegmentDir * ropeSegmentLength;
                var segmentStart = rope.AttachedPosition + ropeSegmentVector * i;
                var segmentCenter = rope.AttachedPosition + ropeSegmentVector * (i + 0.5f);

                var boxWidth = Rope.Diameter;
                var boxHeight = i > 0 ? Rope.SegmentLength : Rope.Diameter;

                //var segment = BodyFactory.CreateCircle(PhysicsWorld, Rope.JointRadius, Rope.SegmentDensity);// BodyFactory.CreateRectangle(PhysicsWorld, 0.05f, Rope.SegmentLength, 0.5f);
                var segment = BodyFactory.CreateRectangle(PhysicsWorld, boxWidth, boxHeight, Rope.SegmentDensity);
                segment.BodyType = BodyType.Dynamic;
                segment.Friction = 0.5f;
                segment.Restitution = 0.2f;
                segment.AngularDamping = 0.2f;//1.1f;
                segment.LinearDamping = 0.2f;// 1.1f;
                segment.CollisionCategories = Category.Cat3;
                segment.SetTransform(segmentCenter, -ropeRotation - 0.5f * (float)Math.PI);

                rope.PhysicsSegments.Add(segment);

                if (i > 0)
                {
                    var segmentJoint = JointFactory.CreateRevoluteJoint(PhysicsWorld, rope.PhysicsSegments[i - 1], segment, new Vector2(0, i == 1 ? Rope.Diameter / 2 : Rope.SegmentLength / 2), new Vector2(0, -Rope.SegmentLength / 2));
                    segmentJoint.CollideConnected = false;
                    rope.PhysicsSegmentJoints.Add(segmentJoint);
                }
                else
                {
                    segment.BodyType = BodyType.Static;
                }
            }
            //var ballAnchor = rope.AttachedEntity.Position + new Vector2(0, rope.AttachedEntity.Radius + 1f);
            var ballJoint = JointFactory.CreateRevoluteJoint(PhysicsWorld, rope.PhysicsSegments.Last(), rope.AttachedEntity.PhysicsBody, new Vector2(0, Rope.SegmentLength / 2), Vector2.Zero);
            ballJoint.CollideConnected = false;
            rope.PhysicsEntityJoint = ballJoint;
            
            rope.AttachedEntity.PhysicsBody.FixedRotation = false;
            //rope.AttachedEntity.PhysicsBody.Mass = 2f;
        }
コード例 #5
0
 public void DrawRope(Rope rope)
 {
     bool first = true;
     foreach(var segment in rope.PhysicsSegments)
     {
         
        //DrawSphere(segment.Position, segment.Rotation, Rope.JointRadius, true);
         DrawRectangle(segment.Position, Rope.Diameter, first ? Rope.Diameter : Rope.SegmentLength, segment.Rotation, true);
         first = false;
     }
 }
コード例 #6
0
ファイル: GameRenderer.cs プロジェクト: SpagAachen/Ballz
        public void DrawRope(Rope rope)
        {
            //var segmentPositions = (from s in rope.PhysicsSegments select s.Position).ToArray();
            //var segmentPositions = (from s in rope.PhysicsSegments select s.GetWorldPoint(new Vector2(0, 0.5f))).ToArray();

            var segmentPositionsList = (from s in rope.PhysicsSegmentJoints select s.WorldAnchorA).ToList();
            segmentPositionsList.Insert(0, rope.AttachedPosition);
            segmentPositionsList.Add(rope.AttachedEntity.Position);
            var segmentPositions = segmentPositionsList.ToArray();

            var triangleCount = (segmentPositions.Length - 1) * 2;
            
            VertexPositionColorTexture[] vpc = new VertexPositionColorTexture[triangleCount * 3];
            
            float u = 0;

            for(int i = 0; i < segmentPositions.Length - 1; i++)
            {
                var p0 = segmentPositions[i + 1];
                var p1 = segmentPositions[i];
                var d = Vector2.Normalize(p1 - p0);
                var n = new Vector2(d.Y, -d.X);
                
                var u0 = u - d.Length() * 0.05f;
                var u1 = u + (p1 - p0).Length() + d.Length() * 0.05f;

                p0 -= d * 0.05f;
                p1 += d * 0.05f;

                var t00 = p0 + n * RopeWidth;
                var t10 = p1 + n * RopeWidth;
                var t01 = p0 - n * RopeWidth;
                var t11 = p1 - n * RopeWidth;

                vpc[i * 6 + 0].Color = Color.White;
                vpc[i * 6 + 0].Position = new Vector3(t11, -1);
                vpc[i * 6 + 0].TextureCoordinate = new Vector2(1, u1 / (2f * RopeWidth));
                vpc[i * 6 + 1].Color = Color.White;
                vpc[i * 6 + 1].Position = new Vector3(t10, -1);
                vpc[i * 6 + 1].TextureCoordinate = new Vector2(0, u1 / (2f * RopeWidth));
                vpc[i * 6 + 2].Color = Color.White;
                vpc[i * 6 + 2].Position = new Vector3(t00, -1);
                vpc[i * 6 + 2].TextureCoordinate = new Vector2(0, u0 / (2f * RopeWidth));

                vpc[i * 6 + 3].Color = Color.White;
                vpc[i * 6 + 3].Position = new Vector3(t01, -1);
                vpc[i * 6 + 3].TextureCoordinate = new Vector2(1, u0 / (2f * RopeWidth));
                vpc[i * 6 + 4].Color = Color.White;
                vpc[i * 6 + 4].Position = new Vector3(t11, -1);
                vpc[i * 6 + 4].TextureCoordinate = new Vector2(1, u1 / (2f * RopeWidth));
                vpc[i * 6 + 5].Color = Color.White;
                vpc[i * 6 + 5].Position = new Vector3(t00, -1);
                vpc[i * 6 + 5].TextureCoordinate = new Vector2(0, u0 / (2f * RopeWidth));

                u = u1;
            }
            
            RopeEffect.World = Matrix.Identity;
            RopeEffect.View = Game.Camera.View;
            RopeEffect.Projection = Game.Camera.Projection;
            RopeEffect.CurrentTechnique.Passes[0].Apply();
            GraphicsDevice.SamplerStates[0] = new SamplerState
            {
                AddressU = TextureAddressMode.Wrap,
                AddressV = TextureAddressMode.Wrap
            };

            GraphicsDevice.DrawUserPrimitives<VertexPositionColorTexture>(PrimitiveType.TriangleList, vpc, 0, triangleCount);
        }