Balles rebondisantes ... @author Yukulélé Yukulele forked:1favorite:0lines:186license : All rights reserved modified : 2009-04-22 08:20:54 Embed Tweet package { import flash.display.Sprite; import flash.display.Stage; import flash.display.StageAlign; import flash.display.StageScaleMode; import flash.events.Event; import flash.events.KeyboardEvent; import flash.events.MouseEvent; import flash.utils.getTimer; /** * ... * @author Yukulélé */ public class Main extends Sprite { public function Main():void { if (stage) init(); else addEventListener(Event.ADDED_TO_STAGE, init); } private function init(e:Event = null):void { stage.align = StageAlign.TOP_LEFT; stage.scaleMode = StageScaleMode.NO_SCALE; removeEventListener(Event.ADDED_TO_STAGE, init); stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseDown); stage.addEventListener(MouseEvent.MOUSE_UP, creeBalle); stage.addEventListener(KeyboardEvent.KEY_DOWN, creeBalle2); stage.addEventListener(Event.RESIZE, resize); resize(); } private function resize(e:Event = null):void { Balle.setStage(stage); } private var posX:Number=0,posY:Number=0,vitX:Number,vitY:Number,temps:int=0,tempsDeb:int=0; private function mouseDown(e:MouseEvent):void { vitX=e.stageX-posX; vitY=e.stageY-posY; posX=e.stageX; posY=e.stageY; temps=getTimer()-tempsDeb; tempsDeb=getTimer(); } private function creeBalle(e:MouseEvent):void { temps=Math.max(temps,getTimer()-tempsDeb); addChild(new Balle(e.stageX,e.stageY,10*vitX/temps,10*vitY/temps)); } private function creeBalle2(e:KeyboardEvent):void { for(var i:int=0; i<10;i++) addChild(new Balle(stage.stageWidth*Math.random(), stage.stageHeight*Math.random(),100*(Math.random()-.5),100*(Math.random()-.5))); } } } import flash.display.Shape import flash.events.TimerEvent; import flash.text.TextField; import flash.text.TextFieldAutoSize; import flash.utils.Timer; import flash.display.Stage; class Balle extends Shape { public static const RAYON:Number = 9.23; public static const IRMUR:Number = .95; public static const IRBALLE:Number = .99; private static var tableau:Vector.<Balle> = new Vector.<Balle>; private static var timer:Timer = creerTimerBalles(); private static var limiteGauche:Number=RAYON; private static var limiteDroite:Number; private static var limiteHaut:Number=RAYON; private static var limiteBas:Number; private static var texte:TextField=new TextField; private static var nbrCol:int=0; private var vitX:Number = 0; private var vitY:Number = 0; private var vit:Number = 0; private var couleur:uint=0xffffff*Math.random(); function Balle(x:Number,y:Number,vitX:Number=0,vitY:Number=0) { this.x = x; this.y = y; this.vitX = vitX; this.vitY = vitY; this.majVit(); this.dessine(); tableau.push(this); texte.text="nbrBalle:"+tableau.length } private function dessine():void { graphics.clear(); graphics.beginFill(couleur); graphics.drawCircle(0, 0, RAYON); } private function majVit():void { vit=Math.sqrt(vitX*vitX+vitY*vitY); } private function majBalle():void { vitY+=.3; vitX*=.999; vitY*=.999; x += vitX/4; y += vitY/4; /* dessine(); graphics.lineStyle(vit*.1,0,vit*.05-.01); graphics.moveTo(0,0); graphics.lineTo(-vitX*2,-vitY*2); */ if (y >= limiteBas && vitY>0) { y = limiteBas; vitY *= -1*IRMUR*IRBALLE; vitX *= IRMUR*IRBALLE; } /*if (y <= limiteHaut && vitY<0) { y = limiteHaut; vitY *= -1*IRMUR*IRBALLE; vitX *= IRMUR*IRBALLE; }*/ if (x <= limiteGauche && vitX<0) { x = limiteGauche; vitX *= -1*IRMUR*IRBALLE; vitY *= IRMUR*IRBALLE; } if (x >= limiteDroite && vitX>0) { x = limiteDroite; vitX *= -1*IRMUR*IRBALLE; vitY *= IRMUR*IRBALLE; } } private static function creerTimerBalles():Timer { var timer:Timer = new Timer(5); timer.addEventListener(TimerEvent.TIMER,timerBalles); timer.start(); return timer; } private static var m:int = -1; private static function timerBalles(e:TimerEvent):void { var vitTot:Number=0; var i:int, j:int, n:int = 0, col:int = 0; for (i = 0; i < tableau.length; i++) { var b1:Balle = tableau[i]; for (j = i+1; j < tableau.length; j++) { n++; var b2:Balle = tableau[j]; var dist:Number = Math.sqrt(Math.pow((b1.x - b2.x), 2) + Math.pow((b1.y - b2.y), 2)); if (dist < RAYON * 2) { col++; // Calcul de la collision entre 2 boules // de même masse et de rayon r en 2D (ex: boules de billard) // Les boules sont positionnées au point de contact // (m.x,m.y) = centre de la boule m (repère de l'image) // (m.vx,m.vy) = vitesse de la boule m avant le choc (repère de l'image) // Calcul de la base orthonormée (n,g) // n est perpendiculaire au plan de collision, g est tangent var nx:Number = (b2.x - b1.x)/(dist); var ny:Number = (b2.y - b1.y)/(dist); var gx:Number = -ny; var gy:Number = nx; // Calcul des vitesses dans cette base var v1n:Number = nx*b1.vitX + ny*b1.vitY; var v1g:Number = gx*b1.vitX + gy*b1.vitY; var v2n:Number = nx*b2.vitX + ny*b2.vitY; var v2g:Number = gx * b2.vitX + gy * b2.vitY; if (v1n-v2n>0) { nbrCol++; //b1.dessine(); //b2.dessine(); // Permute les coordonnées n et conserve la vitesse tangentielle // Exécute la transformation inverse (base orthonormée => matrice transposée) b1.vitX = (nx*v2n + gx*v1g)*IRBALLE*IRBALLE; b1.vitY = (ny*v2n + gy*v1g)*IRBALLE*IRBALLE; b2.vitX = (nx*v1n + gx*v2g)*IRBALLE*IRBALLE; b2.vitY = (ny * v1n + gy * v2g) * IRBALLE * IRBALLE; b1.vitY-=.2*(RAYON*2-dist); } } } } for (i = 0; i < tableau.length; i++) { tableau[i].majBalle(); tableau[i].majVit(); vitTot+=tableau[i].vit; } if (m != tableau.length || col > 0) trace(i, j, n, col); m = tableau.length; //texte.text="nbrBalle:"+tableau.length+"\ncol:"+nbrCol+"\nvitTot:"+vitTot; //texte.autoSize=TextFieldAutoSize.LEFT; tableau.sort(function(b1:Balle,b2:Balle):Number{return b1.y-b2.y}); } public static function setStage(stage:Stage):void { limiteDroite=stage.stageWidth-RAYON; limiteBas=stage.stageHeight-RAYON; stage.addChild(texte); } } Code Fullscreen Preview Fullscreen ball collision stage TimerEvent.ADDED_TO_STAGE TimerEvent.RESIZE Math.pow Math.sqrt length sort addChild align scaleMode start TimerEvent Math.max trace removeEventListener addEventListener TimerEvent.TIMER push Timer stageWidth sort new page view favorite forked pv719 Balles rebondisantes 2 Yukulele forked:0 favorite:0lines:230 (diff:122) tag: ball collision