protected static bool handleEnemyMovement(Collider mover, Collider other, Vector2 deltaPosition, out Vector2 allowedMovement)
 {
     switch (other.m_type)
     {
         case ColliderType.Samus:
             allowedMovement = deltaPosition;
             ((EnemyController)mover.m_owner).handleSamusHit((PlayerController)other.m_owner);
             return true;
         case ColliderType.Projectile:
             allowedMovement = deltaPosition;
             ((EnemyController)mover.m_owner).handleProjectileHit((ProjectileController)other.m_owner);
             return true;
         case ColliderType.Enemy:
         case ColliderType.FrozenEnemy:
         case ColliderType.InvincibleEnemy:
             allowedMovement = deltaPosition;
             return true;
         case ColliderType.Scenery:
             allowedMovement = scaleBackVelocity(mover, other, deltaPosition);
             return true;
         case ColliderType.Effect:
             allowedMovement = deltaPosition;
             return true;
         case ColliderType.Trigger:
             allowedMovement = deltaPosition;
             return true;
         case ColliderType.Transition:
             allowedMovement = scaleBackVelocity(mover, other, deltaPosition);
             return true;
         default:
             throw new Exception("Enemy moved into something it shouldn't have");
     }
 }
        private Color m_tint; // a tint to put on the decoration

        #endregion Fields

        #region Constructors

        /// <summary>
        /// Create a new decoration
        /// </summary>
        /// <param name="decorationSetTexture">Texture containing this decoration's graphic</param>
        /// <param name="indexNumber">An index into the texture, which finds this decoration's location in it</param>
        /// <param name="drawPos">Where in the area the decoration should be drawn</param>
        /// <param name="di">XML information about properties of the Decoration (load from Content)</param>
        /// <param name="tint">Color tint to apply to the graphic</param>
        public Decoration(GameTexture decorationSetTexture, int indexNumber, Vector2 drawPos, DecorationInfo di, Color tint)
        {
            this.m_texture = decorationSetTexture;
            this.m_drawIndex = indexNumber;
            this.m_drawPosition = drawPos;

            Rectangle bounds = new Rectangle(
                di.collision.X - di.graphic.X + (int)drawPos.X,
                di.collision.Y - di.graphic.Y + (int)drawPos.Y,
                di.collision.Width,
                di.collision.Height);
            this.m_collider = new Collider(this, bounds, ColliderType.Scenery);

            this.m_tint = tint;
        }
        public ProjectileController(IGameObject owner, Vector2 position, Vector2 velocity, ProjectileType type, int damage, String texturePath)
        {
            Rectangle bounds = new Rectangle((int)position.X - 1, (int)position.Y - 1, 3, 3);
            m_collider = new Collider(this, bounds, ColliderType.Projectile);

            Owner = owner;
            Velocity = velocity;
            Damage = damage;
            Tint = Color.White;
            Freezes = false;

            m_position = position;
            m_type = type;

            m_texture = new GameTexture(texturePath);
        }
        public ARefillController(Vector2 position, string refillType)
        {
            this.IsActive = true;

            m_position = position;
            m_refillType = refillType;

            m_refillArea = new Rectangle(s_refillArea.X, s_refillArea.Y, s_refillArea.Width, s_refillArea.Height);
            m_refillArea.Offset((int)m_position.X, (int)m_position.Y);

            Rectangle bounds = new Rectangle(-40, -120, 80, 120);
            m_collider = new Collider(this, bounds, ColliderType.Scenery);

            m_animationController =
                new AnimationController(
                    "Animation/Data/MissionObjects",
                    "Animation/Textures/MissionObjects",
                    AnimationName);
        }
 /// <summary>
 /// Determines how to handle various types of collisions.
 /// </summary>
 /// <param name="mover">Collider that is moving</param>
 /// <param name="other">Collider which was moved into</param>
 /// <param name="deltaPosition">Attempted movement by the mover</param>
 /// <param name="allowedMovement">Out param - amount of movement which is allowed</param>
 /// <returns>True if any movement is allowed, false otherwise</returns>
 public static bool handleMovement(Collider mover, Collider other, Vector2 deltaPosition, out Vector2 allowedMovement)
 {
     switch (mover.m_type)
     {
         case ColliderType.Samus:
             return handleSamusMovement(mover, other, deltaPosition, out allowedMovement);
         case ColliderType.Enemy:
         case ColliderType.FrozenEnemy:
         case ColliderType.InvincibleEnemy:
             return handleEnemyMovement(mover, other, deltaPosition, out allowedMovement);
         case ColliderType.Projectile:
             return handleProjectileMovement(mover, other, deltaPosition, out allowedMovement);
         case ColliderType.Effect:
             allowedMovement = deltaPosition;
             return true;
         //case ColliderType.Movable:
         //    break;
         default:
             throw new Exception("Something's moving that shouldn't be");
     }
     return false;
 }
        public ChozoStatue(Vector2 position, Item item, Direction facing)
        {
            if (facing != Direction.Left && facing != Direction.Right)
            {
                facing = Direction.Right;
            }

            m_position = position;
            m_item = item;
            m_facing = facing;
            m_statueAnimation = new AnimationController(
                "Animation/Data/MissionObjects",
                "Animation/Textures/MissionObjects",
                StatueAnimation);
            m_itemAnimation = new AnimationController(
                "Animation/Data/MissionObjects",
                "Animation/Textures/MissionObjects",
                ItemAnimation);

            Rectangle bounds;
            if (m_facing == Direction.Left)
            {
                bounds = new Rectangle(
                    (int)m_position.X - 60,
                    (int)m_position.Y - 120,
                    40,
                    40);
            }
            else
            {
                bounds = new Rectangle(
                    (int)m_position.X + 20,
                    (int)m_position.Y - 120,
                    40,
                    40);
            }
            m_collider = new Collider(this, bounds, ColliderType.Scenery);
        }
        /// <summary>
        /// Protected ctor - use the construct() method
        /// </summary>
        protected CharacterController(
            Vector2 startPosition,
            int speed,
            Rectangle bounds,
            ColliderType type,
            float animationScale,
            string animationDataPath,
            string animationTexturePath)
        {
            this.m_previousPosition = startPosition;
            this.m_position = startPosition;
            this.m_speedMax = speed;

            bounds.Offset((int)m_position.X, (int)m_position.Y);
            this.m_collider = new Collider(this, bounds, type);

            this.AnimationController = new AnimationController(animationDataPath, animationTexturePath);
            this.AnimationController.ActionTriggered += new ActionTriggeredEventHandler(this.handleAction);
            this.AnimationController.Scale = animationScale;

            this.GravityEffect = Gravity.Normal;
            this.Health = this.MaxHealth;
            this.m_previousAngle = (float)Math.PI / 2;
        }
        public void handleImpact(Collider mover)
        {
            PlayerController samus = mover.m_owner as PlayerController;
            if (samus == null) return;

            samus.Inventory.AddItem(m_item);

            m_state = State.ItemTaken;
            m_collider.m_type = ColliderType.Effect;
        }
 /// <summary>
 /// Removes a particular collider from this CollisionDetector
 /// </summary>
 /// <param name="ci">Collider to remove</param>
 public void remove(Collider ci)
 {
     m_tree.Remove(ci);
     ci.forCollisionDetectorUseOnly(null);
 }
 /// <summary>
 /// Adds a collider to the detector and marks that collider as being
 /// owned by this detector
 /// </summary>
 /// <param name="ci">Collider to register</param>
 public void register(Collider ci)
 {
     ci.forCollisionDetectorUseOnly(this);
     m_tree.Insert(ci);
 }
        /// <summary>
        /// Moves a collider in the direction provided until it hits something
        /// </summary>
        /// <param name="mover">Collider which is moving</param>
        /// <param name="deltaPosition">Change in position the collider is trying to make</param>
        public void handleMovement(Collider mover, Vector2 deltaPosition)
        {
            double areaOfMovementX1 = Math.Min(mover.Bounds.X, mover.Bounds.X + deltaPosition.X);
            double areaOfMovementY1 = Math.Min(mover.Bounds.Y, mover.Bounds.Y + deltaPosition.Y);
            double areaOfMovementX2 = Math.Max(mover.Bounds.X + mover.Bounds.Width, mover.Bounds.X + mover.Bounds.Width + deltaPosition.X);
            double areaOfMovementY2 = Math.Max(mover.Bounds.Y + mover.Bounds.Height, mover.Bounds.Y + mover.Bounds.Height + deltaPosition.Y);

            DoubleRect areaOfMovement = new DoubleRect(
                areaOfMovementX1,
                areaOfMovementY1,
                areaOfMovementX2 - areaOfMovementX1,
                areaOfMovementY2 - areaOfMovementY1);

            //DoubleRect newbounds = mover.Bounds + deltaPosition;

            List<Collider> collisions = m_tree.Query(areaOfMovement);
            List<Collider>.Enumerator i = collisions.GetEnumerator();
            Vector2 allowedMovement = deltaPosition;
            Vector2 temp;
            while (i.MoveNext())
            {
                // we will usually collide with our old position - ignore that case
                if (i.Current != mover)
                {
                    bool canMove = CollisionHandler.handleMovement(mover, i.Current, deltaPosition, out temp);
                    if (!canMove)
                    {
                        return; // don't allow movement
                    }
                    if (allowedMovement.X > 0.0f)
                        allowedMovement.X = Math.Min(allowedMovement.X, temp.X);
                    else if (allowedMovement.X < 0.0f)
                        allowedMovement.X = Math.Max(allowedMovement.X, temp.X);
                    if (allowedMovement.Y > 0.0f)
                        allowedMovement.Y = Math.Min(allowedMovement.Y, temp.Y);
                    else if (allowedMovement.Y < 0.0f)
                        allowedMovement.Y = Math.Max(allowedMovement.Y, temp.Y);
                }
            }

            mover.move(allowedMovement);
        }
 public abstract void handleImpact(Collider mover);
 public ATrigger(Rectangle bounds)
 {
     m_collider = new Collider(this, bounds, ColliderType.Trigger);
     m_position = new Vector2(m_collider.Bounds.Center().X, m_collider.Bounds.Center().Y);
 }
