public Frame Process(GlInput input) { if (input.KeyTime(System.Windows.Input.Key.Escape) == 1) { return(null); } if (GameForm.UserWantsToClose && !GameForm.GameInBackgroundRunning) { return(null); } if (input.KeyTime(System.Windows.Input.Key.P) == 1) { PauseButtonPressed = !PauseButtonPressed; _gameForm.GamePaused = PauseButtonPressed; } else { PauseButtonPressed = _gameForm.GamePaused; } _gameForm.UserWantsPauseAfterTurn |= input.KeyTime(System.Windows.Input.Key.Oem4) == 1;//кнопка открытая квадратная скобка, или русская буква х bool goToBeforeRoundAfterDrawing = false; if (!PauseButtonPressed) { //фазы лесенкой, чтобы можно было хоть по всем пройтись if (_processPhase == EProcessPhase.beforeRound) { if (_game.GameFinished) { GoToPhase(EProcessPhase.gameFinished); } else { if (_gameMode == EGameMode.localWithHuman) { GoToPhase(EProcessPhase.getTurnsOfNextRound); } else if (_gameMode == EGameMode.localWithoutHuman || _gameMode == EGameMode.replayFile) { if (_allRounds.ContainsKey(_game.roundNumber)) { _allRounds.TryGetValue(_game.roundNumber, out _currentRound); GoToPhase(EProcessPhase.processRound); } else { if (_gameMode == EGameMode.replayFile) { _game.GameFinished = true; GoToPhase(EProcessPhase.gameFinished); } } // else // { // if (_game.roundNumber > 5) // { // _gameForm.InfoAction = "Рекомендуем снизить скорость просмотра"; // } // } } //иначе остаемся крутиться в before round, пока во втором потоке не сформируется ход } } if (_processPhase == EProcessPhase.getTurnsOfNextRound) { bool humanTurnWasAdded = false; while (_currentRound.turns.Count < _currentPlayerOrder.Count) { var player = _currentPlayerOrder[_currentRound.turns.Count]; if (player.controlledByHuman) { if (humanTurnWasAdded && FrameworkSettings.ForInnerUse.GetAllUserTurnsImmediately == false) { break; } var turn = _game.TryGetHumanTurn(player, input); if (turn != null) { turn.input = _game.GetInputFile(player); _currentRound.turns.Add(turn); humanTurnWasAdded = true; } else { break; } } else { ExternalProgramExecuter epe = new ExternalProgramExecuter(player.programAddress, "input.txt", "output.txt", _settings[_currentGameNumber].JavaPath, _settings[_currentGameNumber].PythonPath); string inputFile = _game.GetInputFile(player); string output; string comment; //exitCode, нигде не используется GameForm.GameInBackgroundRunning = true; ExecuteResult res = epe.Execute(inputFile, FrameworkSettings.ExecutionTimeLimitSeconds, out output, out comment); GameForm.GameInBackgroundRunning = false; var turn = _game.GetProgramTurn(player, output, res, ExternalProgramExecuter.ExecuteResultToString(res)); turn.input = inputFile; _currentRound.turns.Add(turn); } } if (_currentRound.turns.Count == _currentPlayerOrder.Count) { GoToPhase(EProcessPhase.processRound); } } if (_processPhase == EProcessPhase.waitUntilAnimationFinished) { UpdateAnimationStage(); if (animationFinished) { goToBeforeRoundAfterDrawing = true; } } if (_processPhase == EProcessPhase.gameFinished) { if (input.KeyTime(System.Windows.Input.Key.Enter) == 1) { bool success = TryInitNextGame(); if (!success) { return(null); } } } } Frame frame = new Frame(); _game.DrawAll(frame, animationStage, animationFinishStage, _processPhase == EProcessPhase.getTurnsOfNextRound, input); if (_currentRound != null) { DrawAndProcessTimeline(frame, input); } if (goToBeforeRoundAfterDrawing) { GoToPhase(EProcessPhase.beforeRound); } _game.frameNumber++; return(frame); }
private void DrawAndProcessTimeline(Frame frame, GlInput input) { #region timeline { var rounds = _allRounds.Values.ToList(); //thread safe snapshot var turns = rounds.SelectMany(x => x.turns).ToList(); if (turns.Count > 0) { int currentTurn = rounds.Take(_game.roundNumber).Select(x => x.turns.Count).DefaultIfEmpty(0).Sum(); var currentTurns = new List <int>(); for (int i = 0; i < _currentRound.turns.Count; i++) { currentTurns.Add(currentTurn + i); } while (currentTurns.Count > 0 && currentTurns.Last() >= turns.Count) { currentTurns = currentTurns.Select(x => x - 1).ToList(); } int turnUnderMouse; var clickedTurn = _timeline.ManageTimelineByInputAndGetClickedTurn(out turnUnderMouse, frame, input, turns.Count, currentTurns, _settings[_currentGameNumber].FramesPerTurnMultiplier); if (clickedTurn >= 0 && clickedTurn < turns.Count) { //double code string turnName = (turns[clickedTurn] as ITimelineCell).nameOnTimeLine; var inputTxt = turns[clickedTurn].input; if (string.IsNullOrEmpty(inputTxt)) { _gameForm.InfoAction = string.Format("input.txt для хода {0} отсутствует", turnName); } else { Clipboard.SetText(inputTxt); _gameForm.InfoAction = string.Format("input.txt для хода {0} скопирован в буфер обмена", turnName); } var clickedRound = rounds.IndexOf(rounds.First(r => r.turns.Contains(turns[clickedTurn]))); SetStateBeforeGivenRound(clickedRound); } if (turnUnderMouse >= 0 && turnUnderMouse < turns.Count) { string turnName = (turns[turnUnderMouse] as ITimelineCell).nameOnTimeLine; _gameForm.InfoUnderMouse = string.Format("Ход {0}. Статус: {1}", turnName, (turns[turnUnderMouse] as ITimelineCell).shortStatus); if (input.KeyTime(System.Windows.Input.Key.I) == 1) { //double code var inputTxt = turns[turnUnderMouse].input; if (string.IsNullOrEmpty(inputTxt)) { _gameForm.InfoAction = string.Format("input.txt для хода {0} отсутствует", turnName); } else { Clipboard.SetText(inputTxt); _gameForm.InfoAction = string.Format("input.txt для хода {0} скопирован в буфер обмена", turnName); } } if (input.KeyTime(System.Windows.Input.Key.O) == 1) { var outputTxt = turns[turnUnderMouse].output; if (string.IsNullOrEmpty(outputTxt)) { _gameForm.InfoAction = string.Format("output.txt для хода {0} отсутствует", turnName); } else { Clipboard.SetText(outputTxt); _gameForm.InfoAction = string.Format("output.txt для хода {0} скопирован в буфер обмена", turnName); } } } _timeline.Draw(frame, input, turns.Cast <ITimelineCell>().ToList(), currentTurns); } } #endregion }
public int ManageTimelineByInputAndGetClickedTurn(out int turnUnderMouse, Frame frame, GlInput input, int turnCount, List <int> currentGameTurns, double speedMultiplier) { turnUnderMouse = -1; Vector2d positionOfFirstTile = new Vector2d(((IFramePainterInfo)frame).cameraViewport.right - FrameworkSettings.Timeline.TileWidth, 0); Rect2d fullTimelineRect = GetTimelineRect(frame); // var TIMELINE_SPEED_DECREASE_PER_TICK = FrameworkSettings.Timeline.TileLength / 30; double scrollTime = FrameworkSettings.Timeline.ScrollAnimationTimeMs; double followTime = speedMultiplier * FrameworkSettings.Timeline.FollowAnimationTimeMs * speedMultiplier; double allowedRangeDown = (-turnCount * FrameworkSettings.Timeline.TileWidth + fullTimelineRect.size.Y * 0.7).ToRange(0, double.MinValue), allowedRangeUp = 0; if (GeomHelper.PointInSimpleRect(input.Mouse, fullTimelineRect)) { if (_lastAnimatorReason == AnimatorReasons.followLastViewed) { _animator = new Animator <double>(Animator.Linear, _firstTurnOffset, _firstTurnOffset, 1); _lastAnimatorReason = AnimatorReasons.none; } int d = input.Wheel * FrameworkSettings.Timeline.TurnScrollSpeedByMouseOrArrow; if (input.KeyTime(System.Windows.Input.Key.Up) == 1) { d = FrameworkSettings.Timeline.TurnScrollSpeedByMouseOrArrow; } if (input.KeyTime(System.Windows.Input.Key.Down) == 1) { d = -FrameworkSettings.Timeline.TurnScrollSpeedByMouseOrArrow; } if (input.KeyTime(System.Windows.Input.Key.PageUp) == 1) { d = FrameworkSettings.Timeline.TurnScrollSpeedByPageUpDown; } if (input.KeyTime(System.Windows.Input.Key.PageDown) == 1) { d = -FrameworkSettings.Timeline.TurnScrollSpeedByPageUpDown; } if (d != 0) { double go = d * FrameworkSettings.Timeline.TileLength; _animator = new Animator <double>(Animator.EaseOutQuad, _firstTurnOffset, ((_lastAnimatorReason == AnimatorReasons.wheel ? _animator.finish : _firstTurnOffset) + go).ToRange(allowedRangeDown, allowedRangeUp), scrollTime / FrameworkSettings.ForInnerUse.TimerInterval, _timelineTick - 1); _lastAnimatorReason = AnimatorReasons.wheel; _timelineSpeed = 0; _firstTurnOffset += input.Wheel * FrameworkSettings.Timeline.TileLength; } } else { if (_indexOfLastViewedTile >= 0) { _lastAnimatorReason = AnimatorReasons.followLastViewed; } if (_lastAnimatorReason == AnimatorReasons.followLastViewed) { if (currentGameTurns.Count != 0) { _animator = new Animator <double>(Animator.EaseOutQuad, _firstTurnOffset, (fullTimelineRect.size.Y * 0.4 - currentGameTurns.First() * FrameworkSettings.Timeline.TileLength).ToRange(allowedRangeDown, allowedRangeUp), followTime / FrameworkSettings.ForInnerUse.TimerInterval, _timelineTick - 1); _lastAnimatorReason = AnimatorReasons.followLastViewed; } } } //if (_indexOfLastViewedTile >= 0) //{ // var halfYPosition = fullTimelineRect.size.Y / 2; // var viewedTurnPosition = _firstTurnOffset + _indexOfLastViewedTile * FrameworkSettings.Timeline.TileLength; // if (_followLastTurn && viewedTurnPosition < halfYPosition) // { // _animator = new Animator<double>(Animator.EaseOutQuad, // _firstTurnOffset, halfYPosition - _indexOfLastViewedTile * FrameworkSettings.Timeline.TileLength, // _followDuration, currentFrameTick-1); // } //} _firstTurnOffset = _animator.Get(_timelineTick); //if (input.RightMouseTime >= 1 && GeomHelper.PointInSimpleRect(input.Mouse, fullTimelineRect)) //{ // _timelineSpeed = 0; // if (input.RightMouseTime > 1) // { // _firstTurnOffset += input.MouseDelta.Y; // } //} //else if (input.RightMouseUp) //{ // _timelineSpeed = input.MouseDelta.Y; //} //if (input.Wheel != 0 && GeomHelper.PointInSimpleRect(input.Mouse, fullTimelineRect)) //{ // _timelineSpeed = 0; // _firstTurnOffset += input.Wheel * FrameworkSettings.Timeline.TileLength; //} //_firstTurnOffset += _timelineSpeed; //if (_timelineSpeed > 0) //{ // _timelineSpeed = Math.Max(0, _timelineSpeed - TIMELINE_SPEED_DECREASE_PER_TICK); //} //else //{ // _timelineSpeed = Math.Min(0, _timelineSpeed + TIMELINE_SPEED_DECREASE_PER_TICK); //} //correction - must be <=0 and at least one tile should be visible // if (_thereWasADraw == false) // { // _firstTurnOffset = -10000000; // _thereWasADraw = true; // } // _firstTurnOffset = _firstTurnOffset.ToRange(-turnCount * FrameworkSettings.Timeline.TileWidth + FrameworkSettings.Timeline.TileWidth * 10, 0); //todo now only ten are visible _timelineTick++; var underMouse = input.AllButtonsUnderMouse().FirstOrDefault(x => x.StartsWith("__timeline")); if (underMouse != null) { int turnIndex = int.Parse(underMouse.Replace("__timeline", "")); turnUnderMouse = turnIndex; } var clickedTurn = input.AllClickedButtons().FirstOrDefault(x => x.StartsWith("__timeline")); if (clickedTurn != null) { int turnIndex = int.Parse(clickedTurn.Replace("__timeline", "")); return(turnIndex); } return(-1); }