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);
 }