Σενάρια για στρατηγική βασισμένη στη σειρά. Ανάπτυξη στρατηγικής βήμα προς βήμα. Κύρια στάδια δημιουργίας στρατηγικής

Γεια σε όλους! Τώρα θα σας πω πώς να κάνετε ένα απλό RTS (RTS - Στρατηγική σε πραγματικό χρόνο, δηλαδή μια στρατηγική σε πραγματικό χρόνο) να ανοίξει μια αιώρα 8.1 (η λειτουργικότητα δεν είναι εγγυημένη στο 8.0) να δημιουργήσετε ένα αντικείμενο objControl, δηλαδή αυτό θα είναι το κύριο αντικείμενο μας, δημιουργήστε ένα συμβάν δημιουργίας ( Δημιουργία) Προσθήκη συμβάντος => Δημιουργία (Προσθήκη συμβάντος => Δημιουργία) το συμβάν δημιουργίας γίνεται μόνο μία φορά - κατά τη δημιουργία, κάντε κλικ στην καρτέλα ελέγχου στο δεξί κατακόρυφο μενού και κάντε δεξί κλικ στο Εκτέλεση κώδικα (Εκτέλεση κώδικα) και γράψτε τον κώδικα (είναι καλύτερο να μην αντιγράψετε κώδικα, και γράφοντάς τον μόνοι σας καθιστά πολύ πιο εύκολο να θυμάστε):

200?"200px":""+(this.scrollHeight+5)+"px");">startx=0; //Δήλωση μιας μεταβλητής για το σημείο έναρξης του x
starty=0; //Δηλώστε μια μεταβλητή για την αρχή του σημείου κατά y
draw_rect=false; //Μην σχεδιάζετε ένα ορθογώνιο επιλογής


Μεταβλητή: Ένα κομμάτι μνήμης που περιέχει πληροφορίες. Έχουν το δικό τους όνομα με το οποίο μπορείτε να επικοινωνήσετε μαζί τους. Οι μεταβλητές στο GML μπορούν να περιέχουν έναν πραγματικό αριθμό ή μια συμβολοσειρά. Για παράδειγμα, ένα τραπέζι είναι μια μεταβλητή, το ξύλινο ή το γυαλί είναι μια τιμή
Τώρα δημιουργούμε ένα συμβάν βήματος (Βήμα, Προσθήκη συμβάντος => Βήμα) και εκτελούμε ξανά τη λειτουργία (κάνουμε δεξί κλικ στο Εκτέλεση κώδικα):

200?"200px":""+(this.scrollHeight+5)+"px");">
if mouse_check_button_pressed(mb_left) //Εάν πατηθεί LMB
{
draw_rect=true; //Σχεδιάζουμε ένα ορθογώνιο
startx=ποντίκι_x; //Έναρξη x θέση = ποντίκι x θέση
starty=mouse_y; //Θέση εκκίνησης = θέση ποντικιού
με όλα επιλεγμένα=false; //Αυτή δεν είναι ακόμη δηλωμένη μεταβλητή, θα μάθουμε τι θα κάνει αργότερα
}

Αν το mouse_check_button_released(mb_left) //Εάν το LMB απελευθερωθεί
{
draw_rect=false; //Δεν σχεδιάζουμε παραλληλόγραμμο
για(i=0;i<=instance_number(par);i+=1) //Читайте про цикл for ниже
{
ii=instance_find(par,i); //Αναζητούμε ένα αντικείμενο που δεν έχει φτιαχτεί ακόμα
if(collision_rectangle(startx,starty,mouse_x,mouse_y,ii,true,false)) //Εδώ είναι το ορθογώνιο σύγκρουσης (επαφή)
{
ii.selected=true;
}
}
}

Ο κώδικας είναι μεγάλος και πολύπλοκος ενώ μαθαίνουμε για την πρόταση υπό όρους if:
Ο κώδικας με το if εκτελείται ως εξής:

200?"200px":""+(this.scrollHeight+5)+"px");">
αν (προϋπόθεση)
{
δράση
}

Μπορεί επίσης να περιέχει μια άλλη δήλωση (αλλιώς), παράδειγμα:

200?"200px":""+(this.scrollHeight+5)+"px");">if (συνθήκη)
{
δράση
}
αλλού
{
δράση 2
}

Και for is ένας τελεστής βρόχου, εκτελείται ως εξής:

200?"200px":""+(this.scrollHeight+5)+"px");">
Για (<переменная> ; <выражение> ;<действие переменной>)
{
<действия>
}


Το for operator είναι πολύ δυνατό πράγμα, βοηθάει πολύ σε δύσκολες καταστάσεις

Operator - ενέργειες ενσωματωμένες σε μια γλώσσα, για παράδειγμα, οι πιο συνηθισμένες είναι int, if, else, string, switch, for, case, break, exit, κ.λπ., κ.λπ.

Τώρα δημιουργούμε επίσης ένα συμβάν σχεδίασης (σχήμα) και γράφουμε με τον ίδιο τρόπο:

200?"200px":""+(this.scrollHeight+5)+"px");">αν draw_rect=true
{
άλφα=.8;
draw_rectangle_color(startx,starty,mouse_x,mouse_y,c_green,c_green,c_green,c_green,true);
}

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

200?"200px":""+(this.scrollHeight+5)+"px");">draw_rectangle_color(x1,y1,x2,y2,color 1, color 2, color 3, color 4, outline)


περίγραμμα - εάν θα σχεδιαστεί μόνο η άκρη (αληθής) ή το γεμάτο ορθογώνιο (ψευδή)
Βρήκαμε μια νέα λέξη - σταθερά, αυτή είναι μια αριθμητική έκφραση ή κωδικός που αντικαταστάθηκε από μια λέξη, η αιώρα έχει ενσωματωμένες σταθερές:

200?"200px":""+(this.scrollHeight+5)+"px");">true - 1
ψευδές - 0
pi - 3,1415...


Λοιπόν, το καταλάβαμε, τώρα πρέπει να δημιουργήσουμε νέο αντικείμενο- ένα γονικό αντικείμενο που θα συνδεθεί με τα παιδιά του. Ας το ονομάσουμε par (για να αλλάξετε το όνομα πρέπει να αλλάξετε τον κώδικα στο συμβάν βήματος αντικειμένου ελέγχου), γράψτε στο συμβάν δημιουργίας:

200?"200px":""+(this.scrollHeight+5)+"px");">selected=false; //Εδώ είναι η μεταβλητή μας, είτε το αντικείμενο είναι επιλεγμένο

Αυτά είναι όλα. Τώρα, φυσικά, χρειαζόμαστε ένα αντικείμενο που μπορεί να κινηθεί, το ονομάζουμε objTest και γράφουμε τον κώδικα στο συμβάν δημιουργίας:

200?"200px":""+(this.scrollHeight+5)+"px");">gox=x; //Πού να πάτε...
goy=y; //από y
επιλεγμένο=λάθος; //Δεν έχουμε επιλεγεί =)
object_set_parent(self,par) //Εδώ είναι η επιλογή του γονέα

Νέα δράση:

200?"200px":""+(this.scrollHeight+5)+"px");">object_set_parent(ind,obj)

Ορίζει το γονικό αντικείμενο στο αντικείμενο που ονομάζεται ind.
ΚΑΙ νέο χειριστή: εαυτός, σημαίνει ότι η δράση θα πάει στον εαυτό της
Μην φοβάστε, μένει λίγο ακόμα στο βήμα event:

