• Guest
HabraHabr
  • Main
  • Users

  • Development
    • Programming
    • Information Security
    • Website development
    • JavaScript
    • Game development
    • Open source
    • Developed for Android
    • Machine learning
    • Abnormal programming
    • Java
    • Python
    • Development of mobile applications
    • Analysis and design of systems
    • .NET
    • Mathematics
    • Algorithms
    • C#
    • System Programming
    • C++
    • C
    • Go
    • PHP
    • Reverse engineering
    • Assembler
    • Development under Linux
    • Big Data
    • Rust
    • Cryptography
    • Entertaining problems
    • Testing of IT systems
    • Testing Web Services
    • HTML
    • Programming microcontrollers
    • API
    • High performance
    • Developed for iOS
    • CSS
    • Industrial Programming
    • Development under Windows
    • Image processing
    • Compilers
    • FPGA
    • Professional literature
    • OpenStreetMap
    • Google Chrome
    • Data Mining
    • PostgreSQL
    • Development of robotics
    • Visualization of data
    • Angular
    • ReactJS
    • Search technologies
    • Debugging
    • Test mobile applications
    • Browsers
    • Designing and refactoring
    • IT Standards
    • Solidity
    • Node.JS
    • Git
    • LaTeX
    • SQL
    • Haskell
    • Unreal Engine
    • Unity3D
    • Development for the Internet of things
    • Functional Programming
    • Amazon Web Services
    • Google Cloud Platform
    • Development under AR and VR
    • Assembly systems
    • Version control systems
    • Kotlin
    • R
    • CAD/CAM
    • Customer Optimization
    • Development of communication systems
    • Microsoft Azure
    • Perfect code
    • Atlassian
    • Visual Studio
    • NoSQL
    • Yii
    • Mono и Moonlight
    • Parallel Programming
    • Asterisk
    • Yandex API
    • WordPress
    • Sports programming
    • Lua
    • Microsoft SQL Server
    • Payment systems
    • TypeScript
    • Scala
    • Google API
    • Development of data transmission systems
    • XML
    • Regular expressions
    • Development under Tizen
    • Swift
    • MySQL
    • Geoinformation services
    • Global Positioning Systems
    • Qt
    • Dart
    • Django
    • Development for Office 365
    • Erlang/OTP
    • GPGPU
    • Eclipse
    • Maps API
    • Testing games
    • Browser Extensions
    • 1C-Bitrix
    • Development under e-commerce
    • Xamarin
    • Xcode
    • Development under Windows Phone
    • Semantics
    • CMS
    • VueJS
    • GitHub
    • Open data
    • Sphinx
    • Ruby on Rails
    • Ruby
    • Symfony
    • Drupal
    • Messaging Systems
    • CTF
    • SaaS / S+S
    • SharePoint
    • jQuery
    • Puppet
    • Firefox
    • Elm
    • MODX
    • Billing systems
    • Graphical shells
    • Kodobred
    • MongoDB
    • SCADA
    • Hadoop
    • Gradle
    • Clojure
    • F#
    • CoffeeScript
    • Matlab
    • Phalcon
    • Development under Sailfish OS
    • Magento
    • Elixir/Phoenix
    • Microsoft Edge
    • Layout of letters
    • Development for OS X
    • Forth
    • Smalltalk
    • Julia
    • Laravel
    • WebGL
    • Meteor.JS
    • Firebird/Interbase
    • SQLite
    • D
    • Mesh-networks
    • I2P
    • Derby.js
    • Emacs
    • Development under Bada
    • Mercurial
    • UML Design
    • Objective C
    • Fortran
    • Cocoa
    • Cobol
    • Apache Flex
    • Action Script
    • Joomla
    • IIS
    • Twitter API
    • Vkontakte API
    • Facebook API
    • Microsoft Access
    • PDF
    • Prolog
    • GTK+
    • LabVIEW
    • Brainfuck
    • Cubrid
    • Canvas
    • Doctrine ORM
    • Google App Engine
    • Twisted
    • XSLT
    • TDD
    • Small Basic
    • Kohana
    • Development for Java ME
    • LiveStreet
    • MooTools
    • Adobe Flash
    • GreaseMonkey
    • INFOLUST
    • Groovy & Grails
    • Lisp
    • Delphi
    • Zend Framework
    • ExtJS / Sencha Library
    • Internet Explorer
    • CodeIgniter
    • Silverlight
    • Google Web Toolkit
    • CakePHP
    • Safari
    • Opera
    • Microformats
    • Ajax
    • VIM
  • Administration
    • System administration
    • IT Infrastructure
    • *nix
    • Network technologies
    • DevOps
    • Server Administration
    • Cloud computing
    • Configuring Linux
    • Wireless technologies
    • Virtualization
    • Hosting
    • Data storage
    • Decentralized networks
    • Database Administration
    • Data Warehousing
    • Communication standards
    • PowerShell
    • Backup
    • Cisco
    • Nginx
    • Antivirus protection
    • DNS
    • Server Optimization
    • Data recovery
    • Apache
    • Spam and antispam
    • Data Compression
    • SAN
    • IPv6
    • Fidonet
    • IPTV
    • Shells
    • Administering domain names
  • Design
    • Interfaces
    • Web design
    • Working with sound
    • Usability
    • Graphic design
    • Design Games
    • Mobile App Design
    • Working with 3D-graphics
    • Typography
    • Working with video
    • Work with vector graphics
    • Accessibility
    • Prototyping
    • CGI (graphics)
    • Computer Animation
    • Working with icons
  • Control
    • Careers in the IT industry
    • Project management
    • Development Management
    • Personnel Management
    • Product Management
    • Start-up development
    • Managing the community
    • Service Desk
    • GTD
    • IT Terminology
    • Agile
    • Business Models
    • Legislation and IT-business
    • Sales management
    • CRM-systems
    • Product localization
    • ECM / EDS
    • Freelance
    • Venture investments
    • ERP-systems
    • Help Desk Software
    • Media management
    • Patenting
    • E-commerce management
    • Creative Commons
  • Marketing
    • Conferences
    • Promotion of games
    • Internet Marketing
    • Search Engine Optimization
    • Web Analytics
    • Monetize Web services
    • Content marketing
    • Monetization of IT systems
    • Monetize mobile apps
    • Mobile App Analytics
    • Growth Hacking
    • Branding
    • Monetize Games
    • Display ads
    • Contextual advertising
    • Increase Conversion Rate
  • Sundry
    • Reading room
    • Educational process in IT
    • Research and forecasts in IT
    • Finance in IT
    • Hakatonas
    • IT emigration
    • Education abroad
    • Lumber room
    • I'm on my way

