Manuals
Manuals




This translation is community contributed and may not be up to date. We only maintain the English version of the documentation. Read this manual in English

Κύκλος ζωής εφαρμογής

Ο κύκλος ζωής μιας εφαρμογής ή ενός παιχνιδιού Defold είναι, σε γενικές γραμμές, απλός. Η μηχανή περνά από τρία στάδια εκτέλεσης: αρχικοποίηση, βρόχο ενημέρωσης (όπου οι εφαρμογές και τα παιχνίδια περνούν το μεγαλύτερο μέρος του χρόνου τους) και οριστικοποίηση.

Επισκόπηση κύκλου ζωής

Σε πολλές περιπτώσεις απαιτείται μόνο μια στοιχειώδης κατανόηση των εσωτερικών λειτουργιών του Defold. Ωστόσο, μπορεί να συναντήσετε περιπτώσεις όπου η ακριβής σειρά με την οποία το Defold εκτελεί τις εργασίες του είναι ζωτικής σημασίας. Αυτό το έγγραφο περιγράφει πώς η μηχανή εκτελεί μια εφαρμογή από την αρχή έως το τέλος.

Η εφαρμογή ξεκινά αρχικοποιώντας ό,τι χρειάζεται για τη λειτουργία της μηχανής. Φορτώνει την κύρια συλλογή και καλεί την init() σε όλα τα φορτωμένα στοιχεία που διαθέτουν συνάρτηση Lua init(), δηλαδή στοιχεία script και στοιχεία GUI με σενάρια GUI. Αυτό σας επιτρέπει να εκτελέσετε προσαρμοσμένη αρχικοποίηση.

Στη συνέχεια, η εφαρμογή μπαίνει στον βρόχο ενημέρωσης, όπου περνά το μεγαλύτερο μέρος της διάρκειας ζωής της. Σε κάθε καρέ ενημερώνονται τα αντικείμενα παιχνιδιού και τα στοιχεία που περιέχουν. Καλείται η update() κάθε στοιχείου script και σεναρίου GUI. Κατά τη διάρκεια του βρόχου ενημέρωσης, τα μηνύματα αποστέλλονται στους παραλήπτες τους, οι ήχοι αναπαράγονται και όλα τα γραφικά αποδίδονται.

Κάποια στιγμή ο κύκλος ζωής της εφαρμογής τελειώνει. Πριν τερματιστεί η εφαρμογή, η μηχανή βγαίνει από τον βρόχο ενημέρωσης και εισέρχεται στο στάδιο οριστικοποίησης. Προετοιμάζει όλα τα φορτωμένα αντικείμενα παιχνιδιού για διαγραφή και καλεί την final() όλων των στοιχείων τους, επιτρέποντας προσαρμοσμένη εκκαθάριση. Έπειτα τα αντικείμενα διαγράφονται και η κύρια συλλογή εκφορτώνεται.

Αρχικοποίηση

Αυτό το διάγραμμα περιέχει μια λεπτομερέστερη ανάλυση των βημάτων αρχικοποίησης. Τα βήματα του περάσματος «αποστολή μηνυμάτων», ακριβώς πριν από τη «δυναμική δημιουργία αντικειμένων», εμφανίζονται για λόγους σαφήνειας σε ξεχωριστό μπλοκ στα δεξιά.

Επισκόπηση αρχικοποίησης

Στην πραγματικότητα, η μηχανή εκτελεί πολλά ακόμη βήματα κατά την αρχικοποίηση, πριν φορτωθεί η κύρια συλλογή. Ρυθμίζονται ο εκχωρητής μνήμης, οι υποδοχές, τα γραφικά, το HID (συσκευές εισόδου), ο ήχος, η φυσική και πολλά άλλα. Επίσης φορτώνεται και ρυθμίζεται η διαμόρφωση της εφαρμογής (game.project).

Το πρώτο σημείο εισόδου που ελέγχεται από τον χρήστη, στο τέλος της αρχικοποίησης της μηχανής, είναι η κλήση της συνάρτησης init() του τρέχοντος σεναρίου απόδοσης.

Στη συνέχεια φορτώνεται και αρχικοποιείται η κύρια συλλογή. Όλα τα αντικείμενα παιχνιδιού της συλλογής εφαρμόζουν τους μετασχηματισμούς τους —μετατόπιση (αλλαγή θέσης), περιστροφή και κλιμάκωση— στα παιδιά τους. Έπειτα καλούνται όλες οι διαθέσιμες συναρτήσεις init() των στοιχείων.

Η σειρά με την οποία καλούνται οι συναρτήσεις init() των στοιχείων αντικειμένων παιχνιδιού δεν έχει καθοριστεί. Δεν πρέπει να υποθέσετε ότι η μηχανή αρχικοποιεί αντικείμενα της ίδιας συλλογής με συγκεκριμένη σειρά.

