2016-05-07 14 views
-1

[Bearbeiten]Ball Bounce Problem in AS3

Ich war wirklich dumm, alles funktioniert jetzt gut. Also vergessen Sie diese Dummy-Frage!

Die Drehung des Hauptclips war ein großer Fehler.

Ich habe das geändert, indem ich eine Variable namens _rota mit Getter und Setter hinzugefügt.

Ich musste den Clip nicht drehen, sondern nur einen anderen Sprite darin platzieren, so dass ich den Sub-Sprite mit einer einfachen Funktion in die richtige Richtung platzieren kann. Also vermeide ich all diese Schleifen ...

Mein Fehler SRY.

Ich habe gerade einen Sprite hinzugefügt, der die Rotation des Main Sprite hat. Das Ändern der Rotation des Hauptsprites war der Grund dieses Problems ... Also, danke und vergiss diese unklare Frage !!! :)

private function drawLine():void{ 
     if(!clip){ 
      clip = new Sprite(); 
      addChild(clip); 
     } 
     var g:Graphics = clip.graphics; 
     g.clear(); 
     g.lineStyle(1,0xffffff,1); 
     g.beginFill(0xffffff,1); 
     g.drawCircle(Math.sin(rota)*this.width/4,Math.cos(rota)*this.height/4,3); 
     g.endFill(); 
    } 

Ich war die Änderung der Rotation Eigenschaft des Clips, so war es Nützlichkeit Jetzt habe ich ein ziemlich gutes Ergebnis. Gelöst ...

leider wieder ...

Wie Sie die Partikel nun in die richtige Richtung gesetzt sehen ein Ich habe nicht mehr hitTest Fragen ...

enter image description here

Partikel bewegen sich nun in die Richtung, die durch die weißen Punkte angezeigt wird.

[/ edit]

Antwort

0

Als ich ein Sprite in die richtige Richtung festlegen müssen, wenn der Ball Instanz es ist „Rotation Pseudo“ ändern (ich vermeide hier die hitTest Features) ...

Ich habe jetzt zwei Klassen ... Findest du, dass ich auf der hellen Seite des Codes suche oder ist es völlig unklar? ;)

Das ist nur ein Test, und ich habe seit ein paar Jahren keine Zeit mehr zum Codieren gebraucht. Also dieser Test ist nur einige Grundlagen über Trigonometrie zu revidieren ... Zögern Sie nicht, unhöflich zu sein, wenn ich falsch liege!

Meine neue Klasse Main:

package com 
{ 
import com.display.Ball; 

import flash.display.Graphics; 
import flash.display.MovieClip; 
import flash.display.Sprite; 
import flash.display.StageAlign; 
import flash.display.StageScaleMode; 
import flash.events.Event; 
import flash.events.MouseEvent; 
import flash.geom.Point; 

[SWF(width = "400", height = "300", frameRate = "60", backgroundColor = "#dddddd")] 
public class Main extends MovieClip 
{ 
    private var b1:Ball; 
    private var b2:Ball; 
    private var b3:Ball; 
    private var b4:Ball; 
    private var b5:Ball; 
    private var testClip:Sprite; 
    private const ANGLE_TOP_LEFT:int=135; 
    private const ANGLE_BOTTOM_LEFT:int=-135; 
    private const ANGLE_TOP_RIGHT:int=45; 
    private const ANGLE_BOTTOM_RIGHT:int=-45; 

    public function Main() 
    { 
     stage.align = StageAlign.TOP_LEFT; 
     stage.scaleMode = StageScaleMode.NO_SCALE; 
     trace("stageSize = " + getStageSize() + ", fps = " + stage.frameRate); 
     drawlineGuides(); 
     addBalls(); 
     stage.addEventListener(Event.RESIZE,onStageResize); 
    } 
    private function addBalls():void{ 
     b1 = new Ball(500/2,250/2,10); 
     addChild(b1); 
     b1.color = 0x6666cc; 
     b1.rota = 135; 
     b1.drawBall(); 
     b1.move(5); 

     b2 = new Ball(100,100,10); 
     addChild(b2); 
     b2.color = 0xff9900; 
     b2.rota = -110; 
     b2.drawBall(); 
     b2.move(4); 

     b3 = new Ball(50,80,10); 
     addChild(b3); 
     b3.color = 0xff0000; 
     b3.rota = 60; 
     b3.drawBall(); 
     b3.move(3); 

     b4 = new Ball(75,20,10); 
     addChild(b4); 
     b4.color = 0x00aa00; 
     b4.rota = 10; 
     b4.drawBall(); 
     b4.move(4); 

     b5 = new Ball(125,130,10); 
     addChild(b5); 
     b5.color = 0x8457a2; 
     b5.rota = -45; 
     b5.drawBall(); 
     b5.move(4); 

     stage.addEventListener(MouseEvent.MOUSE_DOWN,b1.pauseResume); 
     stage.addEventListener(MouseEvent.MOUSE_DOWN,b2.pauseResume); 
     stage.addEventListener(MouseEvent.MOUSE_DOWN,b3.pauseResume); 
     stage.addEventListener(MouseEvent.MOUSE_DOWN,b4.pauseResume); 
     stage.addEventListener(MouseEvent.MOUSE_DOWN,b5.pauseResume); 
    } 
    private function rotate(e:Event):void{ 
     testClip.rotation = b2.rotation-45; 
    } 
    private function getStageSize():Point{ 
     var p:Point= new Point(stage.stageWidth,stage.stageHeight); 
     return p; 
    } 
    private function drawlineGuides():void{ 
     var g:Graphics = this.graphics; 
     g.clear(); 
     g.lineStyle(1,0x000000,1); 
     g.moveTo(0,stage.stageHeight/2); 
     g.lineTo(stage.stageWidth,stage.stageHeight/2); 
     g.moveTo(stage.stageWidth/2,0); 
     g.lineTo(stage.stageWidth/2,stage.stageHeight); 
    } 
    private function onStageResize(e:Event):void{ 
     drawlineGuides(); 
    } 
} 
} 

