protected void _TestMove(ref float dt, Vector2 velocity, T2DCollisionImage theirImage, List<T2DCollisionInfo> list, bool theyMove) { Assert.Fatal(SceneObject is T2DTileLayer, "Not a tile layer"); T2DTileLayer tileLayer = (T2DTileLayer)SceneObject; _polyImage._sceneObject = tileLayer; T2DSceneObject theirObj = theirImage.SceneObject; Vector2 theirPos = theirObj.Position; Vector2 theirSize = theirObj.Size; Vector2 searchMin = theirPos - 0.5f * theirSize; Vector2 searchMax = searchMin + theirSize; Vector2 searchDelta = theyMove ? velocity * dt : -velocity * dt; // adjust search area by velocity if (searchDelta.X > 0.0f) searchMax.X += searchDelta.X; else searchMin.X += searchDelta.X; if (searchDelta.Y > 0.0f) searchMax.Y += searchDelta.Y; else searchMin.Y += searchDelta.Y; ReadOnlyArray<T2DTileObject> matchedTiles = tileLayer.GetCollisionMatches(searchMin, searchMax); Vector2[] savePoly = _polyImage.CollisionPolyBasis; for (int i = 0; i < matchedTiles.Count; i++) { T2DTileObject tile = matchedTiles[i]; if (!tile.TileType.CollisionsEnabled || !(tile.TileType.ObjectType & theirImage.SceneObject.Collision.CollidesWith)) continue; // Build collision poly for this tile Vector2 scenePos = tileLayer.Position; Vector2 tileSize = tileLayer.TileSize; Vector2 tilePos = tile.GetTileLocalPosition(tileLayer.MapSize, tileSize); Vector2 flip = new Vector2(tile.FlipX ? -1.0f : 1.0f, tile.FlipY ? -1.0f : 1.0f); tileSize *= flip; if (tile.TileType.CollisionPolyBasis == null) { // no custom poly so just use the tile's bounds _polyImage.CollisionPolyBasis = savePoly; // restore to original poly image poly _polyImage.CollisionPolyBasis[0] = tilePos - 0.5f * tileSize; _polyImage.CollisionPolyBasis[1] = _polyImage.CollisionPolyBasis[2] = _polyImage.CollisionPolyBasis[3] = _polyImage.CollisionPolyBasis[0]; _polyImage.CollisionPolyBasis[1].X += tileSize.X; _polyImage.CollisionPolyBasis[2] += tileSize; _polyImage.CollisionPolyBasis[3].Y += tileSize.Y; } else { // see if we need to create a new PolyVertices array for this TileType if (tile.TileType._polyVertices == null || tile.TileType._polyVertices.Length != tile.TileType.CollisionPolyBasis.Length) { tile.TileType._polyVertices = new Vector2[tile.TileType.CollisionPolyBasis.Length]; } for (int j = 0; j < tile.TileType.CollisionPolyBasis.Length; j++) tile.TileType._polyVertices[j] = 0.5f * tile.TileType.CollisionPolyBasis[j] * tileSize + tilePos; // assign our TileType's PolyVertices to the TileLayer's _polyImage array _polyImage.CollisionPolyBasis = tile.TileType._polyVertices; } if (_polyImage.Priority == theirImage.Priority) { // same priority, prefer "TestMove" version -- this ensures // we only use TestMove version of poly collision image, // saving us from implementing move against version. if (theyMove) theirImage.TestMove(ref dt, velocity, _polyImage, list); else _polyImage.TestMoveAgainst(ref dt, velocity, theirImage, list); } else if (_polyImage.Priority < theirImage.Priority) { // gotta use our image if (theyMove) _polyImage.TestMoveAgainst(ref dt, velocity, theirImage, list); else _polyImage.TestMove(ref dt, velocity, theirImage, list); } else { // gotta use their image if (theyMove) theirImage.TestMove(ref dt, velocity, _polyImage, list); else theirImage.TestMoveAgainst(ref dt, velocity, _polyImage, list); } } _polyImage.CollisionPolyBasis = savePoly; }
public override void TestMove(ref float dt, Vector2 ourVelocity, T2DCollisionImage theirImage, List<T2DCollisionInfo> list) { // entire tile layer is moving, find all potential tile collisions _TestMove(ref dt, ourVelocity, theirImage, list, false); }
public override void TestMoveAgainst(ref float dt, Vector2 theirVelocity, T2DCollisionImage theirImage, List<T2DCollisionInfo> list) { // find all potential tile collisions _TestMove(ref dt, theirVelocity, theirImage, list, true); }
public override void TestMoveAgainst(ref float dt, Vector2 theirVelocity, T2DCollisionImage theirImage, List<T2DCollisionInfo> list) { // we'll need to make sure theirCollider is of the right type here...and maybe switch based on one of a few types // We don't know how to collide with other types, so if we get here no collision...or should we assert? }
public override void TestMove(ref float dt, Vector2 ourVelocity, T2DCollisionImage theirImage, List<T2DCollisionInfo> list) { // we'll need to make sure theirCollider is of the right type here...and maybe switch based on one of a few types T2DPolyImage theirPoly = theirImage as T2DPolyImage; Assert.Fatal(theirPoly != null, "T2DPolyImage.TestMove: don't know how to test against this image type"); Vector2 pos = Vector2.Zero; float rot = 0.0f; if (SceneObject != null) { pos = SceneObject.Position; rot = SceneObject.Rotation; } Vector2 theirPos = Vector2.Zero; float theirRot = 0.0f; Vector2 theirVel = Vector2.Zero; if (theirImage.SceneObject != null) { theirPos = theirImage.SceneObject.Position; theirRot = theirImage.SceneObject.Rotation; if (theirImage.SceneObject.Physics != null && Vector2.Dot(theirPos - pos, theirImage.SceneObject.Physics.Velocity) > 0.0f) // only use their velocity if they are moving away from us (i.e., if this can prevent a collision) theirVel = theirImage.SceneObject.Physics.Velocity; } float collisionTime = 0.0f; Vector2 collisionNormal = Vector2.Zero; Vector2 collisionPoint = Vector2.Zero; Vector2 collisionPenetration = Vector2.Zero; bool collisionTest = Collision2D.IntersectMovingPolyPoly( dt, CollisionPoly, theirPoly.CollisionPoly, pos, theirPos, rot, theirRot, ourVelocity, theirVel, ref collisionPoint, ref collisionNormal, ref collisionPenetration, ref collisionTime); if (collisionTest) _AddCollisionPoint(ref dt, collisionTime, collisionPoint, collisionNormal, collisionPenetration, theirImage.SceneObject, 0, list); }
/// <summary> /// Test whether other collision image collides with this image when moving at given velocity for given amount of time. /// Collisions are added to 'list'. /// </summary> /// <param name="dt">Time spent moving, in seconds.</param> /// <param name="theirVelocity">Other image velocity.</param> /// <param name="theirImage">Collision image to test against</param> /// <param name="list">List of collision information to which current collisions will be added to.</param> public virtual void TestMoveAgainst(ref float dt, Vector2 theirVelocity, T2DCollisionImage theirImage, List<T2DCollisionInfo> list) { // we'll need to make sure theirCollider is of the right type here...and maybe switch based on one of a few types // base collider component never collides with anything }
/// <summary> /// Remove a collision image previously installed. /// </summary> /// <param name="image">Collision image to remove.</param> public void RemoveImage(T2DCollisionImage image) { _collisionImages.Remove(image); }
/// <summary> /// Install a new collision image. When moving, the object checks each collision image installed against all /// the collision images of whatever objects it moves toward. /// </summary> /// <param name="image">The collision image to add.</param> public void InstallImage(T2DCollisionImage image) { image._sceneObject = SceneObject; _collisionImages.Add(image); }