示例#1
0
        public override void UpdatePreview()
        {
            ITilemapToolEnvironment env         = this.Environment;
            IReadOnlyGrid <bool>    sourceShape = env.TileDrawSource.SourceShape;

            env.ActiveAreaOutlines.Clear();
            env.ActiveOrigin = new Point2(
                env.HoveredTile.X - sourceShape.Width / 2,
                env.HoveredTile.Y - sourceShape.Height / 2);
            if (sourceShape.Width > 0 && sourceShape.Height > 0)
            {
                env.ActiveArea.ResizeClear(sourceShape.Width, sourceShape.Height);
                for (int y = 0; y < sourceShape.Height; y++)
                {
                    for (int x = 0; x < sourceShape.Width; x++)
                    {
                        env.ActiveArea[x, y] = sourceShape[x, y];
                    }
                }
            }
            else
            {
                env.ActiveArea.ResizeClear(1, 1);
                env.ActiveArea[0, 0] = true;
            }
            env.SubmitActiveAreaChanges(true);
        }
示例#2
0
        public override void UpdatePreview()
        {
            ITilemapToolEnvironment env = this.Environment;

            env.ActiveAreaOutlines.Clear();
            env.ActiveOrigin = env.HoveredTile;
            env.ActiveArea.ResizeClear(0, 0);
            env.SubmitActiveAreaChanges(true);
        }
示例#3
0
        public override void UpdateActiveArea()
        {
            base.UpdateActiveArea();
            ITilemapToolEnvironment env = this.Environment;

            Point2 activeOrigin = env.ActiveOrigin;

            this.floodFill.GetFillArea(env.ActiveTilemap, activeOrigin, false, env.ActiveArea, ref activeOrigin);
            env.ActiveOrigin = activeOrigin;
            env.ActiveAreaOutlines.Clear();
            env.SubmitActiveAreaChanges(true);
        }
示例#4
0
        public override void UpdatePreview()
        {
            ITilemapToolEnvironment env = this.Environment;

            // Don't update flood fill when hovering a tile that's out of range of the tilemap
            if (env.HoveredTile.X < 0 ||
                env.HoveredTile.Y < 0 ||
                env.HoveredTile.X >= env.ActiveTilemap.Size.X ||
                env.HoveredTile.Y >= env.ActiveTilemap.Size.Y)
            {
                return;
            }

            // Don't update flood fill when still hovering the same tile
            if (env.ActiveOrigin == env.HoveredTile)
            {
                return;
            }

            // Don't update flood fill when still inside the previous flood fill area
            Point2 activeLocalHover = new Point2(
                env.HoveredTile.X - env.ActiveOrigin.X,
                env.HoveredTile.Y - env.ActiveOrigin.Y);
            bool hoverInsideActiveRect = (
                activeLocalHover.X >= 0 &&
                activeLocalHover.Y >= 0 &&
                activeLocalHover.X < env.ActiveArea.Width &&
                activeLocalHover.Y < env.ActiveArea.Height);
            bool hoverInsideActiveArea = (hoverInsideActiveRect && env.ActiveArea[activeLocalHover.X, activeLocalHover.Y]);

            if (hoverInsideActiveArea)
            {
                return;
            }

            // Run the flood fill algorithm
            Point2 activeOrigin = env.ActiveOrigin;
            bool   previewValid = this.floodFill.GetFillArea(env.ActiveTilemap, env.HoveredTile, true, env.ActiveArea, ref activeOrigin);

            env.ActiveOrigin = activeOrigin;
            if (!previewValid)
            {
                env.ActiveOrigin = env.HoveredTile;
                env.ActiveArea.ResizeClear(1, 1);
                env.ActiveArea[0, 0] = true;
            }
            env.ActiveAreaOutlines.Clear();
            env.SubmitActiveAreaChanges(previewValid);
        }
