Créer un jeu de course sans moteur 3D

Ce didacticiel vous donnera une alternative à la 3D pour les jeux de course dans ActionScript 3. Aucun cadre externe n'est requis pour cet exemple de style old school..


Aperçu du résultat final

Jetons un coup d'œil au résultat final sur lequel nous allons travailler:


Étape 1: Configuration du document FLA

Créez un nouvel ensemble de documents Flash pour ActionScript 3.0. Je vais utiliser des dimensions de 480x320px, une cadence de 30 FPS et un arrière-plan bleu clair. Enregistrez le fichier avec un nom de votre choix.


Étape 2: créer une classe de document

Outre la FLA, nous devons également créer une classe de document. Créez un nouveau fichier Actionscript et ajoutez ce code:

 package import flash.display.MovieClip; Classe publique Main étend MovieClip fonction publique Main () 

Enregistrez ce fichier dans le même répertoire que notre fichier FLA. Nommez-leMain.as.


Étape 3: Liez le Principale Classe avec la FLA

Afin de compiler le code à partir du Principale classe, nous devons le relier à la FLA. Sur lePropriétés panneau de la FLA, à côté deClasse, entrez le nom de la classe de document, dans ce cas, Principale.

Enregistrez ensuite les modifications sur la FLA..


Étape 4: Tracez une ligne de route

Nous devons commencer par une ligne pour représenter un segment de la route. presse R pour sélectionner le Outil Rectangle. Dans cet exemple, je vais créer un rectangle gris pour la route elle-même, deux petits rectangles rouges à chaque bord de celui-ci et des rectangles verts pour remplir le reste de la ligne. Les verts doivent être encore plus larges que la scène, je les fais 1500 pixels de large. La largeur de la route peut varier selon vos besoins, je vais utiliser l'un des 245px large. Il n'est pas nécessaire qu'ils soient très hauts, car nous allons utiliser plusieurs instances pour dessiner toute la route à l'écran. Je vais les faire 10px haut.


Étape 5: Créer un MovieClip pour les lignes de route

Une fois que vous avez dessiné tous les rectangles, sélectionnez-les tous (Ctrl + A) et appuyez sur F8 pour créer un clip vidéo à partir des rectangles que vous venez de créer. Nommez-le "Route", assurez-vous que le Point d'inscription est au centre et cochez la case "Exporter pour ActionScript".

Vous allez vous retrouver avec un Road MovieClip dans la bibliothèque.

C’est à vous de choisir si vous souhaitez dessiner chaque rectangle sur des calques différents. Je vais juste mettre le gris sur une deuxième couche. Si vous avez une instance de Road sur la scène, supprimez-la. Nous ajouterons le Road MovieClip par code plus tard.


Étape 6: Configurez l'aire de jeu

Revenons à la Principale classe. Nous allons utiliser ça Route MovieClip pour créer l'illusion d'un circuit.

Nous allons déterminer la profondeur de la route visible, ainsi que les dimensions de l'aire de jeu. De plus, dans notre classe, tous les Route les instances que nous ajoutons à la scène seront accessibles à partir d'un tableau. Nous allons utiliser un autre tableau (zMap) pour déterminer la profondeur de chaque ligne.

Dans cet exemple, je définirai une profondeur de 150 lignes de route dans une aire de jeu de 480x320 (il n'est pas nécessaire que la scène ait la même taille, mais comme c'est tout ce qui va être montré, je vais utiliser ces chiffres).

 // Profondeur de la route visible privée const roadLines: int = 150; // Dimensions de l'aire de jeu. private const resX: int = 480; solution privée const: int = 320; // Ligne de la voiture du joueur. const privé noScaleLine: int = 8; // Toutes les lignes de la route seront accessibles à partir d'un tableau. private var zMap: Array = []; lignes de variables privées: Array = []; private var halfWidth: Number; private var lineDepth: int; private const widthStep: Nombre = 1;

Étape 7: Afficher la route par code

