рдЦреЗрд▓реЛрдВ рдореЗрдВ рдХрдЯрдХрдиреЗрд╕ рдФрд░ рдХреНрд░рд┐рдпрд╛рдУрдВ рдХреЗ рдЕрдиреБрдХреНрд░рдо рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди

рдЗрд╕ рдкреЛрд╕реНрдЯ рдореЗрдВ рдореИрдВ рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░реВрдВрдЧрд╛ рдХрд┐ рдЖрдк рд╡реАрдбрд┐рдпреЛ рдЧреЗрдо рдореЗрдВ рдХреНрд░рд┐рдпрд╛рдУрдВ рдФрд░ рдХрдЯрдХреИрд╕реЗрди рдХреЗ рдЕрдиреБрдХреНрд░рдо рдХреЛ рдХреИрд╕реЗ рд▓рд╛рдЧреВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдпрд╣ рд▓реЗрдЦ рдЗрд╕ рд▓реЗрдЦ рдХрд╛ рдЕрдиреБрд╡рд╛рдж рд╣реИ рдФрд░ рдЗрд╕реА рд╡рд┐рд╖рдп рдкрд░ рдореИрдВрдиреЗ рдореЙрд╕реНрдХреЛ рдХреЗ рд▓реБрдЖ рдореЗрдВ рдПрдХ рдкреНрд░рд╕реНрддреБрддрд┐ рджреА, рдЗрд╕рд▓рд┐рдП рдпрджрд┐ рдЖрдк рд╡реАрдбрд┐рдпреЛ рджреЗрдЦрдирд╛ рдкрд╕рдВрдж рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рдЗрд╕реЗ рдпрд╣рд╛рдБ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ ред

рд▓реЗрдЦ рдХреЛрдб рд▓реБрдЖ рдореЗрдВ рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЖрд╕рд╛рдиреА рд╕реЗ рдЕрдиреНрдп рднрд╛рд╖рд╛рдУрдВ рдореЗрдВ рд▓рд┐рдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ (рд╡рд┐рдзрд┐ рдХреЗ рдЕрдкрд╡рд╛рдж рдХреЗ рд╕рд╛рде рдЬреЛ рдХреЛрд░рдЯрд╛рдЗрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рд╡реЗ рд╕рднреА рднрд╛рд╖рд╛рдУрдВ рдореЗрдВ рдирд╣реАрдВ рд╣реИрдВ)ред

рд▓реЗрдЦ рджрд┐рдЦрд╛рддрд╛ рд╣реИ рдХрд┐ рдПрдХ рддрдВрддреНрд░ рдХреИрд╕реЗ рдмрдирд╛рдпрд╛ рдЬрд╛рдП рдЬреЛ рдЖрдкрдХреЛ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдлреЙрд░реНрдо рдХреЗ рдХрдЯрдХрдиреЗрд╕реЗрд╕ рд▓рд┐рдЦрдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ:

local function cutscene(player, npc) player:goTo(npc) if player:hasCompleted(quest) then npc:say("You did it!") delay(0.5) npc:say("Thank you") else npc:say("Please help me") end end 

рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐


рдПрдХреНрд╢рди рд╕реАрдХреНрд╡реЗрдВрд╕ рдЕрдХреНрд╕рд░ рд╡реАрдбрд┐рдпреЛ рдЧреЗрдо рдореЗрдВ рдкрд╛рдП рдЬрд╛рддреЗ рд╣реИрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, cutscenes рдореЗрдВ: рдЪрд░рд┐рддреНрд░ рджреБрд╢реНрдорди рд╕реЗ рдорд┐рд▓рддрд╛ рд╣реИ, рдЙрд╕реЗ рдХреБрдЫ рдХрд╣рддрд╛ рд╣реИ, рджреБрд╢реНрдорди рдЬрд╡рд╛рдм рджреЗрддрд╛ рд╣реИ, рдФрд░ рдЗрд╕реА рддрд░рд╣ред рдЧреЗрдордкреНрд▓реЗ рдореЗрдВ рдХреНрд░рд┐рдпрд╛рдУрдВ рдХрд╛ рдХреНрд░рдо рдкрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдЗрд╕ gif рдкрд░ рдПрдХ рдирдЬрд╝рд░ рдбрд╛рд▓реЗрдВ:



1. рджрд░рд╡рд╛рдЬрд╛ рдЦреБрд▓рддрд╛ рд╣реИ
2. рдЪрд░рд┐рддреНрд░ рдШрд░ рдореЗрдВ рдкреНрд░рд╡реЗрд╢ рдХрд░рддрд╛ рд╣реИ
3. рджрд░рд╡рд╛рдЬрд╛ рдмрдВрдж рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ
4. рд╕реНрдХреНрд░реАрди рдзреАрд░реЗ-рдзреАрд░реЗ рдЧрд╣рд░рд╛рддреА рд╣реИ
5. рд╕реНрддрд░ рдмрджрд▓рддрд╛ рд╣реИ
6. рд╕реНрдХреНрд░реАрди рдЪрдордХреАрд▓реА рдлреАрдХреА рдкрдбрд╝ рдЬрд╛рддреА рд╣реИ
7. рдЪрд░рд┐рддреНрд░ рдХреИрдлреЗ рдореЗрдВ рдкреНрд░рд╡реЗрд╢ рдХрд░рддрд╛ рд╣реИ

рдХреНрд░рд┐рдпрд╛рдУрдВ рдХреЗ рдЕрдиреБрдХреНрд░рдореЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдПрдирдкреАрд╕реА рдХреЗ рд╡реНрдпрд╡рд╣рд╛рд░ рдХреЛ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХрд░рдиреЗ рдпрд╛ рдмреЙрд╕ рдХреА рд▓рдбрд╝рд╛рдЗрдпреЛрдВ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рднреА рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдмреЙрд╕ рдХреБрдЫ рдХреНрд░рд┐рдпрд╛рдУрдВ рдХреЛ рдПрдХ рджреВрд╕рд░реЗ рд╕реЗ рдХрд░рддрд╛ рд╣реИред

рд╕рдорд╕реНрдпрд╛


рдПрдХ рдорд╛рдирдХ рдЧреЗрдо рд▓реВрдк рдХреА рд╕рдВрд░рдЪрдирд╛ рдПрдХреНрд╢рди рджреГрд╢реНрдпреЛрдВ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛ рдХрдард┐рди рдмрдирд╛рддреА рд╣реИред рдорд╛рди рд▓реАрдЬрд┐рдП рдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЧреЗрдо рд▓реВрдк рд╣реИрдВ:



 while game:isRunning() do processInput() dt = clock.delta() update(dt) render() end 

