1+ UsingMoudle (" Window" )
2+ UsingMoudle (" Graphic" )
3+ UsingMoudle (" Algorithm" )
4+ UsingMoudle (" Interactivity" )
5+ UsingMoudle (" Time" )
6+
7+ _FPS_ = 60
8+
9+ _RECT_WINDOW_ = {
10+ x = WINDOW_POSITION_DEFAULT ,
11+ y = WINDOW_POSITION_DEFAULT ,
12+ w = 1280 ,
13+ h = 720
14+ }
15+
16+ CreateWindow (" 地图演示" , _RECT_WINDOW_ , {})
17+
18+ -- 地图中最高点个数的最大值和最小值
19+ _NUM_HP_MAX_ , _NUM_HP_MIN_ = 5 , 1
20+
21+ -- 地图中最低点个数的最大值和最小值
22+ _NUM_LP_MAX_ , _NUM_LP_MIN_ = 10 , 5
23+
24+ -- 地图中最高点高度的最大值和最小值
25+ _ALT_HP_MAX_ , _ALT_HP_MIN_ = 1000 , 800
26+
27+ -- 地图中最低点高度的最大值和最小值
28+ _ALT_LP_MAX_ , _ALT_LP_MIN_ = 200 , 0
29+
30+ -- 地图中影响点坐标和高度对象
31+ AffectPointList = {}
32+
33+ -- 初始化地图中的最高点列表
34+ for i = 1 , math.random (_NUM_HP_MIN_ , _NUM_HP_MAX_ ) do
35+ table.insert (
36+ AffectPointList ,
37+ {
38+ x = math.random (0 , _RECT_WINDOW_ .w ), -- x 方向坐标
39+ y = math.random (0 , _RECT_WINDOW_ .h ), -- y 方向坐标
40+ alt = math.random (_ALT_HP_MIN_ , _ALT_HP_MAX_ ) -- 高度
41+ } -- 地图中的最高点对象
42+ )
43+ end
44+
45+ -- 初始化地图中的最低点列表
46+ for i = 1 , math.random (_NUM_LP_MIN_ , _NUM_LP_MAX_ ) do
47+ table.insert (
48+ AffectPointList ,
49+ {
50+ x = math.random (0 , _RECT_WINDOW_ .w ), -- x 方向坐标
51+ y = math.random (0 , _RECT_WINDOW_ .h ), -- y 方向坐标
52+ alt = math.random (_ALT_LP_MIN_ , _ALT_LP_MAX_ ) -- 高度
53+ } -- 地图中的最低点对象
54+ )
55+ end
56+
57+ -- 输出地图中影响点个数
58+ print (" Affection Point Number: " ..# AffectPointList )
59+
60+ -- 地图中所有点坐标和高度对象
61+ MapPointList = {}
62+
63+ -- 初始化地图中所有点列表
64+ for X = 0 , _RECT_WINDOW_ .w do -- 遍历地图的每一列
65+ local _RowPointList = {} -- 地图每一列中的点对象列表
66+ for Y = 0 , _RECT_WINDOW_ .h do -- 遍历每一列中的每一行
67+
68+ -- 第一次计算地图高度
69+ local _altitude_1 = 0 -- 当前点高度
70+ local _totalDist = 0 -- 当前点距离地图上所有影响点的距离总和
71+ for _ , afp in ipairs (AffectPointList ) do -- 遍历每个影响点计算当前点距离地图上所有影响点的距离总和
72+ local _dist = math.sqrt ((X - afp .x ) ^ 2 + (Y - afp .y ) ^ 2 )
73+ _totalDist = _totalDist + _dist
74+ end
75+ for _ , afp in ipairs (AffectPointList ) do -- 遍历每个影响点计算当前点高度
76+ local _dist = math.sqrt ((X - afp .x ) ^ 2 + (Y - afp .y ) ^ 2 )
77+ _altitude_1 = _altitude_1 + (1 - _dist / _totalDist ) * afp .alt / (# AffectPointList - 1 )
78+ end
79+
80+ -- 第二次计算地图高度
81+ local _altitude_2 = 0
82+ local _totalRecip = 0 -- 当前点距离地图上所有影响点距离的倒数总和
83+ for _ , afp in ipairs (AffectPointList ) do -- 遍历每个影响点计算当前点距离地图上所有影响点距离的倒数总和
84+ local _dist = math.sqrt ((X - afp .x ) ^ 2 + (Y - afp .y ) ^ 2 )
85+ _totalRecip = _totalRecip + 1 / _dist
86+ end
87+ for _ , afp in ipairs (AffectPointList ) do -- 遍历每个影响点计算当前点高度
88+ local _dist = math.sqrt ((X - afp .x ) ^ 2 + (Y - afp .y ) ^ 2 )
89+ _altitude_2 = _altitude_2 + 1 / _dist / _totalRecip * afp .alt
90+ end
91+
92+ table.insert (
93+ _RowPointList ,
94+ {
95+ x = X ,
96+ y = Y ,
97+ alt = _altitude_1 * 0.9925 + _altitude_2 * 0.0075 -- 合并两次地图高度生成的权重和
98+ }
99+ )
100+ end
101+ table.insert (MapPointList , _RowPointList )
102+ end
103+
104+ -- 地图上最高点高度和最低点高度
105+ MaxAlt , MinAlt = 0 , 1000
106+
107+ -- 获取地图上最高点高度和最低点高度
108+ for _ , RowPointList in ipairs (MapPointList ) do
109+ for _ , point in ipairs (RowPointList ) do
110+ if point .alt > MaxAlt then MaxAlt = point .alt end
111+ if point .alt < MinAlt then MinAlt = point .alt end
112+ end
113+ end
114+
115+ -- 将地图上的点高度归一化后将高度范围调整为 0 ~ 1000
116+ for _ , RowPointList in ipairs (MapPointList ) do
117+ for _ , point in ipairs (RowPointList ) do
118+ point .alt = (point .alt - MinAlt ) / (MaxAlt - MinAlt ) * 1000
119+ end
120+ end
121+
122+ -- 为地图上的点着色
123+ for _ , RowPointList in ipairs (MapPointList ) do
124+ for _ , point in ipairs (RowPointList ) do
125+ SetDrawColor (HSLAToRGBA ({h = (1 - point .alt / 1000 ) * 240 , s = 1 , l = 0.35 , a = 1 }))
126+ Point (point )
127+ end
128+ end
129+
130+ -- 绘制影响点中心
131+ for _ , afp in ipairs (AffectPointList ) do
132+ SetDrawColor ({r = 255 , g = 255 , b = 255 , a = 215 })
133+ FillRectangle (
134+ {
135+ x = afp .x - 2.5 ,
136+ y = afp .y - 2.5 ,
137+ w = 5 ,
138+ h = 5
139+ }
140+ )
141+ end
142+
143+ while true do
144+ local _start = GetInitTime ()
145+ if UpdateEvent () then
146+ local _event = GetEventType ()
147+ if _event == EVENT_QUIT then
148+ break
149+ end
150+ end
151+ UpdateWindow ()
152+ local _end = GetInitTime ()
153+ DynamicSleep (1000 / _FPS_ , _end - _start )
154+ end
0 commit comments