public void BlockCollision() { List<Vector2> tilesHitting = RectangleHitsTiles(BoundBox); //Didn't want to make a new BoundBox so this'll do. Gets the tiles the player will be in with his velocity. EntityPosition += EntityVelocity; Vector2 newEntityPosition = EntityPosition; ShapeAABB newRectTest = BoundBox; List<Vector2> newTilesHitting = RectangleHitsTiles(newRectTest); EntityPosition -= EntityVelocity; //The amount of tiles the player will be entering with his new position. List<Vector2> newTiles = newTilesHitting; int highestY = 0; for (int i = 0; i < newTiles.Count; i++) { if (newTiles[i].Y > highestY) highestY = (int)newTiles[i].Y; } foreach (Vector2 newTile in newTiles) { BlockData blockData = GameWorld.GetBlockAt(newTile.X, newTile.Y); if (blockData.ID == 0) continue; Block block = blockData.Block; bool walkThrough = block.GetBlockWalkThrough(); //A wall Rectangle blockBB = block.GetBlockBoundBox((int)newTile.X, (int)newTile.Y); ShapeAABB thisAABB = newRectTest; ShapeAABB blockAABB = new ShapeAABB(blockBB); AABBCollisionResult collide = thisAABB.CollideAABB(blockAABB); if (!collide.IsIntersecting) continue; if (collide.XSmaller){ bool right = (collide.X < 0); if (!walkThrough) { EntityVelocity.X = 0; EntityPosition.X = (newEntityPosition.X + collide.X); ShouldDestroy = true; break; } } else { bool up = (collide.Y > 0); if (!walkThrough){ EntityVelocity.Y = 0; EntityPosition.Y = (newEntityPosition.Y + collide.Y); ShouldDestroy = true; break; } } } }
public virtual void EntityMovement() { if (BoundBox.Left < 0) EntityPosition.X = BoundBox.Width / 2 + 1; if (BoundBox.Top < 0) EntityPosition.Y = BoundBox.Height / 2 + 1; if (BoundBox.Right > GameWorld.BlockSize * GameWorld.WorldSizeX) EntityPosition.X = GameWorld.BlockSize * GameWorld.WorldSizeX - (BoundBox.Width / 2); if (BoundBox.Bottom > GameWorld.BlockSize * GameWorld.WorldSizeY) EntityPosition.Y = GameWorld.BlockSize * GameWorld.WorldSizeY - (BoundBox.Height / 2); List<Vector2> tilesHitting = RectangleHitsTiles(BoundBox); //Didn't want to make a new BoundBox so this'll do. Gets the tiles the player will be in with his velocity. EntityPosition += EntityVelocity; List<Vector2> newTilesHitting = RectangleHitsTiles(BoundBox); //The amount of tiles the player will be entering with his new position. List<Vector2> newTiles = newTilesHitting; int highestY = 0; for (int i = 0; i < newTiles.Count; i++) { if (newTiles[i].Y > highestY) highestY = (int)newTiles[i].Y; } foreach (Vector2 newTile in newTiles) { BlockData blockData = GameWorld.GetBlockAt(newTile.X, newTile.Y); if (blockData.ID == 0) continue; Block block = blockData.Block; bool walkThrough = block.GetBlockWalkThrough(); //A wall Rectangle blockBB = block.GetBlockBoundBox((int)newTile.X, (int)newTile.Y); ShapeAABB thisAABB = BoundBox; ShapeAABB blockAABB = new ShapeAABB(blockBB); AABBCollisionResult collide = thisAABB.CollideAABB(blockAABB); if (!collide.IsIntersecting) continue; if (collide.XSmaller) { bool right = (collide.X < 0); if (!walkThrough) { EntityVelocity.X = 0; EntityPosition.X += collide.X; } block.OnBlockTouched((int)newTile.X, (int)newTile.Y, right ? 3 : 1, this); } else { bool up = (collide.Y > 0); //if (up && EntityVelocity.Y < 0) continue; if (!walkThrough) { EntityVelocity.Y = 0; EntityPosition.Y += collide.Y; if (!up) { TimeFalling = 0; Falling = false; } } block.OnBlockTouched((int)newTile.X, (int)newTile.Y, up ? 2 : 0, this); } } //EntityPosition += EntityVelocity; //Ropes short blockID2 = GameWorld.GetBlockAt(GetEntityTile().X, GetEntityTile().Y).ID; if (EntityVelocity.Y < 6 && blockID2 != 6) EntityVelocity.Y += 1; // Gravity! This is a really nice side effect: The code for not allowing the player to go through a block downwards already exists, so I just need to add this one line to add gravity! if (blockID2 == 6) { if (EntityVelocity.Y > 0) EntityVelocity.Y--; if (EntityVelocity.Y < 0) EntityVelocity.Y++; } if (EntityVelocity.X < 0) EntityVelocity.X += 1; if (EntityVelocity.X > 0) EntityVelocity.X -= 1; if (EntityVelocity.Y != 1) Falling = true; }
internal List<Vector2> RectangleHitsTiles(ShapeAABB rect) { List<Vector2> ret = new List<Vector2>(); //PToV simply turns a Point into a Vector2 Vector2 rectCenter = rect.Center; Vector2 topLeftHit = GameWorld.AbsoluteToTile(new Vector2(rect.Left, rect.Top)); topLeftHit.X = (topLeftHit.X > 0) ? topLeftHit.X - 1 : topLeftHit.X; topLeftHit.Y = (topLeftHit.Y > 0) ? topLeftHit.Y - 1 : topLeftHit.Y; Vector2 bottomRightHit = GameWorld.AbsoluteToTile(new Vector2(rect.Right, rect.Bottom)); bottomRightHit.X = (bottomRightHit.X < GameWorld.WorldSizeX) ? bottomRightHit.X + 1 : bottomRightHit.X; bottomRightHit.Y = (bottomRightHit.Y < GameWorld.WorldSizeY) ? bottomRightHit.Y + 1 : bottomRightHit.Y; //From the top of the rectangle to the bottom, find the tiles that the rectangle intersects and add them. for (int y = (int)topLeftHit.Y; y <= bottomRightHit.Y; y++) { for (int x = (int)topLeftHit.X; x <= bottomRightHit.X; x++) { if (!ret.Contains(new Vector2(x, y))) ret.Add(new Vector2(x, y)); } } return ret; }
public static bool inCamera(Vector2 position, ShapeAABB dimensions) { Rectangle r = new Rectangle((int)position.X, (int)position.Y, dimensions.Width, dimensions.Height); return (r.Intersects(cameraBoundBox) || cameraBoundBox.Contains(r) || r.Contains(cameraBoundBox)); }
public override AABBCollisionResult CollideAABB(ShapeAABB collidingWith) { throw new NotImplementedException(); }
public bool Intersects(ShapeAABB boundBox) { return CollideAABB(boundBox).IsIntersecting; }
public CPGameMode() { RedCapPoint = new ShapeAABB(2520, 384, 168, 96); BluCapPoint = new ShapeAABB(120, 384, 168, 96); }
public override AABBCollisionResult CollideAABB(ShapeAABB bound2) { ShapeAABB bound1 = this; Vector2 bound1HalfWidths = new Vector2(bound1.Width / 2, bound1.Height / 2); Vector2 bound2HalfWidths = new Vector2(bound2.Width / 2, bound2.Height / 2); float yMove = 0; float xMove = 0; float multY = (bound1.Center.Y < bound2.Center.Y) ? -1 : 1; float multX = (bound1.Center.X < bound2.Center.X) ? -1 : 1; int xCDist = (int)Math.Abs(bound2.Center.X - bound1.Center.X); int yCDist = (int)Math.Abs(bound2.Center.Y - bound1.Center.Y); xMove = bound1HalfWidths.X + bound2HalfWidths.X - xCDist; yMove = bound1HalfWidths.Y + bound2HalfWidths.Y - yCDist; //Not colliding. SAT. if (yMove < 0 || xMove < 0) return new AABBCollisionResult(0, 0, false, false); //if (yMove < xMove && yMove > 0) xMove = 0; //else if (xMove < yMove && xMove > 0) yMove = 0; return new AABBCollisionResult((int)(xMove * multX), (int)(yMove * multY), xMove < yMove, true); }
public bool Contains(ShapeAABB boundBox) { if (boundBox.Width >= Width || boundBox.Height >= Height) return false; return boundBox.Left - Left > 0 && Right - boundBox.Right > 0 && boundBox.Top - Top > 0 && Bottom - boundBox.Bottom > 0; }
public virtual void EntityMovement() { if (ShouldDestroy) return; if (BoundBox.Left < 0 || BoundBox.Top < 0 || BoundBox.Right > GameServer.BlockSize * GameServer.WorldSizeX || BoundBox.Bottom > GameServer.BlockSize * GameServer.WorldSizeY) { ShouldDestroy = true; return; } List<Vector2> tilesHitting = RectangleHitsTiles(BoundBox); //Didn't want to make a new BoundBox so this'll do. Gets the tiles the player will be in with his velocity. EntityPosition += EntityVelocity; Vector2 newEntityPosition = EntityPosition; ShapeAABB newRectTest = BoundBox; List<Vector2> newTilesHitting = RectangleHitsTiles(newRectTest); EntityPosition -= EntityVelocity; //The amount of tiles the player will be entering with his new position. List<Vector2> newTiles = newTilesHitting; int highestY = 0; for (int i = 0; i < newTiles.Count; i++) { if (newTiles[i].Y > highestY) highestY = (int)newTiles[i].Y; } foreach (Vector2 newTile in newTiles) { BlockData blockData = GameServer.GetBlockAt(newTile.X, newTile.Y); if (blockData.ID == 0) continue; Block block = blockData.Block; bool walkThrough = block.GetBlockWalkThrough(); //A wall Rectangle blockBB = block.GetBlockBoundBox((int)newTile.X, (int)newTile.Y); ShapeAABB thisAABB = newRectTest; ShapeAABB blockAABB = new ShapeAABB(blockBB); AABBCollisionResult collide = thisAABB.CollideAABB(blockAABB); if (!collide.IsIntersecting) continue; if (collide.XSmaller) { bool right = (collide.X < 0); if (!walkThrough) { EntityVelocity.X = 0; EntityPosition.X = (newEntityPosition.X + collide.X); ShouldDestroy = true; GameServer.SetBlock((int)newTile.X, (int)newTile.Y, 0); break; } } else { bool up = (collide.Y > 0); if (!walkThrough) { EntityVelocity.Y = 0; EntityPosition.Y = (newEntityPosition.Y + collide.Y); ShouldDestroy = true; GameServer.SetBlock((int)newTile.X, (int)newTile.Y, 0); break; } } } EntityPosition += EntityVelocity; if (EntityVelocity.Y < 6) EntityVelocity.Y += EffectOfGravity; if (EntityVelocity.X < 0) EntityVelocity.X += AirFriction; if (EntityVelocity.X > 0) EntityVelocity.X -= AirFriction; }
internal List<Vector2> RectangleHitsTiles(ShapeAABB rect) { List<Vector2> ret = new List<Vector2>(); //PToV simply turns a Point into a Vector2 Vector2 rectCenter = rect.Center; Vector2 topLeftHit = GameServer.AbsoluteToTile(new Vector2(rect.Left, rect.Top)); Vector2 bottomRightHit = GameServer.AbsoluteToTile(new Vector2(rect.Right - 2, rect.Bottom - 2)); //From the top of the rectangle to the bottom, find the tiles that the rectangle intersects and add them. for (int y = (int)topLeftHit.Y; y <= bottomRightHit.Y; y++) { for (int x = (int)topLeftHit.X; x <= bottomRightHit.X; x++) { if (!ret.Contains(new Vector2(x, y))) ret.Add(new Vector2(x, y)); } } return ret; }
public abstract AABBCollisionResult CollideAABB(ShapeAABB collidingWith);
private void BlockCollisions() { List<Vector2> newTiles = RectangleHitsTiles(BoundBox); foreach (Vector2 newTile in newTiles) { BlockData blockData = GameServer.GetBlockAt(newTile.X, newTile.Y); if (blockData.ID == 0) continue; Block block = blockData.Block; bool walkThrough = block.GetBlockWalkThrough(); //A wall Rectangle blockBB = block.GetBlockBoundBox((int)newTile.X, (int)newTile.Y); ShapeAABB thisAABB = BoundBox; ShapeAABB blockAABB = new ShapeAABB(blockBB); AABBCollisionResult collide = thisAABB.CollideAABB(blockAABB); if (!collide.IsIntersecting || collide.X == 0 || collide.Y == 0) continue; if (!walkThrough) { int side = 0; if (collide.Projection.Y > 0) side = 2; if (collide.Projection.Y < 0) side = 0; if (collide.Projection.X > 0) side = 1; if (collide.Projection.X < 0) side = 3; if (collide.Projection.Y < 0) { TimeFalling = 0; Falling = false; } EntityVelocity *= collide.MultProjection; EntityPosition += collide.Projection; block.OnBlockTouched((int)newTile.X, (int)newTile.Y, side, this); } /*else if (collide.XSmaller) { bool right = (collide.X < 0); if (!walkThrough) { EntityVelocity.X = 0; EntityPosition.X += collide.X; } block.OnBlockTouched((int)newTile.X, (int)newTile.Y, right ? 3 : 1, this); } else { bool up = (collide.Y > 0); if (!walkThrough) { EntityVelocity.Y = 0; EntityPosition.Y += collide.Y; if (!up) { TimeFalling = 0; Falling = false; } } block.OnBlockTouched((int)newTile.X, (int)newTile.Y, up ? 2 : 0, this); }*/ } }
private void AttackSword() { int leftX = FacingLeft ? BoundBox.Left - 15 : BoundBox.Right; ShapeAABB bound = new ShapeAABB(new Rectangle(leftX, (int)BoundBox.Top + 5, 15, PlayerHeight - 6)); List<Vector2> newTiles = RectangleHitsTiles(bound); foreach (Vector2 v in newTiles) { BlockData block = GameServer.GetBlockAt(v.X, v.Y); if (block.ID != 0) { ShapeAABB bound2 = new ShapeAABB(block.Block.GetBlockBoundBox((int)v.X, (int)v.Y)); if (bound2.Intersects(bound)) { GameServer.HurtBlock((int)v.X, (int)v.Y, 2); } } } foreach (NetworkPlayer player in GameServer.NetworkPlayers) { if (player == this) continue; if (player.PlayerTeam == PlayerTeam) continue; if (player.BoundBox.Intersects(bound) || player.BoundBox.Contains(bound) || bound.Contains(player.BoundBox)) { player.HurtPlayer(1); player.EntityVelocity.Y = -4; player.EntityVelocity.X = FacingLeft ? -5 : 5; } } }