/// <summary> /// Draw a unit's sprite to the screen /// </summary> /// <param name="sb">SpriteBatch with which to draw</param> /// <param name="unit">Unit to draw</param> /// <param name="xCameraOffset">x coordinate of left side of viewport</param> /// <param name="yCameraOffset">y coordinate of left side of viewport</param> public static void DrawSprite(SpriteBatch sb, Unit unit, int xCameraOffset, int yCameraOffset) { sprite = unit.Sprite; locationVector.X = unit.Center.X - xCameraOffset; locationVector.Y = unit.Center.Y - yCameraOffset; drawSprite(sb, sprite.TextureKey, locationVector, sprite.TextureSelectRect, sprite.Shade, sprite.Origin, sprite.Angle, sprite.Scale, sprite.FacingRight); }
public void CheckAgainstPlayer(Unit player) { if (_state == UnitState.Dead) return; float xDisp = player.Center.X - Center.X; float yDisp = player.Center.Y - Center.Y; //dont fire if not facing if ((xDisp >= 0 && !Sprite.FacingRight) || (xDisp <= 0 && Sprite.FacingRight)) { return; } //fire if close enough to player if (Math.Abs(xDisp) < _weapon.Range && Math.Abs(yDisp) < MAX_Y_ATTACK_OFFSET) { _state = UnitState.Attacking; _attacking = true; _weapon.Fire(Center, Vector2.UnitX * ((player.Center.X > Center.X) ? 1 : -1)); } }
/// <summary> /// Move a unit based on its velocity and the surrounding tiles /// </summary> /// <param name="unit">the unit to move</param> private void moveUnit(Unit unit) { //enter unit moving logic here //I suggest breaking down unit.Velocity into individual x and y components, cast into integers }
/// <summary> /// Move a unit based on its velocity and the surrounding tiles /// </summary> /// <param name="unit">the unit to move</param> private void moveUnit(Unit unit, GameTime gameTime) { int pxRight = (int)(unit.Velocity.X * (float)gameTime.ElapsedGameTime.TotalSeconds); int pxDown = (int)(unit.Velocity.Y * (float)gameTime.ElapsedGameTime.TotalSeconds); if (pxRight != 0) checkHorizontalCollision(unit, pxRight); if (pxDown != 0) checkVerticalCollision(unit, pxDown); if (unit.Top > _collisionLayer.LayerHeight * _collisionLayer.TileHeight) { unit.Damage(100, Direction.South); } }
private void checkVerticalCollision(Unit unit, int pxDown) { if (unit.Bottom >= _collisionLayer.LayerHeight * _collisionLayer.TileHeight) { unit.Y += pxDown; return; //let unit fall } int forwardEdge = (pxDown > 0) ? unit.Bottom : unit.Top; //1 for down, -1 for up int yDirection = pxDown / Math.Abs(pxDown); //start at initial forward edge int startRow = forwardEdge / _collisionLayer.TileHeight; //assume unit moves full distance unit.Y += pxDown; //check up to new assumed unit hitrect edge int endRow = (forwardEdge + pxDown) / _collisionLayer.TileHeight; startRow = (int)MathHelper.Clamp(startRow, 0, _collisionLayer.LayerHeight - 1); endRow = (int)MathHelper.Clamp(endRow, 0, _collisionLayer.LayerHeight - 1); for (int row = startRow; row != (endRow + yDirection); row = row + yDirection) { for (int col = (unit.Left + 1) / _collisionLayer.TileWidth; col <= (unit.Right - 1) / _collisionLayer.TileWidth; col++) { if (!_collisionLayer.IsValidTileLocation(col, row)) { continue; } //pickup checks if (unit == _gino && _pickupLayer.IsValidTileLocation(col, row) && _pickupLayer.Tiles[col, row] != null) { if (_pickupLayer.Tiles[col, row].TileIndexProperties.ContainsKey("PickupType")) { getPickup(_pickupLayer.Tiles[col, row].TileIndexProperties["PickupType"], row, col); } } if (_collisionLayer.Tiles[col, row] != null && _collisionLayer.Tiles[col, row].TileIndex != 0) { if (pxDown > 0) { unit.CollideWithObstacle(Direction.South); unit.Bottom = row * _collisionLayer.TileHeight; } else { unit.CollideWithObstacle(Direction.North); unit.Top = (row + 1) * _collisionLayer.TileHeight; } break; //no need to check more } } } }
private void checkHorizontalCollision(Unit unit, int pxRight) { if (unit.Left < 0 || unit.Right >= _collisionLayer.LayerWidth * _collisionLayer.TileWidth) { unit.X += pxRight; return; } //Get the coordinate of the forward-facing edge //If walking left, forwardEdge = left of bounding box //If walking right, forwardEdge = right of bounding box int forwardEdge = (pxRight > 0) ? unit.Right : unit.Left; //-1 for left, 1 for right int xDirection = pxRight / Math.Abs(pxRight); int startCol = forwardEdge / _collisionLayer.TileWidth; int endCol = (forwardEdge + pxRight) / _collisionLayer.TileWidth; startCol = (int)MathHelper.Clamp(startCol, 0, _collisionLayer.LayerWidth - 1); endCol = (int)MathHelper.Clamp(endCol, 0, _collisionLayer.LayerWidth - 1); unit.X += pxRight; for (int col = startCol; col != (endCol + xDirection); col = col + xDirection) { for (int row = unit.Top / _collisionLayer.TileHeight; row <= (unit.Bottom - 1) / _collisionLayer.TileHeight; row++) { if (!_collisionLayer.IsValidTileLocation(col, row)) { continue; } //pickup checks if (unit == _gino && _pickupLayer.Tiles[col, row] != null) { if (_pickupLayer.Tiles[col, row].TileIndexProperties.ContainsKey("PickupType")) { getPickup(_pickupLayer.Tiles[col, row].TileIndexProperties["PickupType"], row, col); } } //check boundary collision for enemies if (_enemyLayer.IsValidTileLocation(col, row)) { if (_enemyLayer.Tiles[col, row] != null && _enemyLayer.Tiles[col, row].TileIndexProperties.ContainsKey("Name") && _enemyLayer.Tiles[col, row].TileIndexProperties["Name"] == "Bound") { unit.CollideWithObstacle(pxRight > 0 ? Direction.East : Direction.West); } } //within bounds -- check tile collision if (_collisionLayer.Tiles[col, row] != null && _collisionLayer.Tiles[col, row].TileIndex != 0) { if (pxRight > 0) { unit.CollideWithObstacle(Direction.East); unit.Right = col * _collisionLayer.TileWidth; } else { unit.CollideWithObstacle(Direction.West); unit.Left = (col + 1) * _collisionLayer.TileWidth; } break; //no need to check more } } } }