이번에는 wpf를 이용하여 맵제작툴을 만들었다.

Debug 폴더에 Resource폴더를 만들어 녹색타일(19번)과 길타일(24번)을 넣어주었고 json을 이용해 저장하게 하였다.



우선 캔버스와 save, load 버튼을 만들어줌




그리고 스크립트를 아래와 같이 작성했다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
namespace DefenceTool
{
    /// <summary>
    /// MainWindow.xaml에 대한 상호 작용 논리
    /// </summary>
    public partial class MainWindow : Window
    {
        private List<Point> path = new List<Point>();
        public MainWindow()
        {
            InitializeComponent();
 
            int width = 64;
            int height = 64;
            int maxX = 20;
            int maxY = 13;
 
            for(int i=0; i<maxX; i++)
            {
                for(int j=0; j<maxY; j++)
                {
                    makeBaseTile(i * width, j * height);
                }
            }
        }
 
        private void makeBaseTile(int x, int y, string fileName = "Resource/rpgTile019.png")
        {
            Stream imageStreamSource = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read);
            PngBitmapDecoder decoder = new PngBitmapDecoder(imageStreamSource, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
            BitmapSource bitmapSource = decoder.Frames[0];
 
            Image background = new Image();
            background.Source = bitmapSource;
            
            var m = background.Margin;
            m.Left = x;
            m.Top = y;
            background.Margin = m;
 
            background.Tag = fileName;
 
            canvas.Children.Add(background);
        }
 
        private void canvas_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            Point mousepos = e.GetPosition(canvas);
            int x = (int)mousepos.X;
            int y = (int)mousepos.Y;
 
            // 나누기 64에서 소수점단위가 떨어지고 곱하기 64를하면 64단위로만 좌표가 바뀌게됨.
            x /= 64;
            x *= 64;
            y /= 64;
            y *= 64;
 
            // 마우스포인트 위치를 int화해준 위치로 변경
            mousepos.X = x;
            mousepos.Y = y;
 
            // path에 저장된 길이 있으면 처음부터 끝까지 돔
            foreach (Point p in path)
            {
                // 저장된 길과 현재 마우스 위치가 같으면
                if (p.X == mousepos.X && p.Y == mousepos.Y)
                {
                    // path에서 현재 저장된것 삭제
                    path.Remove(p);
 
                    // 캔버스의 자식을 돌면서
                    foreach (Object obj in canvas.Children)
                    {
                        // 이미지를 찾음
                        Image i = obj as Image;
 
                        // 이미지가 널이 아니면(자식이 이미지면)
                        if (i != null)
                        {
                            string tag = i.Tag as string;
                            // 태그(파일명)와 좌표를 비교해 캔버스에서 삭제
                            if (tag == "Resource/rpgTile024.png" && i.Margin.Left == p.X && i.Margin.Top == p.Y)
                            {
                                canvas.Children.Remove(i);
                                return;
                            }
                        }
                    }
                }
            }
 
            // 똑같은 위치에 타일이 없으면 현재자리에 길 생성
            makeBaseTile(x, y, "Resource/rpgTile024.png");
            path.Add(mousepos);
        }
    }
}
cs

이미지는 예전에 wpf 실습할때 출력했던 방식으로 출력. makeBaseTile이라는 함수로 만들어 두었다.

그리고 생성자에서 해당크기만큼 기본타일을 깔아준다.


마우스를 클릭하면 마우스의 위치를 나누기64 곱하기64 해주어 위치를 잡아주고 그 위치에 길을 생성한다.

(나누기 64하면 소수점이 떨어져 0, 1, 2와 같이 딱 떨어지고 거기서 64를 곱해줘서 실제 위치를 잡는것)

그리고 길의 위치를 저장할 List를 만들어 거기에 추가해준다.


이후 길이 있는 위치를 다시 클릭하면 길을 삭제하도록 만들었다. (중간에 있는 foreach문)





