AS3中的球弹跳问题

时间:2016-05-07 12:48:44

标签: actionscript-3 trigonometry bounce

[编辑]

我真的很蠢,现在一切都很好。 所以忘记这个虚假的问题!

主剪辑的旋转是一个很大的错误。

我通过添加带有getter和setter的名为_rota的var来改变这一点。

我没有旋转剪辑但只是在其中放置另一个Sprite,所以我可以使用一个简单的函数将子Sprite放在正确的方向。 所以我避免所有这些循环...

我的错误SRY。

我刚刚添加了一个Sprite,它具有Main Sprite的旋转。 改变主Sprite的旋转是这个问题的原因...... 所以,谢谢你,忘了这个不明确的问题! :)

SELECT * FROM my_table WHERE my_date.year = 2014

我正在改变剪辑的旋转属性,所以它很有用 现在我有一个非常好的结果。 解决...

再次抱歉......

正如您所看到的那样,粒子现在设置在正确的方向上,我没有更多的hitTest问题......

enter image description here

粒子现在正朝着白点显示的方向移动。

[/编辑]

2 个答案:

答案 0 :(得分:1)

第一件事就是我可能会两次修改xy属性的位置。

如果您运行一次逻辑并存储您的方向性,那么您应该能够一次性更新球的位置。

moveBall功能替换为以下内容......

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);
}

答案 1 :(得分:0)

当Ball实例改变它的“伪旋转”时我需要在正确的方向上设置一个Sprite(我在这里避免使用hitTest功能)......

我现在有两节课...... 你在代码的光明面上搜索的东西还是完全不清楚? ;)

这只是一个测试,几年后我没有花时间编写代码。 所以这个测试只是为了修改一些关于三角学的基础知识...... 如果我错了,不要犹豫,粗鲁!

我的新课程主要:

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();
    }
}
}

这是我的新班级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

现在有可能继续行动,即使舞台调整大小,避免了过去的问题......