Implementation of cutscenes and sequences of actions in games

 3r3992. 3r3-31. 3r3-3960. In this post I will talk about how you can implement action sequences and cutscenes in video games. This article is a translation of Here is this article and on the same topic I gave a talk on Lua in Moscow, so if you like watching a video more, you can watch here is . 3r3809.  3r3992. 3r3809.  3r3992. The article code is written in Lua, but can easily be written in other languages ​​(with the exception of the method that uses korutiny, since they are not in all languages). 3r3809.  3r3992. 3r33961. 3r3809.  3r3992. The article shows how to create a mechanism that allows you to write the following cutscenes:
 3r3992. 3r3809.  3r3992. 3r3907. 3r3908. local function cutscene (player, npc)
player: goTo (npc)
if player: hasCompleted (quest) then
npc: say ("You did it!")
delay (0.5) 3r3992. npc: say ("Thank you")
else
npc: say ("Please help me")
end
end
3r33939. 3r33939. 3r3809.  3r3992. 3r3809.  3r3992.

Introduction

3r3809.  3r3992. 3r3809.  3r3992. Sequences of action are often found in video games. For example, in the cutscene: a character meets an enemy, something tells him, the enemy answers, and so on. Sequences of actions can occur in the gameplay. Take a look at this gif:
 3r3992. 3r3809.  3r3992. Implementation of cutscenes and sequences of actions in games  3r3992. 2. The character enters the house
 3r3992. 3. The door closes
 3r3992. 4. The screen darkens smoothly
 3r3992. 5. Level 3r3809 changes.  3r3992. 6. The screen brightens smoothly
 3r3992. 7. The character enters the cafe
 3r3992. 3r3809.  3r3992. Sequences of actions can also be used to script NPC behaviors or to implement boss fights in which the boss performs some actions one after another. 3r3809.  3r3992. 3r3809.  3r3992. 3r373. 3r3393963. 3r3809.  3r3992. 3r3809.  3r3992.