200?"200px":""+(this.scrollHeight+5)+"px");">if distance_to_point(gox,goy) > 20
{
mp_potential_step(gox,goy,6,solid);
}
if(selected=true) && mouse_check_button_pressed(mb_right)
{
gox=ποντίκι_χ;
goy=ποντίκι_υ;

θεματικό πάρκο:
Θα χρειαστούμε:
κτίζοντας ξωτικό
sprite μενού
SPRITES ΔΙΑΦΟΡΩΝ ΚΟΥΜΠΙΩΝ ΟΠΩΣ:
srite με την επιγραφή (κατασκευή, κατασκευή, κατασκευή κ.λπ.)
ένα παράθυρο που εμφανίζεται
σχέδιο κτιρίου,
1) τα υπόλοιπα θα τα προσθέσουμε μόνοι μας
2) η λέξη πλαστό - δημιούργησα μόνος μου, γιατί θα χρειαστεί να το πλαστογραφήσουμε για να ταιριάζει με την πηγή μας)
Ας ξεκινήσουμε:
1) δημιουργήστε όλα όσα είναι γραμμένα στο σημείο I εκτός από το 1)
Ας δημιουργήσουμε μια καθολική μεταβλητή που ονομάζεται χρήματα, ορίζουμε οποιοδήποτε αρχικό ποσό χρημάτων
Θα δημιουργήσουμε επίσης ένα αντικείμενο ποντικιού & πληκτρολογίου
Ας δημιουργήσουμε ένα κείμενο, ας το ονομάσουμε πληροφορίες, δημιουργήστε ένα πάντα συμβάν και δημιουργήστε μια ενέργεια σε αυτό:
επιλέξτε πληροφορίες στην επιλογή δράσης επιλέξτε σύνολο κειμένου στο κείμενο γράψτε αυτό:
"money: " &(global("money".
2) προσθέστε ένα μενού, το κύριο καθήκον του μενού δεν είναι να παρεμβαίνει, αλλά να βοηθά τον παίκτη να πλοηγηθεί (πώς μπορεί να παρεμβαίνει; - είναι εύκολο αν το τοποθετήσετε στη μέση του παιχνιδιού), πριν δημιουργήσετε το μενού, Θα δημιουργήσουμε ένα νέο επίπεδο, το οποίο θα ονομάσουμε μενού, στις αναλογίες του (ρυθμίσεις, επιλογές) στο στοιχείο εμφάνισης που γράφουμε:


θα προσθέσουμε ένα sprite σε αυτό και θα πάρουμε την εικόνα του μενού που ήταν στα υλικά προπαραγωγής (σημείο I) και θα τοποθετήσουμε το μενού μας σε ένα απομονωμένο μέρος όπου δεν θα παρεμβαίνει, αλλά θα είναι ορατό στην οθόνη
Ας τοποθετήσουμε επίσης ένα κουμπί από υλικά προ-φινιρίσματος (σημείο I) με την επιγραφή BUILD (ή κάτι τέτοιο)
ας το βάλουμε στο μενού
Τώρα μεταβείτε στον Επεξεργαστή φύλλου συμβάντων
δημιουργήστε ένα συμβάν (#μπλα μπλα μπλα# - αυτό είναι το μήνυμά μου (εξήγηση) προς εσάς μόνο αντί για μπλα μπλα μπλα θα υπάρχει το σχόλιό μου για εσάς· >> - δράση; ll - διαίρεση των παραθύρων για παράδειγμα:

ποντίκι&πληκτρολόγιο ll στο αντικείμενο κλικ ll αριστερό κλικ για να γίνει αντικείμενο #κουμπί μενού σας με την επιγραφή BUILD (ή κάτι τέτοιο)##τα υπόλοιπα αργότερα (δείτε σημείο 3)#
3)τώρα το πιο δύσκολο κομμάτι(Το χωρίζω σε δύο σημεία για να μην είναι τόσο περίπλοκο)
δημιουργήστε ένα sprite από υλικά προ-τελικής επεξεργασίας "ένα παράθυρο που θα εμφανιστεί"
Στη συνέχεια, δημιουργούμε ένα κενό sprite που ονομάζεται p1, μετακινούμε το παράθυρο από την οθόνη και βάζουμε το p1 στο σημείο όπου πρέπει να εμφανίζεται το παράθυρό σας όταν πατάτε το κουμπί δημιουργίας (ή κάτι τέτοιο CHVER)
Τέλεια! Τώρα μεταβείτε στον επεξεργαστή φύλλου συμβάντος
Ας γράψουμε το ημιτελές γεγονός μέχρι το τέλος:
Κείμενο θα ορίσει κείμενο ll μπλα-μπλα-μπλα)
ποντίκι&πληκτρολόγιο ll στο αντικείμενο κλικ ll αριστερό κλικ για αντικείμενο #κουμπί μενού σας με ετικέτα BUILD (ή κάτι τέτοιο)#>>
4)Το δεύτερο μέρος του πιο δύσκολου μέρους:
ας δημιουργήσουμε ένα sprite όπου θα σχεδιάζεται η εικόνα του κτιρίου (υλικά προ-τελικής επεξεργασίας), ας το ονομάσουμε h1
ας δημιουργήσουμε ένα κενό sprite, το ονομάσουμε p2, τοποθετήστε το τώρα στο σημείο όπου πρέπει να ανοίξει το παράθυρο,
Ας δημιουργήσουμε ένα sprite, επίσης ένα παράθυρο (υλικά προ-τελικής επεξεργασίας), στο παράθυρο θα γράψουμε όμορφα το όνομα του κτιρίου, το κόστος και την περιγραφή του (προαιρετικά) και θα το ονομάσουμε i1
Ας δημιουργήσουμε ένα άλλο κενό sprite που ονομάζεται p3, το τοποθετούμε δίπλα στο p2, μόνο έτσι ώστε να αγγίζει το p2 μόνο με την επάνω αριστερή γωνία
Τώρα ας δημιουργήσουμε πολλά συμβάντα, αλλά πρώτα κάνουμε το προηγούμενο συμβάν μια νέα ενέργεια:
ποντίκι&πληκτρολόγιο ll στο αντικείμενο κλικ ll αριστερό κλικ για αντικείμενο #το κουμπί του μενού σας με την επιγραφή BUILD (ή κάτι τέτοιο)#>> σύστημα θα δημιουργήσει αντικείμενο σε σχέση με το αντικείμενο ll #παράθυρό σας# #αριθμός επιπέδου κάτω από το μενού ονόματος# # X ;Y-μην αλλάξετε# σε αντικείμενο p1
>>σύστημα θα δημιουργήσει αντικείμενο σε σχέση με το αντικείμενο ll #δεύτερο παράθυρό σας# #αριθμός επιπέδου κάτω από το μενού ονόματος# #X;Y-do not change# στο αντικείμενο p2
Πρέπει επίσης να του κάνουμε ένα συμβάν:
αντιγράψτε το συμβάν και αντιστρέψτε το
νέο γεγονός
ποντίκι&πληκτρολόγιο ll είναι πάνω από το αντικείμενο ll h1>>σύστημα θα δημιουργήσει αντικείμενο σε σχέση με το αντικείμενο ll i1 #αριθμός επιπέδου κάτω από το μενού ονόματος# #X;Y-do not change# σε αντικείμενο p3
Ας φτιάξουμε ένα ξωτικό με ένα κτίριο (χρησιμοποιήστε υλικά προπαραγωγής) και ας το πούμε σπίτι
Ας δημιουργήσουμε ένα παράθυρο όπου θα εμφανίζονται τα κτίριά μας όταν επιλεχθούν στο μενού, ονομάστε το rlo
εκδηλώσεις:
ποντίκι&πληκτρολόγιο ll στο αντικείμενο κλικ ll αριστερό κλικ στο h1>>σύστημα θα δημιουργήσει σε αντικείμενο σε σχέση με αντικείμενο ll σπίτι #αριθμός επιπέδου κάτω από το μενού ονόματος# #X;Y-do not change# σε αντικείμενο rlo
>> σύστημα θα αφαιρέσει από την αξία ll #ποσό χρημάτων που πρέπει να αφαιρεθεί κατά την κατασκευή#
Τώρα ήταν αδύνατο να χτιστεί μια εκδήλωση
Θα σου πω το δικό μου πρώην τρόποςαπαγορεύσεις (όταν τελειώσω το γράψιμο θα εξερευνήσω μια άλλη μέθοδο που με έκανε μπλε όταν θυμήθηκα το παγκόσμιο παιχνίδι θεματικού πάρκου)
εκδηλώσεις:
σπίτι ll σε σύγκρουση με άλλο αντικείμενο ll με σπίτι
>>το σπίτι θα καταστραφεί
>> σύστημα θα αφαιρέσει από την αξία ll - #διπλασιάστε το χρηματικό ποσό που αφαιρέθηκε κατά την κατασκευή##σημείωση που πρέπει να βάλετε - ποσότητα#
βασικά τα πάντα.
III τι θέλω να πω:

