如何在 AS3 中顺利移动吃豆人?

问题描述 投票:0回答:1

我正在使用 Adobe Animate(以前称为 Flash)在 ActionScript 3 中编写吃豆人克隆,并且可以使用一些关于移动和速度的建议。根据 Pitman 的吃豆人档案,吃豆人的移动速度约为每秒 75.75 像素。在下面的代码中,您可以看到我将项目的 FPS 设置为 38(最大速度的一半),并将其每帧移动 2 个像素以实现 100% 的速度。动画很流畅并且效果很好。问题是,当我尝试 80% 的速度时,因此必须在某些帧上将像素数从 2 减少,以便“减慢”他的速度。假设我使用相同的系统对幽灵进行编程,我必须达到从 40% 到 105% 的许多其他速度,增量为 5。当您减少任何步骤(参见代码)来减慢 Pacman 速度时,会出现明显的变化口吃。我可以尝试将应用程序的 FPS 设置为 76fps,并以每帧 1 像素的速度移动,但我有一种感觉,将某些步数减少到 0 会产生类似的结果,但在更高的帧速率下可能不会那么明显。有人可以给我任何建议,让我以不同的方式行动吗?我在这里受到限制,只能按整数移动每一帧,不带分数。


    import flash.display.MovieClip;
    import flash.events.KeyboardEvent;
    import flash.events.Event;
    import flash.display.Stage;
    import Configure.Config;

    public final class Pacman extends MovieClip {

        private static var _instance:Pacman;
        private var gridx;
        private var gridy;
        private var config:Config;
        private var decx;
        private var decy;
        private var offsetX;
        private var offsetY;
        private var dir:Number; //pacman's direction. 0=left, 1=up, 2=right, 3=down
        private var stepTable:Array = [];
        private var speedCycle = 0;
        public  var step:Number = 1;

        public function Pacman(_x:Number=112, _y:Number=212) {
            // constructor code
            if( _instance ){
                throw new Error("Singleton... use getInstance()");
            } 
            _instance = this;
            this.addEventListener( Event.ENTER_FRAME, this.enterFrameHandler );
            x = _x; y= _y;
            offsetX = 0;
            offsetY = 24;
            config = Config.getInstance();
            dir = 0; //left
            initStepTable();
        }

        public static function getInstance():Pacman{
            if( !_instance ){
                new Pacman();
            } 
            return _instance;
        }
        
        private function enterFrameHandler(e:Event)
        {
            var _parent = MovieClip(parent);
            var moved = false;
            
            var speedStr:String;
            speedStr = stepTable["80"];
            step = Number(speedStr.charAt(speedCycle));
            
            updateGridPosition()
            
            if(config.isKeyDown(37)) {
                if( canMoveLeft() ) {
                    x -= step;
                    if(decy != .5){
                        if(decy < .5) y += step;
                        if(decy > .5) y -= step;
                    }
                    rotation = 0;
                    //play();
                    moved = true;
                } else {
                }
            }
            if(config.isKeyDown(38) ) {
                if( canMoveUp() ) {             
                    y -= step;
                    if(decx != .5){
                        if(decx < .5) x+=step;
                        if(decx > .5) x-=step;
                    }
                    rotation = 90;
                    //play();
                    moved = true;
                }
            }
            if(config.isKeyDown(39) ) {
                if ( canMoveRight() ) {
                    x += step;
                    if(decy != .5){
                        if(decy < .5) y += step;
                        if(decy > .5) y -= step;
                    }
                    rotation = 180;
                    //play();
                    moved = true;
                }
            }
            if(config.isKeyDown(40) ) {
                if( canMoveDown() ){
                    y += step;
                    if(decx != .5){
                        if(decx < .5) x+=step;
                        if(decx > .5) x-=step;
                    }
                    rotation = 270;
                    //play();
                    moved = true;
                }
            }
            //stop();
            updateGridPosition()
            
            _parent.changeTxtPacX( String(x ) );
            _parent.changeTxtPacY( String(y) );
            _parent.changeTxtPacGrid( String(gridx + ":" + gridy) );
            _parent.changeTxtPacDec( String(decx + ":" + decy) );
            
            speedCycle++; if(speedCycle > 18) speedCycle=0;
        }
        
        private function updateGridPosition(){
            gridx = ( x - offsetX ) / 8;
            gridy = ( y - offsetY ) / 8;
            decx = gridx - Math.floor( gridx );
            decy = gridy - Math.floor( gridy );
        }
        
        private function canMoveLeft():Boolean {
            var leftcontent = MovieClip(parent).getGridContent( Math.floor((gridx + .375 ) - 1), Math.floor(gridy) );
            if( leftcontent != "#" ) return true;
            return false;
        }
        
        private function canMoveUp():Boolean {
            var upcontent = MovieClip(parent).getGridContent( Math.floor(gridx), Math.floor((gridy + .375) - 1));
            if( upcontent != "#" ) return true;
            return false;
        }
        
        private function canMoveRight():Boolean {
            var rightcontent = MovieClip(parent).getGridContent( Math.floor((gridx - .5) + 1), Math.floor(gridy) );
            if ( rightcontent != "#" ) return true;
            return false;
        }
        
        private function canMoveDown():Boolean {
            var downcontent = MovieClip(parent).getGridContent( Math.floor(gridx), Math.floor((gridy - .5) + 1));
            if( downcontent != "#" ) return true;
            return false;
        }
        
        private function initStepTable():void
        {
            /*
                Todo: 
             */
            stepTable["100"] =      "2222222222222222222"; // 100% speed
            stepTable["80"]  =      "2222022220222202220";
            //stepTable[2] =        "0222222202222222"; //Pacman speed at 2-4 (85% of 75 pixels = 64.40 pixels/sec. We get 66.36 using our speed calc)
            //stepTable[3] =        "1111111111111111"; //Pacman speed at 5-20
            //stepTable[4] =        "1111111111111111"; //Pacman speed at 21+
        }

    } //end class
} // end package
actionscript-3 actionscript pacman
1个回答
0
投票

通常在渲染游戏时,您不应该将游戏运动、处理、物理或动画等与帧速率紧密耦合。因为帧速率可以改变,并且通常您希望其他事情基于现实世界时间。

大多数游戏框架或引擎在更新内容时通过使用可变时间步长(也称为在帧之间使用“增量时间”)来处理此问题。 Jonas Tyroller 实际上有一个关于该主题的相当深入的视频,但与语言无关:https://www.youtube.com/watch?v=yGhfUcPjXuE

我会将你的 fps 调整为平滑的值。我推荐60fps。然后处理代码中所有的加速和减速。

我不会写出所有代码,但主要部分是在运动计算中使用帧之间的时间差。因此,您可能需要弄清楚如何将这个概念融入您自己的系统中。这是重要的部分

private var prevFrameTime:Number;

private function enterFrameHandler(e:Event):void {
    var currentTime:Number = getTimer();
    var deltaTime:Number = (currentTime - prevFrameTime) / 1000; // Convert to seconds

    // Use deltaTime in your calculations
    x += step * deltaTime;

    prevFrameTime = currentTime;
}
© www.soinside.com 2019 - 2024. All rights reserved.