Example #14
0
        /// <summary>
        /// Certain tile #s in a TileSet may be marked as impassable.  This function looks up those
        /// numbers and makes instances of those tiles in the Zone impassable by registering the
        /// appropriate collision box.
        /// </summary>
        public void initializeTileColliders()
        {
            foreach (Point globalScreenCoord in PositionsOwned)
            {
                Point zoneScreenCoord = getLocalScreenFromGlobalScreen(globalScreenCoord);

                for (int i = 0; i < SCREEN_WIDTH_IN_TILES; ++i)
                {
                    for (int j = 0; j < SCREEN_HEIGHT_IN_TILES; ++j)
                    {
                        if (!TileSet.tileInfos[Tiles[globalScreenCoord][i, j]].passable &&
                            !FakeTiles.Contains(new KeyValuePair<Point,Point>(globalScreenCoord, new Point(i,j))))
                        {
                            Rectangle bounds = getTileRectangle(zoneScreenCoord, i, j);
                            Collider ci = new Collider(null, bounds, ColliderType.Scenery);
                            CollisionDetector.register(ci);
                        }
                        else if (i == 0 && !this.PositionsOwned.Contains(new Point (globalScreenCoord.X-1, globalScreenCoord.Y)))
                        {
                            Rectangle bounds = getTileRectangle(zoneScreenCoord, i-1, j);
                            Collider ci = new Collider(null, bounds, ColliderType.Scenery);
                            CollisionDetector.register(ci);
                        }
                        else if (i == SCREEN_WIDTH_IN_TILES-1 && !this.PositionsOwned.Contains(new Point (globalScreenCoord.X+1, globalScreenCoord.Y)))
                        {
                            Rectangle bounds = getTileRectangle(zoneScreenCoord, i+1, j);
                            Collider ci = new Collider(null, bounds, ColliderType.Scenery);
                            CollisionDetector.register(ci);
                        }
                        else if (j == 0 && !this.PositionsOwned.Contains(new Point (globalScreenCoord.X, globalScreenCoord.Y-1)))
                        {
                            Rectangle bounds = getTileRectangle(zoneScreenCoord, i, j-1);
                            Collider ci = new Collider(null, bounds, ColliderType.Scenery);
                            CollisionDetector.register(ci);
                        }
                        else if (j == SCREEN_HEIGHT_IN_TILES-1 && !this.PositionsOwned.Contains(new Point (globalScreenCoord.X, globalScreenCoord.Y+1)))
                        {
                            Rectangle bounds = getTileRectangle(zoneScreenCoord, i, j+1);
                            Collider ci = new Collider(null, bounds, ColliderType.Scenery);
                            CollisionDetector.register(ci);
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Scales back an attempted movement so that two colliders don't intersect.
        /// </summary>
        /// <param name="mover">Collider that is moving</param>
        /// <param name="other">Collider that the movement shouldn't be able to move into</param>
        /// <param name="deltaPosition">Amount that mover is trying to move</param>
        /// <returns>How much mover can move so as not to intersect other</returns>
        protected static Vector2 scaleBackVelocity(Collider mover, Collider other, Vector2 deltaPosition)
        {
            // whew! a lot work just to make it so that you can slide along objects when
            //  using multiple directions

            const float EPS = 0.01f;

            DoubleRect dr2 = other.Bounds;

            double reducedX = deltaPosition.X;
            double reducedY = deltaPosition.Y;

            // Project x only movement and fix x velocity
            Vector2 temp = new Vector2(deltaPosition.X, 0);
            DoubleRect dr1 = mover.Bounds + temp;
            if (dr1.IntersectsWith(dr2))
            if (deltaPosition.X > 0 && dr1.X + dr1.Width >= dr2.X) // moving right, rhs collision
            {
                double overlap = dr1.X + dr1.Width - dr2.X + EPS;
                reducedX = Math.Max(0.0f, deltaPosition.X - overlap);
            }
            else if (deltaPosition.X < 0 && dr1.X <= dr2.X + dr2.Width) // moving left, lhs collision
            {
                double overlap = (dr2.X + dr2.Width) - dr1.X + EPS;
                reducedX = Math.Min(0.0f, deltaPosition.X + overlap);
            }

            // Project y only movement and fix y velocity
            temp = new Vector2(0, deltaPosition.Y);
            dr1 = mover.Bounds + temp;
            if (dr1.IntersectsWith(dr2))
            if (deltaPosition.Y > 0 && dr1.Y + dr1.Height >= dr2.Y) // moving down, bottom collision
            {
                double overlap = dr1.Y + dr1.Height - dr2.Y + EPS;
                reducedY = Math.Max(0.0f, deltaPosition.Y - overlap);
            }
            else if (deltaPosition.Y < 0 && dr1.Y <= dr2.Y + dr2.Height) // moving up, top collision
            {
                double overlap = (dr2.Y + dr2.Height) - dr1.Y + EPS;
                reducedY = Math.Min(0.0f, deltaPosition.Y + overlap);
            }

            // if neither X nor Y reduced, must be a corner collision
            // for now, we just won't allow this (if we allow, you can get stuck, but not bad)
            if (reducedX == deltaPosition.X && reducedY == deltaPosition.Y)
            {
                return Vector2.Zero;
            }

            return new Vector2((float)reducedX, (float)reducedY);
        }