Αναστατώθηκα πολύ από την κατάρρευση του παιχνιδιού μου. Ήταν ένα παιχνίδι στρατηγικής και αυτό το άρθρο συντάχθηκε σύμφωνα με το σχήμα του. Σας ζητώ να μην ασκήσετε υπερβολική κριτική, έγραψα για μεγάλο χρονικό διάστημα, αν βρείτε σφάλματα ομιλίας, γράψε και θα τα διορθώσω
και επίσης εδώ είναι ο πηγαίος κώδικας για την ευχαρίστηση προβολής, κοιτάξτε, κατ 'αρχήν όλα είναι ίδια όπως γράφονται εδώ, μόνο που αυτή ήταν μια δοκιμαστική έκδοση του παιχνιδιού. Το κύριο πράγμα είναι να μην αλλάξετε τίποτα, διαφορετικά θα είναι buggy !
χρησιμοποιήστε το, πειραματιστείτε, ελέγξτε το, κάντε ό,τι θέλετε, είναι εντάξει για μένα

KaMiKaZa:
Όλες οι εκφράσεις «συστήματος» πρέπει να περιλαμβάνονται στην ετικέτα «Κώδικας».
Τότε νομίζω ότι θα είναι καλύτερα.
Επίσης, μου φαίνεται ότι τα στιγμιότυπα οθόνης δεν θα έβλαπταν εδώ. Και επίσης ο πηγαίος κώδικας, για αρχάριους.

θεματικό πάρκο:
Δεν ξέρω πώς να τραβήξω στιγμιότυπα οθόνης γεγονότων.

Λοιπόν, αυτό δεν είναι απαραίτητο.

iamnp:
theme_park , υπάρχει ένα ειδικό κουμπί στο πληκτρολόγιο - PrintScreen

θεματικό πάρκο:
Ξέρω ότι μερικοί άνθρωποι το κάνουν διαφορετικά.Επιπλέον, ο καθένας έχει το δικό του sprite
και αν στήσω όλα αυτά τα sprites, λίγοι θα καταλάβουν.
Λοιπόν, ίσως κάποιος δώσει ένα συν; Δεν είναι περίεργο που δυσκολευόμουν;

μπουρλατσένκο:
Προκειμένου ένα τέτοιο μάθημα να ενδιαφέρει κανέναν, πρέπει να διαμορφωθεί ανάλογα, αλλά εδώ "ούτως ή άλλως ήταν".
Κι όμως, αν θέλετε, λίγο-λίγο, όταν έχετε χρόνο, παρακαλούμε να το «ομορφύνετε».

θεματικό πάρκο:
εντάξει, θα γυρίσω από το σχολείο και θα ετοιμαστώ.
ΥΣΤΕΡΟΓΡΑΦΟ. προστέθηκε πηγή

Serega Lebedev:

iamnp, πού πηγαίνουν αυτά τα στιγμιότυπα οθόνης αργότερα;

KaMiKaZa:

Στο πρόχειρο.
Πηγαίνετε σε οποιοδήποτε επεξεργαστής κειμένου, και εκτελέστε τη λειτουργία "Επικόλληση" ή πατήστε Ctrl+V.

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

Τι είναι λοιπόν turn based παιχνίδι? Ο παρακάτω ορισμός μπορεί να βρεθεί στη Wikipedia στρατηγική βασισμένη στη σειρά - αυτό είναι ένα είδος παιχνίδια στον υπολογιστή, το κύριο χαρακτηριστικό του οποίου είναι ότι οι παίκτες κάνουν εναλλάξ κινήσεις, σε αντίθεση με τη στρατηγική σε πραγματικό χρόνο. Θα απλοποιούσα λίγο αυτόν τον ορισμό:

  • Βήμα-βήμα στρατηγική - είναι ένα παιχνίδι στρατηγικής που βασίζεται στη σειρά.
  • Παιχνίδι στρατηγικής - Αυτό είναι ένα είδος παιχνιδιών στο οποίο το κλειδί για την επίτευξη της νίκης είναι ο σχεδιασμός και η στρατηγική σκέψη..
  • Παιχνίδι turn-based - είναι ένα είδος παιχνιδιών του οποίου το κύριο χαρακτηριστικό είναι ότι οι παίκτες κάνουν εναλλάξ κινήσεις.
Τα παιχνίδια σειράς περιλαμβάνουν:
  • Στρατηγικές που βασίζονται στη σειρά
  • Παιχνίδια με κάρτες
  • Επιτραπέζια παιχνίδια (σκάκι, go, μονοπώλιο κ.λπ.)
Σημειώνω ότι τα παιχνίδια turn-based επιβάλλουν λιγότερους περιορισμούς στην πολυπλοκότητα του πρωτοκόλλου αλληλεπίδρασης σε σύγκριση με τα παιχνίδια σε πραγματικό χρόνο. Και συγκεκριμένα, Ο χρόνος αντίδρασης σε ένα συγκεκριμένο γεγονός δεν παίζει βασικό ρόλο. Ο παίκτης έχει συνήθως 10 δευτερόλεπτα για να πάρει μια απόφαση. Ακόμα κι αν το ping είναι τεράστιο, ας πούμε 3 δευτερόλεπτα, τότε ο παίκτης έχει ακόμα 7 δευτερόλεπτα για να σκεφτεί. Επιπλέον, το ping μπορεί να πηδήξει και να πηδήξει, αλλά δεν μας ενδιαφέρει καθόλου αυτό (σε παιχνίδια σε πραγματικό χρόνο, αυτή η κατάσταση πρακτικά σκοτώνει οποιοδήποτε πρωτόκολλο).

Τυπικά (στο 95% των παιχνιδιών turn-based) ακριβώς ένας παίκτης παίρνει την απόφαση ανά πάσα στιγμή. Κατά συνέπεια, ο αριθμός των αιτημάτων στα οποία πρέπει να ανταποκριθούμε επαρκώς περιορίζεται.

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

Το παραπάνω σκεπτικό βασίζεται στη 2μηνη ανάπτυξη ενός συγκεκριμένου παιχνιδιού τράπουλας.

Έξυπνος ή ηλίθιος πελάτης;

Αρχικά, ας αποφασίσουμε πόσο «έξυπνος» μπορεί να είναι ο πελάτης μας. Συζητώ αν αξίζει να αντιγράψω τη λογική της εφαρμογής (κανόνες παιχνιδιού) στον πελάτη. Φυσικά, ο διακομιστής πρέπει να είναι έξυπνος για να αποτρέψει ενδεχόμενο hacking της εφαρμογής. Αξίζει όμως να διδάξουμε επιχειρηματική λογική στον πελάτη;

Αυτό εξαρτάται άμεσα από το πόσο ζυγίζει η πλήρης ποσότητα δεδομένων σχετικά με την κατάσταση του παιχνιδιού σας. Εάν αυτός ο όγκος δεδομένων είναι μεγάλος, χρειάζεται πολύς χρόνος για να συλλεχθεί στον διακομιστή και μεταφερθεί στον πελάτη, τότε είναι λογικό να εφαρμοστεί μέρος της λογικής στον πελάτη για να ανακουφιστεί ο διακομιστής. Για παράδειγμα, στο Civilization ο μετρητής μνήμης που χρησιμοποιείται είναι πάντα εκτός γραφημάτων. Μπορείτε να δημιουργήσετε κάτι παρόμοιο, αφήνοντας μόνο τη διεπαφή χρήστη στον πελάτη;

