简体   繁体   English

Flash As3按键问题

[英]Flash As3 key press issue

Ok so my main problem here is that the KeyboardEvent for flash is wayyy to slow. 好的,所以我的主要问题是,Flash的KeyboardEvent慢了。 Lets say i press the left arrow. 可以说我按了向左箭头。 For some reason, the movement delays and then moves. 由于某种原因,运动会延迟然后运动。 When I was doing double jumping or jumping at all, I had to hold the button rather than do a single press. 当我进行两次跳跃或完全跳跃时,我必须按住按钮而不是按一下。 My question is is there a way for flash to detect a single press of any key and how do I solve the movement delay for keyCode? 我的问题是闪光灯是否可以检测到任何按键的按动,我该如何解决keyCode的移动延迟?

import flash.ui.Keyboard;
import flash.events.KeyboardEvent;
import flash.events.Event;

//Initialized variables

var theKey:KeyObject = new KeyObject(stage);//Help the stage checks for keypressed objects
var hspeed:Number = 0;// horizontal speed
var vspeed:Number = 0;// vertical speed
var gravity:Number = 2;//Gravity
var friction:Number  = .5;//Friction
var ground:int = 800;//Bottom of the stage
var JumpMax:Number = 0;//Double jump

//All Booleans (Mainly player states)
var aDown:Boolean = false;//Press left key
var dDown:Boolean = false;//Press right key
var Jumped:Boolean = false;//Player in jumping state
var AttackMode:Boolean = false;//Player in attacking state
var CrouchMode:Boolean = false;//Player in crouched state
var RightSide:Boolean = false;//Player hitting right side of block
var LeftSide:Boolean = false;//Player hitting left side of block
var DownSide:Boolean = false;//Player hitting the top of block
var UpSide:Boolean = false;//Player hits bottom of block

ultraDaimyo.gotoAndStop("idleDaimyo");

stage.addEventListener(KeyboardEvent.KEY_DOWN, keyYeet);
function keyYeet(e:KeyboardEvent):void 
{
if(e.keyCode == Keyboard.D)
    {
        dDown = true;

    }
if(e.keyCode == Keyboard.A)
    {
        aDown = true;

    }
if(e.keyCode == Keyboard.C)
  {
    AttackMode = true;

  }
if(e.keyCode == Keyboard.W || Jumped == true)
  {
    Jumped = true;
  }
 }

 stage.addEventListener(KeyboardEvent.KEY_UP, keyNot);
 function keyNot(e:KeyboardEvent):void 
{
if(e.keyCode == Keyboard.D)
 {
    dDown = false; 
 }
if(e.keyCode == Keyboard.A)
 {
    aDown = false; 
 }
if(e.keyCode == Keyboard.C)
 {
    AttackMode = false; 
 }
if(e.keyCode == Keyboard.W)
 {
    Jumped = false; 
 }
 }


 stage.addEventListener(Event.ENTER_FRAME, gameCycle);
 function gameCycle(e:Event):void
{
hspeed *= friction;
ultraDaimyo.x += hspeed;
ultraDaimyo.y += gravity;

if(AttackMode)
      {
        ultraDaimyo.gotoAndStop("attackDaimyo");
        ultraDaimyo.x += 5;
        if(ultraDaimyo.scaleX == -1)
          {
            ultraDaimyo.gotoAndStop("attackDaimyo");
            ultraDaimyo.x -= 10;
          }
      }
if(Jumped == true)
  {
     ultraDaimyo.y -= 30;
     ultraDaimyo.gotoAndStop("jumpDaimyo");
  } 
if(dDown)
  {
     hspeed += 20;
     ultraDaimyo.gotoAndStop("runDaimyo");
     ultraDaimyo.scaleX = 1;
  }
if(aDown)
  {
     hspeed -= 20;
     ultraDaimyo.gotoAndStop("runDaimyo");
     ultraDaimyo.scaleX = -1;
  }
if(!aDown && !dDown && !AttackMode && !Jumped)
  {
    ultraDaimyo.gotoAndStop("idleDaimyo");
  }


if(ultraDaimyo.x - ultraDaimyo.width/2 < 0)//If the player goes past the left side
  {
    ultraDaimyo.x = ultraDaimyo.width/2;
  }
if(ultraDaimyo.x + ultraDaimyo.width/2 > 1400)//If the player goes past right
  {
    ultraDaimyo.x = 1400 - ultraDaimyo.width/2;//Player cant go past
  } 
if(ultraDaimyo.y + ultraDaimyo.height/2 < floor && Jumped)//If we are above the floor
  {
    if(Jumped)
      {
          ultraDaimyo.gotoAndStop("jumpDaimyo");
      }
    gravity++;//Accelerate gravity in the process
  }
if(ultraDaimyo.y + ultraDaimyo.height/2 > floor)
  {
    Jumped = false;//If we are on the floor then we're not jumping
    gravity = 0;//Gravity can no longer be applied
    ultraDaimyo.y = floor - ultraDaimyo.height/2;//Player sits on top of the floor
  }
}