示例#5
0
        public override void UpdatePreview()
        {
            ITilemapToolEnvironment env = this.Environment;
            Point2 topLeft = new Point2(
                Math.Min(env.ActionBeginTile.X, env.HoveredTile.X),
                Math.Min(env.ActionBeginTile.Y, env.HoveredTile.Y));
            Point2 size = new Point2(
                1 + Math.Abs(env.ActionBeginTile.X - env.HoveredTile.X),
                1 + Math.Abs(env.ActionBeginTile.Y - env.HoveredTile.Y));

            // Don't update the rect when still using the same boundary size
            bool hoverInsideActiveArea = (env.ActiveOrigin == topLeft && env.ActiveArea.Width == size.X && env.ActiveArea.Height == size.Y);

            if (hoverInsideActiveArea)
            {
                return;
            }

            Vector2 radius = (Vector2)size * 0.5f;
            Vector2 offset = new Vector2(0.5f, 0.5f) - radius;

            // Adjust to receive nicer low-res shapes
            radius.X -= 0.1f;
            radius.Y -= 0.1f;

            env.ActiveOrigin = topLeft;
            env.ActiveArea.ResizeClear(size.X, size.Y);
            for (int y = 0; y < size.Y; y++)
            {
                for (int x = 0; x < size.X; x++)
                {
                    Vector2 relative = new Vector2(x, y) + offset;
                    env.ActiveArea[x, y] =
                        ((relative.X * relative.X) / (radius.X * radius.X)) +
                        ((relative.Y * relative.Y) / (radius.Y * radius.Y)) <= 1.0f;
                }
            }

            env.ActiveAreaOutlines.Clear();
            env.SubmitActiveAreaChanges(true);
        }
示例#6
0
        public override void UpdatePreview()
        {
            ITilemapToolEnvironment env = this.Environment;
            Point2 topLeft = new Point2(
                Math.Min(env.ActionBeginTile.X, env.HoveredTile.X),
                Math.Min(env.ActionBeginTile.Y, env.HoveredTile.Y));
            Point2 size = new Point2(
                1 + Math.Abs(env.ActionBeginTile.X - env.HoveredTile.X),
                1 + Math.Abs(env.ActionBeginTile.Y - env.HoveredTile.Y));

            // Don't update the rect when still using the same boundary size
            bool hoverInsideActiveArea = (env.ActiveOrigin == topLeft && env.ActiveArea.Width == size.X && env.ActiveArea.Height == size.Y);

            if (hoverInsideActiveArea)
            {
                return;
            }

            env.ActiveOrigin = topLeft;
            env.ActiveArea.ResizeClear(size.X, size.Y);
            env.ActiveArea.Fill(true, 0, 0, size.X, size.Y);

            // Manually define outlines in the trivial rect case
            Tileset tileset  = env.ActiveTilemap != null ? env.ActiveTilemap.Tileset.Res : null;
            Vector2 tileSize = tileset != null ? tileset.TileSize : Tileset.DefaultTileSize;

            env.ActiveAreaOutlines.Clear();
            env.ActiveAreaOutlines.Add(new Vector2[]
            {
                new Vector2(0, 0),
                new Vector2(tileSize.X * size.X, 0),
                new Vector2(tileSize.X * size.X, tileSize.Y * size.Y),
                new Vector2(0, tileSize.Y * size.Y),
                new Vector2(0, 0)                 // Close the loop
            });

            env.SubmitActiveAreaChanges(true);
        }
