Jeu : Essaim d'étoiles

Bonjour à tous,

Je souhaite vous présenter mon jeu « Sternenschwarm » pour le CPC6128, que j’ai développé il y a quelque temps. J’ai commencé vers 2023… Malgré l’aide de l’IA déjà disponible à l’époque, j’y ai passé près de 2 ans… Même si les LLM n’ont servi qu’à m’aider à finaliser le projet. L’essentiel du travail a été fait pour le simple plaisir de coder quelque chose de mes propres mains (= de mon propre clavier).

STERNE.DSK (190,3 KB)
(run"sterne")

Points clés :

  • Ordinateur : CPC 6128. J’utilise toute la RAM (bank-switching)
  • On peut y jouer avec les touches fléchées.
  • Le jeu devient de plus en plus difficile au fil des niveaux. Pour compenser cela, on peut « tricher » sur l’écran d’accueil. Les touches 1 à 8 permettent de définir combien de tirs on peut enchaîner directement…
  • De temps en temps, les ennemis NE font PAS d’allers-retours. Cela vient du fait que le programme mesure en permanence le nombre d’objets qu’il peut déplacer. Le jeu tourne à un taux fixe de 25 images par seconde. Il utilise le double buffering et bascule tous les deux VSYNC (soit 20 ms à 50 Hz). Le budget par image est donc de 40 ms. Un rythme régulier saccade moins qu’un framerate variable, c’est pourquoi la fréquence est fixe et non maximisée.
  • Plateforme de développement : « Retro Virtual Machine 2.1 ». Malheureusement, j’ai vendu mon CPC il y a 30 ans. :frowning:
  • Pour créer les graphismes, j’ai codé mon propre éditeur. Il peut enregistrer les images et les sprites dans différents formats de fichier et agencements d’octets. Si cela vous intéresse, je pourrai le partager ici.
  • Quelques statistiques :
    • Assembleur : 7356 lignes sans les lignes vides ni les commentaires.
    • Outils Python : 8
      • répartition optimale des graphismes sur les banques de mémoire 0 à 3

      • génération de tables harmoniques pour le déplacement des ennemis

      • création des sons et de la musique

      • etc.

Mais je ne vais pas vous ennuyer avec d’autres détails et anecdotes de code…

Au fait, je n’ai encore jamais dépassé les 61 000 points… Qui sera le premier à atteindre les 100 000 ?

Salutations,
S.D.

8 « J'aime »

C’est vraiment très sympa.

Les rotations des sprites sont particulièrement réussies.

C’est excellent ! J’adore la fluidité des mouvements, et le seul souci que j’ai, c’est que les ennemis déjà à l’écran s’arrêtent de bouger lorsqu’une nouvelle vague arrive en volant, ce qui les rend assez faciles à abattre. Mais bon, après tout, je n’ai pas encore battu ton score, alors c’est peut-être plutôt pratique !

(Au passage, pourrais-tu réduire la taille à 64 ko pour que je puisse y jouer sur ma GX4000, vu que je n’ai plus mon 6128 :slight_smile: ?)

Sympa, 40k dès la première partie… Sans trop chercher à « survivre à tout prix ».

Si tu ajoutes un boss « ravisseur » (ennemi de haut niveau), tu peux même poster ça dans le fil Galaga :slight_smile:

Petit bug : quand le niveau se termine (texte à l’écran), les tirs (ennemis et joueur) sont figés, puis se débloquent quand le niveau commence. Ils ne sont pas dangereux lorsqu’ils sont figés, mais je ne sais pas s’ils le sont quand ils reprennent leur course.

C’est déjà un jeu d’un bon niveau. Graphismes / animations / défi sympas. Bien meilleur que pas mal de jeux payants de l’époque. Il ne manque que quelques détails pour atteindre le sommet : un petit jingle entre les niveaux ou une ambiance sonore pendant le niveau, et peut-être un peu plus de variations dans les mouvements des ennemis.

Bonjour à tous,

