diff --git a/DungeonShooting_Godot/src/framework/Grid.cs b/DungeonShooting_Godot/src/framework/Grid.cs deleted file mode 100644 index b73f989..0000000 --- a/DungeonShooting_Godot/src/framework/Grid.cs +++ /dev/null @@ -1,206 +0,0 @@ - -using System.Collections.Generic; -using Godot; - -/// -/// 网格数据结构, 通过 x 和 y 存储数据 -/// -public class Grid -{ - /// - /// 遍历网格数据回调 - /// - public delegate void EachGridCallback(int x, int y, T data); - - private readonly Dictionary> _map = new Dictionary>(); - - /// - /// 返回指定xy位置是否存在数据 - /// - public bool Contains(int x, int y) - { - if (_map.TryGetValue(x, out var value)) - { - return value.ContainsKey(y); - } - - return false; - } - - /// - /// 返回指定xy位置是否有数据 - /// - public bool Contains(Vector2I pos) - { - return Contains(pos.X, pos.Y); - } - - /// - /// 设置指定xy位置的数据 - /// - public void Set(int x, int y, T data) - { - if (_map.TryGetValue(x, out var value)) - { - value[y] = data; - } - else - { - value = new Dictionary(); - value.Add(y, data); - _map.Add(x, value); - } - } - - /// - /// 设置指定坐标的数据 - /// - public void Set(Vector2I pos, T data) - { - Set(pos.X, pos.Y, data); - } - - /// - /// 获取指定xy位置的数据 - /// - public T Get(int x, int y) - { - if (_map.TryGetValue(x, out var value)) - { - if (value.TryGetValue(y, out var v)) - { - return v; - } - } - - return default; - } - - /// - /// 获取指定坐标的数据 - /// - public T Get(Vector2I pos) - { - return Get(pos.X, pos.Y); - } - - /// - /// 移除指定xy位置存储的数据 - /// - public bool Remove(int x, int y) - { - if (_map.TryGetValue(x, out var value)) - { - return value.Remove(y); - } - - return false; - } - - /// - /// 往一个区域中填充指定的数据 - /// - /// 起点位置 - /// 区域大小 - /// 数据 - public void SetRect(Vector2I pos, Vector2I size, T data) - { - var x = pos.X; - var y = pos.Y; - for (var i = 0; i < size.X; i++) - { - for (var j = 0; j < size.Y; j++) - { - if (_map.TryGetValue(x + i, out var value)) - { - value[y + j] = data; - } - else - { - value = new Dictionary(); - value.Add(y + j, data); - _map.Add(x + i, value); - } - } - } - } - - /// - /// 移除指定区域数据 - /// - /// 起点位置 - /// 区域大小 - public void RemoveRect(Vector2I pos, Vector2I size) - { - var x = pos.X; - var y = pos.Y; - for (var i = 0; i < size.X; i++) - { - for (var j = 0; j < size.Y; j++) - { - if (_map.TryGetValue(x + i, out var value)) - { - value.Remove(y + j); - if (value.Count == 0) - { - _map.Remove(x + i); - } - } - } - } - } - - /// - /// 清除所有数据 - /// - public void Clear() - { - _map.Clear(); - } - - /// - /// 检测矩形区域内是否与其他数据有碰撞 - /// - /// 起点位置 - /// 区域大小 - public bool RectCollision(Vector2I pos, Vector2I size) - { - var x = pos.X; - var y = pos.Y; - var w = size.X; - var h = size.Y; - //先判断四个角 - if (Contains(x, y) || Contains(x + w - 1, y) || Contains(x, y + h - 1) || Contains(x + w - 1, y + h - 1)) - { - return true; - } - - //逐个点判断 - for (int i = 1; i < w; i++) - { - for (int j = 0; j < h; j++) - { - if (Contains(x + i, y + j)) - { - return true; - } - } - } - - return false; - } - - /// - /// 遍历网格数据 - /// - public void ForEach(EachGridCallback cb) - { - foreach (var pair1 in _map) - { - foreach (var pair2 in pair1.Value) - { - cb(pair1.Key, pair2.Key, pair2.Value); - } - } - } -} diff --git a/DungeonShooting_Godot/src/framework/InfiniteGrid.cs b/DungeonShooting_Godot/src/framework/InfiniteGrid.cs new file mode 100644 index 0000000..09b986f --- /dev/null +++ b/DungeonShooting_Godot/src/framework/InfiniteGrid.cs @@ -0,0 +1,206 @@ + +using System.Collections.Generic; +using Godot; + +/// +/// 无限大的网格数据结构, 通过 x 和 y 存储数据 +/// +public class InfiniteGrid +{ + /// + /// 遍历网格数据回调 + /// + public delegate void EachGridCallback(int x, int y, T data); + + private readonly Dictionary> _map = new Dictionary>(); + + /// + /// 返回指定xy位置是否存在数据 + /// + public bool Contains(int x, int y) + { + if (_map.TryGetValue(x, out var value)) + { + return value.ContainsKey(y); + } + + return false; + } + + /// + /// 返回指定xy位置是否有数据 + /// + public bool Contains(Vector2I pos) + { + return Contains(pos.X, pos.Y); + } + + /// + /// 设置指定xy位置的数据 + /// + public void Set(int x, int y, T data) + { + if (_map.TryGetValue(x, out var value)) + { + value[y] = data; + } + else + { + value = new Dictionary(); + value.Add(y, data); + _map.Add(x, value); + } + } + + /// + /// 设置指定坐标的数据 + /// + public void Set(Vector2I pos, T data) + { + Set(pos.X, pos.Y, data); + } + + /// + /// 获取指定xy位置的数据 + /// + public T Get(int x, int y) + { + if (_map.TryGetValue(x, out var value)) + { + if (value.TryGetValue(y, out var v)) + { + return v; + } + } + + return default; + } + + /// + /// 获取指定坐标的数据 + /// + public T Get(Vector2I pos) + { + return Get(pos.X, pos.Y); + } + + /// + /// 移除指定xy位置存储的数据 + /// + public bool Remove(int x, int y) + { + if (_map.TryGetValue(x, out var value)) + { + return value.Remove(y); + } + + return false; + } + + /// + /// 往一个区域中填充指定的数据 + /// + /// 起点位置 + /// 区域大小 + /// 数据 + public void SetRect(Vector2I pos, Vector2I size, T data) + { + var x = pos.X; + var y = pos.Y; + for (var i = 0; i < size.X; i++) + { + for (var j = 0; j < size.Y; j++) + { + if (_map.TryGetValue(x + i, out var value)) + { + value[y + j] = data; + } + else + { + value = new Dictionary(); + value.Add(y + j, data); + _map.Add(x + i, value); + } + } + } + } + + /// + /// 移除指定区域数据 + /// + /// 起点位置 + /// 区域大小 + public void RemoveRect(Vector2I pos, Vector2I size) + { + var x = pos.X; + var y = pos.Y; + for (var i = 0; i < size.X; i++) + { + for (var j = 0; j < size.Y; j++) + { + if (_map.TryGetValue(x + i, out var value)) + { + value.Remove(y + j); + if (value.Count == 0) + { + _map.Remove(x + i); + } + } + } + } + } + + /// + /// 清除所有数据 + /// + public void Clear() + { + _map.Clear(); + } + + /// + /// 检测矩形区域内是否与其他数据有碰撞 + /// + /// 起点位置 + /// 区域大小 + public bool RectCollision(Vector2I pos, Vector2I size) + { + var x = pos.X; + var y = pos.Y; + var w = size.X; + var h = size.Y; + //先判断四个角 + if (Contains(x, y) || Contains(x + w - 1, y) || Contains(x, y + h - 1) || Contains(x + w - 1, y + h - 1)) + { + return true; + } + + //逐个点判断 + for (int i = 1; i < w; i++) + { + for (int j = 0; j < h; j++) + { + if (Contains(x + i, y + j)) + { + return true; + } + } + } + + return false; + } + + /// + /// 遍历网格数据 + /// + public void ForEach(EachGridCallback cb) + { + foreach (var pair1 in _map) + { + foreach (var pair2 in pair1.Value) + { + cb(pair1.Key, pair2.Key, pair2.Value); + } + } + } +} diff --git a/DungeonShooting_Godot/src/framework/map/DungeonGenerator.cs b/DungeonShooting_Godot/src/framework/map/DungeonGenerator.cs index ff9605b..7047dfa 100644 --- a/DungeonShooting_Godot/src/framework/map/DungeonGenerator.cs +++ b/DungeonShooting_Godot/src/framework/map/DungeonGenerator.cs @@ -35,7 +35,7 @@ private SeedRandom _random; //用于标记地图上的坐标是否被占用 - private Grid _roomGrid { get; } = new Grid(); + private InfiniteGrid _roomGrid { get; } = new InfiniteGrid(); //当前房间数量 private int _count = 0; diff --git a/DungeonShooting_Godot/src/framework/map/image/RoomStaticSprite.cs b/DungeonShooting_Godot/src/framework/map/image/RoomStaticSprite.cs index 8eeb2bb..9c62cfe 100644 --- a/DungeonShooting_Godot/src/framework/map/image/RoomStaticSprite.cs +++ b/DungeonShooting_Godot/src/framework/map/image/RoomStaticSprite.cs @@ -11,7 +11,7 @@ public bool IsDestroyed { get; private set; } private readonly List> _list = new List>(); - private readonly Grid> _grid = new Grid>(); + private readonly InfiniteGrid> _grid = new InfiniteGrid>(); private readonly RoomInfo _roomInfo; //网格划分的格子大小 private readonly Vector2I _step; diff --git a/DungeonShooting_Godot/src/game/ui/mapEditor/tileView/EditorTileMap.cs b/DungeonShooting_Godot/src/game/ui/mapEditor/tileView/EditorTileMap.cs index 50c9957..205f45e 100644 --- a/DungeonShooting_Godot/src/game/ui/mapEditor/tileView/EditorTileMap.cs +++ b/DungeonShooting_Godot/src/game/ui/mapEditor/tileView/EditorTileMap.cs @@ -97,7 +97,7 @@ //绘制填充区域 private bool _drawFullRect = false; //负责存储自动图块数据 - private Grid _autoCellLayerGrid = new Grid(); + private InfiniteGrid _autoCellLayerGrid = new InfiniteGrid(); //用于生成导航网格 private DungeonTileMap _dungeonTileMap; //停止绘制多久后开始执行生成操作 diff --git a/DungeonShooting_Godot/src/test/TestGridData.cs b/DungeonShooting_Godot/src/test/TestGridData.cs index b7db7cb..6049363 100644 --- a/DungeonShooting_Godot/src/test/TestGridData.cs +++ b/DungeonShooting_Godot/src/test/TestGridData.cs @@ -57,7 +57,7 @@ Debug.Log("TestGrid设置值用时: " + (DateTime.Now - time).Milliseconds); time = DateTime.Now; - var testGrid2 = new Grid(); + var testGrid2 = new InfiniteGrid(); for (int i = 0; i < 1000; i++) { for (int j = 0; j < 1000; j++) diff --git a/DungeonShooting_Godot/src/test/TestMask2.cs b/DungeonShooting_Godot/src/test/TestMask2.cs index 635d792..458d712 100644 --- a/DungeonShooting_Godot/src/test/TestMask2.cs +++ b/DungeonShooting_Godot/src/test/TestMask2.cs @@ -44,6 +44,15 @@ public int Y; public Color Color; } + + public class ImagePixel + { + public int X; + public int Y; + public Color Color; + public byte Type; + public float Speed; + } [Export] public Sprite2D Canvas; @@ -52,14 +61,15 @@ public Texture2D Brush1; [Export] public Texture2D Brush2; - - private Grid _grid = new Grid(); private ImageData _brushData1; private ImageData _brushData2; private Image _image; private ImageTexture _texture; + private ImagePixel[,] _imagePixels; + private List _cacheImagePixels = new List(); + public override void _Ready() { _brushData1 = new ImageData(Brush1.GetImage()); @@ -67,20 +77,23 @@ _image = Image.Create(480, 270, false, Image.Format.Rgba8); _texture = ImageTexture.CreateFromImage(_image); Canvas.Texture = _texture; + _imagePixels = new ImagePixel[480, 270]; } public override void _Process(double delta) { + var newDelta = (float)delta; + var pos = (GetGlobalMousePosition() / 4).AsVector2I(); if (Input.IsActionPressed("fire")) { var time = DateTime.Now; - RunTest(_brushData1); + RunTest(_brushData1, pos, 4f); Debug.Log("用时: " + (DateTime.Now - time).TotalMilliseconds); } else if (Input.IsActionPressed("roll")) { var time = DateTime.Now; - RunTest(_brushData2); + RunTest(_brushData2, pos, 4f); Debug.Log("用时: " + (DateTime.Now - time).TotalMilliseconds); } @@ -97,11 +110,26 @@ _image.Fill(new Color(1, 1, 1, 0)); _texture.Update(_image); } + + if (Input.IsActionPressed("move_left")) + { + var time = DateTime.Now; + foreach (var imagePixel in _cacheImagePixels) + { + if (imagePixel.Color.A > 0) + { + imagePixel.Color.A -= imagePixel.Speed * newDelta; + _image.SetPixel(imagePixel.X, imagePixel.Y, imagePixel.Color); + } + } + Debug.Log("用时: " + (DateTime.Now - time).TotalMilliseconds + ", 数量: " + _cacheImagePixels.Count); + } + _texture.Update(_image); } - private void RunTest(ImageData brush) + private void RunTest(ImageData brush, Vector2I position, float time) { - var pos = (GetGlobalMousePosition() / 4 - new Vector2I(brush.Width, brush.Height) / 2).AsVector2I(); + var pos = position - new Vector2I(brush.Width, brush.Height) / 2; var canvasWidth = _texture.GetWidth(); var canvasHeight = _texture.GetHeight(); foreach (var brushPixel in brush.Pixels) @@ -111,8 +139,27 @@ if (x >= 0 && x < canvasWidth && y >= 0 && y < canvasHeight) { _image.SetPixel(x, y, brushPixel.Color); + var temp = _imagePixels[x, y]; + if (temp == null) + { + temp = new ImagePixel() + { + X = x, + Y = y, + Color = brushPixel.Color, + Type = 0, + Speed = brushPixel.Color.A / time, + }; + _imagePixels[x, y] = temp; + + _cacheImagePixels.Add(temp); + } + else + { + temp.Color = brushPixel.Color; + temp.Speed = brushPixel.Color.A / time; + } } } - _texture.Update(_image); } }