//----------------------------------------------------------------------------- // Constructors //----------------------------------------------------------------------------- public CollisionModel(params Rectangle2I[] boxes) { this.bounds = Rectangle2I.Zero; this.boxes = new List <Rectangle2I>(); this.boxes.AddRange(boxes); CalcBounds(); }
//----------------------------------------------------------------------------- // Constructors //----------------------------------------------------------------------------- public CollisionModel(params Rectangle2I[] boxes) { this.bounds = Rectangle2I.Zero; this.boxes = new List<Rectangle2I>(); this.boxes.AddRange(boxes); CalcBounds(); }
//----------------------------------------------------------------------------- // Constructor //----------------------------------------------------------------------------- public PlayerSpinSwordState() { limitTilesToDirection = false; isReswingable = false; lunge = false; swingAnglePullBack = 0; swingAngleDurations = new int[] { 3, 2, 3, 2, 3, 2, 3, 2, 5 }; weaponSwingAnimation = GameData.ANIM_SWORD_SPIN; playerSwingAnimation = GameData.ANIM_PLAYER_SPIN; // Will always spin clockwise. swingWindingOrders = new WindingOrder[] { WindingOrder.Clockwise, WindingOrder.Clockwise, WindingOrder.Clockwise, WindingOrder.Clockwise }; swingCollisionBoxesNoLunge = new Rectangle2I[4, 9]; for (int i = 0; i < 4; i++) { for (int j = 0; j < 9; j++) { int angle = GMath.Wrap((i * 2) - j, Angles.AngleCount); swingCollisionBoxesNoLunge[i, j] = SWING_TOOL_BOXES_SPIN[angle]; } } }
//----------------------------------------------------------------------------- // Constructors //----------------------------------------------------------------------------- // Use Tile.CreateTile() instead of this constructor. protected Tile() { tileGridArea = Rectangle2I.Zero; isAlive = false; isInitialized = false; location = Point2I.Zero; layer = 0; offset = Point2I.Zero; size = Point2I.One; spriteAsObject = new SpriteAnimation(); isSolid = false; isMoving = false; pushDelay = 20; properties = new Properties(this); tileData = null; moveDirection = Point2I.Zero; dropList = null; hasMoved = false; path = null; pathTimer = 0; pathMoveIndex = 0; fallsInHoles = true; soundMove = GameData.SOUND_BLOCK_PUSH; conveyorVelocity = Vector2F.Zero; surfaceTile = null; collisionStyle = CollisionStyle.Rectangular; graphics = new TileGraphicsComponent(this); }
public Sprite(Image image, Rectangle2I sourceRect, Point2I drawOffset) { this.image = image; this.sourceRect = sourceRect; this.drawOffset = drawOffset; this.nextPart = null; }
//----------------------------------------------------------------------------- // Constructors //----------------------------------------------------------------------------- public Sprite() { this.image = null; this.sourceRect = Rectangle2I.Zero; this.drawOffset = Point2I.Zero; this.nextPart = null; }
public CollisionModel(CollisionModel copy) { bounds = Rectangle2I.Zero; boxes = new List<Rectangle2I>(); for (int i = 0; i < copy.boxes.Count; ++i) boxes.Add(copy.boxes[i]); }
// Returns true if this rectangle intersects another. public bool Intersects(Rectangle2I other) { if (IsEmpty && other.IsEmpty) { return(false); } return(!(other.Left - Right >= 0 || other.Top - Bottom >= 0 || Left - other.Right >= 0 || Top - other.Bottom >= 0)); }
// Returns true if the specified rectangle is inside this rectangle. public bool Contains(Rectangle2I rect) { if (IsEmpty || rect.IsEmpty) { return(false); } return((rect.Min >= Min) && (rect.Max <= Max)); }
// Creates a new rectangle that exactly contains two other rectangles. public static Rectangle2I Union(Rectangle2I r1, Rectangle2I r2) { int x1 = Math.Min(r1.Left, r2.Left); int y1 = Math.Min(r1.Top, r2.Top); int x2 = Math.Max(r1.Right, r2.Right); int y2 = Math.Max(r1.Bottom, r2.Bottom); return(new Rectangle2I(x1, y1, x2 - x1, y2 - y1)); }
public CollisionModel(CollisionModel copy) { bounds = Rectangle2I.Zero; boxes = new List <Rectangle2I>(); for (int i = 0; i < copy.boxes.Count; ++i) { boxes.Add(copy.boxes[i]); } }
//----------------------------------------------------------------------------- // Constructors //----------------------------------------------------------------------------- public EventTile() { roomControl = null; eventData = null; position = Vector2F.Zero; size = Point2I.One; properties = new Properties(); collisionBox = new Rectangle2I(0, 0, 16, 16); }
/** <summary> Returns true if the specified rectangle is colliding with this rectangle. </summary> */ public bool Colliding(Rectangle2I rect) { if (IsEmpty || rect.IsEmpty) { return(false); } return((rect.Min < Max) && (rect.Max > Min)); }
//----------------------------------------------------------------------------- // Static Methods //----------------------------------------------------------------------------- // Clamp is exclusive. public static Point2I Clamp(Point2I value, Rectangle2I bounds) { if (bounds.IsEmpty) { return(Point2I.Zero); } return(new Point2I( GMath.Clamp(value.X, bounds.Min.X, bounds.Max.X - 1), GMath.Clamp(value.Y, bounds.Min.Y, bounds.Max.Y - 1))); }
//----------------------------------------------------------------------------- // Drawing //----------------------------------------------------------------------------- // Draws the HUD. public void Draw(Graphics2D g, bool light) { int lightDark = (light ? GameData.VARIANT_LIGHT : GameData.VARIANT_DARK); Rectangle2I r = new Rectangle2I(0, 0, GameSettings.SCREEN_WIDTH, 16); g.DrawSprite(GameData.SPR_HUD_BACKGROUND, lightDark, r); DrawItems(g, lightDark); DrawRupees(g, lightDark); DrawHearts(g, lightDark); }
//----------------------------------------------------------------------------- // Constructor //----------------------------------------------------------------------------- public UnitTool() { unit = null; drawAboveUnit = false; animationPlayer = new AnimationPlayer(); collisionBox = new Rectangle2I(-1, -1, 2, 2); toolType = UnitToolType.Visual; isEquipped = false; isPhysicsEnabled = true; imageVariantID = GameData.VARIANT_NONE; syncAnimationWithDirection = true; }
//----------------------------------------------------------------------------- // Static methods //----------------------------------------------------------------------------- // Return the intersection between two rectangles. // Returns the Empty rect if there is no intersection. public static Rectangle2I Intersect(Rectangle2I r1, Rectangle2I r2) { int x1 = Math.Max(r1.Left, r2.Left); int y1 = Math.Max(r1.Top, r2.Top); int x2 = Math.Min(r1.Right, r2.Right); int y2 = Math.Min(r1.Bottom, r2.Bottom); if (x2 > x1 && y2 > y1) { return(new Rectangle2I(x1, y1, x2 - x1, y2 - y1)); } return(Rectangle2I.Zero); }
public Sprite(SpriteSheet sheet, Point2I index, Point2I drawOffset) { this.image = sheet.Image; this.sourceRect = new Rectangle2I( sheet.Offset.X + (index.X * (sheet.CellSize.X + sheet.Spacing.X)), sheet.Offset.Y + (index.Y * (sheet.CellSize.Y + sheet.Spacing.Y)), sheet.CellSize.X, sheet.CellSize.Y ); this.drawOffset = new Point2I(drawOffset.X, drawOffset.Y); this.image = sheet.Image; this.nextPart = null; }
//----------------------------------------------------------------------------- // Internal //----------------------------------------------------------------------------- // Calculate the bounds rectangle that contains all the boxes. private void CalcBounds() { if (boxes.Count == 0) { bounds = Rectangle2I.Zero; return; } bounds = boxes[0]; for (int i = 1; i < boxes.Count; ++i) { bounds = Rectangle2I.Union(bounds, boxes[i]); } }
//----------------------------------------------------------------------------- // Overridden Methods //----------------------------------------------------------------------------- protected override void Initialize() { base.Initialize(); solutionReferenceArea = new Rectangle2I(3, 4, 3, 3); solutionArea = new Rectangle2I(9, 4, 3, 3); CreateSolutionReference(); /*solution = new PuzzleColor[3, 3] { { PuzzleColor.Red, PuzzleColor.Red, PuzzleColor.Red }, { PuzzleColor.Yellow, PuzzleColor.Red, PuzzleColor.Red }, { PuzzleColor.Blue, PuzzleColor.Red, PuzzleColor.Red }, };*/ hasBeenSolvedAlready = false; isSolved = false; }
// Remove all tiles within the given area. public void RemoveArea(Rectangle2I area) { BaseTileDataInstance[] tiles = GetTilesInArea(area).ToArray(); foreach (BaseTileDataInstance tile in tiles) { tile.Room.Remove(tile); } }
//----------------------------------------------------------------------------- // Internal Iteration //----------------------------------------------------------------------------- private IEnumerable<BaseTileDataInstance> GetTilesInArea(Rectangle2I area) { // Make sure the area is within the level bounds. area = Rectangle2I.Intersect(area, new Rectangle2I(Point2I.Zero, roomSize * dimensions)); // Iterate the tile grid. for (int x = 0; x < area.Width; x++) { for (int y = 0; y < area.Height; y++) { LevelTileCoord coord = (LevelTileCoord) (area.Point + new Point2I(x, y)); Room room = GetRoom(coord); if (room != null) { Point2I tileLocation = GetTileLocation(coord); for (int i = 0; i < roomLayerCount; i++) { TileDataInstance tile = room.GetTile(tileLocation, i); if (tile != null && tile.Location == tileLocation) yield return tile; } } } } // Determine the collection of rooms that will contain the event tiles. Point2I roomAreaMin = GetRoomLocation((LevelTileCoord) area.Min); Point2I roomAreaMax = GetRoomLocation((LevelTileCoord) area.Max); Rectangle2I roomArea = new Rectangle2I(roomAreaMin, roomAreaMax - roomAreaMin + Point2I.One); roomArea = Rectangle2I.Intersect(roomArea, new Rectangle2I(Point2I.Zero, dimensions)); Rectangle2I pixelArea = new Rectangle2I( area.Point * GameSettings.TILE_SIZE, area.Size * GameSettings.TILE_SIZE); // Iterate event tiles. for (int x = roomArea.Left; x < roomArea.Right; x++) { for (int y = roomArea.Top; y < roomArea.Bottom; y++) { Room room = rooms[x, y]; for (int i = 0; i < room.EventData.Count; i++) { EventTileDataInstance eventTile = room.EventData[i]; Rectangle2I tileBounds = eventTile.GetBounds(); tileBounds.Point += room.Location * roomSize * GameSettings.TILE_SIZE; if (pixelArea.Contains(tileBounds.Point)) yield return eventTile; } } } }
// Take tiles from the level (or duplicate them) and put them into a tile grid. public TileGrid CreateTileGrid(Rectangle2I area, bool duplicate) { TileGrid tileGrid = new TileGrid(area.Size, roomLayerCount); BaseTileDataInstance[] tiles = GetTilesInArea(area).ToArray(); foreach (BaseTileDataInstance baseTileOriginal in tiles) { // Duplicate the tile if specified, else remove the original. BaseTileDataInstance baseTile; if (duplicate) { baseTile = baseTileOriginal.Duplicate(); } else { baseTile = baseTileOriginal; baseTileOriginal.Room.Remove(baseTileOriginal); } // Add the tile to the tile grid. if (baseTile is TileDataInstance) { TileDataInstance tile = (TileDataInstance) baseTile; tile.Location += tile.Room.Location * roomSize; tile.Location -= area.Point; tileGrid.PlaceTile(tile, tile.Location, tile.Layer); } else if (baseTile is EventTileDataInstance) { EventTileDataInstance eventTile = (EventTileDataInstance) baseTile; eventTile.Position += eventTile.Room.Location * roomSize * GameSettings.TILE_SIZE; eventTile.Position -= area.Point * GameSettings.TILE_SIZE; tileGrid.AddEventTile(eventTile); } } return tileGrid; }
// Place the tiles in a tile grid starting at the given location. public void PlaceTileGrid(TileGrid tileGrid, LevelTileCoord location) { // Remove tiles. Rectangle2I area = new Rectangle2I((Point2I) location, tileGrid.Size); RemoveArea(area); // Place tiles. foreach (BaseTileDataInstance baseTile in tileGrid.GetTiles()) { if (baseTile is TileDataInstance) { TileDataInstance tile = (TileDataInstance) baseTile; LevelTileCoord coord = (LevelTileCoord) ((Point2I) location + tile.Location); Room room = GetRoom(coord); if (room != null) { tile.Location = GetTileLocation(coord); room.PlaceTile(tile, tile.Location, tile.Layer); } } else if (baseTile is EventTileDataInstance) { EventTileDataInstance eventTile = (EventTileDataInstance) baseTile; eventTile.Position += (Point2I) location * GameSettings.TILE_SIZE; Point2I roomLocation = eventTile.Position / (roomSize * GameSettings.TILE_SIZE); Room room = GetRoomAt(roomLocation); if (room != null) { eventTile.Position -= roomLocation * roomSize * GameSettings.TILE_SIZE; room.AddEventTile(eventTile); } } } }
public AnimationFrame(int startTime, int duration, Image image, Rectangle2I sourceRect, Point2I drawOffset) { this.startTime = startTime; this.duration = duration; this.sprite = new Sprite(image, sourceRect, drawOffset); }
// Take tiles from the level and put them into a tile grid. public TileGrid CreateTileGrid(Rectangle2I area) { return CreateTileGrid(area, false); }
/** <summary> Constructs a copy of the specified rectangle. </summary> */ public Rectangle2I(Rectangle2I r) { this.Point = r.Point; this.Size = r.Size; }
//----------------------------------------------------------------------------- // Mutators //----------------------------------------------------------------------------- // Add a new box to the collision model. public CollisionModel AddBox(Rectangle2I box) { boxes.Add(box); CalcBounds(); return(this); }
/** <summary> Returns true if the specified rectangle is colliding with this rectangle. </summary> */ public bool Colliding(Rectangle2I rect) { if (IsEmpty || rect.IsEmpty) return false; return ((rect.Min < Max) && (rect.Max > Min)); }
// Returns true if the specified rectangle is inside this rectangle. public bool Contains(Rectangle2I rect) { if (IsEmpty || rect.IsEmpty) return false; return ((rect.Min >= Min) && (rect.Max <= Max)); }
// Creates a new rectangle that exactly contains two other rectangles. public static Rectangle2I Union(Rectangle2I r1, Rectangle2I r2) { int x1 = Math.Min(r1.Left, r2.Left); int y1 = Math.Min(r1.Top, r2.Top); int x2 = Math.Max(r1.Right, r2.Right); int y2 = Math.Max(r1.Bottom, r2.Bottom); return new Rectangle2I(x1, y1, x2 - x1, y2 - y1); }
//----------------------------------------------------------------------------- // Static methods //----------------------------------------------------------------------------- // Return the intersection between two rectangles. // Returns the Empty rect if there is no intersection. public static Rectangle2I Intersect(Rectangle2I r1, Rectangle2I r2) { int x1 = Math.Max(r1.Left, r2.Left); int y1 = Math.Max(r1.Top, r2.Top); int x2 = Math.Min(r1.Right, r2.Right); int y2 = Math.Min(r1.Bottom, r2.Bottom); if (x2 > x1 && y2 > y1) return new Rectangle2I(x1, y1, x2 - x1, y2 - y1); return Rectangle2I.Zero; }
//----------------------------------------------------------------------------- // Overridden methods //----------------------------------------------------------------------------- protected override void Initialize() { base.Initialize(); string typeName = Properties.GetString("warp_type", "Tunnel"); warpType = WarpType.Tunnel; if (typeName == "tunnel") warpType = WarpType.Tunnel; else if (typeName == "entrance") warpType = WarpType.Entrance; else if (typeName == "stairs") warpType = WarpType.Stairs; collisionBox = new Rectangle2I(2, 6, 12, 12); warpEnabled = !IsTouchingPlayer(); }
public void SetSelectionGridArea(Rectangle2I area, Level level) { PlaceSelectionGrid(); selectionGridArea = area; selectionGridLevel = level; SetSelectionBox(selectionGridArea.Point * GameSettings.TILE_SIZE, selectionGridArea.Size * GameSettings.TILE_SIZE); }
// Draw an event tile. private void DrawEventTile(Graphics2D g, EventTileDataInstance eventTile, Point2I position, Color drawColor) { SpriteAnimation spr = eventTile.CurrentSprite; int imageVariantID = eventTile.Properties.GetInteger("image_variant"); if (imageVariantID < 0) imageVariantID = eventTile.Room.Zone.ImageVariantID; // Select different sprites for certain events. if (eventTile.Type == typeof(NPCEvent)) { eventTile.SubStripIndex = eventTile.Properties.GetInteger("direction", 0); } else if (eventTile.Type == typeof(WarpEvent)) { string warpTypeStr = eventTile.Properties.GetString("warp_type", "tunnel"); WarpType warpType = (WarpType) Enum.Parse(typeof(WarpType), warpTypeStr, true); if (warpType == WarpType.Entrance) spr = GameData.SPR_EVENT_TILE_WARP_ENTRANCE; else if (warpType == WarpType.Tunnel) spr = GameData.SPR_EVENT_TILE_WARP_TUNNEL; else if (warpType == WarpType.Stairs) spr = GameData.SPR_EVENT_TILE_WARP_STAIRS; } // Draw the sprite. if (!spr.IsNull) { g.DrawAnimation(spr, imageVariantID, editorControl.Ticks, position, drawColor); } else { Rectangle2I r = new Rectangle2I(position, eventTile.Size * GameSettings.TILE_SIZE); g.FillRectangle(r, Color.Blue); } }
public void SetSelectionGrid(TileGrid tileGrid, Point2I location, Level level) { PlaceSelectionGrid(); selectionGridArea = new Rectangle2I(location, tileGrid.Size); selectionGridLevel = level; selectionGrid = tileGrid; SetSelectionBox(selectionGridArea.Point * GameSettings.TILE_SIZE, selectionGridArea.Size * GameSettings.TILE_SIZE); }
//----------------------------------------------------------------------------- // Overridden methods //----------------------------------------------------------------------------- public override void OnInitialize() { base.OnInitialize(); direction = Properties.GetInteger("direction", Directions.Down); extendLength = 0.0f; isBeingPulled = false; SetLength(0.0f); CollisionStyle = CollisionStyle.Circular; IsSolid = true; ClingWhenStabbed = false; SolidType = TileSolidType.HalfSolid; Rectangle2I collisionBox = new Rectangle2I(4, 4, 8, 8); collisionBox.ExtendEdge(direction, 5); CollisionModel = new CollisionModel(collisionBox); if (direction == Directions.Right) Graphics.PlaySprite(GameData.SPR_TILE_PULL_HANDLE_RIGHT); else if (direction == Directions.Up) Graphics.PlaySprite(GameData.SPR_TILE_PULL_HANDLE_UP); else if (direction == Directions.Left) Graphics.PlaySprite(GameData.SPR_TILE_PULL_HANDLE_LEFT); else if (direction == Directions.Down) Graphics.PlaySprite(GameData.SPR_TILE_PULL_HANDLE_DOWN); }
// Return an enumerable list of tiles contained within the given tile grid area. public IEnumerable<Tile> GetTilesInArea(Rectangle2I area, TileLayerOrder layerOrder = TileLayerOrder.LowestToHighest) { Rectangle2I clippedArea = Rectangle2I.Intersect(area, new Rectangle2I(Point2I.Zero, gridDimensions)); foreach (int i in GetLayers(layerOrder)) { for (int y = clippedArea.Top; y < clippedArea.Bottom; y++) { for (int x = clippedArea.Left; x < clippedArea.Right; x++) { Tile tile = tiles[x, y, i]; if (tile != null) { Point2I loc = tile.TileGridArea.Point; if (!clippedArea.Contains(loc)) loc = Point2I.Clamp(loc, clippedArea); if (x == loc.X && y == loc.Y) yield return tile; } } } } }
// Return the highest surface tile at the given position. public Tile GetSurfaceTileAtPosition(Vector2F position, bool includePlatforms = false) { // Because tiles may have moved this frame, we need to check a 3x3 area. Point2I location = GetTileLocation(position); Rectangle2I area = new Rectangle2I(location, Point2I.One); area.Inflate(1, 1); foreach (Tile tile in GetTilesInArea(area, TileLayerOrder.HighestToLowest)) { Rectangle2F tileBounds = tile.Bounds; tileBounds.Point -= tile.Velocity; if (tileBounds.Contains(position) && (tile.IsSurface || (includePlatforms && tile.IsPlatform))) return tile; } return null; }
//----------------------------------------------------------------------------- // Overridden methods //----------------------------------------------------------------------------- protected override void Initialize() { base.Initialize(); string typeName = Properties.GetString("warp_type", "Tunnel"); warpType = (WarpType) Enum.Parse(typeof(WarpType), typeName, true); collisionBox = new Rectangle2I(2, 6, 12, 12); warpEnabled = !IsTouchingPlayer(); // Find the closest room edge. edgeDirection = -1; Rectangle2I roomBounds = RoomControl.RoomBounds; Rectangle2I myBox = new Rectangle2I((int) position.X, (int) position.Y, 16, 16); int minDist = -1; for (int dir = 0; dir < 4; dir++) { int dist = Math.Abs(myBox.GetEdge(dir) - roomBounds.GetEdge(dir)); if (dist < minDist || minDist < 0) { edgeDirection = dir; minDist = dist; } } // Make sure we know if the player respawns on top of this warp point. RoomControl.PlayerRespawn += delegate(Player player) { warpEnabled = !IsTouchingPlayer(); }; // For entrance warp points, intercept room transitions in order to warp. RoomControl.RoomTransitioning += delegate(int direction) { if (warpType == WarpType.Entrance && direction == edgeDirection && IsTouchingPlayer()) { RoomControl.CancelRoomTransition(); Warp(direction); } }; }