/* When THIS collides with collidable c, only resolve * collision effects for THIS. c will call Collide(THIS) * so the collsion effects will be handled on that side. */ public virtual void Collide(Collidable c) { }
/* When a piece is destroyed, it might have death effects. * this method checks those statuses and resolves them */ private void ProcessDestruction(Collidable c) { }
public static void ResolveCollision(Collidable a, Collidable b) { a.Collide(b); b.Collide(a); }
//given an Collidable/coordinate tuple, this method processes those collisions public void TestCollisions(Collidable c, List<Collidable>[,] grid) { HashSet<Collidable> potentialCollisions = new HashSet<Collidable>(); List<Coordinate> zones = GetAllZones(c); foreach (var zone in zones) { potentialCollisions.UnionWith(grid[zone.X, zone.Y]); } foreach(Collidable b in potentialCollisions) { CollisionChecks += 1; if (DoesCollide(c, b)) Collidable.ResolveCollision(c, b); } }
public void InsertCollidable(Collidable c) { switch (c.GetCollisionSetting()) { case 0: FriendlyCollidables.Add(c); break; case 1: FriendlyProjectiles.Add(c); break; case 2: EnemyCollidables.Add(c); break; case 3: EnemyProjectiles.Add(c); break; } }
//this puts an individual Collidable into a zone, then returns a tuple containing the Collidable // and their respective zone public void InsertIntoZones(Collidable a, List<Collidable>[,] grid) { List<Coordinate> zoneList = GetAllZones(a); foreach (var c in zoneList) grid[c.X, c.Y].Add(a); }
public bool IsInBorders(Collidable c) { int x = ((int)c.GetPosition().X / ZoneWidth) + 1; int y = ((int)c.GetPosition().Y / ZoneHeight) + 1; if (x >= 0 && x < GRID_WIDTH && y >= 0 && y < GRID_HEIGHT) return true; else return false; }
//given a collidable returns the primary zone it resides in public Coordinate GetPrimaryZone(Collidable c) { int row = ((int)c.GetPosition().X / ZoneWidth) + 1; int column = ((int)c.GetPosition().Y / ZoneHeight) + 1; return new Coordinate(row, column); }
//returns a list of all of the zones a collidable object intersects public List<Coordinate> GetAllZones(Collidable c) { List<Coordinate> retList = new List<Coordinate>(); Coordinate pos = GetPrimaryZone(c); retList.Add(pos); Vector2 p = c.GetPosition(); int radius = c.GetHitRadius(); bool up, down, left, right; up = down = left = right = false; if (p.X % ZoneWidth <= radius) { retList.Add(new Coordinate(pos.X - 1, pos.Y)); left = true; } else if ((p.X % ZoneWidth) + radius >= ZoneWidth) { retList.Add(new Coordinate(pos.X + 1, pos.Y)); right = true; } //Check overlap on vertical zones if (p.Y % ZoneHeight <= radius) { retList.Add(new Coordinate(pos.X, pos.Y - 1)); up = true; } else if((p.Y % ZoneHeight) + radius >= ZoneHeight) { retList.Add(new Coordinate(pos.X, pos.Y + 1)); down = true; } //Checking corner overlaps if (left) { if (up) retList.Add(new Coordinate(pos.X - 1, pos.Y - 1)); else if (down) retList.Add(new Coordinate(pos.X - 1, pos.Y + 1)); } else if (right) { if (up) retList.Add(new Coordinate(pos.X + 1, pos.Y - 1)); else if (down) retList.Add(new Coordinate(pos.X + 1, pos.Y + 1)); } return retList; }
//checks if two Collidables collide public bool DoesCollide(Collidable a, Collidable b) { int radius = a.GetHitRadius() + b.GetHitRadius(); int dX = (int)b.GetPosition().X - (int)a.GetPosition().X; int dY = (int)b.GetPosition().Y - (int)a.GetPosition().Y; if (radius * radius < dX * dX + dY * dY) return false; else return true; }
//supes important, yo /* This method takes the effects from c * and applies it to THIS. it also does * type based collision resolution. */ public override void Collide(Collidable c) { Dictionary<int,Effect> effects = c.GetCollisionEffects(); foreach(int i in effects.Keys) { var e = effects[i]; e.OnAttach(this); float time = e.GetCurrTime(); if (time <= 0) e.OnEnd(this); else AddActiveEffect(e); } if (c is Actor) { Actor a = (Actor)c; int mt = this.GetHullType(); int ot = a.GetHullType(); // if I'm a projectile, self destruct on impact if (mt == 0) this.Destroy(); // if I'm a missile, self destruct if i hit a solid else if (mt == 1) { if (ot == 2) { this.Destroy(); } } // if I'm a solid, take damage if the enemy is a solid. // the enemy will do the same. there might be a survivor. else if (mt == 2) { if (ot == 2) { //DamagePierce(50); var dmg = new EffectDamagePierce(a.GetCurrHP()); AddActiveEffect(dmg); } } } }
public override void Collide(Collidable c) { this.count++; if (c is Actor) lastActor = (Actor)c; }