Από την άλλη, όσο πιο έξυπνος είναι ο πελάτης, τόσο πιο ακριβή θα είναι η ανάπτυξη του παιχνιδιού. Επιτρέψτε μου να σημειώσω ότι ο χρόνος ανάπτυξης διακομιστή δεν εξαρτάται σε καμία περίπτωση από τη γνώση του πελάτη. Ακόμα κι αν ο πελάτης είναι super-duper-mega smart, εάν ο χρήστης θέλει να φορτώσει ξανά το παράθυρο του προγράμματος περιήγησης, ο διακομιστής θα πρέπει να συλλέξει και να συγκεντρώσει όλα τα δεδομένα σχετικά με το παιχνίδι για να τα μεταφέρει στον πελάτη. A la "Φόρτωση αποθηκευμένου παιχνιδιού". Συμπέρασμα: Ένας έξυπνος πελάτης μπορεί να επιταχύνει μια εφαρμογή, αλλά θα απαιτεί πάντα πρόσθετους πόρους για την ανάπτυξη της εφαρμογής.

Προτείνω το εξής δοκιμή:

1. Το επιτρέπει η ένταση του καναλιού;

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

2. Είναι έντασης εργασίας;

Υπολογίστε την πολυπλοκότητα του αλγόριθμου συλλογής δεδομένων του παιχνιδιού (σε κλάσματα του δευτερολέπτου). Εδώ, λάβετε υπόψη όλα τα ερωτήματα στη βάση δεδομένων. Στη συνέχεια, πολλαπλασιάστε με τον μέσο αριθμό αιτημάτων στον διακομιστή ανά δευτερόλεπτο. Εάν ο χρόνος υπερβαίνει το ένα δευτερόλεπτο, τότε ένας ηλίθιος πελάτης είναι απαράδεκτος. Εάν αυτός ο αριθμός υπερβαίνει τα 200 ms, τότε θα πρέπει να σκεφτείτε αν θα διαρκέσει;

Συνέχιση:

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

(A. Cuningham)

Στα δύο προηγούμενα τεύχη μάθαμε φτιάξτε απλά παιχνίδια 2D, ελέγξτε τα sprites, κάντε κύλιση στην οθόνη του παιχνιδιού, παρακολουθήστε συγκρούσεις αντικειμένων παιχνιδιού, δημιουργήστε μια διεπαφή (κουμπιά, ποντίκι, πληκτρολόγιο, περιοχές κειμένου) και εργαστείτε σε λειτουργίες πλήρους οθόνης και παραθύρων. Όλα αυτά έγιναν χρησιμοποιώντας ένα arcade παιχνίδι ως παράδειγμα.

Αυτή τη φορά θα περάσουμε από τα arcade παιχνίδια σε ένα πιο «σοβαρό» είδος - στρατηγικές. Εδώ θα πρέπει να κυριαρχήσουμε μια ολόκληρη σειρά νέων μηχανισμών, αλλά δεν θα υπάρχει τίποτα περίπλοκο και εδώ. Σε αυτό το άρθρο εμείς Ας μελετήσουμε τη δομή μιας στρατηγικής που βασίζεται στη σειρά(και επίσης στρατηγική σε πραγματικό χρόνο- είναι ακόμα πιο εύκολο να το κάνετε με το LKI-Creator) και θα φτιάξουμε ένα παιχνίδι ως παράδειγμα, σχεδιασμένο, ωστόσο, μόνο για πολλαπλών χρηστώνλειτουργία (και επίσης επεξεργαστής χάρτηγια εκείνη). Θα ασχοληθούμε με το single-player mode στο επόμενο τεύχος της στήλης μας - αφιερωμένο στο βασικά τεχνητή νοημοσύνη .

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

Λοιπόν, μπορείτε να βρείτε τα υλικά από τα προηγούμενα μαθήματα μας στο δικό μας CD, στην ενότητα «Κάνε το μόνος σου παιχνίδι» που δημιουργήθηκε ειδικά για αυτό το σκοπό.

Διατύπωση του προβλήματος

Ας γράψουμε ένα παιχνίδι στρατηγικής που αποτελείται από μια μάχη μεταξύ δύο στρατών φαντασίας. Ο στόχος της μάχης είναι να συλλάβει αρκετούς οβελίσκοι, τοποθετείται στον χάρτη. Πριν από τη μάχη αναπτύσσουμε τα στρατεύματά μας, που αποτελούνται από 6 ξιφομάχοι, 4 τοξότες, 2 ιππότες, 2 μάγοικαι 1 φάντασμα, εντός της επικράτειας που μας έχει ανατεθεί. Εκτός από αυτά, στον χάρτη υπάρχουν και ουδέτερα δράκους.

Χαρακτηριστικά των μαχητών
Μαχητής Κίνηση Επιτυχίες Εύρος Βλάβη ΠΡΟΣΤΑΣΙΑ Δυνατότητες
Ξιφομάχος4 8 1 7 2 -
Τοξότης4 5 7 5 1 -
ιππότης3 15 1 9 4 Healing, Knight's Strike
Μάγος3 12 5 6 0 Μπάλα φωτιάς
Φάντασμα4 7 2 5 5 Αναγέννηση
Ο δράκος6 30 2 12 5 Πτήση

Τα χαρακτηριστικά των μαχητών παρουσιάζονται στον πίνακα. Θεραπεία- αυτό είναι το δικαίωμα να θεραπεύεις έναν γειτονικό πολεμιστή (εκτός από ένα φάντασμα) σε πλήρη υγεία μία φορά ανά μάχη. Knight's Strike- το δικαίωμα πρόκλησης τριπλής ζημιάς μία φορά ανά παιχνίδι. Μπάλα φωτιάς- η επίθεση του μάγου αφαιρεί τα σημεία χτυπήματος όχι μόνο από τον άμεσο στόχο, αλλά και από τα γύρω τετράγωνα. Αναγέννηση- ανάκτηση 1 χτυπήματος ανά στροφή. Πτήση- το δικαίωμα κίνησης πάνω από εμπόδια.

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

Το πάρτι τελειώνει όταν η μία πλευρά είτε συλλάβει περισσότερους από τους μισούς οβελίσκους που υπάρχουν στον χάρτη είτε πεθάνει εντελώς.

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

Προετοιμασία για δουλειά

Πριν ξεκινήσουμε, θα χρειαστεί να εγκαταστήσουμε ξανά το πακέτο LKI-Δημιουργός. Γεγονός είναι ότι σε σχέση με την προηγούμενη φορά, έχουν γίνει πολλές αλλαγές και προσθήκες σε αυτό.

(Ελπιζω οτι Δελφοίέχετε ήδη εγκαταστήσει? αν όχι, τότε διαβάστε συστάσεις για αυτό το θέμα στο προηγούμενο άρθρο μας - στο τεύχος Ιουνίου του περιοδικού ή στο CD αυτού του τεύχους ή στον ιστότοπο.)

Είναι σημαντικό:η προηγούμενη έκδοση του LKI-Creator είχε κάποια προβλήματα συμβατότητας με τις νέες εκδόσεις του Delphi. Σε αυτή την έκδοση εξαλείφονται.

Πάρτε το αρχείο με κείμενα προγράμματος και εικόνες από το CD μας (ενότητα «Παιχνίδι με τα χέρια σας») και αποσυσκευάστε το στον κατάλογο του έργου.

Τώρα μπορείτε να κάνετε λήψη απαραίτητα αρχεία από εδώ .

Θα πρέπει να έχουμε τρεις υποκαταλόγους. Το One - Units - αποθηκεύει βιβλιοθήκες DirectX και λειτουργικές μονάδες του πακέτου LKI-Creator. Σε ένα άλλο - Έργο - θα δουλέψουμε. οι φωτογραφίες που θα χρειαστούμε τοποθετούνται εκεί εκ των προτέρων, και προηγούμενη έκδοσητην στοά μας. Στο τρίτο - Escort - ένα έτοιμο πρόγραμμα που πρέπει να πετύχουμε.

Τώρα ας εγκαταστήσουμε (επανεγκαταστήσουμε) το LKI-Creator. Στο μενού Delphi, ανοίξτε το στοιχείο Component και επιλέξτε Install Component. Εάν έχετε ήδη εγκαταστήσει αυτό το πακέτο, μείνετε στην καρτέλα Into υπάρχον πακέτο, διαφορετικά μεταβείτε στην καρτέλα Into new πακέτο και συμπληρώστε τις κενές γραμμές όπως φαίνεται στην εικόνα (στην επάνω γραμμή, ο ευκολότερος τρόπος είναι να επιλέξετε το LKI2dEngine. αρχείο pas χρησιμοποιώντας το κουμπί Αναζήτηση και στο κάτω μέρος απλώς σημειώστε το LKI). Στη συνέχεια, κάντε κλικ στο OK και επιλέξτε Εγκατάσταση. ΣΕ πάνω πάνελΔελφοί θα πρέπει να δείτε την καρτέλα LKI.

