Forums Développement Multimédia

Les formations Mediabox
Les formations Mediabox

Starfield multidirectionnel

Compatible ActionScript 2. Cliquer pour en savoir plus sur les compatibilités.Compatible ActionScript 3. Cliquer pour en savoir plus sur les compatibilités.Par Monsieur Spi, le 07 mars 2010

Introduction

Bienvenue dans cet exercice.

Je vous propose de voir comment créer un petit starfield multidirectionnel pour animer les fonds de vos jeux de shoot dans l’espace.

L"extension Adobe Flash Plugin est nécessaire pour afficher ce contenu.

Utilisez les flèches du clavier pour déplacer les étoiles.

Commençons par poser les bases
Ce tutorial s'adresse aux débutants et est écrit sur Flash MX en AS2.

Vous trouverez tout de même à ce chapitre les sources de la même chose en Actionscript 3, par Nataly. (note de lilive)

Je n’expliquerai pas en détail les commandes utilisées mais pour les débutants je ferais un rappel succinct de ce que dit l’aide de Flash à chaque nouvelle instruction. Désolé pour les initiés, c'est un peu “lourd” mais çà permet aux débutants de suivre quand ils tombent sur un code qu'ils ne connaissent pas ou mal.

Avant de commencer tout projet il est nécessaire de le définir précisément.
Ici, le but est de créer un mouvement continu et non répétitif sur un ensemble d’objets, dans toutes les directions possibles et commandé à l’aide des touches de direction.

Voyons un peu comment nous pouvons construire cette idée.

Paramètres du projet

Allons-y, ouvrez un nouveau projet et donnez lui les paramètres suivants :

  • Largeur = 600 px
  • Hauteur = 400 px
  • Couleur de fond = noir
  • FPS = 30

Création des clips utiles

On commence par créer un objet vide qui va contenir tous les objets liés à notre starfield.

Pourquoi créer un objet vide ?
Vous réaliserez assez vite que lorsque vous avez de nombreux objets à gérer sur de multiples couches il est plus pratique de ranger les objets de même type dans des boites (des conteneurs) et de manipuler toute la boite quand vous en avez besoin. Ici par exemple si j’ai un vaisseau à rajouter je le rajouterai simplement au dessus de mon objet représentant le starfield sans me soucier du nombre d’objets contenus dans le starfield ni de leur niveau.

On commence donc par créer un objet vide qui va servir de conteneur pour les étoiles.
Pour cela plusieurs commandes sont possibles, ici je préfère créer un clip vide que je nomme « vide » et qui servira de conteneur de référence pour tous mes objets.
Le clip vide se trouve dans la bibliothèque, pour pouvoir l’utiliser avec du code je vais devoir préciser que ce clip est « exporté pour l’ActionScript », c'est-à-dire que mon programme va exporter ce clip automatiquement sur la scène pour me permettre de l’utiliser.

Pour cela allez dans la bibliothèque (CTRL+L), cliquez avec le bouton droit sur le clip nommé « vide » et allez dans ses propriétés. Cochez la case « exporter pour ActionScript » et la case « exporter à la première image ». Le clip est désormais exporté à la première image de votre projet.
Le conteneur « vide » va servir pour d’autres objets, nous allons donc devoir en faire des « copies » pour chaque objet utile, pour cela une ligne de code suffira.

Création du conteneur

Allez sur votre timeline, normalement vous n’avez qu’une frame vide, c’est là que nous allons placer tout notre code, cliquez dessus et affichez le panneau d’actions (F9 sur Flash MX).

Tapez le code suivant :

//
// Starfield Multidirectionnel
// ---------------------------------------------------------------------------------
//
// Crée les objets
attachMovie("vide", "starfield", 10);

Nous venons d'attacher sur la scène une copie de note clip “vide”, de lui donner le nom de “starfield” et de la placer au niveau 10.

Code à connaître : attachMovie() ;

Méthode : prend un symbole de la bibliothèque et l'associe au fichier SWF spécifié par mon_mc sur la scène. Utilisez removeMovieClip() ou unloadMovie() pour supprimer un fichier SWF associé à attachMovie().

