diff --git a/DungeonShooting_Godot/resource/map/tileMaps/testGroup/inlet/Room1.tscn b/DungeonShooting_Godot/resource/map/tileMaps/testGroup/inlet/Room1.tscn index e5f1518..0d8c452 100644 --- a/DungeonShooting_Godot/resource/map/tileMaps/testGroup/inlet/Room1.tscn +++ b/DungeonShooting_Godot/resource/map/tileMaps/testGroup/inlet/Room1.tscn @@ -3,7 +3,7 @@ [ext_resource type="TileSet" uid="uid://b00g22o1cqhe8" path="res://resource/map/tileset/TileSet1.tres" id="1_osa3n"] [ext_resource type="Script" path="res://src/framework/map/DungeonRoomTemplate.cs" id="2_erhdx"] [ext_resource type="Script" path="res://src/framework/map/mark/ActivityMark.cs" id="3_m4jrh"] -[ext_resource type="Texture2D" uid="uid://bu0b11hiuecxy" path="res://resource/sprite/bullet/bullet.png" id="4_d1cfc"] +[ext_resource type="Texture2D" uid="uid://civvcowt2wklr" path="res://resource/sprite/weapon/weapon0001/Weapon0001.png" id="4_wtntr"] [node name="Room1" type="TileMap"] tile_set = ExtResource("1_osa3n") @@ -54,5 +54,5 @@ [node name="Sprite2D" type="Sprite2D" parent="."] position = Vector2(61, 25) -rotation = 0.523599 -texture = ExtResource("4_d1cfc") +rotation = 5.23599 +texture = ExtResource("4_wtntr") diff --git a/DungeonShooting_Godot/src/framework/map/image/ImageCanvas.cs b/DungeonShooting_Godot/src/framework/map/image/ImageCanvas.cs index 3470adb..5a1d349 100644 --- a/DungeonShooting_Godot/src/framework/map/image/ImageCanvas.cs +++ b/DungeonShooting_Godot/src/framework/map/image/ImageCanvas.cs @@ -13,44 +13,62 @@ { Width = width; Height = height; - + _canvas = Image.Create(width, height, false, Image.Format.Rgba8); + + _canvas.Fill(Colors.Gray); + var w = _canvas.GetWidth(); + var h = _canvas.GetHeight(); + for (int i = 0; i < w; i++) + { + _canvas.SetPixel(i, h / 2, Colors.Green); + } + + for (int j = 0; j < h; j++) + { + _canvas.SetPixel(w / 2, j, Colors.Green); + } } public override void _Ready() { + Centered = false; + var imageTexture = ImageTexture.CreateFromImage(_canvas); Texture = imageTexture; } - + public void DrawImageInCanvas(Texture2D texture, int x, int y, float angle, int centerX, int centerY, bool flipY) { var image = texture.GetImage(); + if (flipY) + { + image.FlipY(); + } + var newAngle = Mathf.RoundToInt(Utils.ConvertAngle(angle)); if (newAngle == 0) //原图, 直接画上去 { - //_canvas.BlitRectMask(); + _canvas.BlitRect(image, new Rect2I(0, 0, image.GetWidth(), image.GetHeight()), + new Vector2I(x - centerX, y - centerY)); } - else if (newAngle == 90) //旋转90度 + else //其他角度 { - - } - else if (newAngle == 180) //旋转180度 - { - - } - else if (newAngle == 270) //旋转270度 - { - - } - else - { - + if (newAngle <= 180) + { + DrawRotateImage(image, x, y, newAngle, centerX, centerY); + } + else + { + image.FlipX(); + image.FlipY(); + DrawRotateImage(image, x, y, (newAngle - 180), image.GetWidth() - centerX - 1, image.GetHeight() - centerY - 1); + } } } - - private void DrawRotateImage(Image origin, Image canvas, int x, int y, int angle, int centerX, int centerY) + + private void DrawRotateImage(Image origin, int x, int y, int angle, int centerX, int centerY) { var rotation = Mathf.DegToRad(angle); var width = origin.GetWidth(); @@ -58,12 +76,18 @@ var cosAngle = Mathf.Cos(rotation); var sinAngle = Mathf.Sin(rotation); + if (cosAngle == 0) + { + cosAngle = 1e-6f; + } - var newWidth = width * Mathf.Abs(cosAngle) + height * sinAngle; - var newHeight = width * sinAngle + height * Mathf.Abs(cosAngle); + if (sinAngle == 0) + { + sinAngle = 1e-6f; + } - var num1 = -0.5f * newWidth * cosAngle - 0.5f * newHeight * sinAngle + 0.5f * width; - var num2 = 0.5f * newWidth * sinAngle - 0.5f * newHeight * cosAngle + 0.5f * height; + var newWidth = Mathf.RoundToInt(width * Mathf.Abs(cosAngle) + height * sinAngle); + var newHeight = Mathf.RoundToInt(width * sinAngle + height * Mathf.Abs(cosAngle)); var offsetX = (int)((centerX / sinAngle + @@ -73,6 +97,7 @@ sinAngle - centerY / cosAngle) / (cosAngle / sinAngle + sinAngle / cosAngle)); + var offsetY = (int)((centerX / cosAngle - (-0.5f * newWidth * cosAngle - 0.5f * newHeight * sinAngle + 0.5f * width) / @@ -81,14 +106,16 @@ sinAngle + centerY / sinAngle) / (sinAngle / cosAngle + cosAngle / sinAngle)); + var num1 = -0.5f * newWidth * cosAngle - 0.5f * newHeight * sinAngle + 0.5f * width; + var num2 = 0.5f * newWidth * sinAngle - 0.5f * newHeight * cosAngle + 0.5f * height; for (int x2 = 0; x2 < newWidth; x2++) { for (int y2 = 0; y2 < newHeight; y2++) { //如果(x1,y1)不在原图宽高所表示范围内,则(x2,y2)处的像素值设置为0或255 - var x1 = x2 * cosAngle + y2 * sinAngle + num1; - var y1 = -x2 * sinAngle + y2 * cosAngle + num2; + var x1 = Mathf.RoundToInt(x2 * cosAngle + y2 * sinAngle + num1); + var y1 = Mathf.RoundToInt(-x2 * sinAngle + y2 * cosAngle + num2); if (x1 < 0 || x1 >= width || y1 < 0 || y1 >= height) { @@ -98,8 +125,7 @@ } //如果(x1,y1)在原图宽高所表示范围内,使用最近邻插值或双线性插值,求出(x2,y2)处的像素值 - canvas.SetPixel(x2 + x - offsetX, y2 + y - offsetY, - origin.GetPixel(Mathf.FloorToInt(x1), Mathf.FloorToInt(y1))); + _canvas.SetPixel(x2 + x - offsetX, y2 + y - offsetY, origin.GetPixel(x1, y1)); } } } diff --git a/DungeonShooting_Godot/src/test/TestOptimizeSprite.cs b/DungeonShooting_Godot/src/test/TestOptimizeSprite.cs index 6097932..95cbda4 100644 --- a/DungeonShooting_Godot/src/test/TestOptimizeSprite.cs +++ b/DungeonShooting_Godot/src/test/TestOptimizeSprite.cs @@ -1,3 +1,4 @@ +using System; using Godot; public partial class TestOptimizeSprite : Node2D @@ -6,6 +7,25 @@ public override void _Ready() { + var imageCanvas = new ImageCanvas(200, 200); + imageCanvas.Scale = new Vector2(4, 4); + imageCanvas.DrawImageInCanvas(Texture2D, 10, 30, 0, 0, 0, false); + var time = DateTime.Now; + //imageCanvas.DrawImageInCanvas(Texture2D, 50, 30, 30, 0, 0, true); + GD.Print("useTime: " + (DateTime.Now - time).TotalMilliseconds); + var time2 = DateTime.Now; + //imageCanvas.DrawImageInCanvas(Texture2D, 100, 100, 0, 0, 0, false); + //imageCanvas.DrawImageInCanvas(Texture2D, 100, 100, 90, Texture2D.GetWidth() / 2, Texture2D.GetHeight() / 2, false); + imageCanvas.DrawImageInCanvas(Texture2D, 100, 100, 300, 0, 0, false); + //imageCanvas.DrawImageInCanvas(Texture2D, 100, 100, 145, (int)(Texture2D.GetWidth() * 0.2f), (int)(Texture2D.GetHeight() * 0.2f), false); + //imageCanvas.DrawImageInCanvas(Texture2D, 140, 30, 270, 0, 0, true); + + GD.Print("useTime: " + (DateTime.Now - time2).TotalMilliseconds); + AddChild(imageCanvas); + } + + private void Test1() + { var canvas = Image.Create(150, 150, false, Image.Format.Rgba8); for (int x = 0; x < 150; x++) @@ -17,8 +37,10 @@ } var image = Texture2D.GetImage(); - - RotateImage(image, canvas, 50, 50, 0, image.GetWidth(), image.GetHeight()); + image.FlipX(); + image.Rotate180(); + canvas.BlitRect(image, new Rect2I(0, 0, image.GetWidth(), image.GetHeight()), new Vector2I(10, 10)); + //RotateImage(image, canvas, 50, 50, 30, image.GetWidth(), image.GetHeight()); //RotateImage(imgData, image, 0); @@ -41,58 +63,4 @@ sprite2D.Scale = new Vector2(5, 5); AddChild(sprite2D); } - - public void RotateImage(Image origin, Image canvas, int x, int y, float angle, int centerX, int centerY) - { - angle = Mathf.DegToRad(angle); - var width = origin.GetWidth(); - var height = origin.GetHeight(); - - var cosAngle = Mathf.Cos(angle); - var sinAngle = Mathf.Sin(angle); - - var newWidth = width * Mathf.Abs(cosAngle) + height * sinAngle; - var newHeight = width * sinAngle + height * Mathf.Abs(cosAngle); - - var num1 = -0.5f * newWidth * cosAngle - 0.5f * newHeight * sinAngle + 0.5f * width; - var num2 = 0.5f * newWidth * sinAngle - 0.5f * newHeight * cosAngle + 0.5f * height; - - var offsetX = - (int)((centerX / sinAngle + - (0.5f * newWidth * sinAngle - 0.5f * newHeight * cosAngle + 0.5f * height) / - cosAngle - - (-0.5f * newWidth * cosAngle - 0.5f * newHeight * sinAngle + 0.5f * width) / - sinAngle - centerY / cosAngle) / - (cosAngle / sinAngle + sinAngle / cosAngle)); - - var offsetY = - (int)((centerX / cosAngle - - (-0.5f * newWidth * cosAngle - 0.5f * newHeight * sinAngle + 0.5f * width) / - cosAngle - - (0.5f * newWidth * sinAngle - 0.5f * newHeight * cosAngle + 0.5f * height) / - sinAngle + centerY / sinAngle) / - (sinAngle / cosAngle + cosAngle / sinAngle)); - - - for (int x2 = 0; x2 < newWidth; x2++) - { - for (int y2 = 0; y2 < newHeight; y2++) - { - //如果(x1,y1)不在原图宽高所表示范围内,则(x2,y2)处的像素值设置为0或255 - var x1 = x2 * cosAngle + y2 * sinAngle + num1; - var y1 = -x2 * sinAngle + y2 * cosAngle + num2; - - if (x1 < 0 || x1 >= width || y1 < 0 || y1 >= height) - { - //image.SetPixel(x, y, new Color(0, 0, 0, 0)); - //在图片外 - continue; - } - - //如果(x1,y1)在原图宽高所表示范围内,使用最近邻插值或双线性插值,求出(x2,y2)处的像素值 - canvas.SetPixel(x2 + x - offsetX, y2 + y - offsetY, - origin.GetPixel(Mathf.FloorToInt(x1), Mathf.FloorToInt(y1))); - } - } - } }