이제 툴을 실행하면 원하는대로 길을 찍을 수 있게 된다.





이제 save버튼을 누르면 길이 json으로 저장되고, load버튼을 누르면 json을 불러와 길을 그대로 출력해줘야한다.

해당 부분의 스크립트는 아래와 같다. (예전 wpf로 json을 사용한 부분을 참고)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
private void SaveButton_Click(object sender, RoutedEventArgs e)
{
    JsonObjectCollection root = new JsonObjectCollection();
    JsonArrayCollection pathArray = new JsonArrayCollection("Path");
    foreach(Point pos in path)
    {
        JsonObjectCollection jsonPos = new JsonObjectCollection();
        jsonPos.Add(new JsonNumericValue("X", pos.X));
        jsonPos.Add(new JsonNumericValue("Y", pos.Y));
        pathArray.Add(jsonPos);
    }
    root.Add(pathArray);
 
    String s = root.ToString();
    System.IO.File.WriteAllText("PathData.json", s);
}
 
private void LoadButton_Click(object sender, RoutedEventArgs e)
{    
    String s = System.IO.File.ReadAllText("PathData.json");
    JsonTextParser textParser = new JsonTextParser();
    JsonObjectCollection root = textParser.Parse(s) as JsonObjectCollection;
    JsonArrayCollection pathArray = root["Path"as JsonArrayCollection;
 
 
    // canvas에 뿌려진 길들을 전부 삭제
    for (int i = 0; i < canvas.Children.Count; i++)
    {
        Image preImage = canvas.Children[i] as Image;
        if (preImage != null)
        {
            string tag = preImage.Tag as string;
            if (tag == "Resource/rpgTile024.png")
            {
                // 그냥 remove하게되면 다음에 있던게 당겨져서 그자리에 오기때문에 i를 지우고 다시 i를 한칸전으로 돌려줘야함.
                canvas.Children.RemoveAt(i);
                i--;
            }
        }
    }
    // 리스트에 저장된 길도 초기화해줌.
    path.Clear();
 
 
    // 그리고 json파일에서 불러온 길들만 맵에 뿌려줌
    foreach (JsonObjectCollection obj in pathArray)
    {
        double x = (obj["X"as JsonNumericValue).Value;
        double y = (obj["Y"as JsonNumericValue).Value;
 
        // 타일 생성 후 리스트에 저장
        makeBaseTile((int)x, (int)y, "Resource/rpgTile024.png");
        path.Add(new Point(x,y));
    }
}
cs





이렇게 저장된 json파일을 Unity의 프로젝트 폴더 안으로 복사해준다.

이후 Assets폴더에는 System.Net.Json.dll 파일을 넣어준다. 폴더에 넣어주기만 하면 Unity에서는 자동으로 참조된다.


그리고 길만드는 스크립트(MakePath)로 가서 기존의 맵 추가하는부분을 주석처리한 뒤

Json을 불러와 그 데이터로 맵을 추가해준다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
private void LoadJson()
{
    String s = System.IO.File.ReadAllText("PathData.json");
    JsonTextParser textParser = new JsonTextParser();
    JsonObjectCollection root = textParser.Parse(s) as JsonObjectCollection;
    JsonArrayCollection pathArray = root["Path"as JsonArrayCollection;
 
    foreach (JsonObjectCollection obj in pathArray)
    {
        double x = (obj["X"as JsonNumericValue).Value;
        double y = (obj["Y"as JsonNumericValue).Value;
 
        movePath.Add(new MovePath((int)x / 6412 - (int)y / 64));
    }
}
cs

같은 c#이므로 그대로 복사붙여넣기해서 조금만 수정하면 된다. 

y값의 경우 wpf는 맨위가 0이고 코드는 맨아래가 0이므로 조정.





실행해보면 툴에서 만든 맵 그대로 출력되는것을 볼 수 있다.


Posted by misty_
,