Capricorn 76
Physics joint example.
The ScriptENGINE physics engine provides some physics joints that are used to constrain physical entity movement.
Things like hinges, sliders, gears, pulleys, corkscrews, ball-and-sockets etc.

---------------------------
---------------------------
-- Physics joint example
-- Copyright (c) 2007-09 Capricorn 76 Pty. Ltd.
--
-- The ScriptENGINE physics engine provides some
-- physics joints that are used to
-- constrain physical entity movement.
-- Things like hinges, sliders,
-- gears, pulleys, corkscrews, ball-and-sockets etc.
--
-- Most joints use two entities: a parent and child entity.
-- The physics engine will maintain the joint between the
-- two entities by applying forces and torques to each.
--
-- If no parent entity is specified, then it is assumed to be static,
-- and the child will be assumed to be attached (via the joint) to a fixed location.
--
-- NOTE:
-- The ./Demos/runDemo.e76script is a utility script used to run all the examples.
-- It loads the world, calls the OnWorldLoad(), OnWorldUnload() functions, and runs the graphics engine loop, waiting for the user to press escape.
---------------------------
---------------------------

local subMouse;

---------------------------
-- runDemo.e76script calls this function when the world is loaded
---------------------------
function OnWorldLoad(worldName)
    --print('OnWorldLoad');

    ---------------------------
    -- The SDK world editor creates a worldIds.e76script when the world is saved. It contains all the entity ids.
    -- We load the IDs so that we can refer to the world entities using friendly names.
    ---------------------------
    IApp:loadScript(IWorld:getNameLong() .. '/worldIds');
    IWorld:setActiveCameraId(idCamera_cam1);

    -- Load example's GUI
    OnWorldLoadGui();

    -- Subscribe to the mouse button event only (there is another mouse event that will tell us about all the mouse movements too, but we don't need it)
    subMouse = IEvents:subscribeMouseButton('OnMouseButton');

    -------------------------
    -- ScriptENGINE defaults the physically simulated world dimensions to just surround all the physical entities.
    -- In this example, we're going to move the boxes around & they may move out of this zone.
    -- So we expand the physical world dimensions.
    -------------------------
    IPhysics:setBounds('-100 -100 -100', '100 100 100');

end

---------------------------
-- Load this example's GUI
---------------------------
function OnWorldLoadGui()
    ---------------------------
    -- Let's show some help text
    ---------------------------
    IGraphics:loadGui('help');
end

---------------------------
-- runDemo.e76script calls this function when the world is unloaded
---------------------------
function OnWorldUnload(worldName)
    --print('OnWorldUnload');

    ---------------------------
    -- Unsubscribe to events.
    -- We will no longer be notified of mouse-clicks.
    ---------------------------
    IEvents:unsubscribe(subMouse);
    ISound:unload('shoot');
end

---------------------------
-- Mouse button event handler.
-- The graphics engine will call this callback function
-- whenever the user clicks on a mouse button.
---------------------------
function OnMouseButton(eventType, mouseX, mouseY, mouseWheel, userData)

    ---------------------------
    -- If the user clicked the left-mouse button then do a raycast and see what we hit.
    -- We filter what entities we're interested in (we only want units, not things like waypoints, agents, etc.)
    -- You can raycast in any direction, from any starting position. But we're going to use the mouse position and use the mouse raycast function.
    ---------------------------
    if (IMouse:leftButtonClicked(eventType)) then

        result = IPhysics:rayCastMousePositionFilter(IWorld:getUnitTypeId());
        ---------------------------
        -- Did we hit something?
        ---------------------------
        if (result) then

            boxId           = result['entity'];
            intersection    = result['intersection'];

            -- Calculate a force vector. This is just a vector from our position to the intersection point.
            ourPosition     = IWorld:getEntityPosition(IWorld:getActiveCameraId());

            forceVector     = IMisc:vectorSubtract(intersection, ourPosition);

            -- Normalise the vector. This makes its magnitude = 1 (ie. we scale it, still points in the same direction)
            forceVector     = IMisc:vectorNormalise(forceVector);

            -- Rescale it to a larger force
            forceVector     = IMisc:vectorMultiply(forceVector, 5);

            -- Apply the force to the entity at the intersection point
            intersectionOffset = IMisc:vectorSubtract(intersection, IWorld:getEntityPosition(boxId));
            IPhysics:addEntityImpulseForceOffset(boxId, forceVector, intersectionOffset);

            -- Play a sound just for fun
            -- Play a sound just for fun
            if (not(ISound:soundExists('shoot'))) then
                if (ISound:load('shoot', '../Resources/sfx.wav', false)) then   -- This sound has multiple channels, and so is handled as a 2D sound by the engine
                    ISound:setVolume('shoot', 1);
                end
            end
            if (ISound:soundExists('shoot')) then
                ISound:play('shoot');
            end

        end
    end

end

Copyright © 2006-23 Sep 2009 Capricorn 76 Pty. Ltd. (created on Wed Sep 23 16:49:12 2009)