The problem is

3r3809.  3r3992. 3r3809.  3r3992. The structure of the standard game cycle makes implementation of action sequences difficult. Suppose we have the following game cycle:
 3r3992. 3r3809.  3r3992. 3r3809.  3r3992. 3r3809.  3r3992. 3r3907. 3r3908. while game: isRunning () do
processInput () 3r3992. dt = clock.delta ()
update (dt) 3r3992. render () 3r3992. end
3r33939. 3r33939. 3r3809.  3r3992. 3r3809.  3r3992. We want to implement the following cutscene: the player approaches the NPC, the NPC says: “You did it!”, And then after a short pause, says: “Thank you!”. In a perfect world, we would write it like this:
 3r3992. 3r3809.  3r3992. 3r3907. 3r3908. player: goTo (npc)
npc: say ("You did it!")
delay (0.5) 3r3992. npc: say ("Thank you")
3r33939. 3r33939. 3r3809.  3r3992. 3r3809.  3r3992. And here we meet the problem. Taking action takes some time. Some actions may even wait for input from the player (for example, to close the dialog box). Instead of the function. delay cannot call the same sleep - it will look like the game is frozen. 3r3809.  3r3992. 3r3809.  3r3992. Let's take a look at several hikes to solve the problem. 3r3809.  3r3992. 3r3809.  3r3992.

bool, enum, state machines

3r3809.  3r3992. 3r3809.  3r3992. The most obvious way to implement workflows is to store current state information in bool, string, or enum. The code will look something like this:
 3r3992. 3r3809.  3r3992. 3r3907. 3r3908. function update (dt) 3r3r992. 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 3r3992. - and so on
end
end
3r33939. 3r33939. 3r3809.  3r3992. 3r3809.  3r3992. This approach easily leads to spaghetti code and long chains of if-else expressions, so I recommend avoiding this solution. 3r3809.  3r3992. 3r3809.  3r3992.

Action list

3r3809.  3r3992. 3r3809.  3r3992. Action lists are very similar to state machines. An action list is a list of actions that are performed one after another. In the game loop, the function is called for the current action. update , which allows us to handle the input and render the game, even if the action is performed for a long time. After the action is completed, we proceed to the next. 3r3809.  3r3992. 3r3809.  3r3992. In the cutscene we want to implement, we need to implement the following actions: GoToAction, DialogueAction, and DelayAction. 3r3809.  3r3992. 3r3809.  3r3992. For further examples, I will use the 3r3189 library. middleclass for OOP in Lua. 3r3809.  3r3992. 3r3809.  3r3992. This is how 3r30101 is implemented. DelayAction :
 3r3992. 3r3809.  3r3992. 3r3907. 3r3908. - Designer 3r3992. function DelayAction: initialize (params)
self.delay = params.delay
3r3992. self.currentTime = 0
self.isFinished = false
end
3r3992. function DelayAction: update (dt)
self.currentTime = self.currentTime + dt
if self.currentTime> self.delay then
self.isFinished = true
end
end
3r33939. 3r33939. 3r3809.  3r3992. 3r3809.  3r3992. Function ActionList: update Looks like this:
 3r3992. 3r3809.  3r3992. 3r3907. 3r3908. 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
3r33939. 3r33939. 3r3809.  3r3992. 3r3809.  3r3992. Finally, the implementation of the cutscene itself:
 3r3992. 3r3809.  3r3992. 3r3907. 3r301901. function makeCutsceneActionList (player, npc)