KeyboardEvent does not fire continuously, because that would make it hard to detect single keystrokes. KeyboardEvent不会连续触发,因为这将使检测单个击键变得困难。

What you have to do is use the KeyboardEvent to only change the speed variable, but apply the speed to the position variable in a different continuous Event , namely Event.ENTER_FRAME . 您要做的是使用KeyboardEvent仅更改速度变量,但将速度应用于另一个连续Event (即Event.ENTER_FRAME的位置变量。

I created an example based on your code: 我根据您的代码创建了一个示例:

import flash.ui.Keyboard;
import flash.events.KeyboardEvent;
import flash.events.Event;

//Initialized variables
var speedX:Number = 0;

stage.addEventListener(KeyboardEvent.KEY_DOWN, keyYeet);

function keyYeet(e:KeyboardEvent):void
{
    if(e.keyCode == Keyboard.D)
    {
        speedX = 20;
    }

    if(e.keyCode == Keyboard.A)
    {
        speedX = -20;
    }
}

stage.addEventListener(KeyboardEvent.KEY_UP, keyNot);

function keyNot(e:KeyboardEvent):void
{
    if(e.keyCode == Keyboard.D || e.keyCode == Keyboard.A)
    {
        speedX = 0;
    }
}

addEventListener(Event.ENTER_FRAME, gameCycle);

function gameCycle(e:Event):void
{
    ultraDaimyo.x += speedX;
}

The idea is to set the speed when the key goes down to a certain value and to set it back to 0 when the key goes back up. 这个想法是当按键下降到某个值时设置速度,并在按键返回时将其设置回0。

The speed is continuously applied to the position. 速度将连续应用于该位置。


from the comments: 从评论:

Please double check your first sentence. 请仔细检查您的第一句话。

Sure enough there was a typo, but the content is as I intended it to be. 确实有错别字,但内容确实如我所愿。

the result is continous firing = continuous movement. 结果是连续射击=连续运动。

Not for me. 不适合我。 Chances are this is different for different (keyboard) hardware or software (operating system, flash runtime). 对于不同的(键盘)硬件或软件(操作系统,闪存运行时),这可能是不同的。 Other people have similar experiences as can be seen in these duplicates of the question at hand. 其他人也有类似的经验,就像在手头的问题的这些副本中可以看到的那样。

Let's not look at display objects moving around and comparing opinions about whether they move continuously or not. 我们不要看显示对象的移动,也不要比较它们是否连续移动的观点。 Let's collect some comparable data instead. 让我们收集一些可比较的数据。

Here's a little document class that counts the delay between 5 occurrences of the KEY_DOWN event. 这是一个小的文档类,它计算KEY_DOWN事件在5次出现之间的延迟。

To use it, make sure the application has focus and press down any button until the trace appears in the output panel. 要使用它,请确保应用程序具有焦点并按下任意按钮,直到轨迹出现在输出面板中。

Releasing the key resets the array and another key can be held down. 释放键将重置阵列,并且可以按住另一个键。

package 
{
    import flash.utils.getTimer;
    import flash.events.KeyboardEvent;
    import flash.display.Sprite;

    public class Main extends Sprite 
    {
        private var oldTime:Number = 0;
        private var deltaTimes:Array = [];

        public function Main() 
        {
            stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
            stage.addEventListener(KeyboardEvent.KEY_UP, onKeyUp);
        }

        private function onKeyDown(e:KeyboardEvent):void
        {
            var currentTime:Number = getTimer();

            // collect 5 time differences between two consecutive occurrences of this event

            if (deltaTimes.length < 5)
            {
                deltaTimes.push(currentTime - oldTime)    
            }
            else
            {
                stage.removeEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
                trace(deltaTimes);
            }

            oldTime = currentTime;           
        }

        private function onKeyUp(e:KeyboardEvent = null):void
        {
            deltaTimes = [];

            stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
        }
    }
}

Here are my results: 这是我的结果:

7584,499,49,51,50
2117,500,50,50,50
1786,500,50,50,49
1375,499,48,50,52
1395,500,50,50,50
1385,500,50,50,50
1243,501,47,52,49
2167,501,49,50,50
1587,500,50,50,50
3871,500,50,48,53
2237,500,49,51,49
1715,500,47,53,50

Three important things can be observed: 可以观察到三个重要的事情:

  1. The first value is obviously not interesting as it is the time between two button presses. 第一个值显然并不有趣,因为它是两次按下按钮之间的时间。 (I just wanted to put this together quickly) (我只是想把它们放在一起)
  2. The second value is roughly 500ms, which means between the first and second occurrence of the event, half a second of time passed. 第二个值大约为500毫秒,这意味着在事件的第一次和第二次发生之间经过了半秒的时间。
  3. The last 3 values are roughly 50ms, which is much shorter than 500ms. 最后三个值大约为50ms,比500ms短得多。 This is the rate at which the event will keep firing as long as the key is pressed 这是只要按下按键,事件将持续触发的速率

The code I provided in my answer above fixes this problem. 我在上面的答案中提供的代码解决了此问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM