@TOC
万事开头难
所以我准备用最简单的例子来入门MicroCity。游戏是我们都喜欢的,寓教于乐通常能激发大家的学习兴趣和动力,也比较容易理解和实现。因此,我选择从MicroCity的3D功能入手,介绍相关概念,并通过编写相关代码作为实践。
3D engine of MicroCity
编写一个3D程序通常包括如下几步:
- 创建3D世界
- 设置视角,光线等参数
- 添加Objects实体
- 通过实体的各种function控制其状态(大小,方向,位置,颜色,属性等)改变
- 更新世界
3D world
通过 Create3DWorld()函数来得到一个世界pointer(userdata类型),之后所有的Object都将在这个世界中遨游。皮卡丘,快到碗里来。
首先我们需要了解下这个世界的一些基本规律。这个世界是3维的,xyz轴,是左手坐标系,如下图,所以在设置object的坐标(x,y,z)时要好好考虑。
其中(0,0,0)点作为原点,也就是图中的左手的原点,随xyz轴递增,反向为负。长度单位的选择由你自己决定,可以参考现实世界的米,厘米,毫米,千米,取决于你的世界的东西的块头,和想要的精度。
3D Objects
在这个3D世界中,你可以加入自己想要的object对象。
- 球体 addSphere()
- 立方体 add3DBox()
- 矩形 add3DRect()
- 线段 add3DLine()
- 3ds模型 LoadObject() (皮卡丘在这里加入)
- Camera
- Light
parent关系
- 父子关系可以连接两个物体
- 因为很多物体由多个部件组成,而且坐标系都是相对的
- SetParent(son, father),设置好父子关系后,儿子的位置,方向都是相对于父亲的。大家还记得高中物理一开始的那个坐标系变换么,绝对坐标系和相对坐标系,解题专用。。
位置和朝向
物体在空间中最明显的属性就是其位置和方向,(x,y,z)
- 使用 SetPosition()来设置物体的位置
- 使用SetRotation() 来设置物体的朝向,分别延xyz轴旋转。
颜色
- RGB设置
大小
- 只能通过更改规模设置
- SetScale()在初始尺寸上变大变小,(可只在某维度上变化)。
- LoadTexture()给你的3d Object贴图。
动画
- 如何让世界动起来,就需要增加一个维度,时间
- 和时间赛跑
- 我们用Sleep()来让程序暂停一些cpu时间,来模拟时间的流逝
- 用Update()来更新图像
代码实例
这里要偷个懒,直接用MicroCity里的sample了。
盒子就是小车
function StartSimulation()
W3D = Create3DWorld("WareHouse", true, 0.5, 100) --创建一个3D世界
--创建场景
local scenelen = 1000 --场景的长度
local scenewid = 500 --场景的宽度
local scenerect = Add3DRect(W3D, scenelen, scenewid, 193, 193, 193)
SetPosition(scenerect, scenelen/2, 0, scenewid/2)
SetCamera(W3D, scenelen/2, 500, -scenewid/2, scenelen/2 , 0, scenewid/2) --设置镜头视角(从第2-4个参数的点位置看向后3个参数的点位置)
local box = Add3DBox(W3D, 20, 20, 20, 255, 127, 39) --创建一个盒子,2-4为xyz,5-7为rgb
SetPosition(box, 10, 10, scenewid/2) --设置盒子的位置(盒子的中心点)
--让盒子移动
for x = 10, 990, 1 do
SetObject(box, x, 10, scenewid/2)
Update(W3D)
Sleep(10) -- 10ms更新一次
end
end
然后到MicroCity主程序运行,可以看到下面。(跑到尽头了)
真正的小车
刚刚的小车太简陋了,但是秉着敏捷开发的原则,也是够用了。但是咱们不能骄傲自满,要时刻进步。因此从设计老王那里搞来了一辆卡车,又从sample里搞来了一段代码。
local M3D = Create3DWorld("test")
LoadObject(M3D,"2axle.3ds")
然后运行,还挺酷。其中2axle.3ds这个文件是3ds格式的3d模型,2axpwtm.jpg是模型的贴图,这里自动匹配了。想给车子换皮肤,可以用LoadTexture()换,当然你得买得起皮肤。
好了,你现在要让卡车跑起来,咋办。
function StartSimulation()
W3D = Create3DWorld("WareHouse", true, 0.5, 100) --创建一个3D世界
--创建场景
local scenelen = 1000 --场景的长度
local scenewid = 500 --场景的宽度
local scenerect = Add3DRect(W3D, scenelen, scenewid, 193, 193, 193)
SetPosition(scenerect, scenelen/2, 0, scenewid/2)
SetCamera(W3D, scenelen/2, 500, -scenewid/2, scenelen/2 , 0, scenewid/2) --设置镜头视角
local box = LoadObject(W3D,"2axle.3ds")--创建一个盒子
SetPosition(box, 10, 10, scenewid/2) --设置盒子的位置
--让盒子移动
for x = 10, 990, 1 do
SetObject(box, x, 10, scenewid/2)
Update(W3D)
--Sleep(10)
end
end
然后开心的运行,
放肆的我靠。
这车怎么这么小?苍蝇吧。
什么原因呢,是因为卡车来到了巨人国,或者说画布来到了小人国。因此我们需要调整他们的尺寸比例。当然有两种方法,一种是调整画布Rect,一种是调整卡车。这里演示调整卡车,顺便介绍几个函数。
在创建box后,增加下面一行:
SetScale(box, 10, 10, 10) --小车在xyz轴都放大10倍(不改变设为1)
然后得到下图,这时候你才发现,这个苍蝇是横着走的。
所以又加入如下代码:
SetRotation(box, 0, -90, 0) --沿y轴逆时针旋转90度
大功告成
好了,你已经出师了。
- 欢迎来投简历,急招运筹优化算法工程师-仿真方向,精通MicroCity就行,年薪30+。
- 欢迎来学习咨询,腾讯会议一小时二百,运筹建模,求解器求解,精确算法启发式算法编写,网络可视化,仿真,学术相关,职业规划相关。