Nous allons utiliser toutes les variables et constantes précédentes à l'intérieur du Principale une fonction. Nous allons redimensionner chaque ligne en fonction de la profondeur correspondante.

 fonction publique Main () // Remplit la zMap avec la profondeur des lignes de route pour (var i: int = 0; i < roadLines; i++)  zMap.push(1 / (i - resY / 2));  //We want the line at the bottom to be in front of the rest, //so we'll add every line at the same position, bottom first. lineDepth = numChildren; for (i = 0; i < roadLines; i++)  var line = new Road(); lines.push(line); addChildAt(line, lineDepth); line.x = resX / 2; line.y = resY - i;  //Scaling the road lines according to their position halfWidth = resX / 2; for (i = 0; i < roadLines; i++)  lines[i].scaleX = halfWidth / 60 - 1.2; halfWidth -= widthStep;  

Si vous Publier (Ctrl + Entrée) le document à ce stade, vous aurez une vue d'une route droite.

Vous pouvez jouer avec les calculs de mise à l'échelle pour obtenir des résultats différents. Vous voudrez peut-être une route plus large ou une distance de vision plus longue.


Étape 8: Créer un deuxième graphique routier

À l'heure actuelle, la route est tellement plate que vous ne pourriez pas savoir si nous allons de l'avant. Nous avons besoin d’au moins deux styles de segment différents pour distinguer notre vitesse de déplacement..

Aller au Bibliothèque panneau et double-cliquez sur le Route MovieClip pour revenir aux rectangles que vous avez dessinés. Maintenant, appuyez sur F6 insérer une nouvelle image clé (si vous avez plusieurs calques, vous pouvez insérer une nouvelle image clé sur chaque calque). Maintenant, en fonction du premier cadre, vous pouvez modifier les couleurs des rectangles ou modifier leur conception. Je vais changer leur couleur et ajouter quelques lignes au deuxième cadre.


Étape 9: Gardez la ligne du joueur à l’échelle

Nous allons définir une nouvelle variable dans le Principale classe pour maintenir la cohérence sur la ligne du joueur (en supposant qu'il y aura une voiture dans le jeu, nous allons garder la mise à l'échelle à 1 sur cette ligne)

 var player privé: numéro;

Ensuite, nous allons modifier le Principale une fonction.


Étape 10: Ajouter des lignes alternées à la route

Cette variable sera utilisée dans le Principale une fonction. Maintenant le Route les lignes seront segmentées, certaines afficheront la deuxième image et les autres afficheront la première, renforçant ainsi l'illusion d'une piste de course.

 fonction publique Main () pour (var i: int = 0; i < roadLines; i++)  zMap.push(1 / (i - resY / 2));  playerZ = 100 / zMap[noScaleLine]; for (i = 0; i < roadLines; i++)  zMap[i] *= playerZ;  lineDepth = numChildren; for (i = 0; i < roadLines; i++)  var line = new Road(); lines.push(line); addChildAt(line, lineDepth); line.x = resX / 2; line.y = resY - i;  halfWidth = resX / 2; for (i = 0; i < roadLines; i++)  if (zMap[i] % 100 > 50) lignes [i] .gotoAndStop (1); autres lignes [i] .gotoAndStop (2); lignes [i] .scaleX = halfWidth / 60 - 1.2; halfWidth - = widthStep; 

Il ne sera peut-être pas nécessaire de multiplier par 100 pour obtenir les segments correctement, mais ce sont les chiffres que je vais utiliser dans cet exemple, vous êtes libre de modifier les chiffres à votre goût (et si vous bousillez quelque chose, vous aurez ceci comme référence).


Étape 11: Configurer une vitesse et un décalage

Commençons à faire bouger les choses. Nous allons définir une variable pour la vitesse. Cela indiquera la profondeur par image. Je vais commencer à une vitesse de 20, vous pouvez utiliser n'importe quel nombre.

Nous avons également besoin d’un indicateur pour les segments de route, qui changera en fonction de la vitesse..

 vitesse de la variable privée: int = 20; var privé TexOffset: int = 100;

Étape 12: Commencez à aller de l'avant

Avant de pouvoir utiliser quoi que ce soit avec ces variables, nous devons importer un nouvel événement dans cette classe. Nous pourrions utiliser soit une minuterie ou une EnterFrame. Dans cet exemple, j'utiliserai l'événement EnterFrame.

 import flash.events.Event;

