/// <summary> /// Creates a chain. /// </summary> /// <param name="world">The world.</param> /// <param name="start">The start.</param> /// <param name="end">The end.</param> /// <param name="linkWidth">The width.</param> /// <param name="linkHeight">The height.</param> /// <param name="fixStart">if set to <c>true</c> [fix start].</param> /// <param name="fixEnd">if set to <c>true</c> [fix end].</param> /// <param name="numberOfLinks">The number of links.</param> /// <param name="linkDensity">The link density.</param> /// <returns></returns> public static Path CreateChain(World world, Vector2 start, Vector2 end, float linkWidth, float linkHeight, bool fixStart, bool fixEnd, int numberOfLinks, float linkDensity) { // Chain start / end Path path = new Path(); path.Add(start); path.Add(end); // A single chainlink PolygonShape shape = new PolygonShape(PolygonTools.CreateRectangle(linkWidth, linkHeight)); // Use PathManager to create all the chainlinks based on the chainlink created before. List<Body> chainLinks = PathManager.EvenlyDistibuteShapesAlongPath(world, path, shape, BodyType.Dynamic, numberOfLinks, linkDensity); if (fixStart) { // Fix the first chainlink to the world JointFactory.CreateFixedRevoluteJoint(world, chainLinks[0], new Vector2(0, -(linkHeight / 2)), chainLinks[0].Position); } if (fixEnd) { // Fix the last chainlink to the world JointFactory.CreateFixedRevoluteJoint(world, chainLinks[chainLinks.Count - 1], new Vector2(0, (linkHeight / 2)), chainLinks[chainLinks.Count - 1].Position); } // Attach all the chainlinks together with a revolute joint PathManager.AttachBodiesWithRevoluteJoint(world, chainLinks, new Vector2(0, -linkHeight), new Vector2(0, linkHeight), false, false); return (path); }
/// <summary> /// Duplicates the given Body along the given path for approximatly the given copies. /// </summary> /// <param name="world">The world.</param> /// <param name="path">The path.</param> /// <param name="shapes">The shapes.</param> /// <param name="type">The type.</param> /// <param name="copies">The copies.</param> /// <param name="userData"></param> /// <returns></returns> public static List<Body> EvenlyDistributeShapesAlongPath(World world, Path path, IEnumerable<Shape> shapes, BodyType type, int copies, object userData = null) { List<Vector3> centers = path.SubdivideEvenly(copies); List<Body> bodyList = new List<Body>(); for (int i = 0; i < centers.Count; i++) { Body b = new Body(world); // copy the type from original body b.BodyType = type; b.Position = new Vector2(centers[i].X, centers[i].Y); b.Rotation = centers[i].Z; b.UserData = userData; foreach (Shape shape in shapes) { b.CreateFixture(shape); } bodyList.Add(b); } return bodyList; }
public Chain(Path path, List<Body> bodies) { Path = path; Bodies = bodies; AddRange(bodies); }
public Robot(Texture2D tex, Vector2 pos, World world) { this.tex = tex; this.pos = pos; robotBody = BodyFactory.CreateRectangle(world, 100f / 64f, 100f / 64f, 1f, pos / 64); robotBody.BodyType = BodyType.Dynamic; robotBody.FixedRotation = true; robotBody.CollisionCategories = Category.Cat3; robotBody.CollidesWith = Category.All ^ Category.Cat4; robotBody.BodyId = 4; robotBody.OnCollision += new OnCollisionEventHandler(OnCollision); // path { pos = pos / 64; path = new Path(); path.Add(pos); path.Add(new Vector2(pos.X + 6.5f, pos.Y)); path.Add(new Vector2(pos.X + 6.5f, pos.Y + 0.1f)); path.Add(new Vector2(pos.X, pos.Y + 0.1f)); path.Closed = true; } }
public override void LoadContent() { base.LoadContent(); World.Gravity = new Vector2(0, 9.82f); _border = new Border(World, this, ScreenManager.GraphicsDevice.Viewport); /* Bridge */ //We make a path using 2 points. Path bridgePath = new Path(); bridgePath.Add(new Vector2(-15, 5)); bridgePath.Add(new Vector2(15, 5)); bridgePath.Closed = false; Vertices box = PolygonTools.CreateRectangle(0.125f, 0.5f); PolygonShape shape = new PolygonShape(box, 20); _bridgeBodies = PathManager.EvenlyDistributeShapesAlongPath(World, bridgePath, shape, BodyType.Dynamic, 29); _bridgeBox = new Sprite(ScreenManager.Assets.TextureFromShape(shape, MaterialType.Dots, Color.SandyBrown, 1f)); //Attach the first and last fixtures to the world JointFactory.CreateFixedRevoluteJoint(World, _bridgeBodies[0], new Vector2(0f, -0.5f), _bridgeBodies[0].Position); JointFactory.CreateFixedRevoluteJoint(World, _bridgeBodies[_bridgeBodies.Count - 1], new Vector2(0, 0.5f), _bridgeBodies[_bridgeBodies.Count - 1].Position); PathManager.AttachBodiesWithRevoluteJoint(World, _bridgeBodies, new Vector2(0f, -0.5f), new Vector2(0f, 0.5f), false, true); /* Soft body */ //We make a rectangular path. Path rectanglePath = new Path(); rectanglePath.Add(new Vector2(-6, -11)); rectanglePath.Add(new Vector2(-6, 1)); rectanglePath.Add(new Vector2(6, 1)); rectanglePath.Add(new Vector2(6, -11)); rectanglePath.Closed = true; //Creating two shapes. A circle to form the circle and a rectangle to stabilize the soft body. List<Shape> shapes = new List<Shape>(2); shapes.Add(new PolygonShape(PolygonTools.CreateRectangle(0.5f, 0.5f, new Vector2(-0.1f, 0f), 0f), 1f)); shapes.Add(new CircleShape(0.5f, 1f)); //We distribute the shapes in the rectangular path. _softBodies = PathManager.EvenlyDistributeShapesAlongPath(World, rectanglePath, shapes, BodyType.Dynamic, 30); _softBodyBox = new Sprite(ScreenManager.Assets.TextureFromShape(shapes[0], MaterialType.Blank, Color.Silver * 0.8f, 1f)); _softBodyBox.Origin += new Vector2(ConvertUnits.ToDisplayUnits(0.1f), 0f); _softBodyCircle = new Sprite(ScreenManager.Assets.TextureFromShape(shapes[1], MaterialType.Waves, Color.Silver, 1f)); //Attach the bodies together with revolute joints. The rectangular form will converge to a circular form. PathManager.AttachBodiesWithRevoluteJoint(World, _softBodies, new Vector2(0f, -0.5f), new Vector2(0f, 0.5f), true, true); }
public override void LoadContent() { base.LoadContent(); World.Gravity = new Vector2(0, 9.82f); _border = new Border(World, Lines, Framework.GraphicsDevice); // Bridge // We make a path using 2 points. Path bridgePath = new Path(); bridgePath.Add(new Vector2(-15, 5)); bridgePath.Add(new Vector2(15, 5)); bridgePath.Closed = false; Vertices box = PolygonTools.CreateRectangle(0.125f, 0.5f); PolygonShape shape = new PolygonShape(box, 20); _bridgeBodies = PathManager.EvenlyDistributeShapesAlongPath(World, bridgePath, shape, BodyType.Dynamic, 29); // Attach the first and last fixtures to the world Body anchor = new Body(World, Vector2.Zero); anchor.BodyType = BodyType.Static; World.AddJoint(new RevoluteJoint(_bridgeBodies[0], anchor, _bridgeBodies[0].Position - new Vector2(0.5f, 0f), true)); World.AddJoint(new RevoluteJoint(_bridgeBodies[_bridgeBodies.Count - 1], anchor, _bridgeBodies[_bridgeBodies.Count - 1].Position + new Vector2(0.5f, 0f), true)); PathManager.AttachBodiesWithRevoluteJoint(World, _bridgeBodies, new Vector2(0f, -0.5f), new Vector2(0f, 0.5f), false, true); // Soft body // We make a rectangular path. Path rectanglePath = new Path(); rectanglePath.Add(new Vector2(-6, -11)); rectanglePath.Add(new Vector2(-6, 1)); rectanglePath.Add(new Vector2(6, 1)); rectanglePath.Add(new Vector2(6, -11)); rectanglePath.Closed = true; // Creating two shapes. A circle to form the circle and a rectangle to stabilize the soft body. Shape[] shapes = new Shape[2]; shapes[0] = new PolygonShape(PolygonTools.CreateRectangle(0.5f, 0.5f, new Vector2(-0.1f, 0f), 0f), 1f); shapes[1] = new CircleShape(0.5f, 1f); // We distribute the shapes in the rectangular path. _softBodies = PathManager.EvenlyDistributeShapesAlongPath(World, rectanglePath, shapes, BodyType.Dynamic, 30); // Attach the bodies together with revolute joints. The rectangular form will converge to a circular form. PathManager.AttachBodiesWithRevoluteJoint(World, _softBodies, new Vector2(0f, -0.5f), new Vector2(0f, 0.5f), true, true); // GFX _bridgeBox = new Sprite(ContentWrapper.TextureFromShape(shape, ContentWrapper.Orange, ContentWrapper.Brown)); _softBodyBox = new Sprite(ContentWrapper.TextureFromShape(shapes[0], ContentWrapper.Green, ContentWrapper.Black)); _softBodyBox.Origin += new Vector2(ConvertUnits.ToDisplayUnits(0.1f), 0f); _softBodyCircle = new Sprite(ContentWrapper.TextureFromShape(shapes[1], ContentWrapper.Lime, ContentWrapper.Grey)); }
private PathTest() { //Single body that moves around path _movingBody = BodyFactory.CreateBody(World); _movingBody.Position = new Vector2(-25, 25); _movingBody.BodyType = BodyType.Dynamic; _movingBody.CreateFixture(new PolygonShape(PolygonTools.CreateRectangle(0.5f, 0.5f), 1)); //Static shape made up of bodies _path = new Path(); _path.Add(new Vector2(0, 20)); _path.Add(new Vector2(5, 15)); _path.Add(new Vector2(20, 18)); _path.Add(new Vector2(15, 1)); _path.Add(new Vector2(-5, 14)); _path.Closed = true; CircleShape shape = new CircleShape(0.25f, 1); PathManager.EvenlyDistributeShapesAlongPath(World, _path, shape, BodyType.Static, 100); //Smaller shape that is movable. Created from small rectangles and circles. Vector2 xform = new Vector2(0.5f, 0.5f); _path.Scale(ref xform); xform = new Vector2(5, 5); _path.Translate(ref xform); List<Shape> shapes = new List<Shape>(2); shapes.Add(new PolygonShape(PolygonTools.CreateRectangle(0.5f, 0.5f, new Vector2(-0.1f, 0), 0), 1)); shapes.Add(new CircleShape(0.5f, 1)); List<Body> bodies = PathManager.EvenlyDistributeShapesAlongPath(World, _path, shapes, BodyType.Dynamic, 20); //Attach the bodies together with revolute joints PathManager.AttachBodiesWithRevoluteJoint(World, bodies, new Vector2(0, 0.5f), new Vector2(0, -0.5f), true, true); xform = new Vector2(-25, 0); _path.Translate(ref xform); Body body = BodyFactory.CreateBody(World); body.BodyType = BodyType.Static; //Static shape made up of edges PathManager.ConvertPathToEdges(_path, body, 25); body.Position -= new Vector2(0, 10); xform = new Vector2(0, 15); _path.Translate(ref xform); PathManager.ConvertPathToPolygon(_path, body, 1, 50); }
public Whip(Texture2D tex, Vector2 start, Vector2 end, World world ) { this.tex = tex; this.world = world; this.start = start / 64; this.end = end / 64; Path path = new Path(); path.Add(this.start); path.Add(this.end); //A single chainlink PolygonShape shape = new PolygonShape(PolygonTools.CreateRectangle(0.125f, 0.125f),20); // ChainLink shape = new ChainLink(100); //Use PathFactory to create all the chainlinks based on the chainlink created before. chainLinks = PathManager.EvenlyDistributeShapesAlongPath(world, path, shape, BodyType.Dynamic,30); foreach (Body chainLink in chainLinks) { foreach (Fixture f in chainLink.FixtureList) { f.Friction = 0.2f; f.CollisionCategories = Category.Cat3; Category whipMask = Category.All ^ Category.Cat2; f.CollidesWith = whipMask; f.Body.BodyId = 8; f.OnCollision += new OnCollisionEventHandler(OnCollision); } } //Fix the first chainlink to the world // FixedRevoluteJoint fixedJoint = new FixedRevoluteJoint(chainLinks[0], Vector2.Zero, chainLinks[0].Position); // Game1.world.AddJoint(fixedJoint); //Attach all the chainlinks together with a revolute joint. This is the spacing between links joints = PathManager.AttachBodiesWithRevoluteJoint(world, chainLinks, new Vector2(0, -0.1f), new Vector2(0, 0.1f), false, false); //The chain is breakable for (int i = 0; i < joints.Count; i++) { RevoluteJoint r = joints[i]; r.Breakpoint = 5000f; } }
/// <summary> /// Convert a closed path into a polygon. /// Convex decomposition is automatically performed. /// </summary> /// <param name="path">The path.</param> /// <param name="body">The body.</param> /// <param name="density">The density.</param> /// <param name="subdivisions">The subdivisions.</param> public static void convertPathToPolygon( Path path, Body body, float density, int subdivisions ) { if( !path.isClosed ) throw new Exception( "The path must be closed to convert to a polygon." ); var verts = path.getVertices( subdivisions ); var decomposedVerts = Triangulate.convexPartition( new Vertices( verts ), TriangulationAlgorithm.Bayazit ); foreach( Vertices item in decomposedVerts ) { body.createFixture( new PolygonShape( item, density ) ); } }
public override void Update(GameTime gameTime) { if (Path == null) { Path = new FarseerPhysics.Common.Path(); Path.Add(position / Level.PixelPerMeter); Path.Add(new Vector2(position.X, position.Y + Length) / Level.PixelPerMeter); Path.Closed = false; float rectLength = (Length / Segments) / Level.PixelPerMeter; float rectWidth = (Width) / Level.PixelPerMeter; List <Shape> shapes = new List <Shape>(1); //shapes.Add(new PolygonShape(PolygonTools.CreateRectangle(Width/Level.PixelPerMeter, (Length/Segments)/Level.PixelPerMeter, new Vector2(0, 0), 0f), 1)); shapes.Add(new PolygonShape(PolygonTools.CreateRectangle(rectWidth, rectLength, new Vector2(rectWidth, rectLength), 0f), 1)); Bodies = PathManager.EvenlyDistributeShapesAlongPath(Level.Physics, Path, shapes, BodyType.Dynamic, Segments); if (Object1 == null) { Bodies.ElementAt(0).BodyType = BodyType.Static; } else { WeldJoint joint = JointFactory.CreateWeldJoint(Level.Physics, Object1.fixture.Body, Bodies.ElementAt(0), Vector2.Zero, Vector2.Zero); foreach (Body body in Bodies) { foreach (Fixture fix in body.FixtureList) { fix.IgnoreCollisionWith(Object1.fixture); } } } if (Object2 != null) { WeldJoint joint = JointFactory.CreateWeldJoint(Level.Physics, Object2.fixture.Body, Bodies.ElementAt(Bodies.Count - 1), Vector2.Zero, Vector2.Zero); foreach (Body body in Bodies) { foreach (Fixture fix in body.FixtureList) { fix.IgnoreCollisionWith(Object2.fixture); } } } PathManager.AttachBodiesWithRevoluteJoint(Level.Physics, Bodies, new Vector2(0, 0.25f), new Vector2(0, -0.25f), false, false); } Circle.position = position; }
//Contributed by Matthew Bettcher /// <summary> /// Convert a path into a set of edges and attaches them to the specified body. /// Note: use only for static edges. /// </summary> /// <param name="path">The path.</param> /// <param name="body">The body.</param> /// <param name="subdivisions">The subdivisions.</param> public static void ConvertPathToEdges(Path path, Body body, int subdivisions) { List<Vector2> verts = path.GetVertices(subdivisions); for (int i = 1; i < verts.Count; i++) { body.CreateFixture(new PolygonShape(PolygonTools.CreateEdge(verts[i], verts[i - 1]), 0)); } if (path.Closed) { body.CreateFixture(new PolygonShape(PolygonTools.CreateEdge(verts[verts.Count - 1], verts[0]), 0)); } }
/// <summary> /// Convert a closed path into a polygon. /// Convex decomposition is automatically performed. /// </summary> /// <param name="path">The path.</param> /// <param name="body">The body.</param> /// <param name="density">The density.</param> /// <param name="subdivisions">The subdivisions.</param> public static void ConvertPathToPolygon(Path path, Body body, float density, int subdivisions) { if (!path.Closed) throw new Exception("The path must be closed to convert to a polygon."); List<Vector2> verts = path.GetVertices(subdivisions); List<Vertices> decomposedVerts = Triangulate.ConvexPartition(new Vertices(verts), TriangulationAlgorithm.Earclip); foreach (Vertices item in decomposedVerts) { body.CreateFixture(new PolygonShape(item, density)); } }
/// <summary> /// Convert a closed path into a polygon. /// Convex decomposition is automatically performed. /// </summary> /// <param name="path">The path.</param> /// <param name="body">The body.</param> /// <param name="density">The density.</param> /// <param name="subdivisions">The subdivisions.</param> public static void ConvertPathToPolygon(Path path, Body body, float density, int subdivisions) { if (!path.Closed) throw new Exception("The path must be closed to convert to a polygon."); var verts = path.GetVertices(subdivisions); List<Vertices> decomposedVerts = EarclipDecomposer.ConvexPartition(new Vertices(verts)); //List<Vertices> decomposedVerts = BayazitDecomposer.ConvexPartition(new Vertices(verts)); foreach (Vertices item in decomposedVerts) { body.CreateFixture(new PolygonShape(item, density)); } }
//Contributed by Matthew Bettcher /// <summary> /// Convert a path into a set of edges and attaches them to the specified body. /// Note: use only for static edges. /// </summary> /// <param name="path">The path.</param> /// <param name="body">The body.</param> /// <param name="subdivisions">The subdivisions.</param> public static void convertPathToEdges( Path path, Body body, int subdivisions ) { var verts = path.getVertices( subdivisions ); if( path.isClosed ) { var chain = new ChainShape( verts, true ); body.createFixture( chain ); } else { for( int i = 1; i < verts.Count; i++ ) { body.createFixture( new EdgeShape( verts[i], verts[i - 1] ) ); } } }
//Contributed by Matthew Bettcher /// <summary> /// Convert a path into a set of edges and attaches them to the specified body. /// Note: use only for static edges. /// </summary> /// <param name="path">The path.</param> /// <param name="body">The body.</param> /// <param name="subdivisions">The subdivisions.</param> public static void ConvertPathToEdges(Path path, Body body, int subdivisions) { Vertices verts = path.GetVertices(subdivisions); if (path.Closed) { LoopShape loop = new LoopShape(verts); body.CreateFixture(loop); } else { for (int i = 1; i < verts.Count; i++) { body.CreateFixture(new EdgeShape(verts[i], verts[i - 1])); } } }
/// <summary> /// Creates a bady /// </summary> /// <param name="tex"></param> /// <param name="pos">Physcis units</param> /// <param name="pathLenght"></param> /// <param name="direction">true for an x - axis movement</param> /// <param name="rotation">angle in degrees</param> /// <param name="content"></param> public Bady(Texture2D tex, Vector2 pos, int pathLenght, bool direction, float rotation ,ContentManager content,World world) { this.tex = tex; this.pos = pos; this.world = world; Lasers = new List<Laser>(); laserTex = content.Load<Texture2D>("orangeLaser"); this.direction = direction; // create the path the AI follows if (this.direction) { path = new Path(); path.Add(pos); path.Add(new Vector2(pos.X + pathLenght, pos.Y)); path.Add(new Vector2(pos.X + pathLenght, pos.Y + 0.1f)); path.Add(new Vector2(pos.X, pos.Y + 0.1f)); path.Closed = true; } else { path = new Path(); path.Add(this.pos); path.Add(new Vector2(pos.X, pos.Y + pathLenght)); path.Add(new Vector2(pos.X - 0.1f, pos.Y + pathLenght)); path.Add(new Vector2(pos.X - 0.1f, pos.Y / 64)); path.Closed = true; } //Badybody { badyBody = BodyFactory.CreateRectangle(world, tex.Width / 64.0f, tex.Height / 64.0f, 1f, pos); badyBody.BodyType = BodyType.Dynamic; badyBody.Mass = 10f; badyBody.CollisionCategories = Category.Cat4; badyBody.CollidesWith = Category.All ^ Category.Cat2; badyBody.Rotation = AngleToRads(rotation); badyBody.FixedRotation = true; badyBody.OnCollision += new OnCollisionEventHandler(OnCollision); badyBody.BodyId = 9; } }
private ChainTest() { //Ground FixtureFactory.CreateEdge(World, new Vector2(-40.0f, 0.0f), new Vector2(40.0f, 0.0f)); //Chain start / end Path path = new Path(); path.Add(new Vector2(0, 25)); path.Add(new Vector2(40, 25)); //A single chainlink PolygonShape shape = new PolygonShape(PolygonTools.CreateRectangle(0.125f, 0.6f), 20); //Use PathFactory to create all the chainlinks based on the chainlink created before. List<Body> chainLinks = PathManager.EvenlyDistributeShapesAlongPath(World, path, shape, BodyType.Dynamic, 30); foreach (Body chainLink in chainLinks) { foreach (Fixture f in chainLink.FixtureList) { f.Friction = 0.2f; } } //Fix the first chainlink to the world FixedRevoluteJoint fixedJoint = new FixedRevoluteJoint(chainLinks[0], Vector2.Zero, chainLinks[0].Position); World.AddJoint(fixedJoint); //Attach all the chainlinks together with a revolute joint List<RevoluteJoint> joints = PathManager.AttachBodiesWithRevoluteJoint(World, chainLinks, new Vector2(0, -0.6f), new Vector2(0, 0.6f), false, false); //The chain is breakable for (int i = 0; i < joints.Count; i++) { RevoluteJoint r = joints[i]; r.Breakpoint = 10000f; } }
/// <summary> /// Creates the chain. /// </summary> /// <returns>The chain.</returns> /// <param name="world">World.</param> /// <param name="start">Start.</param> /// <param name="end">End.</param> /// <param name="linkWidth">Link width.</param> /// <param name="linkHeight">Link height.</param> /// <param name="numberOfLinks">Number of links.</param> /// <param name="linkDensity">Link density.</param> /// <param name="attachRopeJoint">Creates a rope joint between start and end. This enforces the length of the rope. Said in another way: it makes the rope less bouncy.</param> /// <param name="fixStart">If set to <c>true</c> fix start.</param> /// <param name="fixEnd">If set to <c>true</c> fix end.</param> public static List<Body> CreateChain( World world, Vector2 start, Vector2 end, float linkWidth, float linkHeight, int numberOfLinks, float linkDensity, bool attachRopeJoint, bool fixStart = false, bool fixEnd = false ) { Debug.Assert( numberOfLinks >= 2 ); // Chain start / end var path = new Path(); path.add( start ); path.add( end ); // A single chainlink var shape = new PolygonShape( PolygonTools.createRectangle( linkWidth, linkHeight ), linkDensity ); // Use PathManager to create all the chainlinks based on the chainlink created before. var chainLinks = PathManager.evenlyDistributeShapesAlongPath( world, path, shape, BodyType.Dynamic, numberOfLinks ); if( fixStart ) { // Fix the first chainlink to the world var axle = BodyFactory.CreateCircle( world, 0.1f, 1, chainLinks[0].position ); JointFactory.CreateRevoluteJoint( world, chainLinks[0], axle, new Vector2( 0, -( linkHeight / 2 ) ), Vector2.Zero ); } if( fixEnd ) { // Fix the last chainlink to the world var lastIndex = chainLinks.Count - 1; var axle = BodyFactory.CreateCircle( world, 0.1f, 1, chainLinks[lastIndex].position ); JointFactory.CreateRevoluteJoint( world, chainLinks[lastIndex], axle, new Vector2( 0, -( linkHeight / 2 ) ), Vector2.Zero ); } // Attach all the chainlinks together with a revolute joint PathManager.attachBodiesWithRevoluteJoint( world, chainLinks, new Vector2( 0, -linkHeight ), new Vector2( 0, linkHeight ), false, false ); if( attachRopeJoint ) JointFactory.CreateRopeJoint( world, chainLinks[0], chainLinks[chainLinks.Count - 1], Vector2.Zero, Vector2.Zero ); return chainLinks; }
//TODO: Comment better /// <summary> /// Moves the body on the path. /// </summary> /// <param name="path">The path.</param> /// <param name="body">The body.</param> /// <param name="time">The time.</param> /// <param name="strength">The strength.</param> /// <param name="timeStep">The time step.</param> public static void MoveBodyOnPath(Path path, Body body, float time, float strength, float timeStep) { Vector2 destination = path.GetPosition(time); Vector2 positionDelta = body.Position - destination; Vector2 velocity = (positionDelta / timeStep) * strength; body.LinearVelocity = -velocity; }
//---------------------------------------------------------------- // Methods //---------------------------------------------------------------- public override void Update( float time_step ) { if ( GameScreen.within_screen_bounds( m_self.m_position ) && !m_self.m_alien_dying && !m_self.m_is_dead && !GameScreen.m_halted ) { Path path; m_prev_src = m_source; m_source = m_self.m_body.Position; m_enemy_position = m_target.m_body.Position + m_target.m_body.LinearVelocity / 10; int x_or_y; // What happens in the current state switch ( m_state ) { case State.SPAWNING: // Randomly choose a destination m_dest = m_origin; if ( Vector2.Distance( m_source, m_dest ) > 2f ) { Vector2[] vertices0 = { m_source, m_dest }; path = new Path( vertices0 ); PathManager.MoveBodyOnPath( path, m_self.m_body, 1.0f, 0.5f, ALIEN_PATROL_SPEED, if_type2:false ); } else if ( m_self.m_body.Rotation != m_start_rotation ) rotate(); break; case State.PATROLLING: // If close to destination, randomly choose another destination if ( Vector2.Distance( m_source, m_dest ) <= .15f ) { if ( Vector2.Distance( m_source, m_origin ) <= .15f ) { x_or_y = rand.Next( 2 ); if ( x_or_y == 0 ) { int pos_or_neg = rand.Next( 2 ); if ( pos_or_neg == 0 ) m_dest = m_source + ( new Vector2( 8, 0 ) ); else if ( pos_or_neg == 1 ) m_dest = m_source + ( new Vector2( -8, 0 ) ); } else if ( x_or_y == 1 ) { int pos_or_neg = rand.Next( 2 ); if ( pos_or_neg == 0 ) m_dest = m_source + ( new Vector2( 0, 8 ) ); else if ( pos_or_neg == 1 ) m_dest = m_source + ( new Vector2( 0, -8 ) ); } } else m_dest = m_origin; } // If path is obstructed, go back to origin if ( Vector2.Distance( m_source, m_prev_src ) <= 0.1f ) { if ( Vector2.Distance( m_source, m_origin ) <= 0.1f ) { x_or_y = rand.Next( 2 ); if ( x_or_y == 0 ) { int pos_or_neg = rand.Next( 2 ); if ( pos_or_neg == 0 ) m_dest = m_source + ( new Vector2( 8, 0 ) ); else if ( pos_or_neg == 1 ) m_dest = m_source + ( new Vector2( -8, 0 ) ); } else if ( x_or_y == 1 ) { int pos_or_neg = rand.Next( 2 ); if ( pos_or_neg == 0 ) m_dest = m_source + ( new Vector2( 0, 8 ) ); else if ( pos_or_neg == 1 ) m_dest = m_source + ( new Vector2( 0, -8 ) ); } } else m_dest = m_origin; } Vector2[] vertices = { m_source, m_dest }; path = new Path( vertices ); PathManager.MoveBodyOnPath( path, m_self.m_body, 1.0f, 1.0f, ALIEN_PATROL_SPEED, if_type2: false ); break; case State.CHASING: if ( !m_target.m_is_killed && !m_target.m_is_dead ) { Vector2[] vertices2 = { m_source, m_enemy_position }; path = new Path( vertices2 ); PathManager.MoveBodyOnPath( path, m_self.m_body, 1.0f, 1.0f, m_self.m_move_step, if_type2: false ); } if ( m_self.m_attack_cooldown == 0 && m_type == AIType.PATROL ) { m_self.attack(); } break; case State.ATTACKING: if ( m_self.m_attack_cooldown == 0 && m_self.m_body.Enabled ) { if ( !( m_self is Queen ) ) { m_self.attack(); } else if ( turn_cooldown <= QUEEN_TURN_COOLDOWN / 2 ) { m_self.attack(); } } if ( m_type == AIType.BOSS && !m_target.m_is_killed && !m_target.m_is_dead ) { if ( m_self is Queen || m_self is BackHit ) { if ( turn_cooldown <= QUEEN_TURN_COOLDOWN / 2 ) { Vector2[] vertices2 = { m_source, m_enemy_position }; path = new Path( vertices2 ); PathManager.MoveBodyOnPath( path, m_self.m_body, 1.0f, 1.0f, m_self.m_move_step ); if ( m_self.m_body.LinearVelocity.Length() != 0 ) m_self.m_body.Rotation += ( (float)Math.Atan2( ( m_enemy_position.Y - m_source.Y ), ( m_enemy_position.X - m_source.X ) ) - (float)Math.PI / 2 - m_self.m_body.Rotation ) / 1.5f; } if ( increasing ) { turn_cooldown++; if ( turn_cooldown >= QUEEN_TURN_COOLDOWN ) { increasing = false; } } else { turn_cooldown--; if ( turn_cooldown <= 0 ) { increasing = true; } } } else { Vector2[] vertices2 = { m_source, m_enemy_position }; path = new Path( vertices2 ); PathManager.MoveBodyOnPath( path, m_self.m_body, 1.0f, 1.0f, m_self.m_move_step ); } } else if ( Vector2.Distance( m_source, m_dest ) > 5f && m_type == AIType.ATTACKER ) { Vector2[] vertices0 = { m_source, m_dest }; path = new Path( vertices0 ); PathManager.MoveBodyOnPath( path, m_self.m_body, 1.0f, 0.1f, m_ai_move_step, if_type2:false ); } break; case State.DEFENDING: break; case State.DYING: //Pretty much do nothing break; } //-------------------------------------------------------- // State Transition //-------------------------------------------------------- if ( m_self.m_alien_dying ) { m_state = State.DYING; } else if ( m_self.m_disabled ) { switch ( m_type ) { case AIType.PATROL: m_state = State.PATROLLING; break; case AIType.BOSS: m_state = State.PATROLLING; break; default: m_state = State.SPAWNING; break; } if (m_self.m_body.LinearVelocity.Length() != 0) m_self.m_body.Rotation += ( (float)Math.Atan2( m_self.m_body.LinearVelocity.Y, m_self.m_body.LinearVelocity.X ) - (float)Math.PI / 2 - m_self.m_body.Rotation ) / 1.5f; } else { switch ( m_state ) { case State.SPAWNING: if ( !m_target.m_is_killed && !m_target.m_is_dead ) { switch ( m_type ) { case AIType.PEON: m_state = State.SPAWNING; break; case AIType.PATROL: m_state = State.PATROLLING; break; case AIType.CHASER: if ( Vector2.Distance( m_enemy_position, m_source ) <= m_self.m_chase_dist && Vector2.Distance( m_enemy_position, m_origin ) <= m_self.m_range && !m_self.m_disabled ) m_state = State.CHASING; else m_state = State.SPAWNING; break; case AIType.ATTACKER: if ( Vector2.Distance( m_enemy_position, m_source ) <= m_self.m_attack_dist && !m_self.m_disabled ) m_state = State.ATTACKING; else m_state = State.SPAWNING; break; case AIType.BOSS: m_state = State.PATROLLING; break; } } break; case State.PATROLLING: if ( !m_target.m_is_killed && !m_target.m_is_dead && m_target.m_body != null ) { switch ( m_type ) { case AIType.PATROL: if ( Vector2.Distance( m_enemy_position, m_source ) <= m_self.m_chase_dist && Vector2.Distance( m_enemy_position, m_origin ) <= m_self.m_range && !m_self.m_disabled ) m_state = State.CHASING; else m_state = State.PATROLLING; break; case AIType.BOSS: if ( Vector2.Distance( m_enemy_position, m_source ) <= m_self.m_chase_dist && Vector2.Distance( m_enemy_position, m_origin ) <= m_self.m_range && !m_self.m_disabled ) m_state = State.CHASING; else m_state = State.PATROLLING; break; } } break; case State.CHASING: if ( !m_target.m_is_killed && !m_target.m_is_dead ) { switch ( m_type ) { case AIType.PATROL: if ( Vector2.Distance( m_enemy_position, m_source ) <= m_self.m_chase_dist && Vector2.Distance( m_enemy_position, m_origin ) <= m_self.m_range ) m_state = State.CHASING; else m_state = State.PATROLLING; break; case AIType.CHASER: if ( Vector2.Distance( m_enemy_position, m_source ) <= m_self.m_chase_dist && Vector2.Distance( m_enemy_position, m_origin ) <= m_self.m_range ) m_state = State.CHASING; else m_state = State.SPAWNING; break; case AIType.BOSS: if ( Vector2.Distance( m_enemy_position, m_source ) <= m_self.m_attack_dist && Vector2.Distance( m_enemy_position, m_origin ) <= m_self.m_range ) m_state = State.ATTACKING; else if ( Vector2.Distance( m_enemy_position, m_source ) <= m_self.m_chase_dist && Vector2.Distance( m_enemy_position, m_origin ) <= m_self.m_range ) m_state = State.CHASING; else m_state = State.PATROLLING; break; } } break; case State.ATTACKING: switch ( m_type ) { case AIType.ATTACKER: if ( Vector2.Distance( m_enemy_position, m_source ) <= m_self.m_attack_dist ) m_state = State.ATTACKING; else m_state = State.SPAWNING; break; case AIType.BOSS: if ( Vector2.Distance( m_enemy_position, m_source ) <= m_self.m_attack_dist ) m_state = State.ATTACKING; else if ( Vector2.Distance( m_enemy_position, m_source ) <= m_self.m_chase_dist && Vector2.Distance( m_enemy_position, m_origin ) <= m_self.m_range ) m_state = State.CHASING; else m_state = State.PATROLLING; break; } if ( m_self.m_body.Rotation != m_start_rotation ) rotate(); break; case State.DEFENDING: break; } if ( m_self.m_body.LinearVelocity.Length() != 0 ) m_self.m_body.Rotation += ( (float)Math.Atan2( m_self.m_body.LinearVelocity.Y, m_self.m_body.LinearVelocity.X ) - (float)Math.PI / 2 - m_self.m_body.Rotation ) / 1.5f; } } }
/// <summary> /// Duplicates the given Body along the given path for approximatly the given copies. /// </summary> /// <param name="world">The world.</param> /// <param name="path">The path.</param> /// <param name="shape">The shape.</param> /// <param name="type">The type.</param> /// <param name="copies">The copies.</param> /// <param name="userData">The user data.</param> /// <returns></returns> public static List<Body> EvenlyDistributeShapesAlongPath(World world, Path path, Shape shape, BodyType type, int copies, DebugMaterial userData) { List<Shape> shapes = new List<Shape>(1); shapes.Add(shape); return EvenlyDistributeShapesAlongPath(world, path, shapes, type, copies, userData); }
public static List<Body> EvenlyDistributeShapesAlongPath(World world, Path path, Shape shape, BodyType type, int copies) { return EvenlyDistributeShapesAlongPath(world, path, shape, type, copies, null); }
/// <summary> /// Duplicates the given Body along the given path for approximatly the given copies. /// </summary> /// <param name="world">The world.</param> /// <param name="path">The path.</param> /// <param name="shapes">The shapes.</param> /// <param name="type">The type.</param> /// <param name="copies">The copies.</param> /// <returns></returns> public static List<Body> EvenlyDistibuteShapesAlongPath(World world, Path path, IEnumerable<Shape> shapes, BodyType type, int copies, float density) { List<Vector3> centers = path.SubdivideEvenly(copies); List<Body> bodyList = new List<Body>(); Body b; for (int i = 0; i < centers.Count; i++) { b = world.CreateBody(); // copy the type from original body b.BodyType = type; b.Position = new Vector2(centers[i].X, centers[i].Y); b.Rotation = centers[i].Z; foreach (Shape shape in shapes) { b.CreateFixture(shape, density); } bodyList.Add(b); } return bodyList; }
/// <summary> /// Duplicates the given Body along the given path for approximatly the given copies. /// </summary> /// <param name="world">The world.</param> /// <param name="path">The path.</param> /// <param name="shape">The shape.</param> /// <param name="type">The type.</param> /// <param name="copies">The copies.</param> /// <param name="userData">The user data.</param> /// <returns></returns> public static List<Body> evenlyDistributeShapesAlongPath( World world, Path path, Shape shape, BodyType type, int copies, object userData ) { var shapes = new List<Shape>( 1 ); shapes.Add( shape ); return evenlyDistributeShapesAlongPath( world, path, shapes, type, copies, userData ); }
/// <summary> /// Duplicates the given Body along the given path for approximatly the given copies. /// </summary> /// <param name="world">The world.</param> /// <param name="path">The path.</param> /// <param name="shape">The shape.</param> /// <param name="type">The type.</param> /// <param name="copies">The copies.</param> /// <param name="density">The density.</param> /// <returns></returns> public static List<Body> EvenlyDistibuteShapesAlongPath(World world, Path path, Shape shape, BodyType type, int copies, float density) { List<Shape> shapes = new List<Shape>(1); shapes.Add(shape); return EvenlyDistibuteShapesAlongPath(world, path, shapes, type, copies, density); }
/// <summary> /// Moves the given body along the defined path. /// </summary> /// <param name="path">The path.</param> /// <param name="body">The body.</param> /// <param name="time">The time.</param> /// <param name="strength">The strength.</param> /// <param name="timeStep">The time step.</param> public static void moveBodyOnPath( Path path, Body body, float time, float strength, float timeStep ) { var destination = path.getPosition( time ); var positionDelta = body.position - destination; var velocity = ( positionDelta / timeStep ) * strength; body.linearVelocity = -velocity; }
protected override void SetupPhysics(World world) { #if EDITOR #else this._pathBodies = new List<Body>(); float width = ConvertUnits.ToSimUnits(this._texture.Width * 0.5f); float height = ConvertUnits.ToSimUnits(this._texture.Height * 0.5f); Vector2 startPos = ConvertUnits.ToSimUnits(this._position); Vector2 endPos = ConvertUnits.ToSimUnits(this._endPosition); Path _ropePath = new Path(); _ropePath.Add(startPos); _ropePath.Add(endPos); PolygonShape rotationPointShape = new PolygonShape(PolygonTools.CreateCircle(height, 8), 25); PolygonShape shape = new PolygonShape(PolygonTools.CreateRectangle(width, height), ConvertUnits.ToSimUnits(1.0f)); PolygonShape sensorShape = new PolygonShape(PolygonTools.CreateCircle(height * 1.5f, 6), 1.0f); List<Shape> shapes = new List<Shape>(2); shapes.Add(new PolygonShape(PolygonTools.CreateRectangle(0.5f, 0.5f, new Vector2(-0.1f, 0f), 0f), 1f)); shapes.Add(new CircleShape(0.5f, 1f)); _pathBodies = PathManager.EvenlyDistributeShapesAlongPath(world, _ropePath, shapes, BodyType.Dynamic, _chainCount); JointFactory.CreateFixedRevoluteJoint(world, _pathBodies[0], Vector2.Zero, startPos); PathManager.AttachBodiesWithRevoluteJoint(world, _pathBodies, new Vector2(0f, -0.5f), new Vector2(0f, 0.5f), false, true); for (int i = 1; i < _pathBodies.Count; i++) { _pathBodies[i].FixtureList[0].CollidesWith = Category.All & ~Category.Cat10 & ~Category.Cat12; _pathBodies[i].FixtureList[1].CollidesWith = Category.All & ~Category.Cat10 & ~Category.Cat12; Fixture fix = FixtureFactory.AttachCircle(height * 2, 0.0f, _pathBodies[i]); fix.IsSensor = true; fix.OnCollision += Body_OnCollision; fix.OnSeparation += Body_OnSeparation; } //Body prevBody = new Body(world); ; //for (int i = 0; i < _chainCount; ++i) //{ // Body body = new Body(world); // body.BodyType = BodyType.Dynamic; // body.Position = startPos + new Vector2(0, height * i); // if (i == 0) // { // Fixture fixture = body.CreateFixture(rotationPointShape); // fixture.Friction = 0.2f; // body.AngularDamping = 0.4f; // FixedRevoluteJoint fixedJoint = JointFactory.CreateFixedRevoluteJoint(world, body, Vector2.Zero, startPos); // } // else // { // Fixture fixture = body.CreateFixture(shape); // fixture.Friction = 0.2f; // Fixture sensorFix = FixtureFactory.AttachCircle(height * 2, 0.0f, body); // sensorFix.IsSensor = true; // fixture.CollidesWith = Category.All & ~Category.Cat10 & ~Category.Cat12; // RopeJoint rj = new RopeJoint(prevBody, body, new Vector2(0.0f, height), new Vector2(0.0f, -height * 0.5f)); // rj.CollideConnected = false; // world.AddJoint(rj); // body.FixtureList[1].Body.OnCollision += Body_OnCollision; // body.FixtureList[1].Body.OnSeparation += Body_OnSeparation; // } // prevBody = body; // _pathBodies.Add(body); //} #endif }
private void LoadStaticObstacles() { box = PolygonTools.CreateRectangle(1f, 10f); shape = new PolygonShape(box, 30); _bridgeBox = new Sprite(ScreenManager.Assets.TextureFromShape(shape, MaterialType.Dots, Color.SandyBrown, 1f)); Path bridgePathL = new Path(); bridgePathL.Add(new Vector2(-400, -50)); bridgePathL.Add(new Vector2(0, 0)); bridgePathL.Closed = false; _bridgeBodiesL = PathManager.EvenlyDistributeShapesAlongPath(World, bridgePathL, shape, BodyType.Dynamic, 30); //Attach the first and last fixtures to the world JointFactory.CreateFixedRevoluteJoint(World, _bridgeBodiesL[0], new Vector2(0f, -0.5f), _bridgeBodiesL[0].Position); JointFactory.CreateFixedRevoluteJoint(World, _bridgeBodiesL[_bridgeBodiesL.Count - 1], new Vector2(0, 0.5f), _bridgeBodiesL[_bridgeBodiesL.Count - 1].Position); PathManager.AttachBodiesWithRevoluteJoint(World, _bridgeBodiesL, new Vector2(0f, -0.5f), new Vector2(0f, 0.5f), false, true); Path bridgePathR = new Path(); bridgePathR.Add(new Vector2(350, -50)); bridgePathR.Add(new Vector2(0, 0)); bridgePathR.Closed = false; _bridgeBodiesR = PathManager.EvenlyDistributeShapesAlongPath(World, bridgePathR, shape, BodyType.Dynamic, 30); //Attach the first and last fixtures to the world JointFactory.CreateFixedRevoluteJoint(World, _bridgeBodiesR[0], new Vector2(0f, -0.5f), _bridgeBodiesR[0].Position); JointFactory.CreateFixedRevoluteJoint(World, _bridgeBodiesR[_bridgeBodiesR.Count - 1], new Vector2(0, 0.5f), _bridgeBodiesR[_bridgeBodiesR.Count - 1].Position); PathManager.AttachBodiesWithRevoluteJoint(World, _bridgeBodiesR, new Vector2(0f, -0.5f), new Vector2(0f, 0.5f), false, true); }
public override void Update(GameTime gameTime) { effect.Projection = GetProjectionMatrix(); effect.View = GetViewMatrix(); if (!isComplete && (MouseInput.isLeftClicked() || (points.Count > 0 && Vector2.Distance(points[points.Count - 1], MouseInput.Position) > 5))) { points.Add(MouseInput.Position); } if (MouseInput.isRightClicked()) { isComplete = false; points.Clear(); } if (KeyboardInput.isKeyPressed(Keys.Enter)) { isComplete = true; // points.Add(points[0]); Vector2[] sourceVerticies; int[] sourceIndicies; Triangulator.Triangulator.Triangulate(points.ToArray(), Triangulator.WindingOrder.Clockwise, out sourceVerticies, out sourceIndicies); verticies = new VertexPositionColorTexture[sourceVerticies.Length]; for (int index = 0; index < sourceVerticies.Length; index++) { Color mRandomColor = new Color( (Globals.Random.Next(50, 230)), (Globals.Random.Next(50, 230)), (Globals.Random.Next(50, 230))); verticies[index] = new VertexPositionColorTexture(new Vector3(sourceVerticies[index], 0f), Color.White, sourceVerticies[index] / 10); } indices = new short[sourceIndicies.Length]; for (int index = 0; index < sourceIndicies.Length; index++) { indices[index] = (short)sourceIndicies[index]; } //RepairTextureWrapSeam(verticies.ToList<VertexPositionColorTexture>(), indices.ToList<short>()); //sourceVerticies.(points[0]); //sourceVerticies.Reverse(); int numOfPoly = indices.Length / 3; for (int index = 0; index < numOfPoly; index++) { List<short> currentIndie = indices.ToList<short>().GetRange(index * 3, 3); List<Vector2> currentVerts = new List<Vector2>(); currentIndie.ForEach(i => currentVerts.Add(sourceVerticies[i])); //= sourceVerticies.ToList<Vector2>().GetRange(index * 3, 3); currentVerts.Reverse(); hull = new PolygonHull(WorldPosition, currentVerts.ToList<Vector2>()); hull.Hull.Position.Y -= Globals.ScreenHeight; //hull.Hull.Opacity = 0.5f; //hull = new BasicHull(WorldPosition,new Vector2(50, 50)); Scene.ComponentManager.GetComponent<LightingComponent>().Light.Hulls.Add(hull.Hull); //currentVerts.Reverse(); /* * List<Vector2> physicsVerts = new List<Vector2>(); currentVerts.ToList<Vector2>().ForEach(s => physicsVerts.Add(ConvertUnits.ToSimUnits(s))); Body b = BodyFactory.CreatePolygon(PhysicsComponent.World, new FarseerPhysics.Common.Vertices(physicsVerts), 1); */ List<Vector2> physicsVerts = new List<Vector2>(); currentVerts.ToList<Vector2>().ForEach(s => physicsVerts.Add(ConvertUnits.ToSimUnits(s))); Path path = new Path(physicsVerts); path.Closed = true; path.Add(physicsVerts[0]); Body body = BodyFactory.CreateBody(PhysicsComponent.World); body.BodyType = BodyType.Static; PathManager.ConvertPathToPolygon(path, body, 1.0f, currentVerts.Count); } outlineVerticies = new List<VertexPositionColor[]>(); if (points.Count > 3) { for (int i = 0; i < points.Count - 2; i++) { MakeZone(points[i], points[i + 1], points[i + 2]); } MakeZone(points[points.Count - 2], points[points.Count - 1], points[0]); MakeZone(points[points.Count - 1], points[0], points[1]); } } //if (hull != null) hull.setPosition(points[0]); base.Update(gameTime); }
public Speedwalk(World world, SpeedwalkData speedwalkData) { bodies = new List<Body>(50); speed = Math.Abs(speedwalkData.Speed); leftToRight = speedwalkData.LeftToRight; radius = speedwalkData.Radius; from = speedwalkData.From; to = speedwalkData.To; speedwalkPath = new SpeedwalkPath(from, to, radius, bodies.Capacity); for (int i = 0; i < bodies.Capacity; i++) { Body body = BodyFactory.CreateCircle(world, speedwalkPath.delta / 2, 1f); body.Position = speedwalkPath.Pts[i]; body.BodyType = BodyType.Kinematic; body.LinearVelocity = Vector2.Zero; bodies.Add(body); } path = new Path(); foreach (Vector2 pt in speedwalkPath.Pts) { path.Add(pt); } path.Closed = true; dShift = leftToRight ? -speed / 30 : speed / 30; }
private void AddCrates() { // Define a path that gives the placements of the crates var cratesPath = new Path(); cratesPath.Add(new Vector2(160, 1000)); cratesPath.Add(new Vector2(3500, 1000)); // Split the path into 30 positions - this is where the crates go var positions = cratesPath .SubdivideEvenly(30) .Select(v3 => new Vector2(v3.X, v3.Y)); foreach (var position in positions) { var crate = new Crate(this) { Position = position }; _crates.Add(crate); _allGameOjbects.Add(crate); } }