Actionscript 3 AS3中的球反弹问题

Actionscript 3 AS3中的球反弹问题,actionscript-3,trigonometry,bounce,Actionscript 3,Trigonometry,Bounce,[编辑] 我真的很笨,现在一切都好了。 所以忘掉这个愚蠢的问题吧 主剪辑的旋转是一个很大的错误 我改变了这一点,添加了一个名为_rota的变量,其中包含getter和setter 我不必旋转剪辑,只需在其中放置另一个精灵,这样我就可以使用一个简单的函数将子精灵放置在正确的方向上。 所以我避免了所有这些循环 我错了 我刚刚添加了一个具有主精灵旋转的精灵。 更改主精灵的旋转是导致此问题的原因。。。 所以,谢谢你,忘掉这个不清楚的问题!!!:) 我正在更改剪辑的旋转属性,因此它很有用 现在我有一个很好

[编辑]

我真的很笨,现在一切都好了。 所以忘掉这个愚蠢的问题吧

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

我改变了这一点,添加了一个名为_rota的变量,其中包含getter和setter

我不必旋转剪辑,只需在其中放置另一个精灵,这样我就可以使用一个简单的函数将子精灵放置在正确的方向上。 所以我避免了所有这些循环

我错了

我刚刚添加了一个具有主精灵旋转的精灵。 更改主精灵的旋转是导致此问题的原因。。。 所以,谢谢你,忘掉这个不清楚的问题!!!:)

我正在更改剪辑的旋转属性,因此它很有用 现在我有一个很好的结果。 解决了

再次抱歉

正如你所看到的,粒子现在被设置在正确的方向,我没有更多的命中问题

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


[/edit]

我看到的第一件事是,您可能会两次修改
x
y
属性的位置

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

将您的
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);
}
私有变量h:int=1;
私有变量v:int=1;
公共功能移动球(e:事件):无效{
速度x=数学sin(deg2rad(旋转+90))*速度;
速度=数学cos(deg2rad(旋转+90))*速度;
如果(x+半径+(速度x*h)>this.loaderInfo.width | |(x+(速度x*h)-半径<0)){
h*=-1;
}
如果(y+半径+(speedy*v)>this.loaderInfo.height | |(y+(speedx*v)-半径<0)){
v*=-1;
}
这个.x+=(速度x*h);
这个.y+=(x v);
}

当球实例发生变化时,我需要将精灵设置在正确的方向上,它是“伪旋转”(我在这里避免使用最击功能)

我现在有两门课。。。 你认为我是在代码的光明面上搜索还是完全不清楚?;)

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

我的新班级:

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();
    }
}
}
这是我的新班级舞会:

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

}
}
package.com.display
{
/*此导入是可选的
如果要在不使用BongSound实例的情况下运行此类
注释调用var bSound的所有行
*/
//导入com.media.sound.BongSound;
导入flash.display.Graphics;
导入flash.display.Sprite;
导入flash.events.Event;
导入flash.events.MouseEvent;
导入flash.geom.Point;
导入flash.media.Sound;
公共类舞会延伸雪碧
{
私有变量半径:int;
私有变量旋转:数字;
私有变量颜色:int;
私有变量:图形;
私有变量g2:图形;
私有变量速度:数字;
私有var speedx:编号;
私家车:号码;
公共变量表:编号;
私人圈子:雪碧;
呈现的私有变量:布尔值=false;
公共变量暂停:布尔值=false;
私有常数0:uint=0;
//私人var bSound:BongSound;
/**
*球(位置:编号,位置:编号,半径:uint)
*此构造函数创建一个反弹球的实例
*posx和posy必须包含在定义的stageWidth和stageHeight的范围内!
*否则,球将被放置在舞台范围内。 */ 公共功能球(posx:Number,posy:Number,radius:uint) { //bSound=新的BongSound(); smallCircle=新精灵(); 这个.addChild(smallCircle); 这个。_半径=半径; 这个.x=posx; 这个.y=posy; _g=这是图形; _g2=小圆。图形; } 私有函数checkStageSize():void{ 如果(此.x+半径+速度x>=此.stage.stageWidth){ this.x=this.stage.stageWidth-this.width; } 如果(此.y+半径+速度>=此.stage.stageHeight){ this.y=this.stage.stageHeight-this.height; }
如果(这个.x-radius+speedx如果你在主类中将旋转设置为60,如下所示:b1.rotation=60;你会遇到同样的问题…哇,我完全忽略了你旋转它的事实。我会用一点解决方案来修改答案。现在一切都很好。对于那些重复的编辑,我很抱歉。代码清晰、高效且d跑得更快。这就是为什么我投票支持你的答案,即使它不能一眼解决我的问题。所以你不需要尝试寻找另一个答案。我错了…请原谅我。我希望“伪旋转”的含义在这种情况下有意义。(?如果你有时间,你能测试这两个类吗(库中没有任何元素)。请告诉我我看的方向是否正确,或者这是否仍然不清楚???非常感谢。这可能有助于理解我为什么在checkBounds()函数中使用Math.atan2,我希望。。
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;
    }

}
}