Ensuite, nous allons couper la dernière condition dans la Principale() fonction et déplacez-le vers une nouvelle fonction que nous créons. Cette nouvelle fonction sera déclenchée par l'événement EnterFrame. Nous aurons donc un mouvement continu sur la route. Appelons ça course().

 fonction publique Main () pour (var i: int = 0; i < roadLines; i++)  zMap.push(1 / (i - resY / 2));  playerZ = 100 / zMap[noScaleLine]; for (i = 0; i < roadLines; i++)  zMap[i] *= playerZ;  lineDepth = numChildren; for (i = 0; i < roadLines; i++)  var line = new Road(); lines.push(line); addChildAt(line, lineDepth); line.x = resX / 2; line.y = resY - i;  halfWidth = resX / 2; for (i = 0; i < roadLines; i++)  lines[i].scaleX = halfWidth / 60 - 1.2; halfWidth -= widthStep;  addEventListener(Event.ENTER_FRAME, race); 

Étape 13: Définir une fonction de course

Ramenons maintenant le conditionnel qui a été coupé à la nouvelle fonction pour obtenir du mouvement. le texOffset pointera la position de la route pour garder une illusion précise de mouvement.

 course de fonction privée (événement: événement): void pour (var i: int = 0; i < roadLines; i++)  if ((zMap[i] + texOffset) % 100 > 50) lignes [i] .gotoAndStop (1); autres lignes [i] .gotoAndStop (2);  texOffset = texOffset + speed; tandis que (texOffset> = 100) texOffset - = 100; 

Si vous Publier cela maintenant, vous devriez obtenir une route animée.


Étape 14: Direction

Les routes parfaitement droites sont ennuyeuses et il existe des milliers de façons de faire évoluer une perspective. Ajoutons maintenant de nouvelles variables pour prendre en charge les courbes en mouvement.

Dans cet exemple, je vais alterner des courbes à droite avec des sections droites. La route à venir sera stockée dans le nextStretch variable. Aussi, nous allons déplacer les lignes ' X position dans les courbes.

 var privé: nombre; // La position x de chaque ligne private var dx: Number; // montant de la courbe par segment private var ddx: Number = 0.02; // Montant de la courbe par ligne private var segmentY: int = roadLines; private var nextStretch = "Droit";

Étape 15: Ajouter des courbes à la route

le rx variable stockera le X position de chaque ligne, nous voudrons donc qu’elle commence au centre et prenne les courbes à partir de là. Également, ddx contrôle la netteté des courbes. Dans cet exemple, je l’aurai à 0,02; vous voudrez peut-être faire varier sa valeur entre les courbes. Voici comment la nouvelle course() la fonction va chercher:

 course de fonction privée (événement: événement): void rx = resX / 2; dx = 0; pour (var i: int = 0; i < roadLines; i++)  if ((zMap[i] + texOffset) % 100 > 50) lignes [i] .gotoAndStop (1); autres lignes [i] .gotoAndStop (2); lignes [i] .x = rx; if (nextStretch == "Straight") if (i> = segmentY) dx + = ddx; sinon dx - = ddx / 64; // Revient en douceur d'une courbe à une partie droite.  sinon si (nextStretch == "Curved") if (i <= segmentY) dx += ddx; else dx -= ddx / 64;  rx += dx;  texOffset = texOffset + speed; while (texOffset >= 100) texOffset - = 100;  segmentY - = 1; tandis que (segmentY < 0)  segmentY += roadLines; if (nextStretch == "Curved") nextStretch = "Straight"; else nextStretch = "Curved";  

Cette fois, nous ne toucherons pas le Principale une fonction. Si vous Publier maintenant vous devriez obtenir quelque chose comme ceci:

Vous voudrez peut-être modifier la valeur de la courbe pour Gauche et Droite, ainsi que les valeurs de direction. À ce stade, vous devriez déjà pouvoir ajouter une voiture à la scène et contrôler manuellement la vitesse..


Étape 16: Collines, pentes

Rappelez-vous que les rectangles de la route ont plus d'un pixel de hauteur? Cela pourrait nous aider à élargir la vue au cas où nous voudrions des collines dans notre jeu..