return ActionList: new {
GoToAction: new {
entity = player, 3r3992. target = npc
}, 3r3992. SayAction: new {
entity = npc,
text = "You did it!" 3r3992.}, 3r3992. DelayAction: new {
delay = 0.5 r3r3992}, 3r3992. SayAction: new {
entity = npc,
text = "Thank you"
} 3r3992.} 3r3992. end
3r3992. - somewhere inside the game cycle 3r3-392. actionList: update (dt)
3r33939. 3r33939. 3r3809.  3r3992. 3r3809.  3r3992. 3r3-3960. Note [/i] : in Lua, the challenge is someFunction ({}) can be done like this: someFunction {} . This allows you to write DelayAction: new {delay = 0.5} instead of DelayAction: new ({delay = 0.5}) . 3r3809.  3r3992. 3r3809.  3r3992. It looks much better. The code clearly shows the sequence of actions. If we want to add a new action, we can easily do it. It's pretty easy to create classes like DelayAction to make writing cutscen more convenient. 3r3809.  3r3992. 3r3809.  3r3992. I advise you to watch the presentation of Sean Middleditch (Sean Middleditch) about action lists, which are more complex examples. 3r3809.  3r3992. 3r3809.  3r3992. 3r3306. 3r3307. 3r3308. 3r3309. 3r33988. 3r33988. 3r33988. 3r3809.  3r3992. 3r3809.  3r3992. Action lists are generally very useful. I used them for my games for quite a long time and was generally happy. But this approach also has disadvantages. Suppose we want to implement a slightly more complicated cutscene:
 3r3992. 3r3809.  3r3992. 3r3907. 3r3908. local function cutscene (player, npc)
player: goTo (npc)
if player: hasCompleted (quest) then
npc: say ("You did it!")
delay (0.5) 3r3992. npc: say ("Thank you")
else
npc: say ("Please help me")
end
end
3r33939. 3r33939. 3r3809.  3r3992. 3r3809.  3r3992. To make an if /else simulation, you need to implement non-linear lists. This can be done using tags. Some actions can be tagged with tags, and then by some condition instead of moving to the next action, you can go to an action that has the desired tag. It works, however it is not as easy to read and write as the function above. 3r3809.  3r3992. 3r3809.  3r3992. Lua korutin make this code a reality. 3r3809.  3r3992. 3r3809.  3r3992.

Korutin

3r3809.  3r3992. 3r340940. Basics of Corutin in Lua 3r3809.  3r3992. 3r3809.  3r3992. Korutina is a function that can be paused and then resumed later. The korutins are executed in the same thread as the main program. New threads for corutin are never created. 3r3809.  3r3992. 3r3809.  3r3992. To pause corutin, call r3r3901. coroutine.yield to resume - coroutine.resume . A simple example is
 3r3992. 3r3809.  3r3992. 3r3907. 3r3908. local function f () 3r3992. print ("hello")
coroutine.yield ()
print ("world!") 3r3992. end
3r3992. local c = coroutine.create (f)
coroutine.resume (c)
print ("uhh ")
coroutine.resume (c)
3r33939. 3r33939. 3r3809.  3r3992. 3r3809.  3r3992. The output of the program: 3r3809.  3r3992. 3r3809.  3r3992. 3r3907. 3r3992. hello 3r3992. uhh 3r3992. world
3r33939. 3r3809.  3r3992. 3r3809.  3r3992. This is how it works. First we create the cortina with r3r3901. coroutine.create . After this call, the korutin does not start executing. For this to happen, we need to run it with coroutine.resume . Then the function is called. f that writes “hello” and pauses itself with coroutine.yield . This is similar to return , but we can resume execution f using 3r301901. coroutine.resume . 3r3809.  3r3992. 3r3809.  3r3992. If you pass arguments when you call 3r-30101. coroutine.yield they will become the return values ​​of the corresponding call 3r-30101. coroutine.resume in the mainstream. For example: 3r380.  3r3992. 3r3809.  3r3992. 3r3907. 3r3908. local function f () 3r3992. 3r3992. coroutine.yield (4? "some text")
3r3992. end
3r3992. ok, num, text = coroutine.resume (c)
print (num, text) - will print '42 "some text" '
3r33939. 3r33939. 3r3809.  3r3992. 3r3809.  3r3992. 3r301901. ok - a variable that allows us to find out the status of cortina. If ok has a value of true then with Korutina everything is fine, no errors occurred inside. The return values ​​following it ( Num , Text ) Are the very arguments that we passed to yield . 3r3809.  3r3992. 3r3809.  3r3992. If ok has a value of false , then something went wrong with Korutina, for example, the function was called inside it. error . In this case, the second return value is an error message. An example of a korutina in which an error occurs:
 3r3992. 3r3809.  3r3992. 3r3907. 3r3908. local function f () 3r3992. print (1 + notDefined)
