public static bool OnMeleeHit(Fixture a, Fixture b, Contact c) { if (b.Body.IsBullet) return true; Projectile p = (Projectile)a.UserData; // If we hit a weapon. if (b.UserData is Weapon) { Weapon w = (Weapon)b.UserData; w.TakeDamage(p.GetPower()); } // If we hit a bot if (b.UserData is Bot) { Bot bot = (Bot)b.UserData; bot.TakeDamage(p.GetPower()); } // If we hit a projectile (e.g. an axe) if (b.UserData is Projectile) { Projectile o = (Projectile)b.UserData; o.TakeDamage(p.GetPower()); } return true; }
public Weapon(SPRWorld sprWorld, Bot bot, Vector2 relativePosition, float relativeRotation, String textureName, Vector2 scale, WeaponType weaponType, float health, float power) { m_SPRWorld = sprWorld; m_Time = 0; this.m_owner = bot; this.m_firing = false; this.m_reloadTime = weaponType == WeaponType.melee ? 0 : .2f; this.m_reloading = 0; this.weaponType = weaponType; this.m_power = power; m_Position = relativePosition; m_Rotation = relativeRotation; m_Texture = TextureStatic.Get(textureName); m_Scale = scale; this.m_health = health; Vertices v = SPRWorld.computedSpritePolygons[textureName]; // Simplify the object until it has few enough verticies. while (v.Count > Physics.Settings.MaxPolygonVertices) // Infinite loop potential? { v = SimplifyTools.DouglasPeuckerSimplify(v, 2); // Where 2 is a completely arbitrary number? } v.Scale(ref scale); //v.Translate(ref relativePosition); v.Rotate(relativeRotation); Fixture f = FixtureFactory.CreatePolygon(v, 1f, bot.Body, relativePosition); m_Fixture = f; f.Friction = 0.5f; f.Restitution = 0f; f.UserData = this; if (this.weaponType == WeaponType.melee) { Body tempBody = BodyFactory.CreateBody(m_SPRWorld.World); tempBody.BodyType = BodyType.Dynamic; Vertices v2 = SPRWorld.computedSpritePolygons["Axe"]; // Simplify the object until it has few enough verticies. while (v2.Count > Physics.Settings.MaxPolygonVertices) // Infinite loop potential? { v2 = SimplifyTools.DouglasPeuckerSimplify(v2, 2); // Where 2 is a completely arbitrary number? } Fixture f2 = FixtureFactory.CreatePolygon(SPRWorld.computedSpritePolygons[textureName], 0.1f, tempBody); f2.Friction = 0.5f; f2.Restitution = 0f; tempBody.SetTransform(this.GetAbsPosition(), this.GetAbsRotation()); Projectile justFired = new Projectile(m_SPRWorld, tempBody, TextureStatic.Get("Axe"), new Vector2(0, 0), this.GetRelRotation(), 5, Settings.MetersPerPixel * 80, 80 * Settings.MetersPerPixel, m_power, m_health); f2.UserData = justFired; f2.OnCollision += Projectile.OnMeleeHit; RevoluteJoint joint = JointFactory.CreateRevoluteJoint(m_SPRWorld.World, this.m_owner.Body, tempBody, Vector2.Zero); joint.MaxMotorTorque = 160; joint.LimitEnabled = true; joint.MotorEnabled = true; joint.LowerLimit = - (float)Math.PI / 4f; joint.UpperLimit = (float)Math.PI / 4f; m_AxeJoint = joint; m_SPRWorld.AddEntity(justFired); } }
public new bool OnCollision(Fixture f1, Fixture f2, Physics.Dynamics.Contacts.Contact c) { // Check if f2 is player if (f2 == SolitudeScreen.ship.Player.PlayerFixture) { SolitudeScreen.ship.Player.oxygen -= Settings.maulerDamage; } return true; }
public bool OnCollision(Fixture f1, Fixture f2, Physics.Dynamics.Contacts.Contact c) { if (f2 == SolitudeScreen.ship.Player.PlayerFixture) { if (DateTime.Now - lastCollided >= TimeSpan.FromSeconds(1)) { lastCollided = DateTime.Now; SolitudeScreen.ship.Player.oxygen -= 50; } } return true; }
public SolitudeObject(Vector2 position, World world, Shape shape, float width, float height) { body = BodyFactory.CreateBody(world, position); //currently in wall class: fixture = new Fixture(body, shape); fixture.OnCollision += new OnCollisionEventHandler(OnCollision); //################### drawOrigin = new Vector2(width, height); drawRectangle = new Rectangle(0, 0, (int)width, (int)height); }
public bool BeforeCollision(Fixture f1, Fixture f2) { if (f2 != senderFixture) { if (f2 == SolitudeScreen.ship.Player.PlayerFixture) { SolitudeScreen.ship.Player.oxygen -= Settings.BulletDamage; } world.RemoveBody(body); SolitudeScreen.ship.contents.Remove(this); } return true; }
public bool OnCollision(Fixture f1, Fixture f2, Physics.Dynamics.Contacts.Contact c) { // Check if f2 is player if (f2 == SolitudeScreen.ship.Player.PlayerFixture && type != WallType.Smooth) { if (type == WallType.HandHold) //grab on to wall { SolitudeScreen.ship.Player.body.LinearVelocity = Vector2.Zero; SolitudeScreen.ship.Player.body.AngularVelocity = 0f; SolitudeScreen.ship.Player.onWall = true; SolitudeScreen.ship.Player.standingOn = (Wall)this; } else if (SolitudeScreen.ship.Player.hasGloves && type == WallType.Grip) // grab if player has gloves { SolitudeScreen.ship.Player.body.LinearVelocity = Vector2.Zero; SolitudeScreen.ship.Player.body.AngularVelocity = 0f; SolitudeScreen.ship.Player.onWall = true; SolitudeScreen.ship.Player.standingOn = this; } else if (SolitudeScreen.ship.Player.hasBoots && type == WallType.Metal) // grab if player has boots { SolitudeScreen.ship.Player.body.LinearVelocity = Vector2.Zero; SolitudeScreen.ship.Player.body.AngularVelocity = 0f; SolitudeScreen.ship.Player.onWall = true; SolitudeScreen.ship.Player.standingOn = this; } else //otherwise { switch (type) //switch because player info is irrelevant { case WallType.Cold: break; case WallType.Hot: break; case WallType.Spike: break; } } } // Check if f2 is other item (ie block) return true; }
public Bullet(Vector2 velocity, Vector2 position, World w, Color color, Fixture sender) : base(position, w, 15f, 15f) { senderFixture = sender; world = w; BulletColor = color; body.BodyType = BodyType.Dynamic; body.IsBullet = true; body.LinearVelocity = velocity; body.Position = position; texture = TextureStatic.Get("bullet"); fixture = FixtureFactory.CreateCircle(7f, 1, body); body.Mass = 0; fixture.Body.UserData = "bullet"; body.Inertia = 0; body.Torque = 0; fixture.CollisionFilter.IgnoreCollisionWith(senderFixture); fixture.BeforeCollision += new BeforeCollisionEventHandler(BeforeCollision); fixture.OnCollision += new OnCollisionEventHandler(OnCollision); w.AddBody(body); }
public static bool OnBulletHit(Fixture a, Fixture b, Contact c) { // Fixture a is always the bullet, and Fixture b is what it hit. if (b.UserData is String && ((string)(b.UserData.ToString())).Equals("Wall")) { if (!m_toRemove.Contains(a.Body)) m_toRemove.Add(a.Body); return true; } if (b.Body.IsBullet) return true; // If we've gotten this far, b.UserData is an Object Projectile p = (Projectile)a.UserData; // If we hit a weapon. if (b.UserData is Weapon) { Weapon w = (Weapon)b.UserData; w.TakeDamage(p.GetPower()); } // If we hit a bot if (b.UserData is Bot) { Bot bot = (Bot)b.UserData; bot.TakeDamage(p.GetPower()); } // If we hit a projectile (e.g. an axe) if (b.UserData is Projectile) { Projectile o = (Projectile)b.UserData; o.TakeDamage(p.GetPower()); } if (!m_toRemove.Contains(a.Body)) m_toRemove.Add(a.Body); return true; }
public Wall(Vector2 position, World world, float width, float height, float density, WallType t, Direction d) : base(position, world, width, height) { body.Rotation = 0; if (d == Direction.Up || d == Direction.Down) // Up or down { body.Rotation = (float)Math.PI / 2; } body.BodyType = BodyType.Static; //world.AddBody(body); fixture = FixtureFactory.CreateRectangle(width, height, density, Vector2.Zero, body, null); fixture.OnCollision += new OnCollisionEventHandler(OnCollision); type = t; this.width = width; this.height = height; drawRectangle = new Rectangle(0, 0, (int)width, (int)height); switch (type){ case WallType.Smooth: textureString = /*TextureStatic.Get(*/"solitudeWallSmooth"; break; case WallType.HandHold: textureString = /*TextureStatic.Get(*/"solitudeWallHandHold"; break; case WallType.Grip: textureString = /*TextureStatic.Get(*/"solitudeWallGrip"; break; case WallType.Metal: textureString = /*TextureStatic.Get(*/"solitudeWallMetal"; break; case WallType.Hot: textureString = /*TextureStatic.Get(*/"solitudeWallHot"; break; case WallType.Cold: textureString = /*TextureStatic.Get(*/"solitudeWallCold"; break; case WallType.Spike: textureString = /*TextureStatic.Get(*/"solitudeWallSpike"; break; } }
// Broad-phase callback. private void AddPair(ref FixtureProxy proxyA, ref FixtureProxy proxyB) { Fixture fixtureA = proxyA.Fixture; Fixture fixtureB = proxyB.Fixture; int indexA = proxyA.ChildIndex; int indexB = proxyB.ChildIndex; Body bodyA = fixtureA.Body; Body bodyB = fixtureB.Body; // Are the fixtures on the same body? if (bodyA == bodyB) { return; } // Does a contact already exist? ContactEdge edge = bodyB.ContactList; while (edge != null) { if (edge.Other == bodyA) { Fixture fA = edge.Contact.FixtureA; Fixture fB = edge.Contact.FixtureB; int iA = edge.Contact.ChildIndexA; int iB = edge.Contact.ChildIndexB; if (fA == fixtureA && fB == fixtureB && iA == indexA && iB == indexB) { // A contact already exists. return; } if (fA == fixtureB && fB == fixtureA && iA == indexB && iB == indexA) { // A contact already exists. return; } } edge = edge.Next; } // Does a joint override collision? Is at least one body dynamic? if (bodyB.ShouldCollide(bodyA) == false) { return; } //Check default filter if (ShouldCollide(fixtureA, fixtureB) == false) { return; } // Check user filtering. if (ContactFilter != null && ContactFilter(fixtureA, fixtureB) == false) { return; } if (fixtureA.BeforeCollision != null && fixtureA.BeforeCollision(fixtureA, fixtureB) == false) { return; } if (fixtureB.BeforeCollision != null && fixtureB.BeforeCollision(fixtureB, fixtureA) == false) { return; } // Call the factory. Contact c = Contact.Create(fixtureA, indexA, fixtureB, indexB); // Contact creation may swap fixtures. fixtureA = c.FixtureA; fixtureB = c.FixtureB; indexA = c.ChildIndexA; indexB = c.ChildIndexB; bodyA = fixtureA.Body; bodyB = fixtureB.Body; // Insert into the world. c.Prev = null; c.Next = ContactList; if (ContactList != null) { ContactList.Prev = c; } ContactList = c; // Connect to island graph. // Connect to body A c.NodeA.Contact = c; c.NodeA.Other = bodyB; c.NodeA.Prev = null; c.NodeA.Next = bodyA.ContactList; if (bodyA.ContactList != null) { bodyA.ContactList.Prev = c.NodeA; } bodyA.ContactList = c.NodeA; // Connect to body B c.NodeB.Contact = c; c.NodeB.Other = bodyA; c.NodeB.Prev = null; c.NodeB.Next = bodyB.ContactList; if (bodyB.ContactList != null) { bodyB.ContactList.Prev = c.NodeB; } bodyB.ContactList = c.NodeB; ++ContactCount; }
/// <summary> /// Destroy a fixture. This removes the fixture from the broad-phase and /// destroys all contacts associated with this fixture. This will /// automatically adjust the mass of the body if the body is dynamic and the /// fixture has positive density. /// All fixtures attached to a body are implicitly destroyed when the body is destroyed. /// Warning: This function is locked during callbacks. /// </summary> /// <param name="fixture">The fixture to be removed.</param> public void DestroyFixture(Fixture fixture) { Debug.Assert(fixture.Body == this); // Remove the fixture from this body's singly linked list. Debug.Assert(FixtureList.Count > 0); #if DEBUG // You tried to remove a fixture that not present in the fixturelist. Debug.Assert(FixtureList.Contains(fixture)); #endif // Destroy any contacts associated with the fixture. ContactEdge edge = ContactList; while (edge != null) { Contact c = edge.Contact; edge = edge.Next; Fixture fixtureA = c.FixtureA; Fixture fixtureB = c.FixtureB; if (fixture == fixtureA || fixture == fixtureB) { // This destroys the contact and removes it from // this body's contact list. World.ContactManager.Destroy(c); } } if ((Flags & BodyFlags.Enabled) == BodyFlags.Enabled) { BroadPhase broadPhase = World.ContactManager.BroadPhase; fixture.DestroyProxies(broadPhase); } FixtureList.Remove(fixture); fixture.Destroy(); fixture.Body = null; ResetMassData(); }
public Player(Vector2 position, World world) : base(position, world, (float)Player.width, (float)Player.height) { body.BodyType = BodyType.Dynamic; PlayerFixture = FixtureFactory.CreateEllipse(width / 2, height / 2, 32, .2f, body); //PlayerFixture = FixtureFactory.CreateRectangle(width, height, .05f, Vector2.Zero, body, null); PlayerFixture.Restitution = .8f; texture = TextureStatic.Get("solitudePlayer"); enterPosition = new Vector2(900, 830); Reset(); hpBar = new HealthBar(oxygen, oxygenCap); fBar = new FuelBar(fuel, fuelCap); //lCnt = new LivesCount(); }
/// <summary> /// Restores collisions between this fixture and the provided fixture. /// </summary> /// <param name="fixture">The fixture.</param> public void RestoreCollisionWith(Fixture fixture) { if (_collisionIgnores.ContainsKey(fixture.FixtureId)) { _collisionIgnores[fixture.FixtureId] = false; FilterChanged(); } }
/// <summary> /// Determines whether collisions are ignored between this fixture and the provided fixture. /// </summary> /// <param name="fixture">The fixture.</param> /// <returns> /// <c>true</c> if the fixture is ignored; otherwise, <c>false</c>. /// </returns> public bool IsFixtureIgnored(Fixture fixture) { if (_collisionIgnores.ContainsKey(fixture.FixtureId)) return _collisionIgnores[fixture.FixtureId]; return false; }
//Cutting a shape into two is based on the work of Daid and his prototype BoxCutter: http://www.box2d.org/forum/viewtopic.php?f=3&t=1473 /// <summary> /// Split a fixture into 2 vertice collections using the given entry and exit-point. /// </summary> /// <param name="fixture">The Fixture to split</param> /// <param name="entryPoint">The entry point - The start point</param> /// <param name="exitPoint">The exit point - The end point</param> /// <param name="splitSize">The size of the split. Think of this as the laser-width</param> /// <param name="first">The first collection of vertexes</param> /// <param name="second">The second collection of vertexes</param> public static void SplitShape(Fixture fixture, Vector2 entryPoint, Vector2 exitPoint, float splitSize, out Vertices first, out Vertices second) { Vector2 localEntryPoint = fixture.Body.GetLocalPoint(ref entryPoint); Vector2 localExitPoint = fixture.Body.GetLocalPoint(ref exitPoint); PolygonShape shape = fixture.Shape as PolygonShape; if (shape == null) { first = new Vertices(); second = new Vertices(); return; } Vertices vertices = new Vertices(shape.Vertices); Vertices[] newPolygon = new Vertices[2]; for (int i = 0; i < newPolygon.Length; i++) { newPolygon[i] = new Vertices(vertices.Count); } int[] cutAdded = { -1, -1 }; int last = -1; for (int i = 0; i < vertices.Count; i++) { int n; //Find out if this vertex is on the old or new shape. if (Vector2.Dot(MathUtils.Cross(localExitPoint - localEntryPoint, 1), vertices[i] - localEntryPoint) > Settings.Epsilon) n = 0; else n = 1; if (last != n) { //If we switch from one shape to the other add the cut vertices. if (last == 0) { Debug.Assert(cutAdded[0] == -1); cutAdded[0] = newPolygon[last].Count; newPolygon[last].Add(localExitPoint); newPolygon[last].Add(localEntryPoint); } if (last == 1) { Debug.Assert(cutAdded[last] == -1); cutAdded[last] = newPolygon[last].Count; newPolygon[last].Add(localEntryPoint); newPolygon[last].Add(localExitPoint); } } newPolygon[n].Add(vertices[i]); last = n; } //Add the cut in case it has not been added yet. if (cutAdded[0] == -1) { cutAdded[0] = newPolygon[0].Count; newPolygon[0].Add(localExitPoint); newPolygon[0].Add(localEntryPoint); } if (cutAdded[1] == -1) { cutAdded[1] = newPolygon[1].Count; newPolygon[1].Add(localEntryPoint); newPolygon[1].Add(localExitPoint); } for (int n = 0; n < 2; n++) { Vector2 offset; if (cutAdded[n] > 0) { offset = (newPolygon[n][cutAdded[n] - 1] - newPolygon[n][cutAdded[n]]); } else { offset = (newPolygon[n][newPolygon[n].Count - 1] - newPolygon[n][0]); } offset.Normalize(); newPolygon[n][cutAdded[n]] += splitSize * offset; if (cutAdded[n] < newPolygon[n].Count - 2) { offset = (newPolygon[n][cutAdded[n] + 2] - newPolygon[n][cutAdded[n] + 1]); } else { offset = (newPolygon[n][0] - newPolygon[n][newPolygon[n].Count - 1]); } offset.Normalize(); newPolygon[n][cutAdded[n] + 1] += splitSize * offset; } first = newPolygon[0]; second = newPolygon[1]; }
internal void Collide() { // Update awake contacts. Contact c = ContactList; while (c != null) { Fixture fixtureA = c.FixtureA; Fixture fixtureB = c.FixtureB; int indexA = c.ChildIndexA; int indexB = c.ChildIndexB; Body bodyA = fixtureA.Body; Body bodyB = fixtureB.Body; if (bodyA.Awake == false && bodyB.Awake == false) { c = c.Next; continue; } // Is this contact flagged for filtering? if ((c.Flags & ContactFlags.Filter) == ContactFlags.Filter) { // Should these bodies collide? if (bodyB.ShouldCollide(bodyA) == false) { Contact cNuke = c; c = cNuke.Next; Destroy(cNuke); continue; } // Check default filtering if (ShouldCollide(fixtureA, fixtureB) == false) { Contact cNuke = c; c = cNuke.Next; Destroy(cNuke); continue; } // Check user filtering. if (ContactFilter != null && ContactFilter(fixtureA, fixtureB) == false) { Contact cNuke = c; c = cNuke.Next; Destroy(cNuke); continue; } // Clear the filtering flag. c.Flags &= ~ContactFlags.Filter; } int proxyIdA = fixtureA.Proxies[indexA].ProxyId; int proxyIdB = fixtureB.Proxies[indexB].ProxyId; bool overlap = BroadPhase.TestOverlap(proxyIdA, proxyIdB); // Here we destroy contacts that cease to overlap in the broad-phase. if (overlap == false) { Contact cNuke = c; c = cNuke.Next; Destroy(cNuke); continue; } // The contact persists. c.Update(this); c = c.Next; } }
public void OnSeparation(Fixture f1, Fixture f2) { IsColliding = false; }
public bool OnCollision(Fixture f1, Fixture f2, Contact c) { return true; }
private float RayCastCallback(Fixture f, Vector2 point1, Vector2 point2, float fl) { if (f != SolitudeScreen.ship.Player.PlayerFixture && f.Body.UserData as string != "bullet") { fixtureInTheWay = f; CanSeePlayer = false; return 0; } return 1; }
private static bool ShouldCollide(Fixture fixtureA, Fixture fixtureB) { if (Settings.UseFPECollisionCategories) { if ((fixtureA.CollisionFilter.CollisionGroup == fixtureB.CollisionFilter.CollisionGroup) && fixtureA.CollisionFilter.CollisionGroup != 0 && fixtureB.CollisionFilter.CollisionGroup != 0) return false; if (((fixtureA.CollisionFilter.CollisionCategories & fixtureB.CollisionFilter.CollidesWith) == Category.None) & ((fixtureB.CollisionFilter.CollisionCategories & fixtureA.CollisionFilter.CollidesWith) == Category.None)) return false; if (fixtureA.CollisionFilter.IsFixtureIgnored(fixtureB) || fixtureB.CollisionFilter.IsFixtureIgnored(fixtureA)) return false; return true; } if (fixtureA.CollisionFilter.CollisionGroup == fixtureB.CollisionFilter.CollisionGroup && fixtureA.CollisionFilter.CollisionGroup != 0) { return fixtureA.CollisionFilter.CollisionGroup > 0; } bool collide = (fixtureA.CollisionFilter.CollidesWith & fixtureB.CollisionFilter.CollisionCategories) != 0 && (fixtureA.CollisionFilter.CollisionCategories & fixtureB.CollisionFilter.CollidesWith) != 0; if (collide) { if (fixtureA.CollisionFilter.IsFixtureIgnored(fixtureB) || fixtureB.CollisionFilter.IsFixtureIgnored(fixtureA)) { return false; } } return collide; }
public new bool OnCollision(Fixture f1, Fixture f2, Physics.Dynamics.Contacts.Contact c) { if (f2 != senderFixture) { if (f2 == SolitudeScreen.ship.Player.PlayerFixture) { SolitudeScreen.ship.Player.oxygen -= Settings.BulletDamage; } world.RemoveBody(body); SolitudeScreen.ship.contents.Remove(this); } return true; }
public bool MyOnCollision(Fixture f1, Fixture f2, Contact c) { //f2.Body.Dispose(); return true; }
/// <summary> /// Ignores collisions between this fixture and the provided fixture. /// </summary> /// <param name="fixture">The fixture.</param> public void IgnoreCollisionWith(Fixture fixture) { if (_collisionIgnores.ContainsKey(fixture.FixtureId)) _collisionIgnores[fixture.FixtureId] = true; else _collisionIgnores.Add(fixture.FixtureId, true); FilterChanged(); }
public override bool OnCollision(Fixture f1, Fixture f2, Physics.Dynamics.Contacts.Contact c) { f2.Body.AngularVelocity = 0f; f2.Body.LinearVelocity = Vector2.Zero; if (f2 == SolitudeScreen.ship.Player.PlayerFixture) { IsColliding = true; SolitudeScreen.ship.Player.onWall = true; } return true; }
public CollisionFilter(Fixture fixture) { _fixture = fixture; if (Settings.UseFPECollisionCategories) _collisionCategories = Category.All; else _collisionCategories = Category.Cat1; _collidesWith = Category.All; _collisionGroup = 0; }
public virtual bool OnCollision(Fixture f1, Fixture f2, Physics.Dynamics.Contacts.Contact c) { f2.Body.AngularVelocity = 0f; f2.Body.LinearVelocity = Vector2.Zero; return true; }
internal void Destroy(Contact contact) { Fixture fixtureA = contact.FixtureA; Fixture fixtureB = contact.FixtureB; Body bodyA = fixtureA.Body; Body bodyB = fixtureB.Body; if (EndContact != null && contact.IsTouching()) { EndContact(contact); } // Remove from the world. if (contact.Prev != null) { contact.Prev.Next = contact.Next; } if (contact.Next != null) { contact.Next.Prev = contact.Prev; } if (contact == ContactList) { ContactList = contact.Next; } // Remove from body 1 if (contact.NodeA.Prev != null) { contact.NodeA.Prev.Next = contact.NodeA.Next; } if (contact.NodeA.Next != null) { contact.NodeA.Next.Prev = contact.NodeA.Prev; } if (contact.NodeA == bodyA.ContactList) { bodyA.ContactList = contact.NodeA.Next; } // Remove from body 2 if (contact.NodeB.Prev != null) { contact.NodeB.Prev.Next = contact.NodeB.Next; } if (contact.NodeB.Next != null) { contact.NodeB.Next.Prev = contact.NodeB.Prev; } if (contact.NodeB == bodyB.ContactList) { bodyB.ContactList = contact.NodeB.Next; } contact.Destroy(); --ContactCount; }