рд╣рдо рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд cutscene рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ: рдЦрд┐рд▓рд╛рдбрд╝реА рдПрдирдкреАрд╕реА рд╕реЗ рд╕рдВрдкрд░реНрдХ рдХрд░рддрд╛ рд╣реИ, рдПрдирдкреАрд╕реА рдХрд╣рддрд╛ рд╣реИ: "рдЖрдкрдиреЗ рдпрд╣ рдХрд┐рдпрд╛!", рдФрд░ рдлрд┐рд░ рдПрдХ рдЫреЛрдЯреЗ рд╕реЗ рдард╣рд░рд╛рд╡ рдХреЗ рдмрд╛рдж рдХрд╣рддрд╛ рд╣реИ: "рдзрдиреНрдпрд╡рд╛рдж!"ред рдПрдХ рдЖрджрд░реНрд╢ рджреБрдирд┐рдпрд╛ рдореЗрдВ, рд╣рдо рдЗрд╕реЗ рдЗрд╕ рддрд░рд╣ рд╕реЗ рд▓рд┐рдЦреЗрдВрдЧреЗ:

 player:goTo(npc) npc:say("You did it!") delay(0.5) npc:say("Thank you") 

рдФрд░ рдпрд╣рд╛рдБ рд╣рдо рдПрдХ рд╕рдорд╕реНрдпрд╛ рдХрд╛ рд╕рд╛рдордирд╛ рдХрд░ рд░рд╣реЗ рд╣реИрдВред рдЪрд░рдгреЛрдВ рдХреЛ рдкреВрд░рд╛ рдХрд░рдиреЗ рдореЗрдВ рдХреБрдЫ рд╕рдордп рд▓рдЧрддрд╛ рд╣реИред рдХреБрдЫ рдХреНрд░рд┐рдпрд╛рдПрдВ рдЦрд┐рд▓рд╛рдбрд╝реА рд╕реЗ рдЗрдирдкреБрдЯ рдХрд╛ рдЗрдВрддрдЬрд╛рд░ рднреА рдХрд░ рд╕рдХрддреА рд╣реИрдВ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдбрд╛рдпрд▓реЙрдЧ рдмреЙрдХреНрд╕ рдХреЛ рдмрдВрдж рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП)ред delay рдлрд╝рдВрдХреНрд╢рди рдХреЗ рдмрдЬрд╛рдп, рдЖрдк рдПрдХ рд╣реА sleep рдХреЛ рдирд╣реАрдВ рдмреБрд▓рд╛ рд╕рдХрддреЗ sleep - рдРрд╕рд╛ рд▓рдЧреЗрдЧрд╛ рдЬреИрд╕реЗ рдЧреЗрдо рдЬрдореА рд╣реИред

рдЖрдЗрдП рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреБрдЫ рджреГрд╖реНрдЯрд┐рдХреЛрдгреЛрдВ рдкрд░ рдПрдХ рдирдЬрд╝рд░ рдбрд╛рд▓реЗрдВред

рдмреВрд▓, рдПрдирдо, рд░рд╛рдЬреНрдп рдорд╢реАрдиреЗрдВ


рдХреНрд░рд┐рдпрд╛рдУрдВ рдХреЗ рдЕрдиреБрдХреНрд░рдо рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХрд╛ рд╕рдмрд╕реЗ рд╕реНрдкрд╖реНрдЯ рддрд░реАрдХрд╛ рд╣реИ рдХрд┐ рд╡рд░реНрддрдорд╛рди рд╕реНрдерд┐рддрд┐ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рдХреЛ рдмреВрд▓, рд▓рд╛рдЗрдиреЛрдВ рдпрд╛ рдПрдирдо рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рдирд╛ред рдХреЛрдб рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦреЗрдЧрд╛:

 function update(dt) if cutsceneState == 'playerGoingToNpc' then player:continueGoingTo(npc) if player:closeTo(npc) then cutsceneState = 'npcSayingYouDidIt' dialogueWindow:show("You did it!") end elseif cutsceneState == 'npcSayingYouDidIt' then if dialogueWindow:wasClosed() then cutsceneState = 'delay' end elseif ... ... --   ... end end 

рдпрд╣ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдЖрд╕рд╛рдиреА рд╕реЗ рд╕реНрдкреЗрдЧреЗрдЯреА рдХреЛрдб рдФрд░ рдЗрдл-рдЗрдореЛрд╢рди рдХреА рд▓рдВрдмреА рд╢реНрд░реГрдВрдЦрд▓рд╛рдУрдВ рдХреА рдУрд░ рдЬрд╛рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдореИрдВ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рдЗрд╕ рддрд░реАрдХреЗ рд╕реЗ рдмрдЪрдиреЗ рдХреА рд╕рд▓рд╛рд╣ рджреЗрддрд╛ рд╣реВрдВред

рдХрд╛рд░реНрд░рд╡рд╛рдИ рдХреА рд╕реВрдЪреА


рдХрд╛рд░реНрд░рд╡рд╛рдИ рд╕реВрдЪреА рд░рд╛рдЬреНрдп рдорд╢реАрдиреЛрдВ рдХреЗ рд╕рдорд╛рди рд╣реИред рдПрдХреНрд╢рди рд▓рд┐рд╕реНрдЯ рдПрдХ рдХреЗ рдмрд╛рдж рдПрдХ рдХреА рдЬрд╛рдиреЗ рд╡рд╛рд▓реА рдХреНрд░рд┐рдпрд╛рдУрдВ рдХреА рд╕реВрдЪреА рд╣реИред рдЧреЗрдо рд▓реВрдк рдореЗрдВ, update рдлрд╝рдВрдХреНрд╢рди рдХреЛ рд╡рд░реНрддрдорд╛рди рдХрд╛рд░реНрд░рд╡рд╛рдИ рдХреЗ рд▓рд┐рдП рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬреЛ рд╣рдореЗрдВ рдЗрдирдкреБрдЯ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдиреЗ рдФрд░ рдЧреЗрдо рдХреЛ рдкреНрд░рд╕реНрддреБрдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рднрд▓реЗ рд╣реА рдХрд╛рд░реНрд░рд╡рд╛рдИ рдореЗрдВ рд▓рдВрдмрд╛ рд╕рдордп рд▓рдЧрддрд╛ рд╣реЛред рдХрд╛рд░реНрд░рд╡рд╛рдИ рдкреВрд░реА рд╣реЛрдиреЗ рдХреЗ рдмрд╛рдж, рд╣рдо рдЕрдЧрд▓реЗ рдкрд░ рдЬрд╛рддреЗ рд╣реИрдВред

рдХрдЯрдХреАрди рдореЗрдВ рдЬрд┐рд╕реЗ рд╣рдо рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рд╣рдореЗрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ: GoToAction, DialogueAction рдФрд░ DelayActionред

рдЖрдЧреЗ рдХреЗ рдЙрджрд╛рд╣рд░рдгреЛрдВ рдХреЗ рд▓рд┐рдП, рдореИрдВ Lua рдореЗрдВ OOP рдХреЗ рд▓рд┐рдП рдорд┐рдбрд┐рд▓рдХреНрд▓рд╛рд╕ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реВрдВрдЧрд╛ред