end
3r3992. c = coroutine.create (f)
ok, msg = coroutine.resume (c)
if not ok then
print ("Coroutine failed!", msg)
end
3r33939. 3r33939. 3r3809.  3r3992.
 3r3992. Conclusion:
 3r3992. 3r3809.  3r3992. 3r3907. 3r3992. Coroutine failed! input: 4: value to global (global global notDefined ’)
3r33939. 3r3809.  3r3992. 3r3809.  3r3992. The status of the coroutine can be obtained by calling coroutine.status . Korutina may be in the following states: 3r38080.  3r3992. 3r3809.  3r3992.
  •  3r3992. 3r33518. “Running” - korutina is running at the moment. 3r301901. coroutine.status was called out of the cortina itself  3r3992. 3r33518. “Suspended” - the quorutine was paused or has never been run 3r31919.  3r3992. 3r33518. “Normal” - korutina is active, but not executed. That is, Korutina launched another Korutina 3r31919 within herself.  3r3992. 3r33518. “Dead” - korutina completed execution (i.e., the function inside the korutina was completed) 3r3519.  3r3992. 3r33521. 3r3809.  3r3992. 3r3809.  3r3992. Now, with the help of this knowledge, we can implement a system of sequences of actions and cutscenes based on corutinas. 3r3809.  3r3992. 3r3809.  3r3992. 3r340940. Creating a cutscene using corutin 3r3809.  3r3992. 3r3809.  3r3992. Here is what the base class
will look like. Action in the new system:
 3r3992. 3r3809.  3r3992. 3r3907. 3r3908. function Action: launch () 3r3992. self: init ()
3r3992. while not self.finished do
local dt = coroutine.yield ()
self: update (dt)
end
3r3992. self: exit () 3r3992. end
3r33939. 3r33939. 3r3809.  3r3992. 3r3809.  3r3992. The approach is similar to action lists: the function. update The action is called until the action has completed. But here we use the korutin and do yield in each iteration of the game cycle ( Action: launch is called from some kind of coroutine). Somewhere in update game cycle, we resume the current cutsceng like this:
 3r3992. 3r3809.  3r3992. 3r3907. 3r3908. coroutine.resume (c, dt)
3r33939. 3r33939. 3r3809.  3r3992. 3r3809.  3r3992. Finally, creating a cutscene:
 3r3992. 3r3809.  3r3992. 3r3907. 3r3908. function cutscene (player, npc)
player: goTo (npc)
npc: say ("You did it!")
delay (0.5) 3r3992. npc: say ("Thank you")
end
3r3992. - somewhere in the code 3r3992. local c = coroutine.create (cutscene, player, npc)
coroutine.resume (c, dt)
3r33939. 3r33939. 3r3809.  3r3992. 3r3809.  3r3992. This is how function is implemented. delay :
 3r3992. 3r3809.  3r3992. 3r3907. 3r3908. function delay (time) 3r3992. action = DelayAction: new {delay = time}
action: launch () 3r3992. end
3r33939. 3r33939. 3r3809.  3r3992. 3r3809.  3r3992. The creation of such wrappers significantly increases the readability of the cutsce code. 3r301901. DelayAction implemented like this:
 3r3992. 3r3809.  3r3992. 3r3907. 3r3908. - Action - the base class of DelayAction