merci beaucoup pour vos retours. Voici quelques aperçus de la réalisation du jeu, afin de mieux comprendre certaines « particularités » de son game design.

  • Espace mémoire requis : Pour pouvoir faire tourner les « ennemis », ceux-ci sont stockés en mémoire dans toutes leurs phases de mouvement. Ils sont intégrés tels quels dans le code du programme.


    Ces images nécessitent à elles seules environ 38 Ko. Pour que les animations soient fluides, j’utilise le double-buffering. Cela demande 16 Ko supplémentaires. La gestion de tous les objets prend 792 octets (via une table dédiée).
    Dans l’ensemble : je suis obligé d’utiliser les 64 Ko supplémentaires du CPC 6128.

  • Taux de rafraîchissement (strictement fixé à 25 images / seconde) : J’avais un jour écrit un jeu d’Asteroids pour le CPC. Il était « mort » en raison du nombre d’objets en mouvement. (Si je le retrouve, je le publierai ici.) C’est ainsi qu’est venue l’idée que le nombre d’objets en mouvement devait s’adapter à la fréquence de rafraîchissement. Un jeu d’Asteroids ne s’y prête pas, car c’est désagréable à jouer si certains astéroïdes saccadent. Ce jeu (Sternenschwarm), en revanche, détecte en interne s’il a encore le temps de déplacer un objet avant d’être rattrapé par le balayage de la trame (raster). La priorité est donnée aux objets qui n’ont pas encore atteint leur place dans la formation. On peut parfois constater que seuls certains objets de la formation bougent et que les autres suivent plus tard.

  • Boss final : Le jeu n’a presque plus de place en mémoire. Et puis, j’appréhende un peu de devoir manipuler de gros objets à l’écran… Le projet est en fait terminé.

  • Bug avec la police : À ma connaissance, ce comportement anormal n’est plus présent actuellement. J’avais effectivement rencontré ce problème au tout début du développement. Une erreur de copier-coller avait embarqué un « call ». Je chercherai le bug à l’occasion. Merci pour le signalement.

2 « J'aime »

Plutôt cool ! Je dois avouer que ça aurait sans doute été l’un de mes jeux préférés s’il avait existé à l’époque.

De toute façon, je suis un grand fan de Galaga et ce jeu en est clairement inspiré — la plupart des jeux qui s’inspirent de Galaga sont plutôt nuls — mais celui-ci est vraiment bon et c’est un vrai plaisir d’y jouer.

Si jamais tu apportes encore quelques modifications, j’aurais une suggestion :

On dirait que les formations au début se déroulent toujours exactement de la même manière. Dans Galaga, il y a au moins un peu de variation, de sorte que chaque niveau a son propre schéma de déploiement. Je pense que cela ferait un bien fou au jeu et donnerait encore plus envie de relancer une partie.

Encore une question : est-ce seulement faisable d’éliminer toutes les escadrilles dans le « Challenging Stage » ? J’ai eu l’impression qu’il était impossible de se positionner de façon à toucher absolument tous les ennemis. Dans Galaga, c’est tout à fait faisable en théorie. Après, rien n’empêche ce jeu d’être différent, bien sûr…

Salut eto,

oui, les formations se déroulent toujours exactement de la même manière. Dans mon premier message sur ce jeu, j’avais présenté les schémas de déplacement sur 2 images. Les faire varier me semble être une idée intéressante.

En fait, j’ai deux idées relativement simples pour potentiellement mettre en œuvre ces nouveaux motifs. Décaler légèrement vers la gauche / la droite (de 2, 4 ou 6 pixels) ou simplement intégrer de manière statique quelques schémas de déplacement supplémentaires. Quant à l’idée d’assembler les schémas de déplacement à partir de plusieurs morceaux, je dois d’abord vérifier ce que cela impliquerait en détail pour le code… Mais je ne souhaite plus trop m’y replonger pour le moment, car je travaille actuellement sur un autre projet logiciel.

Je ne me suis jamais vraiment posé la question de la « position optimale ».

Merci pour tes remarques ! Je garde ça dans un coin de ma tête. Peut-être qu’un jour j’aurai le temps et l’envie de me replonger dans ce jeu.

Non, je ne parlais pas du tout de morceaux. Plutôt de schémas de déplacement statiques, mais en plus grand nombre, par exemple 15 ou un truc du genre — et ensuite, pour chaque niveau, il y a un mapping de vague/formation vers l’un des 15 schémas de déplacement.

Niveau 1 : la formation 1 arrive avec le schéma de déplacement A, la formation 2 avec le schéma de déplacement B, …
Niveau 2 : la formation 1 arrive avec le schéma de déplacement G, la formation 2 avec le schéma de déplacement A, …
Niveau 3 : la formation 1 arrive avec le schéma de déplacement B, la formation 2 avec le schéma de déplacement K, …
etc.

