[[http://www.siedler-games.de|{{:sg-link.jpg|}}]]
====== Einführung ======
Ein Countdown ist eine, auf dem Bildschirm eingeblendete, Zeit die abläuft.
Dies sollte aus diversen Missionen bekannt sein.
Beliebt ist zum Beispiel "in 5 Minuten, 48 Sekunden greift der Gegner an".
Hiermit sollte man aber sparsam umgehen. Zum einen nimmt es die (eventuell gewollte) Überraschung, zum anderen setzt es den Spieler unter Druck. Das erzeugt Stress, und einige möchten gerne stressfrei siedeln.
Andererseits ist es natürlich schön zu wissen, daß die ersehnte Verstärkung, die einem helfen soll einen ansonsten vernichtenden Angriff zurückzuschlagen, in wenigen Minuten eintrifft.
Vielleicht möchte man den Spieler auch genau wissen lassen, wie lange er ein Tor noch verteidigen muss bevor es geschlossen werden kann.
Sowohl der Start eines Timers, als auch dessen Ende sollten immer mit einem Briefing verbunden werden, damit der Spieler weiß was passiert / passieren wird.
Der Start muss im "finished" eines Briefings geschehen, da der Spieler sonst vielleicht das Briefing so schnell wie möglich "durchklicken" möchte, um möglichst viel Zeit über zu haben.
Der manuelle Stopp, also die Beendingung des Countdowns aufgrund eines anderen Ereignisses, muss vor dem Briefing geschehen, da ansonsten Sieg und Niederlage davon abhängen könnte, wie schnell der Spieler das Briefing durchklickt.
Es ist möglich sowohl sichtbare, als auch unsichtbare (stille) Countdowns zu starten. Es kann nur ein sichtbarer Countdown zur Zeit existieren. Natürlich können neben einem sichtbaren Countdown noch beliebig viele stille Countdowns gleichzeitig laufen.
====== Funktionsweise ======
===== Countdown starten =====
Id = StartCountdown( _Limit, _Callback, _Show )
//_Limit// sind die Sekunden die der Countdown läuft. \\
//_Callback// ist die Funktion, die aufgerufen wird wenn der Countdown abgelaufen ist; den Funktionsnamen ohne Klammern und Anführungszeichen angeben; die Callback Funktion ist optional, es wäre aber unlogisch keine anzugeben. \\
//_Show// auf true setzen wenn der Countdown angezeigt werden soll; wenn kein Wert oder false angegeben wird ist es ein stiller Countdown. \\
Die Funktion gibt die Id des Countdowns zurück. Diese wird benötigt, um den Countdown abbrechen zu können.
===== Countdown abbrechen =====
StopCountdown( _Id )
//_Id// kann eine Id eines vorher mit StartCountdown() gestarteten Countdowns sein -- Wenn keine Id übergeben wird, werden alle laufenden Countdowns abgebrochen.
====== Anwendungsbeispiele ======
===== Einfach =====
Start eines sichtbaren 5 Minuten Countdowns. Sobald dieser abgelaufen ist wird OnCountdownFinished() aufgerufen:
StartCountdown( 5 * 60, OnCountdownFinished, true )
===== Start und Abbruch =====
Dieser Code kann zum Testen in eine neue Map kopiert werden. Er demonstriert das Starten und Abbrechen von Countdowns
--[[
Am Anfang werden zwei Countdowns gestartet: Ein Sichtbarer und ein Stiller. Vom ersten wird die Id gespeichert.
Der zweite unterbricht mit seiner Callback Funktion den ersten in der Hälfte der abgelaufenen Zeit.
Dann wird ein stiller Countdown gestartet der in 10 Sekunden einen weiteren sichtbaren Countdown aufruft.
Nach weiteren 20 Sekunden wird dann die Nachricht: "Countdown abgelaufen" ausgegeben
]]
function FirstMapAction()
id = StartCountdown(20, nil, true)
StartCountdown(10, CountdownBreak)
end
function CountdownBreak()
StopCountdown(id)
Message("Countdown abgebrochen")
StartCountdown(10, NewCountdown)
end
function NewCountdown()
StartCountdown(20, CountdownFinished, true)
end
function CountdownFinished()
Message("Countdown abgelaufen")
end
===== Respawn von Armeen =====
Angreifende Armeen erscheinen nach Ablauf eines sichtbaren Countdowns erneut.
function FirstMapAction()
CreateArmyOne()
end
function CreateArmyOne()
armyOne = {}
armyOne.id = 1
...
SetupArmy(armyOne)
local troopDescription = {
leaderType = Entities.PU_LeaderHeavyCavalry1,
...
}
for i = 1, 3 do
EnlargeArmy(armyOne, troopDescription)
end
StartSimpleJob("ControlArmyOne")
end
function ControlArmyOne()
if not armyOne.created then
armyOne.created = not IsDead(armyOne)
return false
end
if IsDead(armyOne) then
-- Angreifende Armee ist tot. Nach 2 Minuten (120 Sekunden) soll die nächste Armee angreifen. Gleichzeitig wird ein Countdown im Spiel angezeigt.
StartCountdown(120, CreateArmyOne, true)
return true
else
-- Armee lebt noch. In die feindliche Stadt gehen und da alles niedermetzeln.
Redeploy(armyOne, "enemycity", 5000)
end
end
====== Benötigte Funktionen ======
Da die Verwendung der spielinternen Funktionen für Countdowns zu umständlich ist, wurden Comfort Funktionen dafür geschrieben, deren Verwendungsweise hier gezeigt wurde. Diese Funktionen müssen natürlich für die Verwendung unverändert ins Script kopiert werden.
function StartCountdown(_Limit, _Callback, _Show)
assert(type(_Limit) == "number")
assert( not _Callback or type(_Callback) == "function" )
Counter.Index = (Counter.Index or 0) + 1
if _Show and CountdownIsVisisble() then
assert(false, "StartCountdown: A countdown is already visible")
end
Counter["counter" .. Counter.Index] = {Limit = _Limit, TickCount = 0, Callback = _Callback, Show = _Show, Finished = false}
if _Show then
MapLocal_StartCountDown(_Limit)
end
if Counter.JobId == nil then
Counter.JobId = StartSimpleJob("CountdownTick")
end
return Counter.Index
end
function StopCountdown(_Id)
if Counter.Index == nil then
return
end
if _Id == nil then
for i = 1, Counter.Index do
if Counter.IsValid("counter" .. i) then
if Counter["counter" .. i].Show then
MapLocal_StopCountDown()
end
Counter["counter" .. i] = nil
end
end
else
if Counter.IsValid("counter" .. _Id) then
if Counter["counter" .. _Id].Show then
MapLocal_StopCountDown()
end
Counter["counter" .. _Id] = nil
end
end
end
function CountdownTick()
local empty = true
for i = 1, Counter.Index do
if Counter.IsValid("counter" .. i) then
if Counter.Tick("counter" .. i) then
Counter["counter" .. i].Finished = true
end
if Counter["counter" .. i].Finished and not IsBriefingActive() then
if Counter["counter" .. i].Show then
MapLocal_StopCountDown()
end
-- callback function
if type(Counter["counter" .. i].Callback) == "function" then
Counter["counter" .. i].Callback()
end
Counter["counter" .. i] = nil
end
empty = false
end
end
if empty then
Counter.JobId = nil
Counter.Index = nil
return true
end
end
function CountdownIsVisisble()
for i = 1, Counter.Index do
if Counter.IsValid("counter" .. i) and Counter["counter" .. i].Show then
return true
end
end
return false
end