Il existe une méthode de création de collines très similaire à la création de courbes. Il peut y avoir beaucoup de méthodes différentes, mais c'est celle que j'utiliserai ici. Pour simplifier, je recyclerai autant du code que nous avons déjà et ajouterai quelques lignes pour ce nouvel effet. Comme d'habitude, si vous n'aimez pas les résultats, vous pouvez modifier les valeurs à volonté.

Nous venons de faire des variables pour le X positions des lignes de route, faisons maintenant ceux pour la y positions aussi bien.

 Variable privée: Nombre; var privé: nombre; var privé: Nombre = 0,01; // Un peu moins raide que les courbes.

Étape 17: Descente, montée

Pour des raisons de simplicité, dans cet exemple, je vais utiliser les mêmes segments de droite pour un effet de montée en ligne droite, et les courbes pour un effet de courbe et de descente..

 course de fonction privée (événement: événement): void rx = resX / 2; ry = resY; dx = 0; dy = 0; pour (var i: int = 0; i < roadLines; i++)  if ((zMap[i] + texOffset) % 100 > 50) lignes [i] .gotoAndStop (1); autres lignes [i] .gotoAndStop (2); lignes [i] .x = rx; lignes [i] .y = ry; if (nextStretch == "Straight") if (i> = segmentY) dx + = ddx; dy - = ddy;  else dx - = ddx / 64; dy + = ddy;  sinon si (nextStretch == "Curved") if (i <= segmentY)  dx += ddx; dy -= ddy;  else  dx -= ddx / 64; dy += ddy;   rx += dx; ry += dy - 1;  texOffset = texOffset + speed; while (texOffset >= 100) texOffset - = 100;  segmentY - = 1; tandis que (segmentY < 0)  segmentY += roadLines; if (nextStretch == "Curved") nextStretch = "Straight"; else nextStretch = "Curved";  

Dans votre jeu, vous devez séparer les courbes des collines et créer deux algorithmes différents, mais cet exemple montre à quel point ils peuvent être similaires..


Étape 18: Améliorer l'esthétique de la route

Les jeux à l'ancienne ne pourraient pas tirer parti de Flash, mais nous le pouvons. Quelque chose d'aussi simple que d'ajouter un dégradé aux lignes de la route fera une belle différence. Si vous le souhaitez, vous pouvez utiliser les filtres et les textures de votre choix, mais dans cet exemple, je n’ajoute que quelques dégradés simples. Revenons donc à la Route MovieClip.

Sur le cadre 1, sélectionnez le rectangle gris, puis accédez au panneau Couleur et choisissez Gradient linéaire dans le menu déroulant, puis choisissez Refléter la couleur en tant que flux, de sorte que le dégradé continue d'avant en arrière de la première à la dernière couleur. Je ne vous dis pas de choisir les mêmes couleurs que moi, mais je vais utiliser les numéros 666666 et 999999 ici. Si vous devez faire pivoter le dégradé, appuyez sur F passer à l’outil de transformation du dégradé, qui vous permettra de déplacer, faire pivoter et redimensionner votre dégradé. Dans ce cas, je déplace le dégradé sur un quart du rectangle et le redimensionne à la moitié de sa taille, afin que le centre soit plus clair et les bords plus sombres. J'utilise une taille similaire pour la partie verte, elle passe donc du vert foncé (# 006600) au vert clair (# 009900) en continu.

Maintenant, allez au cadre 2 et créez de nouveaux dégradés avec des couleurs différentes. Pour le rectangle gris, j'ai conservé la couleur plus claire et n'a changé que la couleur plus foncée en # 777777. Sur la partie verte, j’ai modifié la taille du dégradé pour éviter un aspect en damier. Le changement de couleur était très subtil (# 007700 et # 008800)..

Peut-être que maintenant vous voudrez ajouter un joli fond à l'horizon ou un graphique pour le ciel.


Conclusion

Que vous manquiez de ressources pour les frameworks 3D ou que vous souhaitiez simplement passer à la vieille école, vous avez maintenant un exemple simple montrant comment créer une illusion de profondeur pour un jeu de course. C’est maintenant à vous de décider s’il s’agit d’un Grand Prix moto, d’une course de rue sur une autoroute très passante, ou de quelque chose qui n’a rien à voir avec la course..

J'espère que vous avez trouvé ce tutoriel utile. Merci d'avoir lu!