Note : sans précision de cible la méthode attache le clip à la racine par défaut. Les clips exportés de la bibliothèque doivent être exportés pour l’actionScript (clic droit sur le clip dans la bibliothèque, propriétés, puis cocher « exporter pour AS »

Création des étoiles

On crée ensuite un clip « etoiles » qui va contenir les 3 types d’étoiles dont nous allons nous servir, rouge, bleue, blanche, une étoile sur chaque frame et un code stop() ; sur le layer du dessus. Ce clip va servir de référence, à chaque fois que nous allons créer une nouvelle étoile nous allons dupliquer ce clip et lui demander d’afficher au hasard une des trois frames. Ce type d’objet est appelé dans les jeux vidéo des « sprites » c'est-à-dire des clips contenant plusieurs états d’un même personnage.

Revenons à notre code, à présent nous n'interviendrons plus au sein de l'espace de travail graphique de Flash (IDE) mais uniquement dans la fenêtre d'Actions, le code. Nous avons nos “sprites” au chaud dans la bibliothèque, on sais les poser sur la scène à l'aide du code quand on en a besoin, il ne reste plus qu'à animer tout çà correctement.

Tout d'abord nous allons rajouter quelques lignes qui vont servir à créer toutes les étoiles dans le conteneur « starfield ».

Après le code précédent rajoutez :

//
// Crée les étoiles
for (var i = 1; i<100; i++) {
	starfield.attachMovie("etoiles", "etoile"+i, i);
	var etoile = starfield["etoile"+i];
	etoile.gotoAndStop(random(3)+1);
	etoile._y = random(400);
	etoile._x = random(600);
	etoile.vit = random(10)/10+0.5;
	etoile._alpha = random(100);
	etoile._xscale = etoile._yscale=random(150);
}

Décryptons un peu, premièrement il s’agit d’une boucle qui s’effectue de 1 à 100 sur i. A chaque passage le programme :

  • Attache dans le conteneur « starfield » une copie du sprite « etoiles » et lui donne un nom et un niveau correspondant à la valeur de i (etoile1-niveau1, etoile2-niveau2 ….)
  • Crée un raccourci de programmation nommé « etoile » contenant le chemin de l’étoile en cours (starfield[« etoile »+i]). Notez la syntaxe utilisée ici, nous utilisons les crochets pour spécifier que le nom composé correspond à un objet contenu dans le conteneur « starfield ».
  • Affiche une image aléatoire dans le clip « etoile »
  • Donne une position aléatoire sur l’axe X
  • Donne une position aléatoire sur l’axe Y
  • Donne une vitesse de déplacement aléatoire
  • Donne une transparence aléatoire
  • Donne une taille aléatoire

Vous remarquerez que nous avons rajouté une vitesse propre à l’étoile que nous avons créé. Chaque étoile possédera donc sa propre vitesse de déplacement, nous y reviendrons plus tard. Vous pouvez rajouter des effets à volonté dans cette partie.

Si vous testez votre projet à ce stade vous allez obtenir un joli champ étoilé, c’est cool mais çà ne bouge pas encore, voyons ensuite comment animer tout çà en fonction des touches au clavier.

Code à connaître : for

Instruction : une construction de boucle qui évalue l'expression init (initialiser) une fois, puis commence une séquence de boucle par laquelle, tant que condition est évaluée comme true, instruction est exécutée et l'expression suivante évaluée.

Code à connaître : random()

Fonction : renvoie un entier aléatoire entre 0 et un de moins que l'entier spécifié dans le paramètre valeur.

Boucle principale

Pour commencer nous allons avoir besoin d’utiliser des fonctions et des boucles et la première boucle que nous allons utiliser est la boucle principale du programme, celle qui s’exécute tout le temps.

A la suite du programme rajoutez :

//
// Boucle principale
onEnterFrame = function () {
	touches();
};

Code à connaître : onEnterFrame

Gestionnaire d'événement : invoqué continuellement à la cadence du fichier SWF. Les actions associées à l'événement de clip enterFrame sont traitées avant les actions associées aux images affectées.
Vous devez définir une fonction exécutée lorsque le gestionnaire d'événement est invoqué.

Le code exécuté est une fonction qui aura pour but de lancer une ou plusieurs autres fonctions. Ici nous allons nous contenter de lancer la fonction « touches()» à intervalles régulier.

Pourquoi des fonctions qui lancent des fonctions et puis d’abord c’est quoi les fonctions ? Bien, si vous en êtes là il va me falloir quelques explications avant d’aller plus loin. Allons faire un tour dans l’aide de Flash :

Code à connaître : function

Instruction : un jeu d'instructions que vous définissez pour effectuer une certaine tâche. Vous pouvez déclarer, ou définir, une fonction à un emplacement et l'appeler, ou l'invoquer, depuis différents scripts dans un fichier SWF. Lorsque vous définissez une fonction, vous pouvez également spécifier ses paramètres. Les paramètres sont des supports pour les valeurs sur lesquelles la fonction opère. Vous pouvez transmettre différents paramètres à une fonction à chaque fois que vous l'appelez. Ceci vous permet de réutiliser une fonction dans de nombreuses situations différentes.

Nous avons donc une boucle qui déclenche une fonction de base qui elle même appelle une ou plusieurs autres fonctions à intervalles réguliers. J’ai choisi d’appeler une fonction « touches()» qui va contenir le code de détection des touches.

Touches du clavier

Nous attaquons à présent le vif du sujet, gérer les déplacements.
Pour cela nous allons avoir besoin des touches du clavier, et d’un petit moteur qui va réagir à la pression des touches et intervenir sur les étoiles. La fonction « touches()» servira pour la détection des touches et nous ferons intervenir le moteur lorsqu’une touche est effectivement détectée.

Rajoutez le code suivant à la suite du programme :

//
// Déplacements des étoiles
function touches(){
	// Calcule la direction
	if (Key.isDown(Key.RIGHT)) {
		x--;
	} else if (Key.isDown(Key.LEFT)) {
		x++;
	} else {
		x = x*0.9;
	}
	if (Key.isDown(Key.UP)) {
		y++;
	} else if (Key.isDown(Key.DOWN)) {
		y--;
	} else {
		y = y*0.9;
	}
	fixeVitesse();
	deplaceEtoiles();
}

Cette fonction va faire varier deux paramètres (x et y) en fonction de la pression d’une touche. Si certaines touches ne sont pas enfoncées les valeurs de x et de y décroissent. Les valeurs de x et de y seront utilisées dans une autre fonction, le moteur, servant à déplacer les étoiles. Cette fonction appelle également deux autres fonctions, « fixeVitesse() » et « deplaceEtoiles() ».

Code à connaître : isDown

Usage : Key.isDown(codeDeTouche)
Méthode : renvoie true si la touche spécifiée dans codeDeTouche est enfoncée, false si elle ne l'est pas.

Limiter la vitesse

La fonction « fixeVitesse() » est un paramètre supplémentaire qui intervient sur x et sur y.
Elle permet de limiter la valeur de x et de y et ainsi d’éviter que le moteur accélère exponentiellement (on se croirait dans star trek non ? ;-) . Vous essayerez votre projet sans cette fonction, vous verrez qu’on n’en est pas loin. :mrgreen: )

