θα ήθελα να σας παρουσιάσω το παιχνίδι μου «Sternenschwarm» για τον CPC6128, το οποίο προγραμμάτισα πριν από λίγο καιρό. Ξεκίνησα γύρω στο 2023… Παρόλο που υπήρχε ήδη βοήθεια από AI τότε, ασχολήθηκα σχεδόν 2 χρόνια… Αν και τα LLM απλώς βοήθησαν να ολοκληρωθεί η υλοποίηση. Το μεγαλύτερο μέρος της δουλειάς έγινε καθαρά από μεράκι, γράφοντας κώδικα από το δικό μου χέρι (= πληκτρολόγιο).
Υπολογιστής: CPC 6128. Χρησιμοποιώ ολόκληρη τη μνήμη RAM (bank-switching)
Παίζεται με τα πλήκτρα των βελών (κέρσορα).
Το παιχνίδι δυσκολεύει από πίστα σε πίστα. Για να εξισορροπηθεί αυτό, μπορείτε να «κλέψετε» στην αρχική οθόνη. Με τα πλήκτρα 1 έως 8 μπορείτε να ορίσετε πόσες βολές μπορείτε να ρίξετε συνεχόμενα…
Περιστασιακά οι εχθροί ΔΕΝ κινούνται πέρα-δώθε. Αυτό συμβαίνει επειδή το πρόγραμμα μετρά συνεχώς πόσα αντικείμενα μπορεί να μετακινήσει. Το παιχνίδι τρέχει σε σταθερά 25 καρέ ανά δευτερόλεπτο (fps). Λειτουργεί με double buffering και αλλάζει κάθε δύο VSYNC (από 20 ms στα 50 Hz). Το χρονικό περιθώριο ανά καρέ (frame budget) είναι επομένως 40 ms. Ένας ομοιόμορφος ρυθμός έχει λιγότερα κολλήματα από τις μεταβαλλόμενες ταχύτητες, γι’ αυτό και ο ρυθμός επελέγη σταθερός και όχι ο μέγιστος δυνατός.
Πλατφόρμα ανάπτυξης: «Retro Virtual Machine 2.1». Δυστυχώς πούλησα τον CPC μου πριν από 30 χρόνια.
Για τη δημιουργία των γραφικών έγραψα έναν δικό μου editor. Μπορεί να αποθηκεύει τις εικόνες και τα sprites σε διάφορες μορφές αρχείων και διατάξεις byte. Αν υπάρχει ενδιαφέρον, ευχαρίστως να τον μοιραστώ εδώ.
Μερικά στατιστικά:
Assembler: 7.356 γραμμές χωρίς τις κενές γραμμές και τα σχόλια.
Εργαλεία Python: 8
βέλτιστη κατανομή των γραφικών στις τράπεζες μνήμης (memory banks) 0 έως 3
δημιουργία αρμονικών πινάκων για την κίνηση των εχθρών
Είναι εξαιρετικό! Μου αρέσει πολύ η ρευστή κίνηση, και το μόνο θέμα που έχω είναι ότι οι εχθροί που βρίσκονται ήδη στην οθόνη σταματούν να κινούνται όταν μπαίνει πετώντας μια άλλη ομάδα εχθρών, κάνοντας αρκετά εύκολο το να τους πυροβολήσεις. Από την άλλη βέβαια, δεν έχω ξεπεράσει ακόμα το σκορ σου, οπότε ίσως απλώς να βοηθάει!
Ωραία, πρώτο run 40k… Χωρίς να δώσω ιδιαίτερη σημασία στο «επιβίωση πάση θυσία».
Αν προσθέσεις και ένα boss που «αιχμαλωτίζει» (top level εχθρός), μπορείς άνετα να το βάλεις και στο thread του Galaga
Μικρό bug: όταν τελειώνει η πίστα (κείμενο στην οθόνη), οι σφαίρες (εχθρών και παίκτη) παγώνουν, και μετά ελευθερώνονται ξανά όταν ξεκινάει η πίστα. Δεν είναι επικίνδυνες όσο διαρκεί το πάγωμα, αλλά δεν ξέρω αν γίνονται επικίνδυνες μόλις ελευθερωθούν.
Είναι ήδη ένα πολύ αξιόλογο παιχνίδι. Ωραία γραφικά / animation / πρόκληση. Καλύτερο από πολλά επί πληρωμή παιχνίδια εκείνης της εποχής. Λείπουν μόνο μερικές λεπτομέρειες για να γίνει κορυφαίο: κάποιο jingle ανάμεσα στις πίστες ή ηχητική ατμόσφαιρα μέσα στην πίστα, και ίσως λίγο μεγαλύτερη ποικιλία στα μοτίβα κίνησης των εχθρών.
σας ευχαριστώ πολύ για τα σχόλιά σας. Ορίστε μερικές λεπτομέρειες σχετικά με την υλοποίηση του παιχνιδιού, ώστε να γίνουν κατανοητές ορισμένες «ιδιαιτερότητες» του σχεδιασμού του.
Απαιτήσεις χώρου: Για να μπορούν να περιστρέφονται οι «εχθροί», αποθηκεύονται στη μνήμη σε όλες τις φάσεις κίνησης. Περιλαμβάνονται ακριβώς έτσι στον πηγαίο κώδικα.
Αυτές οι εικόνες και μόνο καταλαμβάνουν περίπου 38 KB. Για να είναι ομαλά τα animation, χρησιμοποιώ double-buffering. Γι’ αυτό χρειάζονται επιπλέον 16 KB. Η διαχείριση όλων των αντικειμένων απαιτεί 792 byte (μέσω ενός ειδικού πίνακα).
Συνολικά: Πρέπει να εκμεταλλευτώ τα επιπλέον 64 KB του CPC 6128.
Ρυθμός ανανέωσης (αυστηρά στα 25 καρέ / δευτερόλεπτο): Κάποτε είχα γράψει ένα παιχνίδι Asteroids για τον CPC. Είχε «πεθάνει» εξαιτίας του αριθμού των κινούμενων αντικειμένων. (Αν το βρω κάπου, θα το ανεβάσω εδώ.) Έτσι προέκυψε η ιδέα ότι ο αριθμός των κινούμενων αντικειμένων πρέπει να βασίζεται στον ρυθμό ανανέωσης. Ένα παιχνίδι τύπου Asteroids δεν είναι κατάλληλο γι’ αυτό, καθώς δεν είναι ευχάριστο να παίζεις όταν ορισμένοι αστεροειδείς κολλάνε. Αυτό το παιχνίδι (Sternenschwarm), από την άλλη πλευρά, αναγνωρίζει εσωτερικά αν μπορεί να μετακινήσει ακόμη ένα αντικείμενο προτού το προλάβει η ακτίνα σάρωσης (raster beam). Προτεραιότητα έχουν τα αντικείμενα που δεν έχουν φτάσει ακόμη στη θέση τους στον σχηματισμό. Περιστασιακά μπορεί κανείς να παρατηρήσει ότι μόνο μεμονωμένα αντικείμενα κινούνται στον σχηματισμό και τα υπόλοιπα ακολουθούν αργότερα.
Τελικό boss: Σχεδόν δεν έχει μείνει καθόλου χώρος στον υπολογιστή για το παιχνίδι. Επίσης, φοβάμαι τα μεγάλα αντικείμενα που πρέπει να διαχειριστώ στην οθόνη… Το έργο έχει ουσιαστικά ολοκληρωθεί.
Σφάλμα με τη γραμματοσειρά: Δεν γνωρίζω αυτή τη στιγμή να εξακολουθεί να υπάρχει αυτή η δυσλειτουργία. Όντως μου είχε συμβεί κάποτε στην αρχική φάση της ανάπτυξης. Ένα λάθος κατά το copy-paste είχε εισαγάγει μια κλήση (call). Θα ψάξω για το σφάλμα με την πρώτη ευκαιρία. Ευχαριστώ για την επισήμανση.
Αρκετά κουλ! Πρέπει να ομολογήσω ότι σίγουρα θα ήταν από τα αγαπημένα μου παιχνίδια, αν υπήρχε τότε.
Έτσι κι αλλιώς είμαι μεγάλος φαν του Galaga και το παιχνίδι είναι ξεκάθαρα εμπνευσμένο από αυτό — τα περισσότερα παιχνίδια που εμπνέονται από το Galaga είναι μάλλον χάλια — αλλά αυτό εδώ είναι πραγματικά καλό και είναι απόλαυση να το παίζεις.
Αν ποτέ αποφασίσεις να προσαρμόσεις κάτι ακόμα, θα είχα μια επιθυμία:
Φαίνεται σαν οι σχηματισμοί στην αρχή να εκτυλίσσονται πάντα με τον ίδιο ακριβώς τρόπο. Το Galaga έχει τουλάχιστον λίγη ποικιλία σε αυτό, έτσι ώστε κάθε πίστα να έχει το δικό της μοτίβο παράταξης. Πιστεύω ότι αυτό θα έκανε πολύ καλό στο συγκεκριμένο παιχνίδι και θα αύξανε το κίνητρο να το ξαναπροσπαθήσει κανείς.
Και μια ερώτηση ακόμα: Είναι άραγε εφικτό στο Challenging Stage να εξολοθρεύσεις όλα τα σμήνη; Μου δόθηκε η εντύπωση ότι δεν μπορώ καν να τοποθετηθώ με τέτοιο τρόπο ώστε να πετύχω πραγματικά όλους τους εχθρούς. Στο Galaga αυτό είναι καταρχήν εφικτό. Βέβαια, το παιχνίδι εδώ μπορεί φυσικά να διαφέρει…
ναι, οι σχηματισμοί εκτελούνται πάντα ακριβώς με τον ίδιο τρόπο. Στην πρώτη μου ανάρτηση για αυτό το παιχνίδι παρουσίασα τα μοτίβα κίνησης σε 2 εικόνες. Το να προσθέσω παραλλαγές σε αυτά μού φαίνεται ενδιαφέρουσα ιδέα.
Στην πραγματικότητα έχω δύο σχετικά απλές ιδέες για το πώς θα μπορούσαν να υλοποιηθούν αυτά τα νέα μοτίβα. Είτε με μια μικρή μετατόπιση προς τα αριστερά / δεξιά (2, 4 ή 6 pixel) είτε απλώς παρέχοντας στατικά μερικά ακόμη μοτίβα κίνησης. Την ιδέα της σύνθεσης των μοτίβων κίνησης από πολλά επιμέρους κομμάτια θα πρέπει πρώτα να την εξετάσω, για να δω τι θα σήμαινε λεπτομερώς για τον κώδικα… Προς το παρόν δεν θα ήθελα να εμβαθύνω τόσο πολύ, καθώς αυτόν τον καιρό δουλεύω πάνω σε ένα άλλο πρότζεκτ λογισμικού.
Όσο για τη «βέλτιστη θέση», δεν το έχω σκεφτεί ποτέ.
Ευχαριστώ για τις παρατηρήσεις σου! Θα τις έχω υπόψη μου. Ίσως κάποια στιγμή βρω τον χρόνο και τη διάθεση να ασχοληθώ ξανά με αυτό το παιχνίδι.
Όχι, δεν εννοούσα καθόλου επιμέρους κομμάτια. Στατικά μοτίβα κίνησης μεν, αλλά περισσότερα από αυτά, π.χ. 15 περίπου – και μετά, για κάθε πίστα υπάρχει μια αντιστοίχιση (mapping) από wave/σχηματισμό σε ένα από τα 15 μοτίβα κίνησης.
Επίπεδο 1: Ο σχηματισμός 1 έρχεται με το μοτίβο κίνησης A, ο σχηματισμός 2 με το μοτίβο κίνησης B, …
Επίπεδο 2: Ο σχηματισμός 1 έρχεται με το μοτίβο κίνησης G, ο σχηματισμός 2 με το μοτίβο κίνησης A, …
Επίπεδο 3: Ο σχηματισμός 1 έρχεται με το μοτίβο κίνησης B, ο σχηματισμός 2 με το μοτίβο κίνησης K, …
κ.ο.κ.
Αυτό θα έπρεπε να είναι ήδη αρκετό για να κάνει το κυνήγι του high score πιο συναρπαστικό, γιατί τότε παίρνεις διαφορετικές θέσεις ανάλογα με την πίστα, ώστε να πετύχεις όσο το δυνατόν περισσότερους καθώς μπαίνουν πετώντας και να πάρεις λιγότερο ρίσκο.
Τρέχουσα κατάσταση και προεπισκόπηση του τι πρόκειται να ακολουθήσει:
Θα υπάρξουν επιπλέον τροχιές πτήσης (μοτίβα κίνησης) των αντικειμένων (δεν θέλω να γράφω συνέχεια «εχθρός»):
Για τη δημιουργία των τροχιών είχα φτιάξει έναν επεξεργαστή τροχιών (flight path editor) σε Python.
Απαίσιος στη χρήση, αλλά λειτουργεί… Στην εικόνα φαίνεται ότι οι τροχιές αποτελούνται από καθορισμένα σημεία. Καθένα από αυτά τα σημεία περιγράφει τη σχετική του θέση σε σχέση με το προηγούμενο στο ταμπλό του παιχνιδιού, το sprite ή τη φάση κίνησης του «αντικειμένου» που ακολουθεί τη διαδρομή. Έχω ορίσει πολλές τέτοιες κινήσεις και φρόντισα να συνδέονται «αρμονικά» μεταξύ τους. Εξαίρεση: Όταν το αντικείμενο κατευθύνεται προς τη θέση-στόχο του, καθώς για αυτό συνεχίζω να χρησιμοποιώ την υπάρχουσα ρουτίνα εύρεσης διαδρομής («pathfinding routine»). Ανάλογα με το πόσα επιμέρους τμήματα τροχιών θα δημιουργήσω (περίπου 10-15;) και θα συνδυάσω στο παιχνίδι (1-3), μπορεί να προκύψουν ενδιαφέροντες σχηματισμοί. Αριθμός πιθανών μοτίβων πτήσης (για 10 τμήματα): 10 + 10x10 + 10x10x10 = 1.110. Για να γίνει η αρχή πιο εύκολη για τον παίκτη, αυτά θα ενεργοποιούνται μόλις από το επίπεδο 9.
Το τελικό τέρας έρχεται!
Το παιχνίδι δεν σχεδιάστηκε ποτέ για να μετακινεί μεγάλα αντικείμενα. Έτσι, θα συνθέσω το τελικό τέρας από μικρά sprites…
(αυτά θα είναι.. Συντεθειμένο από μεμονωμένα sprites τοποθετημένα το ένα δίπλα στο άλλο. Μάλλον όμως δεν θα καταφέρω να φτιάξω animation)
Τον χρόνο επεξεργασίας που απομένει, θα τον χρησιμοποιήσω για να βάλω μερικά γνωστά αντικείμενα να πετούν γύρω-γύρω για άμυνα. Κάθε φορά που καταρρίπτονται όλα αυτά, θα προστίθεται ένα νέο σετ.
Ακτίνα σύλληψης (Tractor beam)
Θα μπει. Αλλά για τεχνικούς λόγους, πολύ σπάνια! (Αυτό οφείλεται σε τεχνικούς λόγους… ίσως περισσότερα για αυτό αργότερα.) Αφήστε τον εαυτό σας να πιαστεί μια φορά. Αξίζει . Αλλά ολοκληρώστε μετά το επίπεδο χωρίς να χάσετε ζωή!!!
Μουσική και ηχητικά εφέ
Θα προστεθούν μερικά ακόμα, αλλά όχι άλλη μουσική.
Αυτή είναι απλώς μια σύντομη ενημέρωση για να δείξω ότι δουλεύω πάνω σε αυτό.
ΑΚΡΙΒΩΣ ΣΤΗΝ ΩΡΑ ΤΟΥ: Οι διακοπές τελείωσαν. Το παιχνίδι ολοκληρώθηκε. Εντελώς εξαντλημένος αλλά ευτυχισμένος.
(Τώρα η δουλειά είναι ένα διάλειμμα από τον προγραμματισμό)
Το πρόγραμμα Python (στο περιβάλλον ανάπτυξής μου) για την ανάλυση των τροχιών των αντικειμένων και τη δημιουργία των συντεταγμένων τους ως bytecode.
Οι μελωδίες ανάμεσα στις πίστες δημιουργήθηκαν μέσω του ChatGPT ως ακολουθίες νοτών.
Ο sprite editor, με τον οποίο σχεδίασα και περιέστρεψα τα sprites. Πρόκειται για ένα πρόγραμμα Python, το οποίο επίσης εκτελείται στον υπολογιστή μου.
Πιστεύω ότι από το «gameplay» φαίνεται πως το παιχνίδι δημιουργήθηκε με μεράκι στο χέρι.
Αν θεωρείς ότι πρέπει να καταταχθεί στην ΤΝ, μπορείς άνετα να κάνεις αυτή την αλλαγή. Δεν έχω κανένα πρόβλημα με αυτό → με τη θετική έννοια. Γράφω το λογισμικό κυρίως για μένα, just for fun.
Σίγουρα, το ότι βρίσκεται σε αυτή την κατηγορία δεν σημαίνει ότι το παιχνίδι είναι εντελώς φτιαγμένο με vibe-coding (για την ακρίβεια πρέπει να αλλάξω τον τίτλο της κατηγορίας), απλώς ότι χρησιμοποιήθηκε AI σε αυτό.