Und hier ist meine neue Klasse Ball:

package com.display 
{ 
/* this import is optionnal 
if you want to run this class without the BongSound instance 
comment all lines where the var bSound is called 
*/ 
//import com.media.sound.BongSound; 

import flash.display.Graphics; 
import flash.display.Sprite; 
import flash.events.Event; 
import flash.events.MouseEvent; 
import flash.geom.Point; 
import flash.media.Sound; 

public class Ball extends Sprite 
{ 
    private var _radius:int; 
    private var _rotation:Number; 
    private var _color:int; 
    private var _g:Graphics; 
    private var _g2:Graphics; 
    private var _speed:Number; 
    private var speedx:Number; 
    private var speedy:Number; 
    public var rota:Number; 
    private var smallCircle:Sprite; 
    private var rendered:Boolean = false; 
    public var paused:Boolean = false; 
    private const ZERO:uint = 0; 
    //private var bSound:BongSound; 
    /** 
    * Ball(posx:Number,posy:Number,radius:uint)<br/> 
    * this constructor create an instance of a bouncing ball<br/> 
    * the posx and posy must be included in the range of the defined stageWidth and stageHeight!<br/> 
    * Otherwise, the ball will be placed in the stage range. 
    */ 
    public function Ball(posx:Number,posy:Number,radius:uint) 
    { 
     //bSound = new BongSound(); 
     smallCircle = new Sprite(); 
     this.addChild(smallCircle); 
     this._radius = radius; 
     this.x = posx; 
     this.y = posy; 
     _g = this.graphics; 
     _g2 = smallCircle.graphics; 
    } 
    private function checkStageSize():void{ 
     if(this.x + radius + speedx >= this.stage.stageWidth){ 
      this.x = this.stage.stageWidth - this.width; 
     } 
     if(this.y + radius + speedy >= this.stage.stageHeight){ 
      this.y = this.stage.stageHeight - this.height; 
     } 
     if(this.x - radius + speedx <= ZERO){ 
      this.x = this.width; 
     } 
     if(this.y - radius + speedy <= ZERO){ 
      this.y = this.height; 
     } 
    } 
    public function get speed():Number 
    { 
     return _speed; 
    } 
    public function set speed(value:Number):void 
    { 
     _speed = value; 
    } 
    public function get color():int 
    { 
     return _color; 
    } 
    public function set color(value:int):void 
    { 
     _color = value; 
    } 
    public function get radius():int 
    { 
     return _radius; 
    } 
    public function set radius(value:int):void 
    { 
     _radius = value; 
    } 
    /** 
    * drawBall()<br/> 
    * this function draws the main Ball Object 
    */ 
    public function drawBall():void 
    { 
     _g.clear(); 
     _g.lineStyle(1,0x666666,1); 
     _g.beginFill(_color,1); 
     _g.drawCircle(0,0,this._radius); 
     _g.endFill(); 
     _g.lineStyle(1,0x666666,1); 
     _g.beginFill(0xffffff,1); 
     _g.endFill(); 
    } 
    /** 
    * drawPoint()<br/> 
    * this function draws the Point Object wich is placed in the direction/rotation of the main Ball instance. 
    */ 
    public function drawPoint():void{ 
     _g2.clear(); 
     _g2.lineStyle(1,0x666666,1); 
     _g2.beginFill(0xffffff,1); 
     _g2.drawCircle(ZERO, ZERO, this._radius/2); 
     smallCircle.x = Math.sin(deg2rad(rota+90))*this.radius/2; 
     smallCircle.y = Math.cos(deg2rad(rota+90))*this.radius/2; 
     _g2.endFill(); 
    } 
    /** 
    * move(speed:Number):void<br/> 
    * this function set the speed and makes the Ball move.<br/> 
    * The displace function is called when an ENTER_FRAME event is triggered. 
    */ 
    public function move(speed:Number):void{ 
     this.speed = speed; 
     this.addEventListener(Event.ENTER_FRAME,displace); 
    } 
    /** 
    * getRota():Number<br/> 
    * this function returns the rotation of the Ball instance.<br/> 
    * the rotation is returned in degrees. 
    */ 
    public function getRota():Number{ 
     return rad2deg(Math.atan2(speedy,speedx)); 
    } 
    /** 
    * pauseResume(e:MouseEvent):void 
    * Pause or resume movement. 
    */ 
    public function pauseResume(e:MouseEvent):void{ 
     switch(paused){ 
      case false: 
       this.removeEventListener(Event.ENTER_FRAME,displace); 
       paused = true; 
       break; 
      case true: 
       this.addEventListener(Event.ENTER_FRAME,displace); 
       paused = false; 
       break; 
     } 
    } 
    /** 
    * checkBounds():void<br/> 
    * <p> 
    * this function plays a Sound when the Ball instance hit the bounds.<br/> 
    * the rota variable is updated (even if the rotation of the Ball instance don't change).<br/> 
    * If the stage is resized, a call to checkStageSize() set the positions x & y in the bounds of the Stage. 
    * </p> 
    * @see checkStageSize() 
    */ 
    private function checkBounds():void{ 
     if(this.x + radius + speedx >= this.stage.stageWidth){ 
      //bSound.play(); 
      rota = rad2deg(Math.atan2(-speedy,-speedx)); 
     } 
     if(this.y + radius + speedy >= this.stage.stageHeight){ 
      //bSound.play(); 
      rota = rad2deg(Math.atan2(speedy,speedx)); 
     } 
     if(this.x - radius + speedx <= ZERO){ 
      //bSound.play(); 
      rota = rad2deg(Math.atan2(-speedy,-speedx)); 
     } 
     if(this.y - radius + speedy <= ZERO){ 
      //bSound.play(); 
      rota = rad2deg(Math.atan2(speedy,speedx)); 
     } 
     checkStageSize(); 
    } 
    /** 
    * <p> 
    * displace(e:Event):void 
    * displace the ball and calls drawPoint to place the sub-Sprite depending of the "rotation" of the Ball instance.</p> 
    * @see #drawPoint() 
    * @see #checkBounds() 
    */ 
    private function displace(e:Event):void{ 
     checkBounds(); 
     speedx = Math.sin(deg2rad(rota+90))*speed; 
     speedy = Math.cos(deg2rad(rota+90))*speed; 
     this.x += speedx; 
     this.y += speedy; 
     drawPoint(); 
    } 
    public function deg2rad(value:Number):Number{ 
     return value/180*Math.PI; 
    } 
    public function rad2deg(value:Number):Number{ 
     return value*180/Math.PI; 
    } 

} 
} 

