2

そのため、より多くの視聴者に向けてゲームを開発することを願って、Processing から Flash に徐々に移行しています。ついに、ユーザーがクリックしてブロックを作成し、その後マウスに引き寄せられるようにする、Flash で動作するアプリケーションを作成しました。速度を比較するためだけに、Processing でもまったく同じものを作成しました。ただし、Flash バージョンを実行して約 15 ~ 20 個のブロックを追加すると、フレームレートが 5 ~ 10 FPS に低下します。処理バージョンでは、目立った速度低下なしで最大 60 を追加できます。どうしたの、フラッシュ?

各バージョンのソースへのリンク:

フラッシュ版

処理バージョン

以下は、あなたが魔法使いであり、コードを厳しく批判して動作するように指示するだけで役立つ場合に備えて、それぞれのソースです。

フラッシュ版:

ブロック.fla

import flash.events.Event;
import flash.display.MovieClip;

stage.addEventListener( Event.ENTER_FRAME, onenter );
stage.addEventListener( MouseEvent.MOUSE_DOWN, onclick );

var main = this;

var lastFrame:Number;

var Blocks:Array = new Array();

function onenter( e:Event ):void
{
    var time:Number = getTimer();
    for( var i = 0; i < Blocks.length; i++ )
    {
        Blocks[ i ].run();
    }
    FrameRate.text = String( Blocks.length ) + "\n" + String( 1000 / ( time - lastFrame ) );
    lastFrame = time;
}

function onclick( e:MouseEvent ):void
{
    var block1 = new Block( Blocks, main, mouseX, mouseY );
}

Block.as

package  {

    import flash.display.MovieClip;
    import flash.geom.Vector3D;

    public class Block extends MovieClip {

        var velocity:Vector3D = new Vector3D( 0, 0 );
        var position:Vector3D = new Vector3D( x, y );
        var acceleration:Vector3D = new Vector3D( 0, 0 );

        public function Block( Blocks:Array, This, x:Number, y:Number ) {
            Blocks.push( this );
            This.addChild( this );
            position.x = x;
            position.y = y;
        }

        public function run()
        {
            x = position.x;
            y = position.y;
            //position.incrementBy( velocity );
            position.x += velocity.x;
            position.y += velocity.y;
            acceleration.x = stage.mouseX - position.x;
            acceleration.y = stage.mouseY - position.y;
            acceleration.normalize();
            //velocity.incrementBy( acceleration );
            velocity.x += acceleration.x;
            velocity.y += acceleration.y;
            velocity.x *= 0.95;
            velocity.y *= 0.95;
            this.graphics.beginFill( 0 );
            this.graphics.moveTo( -10, -10 );
            this.graphics.lineTo( 10, -10 );
            this.graphics.lineTo( 10, 10 );
            this.graphics.lineTo( -10, 10 );
            this.graphics.lineTo( -10, -10 );
            this.graphics.endFill();
        }

    }

}

処理バージョン:

sketch_mar02b.pde

Block[] blocks = new Block[ 0 ];

void setup()
{
  frameRate( 60 );
  size( 550, 400 );
  textFont( createFont( "Verdana", 20 ) );
}

void draw()
{
  background( 255 );
  for( int i = 0; i < blocks.length; i++ )
  {
    blocks[ i ].run();
  }
  text( blocks.length + "\n" + frameRate, 0, 20 );
}

void mousePressed()
{
  new Block( mouseX, mouseY );
}

Block.pde

class Block
{
  PVector position = new PVector( 0, 0 );
  PVector velocity = new PVector( 0, 0 );
  PVector acceleration = new PVector( 0, 0 );
  Block( float x, float y )
  {
    position.set( x, y, 0 );
    blocks = ( Block[] ) append( blocks, this );
  }
  void run()
  {
    position.add( velocity );
    acceleration.set( mouseX - position.x, mouseY - position.y, 0 );
    acceleration.normalize();
    velocity.add( acceleration );
    velocity.mult( 0.95 );
    pushMatrix();
    translate( position.x, position.y );
    fill( 0 );
    rect( -10, -10, 20, 20 );
    popMatrix();
  }
}

助けてくれてありがとう!

4

1 に答える 1

2

1つの問題は、.runを実行するたびに、スプライトのグラフィックボックスを再描画しているのに、スプライトが時間の経過とともにまったく変化しないことです。したがって、コンストラクターで1回描画するだけで十分です。

しかし、何らかの理由ですべてのフレームを再描画する必要がある場合はどうなりますか?たぶん、時間の経過とともにボックスの色を変更しますか?さて、あなたは古い画像をクリアすることを怠っています...したがって、すべてのフレームは、グラフィックスオブジェクトにますます多くのベクトルポイントを追加するだけです。したがって、実際には、黒い四角が1つしかないように見えますが、実際には、ほんの数秒で数千の黒い四角に相当するデータが得られます。このようにグラフィックスオブジェクトをクリアすることができます...

this.graphics.clear();

マイクロ最適化として、this.graphicsをローカル変数に割り当てることができます...

var g:Graphics = this.graphics
g.moveTo(0); // and so on...

私が気付いたもう一つのことは、あなたは時間ベースの動きではなく、フレームベースの動きをしているように見えるということです。ブロック自体はどれくらいの時間が経過したかわからないので、速度が低下します。別の方法は、経過時間に基づいて移動することです。これにより、適切な「速度」で移動し続けますが、アプリはそれを行うためにフレームをドロップします。

これは扱っているボックスなので、ボックスを1行ずつ描画する代わりに、graphics.drawRect()を使用することもできます。

私自身のテストでは、オプション1が最適でした。再描画する必要がある場合は、必ずgraphics.clear()を実行してください。これは、多数のボックスでもほぼ同様に機能します。

追加するために編集...

あなたの例では、.clear()関数呼び出しを追加した後、非常にうまく機能します。ただし、JVMのパフォーマンスはFlashPlayerよりも確実に優れていることに注意してください。これは、人々が高性能のFlashアプリケーションを作成できないということではありませんが、CPUレンダリングを処理するときのFlashPlayerのパフォーマンスの上限はJavaよりもはるかに低いということです。もちろん、最先端に住むことをいとわないのであれば、このようなことができる新しい「Molehill」3DAPIをチェックすることができます...

モグラヒルを使用してFlashに移植されたWiiの3Dゲーム、60fpsで実行http://blog.theflashblog.com/?p=2593

于 2011-03-03T00:54:28.677 に答える