Τώρα το μόνο που μένει είναι να ανεβάσουμε το έργο μας. Στο μενού Αρχείο, επιλέξτε Άνοιγμα, ανοίξτε το αρχείο Project\Obelisk.dpr…

Πού είναι ο χάρτης, Μπίλι; Χρειαζόμαστε έναν χάρτη!

Ωστόσο, πριν μπούμε στα μεγάλα πράγματα, θα χρειαστεί να δουλέψουμε λίγο περισσότερο στη μηχανή γραφικών.

Στο Star Escort, το προηγούμενο έργο μας, ο «χάρτης» δεν είχε κανένα νόημα: τα αστέρια τοποθετήθηκαν τυχαία και δεν επηρέασαν τίποτα, και η θέση των άλλων αντικειμένων είτε προσδιορίστηκε απευθείας στον κώδικα είτε προσδιορίστηκε τυχαία. Αυτό δεν είναι κατάλληλο για κάθε έργο. Αυτό σημαίνει ότι ήρθε η ώρα να προσθέσουμε στον κινητήρα μας χάρτης περιοχής.

Πιθανότατα μπορείτε ήδη να μαντέψετε πώς θα μοιάζει - βάζουμε ένα αντικείμενο χάρτη στο παράθυρο του έργου και, στη συνέχεια, το καταχωρίζουμε στην ιδιοκτησία Χάρτηςτον κινητήρα μας.

Έτσι είναι... αλλά έχουμε περισσότερες από μία κατηγορίες καρτών. Ας ρίξουμε μια πιο προσεκτική ματιά...

Τύποι καρτών

Ο χάρτης αποτελείται από κάτι τοπίοΚαι αντικείμεναεγκατεστημένο σε αυτό. Το τοπίο πιο συχνά (αλλά όχι πάντα) χωρίζεται σε κελιά που ονομάζονται πλακάκια- πλακάκια.

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

Κατά μία έννοια, η ζωή με τετράγωνα είναι ευκολότερη: εάν έχουμε μια δισδιάστατη διάταξη κελιών, είναι αμέσως σαφές πώς να βρούμε τα κελιά που βρίσκονται δίπλα σε ένα δεδομένο κελί. Αυτά είναι +1 και -1 για καθέναν από τους δύο δείκτες. Με τα εξάγωνα, όλα είναι λίγο πιο περίπλοκα... αλλά ο εξαγωνικός πίνακας έχει μια πολύτιμη ιδιότητα: όλες οι κατευθύνσεις σε αυτόν είναι ίδιες. Αυτό δεν συμβαίνει με ένα τετράγωνο πλέγμα: οι διαγώνιες διαφέρουν σημαντικά από τις οριζόντιες και κάθετες. Επομένως, για σοβαρούς στρατηγικούς υπολογισμούς, τα εξάγωνα μπορεί να είναι καλύτερα από τα τετράγωνα.

Υπάρχουν επίσης κάρτες χωρίς πλακάκια. Το LKI-Creator υποστηρίζει δύο τύπους: graph και patchwork.

Ένας χάρτης γραφήματος είναι ένας χάρτης στον οποίο μόνο μερικά βασικά σημεία έχουν νόημα, συν ίσως ειδικές περιοχές (για παράδειγμα, αδιάβατες), και τα υπόλοιπα είναι απλώς ένα μοτίβο που δεν έχει αποτέλεσμα παιχνιδιού. Έτσι φτιάχνονται συχνά οι αστρικοί χάρτες, όπως, ας πούμε, στο Master of Orion: τα αστέρια και οι μαύρες τρύπες είναι βασικά σημεία, τα υπόλοιπα είναι φόντο. Σε αυτήν τη λειτουργία, μερικές φορές φτιάχνουν παγκόσμιους χάρτες, για παράδειγμα, για ένα παιχνίδι ρόλων.

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

Παραδείγματα καρτών από διάφορα παιχνίδια, που υποδεικνύουν τον τύπο, είναι στις εικόνες.

Η πλειοψηφία λοιπόν δισδιάστατηΟι χάρτες (τρισδιάστατοι - ένα ειδικό άρθρο) μπορούν να χωριστούν σε τέσσερις κατηγορίες:

  • Ορθογώνιος- TLKIRectMap. Αυτός είναι ένας χάρτης με πλακάκια, τα κελιά είναι τετράγωνα. Ένας τέτοιος χάρτης, για παράδειγμα, στο Civilization III.
  • Εξαγώνιος- TLKIHexMap. Χάρτης με πλακάκια με εξαγωνικά κελιά. Χρησιμοποιείται σε πολλά παιχνίδια πολέμου, και όχι μόνο: έτσι, για παράδειγμα, φτιάχτηκε παραδοσιακά ο χάρτης μάχης Heroes of Might & Magic.

    Αυτοί οι δύο τύποι καρτών είναι απόγονοι της γενικής τάξης TLKITileMap.

  • Γραφοβάγια- Χάρτης TLKIGraph. Αυτή η κάρτα έχει φόντο (ιδιότητα φόντου)και τα βασικά σημεία που επισημαίνονται σε αυτό είναι στατικά αντικείμενα. Η θέση άλλων αντικειμένων σε αυτόν τον χάρτη εκφράζεται είτε με συνηθισμένες συντεταγμένες (όπως ένα διαστημόπλοιο στο διαστρικό διάστημα) είτε με αναφορά σε ένα αντικείμενο (το ίδιο πλοίο σε τροχιά πλανήτη). Αυτές είναι οι κάρτες Master of Orion, Arcanum (παγκόσμια) και ούτω καθεξής.
  • Κουρελού- TLKIClusterMap. Έχει μια ιδιότητα φόντου, όπως το γράφημα, και μια δεύτερη ιδιότητα - μάσκα, που καθορίζει ποιο σημείο ανήκει σε ποια περιοχή και την ιδιότητα σύνορα, το οποίο ορίζει τις συνδέσεις μεταξύ των "shreds". Έτσι είναι διατεταγμένοι οι χάρτες, για παράδειγμα, στο Medieval: Απόλυτος πόλεμοςή Βικτώρια.

Είναι σημαντικό:Οι κατηγορίες χαρτών δεν περιγράφονται στη λειτουργική μονάδα LKI2dEngine, αλλά στο LKI2dMap.

Γωνίες κλίσης

Αλλά αν πιστεύετε ότι αυτό εξαντλεί τις δυνατότητες του LKI-Creator για την εμφάνιση χαρτών, τότε κάνετε πολύ λάθος.

Ο χάρτης μπορεί να παρουσιαστεί κάτοψηή ισομετρική- κοιτάξτε υπό γωνία προς την κατακόρυφο. Για παράδειγμα, ο χάρτης του Civilization III ή του Heroes of Might & Magic IV είναι ισομετρικός, αλλά το Civilization I υιοθετεί μια άποψη από πάνω προς τα κάτω.

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

Η ιδιότητα του χάρτη είναι υπεύθυνη για την ισομετρία Ισομετρικήκαι δύο παραμέτρους που καθορίζουν τη γωνία με την οποία φαίνεται η κάμερά μας: PhiΚαι Θήτα.

Το πρώτο είναι υπεύθυνο για την περιστροφή του χάρτη σε σχέση με τον κατακόρυφο άξονα: για παράδειγμα, αν τον ρυθμίσετε σε 45 μοίρες (μετριέται σε μοίρες), τότε το ορθογώνιο κελί πλέγματος θα προσανατολιστεί με γωνία προς τα πάνω, όπως στο Civilization . Στο Phi=0, μία από τις πλευρές του κελιού θα είναι οριζόντια.

