2016-05-03 75 views
0

好的,所以我的主要問題在於閃存的KeyboardEvent有點慢。比方說,我按下左箭頭。出於某種原因,運動會延遲然後移動。當我正在做雙跳或跳躍時,我不得不按下按鈕而不是單擊一次。我的問題是有沒有一種方法可以讓閃光燈檢測到任何按鍵的單次按下,以及如何解決keyCode的移動延遲問題?Flash As3按鍵問題

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 
    } 
} 
+0

答案是肯定的。如果您想要比這更好的答案,請編輯您的問題並顯示您當前的代碼,以便有人可以指出您的延遲來自哪裏。 – BadFeelingAboutThis

+0

更新:我在這裏添加了我的角色Daimyo的完整代碼。現在問題是鍵盤事件本身。 keyCode只是在短暫的時間內延遲,然後進行移動。此外,我仍然想知道as3是否只能檢測到印刷機而不是持有。謝謝! – user199845

+0

「按下」意味着什麼?本質上'KEY_UP'事件就相當於一臺印刷機。你的代碼看起來不錯,如果我不得不猜測,你的延遲來自你的'gotoAndStop'而不是事件本身。嘗試在你的按鍵處理程序('keyYeet')中放置一條跟蹤語句並查看該跟蹤是否立即觸發,而不管你在時間軸上看到的是什麼。 – BadFeelingAboutThis

回答

1

KeyboardEvent不會持續觸發,因爲這樣會很難檢測到單個按鍵。

你所要做的是使用KeyboardEvent只改變速度的變量,但適用的速度調整量在不同的連續Event,即Event.ENTER_FRAME

我創建了一個例子根據您的代碼:

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; 
} 

的想法是當鑰匙下降到一定值來設定的速度和當鑰匙轉到備份設置回0。

速度持續應用於該位置。


從註釋:

請仔細檢查你的第一句話。

果然有一個錯字,但內容是我想要的。

結果是連續發射=連續移動。

不適合我。不同的(鍵盤)硬件或軟件(操作系統,閃存運行時)可能會有所不同。其他人有類似的經歷,可以在手頭的這些重複內容中看到。

讓我們不要看顯示對象四處移動,並比較他們是否連續或不動了意見。讓我們來收集一些可比較的數據。

下面是一個小文檔類,用於統計發生了5次事件之間的延遲。

要使用它,請確保應用程序有焦點並按下任何按鈕,直到跟蹤出現在輸出面板中。

釋放鍵將重置陣列,並且可以按住另一個鍵。

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

這裏是我的結果:

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 

三個重要的事情可以看出:

  1. 的第一個值顯然是不感興趣的,因爲它是按兩次按鍵之間的時間 。 (我只是想把這個放在一起 很快)
  2. 第二個值大約是500ms,這意味着在第一次和第二次事件之間,半秒的時間過去了。
  3. 最後3個值大約爲50ms,這比 500ms短得多。這是隻要按下按鍵,事件將繼續觸發的速率

我在上面的答案中提供的代碼修復了此問題。

+0

請仔細檢查你的第一句話。嘗試** [此代碼](http://www.republicofcode.com/tutorials/flash/as3keyboard/2.php)**(從一個小的彩色矩形創建'my_mc')。你會看到,只要左或右鍵給出**「使用中」**信號,結果是連續發射=連續移動。相同的代碼檢測單鍵或長按鍵......不需要鍵來停止移動(儘管在Asker的代碼中會影響'ultraDaimyo.scaleX = ...'代碼,所以他們確實需要一個「鍵入「信號以停止恆定縮放)。 –

+0

@ VC.One我編輯了我的答案,請看看。 – null

+0

嗨,我看了一下。這是好東西。儘管我不同意你的開場白。我說**它連續發射**,否則很難發現**長按**。爲了檢測單箇中風,用戶只需通過k/board上的單次按壓觸發一次事件。它也有能力連續發射。就人類認知而言,我的意思是說。這回答了阿斯克關於單擊與長按的關注。我確認它可以做到這一點。我認爲他們的問題有一個非常長的延遲(想象一下,在你按下跳轉來獲得代碼反應後等待2或3秒的延遲)。 –