1

次の敵クラスを使用していますが、敵はステージの中心に向かって正確な角度で来ていません。では、コードをより正確に機能させるには、コードにどのような変更を加える必要がありますか?

{
import flash.display.MovieClip;
import flash.events.*;
import flash.display.Stage;

public class Enemy1 extends MovieClip
{
    private var BG:MovieClip;
    private var speed:Number = 0.5;

    public function Enemy1(BG:MovieClip) : void
    {
        var RandomX:Array = new Array(100,200,300,400,800,900,1000,1100);
        var RandomY:Array = new Array(100,200,300,600,700,800);
        var r:int = (Math.random() * 8);
        var s:int = (Math.random() * 6);

        x = RandomX[r];
        y = RandomY[s];

        this.BG = BG;

        addEventListener(Event.ENTER_FRAME, moveEnemy); //false, 0, true);.
    }
    private function moveEnemy(e:Event):void
    {
        if (this.x > 660)
        {
            this.x -=  speed;
            this.rotation = 180;
        }

        if (this.x < 540)
        {
            this.x +=  speed;
            this.rotation = 0;
        }

        if (this.y > 510)
        {
            this.y -=  speed;
            this.rotation = 270;
        }

        if (this.y < 390)
        {
            this.y +=  speed;
            this.rotation = 90;
        }

        if (this.x > 660 && this.y > 510)
        {
            this.x -=  speed;
            this.y -=  speed;
            this.rotation = 225;
        }

        if (this.x < 540 && this.y < 390)
        {
            this.x +=  speed;
            this.y +=  speed;
            this.rotation = 45;
        }

        if (this.x < 540 && this.y > 510)
        {
            this.x +=  speed;
            this.y -=  speed;
            this.rotation = 315;
        }

        if (this.x > 660 && this.y < 390)
        {
            this.x -=  speed;
            this.y +=  speed;
            this.rotation = 135;
        }
    }

}
4

2 に答える 2

3

Vesper が指摘しているように、条件をハードコーディングするのではなく、atan2 を使用して角度を取得することが問題です。また、敵の速度を管理する必要があります。敵ごとに 1 つ使用するよりも、中央の ENTER_FRAME ループを使用する方が効率的かもしれません。

コメント付きの例を次に示します。

package  {

    import flash.display.*;
    import flash.events.*;
    import flash.geom.*;

    public class Enemy extends Sprite{

        public static const RAD_TO_DEG:Number = 57.2957795;
        public static const RX:Array = [100,200,300,400,800,900,1000,1100];
        public static const RY:Array = [100,200,300,600,700,800];

        private var tx:Number;//target X
        private var ty:Number;//target Y
        private var size:Number = 20;
        private var ease:Number = .05;

        public function Enemy() {
            addEventListener(Event.ADDED_TO_STAGE,init);
        }
        private function init(e:Event):void{
            //position
            x = RX[(int)(Math.random() * RX.length)];
            y = RY[(int)(Math.random() * RY.length)];
            //render
            graphics.lineStyle(7,Math.random() * 0xFF6600);
            graphics.lineTo(-size,0);
            graphics.moveTo(-size*.5,-size*.5);
            graphics.lineTo(-size,0);
            graphics.moveTo(-size*.5,size*.5);
            graphics.lineTo(-size,0);
        }
        public function seek(ax:Number = NaN,ay:Number = NaN):void{
            if(ax) tx = ax;
            if(ay) ty = ay;
            //vector math stuff - direction to 
            var dx:Number = x-tx;//difference vector x component
            var dy:Number = y-ty;//difference vector x component
            //update position
            x -= dx * ease;
            y -= dy * ease;
            //and rotation based on direction (using atan2 then converting radians to degrees)
            rotation = Math.atan2(dy,dx) * RAD_TO_DEG;
        }

    }

}

および基本的なテスト ドキュメント クラス:

package  {

    import flash.display.*;
    import flash.events.*;

    public class EnemyTester extends Sprite{

        private var cenemies:Vector.<Enemy> = new Vector.<Enemy>();//central enemies
        private var menemies:Vector.<Enemy> = new Vector.<Enemy>();//mouse enemies

        public function EnemyTester() {
            init();
        }
        private function init():void{
            for(var i:int = 0; i < 30; i++){
                cenemies[i] = addChild(new Enemy) as Enemy;
                cenemies[i].seek(stage.stageWidth * .5, stage.stageHeight * .5);
                menemies[i] = addChild(new Enemy) as Enemy;
            }
            addEventListener(Event.ENTER_FRAME,update,false,0,true);
        }
        private function update (e:Event):void{
            for(var i:int = 0; i < 30; i++){
                cenemies[i].seek();
                menemies[i].seek(mouseX,mouseY);
            }
        }



    }

}

明らかに、アートワークがある場合は、アートワークの回転を少し調整して、正しく見えるようにする必要があります。

より高度な敵 AI については、Steering Behaviorsを参照してください。Justin Windle のような as3 ポートがあります。Keith Peter の優れた Actionscript 3.0 Animationでも取り上げられています (コードのダウンロードが可能) 。

于 2013-03-04T12:38:51.790 に答える
0
this.rotation=Math.atan2((stage.stageHeight>>1)-this.y,(stage.stageWidth>>1)-this.x)*180/Math.PI;

(x1,y1) から (x2,y2) までの角度が必要な場合は、 を使用しますMath.atan2(y2-y1,x2-x1)。結果はラジアンで表示されますが、rotationプロパティは度を必要とします。このためには、180 を掛けて PI で割ります。それで全部です。

于 2013-03-04T12:02:51.380 に答える