public override void GameProc(IStateOwner pOwner) { base.GameProc(pOwner); if (pOwner.CurrentState is GameplayGameState stgs1) { //pOwner.EnqueueAction(() => { stgs1.PlayField.HasChanged = true; }); } if (StartOperation == DateTime.MaxValue) { StartOperation = LastOperation = DateTime.Now; } if (ClearActivities.Count > 0) { DateTime useNowTime = DateTime.Now; foreach (var ClearActivity in ClearActivities) { var elapsed = useNowTime - ClearActivity.StartClearTime; foreach (var block in ClearActivity.Blocks) { ClearActivity.ClearAction.ProcessBlock(pOwner, new BlockClearData(block, new BCPoint() { }), elapsed); } } } //for now we clear horizontally across... if ((DateTime.Now - LastOperation).TotalMilliseconds > MSBlockClearTime) { //clear another block on each row. var ClearResult = ClearFrame(pOwner); if (ClearRowInfo.Keys.Count >= 4) { FlashState = !FlashState; } if (ClearActivities.Count > 0) { DateTime NowTime = DateTime.Now; //if there are entries in ClearActivities, we want to make sure those are cleared as well. This is the case if the cleartime has elapsed for each. ClearResult |= ClearActivities.All((kvp) => { return(NowTime - kvp.StartClearTime > kvp.ClearAction.ClearTime); }); } LastOperation = DateTime.Now; if (ClearResult) { //reset the original State. pOwner.CurrentState = _BaseState; foreach (var iterate in AfterClear) { pOwner.EnqueueAction(iterate); } if (pOwner.CurrentState is GameplayGameState stgs2) { // pOwner.EnqueueAction(() => { stgs2.PlayField.HasChanged = true; }); } } } }
public override void GameProc(IStateOwner pOwner) { base.GameProc(pOwner); if (StartOperation == DateTime.MaxValue) { StartOperation = LastOperation = DateTime.Now; } //for now we clear horizontally across... if ((DateTime.Now - LastOperation).TotalMilliseconds > MSLineAddTime) { int InsertionIndex = _BaseState.PlayField.Contents.Length - 1 - InsertionRow - InsertedCount; //since high rows have lower indices, we want to "reverse" it. //if the queue is empty, we are now finished. if (RowInsertions.Count == 0) { //reset the original State. _BaseState.PlayField.HasChanged = true; pOwner.CurrentState = _BaseState; foreach (var iterate in AfterClear) { pOwner.EnqueueAction(iterate); } } else { //dequeue the next line of blocks to insert. NominoBlock[] NextRow = RowInsertions.Dequeue(); //insert into the playfield at InsertionIndex. //This means moving All rows from InsertionIndex up one. for (int moverow = 0; moverow < InsertionIndex; moverow++) { NominoBlock[] ThisRow = _BaseState.PlayField.Contents[moverow + 1]; NominoBlock[] TargetRow = _BaseState.PlayField.Contents[moverow]; for (int copyCol = 0; copyCol < ThisRow.Length; copyCol++) { TargetRow[copyCol] = ThisRow[copyCol]; } } NominoBlock[] InsertedRow = _BaseState.PlayField.Contents[InsertionIndex]; for (int i = 0; i < InsertedRow.Length; i++) { InsertedRow[i] = NextRow[i % NextRow.Length]; } InsertedCount++; LastOperation = DateTime.Now; } //another way of doing this: we can just use DrawProc and draw the background over top, I suppose? } }
protected void AIActionThread() { //the meat and potatoes... while (AIProcessing) { Thread.Sleep(25); //if there are keys to press, we do NOT evaluate the AI Action Frame... //if there are keys to press, press the next one in the queue. We only do ONE per frame though- the idea is that //the AI should at least pretend to be sort of human in it's limitations. if (PressKeyQueue.Count > 0) { var keypress = PressKeyQueue.Dequeue(); if (keypress != GameState.GameKeys.GameKey_Null) { _Owner.EnqueueAction(() => { _Owner.CurrentState.HandleGameKey(_Owner, keypress); }); } } else { Thread.Sleep(200); AIActionFrame(); } } }
public void EnqueueAction(Action pAction) { GameOwner.EnqueueAction(pAction); }
public override void GameProc(IStateOwner pOwner) { if (ReplayData == null) { ReplayData = new StatefulReplay(); } if (!FirstRun) { if (GameOptions.MusicEnabled) { iActiveSoundObject musicplay = null; if (pOwner.Settings.std.MusicOption == "<RANDOM>") { musicplay = Sounds.PlayMusic(pOwner.AudioThemeMan.BackgroundMusic.Key, pOwner.Settings.std.MusicVolume, true); } else { musicplay = Sounds.PlayMusic(pOwner.Settings.std.MusicOption, pOwner.Settings.std.MusicVolume, true); } if (musicplay != null) { musicplay.Tempo = 1f; } FirstRun = true; GameHandler.PrepareField(this, pOwner); } } //update particles. FrameUpdate(); if (pOwner.GameStartTime == DateTime.MinValue) { pOwner.GameStartTime = DateTime.Now; } if (pOwner.LastPausedTime != DateTime.MinValue) { pOwner.GameStartTime += (DateTime.Now - pOwner.LastPausedTime); pOwner.LastPausedTime = DateTime.MinValue; foreach (var iterate in PlayField.BlockGroups) { iterate.LastFall = pOwner.GetElapsedTime(); iterate.HighestHeightValue = 0; } } PlayField.AnimateFrame(); HandleActiveGroups(pOwner); if (GameOvered) { //For testing: write out the replay data as a sequence of little images. //ReplayData.WriteStateImages("T:\\ReplayData"); Sounds.StopMusic(); pOwner.FinalGameTime = DateTime.Now - pOwner.GameStartTime; GameHandler.Statistics.TotalGameTime = pOwner.FinalGameTime; NextAngleOffset = 0; pOwner.EnqueueAction(() => { pOwner.CurrentState = new GameOverGameState(this, GameHandler.GetGameOverStatistics(this, pOwner)); }); } if (PlayField.BlockGroups.Count == 0 && !SpawnWait && !pOwner.CurrentState.GameProcSuspended && !NoTetrominoSpawn) { SpawnWait = true; pOwner.EnqueueAction (() => { SpawnNewTetromino(pOwner); SpawnWait = false; }); } }