рдпрд╣рд╛рдВ рдмрддрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ рдХрд┐ DelayAction рдХреИрд╕реЗ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ DelayAction рд╣реИ:

 --  function DelayAction:initialize(params) self.delay = params.delay self.currentTime = 0 self.isFinished = false end function DelayAction:update(dt) self.currentTime = self.currentTime + dt if self.currentTime > self.delay then self.isFinished = true end end 

ActionList:update рдлрд╝рдВрдХреНрд╢рди рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:

 function ActionList:update(dt) if not self.isFinished then self.currentAction:update(dt) if self.currentAction.isFinished then self:goToNextAction() if not self.currentAction then self.isFinished = true end end end end 

рдФрд░ рдЕрдВрдд рдореЗрдВ, рд╕реНрд╡рдпрдВ cutscene рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди:

 function makeCutsceneActionList(player, npc) return ActionList:new { GoToAction:new { entity = player, target = npc }, SayAction:new { entity = npc, text = "You did it!" }, DelayAction:new { delay = 0.5 }, SayAction:new { entity = npc, text = "Thank you" } } end -- ... -    actionList:update(dt) 

рдиреЛрдЯ : Lua рдореЗрдВ, someFunction({ ... }) рдХреЙрд▓ рдЗрд╕ рддрд░рд╣ рд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ: someFunction{...} ред рдпрд╣ рдЖрдкрдХреЛ DelayAction:new{ delay = 0.5 } рд▓рд┐рдЦрдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ DelayAction:new{ delay = 0.5 } рдмрдЬрд╛рдп DelayAction:new{ delay = 0.5 } DelayAction:new({delay = 0.5}) ред

рдпрд╣ рдмрд╣реБрдд рдмреЗрд╣рддрд░ рд▓рдЧ рд░рд╣рд╛ рд╣реИред рдХреЛрдб рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдХреНрд░рд┐рдпрд╛рдУрдВ рдХрд╛ рдХреНрд░рдо рджрд┐рдЦрд╛рддрд╛ рд╣реИред рдпрджрд┐ рд╣рдо рдПрдХ рдирдИ рдХреНрд░рд┐рдпрд╛ рдЬреЛрдбрд╝рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рд╣рдо рдЖрд╕рд╛рдиреА рд╕реЗ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред DelayAction рдХрдХреНрд╖рд╛рдПрдВ рдмрдирд╛рдиреЗ рдореЗрдВ рдпрд╣ рдХрд╛рдлреА рд╕рд░рд▓ рд╣реИ рдХрд┐ DelayAction рдХреЛ рдФрд░ рдЕрдзрд┐рдХ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдмрдирд╛рдпрд╛ рдЬрд╛ рд╕рдХреЗред

рдореИрдВ рдЖрдкрдХреЛ рд╕рд▓рд╛рд╣ рджреЗрддрд╛ рд╣реВрдВ рдХрд┐ рдЖрдк рдПрдХреНрд╢рди рд▓рд┐рд╕реНрдЯ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕реАрди рдорд┐рдбрд┐рд▓рдбрд┐рдЪ рдХреА рдкреНрд░рд╕реНрддреБрддрд┐ рджреЗрдЦреЗрдВ, рдЬреЛ рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рдЙрджрд╛рд╣рд░рдг рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред


рдХрд╛рд░реНрд░рд╡рд╛рдИ рд╕реВрдЪреА рдЖрдо рддреМрд░ рдкрд░ рдмрд╣реБрдд рдЙрдкрдпреЛрдЧреА рд╣реЛрддреА рд╣реИред рдореИрдВрдиреЗ рдЙрдиреНрд╣реЗрдВ рдХрд╛рдлреА рд╕рдордп рддрдХ рдЕрдкрдиреЗ рдЦреЗрд▓ рдХреЗ рд▓рд┐рдП рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд┐рдпрд╛ рдФрд░ рдХреБрд▓ рдорд┐рд▓рд╛рдХрд░ рдЦреБрд╢реА рд╣реБрдИред рд▓реЗрдХрд┐рди рдЗрд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдореЗрдВ рдХрдорд┐рдпрд╛рдВ рднреА рд╣реИрдВред рдорд╛рди рд▓реЗрдВ рдХрд┐ рд╣рдо рдХреБрдЫ рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рдХрдЯрдХрд┐рди рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ:

 local function cutscene(player, npc) player:goTo(npc) if player:hasCompleted(quest) then npc:say("You did it!") delay(0.5) npc:say("Thank you") else npc:say("Please help me") end end 

рдПрдХ / рдЕрдиреНрдп рд╕рд┐рдореБрд▓реЗрд╢рди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдЧреИрд░-рд░реЗрдЦреАрдп рд╕реВрдЪрд┐рдпреЛрдВ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдпрд╣ рдЯреИрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдХреБрдЫ рдХреНрд░рд┐рдпрд╛рдУрдВ рдХреЛ рдЯреИрдЧ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдФрд░ рдлрд┐рд░, рдХреБрдЫ рд╢рд░реНрдд рдХреЗ рджреНрд╡рд╛рд░рд╛, рдЕрдЧрд▓реА рдХреНрд░рд┐рдпрд╛ рдкрд░ рдЬрд╛рдиреЗ рдХреЗ рдмрдЬрд╛рдп, рдЖрдк рдПрдХ рдРрд╕реЗ рдХрд╛рд░реНрдп рдкрд░ рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВ рдЬрд┐рд╕рдореЗрдВ рд╡рд╛рдВрдЫрд┐рдд рдЯреИрдЧ рд╣реЛред рдпрд╣ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рд╣рд╛рд▓рд╛рдВрдХрд┐ рдЙрдкрд░реЛрдХреНрдд рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд░реВрдк рдореЗрдВ рдкрдврд╝рдирд╛ рдФрд░ рд▓рд┐рдЦрдирд╛ рдЗрддрдирд╛ рдЖрд╕рд╛рди рдирд╣реАрдВ рд╣реИред

Lua coroutines рдЗрд╕ рдХреЛрдб рдХреЛ рдПрдХ рд╡рд╛рд╕реНрддрд╡рд┐рдХрддрд╛ рдмрдирд╛рддреЗ рд╣реИрдВред

Korutiny


рд▓реБрдЖ рдореЗрдВ рдХреЛрд░реБрдЖ рдореВрд▓ рдмрд╛рддреЗрдВ


рдХреЛрд░реБрдЯрд┐рди рдПрдХ рдлрд╝рдВрдХреНрд╢рди рд╣реИ рдЬрд┐рд╕реЗ рд░реЛрдХрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рдлрд┐рд░ рдмрд╛рдж рдореЗрдВ рдлрд┐рд░ рд╕реЗ рд╢реБрд░реВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдореБрдЦреНрдп рдХрд╛рд░реНрдпрдХреНрд░рдо рдХреЗ рд░реВрдк рдореЗрдВ рдПрдХ рд╣реА рдзрд╛рдЧреЗ рдореЗрдВ рдХреЛрд░рдЖрдЙрдЯ рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдХреЛрд░рдЯрд╛рдЗрди рдХреЗ рд▓рд┐рдП рдХреЛрдИ рдирдпрд╛ рдзрд╛рдЧрд╛ рдХрднреА рдирд╣реАрдВ рдмрдирд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

