Fish Fillets Ⅱ
Události
Každá událost se vyznačuje svým jménem a parametry, příklad:
ON_ROOM_BEGIN
…
end
ON_MOVE_STOP guppy
…
end
V příkladu ON_ROOM_BEGIN je událost bez parametrů, ve druhém je událost s jedním parametrem označujícím objekt, který vykonal událost (dokončil pohyb).
Tento zápis ale není klasický styl zápisu v jazyce Lua, místo události ON_ROOM_BEGIN se ve skutečnosti nahradí toto:
OnEvent(Enums.OnStart, "OnStart_%0") function OnStart_%0(eventId)globals.brArray={} globals.br_time=0 __had_begin__ = true
Za %0 se nahradí číslo, po kolikáté byla událost použita, v příkladu bude použita poprvé:
OnEvent(Enums.OnStart, "OnStart_0") --Toto je zaregistrování funkce OnStart_0 pro událost OnStart. (Enums.OnStart je číselná hodnota = 24) function OnStart_0(eventId) --Toto je samotné vytvoření funkce, obsahuje jeden parametr eventId, společný pro všechny události. Zde se eventId rovná 0. globals.brArray={} globals.br_time=0 --Toto je zřejmě inicializace startovních proměnných. __had_begin__ = true --Proměnné __had_begin__ se nastaví true, je možno ji použít třeba v případě, pokud potřebujeme zjistit, zda místnost odstartovala. (if __had_begin__ then ... end)
Celá náhrada za událost je na jednom řádku, aby chybové zprávy ukazovaly správný řádek. Zde si jednotlivé části události rozepíšeme:
OnEvent(Enums.OnMoveStop, "OnMoveStop_0") function OnMoveStop_0(eventId, objectId, direction) assert(guppy ~= nil, "Object guppy does not exist.") if objectId ~= guppy then return end local posX = ObjectX(objectId) local posY = ObjectY(objectId)
Na začátku se zaregistruje funkce, funkci OnMoveStop_0 se nyní předávají již tři parametry, číslo události, id objektu, který vykonal událost, a u pohybových událostí i směr pohybu. Zkontroluje se, zda objekt guppy existuje a jestli tuto událost skutečně vyvolal. Poté se vytvoří lokální proměnné posX a posY, které můžeme použít rychleji bez použití ObjectX a ObjectY.
Jedna funkce pro více události
Z předchozího příkladu jsme pochopili, čím se ve skutečnosti nahrazují události. Tento příklad můžeme využít a trochu si pozměníme jeho funkci.
OnEvent(Enums.OnMoveStop, "MojeUdalost")
OnEvent(Enums.OnFallStop, "MojeUdalost")
function MojeUdalost(eventId, objectId, direction)
…
end
Tímto jsme docílili zaregistrování jedné funkce MojeUdalost pro více událostí. Jelikož události OnMoveStop a OnFallStop mají stejné parametry, můžeme je jednoduše použít.
EventId
Proměnná eventId slouží k identifikování události nebo k jejímu vypnutí a zapnutí. K tomu slouží makra DISABLE a ENABLE (popř. GLOBAL_DISABLE a GLOBAL_ENABLE). Za DISABLE se ve skutečnosti nahradí Disable(eventId). Z toho již můžeme pochopit, jak třeba vypnout událost z jiného místa, viz příklad:
ON_MOVE_BEGIN flounder
OnMoveBeginFlounderId = eventId
…
end
ON_MOVE_BEGIN guppy
if OnMoveBeginFlounderId then Disable(OnMoveBeginFlounderId) end
end
Tento příklad zařídí, že pokud se pohne dříve Guppyová než Flounder, už se jeho událost nezavolá. Bohužel pro funkčnost je potřeba, aby se Flounder pohnul první, jinak se nenastaví proměnná OnMoveBeginFlounderId.
Vlastní událost
Na závěr si vytvoříme jednoduše pomocí ON_TIMER vlastní pseudoudálost
OnTurn, která se zavolá při otočení živočicha.
do
local lookdirs = {}
local OnTurnEvents = {}
ON_TIMER 0.01
if not __had_begin__ then return end
for objectId = 0, Room():GetObjectsCount()-1, 1 do
obj = Object(objectId)
if not obj then break end
if obj:IsCritter() then
local crit = obj:AsCritter()
local critid = crit:GetId()
local olddir = lookdirs[critid]
local newdir = crit:GetLookDir()
lookdirs[critid] = newdir
if olddir ~= newdir and olddir then
for k,v in pairs(OnTurnEvents) do
_G[v](critid, newdir)
end
end
end
end
end
function AddTurnEvent(funcname)
table.insert(OnTurnEvents, funcname)
end
function RemoveTurnEvent(funcname)
for k,v in pairs(OnTurnEvents) do
if v == funcname then
OnTurnEvents[k] = nil
end
end
end
end
AddTurnEvent("TestTurn")
function TestTurn(objectId, dir)
if objectId ~= guppy then return end
…
end