local DelayAction = class ("DelayAction", Action)
3r3992. function DelayAction: initialize (params)
self.delay = params.delay
self.currentTime = 0
self.isFinished = false
end
3r3992. function DelayAction: update (dt)
self.currentTime = self.currentTime + dt
if self.currentTime> = self.delayTime then
self.finished = true
end
end
3r33939. 3r33939. 3r3809.  3r3992. 3r3809.  3r3992. This implementation is identical to the one we used in action lists! Let's take a look at function again. Action: launch :
 3r3992. 3r3809.  3r3992. 3r3907. 3r3908. function Action: launch () 3r3992. self: init ()
3r3992. while not self.finished do
local dt = coroutine.yield () - the most important part of
self: update (dt)
end
3r3992. self: exit () 3r3992. end
3r33939. 3r33939. 3r3809.  3r3992. 3r3809.  3r3992. The main thing here is the cycle. while which is executed until the action is completed. It looks like this:
 3r3992. 3r3809.  3r3992. 3r38080. 3r3809.  3r3992. 3r3809.  3r3992. Let's now look at the function goTo :
 3r3992. 3r3907. 3r3908. function Entity: goTo (target)
local action = GoToAction: new {entity = self, target = target}
action: launch () 3r3992. end
3r3992. function GoToAction: initialize (params)
3r3992. end
3r3992. function GoToAction: update (dt)
if not self.entity: closeTo (self.target) then
- move logic, AI
else
self.finished = true
end
end
3r33939. 3r33939. 3r3809.  3r3992. 3r3809.  3r3992. Korutiny perfectly combined with events (events). Implement the class WaitForEventAction :
 3r3992. 3r3809.  3r3992. 3r3907. 3r3908. function WaitForEventAction: initialize (params)
self.finished = false
3r3992. eventManager: subscribe {
listener = self,
eventType = params.eventType,
callback = WaitForEventAction.onEvent
} 3r3992. end
3r3992. function WaitForEventAction: onEvent (event)
self.finished = true
end
3r33939. 3r33939. 3r3809.  3r3992. 3r3809.  3r3992. This function does not need method update . It will be executed (although it will not do anything ) until it receives an event with the required type. Here is the practical application of this class - the implementation of the function. say :
 3r3992. 3r3809.  3r3992. 3r3907. 3r3908. function Entity: say (text)
