Rapidité et stratégie : MoneyStack
Ce jeu flash a été développé à l'aide de FlashDevelop, un puissant IDE gratuit pour Flash, mais malheureusement non disponible sous Linux.
Le jeu a donc été écrit sous un Windows XP virtualisé par VirtualBox OSE (Wine ne fonctionnant pas pour FlashDevelop, ou plutôt : Wine ne supportant pas le framework .NET2.0 nécessaire à l'utilisation de FlashDevelop).
Licence
Ce code est fourni sous une licence CC-By (cf. fin de page).
De plus, il est interdit de recompiler le jeu "tel quel" en supprimant le lien « Plus de jeux », la mention « tel quel » restant à l'appréciation de l'auteur original du code source (copie, plagiat...).
À propos du code
Vous pouvez générer la documentation du code via l'outil asdoc distribué par défaut avec le Flex SDK.
Classes de BankNoteStack
Fichiers de bases :
Code source : Main.as
Langage : actionscript3 Taille : 7514 caract�res ?package
{
import flash.display.Loader;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.events.MouseEvent;
import flash.events.TextEvent;
import flash.net.navigateToURL;
import flash.net.sendToURL;
import flash.net.URLRequest;
import flash.system.LoaderContext;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFieldType;
import gs.easing.Elastic;
import gs.TweenLite;
import gs.OverwriteManager;
import mochi.as3.*;
/**
* Crée un nouveau jeu CoinStack.
*
* <p>Le but de cette application Flash est de ramasser un maximum de pièces.
* Une pièce ne peut être ramassée que si elle n'est pas recouverte par d'autres pièces.
* Au niveau du code, cette application est extrêmement simple.</p>
* <p>On distingue les classes suivantes :</p>
* <ul>
* <li>Level : Un niveau. Affiche une pub, l'aide, puis le jeu. A la fin du temps réglementaire, les pièces disparaissent une à une. Lorsque la dernière pièce a disparue, le niveau envoie l'évenement Level.LEVEL_ENDED, qui est récupére par cette classe pour enregistrer le score grâce au leaderboard mochiads ;</li>
* <li>Coin : Une pièce.</li>
* </ul>
*
* <p>En plus de ces deux classes, on trouve :</p>
* <ul>
* <li>Global : une classe qui contient en statique toutes les constantes du jeu, ainsi que le score et autre ;</li>
* <li>SecondSprite : un sprite dynamic, pour afficher les publicités mochiads.</li>
* </ul>
* @author Neamar
*/
public class Main extends Sprite
{
/**
* L'image du fond
*
*/
public var Fond:Loader = new Loader();
private var Sponsor:Loader = new Loader();
private var Logo:Loader = new Loader();
private var Niveau:Level;
private var Scores:SecondSprite = new SecondSprite();
private var EnregistrerScore:Sprite = new Sprite();
private var EnregistrerScore_Texte:TextField = new TextField();
private var EnregistrerScore_Pseudo:TextField = new TextField();
private var EnregistrerScore_OK:TextField = new TextField();
public function Main():void
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
// entry point
//Enregistrer le nouveau joueur :
sendToURL(new URLRequest("http://neamar.fr/Res/MoneyStack/Player.php"));
OverwriteManager.init();
Global.stage = this.stage;
addChild(Scores);
MochiServices.connect("028ef12af089b8d6", Scores);
Niveau = new Level();
Niveau.addEventListener(Level.LEVEL_ENDED, niveauTermine);
Fond.load(new URLRequest("http://neamar.fr/Res/MoneyStack/Images/Fond.jpg"),new LoaderContext(true));
addChild(Fond);
setChildIndex(Fond, 0);
//On met cet écouteur d'évenement ici pour ne pas le répéter.
EnregistrerScore_Pseudo.addEventListener(KeyboardEvent.KEY_DOWN, toucheAppuyee);
EnregistrerScore_OK.addEventListener(MouseEvent.CLICK, saveScore);
Sponsor.load(new URLRequest("http://neamar.fr/Res/CoinStack/Images/MiniJeu.png"), new LoaderContext(true));
Sponsor.addEventListener(MouseEvent.CLICK, visiterSponsor);
Logo.load(new URLRequest("http://neamar.fr/Res/MoneyStack/Images/MoneyStack.jpg"), new LoaderContext(true));
Global.Logo = Logo;
}
/**
* Valide la case avec le pseudo du joueur.
*
* @param e L'évenement clavier.
* @author Neamar
*/
private function toucheAppuyee(e:KeyboardEvent):void
{
if (e.charCode == 13 || e.keyCode == 13)
EnregistrerScore_OK.dispatchEvent(new MouseEvent(MouseEvent.CLICK));
}
/**
* Fonction appelée quand l'évenement Level.LEVEL_ENDED est émis.
*
* Affiche une boite permettant d'enregistrer son pseudo et son score, ainsi que le sponsor du jeu.
* @param e Inutile
* @author Neamar
*/
public function niveauTermine(e:Event=null):void
{
removeEventListener(Level.LEVEL_ENDED, niveauTermine);
this.stage.removeChild(Niveau);
EnregistrerScore.graphics.clear();
EnregistrerScore.addChild(EnregistrerScore_Texte);
EnregistrerScore_Texte.multiline = true;
EnregistrerScore_Texte.width = 380;
//EnregistrerScore_Texte.height = 100;
EnregistrerScore_Texte.x = 20;
EnregistrerScore_Texte.y = 5;
EnregistrerScore_Texte.htmlText ="<font size=\"20\">Fin de la partie.</font><br>Votre score : <b>" + int(Global.Score) + "</b><br><br>Entrez votre pseudo pour enregistrer vos points :";
EnregistrerScore_Texte.selectable = false;
EnregistrerScore.addChild(EnregistrerScore_Pseudo);
EnregistrerScore_Pseudo.autoSize = TextFieldAutoSize.CENTER;
EnregistrerScore_Pseudo.type = TextFieldType.INPUT;
if(EnregistrerScore_Pseudo.text=='')
EnregistrerScore_Pseudo.text = "Pseudo";
EnregistrerScore_Pseudo.width = 100;
EnregistrerScore_Pseudo.height = 25;
EnregistrerScore_Pseudo.background = true;
EnregistrerScore_Pseudo.backgroundColor = 0xFFFFFF;
EnregistrerScore_Pseudo.alpha = .4;
EnregistrerScore_Pseudo.x = EnregistrerScore_Texte.width/2 - EnregistrerScore_Pseudo.width / 2;
EnregistrerScore_Pseudo.y = EnregistrerScore_Texte.height - 20;
addChild(EnregistrerScore);
EnregistrerScore.scaleX = EnregistrerScore.scaleY = 1.4;
EnregistrerScore.x = Global.FLASH_WIDTH / 2 - 200;
EnregistrerScore.y = 480;
TweenLite.to(EnregistrerScore,2,{y:35,ease:Elastic.easeOut});
EnregistrerScore.width = 400;
//EnregistrerScore.height = 200;
EnregistrerScore.filters=new Array(Global.SHADOW);
EnregistrerScore.graphics.lineStyle(2, 0, .8);
EnregistrerScore.graphics.beginFill(0xFFFFFF, .4);
EnregistrerScore.graphics.drawRoundRect(0, 0, EnregistrerScore.width, 120, 10, 10);
EnregistrerScore.addChild(EnregistrerScore_OK);
EnregistrerScore_OK.text = "Enregistrer";
EnregistrerScore_OK.selectable = false;
EnregistrerScore_OK.textColor = 0xB30000;
EnregistrerScore_OK.x = 300;
EnregistrerScore_OK.y = 80;
//Le sponsor MiniJeu gratuit :
addChild(Sponsor);
Sponsor.x = Global.FLASH_WIDTH / 2 - 303 / 2;//303 = Sponsor.width
Sponsor.y = 220;
Global.stage.focus = EnregistrerScore_Pseudo;
EnregistrerScore_Pseudo.setSelection(0, EnregistrerScore_Pseudo.text.length);
}
/**
* Fonction appelée quand l'utilisateur a entré son pseudo et appuyé sur "Enregistrer".
*
* Enregistre le score et l'envoie aux serveurs de MochiAds, affiche le leaderBoard.
* @param e Inutile
* @author Neamar
*/
public function saveScore(e:Event):void
{
if (EnregistrerScore_Pseudo.text == "Pseudo")
return;
removeChild(EnregistrerScore);
removeChild(Sponsor);
var o:Object = { n: [9, 1, 4, 7, 3, 8, 11, 1, 13, 2, 5, 12, 1, 5, 15, 2], f: function (i:Number,s:String):String { if (s.length == 16) return s; return this.f(i+1,s + this.n[i].toString(16));}};
var boardID:String = o.f(0,"");
MochiScores.showLeaderboard({boardID: boardID, score: int(Global.Score), name: EnregistrerScore_Pseudo.text,onClose:init});
}
private function visiterSponsor(e:MouseEvent):void
{
navigateToURL(new URLRequest("http://www.mini-jeu-gratuit.fr/vip/neamar/"));
}
}
}
Code source : Level.as
Langage : actionscript3 Taille : 7338 caract�res ?package
{
import adobe.utils.CustomActions;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.events.TimerEvent;
import flash.filters.BevelFilter;
import flash.filters.DropShadowFilter;
import flash.filters.GlowFilter;
import flash.text.TextField;
import flash.utils.Timer;
import Utilitaires.geom.SatShape;
import mochi.as3.*;
import gs.TweenLite;
/**
* Un niveau.
*
* <p>Chaque niveau contient Global.COINS_IN_GAME pièces.<br/>
* On affiche d'abord une publicité pendant que les pièces tombent, puis on montre l'aide.<br/>
* Un clic quitte l'aide et lance le niveau. Une fois le temps écoulé, le spièces disparaissent une à une.
* @author Neamar
*/
public dynamic class Level extends Sprite
{
public static const LEVEL_ENDED:String = "FIN_NIVEAU";
/**
* Vaut false tant que le jeu n'a pas commencé : écite que l'on puisse cliquer sur les pièces pendant l'affichage de la pub.
*/
public var hasStarted:Boolean = false;
/**
* Les différents types de pièces que l'on peut rencontrer dans le jeu (définies dans le jeu).
*/
public static const MonnaiePossibles:Array/*Class*/ = new Array(Coin.p1Cent, Coin.p2Cents, Coin.p5Cents, Coin.p10Cents, Coin.p20Cents, Coin.p50Cents, Coin.p1Euro, Coin.p2Euros, BankNote.b5, BankNote.b10, BankNote.b20, BankNote.b50, BankNote.b100, BankNote.b200, BankNote.b500);
/**
* Valeurs en points de chaque pièce/billet.
*/
public static const Valeurs:Array/*int*/= new Array(0.01, 0.02,0.05, 0.1,0.20,0.50,1,2,5,10,20,50,100,200,500);
/**
* Nombre de pièces que contient actuellement le niveau. Sa valeur n'est pas mise à jour une fois que la partie a commencée.
*
* <p>Cette variable sert uniquement lors de l'apparition des pièces.</p>
*/
public var NbBillets:int = 0;
private var Chrono:Timer;
private var ChampTexte:TextField = new TextField();
private var TexteSprite:SecondSprite = new SecondSprite();
private var FondTexteSprite:Sprite = new Sprite();
private var apresMessage:Function;
/**
* Créer un nouveau niveau.
*/
public function Level()
{
function fin_pub(e:Event = null):void
{
TexteSprite.filters = new Array(new BevelFilter(), new GlowFilter(0xFFFFFF, .9, 32, 32, 6));
TexteSprite.buttonMode = true;
TexteSprite.scaleX = TexteSprite.scaleY = 1.5;
TexteSprite.addChild(ChampTexte);
ChampTexte.y = 150/TexteSprite.scaleX;
ChampTexte.width = Global.FLASH_WIDTH/TexteSprite.scaleX;
ChampTexte.height = Global.FLASH_HEIGHT/TexteSprite.scaleY;
ChampTexte.selectable = false;
//ChampTexte.textColor = 0;
ChampTexte.multiline = true;
afficherMessage(lancerNiveau, "<b>But du jeu</b><br>Ramassez le plus d'argent possible en cliquant sur les pièces et les billets.<br>Vous ne pouvez récupérer un élément que <b>si il n'est pas recouvert</b>.<br><br><br><b>Score</b><br>Chaque élément vous rapporte sa valeur en points (50? : 50 points).<br>Si vous tentez de ramasser un objet recouvert, vous perdez sa valeur.<br><br><b>Fin du jeu</b><br>Le jeu se termine après " + Math.floor(Global.LEVEL_TIME / 1000) + " secondes.<br><br><b><i><font color=\"#FF0000\">Cliquez pour commencer...</font></i></b>");
}
//Mettre sur la scène le niveau.
Global.stage.addChild(this);
this.addEventListener(Event.ENTER_FRAME, creerMonnaie);
addChild(TexteSprite);
MochiAd.showInterLevelAd( { clip:TexteSprite, id:"028ef12af089b8d6", res:"640x480", no_bg:true, ad_started:creerMonnaie, ad_finished:fin_pub } );
//removeChild(TexteSprite);
//lancerNiveau();
}
/**
* Lance le jeu une fois la pub et l'aide affichées.
*/
public function lancerNiveau():void
{
removeEventListener(Event.ENTER_FRAME, creerMonnaie);
//Créer tous les objets
for (var i:int = NbBillets; i < Global.BANKS_IN_GAME; i++)
creerMonnaie();
Global.Score = 0;
hasStarted = true;
Chrono = new Timer(Global.LEVEL_TIME, 1);
Chrono.start();
Chrono.addEventListener(TimerEvent.TIMER, finNiveau);
}
public function tryRemove(e:Event):void
{
var Obj:SatShape = (e.currentTarget as SatShape);
if (!hasStarted)
return;
var i:int = this.numChildren - 1;
var estDessous:Boolean = false;
while (getChildAt(i) != Obj)
{
var Monnaie:SatShape = (getChildAt(i) as SatShape);
if (Obj.hitTest(Monnaie))
{
TweenLite.to(Obj, .7, { scaleX:.7, scaleY:.7 } );
TweenLite.to(Obj, .3, { delay:.7, scaleX:1, scaleY:1 } );
TweenLite.to(Monnaie, 1, { rotation:Monnaie.rotation+360 } );
estDessous = true;
}
i--;
}
if (!estDessous)
{
Global.Score += Obj['Valeur'];
Obj.destroy();
}
else
Global.Score -= Obj['Valeur'];
trace(Global.Score,Obj['Valeur']);
}
private function creerMonnaie(e:Event=null):SatShape
{
var Monnaie:SatShape;
if (NbBillets <= Global.BANKS_IN_GAME)
{
if (NbBillets % MonnaiePossibles.length <= 7)
Monnaie = new Coin(this, NbBillets % MonnaiePossibles.length);
else
Monnaie = new BankNote(this, NbBillets % MonnaiePossibles.length);
addChild(Monnaie);
NbBillets++;
if(this.contains(TexteSprite))
setChildIndex(TexteSprite, numChildren - 1);//Garder le texte au premier rang.
return Monnaie;
}
else
return null;
}
private function supprimerBillet(e:Event = null):void
{
if (numChildren!=0)
{
(getChildAt(0) as SatShape).destroy();
}
else
{
removeEventListener(Event.ENTER_FRAME, supprimerBillet);
dispatchEvent(new Event(LEVEL_ENDED));
}
}
private function finNiveau(e:TimerEvent):void
{
//afficherMessage(null, "<font size=\"20\">Fin de la partie.</font><br><br><br><b>Votre score : " + Global.Score + "</b>");
addEventListener(Event.ENTER_FRAME, supprimerBillet);
}
private function afficherMessage(apresClick:Function,Texte:String):void
{
addChild(TexteSprite);
TexteSprite.addChild(Global.Logo);
Global.Logo.scaleX = Global.Logo.scaleY = 1 / TexteSprite.scaleX;
TexteSprite.addChild(FondTexteSprite);
FondTexteSprite.graphics.clear();
FondTexteSprite.graphics.beginFill(0xFFFFFF, .3);
FondTexteSprite.graphics.drawRect(0, 0, Global.FLASH_WIDTH, Global.FLASH_HEIGHT);
FondTexteSprite.alpha = 0;
TweenLite.to(FondTexteSprite, 1, { alpha:.3 , onComplete:TexteSprite.addEventListener, onCompleteParams:[MouseEvent.CLICK, supprimerMessage]} );
ChampTexte.htmlText = Texte;
//TexteSprite.addEventListener(MouseEvent.CLICK, supprimerMessage); //Inclus dans le TweenLite une fois celui-ci terminé.
apresMessage = apresClick;
}
private function supprimerMessage(e:MouseEvent = null):void
{
TexteSprite.removeEventListener(MouseEvent.CLICK, supprimerMessage);
removeChild(TexteSprite);
ChampTexte.text = '';
if (TexteSprite.contains(FondTexteSprite))
TexteSprite.removeChild(FondTexteSprite);
if(apresMessage!=null)
apresMessage();
}
}
}
Code source : BankNote.as
Langage : actionscript3 Taille : 2421 caract�res ?package
{
import flash.display.Bitmap;
import flash.display.DisplayObject;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.FocusEvent;
import flash.events.MouseEvent;
import flash.filters.DropShadowFilter;
import flash.filters.GlowFilter;
import flash.geom.Point;
import flash.geom.Rectangle;
import Utilitaires.ArrayPlus;
import Utilitaires.geom.SatRectangle;
import Utilitaires.geom.SatShape;
import Utilitaires.geom.Vector;
import gs.TweenLite;
/**
* Une pièce.
* @author Neamar
*/
public class BankNote extends SatRectangle
{
[Embed(source="../assets/5.jpg")]
public static var b5:Class;
[Embed(source="../assets/10.jpg")]
public static var b10:Class;
[Embed(source="../assets/20.jpg")]
public static var b20:Class;
[Embed(source="../assets/50.jpg")]
public static var b50:Class;
[Embed(source="../assets/100.jpg")]
public static var b100:Class;
[Embed(source="../assets/200.jpg")]
public static var b200:Class;
[Embed(source="../assets/500.jpg")]
public static var b500:Class;
/**
* La valeur en points de la pièce.
*/
public var Valeur:int;
private var Parent:Level;
private var Img:Bitmap;
/**
* Crée une nouvelle pièce
*
* @param Parent Le niveau conteneur.
* @param IDClass Le type que doit avoir la pièce : 1?, 50 centimes...
*/
public function BankNote(Parent:Level,IDClass:int)
{
Img = new Level.MonnaiePossibles[IDClass];
super(Global.FLASH_WIDTH * Math.random(), Global.FLASH_HEIGHT * Math.random(), Img.width, Img.height);
this.Parent = Parent;
var BilletStyle:int = 0;
this.Valeur = Level.Valeurs[IDClass];
Img.smoothing = true;
Img.x = -width/2;
Img.y = -height / 2;
this.addChild(Img);
this.filters = new Array(Global.SHADOW);
this.addEventListener(MouseEvent.CLICK, Parent.tryRemove);
this.cacheAsBitmap = true;
this.rotation = -180 + Math.random() * 360;
this.alpha = 0;
TweenLite.to(this, .5, { alpha:1 } );
}
/**
* Détruit la pièce pour gagner de la mémoire.
*/
public override function destroy():void
{
Parent.removeChild(this);
removeChild(getChildAt(0));
removeEventListener(MouseEvent.CLICK, Parent.tryRemove);
super.destroy();
}
}
}
Code source : Coin.as
Langage : actionscript3 Taille : 2461 caract�res ?package
{
import flash.display.Bitmap;
import flash.display.DisplayObject;
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.filters.DropShadowFilter;
import flash.filters.GlowFilter;
import Utilitaires.geom.SatCircle;
import Utilitaires.geom.SatShape;
import gs.TweenLite;
/**
* Une pièce.
* @author Neamar
*/
public class Coin extends SatCircle
{
[Embed(source="../assets/1Centime.png")]
public static var p1Cent:Class;
[Embed(source="../assets/2Centimes.png")]
public static var p2Cents:Class;
[Embed(source="../assets/5Centimes.png")]
public static var p5Cents:Class;
[Embed(source="../assets/10Centimes.png")]
public static var p10Cents:Class;
[Embed(source="../assets/20Centimes.png")]
public static var p20Cents:Class;
[Embed(source="../assets/50Centimes.png")]
public static var p50Cents:Class;
[Embed(source="../assets/1Euro.png")]
public static var p1Euro:Class;
[Embed(source="../assets/2Euros.png")]
public static var p2Euros:Class;
/**
* La valeur en points de la pièce.
*/
public var Valeur:Number;
private var Parent:Level;
private var Img:Bitmap;
/**
* Crée une nouvelle pièce
*
* @param Parent Le niveau conteneur.
* @param IDClass Le type que doit avoir la pièce : 1?, 50 centimes...
*/
public function Coin(Parent:Level,IDClass:int)
{
this.Parent = Parent;
var CoinStyle:int = 0;
Img = new Level.MonnaiePossibles[IDClass];
super(Global.FLASH_WIDTH * Math.random(),Global.FLASH_HEIGHT * Math.random(),Math.min(Img.width, Img.height) / 2)
this.Valeur = Level.Valeurs[IDClass];
Img.smoothing = true;
Img.x = -Img.width/2;
Img.y = -Img.height/2;
this.addChild(Img);
this.filters = new Array(Global.SHADOW);
this.addEventListener(MouseEvent.CLICK, Parent.tryRemove);
this.cacheAsBitmap = true;
this.rotation = -180 + Math.random() * 360;
this.alpha = 0;
TweenLite.to(this, .5, {alpha:1 } );
}
/**
* Détruit la pièce pour gagner de la mémoire.
*/
public override function destroy():void
{
Parent.removeChild(this);
removeChild(getChildAt(0));
removeEventListener(MouseEvent.CLICK, Parent.tryRemove);
super.destroy();
}
/**
* Supprime la pièce une fois qu'on lui a cliquée dessus.
*/
}
} Mathématiques
Ce jeu utilise le théorème de séparation des axes. Afin de simplifier la programmation, on trouvera donc une classe Vecteur.
Code source : Vecteur.as
Langage : actionscript3 Taille : 773 caract�res ?package
{
import flash.geom.Point;
/**
* ...
* @author Neamar
*/
public class Vecteur extends Point
{
public function Vecteur(x:Number, y:Number)
{
super(x, y);
}
public static function fromPoints(A:Point, B:Point):Vecteur
{
return new Vecteur(B.x - A.x, B.y - A.y);
}
public function get Unitaire():Vecteur
{
var N:Number = Norme;
return new Vecteur(x / Norme, y / Norme);
}
public function get Norme():Number
{
return Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
}
public function scalaire(V:Vecteur):Number
{
return this.x * V.x + this.y * V.y;
}
public function multiplier(k:Number):Vecteur
{
return new Vecteur(k * x, k * y);
}
}
}
Code source : SatCircle.as
Langage : actionscript3 Taille : 1039 caract�res ?package Utilitaires.geom
{
import flash.geom.Point;
import Utilitaires.ArrayPlus;
import Utilitaires.geom.SatShape;
/**
* ...
* @author Neamar
*/
public class SatCircle extends SatShape
{
public var Rayon:int;
public function SatCircle(x:int, y:int, Rayon:int)
{
super(x, y);
this.Rayon = Rayon;
makeVector();
}
public override function makeVector():void
{
this.Sommets = new ArrayPlus(new Point(0,0)); //Ce n'est pas un sommet au sens propre, mais ça nous suffira pour Sat.
super.makeVector();
}
public override function axesAvec(Forme:SatShape):ArrayPlus
{
this.Vecteurs = new ArrayPlus();
for each(var Sommet:Point in Forme.Sommets)
{
Vecteurs.push
(
Vector.fromPoints
(
new Point(this.x,this.y),
Forme.localToGlobal(Sommet)
)
);
}
makeVector();
return _Axes;
}
public override function projeter(Axe:Vector):Number
{
return Rayon;
}
}
}
Code source : SatRectangle.as
Langage : actionscript3 Taille : 1577 caract�res ?package Utilitaires.geom
{
import flash.geom.Point;
import Utilitaires.ArrayPlus;
import Utilitaires.geom.Vector;
/**
* Un rectangle SAT.
* @author Neamar
*/
public class SatRectangle extends SatShape
{
private var _width:Number;
private var _height:Number;
public function SatRectangle(x:int,y:int,Width:int,Height:int)
{
super(x, y);
_width=Width;
_height = Height;
//liste des vecteurs composant la forme.
makeVector();
}
public override function get width():Number { return _width; }
public override function get height():Number { return _height; }
public override function makeVector():void
{
Vecteurs = new ArrayPlus
(
Vector.fromPoints
(
this.localToGlobal(new Point(-width/2,-height/2)),
this.localToGlobal( new Point( -width / 2, height / 2))
),
Vector.fromPoints
(
this.localToGlobal(new Point( -width / 2, -height / 2)),
this.localToGlobal(new Point(width / 2, -height / 2))
)
);
Sommets = new ArrayPlus
(
new Point( -width / 2, -height / 2),
new Point( -width / 2, height / 2),
new Point( width / 2, -height / 2),
new Point( width / 2, height / 2)
)
super.makeVector();
}
public override function projeter(Axe:Vector):Number
{
var dpi:Number = Vector.scalaire(Vecteurs[0],Axe);
var dpj:Number = Vector.scalaire(Vecteurs[1],Axe);
return (Math.abs(dpi) + Math.abs(dpj))/2;//projection de la diagonale sur Axe.
}
}
}
Code source : SatShape.as
Langage : actionscript3 Taille : 2922 caract�res ?package Utilitaires.geom
{
import flash.display.Sprite;
import Utilitaires.ArrayPlus;
/**
* Une forme qui peut être utilisée avec le Separating Axis Theorem pour des hitTests plus avancés.
* @author Neamar
*/
public class SatShape extends Sprite
{
public var rotation_rad:Number;
/**
* Liste des axes à tester pour SAT.
*/
protected var _Axes:ArrayPlus=new ArrayPlus();//Coordonnées ABSOLUES
/**
* Liste des vecteurs (segments) composant la figure.
*/
public var Vecteurs:ArrayPlus = new ArrayPlus();//Coordonnées ABSOLUES
public var Sommets:ArrayPlus = new ArrayPlus();//Coordonnées RELATIVES
public function SatShape(x:int,y:int)
{
this.x = x;
this.y = y;
}
public function destroy():void
{
Vecteurs = null;
Sommets = null;
_Axes = null;
}
public function makeAxis():void
{
_Axes = new ArrayPlus();
for each(var Vecteur:Vector in Vecteurs)
{
var Axe:Vector = Vecteur.clone();
Axe.unitaire();
_Axes.push(Axe);
}
}
public function makeVector():void
{
//Une fois la génération des vecteurs finies, en déduire les axes.
makeAxis();
}
public override function set rotation(v:Number):void
{
this.rotation_rad = v * Math.PI / 180;//Angle en radians
super.rotation = v;
makeVector();
}
/**
* Renvoie la liste des axes à utiliser pour SAT
*
* @param Forme La forme avec laquelle sera effectuée la collision (utilisée pour les cercles)
*/
public function axesAvec(Forme:SatShape):ArrayPlus
{
return _Axes;
}
/**
* Détermine si la forme est en collision avec Obj.
*
* @param Obj La forme avec laquelle la collision doit être testée.
*/
public function hitTest(Obj:SatShape):Boolean
{
//if (!this.hitTestObject(Obj))
//return false;
//Vecteur entre les centres des deux formes.
var Delta:Vector = new Vector(Obj.x - this.x, Obj.y - this.y);
///Liste des axes à tester.
var Axes:ArrayPlus = ArrayPlus.concat(this.axesAvec(Obj), Obj.axesAvec(this));
for each(var Axe:Vector in Axes)
{
//projection des billets selon ces axes.
var aSize:Number = this.projeter(Axe);//Produit scalaire de la diagonale de this avec l'axe
var bSize:Number = Obj.projeter(Axe);//Produit scalaire de la diag de Obj selon Axe.
var dSize:Number = Math.abs(Vector.scalaire(Delta,Axe));
if ((aSize + bSize) - dSize <= 0)
{
return false;
break;
}
}
return true;
}
/**
* Projette la forme selon Axe. Renvoie la longueur de la projection.
*
* @param Axe L'axe sur lequel la forme doit être projeté.
*/
public function projeter(Axe:Vector):Number
{
throw(new Error("Appel d'une méthode abstraite."));
}
}
}
Constantes Globales
Code source : Global.as
Langage : actionscript3 Taille : 986 caract�res ?package
{
import flash.display.Loader;
import flash.display.Sprite;
import flash.display.Stage;
import flash.filters.DropShadowFilter;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
/**
* ...
* @author Neamar
*/
public class Global
{
public static var stage:Stage;
public static const FLASH_WIDTH:int = 640;
public static const FLASH_HEIGHT:int = 480;
public static const LEVEL_TIME:int = 60*1000;
public static const BANKS_IN_GAME:int = 500;
public static const TOLERANCE:int = 3;//La tolérance indique de combien de pixels peut se tromper le joueur, certaines jonctions étant assez traitres.
public static const SHADOW:DropShadowFilter = new DropShadowFilter(7, -45, 0, 0.8, 4, 4, 2);
//public static const LIGHT:DropShadowFilter = new DropShadowFilter(3, -45, 0xFFFFFF, 0.5, 2, 2, 3,1,true);
public static var Score:Number = 0;
public static var Logo:Loader;
}
} Spécial
MochiAds demande un sprite dynamique pour afficher ses scores, d'où cette classe inutile.
Code source : SecondSprite.as
Langage : actionscript3 Taille : 202 caract�res ?package
{
import flash.display.Sprite;
/**
* ...
* @author Neamar
*/
public dynamic class SecondSprite extends Sprite
{
public function SecondSprite()
{
}
}
}