coroutine.yield рдХреЛ рд░реЛрдХрдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ coroutine.yield рдХреЛ рдХреЙрд▓ рдХрд░рдирд╛ рд╣реЛрдЧрд╛, рдлрд┐рд░ рд╕реЗ рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП - coroutine.resume ред рдПрдХ рд╕рд░рд▓ рдЙрджрд╛рд╣рд░рдг:

 local function f() print("hello") coroutine.yield() print("world!") end local c = coroutine.create(f) coroutine.resume(c) print("uhh...") coroutine.resume(c) 

рдХрд╛рд░реНрдпрдХреНрд░рдо рдХрд╛ рдЖрдЙрдЯрдкреБрдЯ:

 рдирдорд╕реНрддреЗ
 рдЙрд╣ ...
 рджреБрдирд┐рдпрд╛


рдпрд╣рд╛рдБ рдпрд╣ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╣рдо coroutine.create рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ coroutine.create рдмрдирд╛рддреЗ рд╣реИрдВред рдЗрд╕ рдХреЙрд▓ рдХреЗ рдмрд╛рдж, рдХреЙрд░рдЯрд┐рди рд╢реБрд░реВ рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИред рдРрд╕рд╛ рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдЗрд╕реЗ coroutine.resume рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЪрд▓рд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рддрдм рдлрд╝рдВрдХреНрд╢рди f рдХреЛ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬреЛ "рд╣реЗрд▓реЛ" рд▓рд┐рдЦрддрд╛ рд╣реИ рдФрд░ рдХреЛрд░рдЯрд╛рдЗрди.рдлреАрд▓реНрдб рдХреЗ рд╕рд╛рде рдЦреБрдж рдХреЛ рд░реЛрдХ рджреЗрддрд╛ рд╣реИред рдпрд╣ return рд╕рдорд╛рди рд╣реИ, рд▓реЗрдХрд┐рди рд╣рдо coroutine.resume рд╕рд╛рде f рдХреЛ рдлрд┐рд░ рд╕реЗ рд╢реБрд░реВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рдпрджрд┐ рдЖрдк coroutine.yield рдХреЙрд▓ рдХрд░рддреЗ рд╕рдордп рддрд░реНрдХ рдкрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд╡реЗ "рдореБрдЦреНрдп рдзрд╛рд░рд╛" рдореЗрдВ coroutine.resume рд╕рдВрдмрдВрдзрд┐рдд рдХреЙрд▓ рдХреЗ рд░рд┐рдЯрд░реНрди рдорд╛рди рдмрди рдЬрд╛рдПрдВрдЧреЗред

рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП:

 local function f() ... coroutine.yield(42, "some text") ... end ok, num, text = coroutine.resume(c) print(num, text) -- will print '42 "some text"' 

ok рдПрдХ рд╡реИрд░рд┐рдПрдмрд▓ рд╣реИ рдЬреЛ рд╣рдореЗрдВ рдХреЛрд░рдЯрд╛рдЗрди рдХреА рд╕реНрдерд┐рддрд┐ рдЬрд╛рдирдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рдпрджрд┐ ok рд╣реИ, рддреЛ рдХреЛрд░рдЯрд╛рдЗрди рдХреЗ рд╕рд╛рде рд╕рдм рдХреБрдЫ рдареАрдХ рд╣реИ, рдЕрдВрджрд░ рдХреЛрдИ рддреНрд░реБрдЯрд┐ рдирд╣реАрдВ рд╣реБрдИ рд╣реИред рдЗрд╕рдХреЗ рдкреАрдЫреЗ рдХреЗ рдорд╛рди ( num , text ) рд╡рд╣реА рддрд░реНрдХ рд╣реИрдВ рдЬреЛ рд╣рдордиреЗ yield рд▓рд┐рдП рдкрд╛рд░рд┐рдд рдХрд┐рдП рдереЗред

рдпрджрд┐ ok false , рддреЛ рдХреЛрд░рдЯрд╛рдЗрди рдХреЗ рд╕рд╛рде рдХреБрдЫ рдЧрд▓рдд рд╣реЛ рдЧрдпрд╛ рдерд╛, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, error рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдЗрд╕рдХреЗ рдЕрдВрджрд░ рдмреБрд▓рд╛рдпрд╛ рдЧрдпрд╛ рдерд╛ред рдЗрд╕ рд╕реНрдерд┐рддрд┐ рдореЗрдВ, рджреВрд╕рд░рд╛ рд░рд┐рдЯрд░реНрди рдорд╛рди рдПрдХ рддреНрд░реБрдЯрд┐ рд╕рдВрджреЗрд╢ рд╣реЛрдЧрд╛ред рдХреЛрд░рдЯрд╛рдЗрди рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдЬрд┐рд╕рдореЗрдВ рдПрдХ рддреНрд░реБрдЯрд┐ рд╣реЛрддреА рд╣реИ:

 local function f() print(1 + notDefined) end c = coroutine.create(f) ok, msg = coroutine.resume(c) if not ok then print("Coroutine failed!", msg) end 

рдирд┐рд╖реНрдХрд░реНрд╖:

 Coroutine рд╡рд┐рдлрд▓!  рдЗрдирдкреБрдЯ: 4: рд╢реВрдиреНрдп рдорд╛рди (рд╡реИрд╢реНрд╡рд┐рдХ 'рдиреЛрдЯрд┐рдлрд╛рдЗрдб') рдкрд░ рдЕрдВрдХрдЧрдгрд┐рдд рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕


Coroutine рдХреА рд╕реНрдерд┐рддрд┐ coroutine.status рдХреЙрд▓ рдХрд░рдХреЗ рдкреНрд░рд╛рдкреНрдд рдХреА рдЬрд╛ рд╕рдХрддреА рд╣реИред Corutin рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╕реНрдерд┐рддрд┐рдпреЛрдВ рдореЗрдВ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ:

  • "рд░рдирд┐рдВрдЧ" - рд╡рд░реНрддрдорд╛рди рдореЗрдВ рдХреЛрд░реНрдЙрдЯрд┐рди рдЪрд▓ рд░рд╣рд╛ рд╣реИред corutine.status рдХреЛ corutin рд╕реЗ рд╣реА рдмреБрд▓рд╛рдпрд╛ рдЧрдпрд╛ рдерд╛
  • "рдирд┐рд▓рдВрдмрд┐рдд" - рдХреЛрд░реБрдЯрд┐рди рдХреЛ рд░реЛрдХ рджрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ рдпрд╛ рдХрднреА рднреА рд╢реБрд░реВ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛
  • "рд╕рд╛рдорд╛рдиреНрдп" - рдХреЛрд░реБрдЯрд┐рди рд╕рдХреНрд░рд┐рдп рд╣реИ, рд▓реЗрдХрд┐рди рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдпрд╛рдиреА, corutin рдиреЗ рдЕрдкрдиреЗ рднреАрддрд░ рдПрдХ рдФрд░ corutin рд▓реЙрдиреНрдЪ рдХрд┐рдпрд╛
  • "рдореГрдд" - coroutine рдкреВрд░реНрдг рдирд┐рд╖реНрдкрд╛рджрди (рдпрд╛рдиреА, coroutine рдкреВрд░рд╛ рд╣реБрдЖ)