Rajoutez ce code après la fonction « touches ()» :

// 
// Fixe la vitesse
function fixeVitesse() {
	if (x<-vit) {
		x = -vit;
	}
	if (x>vit) {
		x = vit;
	}
	if (y<-vit) {
		y = -vit;
	}
	if (y>vit) {
		y = vit;
	}
}

Nous fixons des limites à la valeur que peuvent prendre x et y.
On remarque l’utilisation d’une variable « vit » qui représente la vitesse max que les étoiles peuvent atteindre. On pourrait mettre à chaque fois une valeur numérique fixe mais c’est plus pratique, lorsque la même valeur se répète, de créer une variable et de modifier juste cette variable quand on veut faire une modification. On utilisera bien sur plusieurs variables tout au long du programme, pour garder un code propre je propose de placer toutes les variables au même endroit, c'est-à-dire en haut du code juste après la création des objets.

Remontez après le code de création des objets et placer le code :

//
// Variables
vit = 18;

Moteur des étoiles

Voyons la fonction « deplaceEtoiles() » à présent.
Il s’agit du moteur proprement dit, c’est cette fonction qui va déplacer toutes les étoiles une par une à sa propre vitesse et en fonction des touches de directions utilisées.

Placez ce code après la fonction « fixeVitesse () » :

//
// Déplace les étoiles
function deplaceEtoiles() {
	for (var i in starfield) {
		var ob = starfield[i]>;
		ob._y += ob.vit*y;
		ob._x += ob.vit*x;
		limites(ob);
	}
}

Code à connaître : for...in

Instruction : effectue une boucle sur les propriétés d'un objet ou sur les éléments d'un tableau et exécute l'instruction pour chaque propriété d'un objet.

Le code « for…in » est très utile, il permet de toucher tous les clips contenus dans notre objet « starfield », on peut donc faire varier la vitesse de chaque sprite indépendamment. Ici nous allons agir sur la position _x et _y de chaque étoile en se servant de la vitesse propre à chaque étoile (rappelez-vous que nous avions fixé une vitesse à chaque étoile lors de leur création) et des valeurs de x et de y que nous avons calculé à l’aide des touches de direction

Valeurs de départ

Si vous testez votre moteur il ne marchera pas, et pour cause, à aucun moment nous n’avons défini les valeurs initiales de x et de y, pour votre programme elles sont encore « undefined » et sans ces paramètres point de déplacement.

Dans le bloc de code contenant les variables rajoutez :

x = 0;
y = 0;

Notre moteur est prêt, toutes les étoiles se déplacent sur les deux axes en fonction des touches de direction, si on relâche certaines touches le moteur ralenti progressivement et la vitesse ne dépasse jamais un certain niveau.

Cependant il reste un petit problème, les étoiles sortent de la zone de jeu.