示例#7
0
        public override void UpdateAction()
        {
            base.UpdateAction();
            ITilemapToolEnvironment env = this.Environment;
            Grid <bool>             drawArea;
            Point2 drawPos;

            // Since the cursor might move faster than one tile per update, we'll need
            // to expand the previewed actived area along its line of movement.
            if (Math.Abs(this.lastHoveredTile.X - env.HoveredTile.X) > 1 ||
                Math.Abs(this.lastHoveredTile.Y - env.HoveredTile.Y) > 1)
            {
                Grid <bool> activeBrush = env.ActiveArea;
                Point2      brushOffset = new Point2(
                    env.ActiveOrigin.X - env.HoveredTile.X,
                    env.ActiveOrigin.Y - env.HoveredTile.Y);

                // We'll be using a temporary draw buffer to accumulate a mask for our line-filled
                // drawing operation.
                this.drawAreaBuffer.ResizeClear(
                    activeBrush.Width + MathF.Abs(env.HoveredTile.X - this.lastHoveredTile.X),
                    activeBrush.Height + MathF.Abs(env.HoveredTile.Y - this.lastHoveredTile.Y));
                drawArea = this.drawAreaBuffer;
                drawPos  = new Point2(
                    Math.Min(this.lastHoveredTile.X, env.HoveredTile.X) + brushOffset.X,
                    Math.Min(this.lastHoveredTile.Y, env.HoveredTile.Y) + brushOffset.Y);

                // Determine the vector of movement
                Vector2 tileMoveDelta  = (Vector2)env.HoveredTile - (Vector2)lastHoveredTile;
                Vector2 tileMoveDir    = tileMoveDelta.Normalized;
                Vector2 tileMoveNormal = tileMoveDir.PerpendicularRight;

                // Project the shape onto the perpendicular axis to that vector, so
                // we can determine brush line width.
                float minPosInMoveShape = 0.0f;
                float maxPosInMoveShape = 0.0f;
                for (int y = 0; y < activeBrush.Height; y++)
                {
                    for (int x = 0; x < activeBrush.Width; x++)
                    {
                        if (activeBrush[x, y])
                        {
                            Vector2 relativePos  = new Vector2(x, y) + brushOffset;
                            float   projectedPos = Vector2.Dot(tileMoveNormal, relativePos);
                            minPosInMoveShape = MathF.Min(minPosInMoveShape, projectedPos - 0.5f);
                            maxPosInMoveShape = MathF.Max(maxPosInMoveShape, projectedPos + 0.5f);
                        }
                    }
                }

                // Fill all the tiles that are within the "movement line"
                for (int y = 0; y < this.drawAreaBuffer.Height; y++)
                {
                    for (int x = 0; x < this.drawAreaBuffer.Width; x++)
                    {
                        Vector2 relativePos = new Vector2(x, y) + drawPos - this.lastHoveredTile;

                        float projectedWidthPos = Vector2.Dot(tileMoveNormal, relativePos);
                        if (projectedWidthPos < minPosInMoveShape)
                        {
                            continue;
                        }
                        if (projectedWidthPos > maxPosInMoveShape)
                        {
                            continue;
                        }

                        float projectedLengthPos = Vector2.Dot(tileMoveDir, relativePos);
                        if (projectedLengthPos < 0.0f)
                        {
                            continue;
                        }
                        if (projectedLengthPos > tileMoveDelta.Length)
                        {
                            continue;
                        }

                        this.drawAreaBuffer[x, y] = true;
                    }
                }

                // Insert the brush at the start of the line, i.e. the last position
                activeBrush.CopyTo(
                    this.drawAreaBuffer,
                    this.lastHoveredTile.X - drawPos.X + brushOffset.X,
                    this.lastHoveredTile.Y - drawPos.Y + brushOffset.Y);

                // Insert the brush at the end of the line, i.e. the current position
                activeBrush.CopyTo(
                    this.drawAreaBuffer,
                    env.ActiveOrigin.X - drawPos.X,
                    env.ActiveOrigin.Y - drawPos.Y);
            }
            // Otherwise, we can just draw exactly our movement brush
            else
            {
                drawArea = env.ActiveArea;
                drawPos  = env.ActiveOrigin;
            }

            // Perform a tile editing operation using the drawin area and position we calculated
            env.PerformEditTiles(
                EditTilemapActionType.DrawTile,
                env.ActiveTilemap,
                drawPos,
                drawArea,
                env.TileDrawSource,
                new Point2(
                    drawPos.X - env.ActionBeginTile.X,
                    drawPos.Y - env.ActionBeginTile.Y));
            this.lastHoveredTile = env.HoveredTile;
        }