рдЕрдм, рдЗрд╕ рдЬреНрдЮрд╛рди рдХреА рдорджрдж рд╕реЗ, рд╣рдо рдХреЛрд░рдЖрдЙрдЯреНрд╕ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдХреНрд░рд┐рдпрд╛рдУрдВ рдФрд░ рдХрдЯрдХреИрди рдХреЗ рдЕрдиреБрдХреНрд░рдореЛрдВ рдХреА рдПрдХ рдкреНрд░рдгрд╛рд▓реА рдХреЛ рд▓рд╛рдЧреВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

Corutin рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ cutscenes рдмрдирд╛рдирд╛


рдпрд╣рд╛рдВ рдирдИ рдкреНрд░рдгрд╛рд▓реА рдкрд░ рдЖрдзрд╛рд░ Action рдХреНрд▓рд╛рд╕ рдЬреИрд╕рд╛ рджрд┐рдЦреЗрдЧрд╛:

 function Action:launch() self:init() while not self.finished do local dt = coroutine.yield() self:update(dt) end self:exit() end 

рдПрдХреНрд╢рди рд╕реВрдЪрд┐рдпреЛрдВ рдХреЗ рд▓рд┐рдП рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╕рдорд╛рди рд╣реИ: рдХрд╛рд░реНрд░рд╡рд╛рдИ рдХрд╛ update рдлрд╝рдВрдХреНрд╢рди рддрдм рддрдХ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬрдм рддрдХ рдХрд┐ рдХрд╛рд░реНрд░рд╡рд╛рдИ рдкреВрд░реА рдирд╣реАрдВ рд╣реЛ рдЬрд╛рддреАред рд▓реЗрдХрд┐рди рдпрд╣рд╛рдВ рд╣рдо рдХреЛрд░рдЯрд╛рдЗрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдЧреЗрдо рд▓реВрдк рдХреЗ рдкреНрд░рддреНрдпреЗрдХ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдореЗрдВ yield рдХрд░рддреЗ рд╣реИрдВ ( Action:launch рдХреЛ рдХреБрдЫ рдХреЛрд░рдЖрдЙрдЯ рд╕реЗ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ)ред рдЧреЗрдо рд▓реВрдк рдХреЗ update рдореЗрдВ рдХрд╣реАрдВ рди рдХрд╣реАрдВ рд╣рдо рдЗрд╕ рддрд░рд╣ рд╕реЗ рд╡рд░реНрддрдорд╛рди рдХрдЯрдХ рдХрд╛ рдирд┐рд╖реНрдкрд╛рджрди рдлрд┐рд░ рд╕реЗ рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ:

 coroutine.resume(c, dt) 

рдФрд░ рдЕрдВрдд рдореЗрдВ, рдПрдХ cutscene рдмрдирд╛рдиреЗ:

 function cutscene(player, npc) player:goTo(npc) npc:say("You did it!") delay(0.5) npc:say("Thank you") end -- -  ... local c = coroutine.create(cutscene, player, npc) coroutine.resume(c, dt) 

рдпрд╣рд╛рдВ рдмрддрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ рдХрд┐ delay рдлрд╝рдВрдХреНрд╢рди рдХреИрд╕реЗ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ:

 function delay(time) action = DelayAction:new { delay = time } action:launch() end 

рдЗрд╕ рддрд░рд╣ рдХреЗ рд░реИрдкрд░ рдмрдирд╛рдиреЗ рд╕реЗ рдХрдЯрдХрд╕реАрди рдХреЛрдб рдХреА рдкрдардиреАрдпрддрд╛ рдореЗрдВ рд╕реБрдзрд╛рд░ рд╣реЛрддрд╛ рд╣реИред DelayAction рдЗрд╕ рддрд░рд╣ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ DelayAction :

 -- Action -   DelayAction local DelayAction = class("DelayAction", Action) function DelayAction:initialize(params) self.delay = params.delay self.currentTime = 0 self.isFinished = false end function DelayAction:update(dt) self.currentTime = self.currentTime + dt if self.currentTime >= self.delayTime then self.finished = true end end 

рдпрд╣ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдЙрд╕реА рдХреЗ рд╕рдорд╛рди рд╣реИ рдЬрд┐рд╕реЗ рд╣рдордиреЗ рдХреНрд░рд┐рдпрд╛ рд╕реВрдЪрд┐рдпреЛрдВ рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рд╣реИ! рдЖрдЗрдП Action:launch рдкрд░ рдПрдХ рдирдЬрд╝рд░ рдбрд╛рд▓реЗрдВ Action:launch рдлрд╝рдВрдХреНрд╢рди рдлрд┐рд░ рд╕реЗ:

 function Action:launch() self:init() while not self.finished do local dt = coroutine.yield() -- the most important part self:update(dt) end self:exit() end 

рдпрд╣рд╛рдВ рдореБрдЦреНрдп рдмрд╛рдд рдпрд╣ рд╣реИ рдХрд┐ while , рдЬреЛ рдХрд╛рд░реНрд░рд╡рд╛рдИ рдкреВрд░реА рд╣реЛрдиреЗ рддрдХ рдЪрд▓рддрд╛ рд╣реИред рдпрд╣ рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:



рдЖрдЗрдП рдЕрдм goTo рдлрд╝рдВрдХреНрд╢рди рдХреЛ рджреЗрдЦреЗрдВ:

 function Entity:goTo(target) local action = GoToAction:new { entity = self, target = target } action:launch() end function GoToAction:initialize(params) ... end function GoToAction:update(dt) if not self.entity:closeTo(self.target) then ... --  , AI else self.finished = true end end 

Coroutines рдШрдЯрдирд╛рдУрдВ рдХреЗ рд╕рд╛рде рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рдЪрд▓рддреА рд╣реИрдВред WaitForEventAction рд╡рд░реНрдЧ рдХреЛ рд▓рд╛рдЧреВ рдХрд░реЗрдВ:

 function WaitForEventAction:initialize(params) self.finished = false eventManager:subscribe { listener = self, eventType = params.eventType, callback = WaitForEventAction.onEvent } end function WaitForEventAction:onEvent(event) self.finished = true end 

рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рдХреЛ update рд╡рд┐рдзрд┐ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред рдпрд╣ рддрдм рддрдХ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ (рд╣рд╛рд▓рд╛рдВрдХрд┐ рдпрд╣ рдХреБрдЫ рднреА рдирд╣реАрдВ рдХрд░рддрд╛ ...) рдЬрдм рддрдХ рдХрд┐ рдпрд╣ рдЖрд╡рд╢реНрдпрдХ рдкреНрд░рдХрд╛рд░ рдХреЗ рд╕рд╛рде рдПрдХ рдШрдЯрдирд╛ рдкреНрд░рд╛рдкреНрдд рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред рдпрд╣рд╛рдБ рдЗрд╕ рд╡рд░реНрдЧ рдХрд╛ рд╡реНрдпрд╛рд╡рд╣рд╛рд░рд┐рдХ рдЕрдиреБрдкреНрд░рдпреЛрдЧ рд╣реИ - say рдХрд╛рд░реНрдп рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди:

 function Entity:say(text) DialogueWindow:show(text) local action = WaitForEventAction:new { eventType = 'DialogueWindowClosed' } action:launch() end 

рд╕рд░рд▓ рдФрд░ рдкрдардиреАрдпред рдЬрдм рд╕рдВрд╡рд╛рдж рдмреЙрдХреНрд╕ рдмрдВрдж рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдпрд╣ 'DialogueWindowClosed` рдкреНрд░рдХрд╛рд░ рдХреА рдПрдХ рдШрдЯрдирд╛ рднреЗрдЬ рджреЗрддрд╛ рд╣реИред рдХрд╣рдиреЗ рдХрд╛ рдХрд╛рд░реНрдп рд╕рдорд╛рдкреНрдд рд╣реЛрддрд╛ рд╣реИ рдФрд░ рдЕрдЧрд▓реЗ рдПрдХ рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдирд╛ рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИред

Coroutine рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ, рдЖрдк рдЖрд╕рд╛рдиреА рд╕реЗ рдиреЙрдирд▓рд╛рдЗрдирд┐рдпрд░ рдХрдЯрд╕реНрдХреИрди рдФрд░ рдбрд╛рдпрд▓реЙрдЧ рдЯреНрд░реА рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ:

 local answer = girl:say('do_you_love_lua', { 'YES', 'NO' }) if answer == 'YES' then girl:setMood('happy') girl:say('happy_response') else girl:setMood('angry') girl:say('angry_response') end 



рдЗрд╕ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, say рдлрд╝рдВрдХреНрд╢рди рдкрд╣рд▓реЗ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдереЛрдбрд╝рд╛ рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рд╣реИред рдпрд╣ рд╕рдВрд╡рд╛рдж рдореЗрдВ рдЦрд┐рд▓рд╛рдбрд╝реА рдХреА рдкрд╕рдВрдж рдХреЛ рд▓реМрдЯрд╛рддрд╛ рд╣реИ, рд╣рд╛рд▓рд╛рдВрдХрд┐ рдЗрд╕реЗ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдореБрд╢реНрдХрд┐рд▓ рдирд╣реАрдВ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, WaitForEventAction рдХреЛ WaitForEventAction рд╕реЗ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЬреЛ PlayerChoiceEvent рдИрд╡реЗрдВрдЯ рдХреЛ рдкрдХрдбрд╝ рд▓реЗрдЧрд╛ рдФрд░ рдлрд┐рд░ рдЙрд╕ рдкреНрд▓реЗрдпрд░ рдХреА рдкрд╕рдВрдж рдХреЛ рд▓реМрдЯрд╛рдПрдЧрд╛ рдЬрд┐рд╕рдХреА рдЬрд╛рдирдХрд╛рд░реА рдИрд╡реЗрдВрдЯ рдСрдмреНрдЬреЗрдХреНрдЯ рдореЗрдВ рд╢рд╛рдорд┐рд▓ рд╣реЛрдЧреАред

рдереЛрдбрд╝рд╛ рдФрд░ рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рдЙрджрд╛рд╣рд░рдг


рдХреЛрд░рдЯрд╛рдЗрди рдХреЗ рд╕рд╛рде, рдЖрдк рдЖрд╕рд╛рдиреА рд╕реЗ рдЯреНрдпреВрдЯреЛрд░рд┐рдпрд▓ рдФрд░ рдЫреЛрдЯреЗ quests рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП:

 girl:say("Kill that monster!") waitForEvent('EnemyKilled') girl:setMood('happy') girl:say("You did it! Thank you!") 



рдПрдЕрд░ рдЗрдВрдбрд┐рдпрд╛ рдХреЗ рд▓рд┐рдП рдХреЙрд░рдЖрдЙрдЯ рдХрд╛ рднреА рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЖрдк рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ рдЬрд┐рд╕рдХреЗ рд╕рд╛рде рд░рд╛рдХреНрд╖рд╕ рдХреБрдЫ рдкреНрд░рдХреНрд╖реЗрдкрд╡рдХреНрд░ рдХреЗ рд╕рд╛рде рдЖрдЧреЗ рдмрдврд╝реЗрдЧрд╛:

 function followPath(monster, path) local numberOfPoints = path:getNumberOfPoints() local i = 0 --      while true do monster:goTo(path:getPoint(i)) if i < numberOfPoints - 1 then i = i + 1 --     else --   i = 0 end end end 



рдЬрдм рд░рд╛рдХреНрд╖рд╕ рдЦрд┐рд▓рд╛рдбрд╝реА рдХреЛ рджреЗрдЦрддрд╛ рд╣реИ, рддреЛ рд╣рдо рдмрд╕ рдХреЛрд░рдЯрд╛рдЗрди рдХреЛ рдкреВрд░рд╛ рдХрд░рдирд╛ рдмрдВрдж рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЗрд╕реЗ рд╣рдЯрд╛ рд╕рдХрддреЗ рд╣реИрдВред рдЗрд╕рд▓рд┐рдП, followPath рднреАрддрд░ рдПрдХ рдЕрдирдВрдд рд▓реВрдк ( while true ) рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЕрдирдВрдд рдирд╣реАрдВ рд╣реИред

