public static void CheckCurrent(PhysObj obj, int x, int y) { if (!IsLegalXY(x, y)) return; if (environmentData[x, y].airCurrent != Vector2.Zero) obj.nextForce = environmentData[x, y].airCurrent; //if (obj.nextForce.X != 0) obj.terminalSpeed.X = 10; //else obj.terminalSpeed.X = 6; }
public void GetPickedUp(Player parent) { if (this.parent == null) { this.parent = parent; position = parent.position; parent.pickUp = this; } }
public AABB(PhysObj obj, float x1, float y1, float x2, float y2) { this.physObj = obj; this.x1 = x1; this.x2 = x2; this.y1 = y1; this.y2 = y2; omitTop = false; omitLeft = false; omitRight = false; omitBottom = false; incline = false; }
public AABB(PhysObj obj, Vector2 Position, Vector2 Size) : this(obj, Position.X, Position.Y, Position.X + Size.X, Position.Y + Size.Y) { }
public CollisionBox(PhysObj physObj, float Size) : this(physObj, new Vector2(Size, Size)) { }
public CollisionBox(PhysObj physObj, Vector2 Size) { this.physObj = physObj; WorldCornerMin = Vector2.Zero; WorldCornerMax = Vector2.Zero; LocalCornerMin = Vector2.Zero; LocalCornerMax = Vector2.Zero; Position = Vector2.Zero; Offset = Vector2.Zero; this.Size = Size; CalculateCorners(); }
public static void CheckEnvironment(PhysObj obj) { Point cornerTopLeft = PositionToGrid(new Vector2(obj.hitBox.Left(), obj.hitBox.Top())); Point cornerBottomRight = PositionToGrid(new Vector2(obj.hitBox.Right(), obj.hitBox.Bottom())); bool collision = false; float friction = obj.frictionMultiplier; List<AABB> collisionList = new List<AABB>(); List<float> frictionList = new List<float>(); for (int y = cornerTopLeft.Y; y <= cornerBottomRight.Y; y++) { for (int x = cornerTopLeft.X; x <= cornerBottomRight.X; x++) { if (CheckCollision(new Point(x, y))) { AABB aabb = new AABB(null, GridToPosition(new Point(x, y)), new Vector2(collisionSize)); if (environmentData[x, y].inclineType != InclineType.Flat) { aabb = SolveIncline(obj, x, y); } if (environmentData[x, y].oneWayPlatform) { aabb.omitLeft = true; aabb.omitRight = true; aabb.omitBottom = true; if (obj.speed.Y < 0 || obj.ignoreOneWay) { aabb.omitTop = true; } } if ((CheckCollision(x - 1, y) && !environmentData[x - 1, y].oneWayPlatform) || environmentData[x, y].omitLeft) aabb.omitLeft = true; if ((CheckCollision(x + 1, y) && !environmentData[x + 1, y].oneWayPlatform) || environmentData[x, y].omitRight) aabb.omitRight = true; if ((CheckCollision(x, y + 1) && !environmentData[x, y + 1].oneWayPlatform) || environmentData[x, y].omitBottom) aabb.omitBottom = true; if ((CheckCollision(x, y - 1) && !environmentData[x, y - 1].oneWayPlatform) || environmentData[x, y].omitTop) aabb.omitTop = true; //if (CheckCollision(x - 1, y) && environmentData[x,y].inclineType == InclineType.Flat) //{ // if (environmentData[x - 1, y].inclineType != InclineType.Flat && (obj.position.X > aabb.x1 && obj.position.X < aabb.x2)) aabb.omitTop = true; //} collisionList.Add(aabb); collision = true; frictionList.Add(GetFriction(obj, environmentData[x, y])); } CheckCurrent(obj, x, y); if (IsLegalXY(x,y) && environmentData[x, y].killZone) { obj.Die(); } } } Point checkBelow = PositionToGrid(new Vector2(obj.position.X, obj.hitBox.Bottom() + 1)); if (CheckCollision(checkBelow)) { if (environmentData[checkBelow.X, checkBelow.Y].inclineType != InclineType.Flat) { //Trace.WriteLine("Barf!"); if (!obj.jumpingLegacy) { //AABB aabb = new AABB(null, GridToPosition(checkBelow), new Vector2(collisionSize)); //aabb = SolveIncline(obj, checkBelow.X, checkBelow.Y); //obj.hitBox.SetPosition(obj.hitBox.GetPosition() + new Vector2(0, aabb.y2 - obj.hitBox.Bottom())); //collisionList.Add(aabb); //frictionList.Add(GetFriction(obj, environmentData[checkBelow.X, checkBelow.Y])); obj.nextForce.Y += 20; } } } //int y1 = cornerBottomRight.Y + 1; //for (int x = cornerTopLeft.X; x <= cornerBottomRight.X; x++) //{ // if (CheckCollision(x, y1)) // { // AABB aabb = new AABB(null, GridToPosition(new Point(x, y1)), new Vector2(collisionSize)); // if (environmentData[x, y1].inclineType != InclineType.Flat) // { // obj.position += new Vector2(0, 32); // collisionList.Add(aabb); // frictionList.Add(GetFriction(obj, environmentData[x, y1])); // } // } //} //if (collision == false) //{ // if (obj.state == PhysState.Grounded) //{ //check to see if there's ground beneath the object: //Point under = PositionToGrid(obj.tempPosition); //under.Y += 1; //if (CheckCollision(under.X, under.Y)) //{ // collision = true; //} //if (!collision) obj.state = PhysState.Air; //int y = cornerBottomRight.Y + 1; //for (int x = cornerTopLeft.X; x < cornerBottomRight.X; x++) //{ // if (CheckCollision(x, y)) // { // collision = true; // break; // } //} //if (!collision) obj.state = PhysState.Air; // } // return; //} foreach (AABB aabb in collisionList) { Vector2 solution = aabb.SolveCollision(obj.hitBox.GetAABB()); obj.hitBox.SetPosition(obj.hitBox.GetPosition() + solution); if (solution.Y < 0) { friction = frictionList.ElementAt(collisionList.IndexOf(aabb)); } } Vector2 newpos = obj.hitBox.GetPosition(); if (newpos.Y != obj.tempPosition.Y) obj.speed.Y = SolveBounce(obj, true); if (newpos.X != obj.tempPosition.X) obj.speed.X = SolveBounce(obj, false); if (newpos.Y < obj.tempPosition.Y) { obj.state = PhysState.Grounded; } obj.tempPosition = newpos; if (obj.state == PhysState.Grounded) { obj.frictionMultiplier = friction; if (friction == EnvironmentData.NORMAL) { obj.moveForce = 1; } else if (friction == EnvironmentData.ICE) { obj.moveForce = .2f; } } else { obj.frictionMultiplier = EnvironmentData.AIR; obj.moveForce = .2f; } }
public static AABB SolveIncline(PhysObj obj, int x, int y) { bool omitTop = false; Vector2 cornerTopLeft = GridToPosition(new Point(x, y)); Vector2 cornerBottomRight = cornerTopLeft + new Vector2(collisionSize); float thirdSize = collisionSize / 3; float halfSize = collisionSize / 2; switch (environmentData[x, y].inclineType) { case InclineType.ThreeTileRight1: float ratio = (cornerTopLeft.X - obj.tempPosition.X) / collisionSize; if (ratio > 0 || ratio < -1) omitTop = true; cornerTopLeft.Y = cornerBottomRight.Y + ratio * (thirdSize); break; case InclineType.ThreeTileRight2: ratio = (cornerTopLeft.X - obj.tempPosition.X) / collisionSize; cornerTopLeft.Y = cornerBottomRight.Y - (thirdSize) + ratio * (thirdSize); if (ratio > 0 || ratio < -1) omitTop = true; break; case InclineType.ThreeTileRight3: ratio = (cornerTopLeft.X - obj.tempPosition.X) / collisionSize; if (ratio > 0 || ratio < -1) omitTop = true; cornerTopLeft.Y = cornerBottomRight.Y - (2 * thirdSize) + ratio * (thirdSize); break; case InclineType.ThreeTileLeft1: ratio = (cornerTopLeft.X - obj.tempPosition.X) / collisionSize; if (ratio > 0 || ratio < -1) omitTop = true; cornerTopLeft.Y = cornerTopLeft.Y - ratio * (thirdSize); break; case InclineType.ThreeTileLeft2: ratio = (cornerTopLeft.X - obj.tempPosition.X) / collisionSize; //if (ratio > 0 || ratio < -1) omitTop = true; cornerTopLeft.Y = cornerTopLeft.Y + (thirdSize) - ratio * (thirdSize); break; case InclineType.ThreeTileLeft3: ratio = (cornerTopLeft.X - obj.tempPosition.X) / collisionSize; if (ratio > 0 || ratio < -1) omitTop = true; cornerTopLeft.Y = cornerTopLeft.Y + (2 * thirdSize) - ratio * (thirdSize); break; case InclineType.TwoTileRight1: ratio = (cornerTopLeft.X - obj.tempPosition.X) / collisionSize; if (ratio > 0 || ratio < -1) omitTop = true; cornerTopLeft.Y = cornerBottomRight.Y + ratio * (halfSize); break; case InclineType.TwoTileRight2: ratio = (cornerTopLeft.X - obj.tempPosition.X) / collisionSize; if (ratio > 0 || ratio < -1) omitTop = true; cornerTopLeft.Y = cornerBottomRight.Y - (halfSize) + ratio * (halfSize); break; case InclineType.TwoTileLeft1: ratio = (cornerTopLeft.X - obj.tempPosition.X) / collisionSize; if (ratio > 0 || ratio < -1) omitTop = true; cornerTopLeft.Y = cornerTopLeft.Y - ratio * (halfSize); break; case InclineType.TwoTileLeft2: ratio = (cornerTopLeft.X - obj.tempPosition.X) / collisionSize; if (ratio > 0 || ratio < -1) omitTop = true; cornerTopLeft.Y = cornerTopLeft.Y + (halfSize) - ratio * (halfSize); break; } AABB aabb = new AABB(null, cornerTopLeft.X, cornerTopLeft.Y, cornerBottomRight.X, cornerBottomRight.Y); aabb.omitLeft = true; aabb.omitRight = true; if (omitTop) { aabb.omitTop = true; aabb.omitBottom = true; } aabb.incline = true; return aabb; }
public static float SolveBounce(PhysObj obj, bool bounceVertical) { if (obj.canBounce) { if (bounceVertical) return -obj.speed.Y * obj.bounceMultiplier; else return -obj.speed.X / 2; } return 0; }
public static float GetFriction(PhysObj obj, EnvironmentData data) { switch (data.frictionType) { case FrictionType.Normal: return EnvironmentData.NORMAL; case FrictionType.Ice: return EnvironmentData.ICE; } return 1; }
public void GetDropped(Vector2 throwForce) { nextForce += throwForce; parent = null; }
public override void AdjustCollision(PhysObj obj) { base.AdjustCollision(obj); grabBox.SetPosition(position); }
public virtual void AdjustCollision(PhysObj obj) { if (playerTangible != PlayerObjectMode.None && obj.playerTangible != PlayerObjectMode.None) { if (playerTangible != obj.playerTangible) return; } if (!obj.isSolidObject || !hitBox.CheckCollision(obj.hitBox)) { return; } AABB aabb = obj.hitBox.GetAABB(); Vector2 solution = aabb.SolveCollision(hitBox.GetAABB()); hitBox.SetPosition(hitBox.GetPosition() + solution); Vector2 newpos = hitBox.GetPosition(); if (newpos.Y != position.Y) speed.Y = Level.SolveBounce(this, true); if (newpos.X != position.X) speed.X = Level.SolveBounce(this, false); if (newpos.Y < position.Y) { state = PhysState.Grounded; frictionMultiplier = EnvironmentData.NORMAL; obj.currentMass += currentMass; if (obj.affectsResident && !obj.residentList.Contains(this)) obj.residentList.Add(this); } if (newpos.Y > position.Y) { speed.Y = obj.speed.Y; if (speed.Y < 0) speed.Y = 0; } Vector2 prevPosition = position; position = newpos; Vector2 dPos = position - prevPosition; foreach (PhysObj resident in residentList) { resident.position += dPos; resident.hitBox.SetPosition(resident.position); } }
public virtual bool CheckCollision(PhysObj obj) { return false; }