Economiser des lignes de code en ActionScript
Par -Alexandre LEGOUT aka LAlex- le 14 avril 2004, 17:37 - AS2 - Lien permanent
Je corrige actuellement les soumissions de concurrents des Actionscript Awards, menés à Singapour. Une des contraintes étant le nombre de lignes de code (60 lignes max.), des développeurs ont déployé des trésors d'ingéniosité pour économiser des lignes d'instructions !
Ce qui complique évidemment la compréhension de ce qu'est sensé faire le code, et ainsi ne simplifie pas mon travail de correcteur ! ![]()
L'ensemble de ces pratiques n'est évidemment pas à conseiller !!!
Etant donné que même si le code fonctionne quand-même, le lisibilité s'en trouve fortement réduite. Je ne les donne ici que par curiosité intellectuelle pour ceux qui voudraient se lancer dans ce type de contest.
Tout d'abord, il n'y a pas suffisamment de personnes qui savent que les commandes createEmptyMovieClip() et duplicateMovieClip() retournent une référence sur le clip crée (ou dupliqué). Il ets donc possible de récupérer cet objet nouvellement créé sur la même ligne. De même, l'argument objetInit peut se révéler trés utile dans cette course aux lignes :var mc = _root.monClipOriginal.duplicateMovieClip("monClone", _root.getNextHighestDepth(), {_x: 100, _y: 200, _alpha:50});
Ensuite, il existe l'éternel instruction ternaire qui remplace quasi-systématiquement le if. Bien évidemment, les if imbriqués deviennent des ? imbriqués ! ![]()
var myVar = (this._x > 10 ? 10 : 20);
Penchons-nous maintenant sur l'opérateur d'affectation qu'est '='. En effet, une instrcution d'affectation retourne la valeur qui vient d'être affectée. Ainsi, il est possible d'affecter la même valeur à plusieurs valeurs d'un coup.
// Equivalent de
var myVar;
if (this._x > 10) {
myVar = 10;
} else {
myVar = 20;
}monClip._xscale = monClip._yscale = 50;
Pour info, c'est pour cette raison que lorsqu'on crée un setter dans une classe, son utilisation fait appel au getter correspondant (plus d'infos chez petepx)
Si on combine plusieurs astuces, on peut obtenir le code pour créer une ombre par exemple (en supposant que la profondeur en dessous du clip visé est vide)// Si, si, il s'agit d'une seule ligne de code !
Mais le truc qui m'a le plus surpris, parce que je n'y avais pas pensé une seule seconde, c'est l'utilisation de la virgule. En effet, la virgule est souvent utilisée conjointement à l'instruction var pour déclarer plusieurs variables d'un coup... mais l'on peut l'utiliser dans bien d'autres situations :
(color = new Color(mc = monClip.duplicateMovieClip(monClip._name + "_shadow", monClip.getDepth()-1, {_x : monClip._x + 10, _y: monClip._y + 10, _alpha: 50}))).setRGB(0);
// Le clip d'ombre est dans mc
trace(mc);// Utilisation "normale"
var maVar = 10, monAutreVar = 20;
// Utilisation détournée
(mc = _root.createEmptyMovieClip("newclip", 10)), mc._alpha=15;
Futé tout ca non ?
Si vous avez d'autres astuces du genre, ca me plairait bien de toutes les collecter, histoire de savoir jusqu'à quel point on peut être tordu à ce niveau la !!! ![]()
Commentaires
J'ai surtout vu l'appli de André Michelle qu'il présente en cherchant bien sur son blog pour faire un pacman en 30 lignes...
Et forcément pour faire la map .. c'est assez intéressant 


Voir ici
Je dirais tout de même qu'on peut encore optimiser la taille de son code...
bye
salut
la premiere qui me vient en tete est celle-ci :
avant :
(mc = _root.createEmptyMovieClip("newclip", 10)), mc._alpha=15;apres :_root.createEmptyMovieClip("newclip", 10)._alpha=15;liguorien >> Oui, dans ce cas précis, mais l'utilisation de la virgule peut servir dans a peu prés tous les cas pour remplacer le ;
++ ^^
mais c'est clair que si on codait tous comme cela tout le temps.. on deviendrait de vrais psycotiques....
Je te raconte pas l'agonie que je vis à essayer de comprendre ce que fait le code, et a corriger ... 8O
salut
un autre petit truc qui est déjà connu mais sa vaut la peine de le mentionner car il n'est pas dans ce post...
//methode traditionellevar liste = new Array();
liste.push("1");
liste.push("2");
liste.push("3");
//methode abrégé
var liste = ["1","2","3"];
A+
liguorien > C'est dans la doc, cette notation raccourcit de tableau!
Oui, cette méthode d'initialisation est pratique aussi. Mais ta méthode "traditionnelle" me semble plutôt lourde non ? En général, si on utilise pas l'initialisation avec crochets, on fait quelque chose du genre
var liste = new Array("1", "2", "3");Dans la même veine, il y a aussi la déclaration d'objets :var homme = {age:25, poids: 85, taiile: 1.85}++ ^^
en général pour les tableaux je préfère taper :

var liste = [ "1", "2", "3" ] ;du coup si j'ai :var ar = [en version 1 seule ligne cela donne :{ name : "moi" , pseudo : "ekameleon" } ,
{ name : "toi" , pseudo : "lalex" }
]
var ar = [ { name : "moi" , pseudo : "ekameleon" } , { name : "toi" , pseudo : "lalex" } ]bye
Oauip, la virgule passe partout, sauf si les elements sont des structures (if, for, while, etc.). Et puis faut rappeler que la virgule est un operateur, elle renvoit une valeur, pas comme le point-virgule.
J'avais fait une chtite presentation sur le sujet pour le user group flashmove. Je ne sais pas ce que ca vaut sans mes fantastiques commentaires d'accompagnement ;p, mais c'est ici.
Et puis pour economiser des lignes, rien ne vaut la technique ninja de la mort qui est d'utiliser un bug de l'autoformat (marche sous MX et MX2004). Bon, la faut bien reconaitre c'est un peu de la triche et le code devient carrement illisible. Mais pour la route, copie le code ci-dessous dans flash et appuie sur le bouton d'autoformat. Hop! C'est magique!!
func1 = function() {func2 = function() {
var1 = "hello";
var2 = "lalex";
// meme une boucle
for (var i=0; i<10; i++) {
trace(i*i);
}
// et un if
if (var1 == "hello") {
var3 = "pouet";
}
var4 = "toto";
}
}
J'espere que personne n'a utiliser ca sinon tu vas en chier ;). Bon courage pour les evaluations.
A+,
Timoth'
Ha merde, mon signe 'inferieur' s'est fait niquer par le formattage...
Moi aussi j'ai une petite astuce.
Lorsqu'il n'ya q'une seule ligne de code à executer les accolades sont bien souvent inutiles
Exemple :
if(condition) action();Dommage que l'autoformat de flash les rajoutes.
Sinon dans l'absolu on peut mettre tout sur une seule ligne sans que le compilateur ne bronche (c'est comme en html)
"Une des contraintes étant le nombre de lignes de code (60 lignes max.), ..."
bah samsam a raison
on peut toute mettre sur 1 seule ligne
suffit de virer tous les CRLF et de terminer chaques block d'instruction {} par un semi-colon ;
y a pas de limite
j'espere pour toi qu'il y avait une autre contrainte comme "max 200 char par ligne"
sinon ca peut faire mal aux yeux a lire
toto=function(n){var name=n;this.getName=function(){return name;};this.setName=function(value){name=value;};this.name=function(){return this.getName();};};a=new toto("hello");trace(a.getName());a.setName("bonjour");trace(a.getName());
T'inquietes, ils avaient pense a ca :). Les regles specifiaient:
1) le nombre de ligne est compte apres passage par l'autoformat. Ca rend impossible d'avoir deux statements separes par un point-virgule sur la meme ligne, a moins d'utiliser le bug dont je parlais plus haut (mais c'est de la triche ;))
2) un maximum de 30 declarations/assignments par lignes, pour limiter l'usage de la virgule.
humm ca aurait pas ete plu simple qu'ils limitent juste la taille Ko du SWF,
genre comme les demo 5Ko, tu mets tout ce que tu veux dedans mais la limite max c est 5Ko
oui moi je préfère ce genre d'exercice de style
limiter le poid du swf est une très bonne idée de concours 
facile, tu fais un loadMovie() pour charger le contenu...