рдХреЛрд░реБрдЯрд┐рди рдХреЗ рд╕рд╛рде, рдЖрдк "рд╕рдорд╛рдирд╛рдВрддрд░" рдХреНрд░рд┐рдпрд╛рдПрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЬрдм рддрдХ рджреЛрдиреЛрдВ рдХрд╛рд░реНрд░рд╡рд╛рдИ рдкреВрд░реА рдирд╣реАрдВ рд╣реЛ рдЬрд╛рддреА рддрдм рддрдХ рдХрдЯрдХ рдЕрдЧрд▓реА рдХрд╛рд░реНрд░рд╡рд╛рдИ рдХреЗ рд▓рд┐рдП рдЖрдЧреЗ рдирд╣реАрдВ рдмрдврд╝реЗрдЧрд╛ред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╣рдо рдПрдХ рдХрдЯрдХ рдмрдирд╛рдпреЗрдВрдЧреЗ рдЬрд╣рд╛рдБ рдПрдХ рд▓рдбрд╝рдХреА рдФрд░ рдПрдХ рдмрд┐рд▓реНрд▓реА рдЕрд▓рдЧ-рдЕрд▓рдЧ рдЧрддрд┐ рд╕реЗ рдорд┐рддреНрд░ рдХреЗ рдмрд┐рдВрджреБ рдкрд░ рдЬрд╛рддреА рд╣реИред рдЙрдирдХреЗ рдЖрдиреЗ рдХреЗ рдмрд╛рдж, рдмрд┐рд▓реНрд▓реА рдХрд╣рддреА рд╣реИ "рдореНрдпрд╛рдК"ред

 function cutscene(cat, girl, meetingPoint) local c1 = coroutine.create( function() cat:goTo(meetingPoint) end) local c2 = coroutine.create( function() girl:goTo(meetingPoint) end) c1.resume() c2.resume() --  waitForFinish(c1, c2) --    cat:say("meow") ... end 

рдпрд╣рд╛рдВ рд╕рдмрд╕реЗ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣рд┐рд╕реНрд╕рд╛ waitForFinish рдлрдВрдХреНрд╢рди рд╣реИ, рдЬреЛ рдХрд┐ WaitForFinishAction рдХреНрд▓рд╛рд╕ рдХреЗ рдЖрд╕рдкрд╛рд╕ рдПрдХ рдЖрд╡рд░рдг рд╣реИ, рдЬрд┐рд╕реЗ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:

 function WaitForFinishAction:update(dt) if coroutine.status(self.c1) == 'dead' and coroutine.status(self.c2) == 'dead' then self.finished = true else if coroutine.status(self.c1) ~= 'dead' then coroutine.resume(self.c1, dt) end if coroutine.status(self.c2) ~= 'dead' then coroutine.resume(self.c2, dt) end end 

рдпрджрд┐ рдЖрдк Nth рдирдВрдмрд░ рдХреА рдХреНрд░рд┐рдпрд╛рдУрдВ рдХреЛ рд╕рд┐рдВрдХреНрд░рдирд╛рдЗрдЬрд╝ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рдЗрд╕ рд╡рд░реНрдЧ рдХреЛ рдЕрдзрд┐рдХ рд╢рдХреНрддрд┐рд╢рд╛рд▓реА рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВред

рдЖрдк рдПрдХ рдРрд╕рд╛ рд╡рд░реНрдЧ рднреА рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ рддрдм рддрдХ рдЗрдВрддрдЬрд╛рд░ рдХрд░реЗрдЧрд╛ рдЬрдм рддрдХ рдХрд┐ рд╕рднреА рдХреЛрд░реВрдЯрд╛рдЗрди рдореЗрдВ рд╕реЗ рдПрдХ рдкреВрд░рд╛ рдирд╣реАрдВ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ, рдмрдЬрд╛рдп рдЗрд╕рдХреЗ рдХрд┐ рд╕рднреА рдХреЛрд░рд╛рдЙрдЯрд╛рдЗрди рдХреЗ рдкреВрд░рд╛ рд╣реЛрдиреЗ рдХрд╛ рдЗрдВрддрдЬрд╛рд░ рдХрд┐рдпрд╛ рдЬрд╛рдПред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдорд┐рдиреА-рдЧреЗрдо рд░реЗрд╕рд┐рдВрдЧ рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдХреЛрд░рдЯрд╛рдЗрди рдХреЗ рдЕрдВрджрд░ рдПрдХ рд╕рд╡рд╛рд░ рдХреЗ рдлрд┐рдирд┐рд╢ рд▓рд╛рдЗрди рддрдХ рдкрд╣реБрдВрдЪрдиреЗ рдФрд░ рдлрд┐рд░ рдХреБрдЫ рд╕реАрдХреНрд╡реЗрдВрд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрдВрддрдЬрд╛рд░ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред

рдзрдирд┐рдпрд╛ рдХреЗ рдлрд╛рдпрджреЗ рдФрд░ рдиреБрдХрд╕рд╛рди


Coroutines рдПрдХ рдмрд╣реБрдд рд╣реА рдЙрдкрдпреЛрдЧреА рддрдВрддреНрд░ рд╣реИред рдЗрдирдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЖрдк cutscenes рдФрд░ рдЧреЗрдордкреНрд▓реЗ рдХреЛрдб рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ рдкрдврд╝рдиреЗ рдФрд░ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░рдиреЗ рдореЗрдВ рдЖрд╕рд╛рди рд╣реИред рдЗрд╕ рддрд░рд╣ рдХреЗ Cutscenes рдХреЛ рдЖрд╕рд╛рдиреА рд╕реЗ рдореЙрдбрд░реНрд╕ рдпрд╛ рдЙрди рд▓реЛрдЧреЛрдВ рджреНрд╡рд╛рд░рд╛ рд▓рд┐рдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдЬреЛ рдкреНрд░реЛрдЧреНрд░рд╛рдорд░ рдирд╣реАрдВ рд╣реИрдВ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЧреЗрдо рдпрд╛ рд╕реНрддрд░ рдХреЗ рдбрд┐рдЬрд╛рдЗрдирд░)ред

рдФрд░ рдпрд╣ рд╕рдм рдПрдХ рдзрд╛рдЧреЗ рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╕рд┐рдВрдХреНрд░рдирд╛рдЗрдЬрд╝реЗрд╢рди рдпрд╛ рджреМрдбрд╝ рдХреА рд╕реНрдерд┐рддрд┐ рдореЗрдВ рдХреЛрдИ рд╕рдорд╕реНрдпрд╛ рдирд╣реАрдВ рд╣реИред

рдЕрдкреНрд░реЛрдЪ рдХреЗ рдиреБрдХрд╕рд╛рди рд╣реИрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдмрдЪрдд рдХреЗ рд╕рд╛рде рд╕рдорд╕реНрдпрд╛рдПрдВ рд╣реЛ рд╕рдХрддреА рд╣реИрдВред рдорд╛рди рд▓реАрдЬрд┐рдП рдХрд┐ рдЖрдкрдХреЗ рдЧреЗрдо рдореЗрдВ рдХреЛрд░рдЯрд╛рдЗрди рдХреЗ рд╕рд╛рде рдПрдХ рд▓рдВрдмрд╛ рдЯреНрдпреВрдЯреЛрд░рд┐рдпрд▓ рд╣реИред рдЗрд╕ рдЯреНрдпреВрдЯреЛрд░рд┐рдпрд▓ рдХреЗ рджреМрд░рд╛рди рдЦрд┐рд▓рд╛рдбрд╝реА рд╕рд╣реЗрдЬ рдирд╣реАрдВ рдкрд╛рдПрдЧрд╛ рдХреНрдпреЛрдВрдХрд┐ рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдХреЛрд░рдЖрдЙрдЯ рдХреА рд╡рд░реНрддрдорд╛рди рд╕реНрдерд┐рддрд┐ (рдЬрд┐рд╕рдореЗрдВ рдЗрд╕рдХреА рдкреВрд░реА рд╕реНрдЯреИрдХ рдФрд░ рдЕрдВрджрд░ рд╡реИрд░рд┐рдПрдмрд▓ рдХреЗ рдореВрд▓реНрдп рд╢рд╛рдорд┐рд▓ рд╣реИрдВ) рдХреЛ рд╕рд╣реЗрдЬрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА, рддрд╛рдХрд┐ рд╕реЗрд╡ рд╕реЗ рдЖрдЧреЗ рд▓реЛрдб рд╣реЛрдиреЗ рдкрд░, рдЖрдк рдЯреНрдпреВрдЯреЛрд░рд┐рдпрд▓ рдЬрд╛рд░реА рд░рдЦ рд╕рдХреЗрдВред

