APE : mise en pratique

Cela fait longtemps qu’un petit test d’APE, le moteur physique AS3, traîne sur mon ordi : c’est le moment d’en faire un petit tuto. Depuis le temps que Erick me le demande !
Récupération du framework et création du projet
- Dans un premier temps, récupérez le framework APE. A cette adresse vous pouvez le télécharger en version archive.
Attention : le code source donné via le repository, et la doc associée ne correspondent pas. Le SVN sert uniquement de dépôt pour les futures versions. A récupérer via le SVN si vous êtes vraiment un foufou des frameworks !
- Créez un nouveau projet ActionScript, nommé APE.
- Clic droit sur le projet, et dans les propriétés, allez dans « ActionScript Build Path », et ajoutez le chemin vers APE (pointez sur le répertoire « source »). APE est maintenant disponible.
Un peu de code !
- Import des classes
Nous allons donc commencer par importer les classes nécessaires. Nous aurons besoin de APE dans son ensemble, ainsi que la classe Event et KeyboardEvent :
package
{
import org.cove.ape.*;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.KeyboardEvent;
[SWF(width="1000", height="1000")]
public class APE extends Sprite
{
public function APE()
{
}
}
}
- Implémentation du moteur
Placez vous dans le constructeur et déclarez le moteur comme suit (tout est dans le commentaire !) :
public function APE()
{
// On boust un brin le framerate de l'appli
stage.frameRate = 60;
// le paramètre donne la vitesse d'execution du moteur.
// La classe APEngine préconise 1/3 ou 1/4...
// fesons ce qu'on nous dis !
APEngine.init(1/4);
// Définition du conteneur du moteur : ici this
APEngine.container = this;
// Ajout du vecteur de gravité global au moteur.
// ici : force de 3 vers le bas.
// Vous pouvez aussi essayer d'autre valeur de vecteur
APEngine.addMasslessForce(new Vector(0,3));
}
- Création du monde
Maintenant nous allons créer un « monde physique ». Toujours dans le constructeur, nous allons créer 3 objets avec des composantes d’élasticité, et 5 objets standards (toujours dans le constructeur) :
// Création du groupe référencant les particules et contrraintes // le paramètre true indique que ce groupe contient des particules et contraintes // dépendantes les une des autres // (en gros que les plaques seront le sol de la bébête) var g:Group = new Group(true); // -OBJET ELASTIQUE ------------------------------------------ // Création de la plaque Elastique 1 // les paramètres donnent la position x et y, // la taille width et height, // la rotation de l'élément, // et si l'objet est fixe ou non var plElastic1:RectangleParticle = new RectangleParticle(720, 400, 50, 5, 0,true); // Elasticité de la plaque plElastic1.elasticity = 2; // Style de la plaque plElastic1.setStyle(0, 0x6699aa, 1, 0x996633); // Ajout de la plaque dans le groupe g.addParticle(plElastic1); // idem pour la plaque 2 var plElastic2:RectangleParticle = new RectangleParticle(745, 300, 5, 200, 0,true); plElastic2.elasticity = 1; plElastic2.setStyle(0, 0x6699aa, 1, 0x996633); g.addParticle(plElastic2); // idem pour la plaque 3 var plElastic3:RectangleParticle = new RectangleParticle(80, 360, 100, 5, 45,true); plElastic3.elasticity = 2; plElastic3.setStyle(0, 0x6699aa, 1, 0x996633); g.addParticle(plElastic3); // -OBJET STANDARD ------------------------------------------ // idem que précédent sans propriété particulière var plStd1:RectangleParticle = new RectangleParticle(400, 400, 600, 5, 0,true); g.addParticle(plStd1); var plStd2:RectangleParticle = new RectangleParticle(55, 220, 5, 200, 0,true); g.addParticle(plStd2); var plStd3:RectangleParticle = new RectangleParticle(350, 200, 300, 5, 0,true); g.addParticle(plStd3); var plStd4:RectangleParticle = new RectangleParticle(450, 300, 350, 5, 0,true); g.addParticle(plStd4); var plStd5:RectangleParticle = new RectangleParticle(550, 100, 350, 5, 0,true); g.addParticle(plStd5);
Vous pouvez jouer avec plein d’autres propriétés pour ces objets : mass, friction, … A vous de tester tout ça !
- Création de la bébête
Bon le plus marrant ! La bébête à roulette. Alors là on peut se lâcher complet ! … bon pas trop quand même pour le tuto, je vous laisse le soin de vous amuser. On va créer une bestiole à 4 roues.
Dans un premier temps, on va déclarer les « roues » au niveau de la classe : elle devront être accessibles à l’ensemble des méthodes pour la suite du tuto :
[SWF(width="1000", height="1000")]
public class APE extends Sprite
{
private var wheelParticleA:WheelParticle;
private var wheelParticleB:WheelParticle;
private var wheelParticleC:WheelParticle;
private var wheelParticleD:WheelParticle;
public function APE()
{
// …
La création en elle-même :
// Création de la particule Roue A
// les paramètres donnent la position x et y,
// le rayon,
// et si l'objet est fixe ou non,
// et on peu lui ajouter des propriétés (ici une masse = 2)
wheelParticleA = new WheelParticle(140,10,14,false, 2);
g.addParticle(wheelParticleA);
// idem pour la roue B
wheelParticleB = new WheelParticle(180,10,14,false, 2);
g.addParticle(wheelParticleB);
// idem pour la roue C
wheelParticleC = new WheelParticle(180,50,14,false, 2);
g.addParticle(wheelParticleC);
// idem pour la roue D
wheelParticleD = new WheelParticle(140,50,14,false, 2);
g.addParticle(wheelParticleD);
// création des connecteurs entre les roues
// les paramètres : les 2 objets à connecter,
// le dureté de la connection,
// et si l'objet est coller ou non,
// la taille de la connection
var wheelConnector1:SpringConstraint = new SpringConstraint(wheelParticleA,
wheelParticleB, 0.5, true, 8);
var wheelConnector2:SpringConstraint = new SpringConstraint(wheelParticleB,
wheelParticleC, 0.5, true, 8);
var wheelConnector3:SpringConstraint = new SpringConstraint(wheelParticleC,
wheelParticleD, 0.5, true, 8);
var wheelConnector4:SpringConstraint = new SpringConstraint(wheelParticleD,
wheelParticleA, 0.5, true, 8);
// Ajout des connecteurs au groupe
g.addConstraint(wheelConnector1);
g.addConstraint(wheelConnector2);
g.addConstraint(wheelConnector3);
g.addConstraint(wheelConnector4);
// Ajout du groupe au moteur de rendu
APEngine.addGroup(g);
Voila pour la bébête !
- La routine RUN
Nous allons maintenant créer la routine EnterFrame qui va mettre à jour tout ça dans le temps :
private function run(evt:Event):void {
// on demande au moteur de faire son boulot ...
APEngine.step();
// ... et on affiche le résultat
APEngine.paint();
}
Il faut aussi ajouter dans le constructeur le lancement de l’évènement EnterFrame :
addEventListener(Event.ENTER_FRAME, run);
- Ajout de la couche d’interactivité
Plus qu’à faire bouger le biniou ! Pour cela, on ajoute 2 évènements Clavier KEY_DOWN et KEY_UP avec leurs méthodes associées :
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler); stage.addEventListener(KeyboardEvent.KEY_UP, keyUpHandler);
Et les méthodes :
// Quand l'utilisateur presse une touche ...
private function keyDownHandler(keyEvt:KeyboardEvent):void {
var keySpeed:Number = 0.4;
// Quand l'utilisateur presse la touche gauche : on change la vitesse angulaire des roues
if (keyEvt.keyCode == 37) {
wheelParticleA.angularVelocity = -keySpeed;
wheelParticleB.angularVelocity = -keySpeed;
wheelParticleC.angularVelocity = -keySpeed;
wheelParticleD.angularVelocity = -keySpeed;
}
// idem pour la touche droite
else if (keyEvt.keyCode == 39) {
wheelParticleA.angularVelocity = keySpeed;
wheelParticleB.angularVelocity = keySpeed;
wheelParticleC.angularVelocity = keySpeed;
wheelParticleD.angularVelocity = keySpeed;
}
}
// Quand l'utilisateur relâche une touche ...
private function keyUpHandler(keyEvt:KeyboardEvent):void {
// On remet les vitesse angulaire des roue a 0
wheelParticleA.angularVelocity = 0;
wheelParticleB.angularVelocity = 0;
wheelParticleC.angularVelocity = 0;
wheelParticleD.angularVelocity = 0;
}
Et voilà !!!!
Ressources
- Site web APE (à voir les démos et exemples)
- Documentation de l’API
- repository SVN pour les anciens !
Tags: AS3, opensource, physique, Tutoriels

--> 29 septembre 2007 ( 11:38 )
Un grand merci, ca manquais vraiment !
--> 29 septembre 2007 ( 18:01 )
heuu dit moi, comment ton code fais t’il pour fonctionner alors que addParticle n’est pas une methode de la classe APEngine ???
en tous cas chez moi ca compile pas.
( ape 0.45)
--> 30 septembre 2007 ( 12:32 )
Oups !… Erreur !
Je viens de me rendre compte que j’avais réalisé cette exemple avec la version 0.3 d’APE… grosse erreur désolé…
La réponse ce trouve avec la classe Group. APEngine permet d’ajouter un Group, ce group référençant les particules et contraintes.
Vous devez dons créer un nouveau group. A chaque particule ou contraintes, vous devez l’ajouter a votre group (monGroup.addPArticle(…); addConstraint(…) ;).
Et au final ajouter le groupe au moteur (APEngine.addGroup(monGroup); )
Bon je corrige tout ça dès Lundi. Encore une fois pardon !
--> 1 octobre 2007 ( 7:53 )
Salut,
bravo pour ce blog de qualité (que je découvre) et merci de proposer un exemple un peu poussé avec APE.
j’en étais toujours à faire des particules et des ressorts ce qui est bien mais pas top…
merci
--> 5 octobre 2007 ( 16:29 )
ahhhhhh moi qui suis pas matheux ca fait plaisir de voir des implémentations de ce style.
Question: ce moteur rend il plus simple les détections de collision, à savoir que les tests de proximité…c est un peu la folie furieuse quand même.
--> 10 octobre 2007 ( 3:24 )
Merci pour l’article.
--> 11 octobre 2007 ( 11:31 )
Merci pour ces retours, ca fait plaisir !
@lutaseb : concernant la détection de collision, celle-ci est intrinsèque au moteur physique. Globalement, le principe d’APE est de définir un monde physique, avec toutes les particularitées qui le compose, et les "phénomènes" physiques sont gérés de manière automatique par le moteur.
Autre piste pour aller plus loin dans APE : regardez de plus près le méthode setDisplay de AbstractParticle ( http://www.cove.org/ape/docs/api... ). Celle-ci vous permet de définir une particule abstraite, et de lui associer un DisplayObject (une image, un composant, un conteneur, …). Du coup APE devient carrement fun, et vous permet de faire plus qu’un flipper !
--> 4 novembre 2007 ( 13:16 )
merci pour ce tuto !
--> 12 janvier 2008 ( 11:14 )
J’ai bien aimé l’article
--> 18 février 2008 ( 3:44 )
Interessant,
--> 18 février 2008 ( 3:45 )
tres cool
--> 4 mars 2008 ( 14:49 )
tres interessant. merci!