[Script] Moving platforms
Posted: Mon May 04, 2015 11:16 pm
I've made a new asset (using the old ones...) which allows for platforms (like forest_bridge) to be moved up and down and sideways (without anything on them, however).
Do the following: in "items.lua", add the following lines (feel free to remove comments!)
and in "sounds.lua", add the following:
Then, in a script_entity in your dungeon, you have to specify two things: a sequence of points through which you want the platform to move, and the total time of movements. For example,
Then, place a "forest_bridge_moving" platform at x = 14, z = 14, and elevation 2; say that its id is "forest_bridge_moving_1"; then add the following lines to the script (maybe connect them to a floor trigger, or a lever, etc):
and watch the platform moving from (14,14,2) to (15,13,1) in 2 seconds, and then to (12,13,1) in another 3 seconds. Do not try to "jump" on moving platforms, because you will fall through (as of now).
Alois
PS: Thanks to JKos for the "data" trick!
Do the following: in "items.lua", add the following lines (feel free to remove comments!)
Code: Select all
defineObject{
name = "forest_bridge_moving",
baseObject = "base_floor_decoration",
components = {
{
class = "Model",
model = "assets/models/env/forest_bridge.fbx", -- the forest bridge model (change here as needed)
staticShadow = true,
},
{
class = "Platform", -- or otherwise you are going to fall through the model :)
},
{
class = "Timer",
DisableSelf = false, -- never stop (until you say so!)
TimerInterval = 0.05, -- time interval (change as needed, but modify also below)
onActivate = function(self)
if (self.go.data:get("tmax") == 0) then -- to avoid the "start when run" problem
self:stop() -- if tmax = 0, then nothing has to move, stop timer
return
end
local points = self.go.data:get("points") -- the path to follow (see instructions)
local interval = 0 -- the i-th interval of points
for idx = 1,#points-1 do
local time = self.go.data:get("time")
if ((points[idx].t <= time) and (time < points[idx+1].t)) then -- if the time is in between two points
interval = idx -- register the interval
end
end
if (interval ~= 0) and (interval ~= self.go.data:get("interval")) then -- has the interval changed?
self.go.data:set("interval",interval) -- save it
local ps = points[interval] -- starting point of the i-th interval
local pf = points[interval+1] -- ending point of the i-th interval
local dt = points[interval+1].t - points[interval].t -- length, in seconds, of the interval
local dx = 3 * (pf.x - ps.x) / dt / 20 -- space to move in the x direction (east-west)
local dy = 3 * (pf.y - ps.y) / dt / 20 -- space to move in the y direction (up-down)
local dz = 3 * (ps.z - pf.z) / dt / 20 -- space to move in the z direction (north-south)
self.go.data:set("d",{dx = dx, dy = dy, dz = dz}) -- save the datum
end
self.go.data:set("time",self.go.data:get("time") + 0.05) -- increase time (of TimerInterval)
if (not(self.go.data:get("sound"))) then -- is there a sound? if not
self.go.sound:play("wall_sliding_loop") -- moving platform sound (see sound.lua for the definition)
self.go.data:set("sound",true) -- register the fact that a sound is playing
end
if (self.go.data:get("time") < self.go.data:get("tmax")) then -- are we before the end of the movement?
local offset = self.go:getWorldPosition() -- yes: where is the platform?
local d = self.go.data:get("d") -- take the increase in space
self.go:setWorldPosition(vec(offset.x+d.dx,offset.y+d.dy,offset.z+d.dz)) -- and move it!
elseif (self.go.data:get("time") < self.go.data:get("tmax")+0.05) then -- the movement has just ended? (0.04 = TimerInterval - 0.01)
self.go.sound:play("wall_sliding_lock") -- change sound
local point = points[#points] -- take the last point
self.go:setPosition(point.x,point.z,self.go.facing,point.y,self.go.level) -- and set the bridge to it (with integers!)
elseif (self.go.data:get("time") > self.go.data:get("tmax") + 2) then -- two seconds more (the "lock" sound still has to play)
self.go.data:set("time",0) -- reset values
self.go.data:set("tmax",0) -- reset values
self.go.data:set("sound",false) -- reset values
self.go.data:set("interval",0) -- reset values
self.go.sound:stop() -- stop sound
self.go.timer:stop() -- stop timer
end
end,
},
{
class = "Script",
name = "data",
source = [[
data = {time = 0, interval = 0, tmax = 0, sound = false}
function set(self,name,value)
self.data[name] = value
end
function get(self,name)
return self.data[name]
end
]],
},
{
class = "Sound",
volume = 100,
},
},
editorIcon = 184,
automapIcon = 136,
}Code: Select all
defineSound{
name = "wall_sliding_loop",
filename = "assets/samples/env/wall_sliding_01.wav",
loop = true,
volume = 0.5,
minDistance = 2,
maxDistance = 10,
}Code: Select all
local points = {
{x = 14, y = 2, z = 14, t = 0},
{x = 15, y = 1, z = 13, t = 2},
{x = 12, y = 1, z = 13, t = 5},
}
local tmax = 5Code: Select all
forest_bridge_moving_1.data:set("points",points)
forest_bridge_moving_1.data:set("tmax",tmax)
forest_bridge_moving_1.timer:start()Alois
PS: Thanks to JKos for the "data" trick!