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