Ça devrait déjà suffire à rendre la course au meilleur score plus palpitante, parce qu’on prendrait alors des positions différentes selon le niveau pour en éliminer un maximum dès leur arrivée tout en prenant moins de risques.

D’accord. Merci pour l’info / l’astuce :slight_smile:
Je vais y jeter un œil dans les prochains jours. Je vous ferai un retour.

1 « J'aime »

Point d’étape et aperçu de ce qui arrive :

  1. Il y aura d’autres trajectoires de vol (schémas de mouvement) pour les objets (je ne veux pas toujours écrire « ennemi ») :
    Pour créer les trajectoires, j’avais écrit un éditeur de trajectoires en Python.
    Une horreur à utiliser, mais il fonctionne… Sur l’image, on voit que les trajectoires se composent de points définis. Chacun de ces points décrit sa position relative par rapport au précédent dans la zone de jeu, ainsi que la phase de sprite ou de mouvement de l’« objet » qui suit le tracé. J’ai défini beaucoup de mouvements de ce type en veillant à ce qu’ils s’enchaînent de manière « harmonieuse ». Seule exception : lorsque l’objet se dirige vers sa position cible, car j’utilise toujours la « routine de pathfinding » existante pour cela. Selon le nombre de sections de trajectoire que je vais créer (env. 10 à 15 ?) et combiner dans le jeu (1 à 3), des formations intéressantes pourraient voir le jour. Nombre de schémas de vol envisageables (avec 10 sections) : 10 + 10x10 + 10x10x10 = 1 110. Pour faciliter la prise en main par le joueur, ceux-ci ne seront activés qu’à partir du niveau 9.
  2. Le monstre de fin arrive !
    Le jeu n’a jamais été conçu pour déplacer de gros objets. Je vais donc assembler le monstre de fin à partir de petits sprites…

    (ce seront eux… Composés de sprites individuels placés côte à côte. En revanche, je ne pense pas réussir à faire d’animation)
    J’utilise le temps de calcul restant pour faire voler quelques objets déjà connus en guise de défense. Dès qu’ils sont tous abattus, un nouveau groupe apparaît.
  3. Rayon tracteur
    Il sera bien là. Mais très rarement, pour des raisons techniques ! (C’est dû à des contraintes techniques… j’en reparlerai peut-être plus en détail plus tard.) Laissez-vous capturer au moins une fois. Ça vaut le coup :wink:. Mais terminez ensuite le niveau sans perdre une seule vie !!!
  4. Musique et effets sonores
    Quelques effets supplémentaires vont être ajoutés, mais pas de nouvelle musique.

C’est juste un petit aperçu rapide pour vous montrer que je bosse dessus.

1 « J'aime »

ATTERRISSAGE PARFAIT : vacances terminées. Jeu fini. Complètement crevé mais heureux. :slight_smile:
(Maintenant, le boulot est une pause après la programmation)

STERNE_21.DSK (190,3 KB)
(run"sterne")

Amusez-vous bien avec. J’attends vos retours avec impatience, qu’ils soient bons ou mauvais.

4 « J'aime »

Jeu plutot sympa. J’aurais adoré à l’epoque!

Ooooh c’est vraiment mignon et authentique !

Je demanderais juste un sprite différent quand le vaisseau bouge pour le voir s’incliner à gauche et à droite :slight_smile:

PS : Ça ne devrait pas plutôt être dans la catégorie IA ?

Les contenus suivants sont générés par IA :

  • L’écran de démarrage : texte multicolore.
  • Le programme Python (sur mon environnement de développement) permettant de décomposer les trajectoires des objets et de générer leurs coordonnées sous forme de bytecode.
  • Les mélodies entre les niveaux ont été fournies via ChatGPT sous forme de séquences de notes.
  • L’éditeur de sprites, avec lequel j’ai dessiné et fait pivoter les sprites. Il s’agit d’un programme Python qui tourne également sur mon poste de travail.

Je pense qu’au niveau du « gameplay », on peut voir que le jeu a été conçu avec amour et à la main.

Si tu penses qu’il faut le classer dans la catégorie IA, n’hésite pas à faire la modification. Ça m’est égal, au sens positif du terme. Au fond, je développe ce logiciel pour moi, juste pour le plaisir.

1 « J'aime »

Tout à fait, le fait d’être dans cette catégorie ne signifie pas que le jeu a été entièrement codé au feeling (d’ailleurs, il faut que je change le titre de la catégorie), mais simplement que l’IA a été utilisée pour le concevoir.

Il est vraiment très beau et très agréable à jouer !