public BasicWeapon(RectangularMask rectangularMask) : base(rectangularMask) { base.CollidingMode = CollidingMode.Inclusion; CollidingInclusionSet.Add(typeof(AI <MonkeyBoard>)); CollidingInclusionSet.Add(typeof(BorderTile)); }
protected CollisionStatus IsCollidingInto(Position nextPosition, RectangularMask mask, Collidable <TBoard> otherCollidable) { // creates a dummy variable just to store the out value int dummyCollisionDistance; return(IsCollidingInto(new Position(), nextPosition, mask, otherCollidable, out dummyCollisionDistance)); }
public Rocket(RectangularMask rectangularMask = default(RectangularMask)) : base(rectangularMask) { HomingSound = new SoundPlayer(@"Resources/Sfx/weapon_homing.wav"); AIKilledSound = new SoundPlayer(@"Resources/Sfx/explosion.wav"); HomingSound.PlayLooping(); }
public Movable(RectangularMask rectangularMask = default(RectangularMask), IEnumerable <IMovement> movements = null, Position position = default(Position)) : base(rectangularMask, position) { if (movements == null) { MovementList = new List <IMovement>(); } else { MovementList = new List <IMovement>(movements); } }
public Controllable(RectangularMask rectangularMask = default(RectangularMask), IEnumerable <IMovement> movements = null, Position position = default(Position)) : base(rectangularMask, movements, position) { }
protected CollisionStatus IsCollidingInto(Position previousPosition, Position nextPosition, RectangularMask mask, Collidable <TBoard> otherCollidable, out int collisionDistance) { // assume no collision first, and therefore collision distance is 0 collisionDistance = 0; // check whether if the other collidable object is itself // if it is, ignore if (this == otherCollidable) { return(CollisionStatus.NoCollision); } // sometimes removal of board is done before this (because of the async nature of event handling) // if so, we ignore the collision if (Board == null) { return(CollisionStatus.NoCollision); } // we do checks according to the colliding mode // we also check whether the other collidable object's type // is found within the inclusion or exclusion set if (CollidingMode == Logic.CollidingMode.Exclusion && CollidingExclusionSet.Contains(otherCollidable.GetType()) || otherCollidable.CollidingMode == Logic.CollidingMode.Exclusion && otherCollidable.CollidingExclusionSet.Contains(this.GetType())) { return(CollisionStatus.NoCollision); } else if (CollidingMode == Logic.CollidingMode.Inclusion || otherCollidable.CollidingMode == Logic.CollidingMode.Inclusion) { bool tmp = false; foreach (Type c in CollidingInclusionSet) { if ((otherCollidable.GetType().IsSubclassOf(c) || this.GetType().IsSubclassOf(c)) || (otherCollidable.GetType().Equals(c)) || (this.GetType().Equals(c))) { tmp = true; break; } } if (!tmp) { foreach (Type c in otherCollidable.CollidingInclusionSet) { if (otherCollidable.GetType().IsSubclassOf(c) || this.GetType().IsSubclassOf(c) || (otherCollidable.GetType().Equals(c)) || (this.GetType().Equals(c))) { tmp = true; break; } } } if (!tmp) { return(CollisionStatus.NoCollision); } } // IMPORTANT // check for mask collision here // refer to CollidableMaskCalculation.png for pictorial descriptions // note that a mask can at most take up a grid size // which is (FinenessLimit * 2) by (FinenessLimit * 2) // we will be converting all X and Y values into the absolute fineness values // for convenience in comparison // TODO: // should use subprocedure to calculate all these because most calculation parts // are the same // check for x-axis first RectangularMask otherMask = otherCollidable.RectangularMask; int otherMaskFinenessX = otherCollidable.X * Board.FinenessLimit * 2 + otherCollidable.FinenessX; int otherMaskLeftFinenessX = otherMaskFinenessX + otherMask.LeftMargin; int otherMaskRightFinenessX = otherMaskFinenessX + Board.FinenessLimit * 2 - 1 - otherMask.RightMargin; int maskFinenessX = nextPosition.X * Board.FinenessLimit * 2 + nextPosition.FinenessX; int maskLeftFinenessX = maskFinenessX + mask.LeftMargin; // because the upper limit is exclusive unlike the lower limit, and since the fineness unit is discrete // there is a need to -1 int maskRightFinenessX = maskFinenessX + Board.FinenessLimit * 2 - 1 - mask.RightMargin; // check collision now by comparing the mask // if x doesn't collide, that means it won't collide anyway, so return false if (!((maskLeftFinenessX <= otherMaskLeftFinenessX && otherMaskLeftFinenessX <= maskRightFinenessX) || (maskLeftFinenessX <= otherMaskRightFinenessX && otherMaskRightFinenessX <= maskRightFinenessX) || (otherMaskLeftFinenessX <= maskLeftFinenessX && maskLeftFinenessX <= otherMaskRightFinenessX) || (otherMaskLeftFinenessX <= maskRightFinenessX && maskRightFinenessX <= otherMaskRightFinenessX))) { return(CollisionStatus.NoCollision); } // now check for y-axis int otherMaskFinenessY = otherCollidable.Y * Board.FinenessLimit * 2 + otherCollidable.FinenessY; int otherMaskTopFinenessY = otherMaskFinenessY + otherMask.TopMargin; int otherMaskBottomFinenessY = otherMaskFinenessY + Board.FinenessLimit * 2 - 1 - otherMask.BottomMargin; int maskFinenessY = nextPosition.Y * Board.FinenessLimit * 2 + nextPosition.FinenessY; int maskTopFinenessY = maskFinenessY + mask.TopMargin; int maskBottomFinenessY = maskFinenessY + Board.FinenessLimit * 2 - 1 - mask.BottomMargin; // check collision now by comparing the mask // if y doesn't collide, return false if (!((maskTopFinenessY <= otherMaskTopFinenessY && otherMaskTopFinenessY <= maskBottomFinenessY) || (maskTopFinenessY <= otherMaskBottomFinenessY && otherMaskBottomFinenessY <= maskBottomFinenessY) || (otherMaskTopFinenessY <= maskTopFinenessY && maskTopFinenessY <= otherMaskBottomFinenessY) || (otherMaskTopFinenessY <= maskBottomFinenessY && maskBottomFinenessY <= otherMaskBottomFinenessY))) { return(CollisionStatus.NoCollision); } // this part onwards reveals where the collision is headed from CollisionStatus statusForOther; // first check for direction of collision for Y to solve a serious bug int previousFinenessY = previousPosition.Y * Board.FinenessLimit * 2 + previousPosition.FinenessY; int previousTopFinenessY = previousFinenessY + mask.TopMargin; int previousBottomFinenessY = previousFinenessY + Board.FinenessLimit * 2 - 1 - mask.BottomMargin; if (previousBottomFinenessY < otherMaskTopFinenessY) { collisionDistance = otherMaskTopFinenessY - previousBottomFinenessY - 1; statusForOther = CollisionStatus.CollisionFromTop; } else if (previousTopFinenessY > otherMaskBottomFinenessY) { collisionDistance = previousTopFinenessY - otherMaskBottomFinenessY - 1; statusForOther = CollisionStatus.CollisionFromBottom; } else { // next check for direction of collision for X first int previousFinenessX = previousPosition.X * Board.FinenessLimit * 2 + previousPosition.FinenessX; int previousLeftFinenessX = previousFinenessX + mask.LeftMargin; int previousRightFinenessX = previousFinenessX + Board.FinenessLimit * 2 - 1 - mask.RightMargin; if (previousRightFinenessX < otherMaskLeftFinenessX) { // there is a need to minus 1 because without minusing, the two masks will exactly clip onto each other // at the boundary. By minusing 1, the two masks will be exactly at side by side. collisionDistance = otherMaskLeftFinenessX - previousRightFinenessX - 1; statusForOther = CollisionStatus.CollisionFromLeft; } else { collisionDistance = previousLeftFinenessX - otherMaskRightFinenessX - 1; statusForOther = CollisionStatus.CollisionFromRight; } } return(statusForOther); }
public Collidable(RectangularMask rectangularMask = default(RectangularMask), Position position = default(Position)) : base(position) { RectangularMask = rectangularMask; }
protected CollisionStatus PerformCollidingInto(Position previousPosition, Position nextPosition, RectangularMask mask, Collidable <TBoard> otherCollidable, out int collisionDistance) { // instead of just checking for collision, this method will also trigger the collision after events CollisionStatus statusForOther = IsCollidingInto(previousPosition, nextPosition, mask, otherCollidable, out collisionDistance); CollisionStatus statusForItself = CollisionStatus.NoCollision; switch (statusForOther) { case CollisionStatus.CollisionFromTop: statusForItself = CollisionStatus.CollisionFromBottom; break; case CollisionStatus.CollisionFromBottom: statusForItself = CollisionStatus.CollisionFromTop; break; case CollisionStatus.CollisionFromLeft: statusForItself = CollisionStatus.CollisionFromRight; break; case CollisionStatus.CollisionFromRight: statusForItself = CollisionStatus.CollisionFromLeft; break; } // calls class-specific behavioural methods. For instance, these methods will trigger removal of bananas from board when they collide with the monkey. if (statusForOther != CollisionStatus.NoCollision) { CollisionStatus newStatusForItself = BeforeCollision(otherCollidable, statusForItself); CollisionStatus newStatusForOther; if (newStatusForItself != CollisionStatus.NoCollision) { newStatusForOther = otherCollidable.BeforeCollision(this, statusForOther); } else { newStatusForOther = CollisionStatus.NoCollision; } CollisionAfter(otherCollidable, newStatusForItself); otherCollidable.CollisionAfter(this, newStatusForOther); return(newStatusForOther); } return(statusForOther); }
public Tile(string tileIdentifier, RectangularMask rectangularMask) : base(rectangularMask) { // the identifier is meant for creating the correct TileUI TileIdentifier = tileIdentifier; }
public NonKillableNonMovingAI(RectangularMask rectangularMask) : base(rectangularMask) { }
public BasicMovingAI(RectangularMask rectangularMask) : base(rectangularMask) { }
public NonMovingGravityAffectedAI(RectangularMask rectangularMask) : base(rectangularMask) { }
public NonMovingAI(RectangularMask rectangularMask) : base(rectangularMask) { // set AI killed sound to be standard AIKilledSound = new SoundPlayer("Resources/Sfx/Enemy Killed.wav"); }
public Weapon(RectangularMask rectangularMask) : base(rectangularMask) { }
public RocketRight(RectangularMask rectangularMask = default(RectangularMask)) : base(rectangularMask) { }
public AI(RectangularMask rectangularMask) : base(rectangularMask) { }