本节书摘来异步社区《Lua游戏AI开发指南》一书中的第2章,第2.8节,作者: 【美】David Young(杨) 译者: 王磊 责编: 陈冀康,更多章节内容可以访问云栖社区“异步社区”公众号查看。
2.8 发射方块
现在我们有了基本的光照和一个物理平面,还能创建和模拟物理对象,是时候发射一些东西了。在开始创建智能体之前,先让我们快速了解一下沙箱对象的另外一些物理属性,以及如何与输入控制器进行交互。
Sandbox_HandleEvent函数让沙箱能够响应鼠标和键盘输入事件。事件参数是一个Lua表,存储了事件的生成来源、事件是由按下还是松开按钮产生的以及事件是哪个键产生的这类信息。鼠标移动事件也类似,但包含了鼠标指针的宽高位置。
我们已经知道如何创建一个沙箱对象了,要发射一个对象只需要把它放置在相机的位置,然后对它施加一个物理冲击。
现在我们打算在接收到空格键按下事件时创建并发射一个方块。相机的位置和朝向可以从沙箱中的Sandbox.GetCameraPosition和Sandox.GetCameraForward函数获取到。我们会把位置和朝向赋值给方块并对它沿相机面对的方向施加一个力。为了给物体添加一点自转,你可以使用Core.ApplyAngularImpulse函数来让它在飞向天空时开始自转。
Sandbox.lua:
function Sandbox_HandleEvent(sandbox, event)
if (event.source == "keyboard" and
event.pressed and event.key == "space_key" ) then
local block = Sandbox.CreateObject(
sandbox,
"models/nobiax_modular/modular_block.mesh");
local cameraPosition =
Sandbox.GetCameraPosition(sandbox);
-- Normalized forward camera vector.
local cameraForward =
Sandbox.GetCameraForward(sandbox);
-- Offset the block's position in front of the camera.
local blockPosition =
cameraPosition + cameraForward * 2;
local rotation = Sandbox.GetCameraOrientation(sandbox);
-- Mass of the block in kilograms.
Core.SetMass(block, 15);
Core.SetRotation(block, rotation);
Core.SetPosition(block, blockPosition);
-- Applies instantaneous force for only one update tick.
Core.ApplyImpulse(
block, Vector.new(cameraForward * 15000));
-- Applies instantaneous angular force for one update
-- tick. In this case blocks will always spin forwards
-- regardless where the camera is looking.
Core.ApplyAngularImpulse(
block, Sandbox.GetCameraLeft(sandbox) * 10);
end
end
现在运行沙箱,我们就可以四处移动、转动相机和发射方块了,如图2-3所示。