protected override void HandleInput(UserInputMessage message) { var player = GameModel.Instance.CurrentMap.PlayerCharacter; switch (message.Input) { case UserInput.Up: _throttleTicks = Constants.MAP_MOVE_CHARACTER_TICKS; Bus.Broadcast(CharacterMoveMessage.PanMapOnMove(SpriteDirection.Up, player)); break; case UserInput.Down: _throttleTicks = Constants.MAP_MOVE_CHARACTER_TICKS; Bus.Broadcast(CharacterMoveMessage.PanMapOnMove(SpriteDirection.Down, player)); break; case UserInput.Left: _throttleTicks = Constants.MAP_MOVE_CHARACTER_TICKS; Bus.Broadcast(CharacterMoveMessage.PanMapOnMove(SpriteDirection.Left, player)); break; case UserInput.Right: _throttleTicks = Constants.MAP_MOVE_CHARACTER_TICKS; Bus.Broadcast(CharacterMoveMessage.PanMapOnMove(SpriteDirection.Right, player)); break; case UserInput.Confirm: Bus.Broadcast(CharacterInteractMessage.New(player)); break; case UserInput.Cancel: break; case UserInput.Option: Bus.Broadcast(ShowMenuMessage.New()); break; default: break; } }
protected override void HandleInput(UserInputMessage message) { //we only respond to confirm to advance the dialog if (message.Input == UserInput.Confirm) { //this will either advance the current page if it's not done displaying, or go to the next page AdvanceDialog(); } }
protected override void HandleInput(UserInputMessage message) { var menu = MenuModel.Instance; var menuState = MenuUtility.GetMenuState(menu.CurrentCursorLocation); InMenuInputHandler.HandleMenuInput(menu, message.Input, menuState); if (menuState == MenuState.Navigation && message.Input == UserInput.Cancel) { CloseMenu(); } }
protected override void HandleInput(UserInputMessage message) { //TODO: Determine what to do in battle for each of the inputs. switch (message.Input) { case UserInput.Up: foreach (var readyPartyMember in BattleModel.Instance.BattleData.AllPartyMembersInBattle) { readyPartyMember.ActionCounter = 0; readyPartyMember.HasQueuedAbility = false; readyPartyMember.PartyMember.TryAddHealth(10); } break; case UserInput.Down: foreach (var readyPartyMember in BattleModel.Instance.BattleData.AllPartyMembersInBattle) { readyPartyMember.PartyMember.TryAddHealth(-9999); } break; case UserInput.Left: foreach (var readyPartyMember in BattleModel.Instance.BattleData.AllAlivePartyMembersInBattle .Where(x => x.ActionCounter == Constants.BATTLE_ACTION_COUNTER_READY) .Where(x => x.HasQueuedAbility == false)) { if (readyPartyMember == BattleModel.Instance.BattleData.PartyMemberInBattle2) { var ability2 = GameObjectFactory.Instance.AbilityContainer.GetById("Attack150"); var target2 = BattleModel.Instance.BattleData.AllAliveEnemiesInBattle.First(); BattleManager.QueueAbility(readyPartyMember, ability2, target2); return; } var ability = GameObjectFactory.Instance.AbilityContainer.GetById("Lightning3"); var target = BattleModel.Instance.BattleData.AllAliveEnemiesInBattle.First(); BattleManager.QueueAbility(readyPartyMember, ability, target); } break; case UserInput.Right: break; case UserInput.Confirm: break; case UserInput.Cancel: //TODO: Ending the battle should be handled by messages (listening for enemies dying?) For now, cancel does it BattleUtility.EndBattle(); break; case UserInput.Option: break; default: break; } }
protected virtual void OnTick(TickMessage message) { //decrement the throttle counter _throttleTicks = Math.Max(-1, _throttleTicks - 1); //if we're no longer throttling, see if we have anything queued / to repeat if (_throttleTicks == 0) //we specifically check 0 here, as we only do this for 1 tick before the value goes to -1 and 'resets' { lock (_locker) //we don't want to dequeue a message or set last handled message to null while we're handling one already { _lastHandledMessage = null; //any queued message takes precedent if (_messageQueue.Count > 0) { var queuedMessage = _messageQueue.Dequeue(); //we have something in queue. Only handle it if we should be handling input at all if (HandledStates.Contains(GameModel.Instance.State)) { //we don't want to broadcast this, as it's already been broadcast, so just execute the handler OnUserInput(queuedMessage); } } //otherwise, check immediately to see if there is any key already being pressed, and broadcast that else { //only consider rebroadcasting if we're still in the state we handled originally, and we support repeating this input automatically var downInput = InputUtility.SupportedUserInput.FirstOrDefault(x => UiThread.Execute(() => Keyboard.IsKeyDown(x)) && HandledStates.Contains(GameModel.Instance.State) && (SupportedRepeatableInput?.Contains(InputUtility.MapUserInput(x)) ?? false)); if (InputUtility.IsSupportedUserInput(downInput)) { Bus.Broadcast<UserInputMessage>( UserInputMessage.New( GameModel.Instance.State, InputUtility.MapUserInput(downInput))); } } } } }
protected abstract void HandleInput(UserInputMessage message);
protected virtual void OnUserInput(UserInputMessage message) { //all input managers need to lock, to ensure we don't get multiple threads handling very quick input lock (_locker) { //only handle this input if we're in the correct state, and we're not already throttling input, and this message hasn't yet been handled if (HandledStates.Contains(message.State) && message.IsHandled == false) { //if we're not throttling input, handle it if (_throttleTicks <= 0) { _lastHandledMessage = message; message.MarkAsHandled(); HandleInput(message); //if we've handled input, and we haven't throttled at all, put a default throttle on, just to prevent crazy fast input if (_throttleTicks <= 0) { _throttleTicks = Constants.INPUT_DEFAULT_THROTTLE; } } else { //we want to queue it up if the input is different than the last item in the queue, or the queue is empty and it's different than the last input we saw if ((_messageQueue.Count > 0 && _messageQueue.Last().Input != message.Input) || (_messageQueue.Count == 0 && _lastHandledMessage != null && _lastHandledMessage.Input != message.Input)) { if (SupportedRepeatableInput?.Contains(message.Input) ?? false) { if (_messageQueue.Count < 2) { _messageQueue.Enqueue(message); } } } } } } }