Actionscript 3平滑的雪碧运动

时间:2012-03-04 16:48:45

标签: actionscript-3 sprite game-physics

我使用键盘在屏幕上移动一个Sprite,速率为10像素/ ENTER_FRAME事件。问题在于,当它移动时,你可以看到它每10个像素被“重绘”一次,这使得它很难被看到。我没有在其他Flash游戏中看到过这个。

如果你仔细观察,你也可以在这里看到这一点(尽管规模要小得多):http://kirill-poletaev.blogspot.com/2010/07/smooth-character-movement-using-as3.html

我想摆脱那种影响,任何想法?


如果玩家距离屏幕边缘的距离为......,它会停止移动(通过向相反方向移动),并且BG开始滚动(可以看到相同的视觉效果)。 在背景中播放音乐时,小地图会根据玩家的位置进行更新。


    private function updater(e:Event):void
        {
            if(up && GlobalVars.vars.upPossible)
            {
                cont.y-=unit;
                setu(); // Player graphics state
            }
            else if(down && GlobalVars.vars.downPossible)
                 {
                     cont.y+=unit;
                     setd(); // Player graphics state
                 }
            else if(left && GlobalVars.vars.leftPossible)
                 {
                    cont.x-=unit;
                    setl(); // Player graphics state
                 }
            else if(right && GlobalVars.vars.rightPossible)
                 {
                     cont.x+=unit;
                     setr(); // Player graphics state
                 }
            else
                 {
                     ups.visible=false; downs.visible=false; rights.visible=false;
                     lefts.visible=false; normals.visible=true; // Player graphics state
                     GlobalVars.vars.scXr=0; GlobalVars.vars.scYu=0; GlobalVars.vars.scXl=0;
                     GlobalVars.vars.scYd=0; cont.x=int(cont.x); cont.y=int(cont.y); //Someone from the Kongregate.com forums suggested this, no visible effect 
                 }
            if((cont.x=GlobalVars.vars.maxX))
            {
                if(cont.x=GlobalVars.vars.maxX && right && GlobalVars.vars.canScrollR) GlobalVars.vars.scXr=1, cont.x-=unit, setr();
            }
            else GlobalVars.vars.scXl=0, GlobalVars.vars.scXr=0; //BG Scrolling
            if((cont.y=stage.stageHeight*7.3/10))
            {
                if(cont.y=stage.stageHeight*7.3/10 && down && GlobalVars.vars.canScrollD) GlobalVars.vars.scYd=1, cont.y-=unit, setd();
            }
            else GlobalVars.vars.scYu=0, GlobalVars.vars.scYd=0; //BG Scrolling
            if(cont.y>=stage.stageHeight*7.3/10 && cont.x>=GlobalVars.vars.maxX)  GlobalVars.vars.minimapTr=1;
            else  GlobalVars.vars.minimapTr=0;
            if(cont.y-unitGlobalVars.vars.sH-cont.height-3.1) GlobalVars.vars.downPossible=false;
            else GlobalVars.vars.downPossible=true;
            if(cont.x-unitGlobalVars.vars.sW-cont.width-3.5) GlobalVars.vars.rightPossible=false;
            else GlobalVars.vars.rightPossible=true;
            GlobalVars.vars.plX=cont.x; //for minimap
            GlobalVars.vars.plY=cont.y;

此外,关键监听器功能:



stage.addEventListener(KeyboardEvent.KEY_DOWN, keyD, false, 0, true);
stage.addEventListener(KeyboardEvent.KEY_UP, keyU, false, 0, true);

private function keyD(e:KeyboardEvent):void
    {
        if(e.keyCode==37 || e.keyCode==65) left=true;
        if(e.keyCode==38 || e.keyCode==87) up=true;
        if(e.keyCode==39 || e.keyCode==68) right=true;
        if(e.keyCode==40 || e.keyCode==83) down=true;
    }
private function keyU(e:KeyboardEvent):void
    {
        if(e.keyCode==37 || e.keyCode==65) left=false;
        if(e.keyCode==38 || e.keyCode==87) up=false;
        if(e.keyCode==39 || e.keyCode==68) right=false;
        if(e.keyCode==40 || e.keyCode==83) down=false;
    }

我通过将FPS增加到120并将步骤减少到4来获得了一些改进,但它仍然存在。我很确定这不是性能问题,而是运动方法的错误。

3 个答案:

答案 0 :(得分:2)

一些建议:

  1. 提高帧率
  2. 使用补间库(例如GTween)具有一些缓动效果。
  3. 基本上,如果你想让对象向右跳10px,不要只是立即移动它,让它以一些缓动效果动画到它的新位置。此外,如果对象仍然在移动并且再次按下该键,您可能希望稍微加速移动(但只能达到一点!)。

答案 1 :(得分:0)

我想你在问如何让它更顺畅。良好:

如果您根据frame更改 2px 的移动,那么您将获得更多更流畅的体验。但是,该动作会看到非常慢。要解决此问题,您只需提高swf的帧速率。我相信最大是120帧,但这应该更多

答案 2 :(得分:0)

我喜欢Tweenlite,它非常适合预定义的效果。它不是你游戏的核心,所以我会使用Tweenlite来实现UI效果,但几乎没有响应用户控件的游戏动作。

我认为大约24-30 fps的游戏很棒,这就是我设置所有游戏的方式。我觉得你很挑剔,但也许你所缺少的是一些优势:顺利开始和结束运动。在大多数平台游戏中,我有类似的机制:

您希望机芯开始变慢,达到您定义的正常(最大)速度,当玩家按下按钮时,它会减慢回到0.这意味着您需要检查输入的速度无论按钮触发器是什么帧(它们都会增加速度,但不是改变速度和移动物体的唯一条件)

enterframe loop:
  //check for each direction:
  if up, y_speed++
  else if down, y_speed--
  else if right, x_speed++
  else if left, x_speed--
  else // perform a decrease:
    y_speed *= .8
    x_speed *= .8
  // make sure we aren't past the max speed
  if x_speed>max_x_speed
    x_speed = max_x_speed
  etc. else other direction and y_speed
  // now apply the movement
  object.x += x_speed
  object.y += y_speed
  // remove the enterframe for better performance
  if math.abs(x_speed)<.1 && math.abs(y_speed)<.1
    // remove enterframe for movement here, add it again next time we know we have movement (button downs related to the movement, etc.)

我会在你的代码中实现这个,但你的代码太拥挤了。无论如何,大多数使用这些简单控件的游戏都像你的应用程序一样工作。