lolol why not ?
mais une question me viens à l'esprit : raccourcir le nb de ligne de code ca veut pas dire optimiser... Quand je dis optimiser j'entends par la est-ce plus rapide pour l'ordi de lire un
(cond) ? action() : sinon();ou unif (cond){
action();
}
else
{
sinon();
}
M'est avis que la rapidité n'est pas visible si tu as qq if qui trainent par la mais bon pour une 100aine ca peut etre assez intéressant lol ^^ mais bon la c'est plus le code qu'il faut optimiser c'est l'algorithme
@++
oui en effet, l'optimisation ici n'est pas la même donc forcément on parle d'autre chose
Mais est-ce qu'il y a des moyens en flash de faire du benchmark?!??!?! Vu que ça risque d'être dur sinon de faire de l'optimisation de code.
salut
pour tester moi j'aime bien AS2Unit .
A+
euh faut pas confondre les tests...
as2unit --> permet de definir des class de tests pour verifier si une class a le comportement voulu
faire du benchmark ou tester la rapidité ca se fait avec un profiler pas avec un framework xUnit
Sa me fait rire vos truc on dirait des gas qui découvre les différentes syntaxes possible d'un langage ...
)
O tien la virgule .. o tient ya plusieur constructeur .... fo pas oublier qu'au départ le principe d'économisation de lignes et directement en liaison avec l'optimisation ...
//l'affection renvoyant la valeur affecté permet une initialisation en ligneJe ne sais pas encore comment le compilo traite ça en AS2 étant donné que le code est retranscrit en AS1, mais il faut savoir qu'en C++ par exemple, pour la version1 il faut aller chercher en mémoire a chaque fois la valeur de type 'int' 5 stokée a un endroit différent en mémoire comme attribut constant . Le fait de le mettre en ligne permet donc dans ce cas d'éviter 2 accés en mémoire... Benchez tout ça en AS et vous verrez bien aussi que la deuxième version est plus rapide... Dans le cas présent on ne peut pas dire que la lisibilité est entravée. Par contre la lisibilité en prend un coup quand on imbrique des conditionnelle de type (condition?instructionIfTrue :(condition?instructionIfFalse), cependant le but du code est surtout d'effectuer des opération qui utilisent le moins possible de CPU de mémoire et d'accès mémoire. C'est cette même logique qui insite à mettre des sous routines assembleur pour effectuer des action critiques ou des calcul bas niveaux par exemple pour des opération se répétant 200000 fois (calcul d'images, opération de tri, etc... ci dessous : deux versions d'une fonction qui effectue les même chose...(enfin si je me suis pas planté) Version 1 : optimisé et illisible... Version 2 : déclaration d'une variable en plus, et au pire une affection en plus que dans la version 1 ; le code est aussi plus long... (je ne parle pas des accès en mémoire en plus, je ne sais pas comment ça marchevar n:Number, l:Number, p:Number;
//Version1
n=5;
l=5;
p=5;
//Version2
n=l=p=5;
// Version 2function correctOverrideCursor1() : Number
{
return (_nIndex<0)? ((_nIndex==-1)? 0 : _nIndex = 0) : (_nIndex >= _nLength)? (_nIndex = _nLength-1) : _nIndex;
}
// Version 2
function correctOverrideCursor2() : Number
{
var nRetour:Number;
if(_nIndex<0)
if(_nIndex==-1)
nRetour = 0;
else
nRetour =_nIndex = 0;
else
if(_nIndex >= _nLength)
nRetour = _nIndex = _nLength-1;
else
nRetour = _nIndex;
return nRetour;
}
Si cette fonction doit etre appélée 30000 fois mieux vaut utiliser la permière version ...
Personnellement je prend toujours le code optimisé et je met l'équivalent lisible en dessous en commentaire.
A plus les foufous
a zut ya eu un problem d'interprétation ... le > > est en fait un supérieur....
Pour savoir pour la prochaine fois ... faut mettre quoi pour que ça passe ? un antislash ? heinG ?
Ravi de t'avoir fait passer un bon moment !
Il n'y a pas que des experts comme toi qui passent sur ce blog, qui se veut aussi un blog de vulgarisation pour ceux qui ne possèdent pas tes immeeeenses connaisances en la matière ! 
Concernant le >, c'est tout simplement un bug : je vais le rectifier !
++ ^^
Mais non oOOo simplement que certain commentaires étaient un peu une découverte des fonctionnalités de base et "pas si extraordinaire que ça"
de flash ... Un peu comme si on faisait partager a toute une assistance que ya de la pomme dans une tarte a la pomme... 
Pi chui pas comme ça !! Sa se voulait pas être méchant du tout ! C'est simplement le coup de liguorien sur l'initialisation d'un Array qui m'a fait sourire... le coup du push() alors qu'il est pas noobnoob...
Et pi dixit il a pas tort le monsieur
jdi plus rien promis...je referais pu
++@
(pi au fait je viens de m'en rendre compte ya eu aussi un pb avec le inférieur, javais po vu)
Mouarf, ca m'a aussi surpris du sieur liguorien, mais pourquoi pas ?
En tout cas, moi par exemple, bien que connaissant la virgule, ca m'a vachement surpris, car je n'avais pas pensé à cette utilisation la (pour autre chose que des variables) !
Comme pour l'utilisation de la déférence à outrance que tout le monde ne pratique pas forcément : (new MaClasse).maMethode().monAutreMethode().encoreUneMethode(), etc... Des pratiques qui utilisent les fonctionnalités "de base" comme tu le dis, mais qui ne sont pas forcément utilisées tous les jours (et pas forcément conseillées d'ailleurs)
Sinon pour le inférieur, oui c'est un problème de décodage des caractères HTML !
++ ^^
yan >> Mais non oOOo simplement que certain commentaires étaient un peu une découverte des fonctionnalités de base et "pas si extraordinaire que ça"
si tu lis bien le titre du post, sa dit "Economiser des lignes de code en ActionScript" et non pas "découverte extraordinaire en ActionScript"
Petit rappel en passant : l'affecttion est évaluée de droite a gauche tandis que la virgule de gauche a droite....
pchti Exemple:
function tutu1() : Number{
return (nIndex<0)? ( <strong>nIndex = -1,0 </strong>) : ( (nIndex >= nLength)?(nIndex = nLength-1) : nIndex);
}
Ici si nIndex<0 alors la fonction retourne 0 (mais nIndex = -1)
je vous salue bien bas et en post incrémentation s'il vous plait ;p
a++
Salut à tous,
Je cherche l'algorithme de pacman ?
Es que quelqun pourait m'éclairssir ?
Merci.
Charlouille
Hola alguien de ustdes me podría evnviar el codigo para crear el juego del pacman en action scrip, por favor me urge,
SVP comment aller a une certaine de ligne de code.
(l'equivalent de goto en c et c++)
Fil des commentaires de ce billet