我试着遵循Lee的闪电战教程系列以及Rex Van der spuy的“闪光灯高级游戏设计”的技巧。
我是一个开发人员,致力于一个网上虚拟世界制造的闪光灯。我做了一个电话应用程序(类似于手机在大盗窃罪汽车游戏)。不管怎么说,当一个消息被发送时,我们想要播放这个疯狂的动画,一个信封在周围飞来飞去,在周围闪烁着火花。这是一个滞后(特别是在旧电脑),所以我认为这将是一个很好的机会使用闪电战。然而,闪电战动画的播放速度实际上比常规电影慢!这到底是怎么回事?闪电战只对移动设备更好,在计算机上更慢吗?也许我做错了什么。这是我的代码:
//这部分发生在电话IT初始化时
//**
//---------------- Blitting stuff ----------------------------------
// add this bitmap stage to the display list so we can see it
_bitmapStage = new BitmapData(550, 400, true, 0xD6D6D6);
_phoneItself.addChild(new Bitmap(_bitmapStage));
var _spritesheetClass:Class = getDefinitionByName("ESpritesheet_1") as Class;
_spritesheet = new _spritesheetClass() as BitmapData;
_envelopeBlit = new BlitSprite(_spritesheet, BlitConfig.envelopeAnimAry , _bitmapStage);
_envelopeBlit.x = -100;
_envelopeBlit.y = 0;
_envelopePlayTimer = new Timer(5, 0);
_envelopePlayTimer.addEventListener(TimerEvent.TIMER, onEnterTimerFrame);
_envelopeBlit.addEventListener("ENV_ANIM_DONE", onEnvAnimFinished);// a "BlitSprite“是我做的一个类。看起来是这样的:
package com.fs.util_j.blit_utils
{
import flash.display.BitmapData;
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.geom.Point;
import flash.geom.Rectangle;
public class BlitSprite extends EventDispatcher
{
private var _fullSpriteSheet:BitmapData;
private var _rects:Array;
private var _bitmapStage:BitmapData;
private var pos:Point = new Point ();
public var x:Number = 0;
public var y:Number = 0;
public var _animIndex:int =0,私有变量_count:int = 0;
public var animate:Boolean = true;
private var _whiteTransparent:BitmapData;
private var _envelopeAnimAry:Array;
private var _model:Object;
public function BlitSprite(fullSpriteSheet:BitmapData, envelopeAnimAry:Array, bitmapStage:BitmapData, model:Object = null)
{
_fullSpriteSheet = fullSpriteSheet;
_envelopeAnimAry = envelopeAnimAry;
_bitmapStage = bitmapStage;
_model= model;
init();
}
private function init():void
{
// _whiteTransparent = new BitmapData(100, 100, true, 0x80FFffFF);
this.addEventListener("ENV_ANIM_DONE", onEvnAnimDone);
}
protected function onEvnAnimDone(event:Event):void
{
}
public function render():void
{
// pos.x = x - _rects[_animIndex].width*.5;
// pos.y = y - _rects[_animIndex].width*.5;
// if (_count % 1 == 0 && animate == true)
// {
// trace("rendering");
if (_animIndex == (_envelopeAnimAry.length - 1) )
{
// _animIndex = 0;
dispatchEvent(new Event("ENV_ANIM_DONE", true));
animate = false;
// trace("!!!!animate over " + _model.animOver);
// if (_model != null)
// {
// _model.animOver = true;
// }
// trace("!!!!animate over " + _model.animOver);
}
else
{
_animIndex++;
}
pos.x = x + _envelopeAnimAry[_animIndex][1];
pos.y = y + _envelopeAnimAry[_animIndex][2];
_bitmapStage.copyPixels(_fullSpriteSheet, _envelopeAnimAry[_animIndex][0], pos, null, null, true);
}
}
}
// THIS PART HAPPENS WHEN PHONE'S SEND BUTTON IS CLICKED
_envelopeBlit.animate = true;
_envelopeBlit._animIndex = 0;
_darkSquare.visible = true;
_envelopePlayTimer.addEventListener(TimerEvent.TIMER, onEnterTimerFrame);
_envelopePlayTimer.start();它还使用BlitConfig,它存储有关TexturePacker所吐出的spritesheet的信息。
package com.fs.pack.phone.configuration
{
import flash.geom.Rectangle;
public final class BlitConfig
{
public static var _sending_message_real_20001:Rectangle = new Rectangle(300,1020,144,102);
public static var _sending_message_real_20002:Rectangle = new Rectangle(452,1012,144,102);
public static var _sending_message_real_20003:Rectangle = new Rectangle(852,852,146,102);
public static var _sending_message_real_20004:Rectangle = new Rectangle(2,1018,146,102);
public static var _sending_message_real_20005:Rectangle = new Rectangle(702,822,148,102);
.
.
.
public static var _sending_message_real_20139:Rectangle = new Rectangle(932,144,1,1);
public static var envelopeAnimAry:Array = [
// rectangle, x offset, y offset
[ _sending_message_real_20001, 184,155],
[ _sending_message_real_20002, 184,155],
[ _sending_message_real_20003, 183,155],
[ _sending_message_real_20004, 183,155],
.
.
.
[ _sending_message_real_20139, 0,0]
]
public function BlitConfig()
{
}
}
}发布于 2013-08-30 17:53:52
编辑:知道这不是移动的,我下面的答案是不相关的。不过,我会把它留在那里,以防将来有人在闪电战中遇到麻烦。
关于这个特定的问题,你每5ms运行一次计时器。首先,计时器准确的最低范围是>15 is,所以这永远不是一个可行的解决方案。对于任何与在舞台上显示时间有关的计时器,都不应该比单个帧做得更少。(1000/stage.framerate.~40 app的30 app应用程序)
对于闪电战,目标是减少计算和渲染。按照你现在设置的方式,看起来你每隔5毫秒就会闪动一次。这实际上是MovieClip渲染频率的8倍以上。你应该减少你的blit频率。只有当一个改变实际上已经超出了翻译的范围时,才能这样做。这样做的频率比这要高,其原因是速度太慢(同样,创建位图也很慢)。
通常,您不希望在AIR for Mobile应用程序中使用blit (我假设您是这样做的,因为您提到了正在初始化的电话)。我不确定使用其他/本机SDK是否可以这样做,但要避免在空气中使用。
本质上,这取决于闪电战是如何运作的。闪电战采取屏幕截图,并显示在舞台上,而不是实际的对象。总的来说,这是很棒的。这意味着您的显示对象,特别是渲染速度慢的向量,必须少得多地呈现。这是特别好的动画,因为一个对象倾向于重新呈现每一次它是以任何方式,但不是一个位图。
然而,在移动平台上,创建位图非常缓慢。我从来没有研究过SDK是如何创建位图的,但是它并没有高效地创建位图(它常常让我怀疑它是否做到了逐像素)。在台式机上,这通常是好的。有足够的CPU和大量的RAM来使这种情况迅速发生。然而,在手机上,这种奢侈目前并不存在。因此,当您创建和创建位图时,运行该进程需要一段时间。
这个问题在高分辨率屏幕上更加严重。我在今年1月至5月开发了一个应用程序,在GPU加速环境中有选择地使用闪存来使用过滤器。在iPad 2上,闪电战使我的应用程序从30 app到24 app。没什么大不了的,用户不会注意到的。然而,在带有视网膜显示器的iPad 3上,它下降到10 iPad。当你想到它的时候,这是有意义的,因为视网膜iPads的像素是非视网膜iPads的4倍。
如果你真的想在手机上使用闪电战,我建议以下几点:
View,在iPhone 4上用不到一个框架(~40 on )来完成它。因此,一般来说,在移动设备上使用闪存,因为位图创建是缓慢的。
https://stackoverflow.com/questions/18538415
复制相似问题