此处公告通常对读者进行申明或对该WIKI某些规则进行公告,请在确认后修改本通告。本WIKI编辑权限开放,欢迎收藏起来防止迷路,也希望有爱的小伙伴和我们一起编辑哟~

全站通知:

导航地图显示

阅读

    

2022-10-31更新

    

最新编辑:8f23

阅读:

  

更新日期:2022-10-31

  

最新编辑:8f23

来自风暴工程:建造与救援WIKI_BWIKI_哔哩哔哩
跳到导航 跳到搜索
页面贡献者 :
8f23

如果是第一次来,按"Ctrl+D"可以收藏随时查看更新~觉得WIKI好玩的话,请推荐给朋友哦~(◕ω<)☆
按右上角“WIKI功能→编辑”即可修改页面内容。

地图显示基本思路

首先我们从GPS模块中读取地图中心坐标,从驾驶座(或其他输入设备)读取并变换得到地图缩放等级,从指南针模块读取载具当前指向,从键盘读取导航点坐标。

随后,我们使用Lua绘制出地图图像,并在此之上使用不同颜色叠加标记地图中心点、载具指向、导航点位置及方位。

最后,我们通过屏幕展示地图图像。

背景知识

Lua显示函数

游戏的Lua中已经提供了用于输出地图的函数,并且提供了从GPS地图坐标到屏幕像素坐标的转换函数。游戏中Lua地图支持从0.1到50的不同缩放等级。

此外,还可以使用Lua绘制若干基本图形。游戏中需要提供起始两点的像素坐标以绘制直线。我们绘制从屏幕中心出发的直线来标记载具指向和导航点方位。游戏中的直线绘制函数支持输入位于屏幕像素范围以外的点坐标作为参数。

从驾驶座控制轴数值输出到地图缩放等级的转换

从控制轴上读取到的数值量值域为[-1, 1],且线性相关于按键时间。而我们期望地图的缩放等级能够指数相关于控制轴输出的数值,从而实现更好的表现效果。因此,我们需要一个如下式的转换函数来实现这一过程,其中x表示控制轴输入,z表示缩放等级,a和b为常量。

[math]\displaystyle{ z = e ^ {( ax + b )} , x \in [-1, 1] , a , b \in R }[/math]

为了更加充分地利用控制轴输出的值域,我们规定控制轴输出-1时对应的地图缩放等级为0.1,而输出1时对应的地图缩放等级为50。省略运算过程,我们直接给出一组“魔法量”:a = 3.1073040492111, b = 0.80471895621705 。同时,也给出相反变换方向的另一组数值以供参考:a = -3.1073040492111, b = 0.80471895621705 。

此外,我们设置驾驶座控制轴模式为保持,这样地图缩放等级将不会自动恢复到0输入对应的等级。

微控示例

在本示例中,我们使用Lua脚本来实现导航运算。在基本的导航功能以外,我们还实现了若干附加实用功能,读者可根据需要自行删改。经测试,该实例在v1.6.2 64bit版本有效。

效果图

Map video display.jpg

输入参数与结果输出

序号 输入/输出 类型 名称 说明
1 输出 视频 Map Video Output 地图图像输出。
2 输入 数值 Curr X 当前X坐标。从GPS组件获取。
3 输入 数值 Curr Y 当前Y坐标。从GPS组件获取。
4 输入 数值 Waypoint X 导航点X坐标。
5 输入 数值 Waypoint Y 导航点Y坐标。
6 输入 数值 Heading 当前方向。从指南针组件获取。
7 输入 数值 Scale 缩放等级。输入范围为-1 ~ -1。
8 输入 布尔 Waypoint Line Enableg 是否展示导航点信息。
9 常数 数值 Heading Line Color Alpha 载具指向线的图形透明度。
10 常数 数值 Point Color Alpha 中心点的图形透明度。
11 常数 数值 Waypoint Color Alpha 导航点及指示线的图形透明度。

Lua脚本

   -- Tick function that will be executed every logic tick
   function onTick()
       heading = input.getNumber(1)
       scale = input.getNumber(2)
       curr_x = input.getNumber(3)
       curr_y = input.getNumber(4)
       waypoint_x = input.getNumber(5)
       waypoint_y = input.getNumber(6)
       waypoint_line_enable = input.getBool(1)
       heading_line_color_alpha = property.getNumber('Heading Line Color Alpha')
       point_color_alpha = property.getNumber('Point Color Alpha')
       waypoint_color_alpha = property.getNumber('Waypoint Color Alpha')
   end
   function onDraw()
       screen_width = screen.getWidth()
       screen_height = screen.getHeight()
       screen_width_half = screen_width / 2
       screen_height_half = screen_height / 2
       screen_width_s = screen_width - 1
       screen_height_s = screen_height - 1
       screen_width_half_s = screen_width_half - 1
       screen_height_half_s = screen_height_half - 1
       -- convert value to 0.1~50
       scale = math.exp(scale * 3.1073040492111 + 0.80471895621705)
       screen.drawMap(curr_x, curr_y, scale)
       screen.setColor(255, 0, 0, point_color_alpha)
       screen.drawCircle(screen_width_half_s, screen_height_half_s, 3)
   
       screen.setColor(0, 255, 0, heading_line_color_alpha)
       heading_x = 0
       heading_y = 0
       if(heading == 0)
       then
       screen.drawLine(screen_width_half_s, screen_height_half_s, screen_width_half_s, 0)
       elseif(heading <= -0.5 or heading >= 0.5)
       then
           screen.drawLine(screen_width_half_s, screen_height_half_s, screen_width_half_s, screen_height_s)
       elseif(heading > 0)
       then
           tan = math.tan((0.25 - heading) * 2 * math.pi)
           screen.drawLine(screen_width_half_s, screen_height_half_s, 0, screen_height_half - tan * screen_height_half)
       else
           tan = math.tan((heading + 0.25) * 2 * math.pi)
           screen.drawLine(screen_width_half, screen_height_half_s, screen_width_s, screen_height_half - tan * screen_height_half)
       end
       if(waypoint_line_enable)
       then
           screen.setColor(0, 0, 255, waypoint_color_alpha)
           waypoint_pixel_x, waypoint_pixel_y = map.mapToScreen(curr_x, curr_y, scale, screen_width, screen_height, waypoint_x, waypoint_y)
           screen.drawLine(screen_width_half, screen_height_half, waypoint_pixel_x, waypoint_pixel_y)
           screen.drawCircle(waypoint_pixel_x, waypoint_pixel_y, 3)
       end
   end