Επειδή ο κώδικας init() μπορεί να στείλει νέα μηνύματα, να δώσει εντολή σε στοιχεία factory να δημιουργήσουν αντικείμενα, να επισημάνει αντικείμενα για διαγραφή και να εκτελέσει πολλές άλλες ενέργειες, η μηχανή πραγματοποιεί ένα πλήρες πέρασμα «μετά την ενημέρωση» (post update). Αυτό το πέρασμα παραδίδει μηνύματα, δημιουργεί στην πράξη τα αντικείμενα παιχνιδιού των factory και διαγράφει αντικείμενα. Περιλαμβάνει επίσης μια ακολουθία «αποστολής μηνυμάτων» που όχι μόνο παραδίδει τα μηνύματα της ουράς, αλλά επεξεργάζεται και τα μηνύματα προς proxy συλλογής. Οι επόμενες ενημερώσεις των proxy, όπως ενεργοποίηση, απενεργοποίηση, φόρτωση και σήμανση για εκφόρτωση, πραγματοποιούνται σε αυτά τα βήματα.

Το παραπάνω διάγραμμα δείχνει ότι μπορείτε να φορτώσετε ένα proxy συλλογής κατά τη διάρκεια της init(), να βεβαιωθείτε ότι όλα τα αντικείμενα που περιέχει έχουν αρχικοποιηθεί και έπειτα να εκφορτώσετε τη συλλογή μέσω του proxy — όλα αυτά πριν από την πρώτη κλήση της update() ενός στοιχείου, δηλαδή πριν η μηχανή φύγει από το στάδιο αρχικοποίησης και εισέλθει στον βρόχο ενημέρωσης:

function init(self)
    print("init()")
    msg.post("#collectionproxy", "load")
end

function update(self, dt)
    -- The proxy collection is unloaded before this code is reached.
    print("update()")
end

function on_message(self, message_id, message, sender)
    if message_id == hash("proxy_loaded") then
        print("proxy_loaded. Init, enable and then unload.")
        msg.post("#collectionproxy", "init")
        msg.post("#collectionproxy", "enable")
        msg.post("#collectionproxy", "unload")
        -- The proxy collection objects’ init() and final() functions
        -- are called before we reach this object’s update()
    end
end

Ο βρόχος ενημέρωσης

Ο βρόχος ενημέρωσης διατρέχει μια μεγάλη ακολουθία μία φορά ανά καρέ. Για λόγους σαφήνειας, η ακολουθία ενημέρωσης στο παρακάτω διάγραμμα χωρίζεται σε λογικά μπλοκ. Η «Αποστολή μηνυμάτων» εμφανίζεται επίσης ξεχωριστά:

Βρόχος ενημέρωσης

Είσοδος

Η είσοδος διαβάζεται από τις διαθέσιμες συσκευές, αντιστοιχίζεται με τις συνδέσεις εισόδου και έπειτα αποστέλλεται. Κάθε αντικείμενο παιχνιδιού που έχει αποκτήσει εστίαση εισόδου στέλνει την είσοδο στις συναρτήσεις on_input() όλων των στοιχείων του. Ένα αντικείμενο παιχνιδιού με ένα στοιχείο script και ένα στοιχείο GUI με σενάριο GUI λαμβάνει είσοδο στις συναρτήσεις on_input() και των δύο στοιχείων, εφόσον αυτές έχουν οριστεί και τα στοιχεία έχουν αποκτήσει εστίαση εισόδου.

Κάθε αντικείμενο παιχνιδιού που έχει αποκτήσει εστίαση εισόδου και περιέχει στοιχεία proxy συλλογής προωθεί την είσοδο στα στοιχεία μέσα στη συλλογή του proxy. Η διαδικασία συνεχίζεται αναδρομικά σε ενεργοποιημένα proxy συλλογής που βρίσκονται μέσα σε άλλα ενεργοποιημένα proxy.

Ενημέρωση

Η μηχανή διατρέχει κάθε στοιχείο αντικειμένου παιχνιδιού στην κύρια συλλογή. Αν ένα στοιχείο διαθέτει συνάρτηση update(), η συνάρτηση καλείται. Αν το στοιχείο είναι proxy συλλογής, κάθε στοιχείο στη συλλογή του proxy ενημερώνεται αναδρομικά, ακολουθώντας όλα τα βήματα της ακολουθίας «Ενημέρωση» στο παραπάνω διάγραμμα.

Η σειρά με την οποία καλούνται οι συναρτήσεις update() των στοιχείων αντικειμένων παιχνιδιού δεν έχει καθοριστεί. Δεν πρέπει να υποθέσετε ότι η μηχανή ενημερώνει αντικείμενα της ίδιας συλλογής με συγκεκριμένη σειρά.

Στο επόμενο βήμα αποστέλλονται όλα τα μηνύματα της ουράς. Επειδή ο κώδικας on_message() του παραλήπτη μπορεί να στείλει επιπλέον μηνύματα, ο αποστολέας συνεχίζει μέχρι να αδειάσει η ουρά. Υπάρχει, ωστόσο, όριο στον αριθμό των επαναλήψεων της ουράς που εκτελεί ο αποστολέας. Για λεπτομέρειες, ανατρέξτε στο εγχειρίδιο Ανταλλαγής μηνυμάτων, στην ενότητα «Προχωρημένα θέματα».