DialogueWindow: show (text) 3r3992. local action = WaitForEventAction: new {
eventType = 'DialogueWindowClosed'
} 3r3992. action: launch () 3r3992. end
3r33939. 3r33939. 3r3809.  3r3992. 3r3809.  3r3992. Simple and readable. When the dialog closes, it sends an event of type 'DialogueWindowClosed`. The “say” action is completed and its execution begins following it. 3r3809.  3r3992. 3r3809.  3r3992. With the help of Corutin, non-linear cutscenes and dialog trees can be easily created: 3r-3980.  3r3992. 3r3809.  3r3992. 3r3907. 3r3908. local answer = girl: say ('do_you_love_lua',
{'YES', 'NO'}) 3r3r2992. if answer == 'YES' then
girl: setMood ('happy')
girl: say ('happy_response')
else
girl: setMood ('angry')
girl: say ('angry_response')
end
3r33939. 3r33939. 3r3809.  3r3992. 3r3809.  3r3992. 3r33788. 3r3809.  3r3992. 3r3809.  3r3992. In this example, the function say slightly more complicated than the one I showed earlier. It returns the player's choice in the dialogue, but it is not difficult to implement. For example, can be used internally. WaitForEventAction which catches the event PlayerChoiceEvent and then returns the choice of the player, information about which will be contained in the event object. 3r3809.  3r3992. 3r3809.  3r3992. 3r340940. Slightly more complex examples are 3r3809.  3r3992. With the help of korutin you can easily create tutorials and small quests. For example: 3r380.  3r3992. 3r3809.  3r3992. 3r3907. 3r3908. girl: say ("Kill that monster!")
waitForEvent ('EnemyKilled')
girl: setMood ('happy')
girl: say ("You did it! Thank you!")
3r33939. 3r33939. 3r3809.  3r3992. 3r3809.  3r3992.  3r3992. 3r3809.  3r3992. 3r3907. 3r3908. function followPath (monster, path)
local numberOfPoints = path: getNumberOfPoints ()
local i = 0 is the index of the current point in the path
while true do
monster: goTo (path: getPoint (i))
3r3992. if i 3r340 i = i + 1 - go to the next point
else - start over
first. i = 0 r3r3992. end
end
end
3r33939. 3r33939. 3r3809.  3r3992. 3r3809.  3r3992. 3r33853. 3r3809.  3r3992. 3r3809.  3r3992. When the monster sees the player, we can simply stop doing the coruntine and remove it. Therefore, an infinite loop ( While true ) Inside followPath in fact is not infinite. 3r3809.  3r3992. 3r3809.  3r3992. Even with the help of korutin, you can do "parallel" actions. The cutscene will proceed to the next action only after the completion of both actions. For example, let's make a cutscene where a girl and a cat go to a certain point to a friend with different speeds. After they come to her, the cat says “meow”. 3r3809.  3r3992. 3r3809.  3r3992. 3r3907. 3r3908. function cutscene (cat, girl, meetingPoint)
local c1 = coroutine.create (
function ()
cat: goTo (meetingPoint)
end)
3r3992. local c2 = coroutine.create (
function ()
girl: goTo (meetingPoint)
end)
3r3992. c1.resume () 3r3992. c2.resume () 3r3992. 3r3992. - synchronization 3r3992. waitForFinish (c? c2)
3r3992. - cutscene continues to run 3r3992. cat: say ("meow")
3r3992. end
3r33939. 3r33939. 3r3809.  3r3992. 3r3809.  3r3992. The most important part here is the function waitForFinish which is a wrapper around class WaitForFinishAction , which can be implemented as follows: 3r3809.  3r3992. 3r3809.  3r3992. 3r3907. 3r3908. 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.c? dt)
end
3r3992. if coroutine.status (self.c2) ~ = 'dead' then
coroutine.resume (self.c? dt)
end
end
3r33939. 3r33939. 3r3809.  3r3992. 3r3809.  3r3992. You can make this class more powerful if you allow the synchronization of the Nth number of actions. 3r3809.  3r3992. 3r3809.  3r3992. You can also make a class that will wait for one of korutin will complete, instead of waiting, until 3r-3960. all [/i] Korutiny completes execution. For example, it can be used in racing mini-games. Inside the coroutine will be waiting until one of the riders reaches the finish line and then perform some sequence of actions. 3r3809.  3r3992. 3r3809.  3r3992. 3r340940. Advantages and disadvantages of Corutin
3r3809.  3r3992. 3r3809.  3r3992. Korutiny is a very useful mechanism. Using them, you can write cutscenes and gameplay code that is easy to read and modify. This kind of cutscenes can easily be written by modders or people who are not programmers (for example, game or level designers). 3r3809.  3r3992. 3r3809.  3r3992. And all this is done in one thread, so there are no problems with synchronization or 3r3393950. race condition
. 3r3809.  3r3992. 3r3809.   3r3992. The approach has drawbacks. For example, there may be problems with saving. Suppose there is a long tutorial in your game, implemented with the help of coruntine. During this tutorial, the player will not be able to persist, because To do this, you will need to save the current state of the corortina (which includes her entire stack and the values ​​of the variables inside), so that when you continue to load from the save, you can continue with the tutorial. 3r3809.  3r3992. 3r3809.  3r3992. (3r3-3960. Note 3r3-3961.: With the help of the 3-333962 library. PlutoLibrary 3r3-3963. You can serialize cortutin, but the library only works with Lua 5.1) 3r33980.  3r3992. 3r3809.  3r3992. This problem does not occur with cutscenes, because usually in games it is not allowed to remain in the middle of the cutscene. 3r3809.  3r3992. 3r3809.  3r3992. The problem with a long tutorial can be solved by breaking it into small pieces. Suppose a player passes the first part of the tutorial and must go to another room to continue the tutorial. At this point, you can make a checkpoint or give the player the opportunity to save. In the save, we will write something like “the player went through part 1 of the tutorial”. Next, the player will go through the second part of the tutorial, for which we will already use another korutin. And so on When loading, we will simply begin the execution of the coroutine, the corresponding part, which the player must pass. 3r3809.  3r3992. 3r3809.  3r3992.
Conclusion 3r37777. 3r3809.  3r3992. 3r3809.  3r3992. As you can see, there are several different approaches for implementing a sequence of actions and cutscenes. It seems to me that the approach with corortes is very powerful and I am happy to share it with the developers. I hope that this solution to the problem will make your life easier and will allow you to make you epic cutscenes in your games. 3r33988. 3r3992. 3r3992. 3r33985. ! function (e) {function t (t, n) {if (! (n in e)) {for (var r, a = e.document, i = a.scripts, o = i.length; o-- ;) if (-1! == i[o].src.indexOf (t)) {r = i[o]; break} if (! r) {r = a.createElement ("script"), r.type = "text /jаvascript", r.async =! ? r.defer =! ? r.src = t, r.charset = "UTF-8"; var d = function () {var e = a.getElementsByTagName ("script")[0]; e.parentNode.insertBefore (r, e)}; "[object Opera]" == e.opera? a.addEventListener? a.addEventListener ("DOMContentLoaded", d,! 1): e.attachEvent ("onload", d ): d ()}}} t ("//mediator.mail.ru/script/2820404/"""_mediator") () (); 3r33986. 3r3992. 3r33988. 3r3992. 3r3992. 3r3992. 3r3992.

It may be interesting

  • Comments
  • About article
  • Similar news
This publication has no comments.

weber

Author

20-10-2018, 16:28

Publication Date

Game development / Programming / Lua

Category
  • Comments: 0
  • Views: 342
Fit tutorials on YouTube
Python transpiler chain → 11l → C
Mobile OAuth 2.0 Security
We write the FPGA loader in LabVIEW.
Flying Pigs, or Optimizing Interpreters
Codable for API requests and how to put
Write a comment
Name:*
E-Mail:


Comments
There is a very weak knowledge in people about the astrology and spiritual stuff even it was well known by everyone in ancient times and it was the secret behind their happy life. Today is the time, when we lost our faith on spiritual science and we became addict of modern science technology.

Knowledge is very important to do any ritual properly but it is very hard to find a true knowledge about tantra, vashikaran, healing etc but thanks to avijeet aacharya who is supporting people by his free article like you and spreading the knowledge to needy people.

I seen your page and it look so interesting and i am thankful to you for spreading knowledge by this portal. if someone wants to learn about different types of
powerful vashikaran mantra for boyfriend so read avijeet aacharya pages on his portal and find interesting topics and updates.
Today, 23:14

trishamukharjee

Ambulances maroc est installée à Marrakech & Rabat et se déplace dans le royaume entier pour des trajets toutes distances en ambulances. Check Out: médecin a domicile Marrakech
Today, 16:37

noorseo

Welcome in the Top Class Escorts in Delhi. Are you instant going on google and doing searches for Delhi Escorts? Then Your Search is now Over Here. Our Escorts in Delhi is ready to make your glorious mood for Call Girls in Delhi.
[hide]Call Girl in Delhi[/http://escortservicesinnewdelhi.launchrock.com/] | [hide]Escort Services in New Delhi[/https://telegra.ph/Call-Girls-in-Delhi-7428151367-Call-Girls-Services-in
-Mahipalpur-01-15] | [hide]Call Girls Services in Mahipalpur[/https://escortservicesinnewdelhi.mystrikingly.com/] | [hide]Sex Services in Paharganj[/http://www.geocities.ws/natashasingh76/index.html]

Today, 14:24

Natasha Singh

Hi there, I found your blog via Google while searching for such kinda informative post and your post looks very interesting for me  hole in one coverage
Today, 12:32

jacksonseo

Great article it is useful and some new ideas after reading this article it is useful and a lot of new things and getting a lot of writing.  https://www.dawateislami.net/about-us
Today, 11:41

Global Islamic Organization

Adv
Website for web developers. New scripts, best ideas, programming tips. How to write a script for you here, we have a lot of information about various programming languages. You are a webmaster or a beginner programmer, it does not matter, useful articles will help to make your favorite business faster.

Login

Registration Forgot password