Le mouvement perpétuel

Certains d’entre vous se sont sûrement déjà posés la question, comment un nombre d’étoiles fixes peut donner l’illusion d’un mouvement perpétuel et irrégulier ?

:idea: La réponse tient en deux points, la vitesse propre à chaque étoile qui donne une illusion de profondeur, et une nouvelle fonction « limite(ob) » qui est la clé du système, elle replace les étoiles à l’autre bout de la zone visible lorsque celles-ci en sortent par un bord.

A la suite du programme tapez le code suivant :

//
// Limites du tableau pour tous les objets
function limites(ob) {
	if (ob._x<xmin) {
		ob._x = xmax;
	}
	if (ob._x>xmax) {
		ob._x = xmin;
	}
	if (ob._y<ymin) {
		ob._y = ymax;
	}
	if (ob._y>ymax) {
		ob._y = ymin;
	}
}

La première chose que l’on remarque c’est le paramètre « ob » que l’on a rajouté dans la fonction. Ce paramètre représente l’objet pour lequel la fonction va intervenir, pour nous ce sera donc pour chaque étoile. On compare alors la position de l’étoile sur les axes X et Y. Si l’étoile sort de la zone visible elle est replacée de l’autre côté. C'est-à-dire que si elle sort par la droite elle réapparaît avec la même vitesse et la même direction à gauche du tableau. Pour déterminer les limites du tableau on va utiliser de nouvelles variables, à placer dans le bloc de code dédié aux variables dans le programme :

xmax = 600;
xmin = 0;
ymax = 400;
ymin = 0;

Testez votre projet et si tout s’est bien passé vous avez votre starfield multidirectionnel infini :)

L"extension Adobe Flash Plugin est nécessaire pour afficher ce contenu.

starfield_etape_1.fla

La suite logique est de rajouter un vaisseau au centre de la scène qui va pivoter sur un axe pour s'orienter dans le sens de la marche. Puis de créer le tir du vaisseau et enfin les ennemis. Il ne reste alors plus qu'à gérer tout ce qui est superflu mais qui fait la beauté de vos jeux, l'intro, l'interface, le hud, la gestion des levels, du score etc… des choses que nous verrons peut-être dans une prochaine étape si je trouve la motivation pour continuer ;-)

Bons jeux !


Version Actionscript 3

La même chose portée sous AS3
Nataly le 23/06/10
La gestion du clavier sous AS3 diffère du principe AS2. BillyBen nous a fait un joli tuto pour illustrer les différentes options possibles qui a donné lieu à une discussion ici.
Il existe également maintenant une version AS3 de ce tutoriel
Kouliane le 11/03/11


Aller plus loin

Ce petit tutorial avait été posté dans la salle “Développement de jeux” du forum de Médiabox. Certains membres se sont lancé dans ce que l'on pourrait appeler une “battle”, un petit jeu où chacun vient apporter sa pierre, faire une optimisation, ici où là, développer de nouvelles options, et surtout s'amuser. Rapidement nous avons obtenus une bonne base pour la création d'un jeu de tir spacial, partis du tutoriel que vous avez lu ci-dessus nous en somme arrivé au final en une version avec des classes et de nombreuses options et ajouts, comme le tir, les ennemis (astéroïdes), les explosions, l'effet “aimant” avec son effet spécial électrique, un HUD, la possibilité de redéfinir les touches, … bref, la porte reste ouverte et n'hésitez surtout pas si vous avez envie de vous amuser à continuer là où d'autre se sont arrêtés.

Voici les sources, je vous recommande vivement de les étudier dans l'ordre si vous êtes débutants, cela vous permettra de comprendre les évolutions du code et l'utilité de ces modifications.

starfield_evolutions.rar

starfield_derniere_version_avec_les_classes_par_paodao.zip

Ici une variante de ce tutoriel qui explique comment déplacer un vaisseau spacial à l'aide des touches fléchées du clavier: Déplacer un objet avec les touches du clavier - Vaisseau spatial
lilive, le 12/04/2010

Version finale

L"extension Adobe Flash Plugin est nécessaire pour afficher ce contenu.

Utilisez les flèches directionnelles pour vous déplacer.
ESPACE pour tirer.
SHIFT pour attirer les astéroïdes.

Remerciements

Les codes fournis dans les sources sont libres de droits, cela n'empêche pas de remercier les participants qui ont posé (et poserons peut être encore) leur patte sur le code.

  • PaoDao
  • Nicoptère
  • Nelchael
  • Leonerep
  • Dada
  • Joni
  • HugoTr
  • Karadoc

… and so ? Let’s go baby ! 8-)

:arrow: Si vous souhaitez en discuter sur le forum c'est par ici : http://flash.mediabox.fr/index.php?showtopic=103124