Για τα στοιχεία αντικειμένων σύγκρουσης, τα μηνύματα φυσικής —συγκρούσεις, trigger, αποκρίσεις ray cast κ.λπ.— αποστέλλονται σε ολόκληρο το αντικείμενο παιχνιδιού και σε όλα τα στοιχεία που περιέχουν script με συνάρτηση on_message().

Έπειτα ενημερώνονται οι μετασχηματισμοί, εφαρμόζοντας κάθε μετατόπιση, περιστροφή και κλιμάκωση ενός αντικειμένου παιχνιδιού στα στοιχεία του και στα στοιχεία των παιδικών αντικειμένων παιχνιδιού.

Ενημέρωση απόδοσης

Το μπλοκ ενημέρωσης απόδοσης αποστέλλει πρώτα όλα τα μηνύματα στην υποδοχή (socket) @render, όπως τα μηνύματα set_view_projection του στοιχείου κάμερας και τα μηνύματα set_clear_color. Στη συνέχεια καλείται η update() του σεναρίου απόδοσης.

Στάδιο μετά την ενημέρωση

Μετά τις ενημερώσεις εκτελείται το στάδιο «μετά την ενημέρωση» (post update). Σε αυτό το στάδιο εκφορτώνονται από τη μνήμη τα proxy συλλογής που έχουν επισημανθεί για εκφόρτωση, κάτι που συμβαίνει κατά την ακολουθία «αποστολή μηνυμάτων». Κάθε αντικείμενο παιχνιδιού που έχει επισημανθεί για διαγραφή καλεί όλες τις διαθέσιμες συναρτήσεις final() των στοιχείων του. Ο κώδικας στις συναρτήσεις final() στέλνει συχνά νέα μηνύματα στην ουρά, οπότε εκτελείται ακόμη ένα πέρασμα «αποστολής μηνυμάτων».

Κάθε στοιχείο factory που έχει λάβει εντολή να δημιουργήσει ένα αντικείμενο παιχνιδιού το δημιουργεί στη συνέχεια. Τέλος, τα αντικείμενα παιχνιδιού που έχουν επισημανθεί για διαγραφή διαγράφονται πραγματικά.

Το τελευταίο βήμα του βρόχου ενημέρωσης περιλαμβάνει την αποστολή μηνυμάτων στην υποδοχή @system, όπως τα exit και reboot, την ενεργοποίηση ή απενεργοποίηση του profiler και την έναρξη ή διακοπή της καταγραφής βίντεο. Στη συνέχεια αποδίδονται τα γραφικά, γίνεται η καταγραφή βίντεο και αποδίδεται το οπτικό εργαλείο δημιουργίας προφίλ. Δείτε την τεκμηρίωση εντοπισμού σφαλμάτων.

Ρυθμός καρέ και χρονικό βήμα συλλογής

Ο αριθμός των ενημερώσεων καρέ ανά δευτερόλεπτο, ο οποίος ισούται με τον αριθμό των εκτελέσεων του βρόχου ενημέρωσης, μπορεί να οριστεί στις ρυθμίσεις του έργου ή μέσω προγραμματισμού, στέλνοντας το μήνυμα set_update_frequency στην υποδοχή @system. Επιπλέον, μπορείτε να ορίσετε ξεχωριστά το χρονικό βήμα (time step) κάθε proxy συλλογής, στέλνοντάς του το μήνυμα set_time_step. Η αλλαγή του χρονικού βήματος μιας συλλογής δεν επηρεάζει τον ρυθμό καρέ. Επηρεάζει το χρονικό βήμα ενημέρωσης της φυσικής και τη μεταβλητή dt που μεταβιβάζεται στην update(). Επίσης, δεν αλλάζει τον αριθμό των κλήσεων της update() ανά καρέ — η συνάρτηση καλείται πάντα ακριβώς μία φορά.

(Για λεπτομέρειες, ανατρέξτε στο εγχειρίδιο proxy συλλογής και στην τεκμηρίωση του set_time_step.)

Οριστικοποίηση

Όταν τερματίζεται η εφαρμογή, ολοκληρώνεται πρώτα η τελευταία ακολουθία του βρόχου ενημέρωσης. Αυτή εκφορτώνει όλα τα proxy συλλογής, οριστικοποιώντας και διαγράφοντας όλα τα αντικείμενα παιχνιδιού σε κάθε συλλογή proxy.

Έπειτα η μηχανή περνά σε μια ακολουθία οριστικοποίησης που χειρίζεται την κύρια συλλογή και τα αντικείμενά της:

Οριστικοποίηση

Οι συναρτήσεις final() καλούνται πρώτα. Ακολουθεί ακόμη μία αποστολή μηνυμάτων. Τέλος, όλα τα αντικείμενα παιχνιδιού διαγράφονται και η κύρια συλλογή εκφορτώνεται.

Στο παρασκήνιο, η μηχανή κλείνει τα υποσυστήματα: η διαμόρφωση του έργου διαγράφεται, το εργαλείο δημιουργίας προφίλ μνήμης κλείνει και ούτω καθεξής.

Η εφαρμογή έχει πλέον τερματιστεί πλήρως.