( рдиреЛрдЯ : рдкреНрд▓реВрдЯреЛрд▓реНрдпреВрд▓реЗрдЯреНрд╕ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП, рдХреЛрд░рдЯрд╛рдЗрди рдХреЛ рдХреНрд░рдордмрджреНрдз рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреЗрд╡рд▓ рд▓реБрдЖ 5.1 рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддреА рд╣реИ)

рдпрд╣ рд╕рдорд╕реНрдпрд╛ рдХрдЯрдХрдиреЗрд╕ рдХреЗ рд╕рд╛рде рдирд╣реАрдВ рд╣реЛрддреА рд╣реИ, рдЬреИрд╕рд╛ рдХрд┐ рдЖрдорддреМрд░ рдкрд░ рдХрдЯрдХреАрди рдХреЗ рдмреАрдЪ рдХреЗ рдЦреЗрд▓ рдХреА рдЕрдиреБрдорддрд┐ рдирд╣реАрдВ рд╣реИред

рдпрджрд┐ рдЖрдк рдЗрд╕реЗ рдЫреЛрдЯреЗ рдЯреБрдХрдбрд╝реЛрдВ рдореЗрдВ рддреЛрдбрд╝рддреЗ рд╣реИрдВ, рддреЛ рдПрдХ рд▓рдВрдмреЗ рдЯреНрдпреВрдЯреЛрд░рд┐рдпрд▓ рдХреА рд╕рдорд╕реНрдпрд╛ рд╣рд▓ рд╣реЛ рд╕рдХрддреА рд╣реИред рдорд╛рди рд▓реАрдЬрд┐рдП рдХрд┐ рдПрдХ рдЦрд┐рд▓рд╛рдбрд╝реА рдЯреНрдпреВрдЯреЛрд░рд┐рдпрд▓ рдХреЗ рдкрд╣рд▓реЗ рднрд╛рдЧ рд╕реЗ рдЧреБрдЬрд░рддрд╛ рд╣реИ рдФрд░ рдЙрд╕реЗ рдЯреНрдпреВрдЯреЛрд░рд┐рдпрд▓ рдЬрд╛рд░реА рд░рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рджреВрд╕рд░реЗ рдХрдорд░реЗ рдореЗрдВ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рдЗрд╕ рдмрд┐рдВрджреБ рдкрд░, рдЖрдк рдПрдХ рдЪреМрдХреА рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ рдпрд╛ рдЦрд┐рд▓рд╛рдбрд╝реА рдХреЛ рдмрдЪрд╛рдиреЗ рдХрд╛ рдЕрд╡рд╕рд░ рджреЗ рд╕рдХрддреЗ рд╣реИрдВред рд╕рд╣реЗрдЬрдиреЗ рдореЗрдВ, рд╣рдо рдХреБрдЫ рдРрд╕рд╛ рд▓рд┐рдЦреЗрдВрдЧреЗ рдЬреИрд╕реЗ "рдЦрд┐рд▓рд╛рдбрд╝реА рдиреЗ рдЯреНрдпреВрдЯреЛрд░рд┐рдпрд▓ рдХреЗ рднрд╛рдЧ 1 рдХреЛ рдкреВрд░рд╛ рдХрд┐рдпрд╛"ред рдЕрдЧрд▓рд╛, рдЦрд┐рд▓рд╛рдбрд╝реА рдЯреНрдпреВрдЯреЛрд░рд┐рдпрд▓ рдХреЗ рджреВрд╕рд░реЗ рднрд╛рдЧ рд╕реЗ рдЧреБрдЬрд░реЗрдЧрд╛, рдЬрд┐рд╕рдХреЗ рд▓рд┐рдП рд╣рдо рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдПрдХ рдФрд░ рдХреЙрд░рдЖрдЙрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗред рдФрд░ рдЗрд╕реА рддрд░рд╣ ... рдЬрдм рд▓реЛрдб рд╣реЛ рд░рд╣рд╛ рд╣реИ, рддреЛ рд╣рдо рд╕рд┐рд░реНрдл рдЙрд╕ рд╣рд┐рд╕реНрд╕реЗ рдХреЗ рдЕрдиреБрд░реВрдк рдХреЙрд░рдЯреАрди рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ рдЬреЛ рдЦрд┐рд▓рд╛рдбрд╝реА рдХреЛ рдЧреБрдЬрд░рдирд╛ рд╣реЛрдЧрд╛ред

рдирд┐рд╖реНрдХрд░реНрд╖


рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдХреНрд░рд┐рдпрд╛рдУрдВ рдФрд░ cutscenes рдХреЗ рдЕрдиреБрдХреНрд░рдо рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрдИ рдЕрд▓рдЧ-рдЕрд▓рдЧ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╣реИрдВред рдпрд╣ рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдХреЛрд░рдЯрд╛рдЗрди рджреГрд╖реНрдЯрд┐рдХреЛрдг рдмрд╣реБрдд рд╢рдХреНрддрд┐рд╢рд╛рд▓реА рд╣реИ рдФрд░ рдореБрдЭреЗ рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреЗ рд╕рд╛рде рд╕рд╛рдЭрд╛ рдХрд░рдиреЗ рдореЗрдВ рдЦреБрд╢реА рд╣реЛ рд░рд╣реА рд╣реИред рдореБрдЭреЗ рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рд╕рдорд╕реНрдпрд╛ рдХрд╛ рдпрд╣ рд╕рдорд╛рдзрд╛рди рдЖрдкрдХреЗ рдЬреАрд╡рди рдХреЛ рдЖрд╕рд╛рди рдмрдирд╛ рджреЗрдЧрд╛ рдФрд░ рдЖрдкрдХреЛ рдЕрдкрдиреЗ рдЦреЗрд▓ рдореЗрдВ рдорд╣рд╛рдХрд╛рд╡реНрдп рдХрдЯрдХрдиреЗрд╕реЗрд╕ рдмрдирд╛рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдЧрд╛ред

Source: https://habr.com/ru/post/hi427135/


All Articles