Presque chaque jeu peut être considéré comme ayant une fonction principale qui contient toute la logique du jeu et qui est exécutée lorsque l’utilisateur fait quelque chose ou après un certain temps. Ce cycle d’exécution répétée de la même fonction principale est appelé la boucle de jeu, et est crucial pour comprendre pour toute sorte de développement de jeux.
Vous avez probablement déjà joué au jeu de société Chutes and Ladders (ou à Snakes and Ladders, comme nous l'appelons au Royaume-Uni).
(Crédit photo incurable_hippie sur Flickr)
Chaque joueur lance le dé (ou fait tourner la roulette) et avance du nombre de cases indiqué. La case sur laquelle ils atterrissent peut les amener à glisser en arrière ou à gravir plusieurs espaces. Le joueur gagne la partie lorsqu'il arrive au dernier carré.
Ainsi, dans l’image ci-dessus, atterrir sur la case 6 fait grimper de quatre cases jusqu’à la case 10; atterrir sur la place 19 fait reculer de 15 cases vers la place 4; et atterrir sur Square 64 signifie que vous gagnez la partie.
Maintenant, supposons que vous jouiez en solo, pour vous entraîner. Vous faites la même chose que ci-dessus, encore et encore, jusqu'à atteindre la Place 64. Comment représenteriez-vous cela dans le code?
Vous commenceriez probablement par créer un tableau pour stocker les valeurs des carrés. La plupart des éléments contiendraient zéro, mais quelques-uns contiendraient soit un nombre positif (indiquant une échelle), soit un nombre négatif:
Remarque: Ceci est un pseudocode, pas AS3
var specialSquares: Array = []; specialSquares [0] = 0; // la case sur laquelle les joueurs commencent, avant 1 specialSquares [1] = 0 ;? specialSquares [6] = +4 ;? specialSquares [19] = -15;
? etc. Ensuite, vous auriez une fonction pour déplacer le joueur en fonction du nombre sur le dé:
function movePlayer (carrés: Nombre) newSquare = currentSquare + squares; newSquare + = specialSquares [newSquare]; currentSquare = newSquare;
Vous pouvez ensuite mettre cela dans une fonction plus grande représentant un tour complet:
function takeATurn () diceNumber = random (1, 6); // nombre aléatoire compris entre 1 et 6 movePlayer (diceNumber); if (currentSquare == 64) // le joueur a gagné! jeu terminé
Cette fonction, prendreAprès ()
, encapsule la logique de jeu de base pour les chutes et les échelles à joueur unique. Mais comment pouvons-nous réellement faire fonctionner cette fonction? Il y a plusieurs options:
Nous pourrions placer un bouton sur l'écran et le faire appeler prendreAprès ()
chaque fois qu'il est cliqué. Si vous avez déjà joué au Scrabble sur Facebook ou à Words With Friends, vous avez déjà vu cette option en action..
Nous pourrions faire prendreAprès ()
courir toutes les soixante secondes.
En fait, cette option est un peu plus compliquée qu'il n'y paraît. En pratique, on ne voit jamais de jeux sans certains entrée du joueur; sans interaction, cela ne peut pas vraiment être considéré comme un jeu. Cependant, certains jeux comportent un élément de "calendrier". Considérez FarmVille: vous, le joueur, plantez vos cultures, puis toutes les quelques minutes (ou toutes les heures), elles se développent un peu plus loin, des graines aux pousses en passant par les fruits. Et dans certains modes de Civilization, vous disposez d'un temps défini (par exemple cinq minutes) pour effectuer tous vos mouvements pendant un "tour"; une fois que ces cinq minutes sont écoulées, la fonction principale de la logique de jeu est déclenchée.
Certains jeux utilisent un mélange de ces deux options: par exemple, Mafia Wars dispose d’une ressource appelée "énergie" qui recharge une unité toutes les cinq minutes; vous effectuez des actions dans le jeu en utilisant cette ressource, de sorte que la fonction logique principale du jeu est toujours déclenchée par une action de l'utilisateur, elle est simplement limitée dans le temps.
Ceci est un modèle commun à la plupart des jeux: un morceau de code contenant la logique de jeu principale est déclenché à plusieurs reprises. Nous appelons cela la boucle de jeu.
Il existe un terme pour l'action ou la période de temps qui déclenche également le code de la logique de jeu principale: a cocher (comme le son fait une horloge).
Ainsi, dans Civilization, le tick est toutes les cinq minutes. Dans Words With Friends, à vous de jouer les causes une tique. En d'autres termes, la boucle de jeu s'exécute une fois par tick.
Super Mario Bros ne semble appartenir à aucune de ces catégories. Mario répond à l'entrée du joueur? et pourtant, toutes sortes de choses se passent sans que vous ayez à faire quoi que ce soit (Goombas se promène, le compte à rebours, les objets tombent). Sont là deux boucles de jeu?
Non, il y en a juste un, et il est déclenché uniquement par le temps - mais avec un tick d'une fraction de seconde.
Dans Civilization, vous disposez de cinq minutes pour entrer tout ce que vous voulez faire dans le tour en cours, avant que le jeu "tique" et exécute à nouveau la boucle de jeu en fonction de toutes vos entrées. Donc, si vous dites, au virage 23, que vous voulez que vos guerriers attaquent un cerf, alors au virage 24, tout le monde reçoit de la venaison pour le dîner.
C'est pareil avec Mario. Si vous appuyez sur le bouton de saut pendant un tick, puis à la prochaine itération de la boucle de jeu, Mario commencera à sauter.
Notez que vous ne pas vous devez programmer votre pression de saut juste au moment où la fonction logique de jeu est déclenchée - toutes vos actions pendant une période de tick sont enregistrées et utilisées lors de la prochaine itération de la boucle de jeu.
Toute la logique du jeu est gérée dans la boucle de jeu. Mais un jeu ne se limite pas à sa logique, le graphisme étant l'exemple majeur.
Dessiner des graphiques à l'écran est un travail difficile pour l'ordinateur. Supposons que vous ayez un jeu d'action avec un tic-tac de 1 / 60ème de seconde; cela devrait donner l'impression que le jeu réagit de manière fluide aux commandes du joueur. Mais que se passe-t-il si l'ordinateur du joueur est trop lent pour exécuter tout le code de la logique du jeu (réponse à une saisie, simulation de la gravité, exécution de routines d'IA) et tout dessiner à l'écran en 1 / 60ème de seconde?
Dans ce scénario, nous pouvons utiliser deux boucles distinctes: une boucle de jeu et une tirer la boucle. Nous pourrions alors exécuter la boucle de tirage à une fréquence beaucoup plus basse que la boucle de jeu; disons que nous actualisons l'écran deux fois moins souvent, c'est-à-dire tous les 1 / 30e de seconde.
La puissance de traitement requise par le jeu peut varier d’un niveau à l’autre. Considérez un shoot-'-up-up: les premiers niveaux n’auront que très peu de navires à l’écran, pour que le joueur puisse entrer doucement, tandis que les derniers niveaux pourraient avoir des dizaines de navires ennemis et des centaines de balles volant toutes autour de la même scène à une fois que. La boucle de jeu doit déterminer comment tous ces objets doivent se déplacer, et la boucle d’attribution doit rendre chaque objet. Ainsi, il a peut-être été possible d’exécuter à la fois la boucle de jeu et la boucle d’attaque tous les 1 / 60e de seconde. début du jeu, à la fin quelque chose doit donner.
Il est généralement plus simple de ralentir la boucle d’attaque que la boucle de jeu, si vous devez choisir. Ajuster la durée de la boucle de jeu signifie ajuster tout dans votre jeu en fonction du temps; Si Mario tourne à une vitesse de 20 pixels / seconde et que vous concevez le jeu avec une longueur de tick de 1 / 60ème de seconde, vous devez le déplacer d’un tiers de pixel par tick. Si vous ajustez la boucle de jeu pour avoir une longueur de tick de 1 / 30e de seconde, vous devez alors ajuster cette valeur à 2 / 3e de pixel par tick - et même c'est un simple changement par rapport à la conservation des calculs physiques et des routines d'IA cohérent.
Pour cette raison, les jeux ont souvent pour objectif de garder la coche de la boucle de jeu cohérente et de ralentir la boucle de tirage au besoin, si davantage de puissance est nécessaire. Si vous avez déjà activé le compteur FPS (abréviation de Frames Per Second, nombre de fois que la boucle de tirage s’exécute par seconde) dans un jeu de tir à la première personne, vous l’avez vu changer en fonction de la quantité affichée à l’écran. ; le taux de rafraîchissement de la boucle de tirage est ajusté automatiquement. Le jeu peut sembler risqué - comme une vidéo en streaming en direct sur une connexion Internet lente - mais s'il n'est pas exécuté sur un ordinateur avec une puissance bien inférieure à celle que les développeurs du jeu avaient en tête, tous les objets du monde du jeu continueront à se déplacer et interagir aux vitesses correctes.
Pour un excellent article expliquant comment Flash gère cela, consultez le post de Sean Christmann sur le 'Elastic Racetrack'.