2

所以我逐渐痛苦地从 Processing 转向 Flash,希望能够为更广泛的受众开发游戏。终于,我得到了一个在 Flash 中制作的工作应用程序,它只允许用户单击以创建随后被鼠标吸引的块。我在处理中也做了同样的事情,只是为了比较速度。但是,当我运行 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 );
}

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

块.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

一个问题是,在每次执行 .run 时,您都会重新绘制精灵的图形框,但精灵不会随着时间的推移而改变。所以只在构造函数中绘制一次就足够了。

但是如果你因为某种原因不得不重绘每一帧呢也许随着时间的推移改变盒子的颜色?好吧,您忽略了清除旧图像...所以每一帧您只需向图形对象添加越来越多的矢量点。所以实际上,虽然你看起来只有一个黑色方块,但实际上几秒钟后你就有了数千个黑色方块的数据。您可以像这样清除图形对象...

this.graphics.clear();

作为微优化,您可以将 this.graphics 分配给局部变量...

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

我注意到的另一件事是,您似乎没有基于时间的运动,而是基于帧的运动。积木本身不知道已经过去了多少时间,所以它们会放慢速度。另一种方法是将它们的移动基于经过的时间,这将使它们以正确的“速度”移动,但应用程序会丢帧来执行此操作。

由于这是您要处理的框,因此您也可以使用 graphics.drawRect() 而不是逐行绘制框。

在我自己的测试中,选项 1 效果最好。如果您必须重绘,请确保执行 graphics.clear(),因为即使对于大量框,它也几乎同样有效。

编辑添加...

您的示例,在添加 .clear() 函数调用后执行得非常好。然而,我应该提醒您,JVM 肯定会比 Flash Player 具有更好的性能。这并不是说人们不能制作高性能的 Flash 应用程序,而是说 Flash Player 在处理 CPU 渲染时的性能上限远低于 Java。当然,如果你愿意生活在最前沿,你可以查看新的“Molehill”3D api,它们能够完成这样的事情......

Wii 上的 3D 游戏使用 molehill 移植到 Flash,运行速度为 60fps http://blog.theflashblog.com/?p=2593

于 2011-03-03T00:54:28.677 回答