Printscreens: enter image description here enter image description here

Es ist nun möglich, die Bewegungen auch weiterhin Wenn die Größe der Bühne geändert wird, werden die Probleme vermieden, die ich in der Vergangenheit hatte ...

+0

Ich hoffe, dass die Bedeutung der "Pseudo-Rotation" in diesem Zusammenhang sinnvoll ist. :(??? Wenn Sie etwas Zeit haben, könnten Sie diese 2 Klassen testen (es gibt kein Element in der Bibliothek). Können Sie mir bitte sagen, ob ich in die richtige Richtung schaue oder ob das unklar bleibt ??? Vielen Dank – tatactic

+0

Dies könnte helfen, zu verstehen, warum ich das Math.atan2 in der Funktion checkBounds() benutze, hoffe ich .. – tatactic

1

Das erste, was mich herausspringt ist Sie möglicherweise die Position beider x und y Eigenschaften zweimal ändern.

Wenn Sie die Logik einmal ausführen und Ihre Direktionalität speichern, sollten Sie in der Lage sein, die Position Ihres Balls auf einmal zu aktualisieren.

Ersetzen Sie Ihre moveBall Funktion mit dem folgenden ...

private var h:int = 1; 
private var v:int = 1; 
public function moveBall(e:Event):void { 
    speedx = Math.sin(deg2rad(rotation+90))*speed; 
    speedy = Math.cos(deg2rad(rotation+90))*speed; 

    if (x + radius + (speedx * h) > this.loaderInfo.width || (x + (speedx * h) - radius < 0)) { 
     h *= -1; 
    } 

    if (y + radius + (speedy * v) > this.loaderInfo.height || (y + (speedx * v) - radius < 0)) { 
     v *= -1; 
    } 

    this.x += (speedx * h); 
    this.y += (speedy * v); 
} 
+0

Wenn Sie die Rotation in der Main-Klasse auf 60 setzen: b1.rotation = 60; Du bekommst das gleiche Problem ... – tatactic

+0

Wow, ich habe total übersehen, dass du es gedreht hast. Ich werde die Antwort mit einer Lösung in einem Stück überarbeiten. – Atriace

+0

Alles funktioniert jetzt gut. Es tut mir leid wegen dieser wiederholten Änderungen. Die Dinge sind einfach, wenn der Code klar, effizient und schneller ist. Das ist der Grund, warum ich deine Antwort gewählt habe, auch wenn es mein Problem nicht auf einen Blick gelöst hat. Sie müssen also nicht versuchen, eine andere Antwort zu finden. Ich habe mich geirrt ... Verzeih mir das. – tatactic