Το δεύτερο ελέγχει την κλίση της κάμερας σε σχέση με την κατακόρυφο. Για ευκολία, δίνεται ως η αναλογία οριζόντιων και κάθετων μονάδων μήκους. Ας πούμε, εάν θέλουμε το κελί μας να έχει το μισό ύψος όσο το πλάτος, πρέπει να ορίσουμε το Theta στο 2.

Με έναν χάρτη με πλακάκια, δεν επιτρέπεται να επιλέξουμε αυτές τις γωνίες αυθαίρετα: άλλωστε δεν έχουμε (ακόμα) 3D. Εξαρτώνται άμεσα από τις παραμέτρους των πλακιδίων. Για παράδειγμα, εάν έχουμε έναν άξονα σε σχήμα ρόμβου με γωνία προς τα πάνω και ο κατακόρυφος άξονας είναι το μισό του μεγέθους του οριζόντιου άξονα, τότε πρέπει να ορίσουμε τις παραμέτρους 45 και 2.

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

Αρθρώσεις

Συνονθύλευμα χάρτης, κάτοψη.

Οι χάρτες πλακιδίων έχουν ένα άλλο πρόβλημα - την ένωση πλακιδίων. Ελέγχεται από την παράμετρο TileBorderStyle. Τις περισσότερες φορές αυτό tileStraight, μια λειτουργία στην οποία τα πλακίδια απλά ταιριάζουν μεταξύ τους χωρίς εφέ ακμών ή tileBorder, στις οποίες σχεδιάζονται γραμμές που χωρίζουν το ένα πλακίδιο από το άλλο - τα όρια των κελιών (στην τελευταία περίπτωση, μην ξεχάσετε να ορίσετε χρώμαπλέγματα στην παράμετρο TileBorderColor).

Αλλά υπάρχει μια πιο πονηρή επιλογή, όταν πανομοιότυπα πλακάκια είναι δίπλα στο άλλο χωρίς αλλαγές και διαφορετικά χρησιμοποιούνται χρησιμοποιώντας ένα ειδικό "μεταβατικό" πλακίδιο. Αυτό γίνεται συνήθως εάν ο χάρτης αποτελείται κυρίως από μεγάλες εκτάσεις ενός τύπου επικράτειας, ας πούμε, μεγάλες περιοχές πρασίνου, και ένα μεμονωμένο κελί δεν είναι σημαντικό και δεν πρέπει να γίνει αντιληπτό από τον παίκτη. Αυτή είναι η κάρτα Heroes of Might Magic. Αλλά εάν κάθε κύτταρο υποβάλλεται σε επεξεργασία ξεχωριστά, όπως στο Civilization, τότε αυτή η μέθοδος δεν είναι κατάλληλη και είναι καλύτερο να διαχωρίζονται σαφώς τα κελιά το ένα από το άλλο. Τεχνολογία "Fused" (ονομάζεται επίσης μάσκα) καθορίζεται από την τιμή TileBorderStyle ίση με tileMasked. Θα μιλήσουμε για τη δομή τους άλλη φορά - αυτό είναι ένα αρκετά περίπλοκο θέμα.

Πλακάκι

Στοιχείο χάρτη - αντικείμενο κλάσης TLKITile- έχει απλή δομή. Αρχικά περιέχει: συντεταγμένες, το sprite που το σχεδιάζει, τον κωδικό τύπου πλακιδίου (που καθορίζει τι έχουμε εδώ - λόφο, έρημο, δρόμο, θάλασσα;) και ικανότητα cross-country (αυτό είναι σχετικό στα περισσότερα παιχνίδια). Το τελευταίο είναι ο αριθμός των μονάδων κίνησης που δαπανώνται για τη μετακίνηση μέσω αυτού του πλακιδίου γηομάδα. Για αδιάβατα πλακάκια, αυτός είναι αρνητικός αριθμός.

Μια άλλη παράμετρος - Αντικείμενα, μια λίστα αντικειμένων που βρίσκονται σε αυτό το πλακίδιο (τύπος TLKIGameObject).

Για να μάθετε σε ποιο κελί έγινε κλικ, ο χάρτης έχει μια μέθοδο MouseTile(x,y) επιστρέφοντας το επιλεγμένο πλακίδιο.

