//protected virtual bool PixelCollusion(MovingObj other) //{ // Color[] bitsThis = new Color[currentTexture.Width * currentTexture.Height]; // Color[] bitsOther = new Color[other.currentTexture.Width * other.currentTexture.Height]; // Color[] bitsThisScaled = new Color[RoundUp(currentTexture.Width * currentTexture.Height * scale)]; // Color[] bitsOtherScaled = new Color[RoundUp(other.currentTexture.Width * other.currentTexture.Height * other.scale)]; //} //private Color[] ScaledClrs(Texture2D txtr, float scale) //{ // //NOT WORKING. FK. // Color[] clrs = new Color[txtr.Width * txtr.Height]; // int colsInScaled = RoundUp(txtr.Width * scale); // int rowsInScaled = RoundUp(txtr.Height * scale); // Color[] scaled = new Color[colsInScaled * rowsInScaled]; // for (int row = 0; row < txtr.Height; row++) // { // int rowStartNonTransperent = -1; // int rowEndNonTransperent = -1; // for (int col = 0; col < txtr.Width; col++) // { // //clrs[row * width + column] how to get to the current cell // if (rowStartNonTransperent == -1 && clrs[row * txtr.Width + col] != Color.Transparent) // { // rowStartNonTransperent = col; // } // if (rowStartNonTransperent != -1 && clrs[row * txtr.Width + col] == Color.Transparent) // { // rowEndNonTransperent = col; // } // } // for (int currColInScaled = 0; currColInScaled < colsInScaled; currColInScaled++) // { // scaled[] // } // } //} //private int RoundUp(float num) //{ // bool a = num - (int)num > 0; // int rounded = Convert.ToInt32(num); // return (num - rounded) > 0 ? rounded + 1 : rounded; //} /// <summary> /// Returns the direction of other realative to this if there's a collusion. Returns Direction.None otherwise /// Prefers left/right collusions over up/bottom collusions /// </summary> public virtual List <Direction> Collusion(MovingObj other) { return(ProtectedCollusion(other, this.Left, this.Right, this.Top, this.Bottom)); }
public override List <Direction> Collusion(MovingObj other) { return(ProtectedCollusion(other, Left + speedX, Right + speedX, Top + SpeedY, Bottom + SpeedY)); }
/// <summary> /// Returns the directions of the collusion of other with this and invokes handle collusion /// </summary> protected List <Direction> ProtectedCollusion(MovingObj other, float thisLeft, float thisRight, float thisTop, float thisBottom) { float otherTop = other.Top + other.SpeedY; float otherBottom = other.Bottom + other.SpeedY; float otherLeft = other.Left + other.SpeedX; float otherRight = other.Right + other.SpeedX; List <Direction> dirs = new List <Direction>(); if (!(thisLeft <= otherRight && thisRight >= other.Left && thisBottom >= otherTop && thisTop <= otherBottom)) { //there's no collusion return(dirs); } if (this is Floor) { if (otherBottom >= thisTop) { dirs.Add(Direction.Up); other.HandleCollusion((dynamic)this, dirs); } return(dirs); } //other is checking if he is colliding me //check collusion from right, speed must be negative cus other must go right if (other.SpeedX < 0 && thisRight > otherLeft && thisLeft <= otherLeft) { //it's in X range of collusion, check Y if (thisTop <= otherTop && thisBottom >= otherBottom) { //this is Bigger than other (other is inside of this Y) dirs.Add(Direction.Right); } else if (otherTop <= thisTop && otherBottom >= thisBottom) { //other is bigger than this dirs.Add(Direction.Right); } else if (!(this is Floor) && otherTop <= thisTop && otherBottom >= thisTop) { //other is in limbo dirs.Add(Direction.Right); } } if (!dirs.Contains(Direction.Right)) { //check from left, speed must be positive cus other must go left if (other.SpeedX > 0 && thisLeft <= otherRight && thisRight >= otherRight) { //it's in X range of collusion, check Y if (thisTop <= otherTop && thisBottom >= otherBottom) { //this is Bigger than other (other is inside of this Y) dirs.Add(Direction.Left); } else if (otherTop <= thisTop && otherBottom >= thisBottom) { //other is bigger than this dirs.Add(Direction.Left); } else if (!(this is Floor) && otherTop <= thisTop && otherBottom >= thisTop) { //other is in limbo dirs.Add(Direction.Left); } } } if (thisTop <= otherBottom && thisBottom >= otherTop) { //in Y range. check if X is in range if (thisLeft <= otherLeft && thisRight >= otherRight) //this is bigger than other { dirs.Add(Direction.Up); } else if (otherLeft <= thisLeft && otherRight >= thisRight) //other is bigger than this { dirs.Add(Direction.Up); } else if ((other.PrevSarfuce == null || this.Equals(other.PrevSarfuce)) && thisLeft >= otherLeft && thisLeft <= otherRight) //other partially standing on this, other is on right side of this { dirs.Add(Direction.Up); } else if ((other.PrevSarfuce == null || this.Equals(other.PrevSarfuce)) && thisRight <= otherRight && thisRight >= otherLeft) //other partially standing on this, other is on left side of this { dirs.Add(Direction.Up); } } if (!dirs.Contains(Direction.Up)) { if (thisBottom >= otherTop && thisTop <= otherBottom) { //Y is in range. Check if X is in range if (thisLeft <= otherLeft && thisRight >= otherRight) //this is bigger than other { dirs.Add(Direction.Down); } else if (otherLeft <= thisLeft && otherRight >= thisRight) //other is bigger than this { dirs.Add(Direction.Down); } } } if (dirs.Contains(Direction.Up) && (dirs.Contains(Direction.Left) || dirs.Contains(Direction.Right))) { if (dirs.Contains(Direction.Left)) { if (other.Bottom > thisTop) { //flip em dirs[0] = Direction.Up; dirs[1] = Direction.Left; } } if (dirs.Contains(Direction.Right)) { if (other.Bottom > thisTop) { //flip em dirs[0] = Direction.Up; dirs[1] = Direction.Right; } } } //Checking for a possibilty that "other" was way too fast, and just passed "this" in 1 turn if (dirs.Count == 0) { if (otherBottom <= thisBottom && otherTop >= thisTop) //if it's in cullosion range in terms of Y axis { if (other.SpeedX > 0 && thisLeft >= other.Right && thisRight <= otherLeft) //if other passed this in the turn (the speed has to be positive) { dirs = new List <Direction> { Direction.Left }; } else if (other.SpeedX < 0 && thisRight <= other.Left && thisLeft >= otherRight) { dirs = new List <Direction> { Direction.Right }; } } } other.HandleCollusion((dynamic)this, dirs); return(dirs); }