public bool CharHitsPlatform(Character character, Platform platform) { DirCardinal dir = CollideDetect.GetDirectionOfCollision(character, platform); if (dir != DirCardinal.Down) { return(false); } // Character is "Dropping" through platforms: if (character.status.action is DropdownAction) { character.physics.touch.TouchMover(null); return(false); } // Activate the Platform platform.ActivatePlatform(); character.physics.touch.TouchMover(platform); // Assign the Character with the "OnMover" action, which will maintain their momentum after leaving the platform. ActionMap.OnMover.StartAction(character); // Special Character Collision for Platforms. // Only the Character should run collision. Platform has no need to be touched, pushed, aligned, etc. // Additionally, it needs to skip the intend.Y test normally associated with CollideObjDown(platform). character.physics.touch.TouchDown(); character.physics.AlignUp(platform); character.physics.StopY(); return(true); }
public bool RunImpact(GameObject character, GameObject obj) { Character ch = (Character)character; // Specific Impact Types if (obj is Enemy) { return(((Enemy)obj).RunCharacterImpact(ch)); } if (obj is Item) { return(this.CharHitsItem(ch, (Item)obj)); } if (obj is Platform) { return(this.CharHitsPlatform(ch, (Platform)obj)); } if (obj is Projectile) { return(this.CharHitsProjectile(ch, (Projectile)obj)); } if (obj is Block) { return(this.CharHitsBlock(ch, (Block)obj)); } DirCardinal dir = CollideDetect.GetDirectionOfCollision(ch, obj); // Standard Collision return(Impact.StandardImpact(ch, obj, dir)); }
public bool EnemyHitsPlatform(Enemy enemy, Platform platform) { // If the enemy doesn't collide with tiles, they don't collide with platforms. if (enemy.CollideVal <= CollideEnum.NoTileCollide) { return(false); } DirCardinal dir = CollideDetect.GetDirectionOfCollision(enemy, platform); if (dir != DirCardinal.Down) { return(false); } // Enemy needs to track it's platform physics: enemy.physics.touch.TouchMover(platform); // Special Actor Collision for Platforms. // Only the Actor should run collision. Platform has no need to be touched, pushed, aligned, etc. // Additionally, it needs to skip the intend.Y test normally associated with CollideObjDown(platform). enemy.physics.touch.TouchDown(); enemy.physics.AlignUp(platform); enemy.physics.StopY(); return(true); }
/**************************** *** Directional Detection *** ****************************/ // Identifies the direction of a collision. // WARNING: Heavy use. Only run this AFTER you've tested for if the objects overlap. public static DirCardinal GetDirectionOfCollision(GameObject obj, GameObject obj2) { // If the movement between the objects > the amount overlapped, ignore the overlap. // This prevents problems like inaccurate hitboxes from the wrong side. int maxOverlapY = CollideDetect.GetMaxOverlapY(obj.physics, obj2.physics); int relativeY = CollideDetect.GetRelativeDY(obj.physics, obj2.physics); int overlapY = CollideDetect.GetOverlapY(obj, obj2, relativeY <= 0); if (Math.Abs(overlapY) <= maxOverlapY) { return(relativeY > 0 ? DirCardinal.Up : DirCardinal.Down); } // Same as above, but for X coordinates. int maxOverlapX = CollideDetect.GetMaxOverlapX(obj.physics, obj2.physics); int relativeX = CollideDetect.GetRelativeDX(obj.physics, obj2.physics); int overlapX = CollideDetect.GetOverlapX(obj, obj2, relativeX <= 0); if (Math.Abs(overlapX) <= maxOverlapX) { return(relativeX > 0 ? DirCardinal.Left : DirCardinal.Right); } // If we've made it this far, the object is overlapping, but already passed the edge. // We return false to avoid unusual behavior, such as 'popping' up on a platform when you're slightly beneath it. return(DirCardinal.None); }
// TODO HIGH PRIORITY: Might not need this if we rebuild GetDirectionOfCollision, due to no longer needing floats, etc. // Forces a direction to be assumed in a collision based on relative motion of the objects. public static DirCardinal AssumeDirectionOfCollision(Physics obj1Phys, Physics obj2Phys) { int relativeY = CollideDetect.GetRelativeDY(obj1Phys, obj2Phys); int relativeX = CollideDetect.GetRelativeDX(obj1Phys, obj2Phys); // If the relative motion of Y is greater than the relative motion of X, return a vertical collision. if (relativeY > relativeX) { return(relativeY > 0 ? DirCardinal.Up : DirCardinal.Down); } return(relativeX > 0 ? DirCardinal.Left : DirCardinal.Right); }
public CollideBroad() { // Assign Narrow Collision Component (can swap out as desired) this.narrow = new CollideDetect(); // Build List for Broad Collision this.objectList = new List <GameObject> [4]; this.objectList[0] = new List <GameObject>(); this.objectList[1] = new List <GameObject>(); this.objectList[2] = new List <GameObject>(); this.objectList[3] = new List <GameObject>(); this.comparePos = new BroadComparePos(); }
public bool CharHitsProjectile(Character character, Projectile projectile) { // Skip Character if they cast the projectile. if (projectile.ByCharacterId == character.id) { return(false); } DirCardinal dir = CollideDetect.GetDirectionOfCollision(character, projectile); // Set the projectile to bounce off of the screen: EndBounceParticle.SetParticle(character.room, Systems.mapper.atlas[(byte)AtlasGroup.Objects], projectile.SpriteName, new Vector2(projectile.posX, projectile.posY), Systems.timer.Frame + 40, 1, 0.5f, 0f); // Destroy the Projectile projectile.Destroy(); // If this projectile can be jumped on: if (projectile.SafelyJumpOnTop) { // Hit from above (projectile is below): if (dir == DirCardinal.Down) { //character.BounceUp(projectile.posX + projectile.bounds.MidX, 1, 0, 0); ActionMap.Jump.StartAction(character, 1, 0, 0, true, false); Systems.sounds.bulletJump.Play(); return(true); } // Hit from below (projectile is above): else if (dir == DirCardinal.Up && character.status.action is Action) { character.status.action.EndAction(character); } } // If wearing a hard hat, can ignore damage from above. if (dir == DirCardinal.Up) { if (character.hat is HardHat) { return(true); } } character.wounds.ReceiveWoundDamage(projectile.Damage); return(true); }
public bool CharHitsItem(Character character, Item item) { // Sport Ball if (item is SportBall) { return(((SportBall)item).RunCharacterImpact(character)); } // If this item is being held, skip. if (item.isHeld) { return(false); } // If the entity is intangible, don't collide with the Character. if (item.intangible > Systems.timer.Frame) { return(false); } DirCardinal dir = CollideDetect.GetDirectionOfCollision(character, item); // If item is hit from side: if (dir == DirCardinal.Left || dir == DirCardinal.Right) { // Check if Grabbing Item if (character.heldItem.WillPickupAttemptWork(item, dir)) { character.heldItem.PickUpItem(item); return(true); } } // If item is hit from above: else if (dir == DirCardinal.Up) { // Check if Grabbing Item if (character.heldItem.WillPickupAttemptWork(item, character.FaceRight ? DirCardinal.Right : DirCardinal.Left)) { character.heldItem.PickUpItem(item); return(true); } } // If we've made it this far, run standard collision with item: return(Impact.StandardImpact(character, item, dir)); }
public static void ProcessCollision(GameObject obj, GameObject obj2) { // If an overlap is not detected, end the narrow testing here. if (!CollideDetect.IsOverlapping(obj, obj2)) { return; } // Order the objects by archetype, and run them through the collision map. if (obj.Meta.Archetype < obj2.Meta.Archetype) { CollideNarrow.RefineCollision(obj, obj2); } else { CollideNarrow.RefineCollision(obj2, obj); } }
public bool RunImpact(GameObject enemy, GameObject obj) { Enemy en = (Enemy)enemy; // If the object is a platform, run special collision tests first. if (obj is Platform) { return(this.EnemyHitsPlatform(en, (Platform)obj)); } // For projectiles, direction may be unnecessary. if (obj is Projectile) { return(en.RunProjectileImpact(obj as Projectile)); } // Don't collide with Flight Enemies if (en is EnemyFlight || obj is EnemyFlight) { return(false); } DirCardinal dir = CollideDetect.GetDirectionOfCollision(en, obj); // Specific Impact Types if (obj is Enemy) { return(this.EnemyHitsEnemy(en, (Enemy)obj, dir)); } if (obj is Item) { return(this.EnemyHitsItem(en, (Item)obj, dir)); } if (obj is Block) { return(this.EnemyHitsBlock(en, (Block)obj, dir)); } // Standard Collision return(Impact.StandardImpact(en, obj, dir)); }
public bool ItemHitsPlatform(Item item, Platform platform) { DirCardinal dir = CollideDetect.GetDirectionOfCollision(item, platform); if (dir != DirCardinal.Down) { return(false); } // Item needs to track it's platform physics: item.physics.touch.TouchMover(platform); // Special Actor Collision for Platforms. // Only the Actor should run collision. Platform has no need to be touched, pushed, aligned, etc. // Additionally, it needs to skip the intend.Y test normally associated with CollideObjDown(platform). item.physics.touch.TouchDown(); item.physics.AlignUp(platform); item.physics.StopY(); return(true); }
public bool RunImpact(GameObject item, GameObject obj) { Item it = (Item)item; // Specific Impact Types if (obj is Projectile) { return(this.ItemHitsProjectile(it, (Projectile)obj)); } // Make sure the items aren't being held. if (it.isHeld) { return(false); } // Platforms if (obj is Platform) { return(this.ItemHitsPlatform(it, (Platform)obj));; } // Item-Item Collision if (obj is Item) { if (((Item)obj).isHeld) { return(false); } } DirCardinal dir = CollideDetect.GetDirectionOfCollision(it, obj); // Standard Collision return(Impact.StandardImpact(it, obj, dir)); }
public bool CharHitsBlock(Character character, Block block) { DirCardinal dir = CollideDetect.GetDirectionOfCollision(character, block); return(Impact.StandardImpact(character, block, dir)); }