Οι μέθοδοι πλακιδίων περιλαμβάνουν Είναι Γείτονας(Πλακάκι, Απόσταση). Αυτή η συνάρτηση επιστρέφει true εάν το Tile δεν απέχει περισσότερο από κελιά Distance από το δεδομένο πλακίδιο (από προεπιλογή αυτή η παράμετρος είναι ίση με ένα, δηλαδή, εάν γράψετε απλώς IsNeighbour(Tile), η συνάρτηση θα επιστρέψει true για το πλακίδιο που βρίσκεται ακριβώς δίπλα Για ένα τετράγωνο πλέγμα, αυτά τα πλακίδια που οριοθετούν διαγώνια θεωρούνται επίσης «γείτονες».

Λειτουργίες Πρώτος ΓείτοναςΚαι Επόμενος Γείτοναςχρησιμοποιούνται για τον έλεγχο όλων των κελιών που βρίσκονται δίπλα σε ένα δεδομένο. Το πρώτο από αυτά δείχνει σε κάποιο γειτονικό κελί και το δεύτερο μπορεί να κληθεί μόνο αφού καλέσει το πρώτο και δίνει τους επόμενους γείτονες, έναν κάθε φορά.

Αριθμός γειτόνων

// Προκαλώντας βλάβη σε ένα κύτταρο

διαδικασία TObeliskTile.Damage(dmg: ακέραιος);

αν(Objects.Count > 0) και// Μπορεί να έχουμε

// όχι περισσότερα από ένα αντικείμενο ανά κελί

(Objects.ID > 0) // Παθητικά αντικείμενα

// δεν έχει υποστεί ζημιά

Dec(Objects.Hits,

// Αφαιρέστε αυτόματα την προστασία από ζημιές

Μέγ.(0,dmg-(Αντικείμενα όπως και TObeliskGameObject).Defense);

αν Objects.Hitshen Die; // Αφαιρούμε τους νεκρούς

// Επίθεση με βολίδα

διαδικασία TObeliskTile.Fireball;

varΓείτονας: TObeliskTile;

Neighbor:= FirstNeighbour ως TObeliskTile;

Neighbor.Damage(6);

Neighbor:= NextNeighbour ως TObeliskTile;

μέχριΓείτονας = μηδέν; // Μέχρι να ξεμείνουν οι γείτονες

Ένα παράδειγμα είναι στην πλαϊνή γραμμή "Αριθμός γειτόνων". Αυτή η διαδικασία υπολογίζει τη βολίδα που χτυπά ένα κελί και όλους τους γείτονές του.

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

Συχνά χρειαζόμαστε κάποιες άλλες παραμέτρους, και συνήθως η κατηγορία των πλακιδίων που συνθέτουν τον χάρτη είναι απόγονος TLKITile. Έτσι στο παράδειγμα - το TObeliskTile κληρονομείται από το TLKITile.

Είναι σημαντικό:Εάν φέρουμε έναν χάρτη με πλακάκια στην οθόνη του παιχνιδιού μας, οι συντεταγμένες, καθώς και οι μέθοδοι TLKIGameObject που σχετίζονται με την απόσταση, αρχίζουν από προεπιλογή να μετρούν την απόσταση σε πλακίδια και όχι σε σημεία. Οι συντεταγμένες κουμπιών, εικονιδίων κ.λπ. συνεχίστε να μετράτε σε pixel! Αλλά αυτή η λειτουργία μπορεί να απενεργοποιηθεί - αυτό μπορεί να είναι χρήσιμο για στρατηγικές σε πραγματικό χρόνο.

Επιλογή κάρτας

Λοιπόν, ας ξεκινήσουμε με ένα ορθογώνιο πλέγμα (TLKIRectMap), μια ισομετρική χαρτογράφηση (γωνιακές παράμετροι 0, 1,5). Αφήστε το πλέγμα να σχεδιαστεί (στυλ tileBorder). Ας πούμε στον κινητήρα ότι ο συγκεκριμένος χάρτης πρέπει να εμφανίζεται. Μέχρι στιγμής έχουν ολοκληρωθεί όλες οι απαραίτητες ενέργειες χωρίς να γραφτεί ούτε μια γραμμή κώδικα.

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

Θα δηλώσουμε τις φιγούρες, όπως και πριν, ως sprites.

Επεξεργαστής χάρτη

Χάρτης συνονθύλευμα, ισομετρικός.

Υπάρχουν αρκετές δυσκολίες εδώ. Ακριβώς ο ίδιος κινητήρας, οι ίδιες δηλώσεις πλακιδίων... Η διεπαφή, όπως η επιλογή ενός πλακιδίου, η φόρτωση/αποθήκευση κ.λπ., μπορεί να γίνει εύκολα τυπικά μέσαΔελφοί: κανείς δεν μας αναγκάζει να το αλλάξουμε σε λειτουργία πλήρους οθόνης. Δεν θα το αναλύσουμε εδώ - όλα βρίσκονται στο αρχείο παραδείγματος. Το παράδειγμα κώδικα που χρησιμοποιήθηκε σκόπιμα ο απλούστερος τρόπος; Εάν θέλετε, μπορείτε, για παράδειγμα, να κάνετε την παλέτα αντικειμένων και την παλέτα πλακιδίων γραφική.

Το πρόγραμμα επεξεργασίας έχει μόνο δύο χαρακτηριστικά που δεν μας είναι γνωστά. Το πρώτο είναι αρκετά απλό: είναι νέο χαρακτηριστικόένα ποντίκι σχεδιασμένο ειδικά για χάρτες με πλακάκια. Λειτουργία TLKIRectMap.SelectTileεπιστρέφει έναν δείκτη στο ακριβές πλακίδιο στο οποίο έγινε κλικ, ώστε να μπορούμε να χειριστούμε εύκολα το κλικ.

Αλλά το δεύτερο νέο προϊόν αξίζει πιο προσεκτικής εξέτασης.

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

Ας δούμε τον κωδικό (“Write card”).

Ηχογράφηση κάρτας

διαδικασία TObeliskMap.Save;

var i,j: ακέραιος;

InitSave(FName);

WriteStr(MapName);

Write(Map.Width, SizeOf(Map.Width));

Write(Map.Height, SizeOf(Map.Height));

Για i:=0 προς τηνΧάρτης.Πλάτος-1 κάνω

για j:=0 προς τηνΧάρτης.Ύψος-1 κάνω

Write(Map.Tiles.Code, SizeOf(integer);

Ετσι δουλευει. Πρώτα πρέπει να ανοίξετε το αρχείο χρησιμοποιώντας μια ειδική διαδικασία InitSave, του οποίου η μόνη παράμετρος είναι το όνομα αρχείου. Στη συνέχεια αποθηκεύουμε την κεφαλίδα για έλεγχο τύπου χρησιμοποιώντας μια ειδική διαδικασία WriteHeader. Στη συνέχεια σημειώνουμε όλα όσα χρειαζόμαστε χρησιμοποιώντας τη διαδικασία WriteStrγια συμβολοσειρές και για όλα τα άλλα πεδία - Γράφω(η δεύτερη παράμετρός του είναι το μέγεθος των γραπτών δεδομένων σε byte). Μπορείτε να γράψετε τις δικές σας διαδικασίες για πεδία αντικειμένων, όπως απαιτείται Αποθηκεύσετεμε εγγραφή κεφαλίδας. Τέλος, κλείνουμε το αρχείο με τη διαδικασία FinSave.

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

RegisterUserName(tpMap, "TObeliskMap");

TpMapείναι μια σταθερά που πρέπει να δηλώσεις κι εσύ. Εξισώστε το, ας πούμε, με 1. Και στον κατασκευαστή του αντικειμένου TObeliskMap, αντιστοιχίστε την τιμή αυτής της σταθεράς στην παράμετρο TypeID.

Γιατί όλη αυτή η φασαρία; Εκτός από την αντιστοίχιση τύπου, έχετε ένα πολύ σημαντικό όφελος.

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

Αυτός ο κωδικός θα αρχικοποιήσει αυτόματα το νέο πεδίο ως κενό εάν δεν έχει αποθηκευτεί στο αρχείο. Και μπορείτε να γράψετε ένα αρχείο προσθέτοντας απλώς τη γραμμή WriteStr(Name) στο τέλος.

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

Ας παίξουμε

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

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

Στην οθόνη μας θα εφαρμόσουμε κουμπιά TLKIButton σε μορφή τοξότων, ξιφομάχων, μάγων, φαντασμάτων, ιπποτών.

Πρώτα έχουμε τη ρύθμιση. Ας ορίσουμε τη ζώνη τοποθέτησης για τη μία πλευρά ως τις τρεις πάνω «γραμμές» του χάρτη, για την άλλη - ως τις τρεις κάτω «γραμμές».

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

Στην αρχή κάθε νέας κίνησης, όλα τα κουμπιά ενεργοποιούνται ξανά: αυτό γίνεται έτσι ώστε να είναι ευκολότερο για ένα άτομο να παρατηρήσει με ποιον δεν έχει ακόμη μοιάζει. Αντίστοιχα, κάνοντας κλικ στο κουμπί επιλέγεται η εικόνα και μόλις γίνει μια κίνηση, το κουμπί εξαφανίζεται. Ένα άλλο κουμπί - "Τερματισμός στροφής" - εμφανίζεται μόνο μετά τη φάση τοποθέτησης.

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

Μετακίνηση του σχήματος

// Εάν το επιλεγμένο κελί καταλαμβάνεται από τον εχθρό, επιτιθέμεθα,

// αν είμαστε ελεύθεροι, κυκλοφορούμε, αν είμαστε απασχολημένοι με τους δικούς μας

// ή ένα εμπόδιο - αγνοήστε το κλικ

Tile:= Map.MouseTile(MouseX, MouseY);

αν(Πλακάκι = μηδέν)// Κάντε κλικ έξω από το παράθυρο του παιχνιδιού

έπειταέξοδος;

// Κίνηση

αν(Tile.Objects.Count = 0)

και(Απόσταση (Εαυτός)

και οχιΜετακινήθηκε έπειτα

// Ας ελέγξουμε αν μπορούμε να φτάσουμε εκεί

αν δεν HasWay (Πλακάκι) έπειταέξοδος;

MoveObj(ID, Tile.x, Tile.y);

// Το παιχνίδι είναι turn-based - μετακινηθείτε αμέσως

Μετακινήθηκε:= true;

//

ανΕπιτέθηκε έπειτα

Icon.IsVisible:= ψευδής;

// Επίθεση

αν(Tile.Objects.Count > 0)

και(Απόσταση (Εαυτός)

και οχιΕπιτέθηκε έπειτα

Αντικείμενο:= Πλακίδιο.Αντικείμενα;

// Επιτιθέμεθα μόνο στους εχθρούς

αν Obj.Side = Πλευρά έπειταέξοδος;

Obj.Damage(dmg);

Attacked:= true;

// Εάν η μετακίνηση έχει ολοκληρωθεί, αφαιρέστε το εικονίδιο

ανΜετακινήθηκε έπειτα

Icon.IsVisible:= ψευδής;

Η επεξεργασία της κίνησης γίνεται ως εξής (δείτε «Μετακίνηση κομματιού»). Το κελί στο οποίο έγινε κλικ βρίσκεται. Εάν υπάρχει εχθρός πάνω του, και είναι εντός εμβέλειας, υφίσταται ζημιά, εάν είναι άδειο και εντός εμβέλειας, το κομμάτι μετακινείται (αν το επιτρέπουν τα εμπόδια), εάν είναι κατειλημμένο, αλλά όχι από έναν εχθρό, το κλικ αγνοείται .

Όταν πλησίασαν και οι δύο πλευρές, οι δράκοι έδρασαν. Λειτουργούν πολύ απλά: επιλέγουν τον πλησιέστερο μη δράκο που βρίσκεται σε απόσταση 7 τετραγώνων από αυτούς και επιτίθενται. Δείτε τον κωδικό Dragon Actions.

Δράσεις Dragon

// Έλεγχος πλακιδίων εντός 7 τετραγώνων από τον δράκο

Για i:= Μέγ.(0, x - 7) προς τηνΕλάχιστο (μέγιστο μέγεθος, x + 7) κάνω

Για j:= Μέγ.(0, y - 7) προς τηνΕλάχιστο (Μέγιστο μέγεθος, y + 7) κάνω

if (Map.Tiles.Objects.Count > 0) και

(Map.Tiles.Objects.Code>1)

// 0 - κωδικός εμποδίου, 1 - δράκος

έπειτα αρχίζουν

// Επιλογή σημείου προς μετακίνηση

αν x=i έπειτατσεκούρι:=i

αλλούαν x>i έπειτα ax:=i+2

αλλούτσεκούρι:= i-2;

αν y=j έπειτα ay:=j

αλλούαν y>j έπειτα ay:= j+2

αλλού ay:= j-2;

MoveObj(NO, ax, ay);

// Ας επιτεθούμε

Map.Tiles.Damage(12);

// Σπάζοντας τον κύκλο: όχι περισσότερες από μία επίθεση

// κάθε δράκος ανά γύρο

Τέλος, το μόνο που μένει είναι να ελέγξουμε αν περισσότεροι από τους μισούς οβελίσκους καταλαμβάνονται από στρατεύματα της μιας πλευράς - και αν είναι, τότε σταματήστε το παιχνίδι και ανακηρύξτε τον νικητή!


Έτσι, έχουμε ένα παιχνίδι στρατηγικής. Ωστόσο, για απόλυτη ευτυχία, αυτό που λείπει, πρώτα απ 'όλα, είναι η τεχνητή νοημοσύνη, η οποία θα επιτρέψει στο παιχνίδι να έχει λειτουργία για έναν παίκτη ( απλούστερη διαδικασίαΔεν υπολογίζουμε τον έλεγχο του δράκου). Αυτό θα κάνουμε την επόμενη φορά. Τα λέμε σε ένα μήνα!

Σε μελλοντικά τεύχη

Στα παρακάτω θέματα θα μιλήσουμε για:

  • συστήματα σωματιδίων για την εμφάνιση καπνού, σπινθήρων κ.λπ.
  • εργασία με διαφάνεια·
  • τρισδιάστατοι κινητήρες.
  • Βασικά στοιχεία τεχνητής νοημοσύνης.
  • αποσφαλμάτωση του προγράμματος.
  • δημιουργώντας ένα σχέδιο παιχνιδιού και σενάριο,
  • σύνταξη ενός εγγράφου σχεδιασμού·
  • ισορροπία παιχνιδιού?
  • σκέψη μέσα από τους χαρακτήρες του παιχνιδιού και τις γραμμές τους.
  • εργασία με πακέτα Photoshop και 3D.
  • κινούμενα σχέδια?
  • μουσική και φωνητική υποκριτική·
  • και πολλα ΑΚΟΜΑ.

Είναι πολύ πιθανό να μάθετε πώς να τα κάνετε όλα αυτά με τα χέρια σας. Σύντομα θα το δείτε αυτό.

Γράψτε μας…

Για όσους πιστεύουν ότι το πακέτο μπορεί να συμπληρωθεί με κάτι: πρώτον, μην ξεχνάτε ότι δεν υπάρχει Τελική έκδοσηπακέτο, αλλά μόνο αυτό που υλοποιεί τις λειτουργίες που περιγράφονται στα άρθρα μας. Ίσως κάποιες από τις ιδέες σας έχουν ήδη υλοποιηθεί και περιμένουν τη σειρά τους (δείτε την πλαϊνή γραμμή «Σε μελλοντικά τεύχη»). Και σε κάθε περίπτωση: όταν μας προσφέρετε μια ιδέα, προσπαθήστε να αιτιολογήσετε γιατί η πρότασή σας είναι χρήσιμη για πολλά παιχνίδια ταυτόχρονα και όχι μόνο για το συγκεκριμένο σας.

Για ανεξάρτητη εργασία

Ενώ περιμένετε το επόμενο τεύχος, μπορείτε να εργαστείτε στο δικό σας έργο ή μπορείτε να προσπαθήσετε να το βελτιώσετε. Ακολουθούν μερικές ιδέες για τη δική σας υλοποίηση:

  • Διαχωρίστε τα αντικείμενα εμποδίων σε καταστρεπτά (δέντρα και θάμνους) και άφθαρτα (πέτρες) και βεβαιωθείτε ότι οι βολίδες και η αναπνοή του δράκου καίνε τη βλάστηση.
  • Δημιουργήστε λάκκους (καφέ κελί) ή μια φωτιά που ανάβει για πολλές στροφές (κόκκινο κελί) στο σημείο όπου πυροδοτήθηκε η επίθεση πυρκαγιάς.
  • Επιτρέψτε σε ξιφομάχους και ιππότες να καλύπτουν τους γείτονές τους, δίνοντάς τους +1 στην άμυνα.
  • κάνει την κίνηση των μορφών στην οθόνη ομαλή.

Τι κι αν σε πραγματικό χρόνο;

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

  • δεν χρειάζεται πεδίο Ταχύτητα παιχνιδιούστην τάξη TObeliskObject- χρησιμοποιήστε την ταχύτητα από τον βασικό κινητήρα (η ταχύτητα κίνησης στην οθόνη είναι ίση με την ταχύτητα του παιχνιδιού).
  • Ο ακέραιος υπολογισμός των αποστάσεων είναι απενεργοποιημένος.
  • Ο κώδικας κίνησης της φιγούρας ξαναγράφεται, λαμβάνοντας υπόψη το γεγονός ότι είναι απαραίτητο να χαράξουμε μια τροχιά γύρω από τα εμπόδια.
  • Το κουμπί "τέλος κίνησης" αφαιρείται.

Αυτό είναι όλο. Θα προσπαθήσετε να το κάνετε μόνοι σας;

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

Borisyuk Yuri Aleksandrovich, σύμβουλος διαχείρισης, γιατρός τεχνικές επιστήμες

Μου αρέσει πολύ η σειρά master class που διδάσκεις.Προσωπικά, έχοντας προηγουμένως επικεφαλής ενός εργοστασίου, άρχισα να αλλάζω τις προσεγγίσεις μου στη διαχείριση, συμπεριλαμβανομένου. χάρη στις πληροφορίες που λάβατε από εσάς. Αυτή με κάποιο τρόπο ανταποκρίθηκε σε αυτό που έκανα και παρατήρησα στο εργοστάσιο. Από τότε, άρχισα να σκέφτομαι πόσο αναποτελεσματικές είναι οι βιομηχανικές δυνατότητες της Ρωσίας και πόσο τεράστιες είναι οι δυνατότητες και πώς αυτό μπορεί να πραγματοποιηθεί. Γνωριμία με τα προβλήματα προσωπικά διαφορετικές επιχειρήσεις(μερικές φορές οι φίλοι με προσκαλούν ως ειδικό) Βλέπω πόσα μπορούν να γίνουν, πώς να αυξήσω τόσο την αποτελεσματικότητα όσο και την αποδοτικότητα.

Dryagin Oleg Borisovich

Ναι, μου αρέσουν τα master classes σας,πολύ συστηματική προσέγγιση, γνώση της ύλης σε υψηλό επίπεδο και φυσικά πολύ πρακτική εμπειρία στα θέματα που εξετάζονται. Αυτό που με ελκύει είναι αυτόΟ επαγγελματισμός του Αλέξανδρου και το υψηλό επίπεδο επαγγελματικής γνώσης του αντικειμένου μου επιτρέπει να βλέπω διαφορετικά τα ήδη γνώριμα πράγματα. Από την άποψή μου αυτό είναιΕίναι πολύ σημαντικό και απαραίτητο να βλέπεις τα πράγματα που ξέρεις με νέο τρόπο, γιατί... Κατά τη διάρκεια της χειρουργικής εργασίας, πολύ συχνά το μάτι «θολώνει» και σταματάς να βλέπεις, στην πραγματικότητα, προφανή πράγματα.

Elena Fedash, Διευθύντρια HR, ATB Corporation, Dnepropetrovsk.