void OnKeyEvents(CryEngine.InputEvent evt) { //这里主要处理连按的逻辑,第一次收到按下通知后立刻发出键盘事件,然后延迟一段时间,如果后续还有down通知,按照一定频率触发键盘事件。 float currTime = Engine.Timer.GetCurrTime(); if (evt.State == InputState.Down) { float lastDownTime; if (_lastKeyDownTime.TryGetValue(evt.KeyId, out lastDownTime)) { if (currTime - lastDownTime < 0) { return; } } _lastKeyDownTime[evt.KeyId] = currTime + 0.05f; } else if (evt.State == InputState.Released) { _lastKeyDownTime.Remove(evt.KeyId); return; } else if (evt.State == InputState.Pressed) { _lastKeyDownTime[evt.KeyId] = currTime + 0.5f; } else { return; } _touchInfo.keyCode = evt.KeyId; _touchInfo.keyName = null; _touchInfo.modifiers = evt.InputModifiers; bool shift = (evt.InputModifiers & InputModifierFlags.Shift) != 0; //evt.keyName is not reliable, I parse it myself. if (evt.KeyId >= KeyId.Q && evt.KeyId <= KeyId.P || evt.KeyId >= KeyId.A && evt.KeyId <= KeyId.L || evt.KeyId >= KeyId.Z && evt.KeyId <= KeyId.M) { bool capsLock = (evt.InputModifiers & InputModifierFlags.CapsLock) != 0; if (shift) { capsLock = !capsLock; } if (capsLock) { _touchInfo.keyName = evt.KeyName.ToUpper(); } else { _touchInfo.keyName = evt.KeyName; } } else { if (_charByScanCode3.TryGetValue(evt.KeyId, out _touchInfo.keyName)) { if ((evt.InputModifiers & InputModifierFlags.NumLock) == 0) { _touchInfo.keyName = null; } } else if (shift) { if (!_charByScanCode2.TryGetValue(evt.KeyId, out _touchInfo.keyName)) { _charByScanCode1.TryGetValue(evt.KeyId, out _touchInfo.keyName); } } else { _charByScanCode1.TryGetValue(evt.KeyId, out _touchInfo.keyName); } } _touchInfo.UpdateEvent(); DisplayObject f = this.focus; if (f != null) { f.BubbleEvent("onKeyDown", _touchInfo.evt); } else { this.DispatchEvent("onKeyDown", _touchInfo.evt); } }