private void RemoveMarkedGems() { // Iterate through the board for (var x = 0; x < Constants.KBoardWidth; x++) { for (var y = 0; y < Constants.KBoardHeight; y++) { var i = x + y * Constants.KBoardWidth; if (_board[i] < -1) { // Increase the count for negative crystal types _board[i]++; if (_board[i] == -1) { _numGemsInColumn[x]--; _boardChangedSinceEvaluation = true; // Transform any gem above this to a falling gem for (var yAbove = y + 1; yAbove < Constants.KBoardHeight; yAbove++) { var idxAbove = x + yAbove * Constants.KBoardWidth; if (_board[idxAbove] < -1) { _numGemsInColumn[x]--; _board[idxAbove] = -1; } if (_board[idxAbove] == -1) { continue; } // The gem is not connected, make it into a falling gem var gemType = _board[idxAbove]; var gemSprite = _boardSprites[idxAbove]; var gem = new FallingGem() { gemType = gemType, sprite = gemSprite, yPos = yAbove, ySpeed = 0 }; _fallingGems[x].Add(gem); // Remove from board _board[idxAbove] = -1; _boardSprites[idxAbove] = null; _numGemsInColumn[x]--; } } } } } }
private void GameLoop() { if (!_isGameOver) { RemoveMarkedGems(); int x; FallingGem gem; // Add falling gems for (x = 0; x < Constants.KBoardWidth; x++) { if (_numGemsInColumn[x] + _fallingGems[x].Count < Constants.KBoardHeight && _timeSinceAddInColumn[x] >= Constants.KTimeBetweenGemAdds) { // A gem should be added to this column! var gemType = CCRandom.GetRandomInt(0, 4); var gemSprite = new CCSprite("crystalscrystals/" + gemType + ".png"); gemSprite.Position = new CCPoint(_fieldPositionZero.X + x * Constants.KGemSize, _fieldPositionZero.Y + Constants.KBoardHeight * Constants.KGemSize); gemSprite.AnchorPoint = CCPoint.Zero; gem = new FallingGem() { gemType = gemType, sprite = gemSprite, yPos = Constants.KBoardHeight, ySpeed = 0 }; _fallingGems[x].Add(gem); _gameBoardLayer.AddChild(gemSprite); _timeSinceAddInColumn[x] = 0; } _timeSinceAddInColumn[x]++; } #region Move falling gems var gemLanded = false; for (x = 0; x < Constants.KBoardWidth; x++) { var column = _fallingGems[x]; var numFallingGems = _fallingGems[x].Count; for (var i = numFallingGems - 1; i >= 0; i--) { gem = column[i]; gem.ySpeed += 0.06f; gem.ySpeed *= 0.99f; gem.yPos -= gem.ySpeed; if (gem.yPos <= _numGemsInColumn[x]) { // The gem hit the ground or a fixed gem if (!gemLanded) { CCSimpleAudioEngine.SharedEngine.PlayEffect("Sounds/tap-" + CCRandom.Next(0, 4) + ".wav"); gemLanded = true; } column.RemoveAt(i); // Insert into board var y = _numGemsInColumn[x]; if (_board[x + y * Constants.KBoardWidth] != -1) { Debug.WriteLine("Warning! Overwriting board idx: " + x + y * Constants.KBoardWidth + " type: " + _board[x + y * Constants.KBoardWidth]); } _board[x + y * Constants.KBoardWidth] = gem.gemType; _boardSprites[x + y * Constants.KBoardWidth] = gem.sprite; // Update fixed position gem.sprite.Position = new CCPoint(_fieldPositionZero.X + x * Constants.KGemSize, _fieldPositionZero.Y + y * Constants.KGemSize); _numGemsInColumn[x]++; _boardChangedSinceEvaluation = true; } else { // Update the falling gems position gem.sprite.Position = new CCPoint(_fieldPositionZero.X + x * Constants.KGemSize, _fieldPositionZero.Y + gem.yPos * Constants.KGemSize); } } } #endregion // Check if there are possible moves and no gems falling var isFallingGems = false; for (x = 0; x < Constants.KBoardWidth; x++) { if (_numGemsInColumn[x] != Constants.KBoardHeight) { isFallingGems = true; break; } } if (!isFallingGems) { var possibleMove = FindMove(); if (possibleMove == -1) { // Create a possible move CreateRandomMove(); } } // Update timer var currentTime = DateTime.Now; var elapsedTime = (currentTime - _startTime).TotalMilliseconds / Constants.KTotalGameTime; var timeLeft = (1 - elapsedTime) * 100; if (timeLeft < 0) { timeLeft = 0; } if (timeLeft > 99.9) { timeLeft = 99.9; } _timer.Percentage = (float)timeLeft; // Update consecutive moves / powerplay if ((currentTime - _lastMoveTime).TotalMilliseconds > Constants.KMaxTimeBetweenConsecutiveMoves) { _numConsecutiveGems = 0; } UpdatePowerPlay(); // Update sparkles UpdateSparkles(); // Check if timer sound should be played if (timeLeft < 6.6 && !_endTimerStarted) { CCSimpleAudioEngine.SharedEngine.PlayEffect("Sounds/timer.wav"); _endTimerStarted = true; } // Check for game over if (timeLeft < 0.000001f) { CreateGameOver(); RunOutroAnimations(); _isGameOver = true; CCSimpleAudioEngine.SharedEngine.PlayEffect("Sounds/endgame.wav"); MainSceneLayer.LastScore = _score; } else if ((currentTime - _lastMoveTime).TotalMilliseconds > Constants.KDelayBeforeHint && !_isDisplayingHint) { DisplayHint(); } } else { UpdateGameOver(); } }