Learning Game AI Programming with Lua
上QQ阅读APP看书,第一时间看更新

Shooting blocks

Now that we have some basic lighting, a physics plane, and the ability to create and simulate physics objects, it's time to start shooting things. Before we jump head-first into creating agents, we'll take a quick detour into accessing some of the physics aspects of sandbox objects, as well as interacting with input controls.

The Sandbox_HandleEvent function allows the sandbox to respond to mouse and keyboard inputs. The event parameter is a Lua table that stores the source of the event, whether the event was generated by a down or up key press, and what key caused the event. Mouse-movement events are similar, but contain the width and height location of the mouse cursor.

As we already know how to create a sandbox object, all we need to do to shoot objects is position the object at the camera's position and orientation and apply a physics impulse on the object.

In this case, we're going to create and shoot a block on a space_key press event. The camera's position and forward vector can be returned from the sandbox using the Sandbox.GetCameraPosition and Sandox.GetCameraForward functions. We'll assign the position and orientation to the block and apply a force to the block in the camera's forward direction. To add a bit of spin to the object, you can use the Core.ApplyAngularImpulse function to cause the block to start spinning as it flies through the air:

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

If we run the sandbox now, we can move around, point the camera, and shoot blocks.

Shooting blocks in the sandbox