private Shape GenerateShape() { if (_shapeTypeIndex == _shapeTypes.Length) { _shapeTypeIndex = 0; ShuffleShapeTypes(); } var shapeNum = _shapeTypes[_shapeTypeIndex++]; var shape = new Shape((ShapeType) shapeNum); int xOffset = -2; if (shape.Type == ShapeType.O) xOffset = -1; shape.SetPosition(Constants.BlockAreaSizeX / 2 + xOffset, -1); return shape; }
public void Update(GameTime gameTime) { if (_gameOver) return; if (_currentShape == null) { _currentShape = _nextShape ?? GenerateShape(); _currentShapeBlocks = _currentShape.GetBlocks(); _nextShape = GenerateShape(); _nextShapeBlocks = _nextShape.GetBlocks(); _moveTimeElapsed = 0.0; } if (InputHandler.KeyPressed(Keys.Right)) _currentShape.Move(Direction.Right, this); else if (InputHandler.KeyPressed(Keys.Left)) _currentShape.Move(Direction.Left, this); else if (InputHandler.KeyPressed(Keys.Up)) if (_currentShape.Rotate(Direction.Right, this)) _currentShapeBlocks = _currentShape.GetBlocks(); // Calculate ghost shape position _ghostPosition = new Point(_currentShape.Position.X, _currentShape.Position.Y); for (int y = _ghostPosition.Y + 1; y < Constants.BlockAreaSizeY; y++) if (_currentShape.IsValidDropPoint(new Point(_ghostPosition.X, y), this)) _ghostPosition.Y = y; else break; _moveTimeElapsed += gameTime.ElapsedGameTime.TotalSeconds; var userDrop = InputHandler.KeyDown(Keys.Down); if (!(_moveTimeElapsed >= ShapeMoveDelay + _shapeMoveDelayMod) && !userDrop) return; if (_moveTimeElapsed >= ShapeMoveDelay + _shapeMoveDelayMod) _moveTimeElapsed -= ShapeMoveDelay + _shapeMoveDelayMod; var shapePos = new Point(_currentShape.Position.X, _currentShape.Position.Y); if (!_currentShape.Drop(this)) { for (int x = 0; x < _currentShape.Size; x++) for (int y = 0; y < _currentShape.Size; y++) { var block = _currentShapeBlocks[x, y]; if (block == null) continue; PlaceAt(block, x + shapePos.X, y + shapePos.Y); } _currentShape = null; } else if (userDrop) OnUserDrop(); // Check for filled rows var rows = new Queue<int>(); // Queue: first-in -> first-out // Loop through all rows, top to bottom, adding any full rows to the queue for (int y = 0; y < Constants.BlockAreaSizeY; y++) for (int x = 0; x < Constants.BlockAreaSizeX; x++) { if (_blocks[x, y] == null) break; if (x == Constants.BlockAreaSizeX - 1) rows.Enqueue(y); } while (rows.Count > 0) { var row = rows.Dequeue(); for (int x = 0; x < Constants.BlockAreaSizeX; x++) RemoveAt(x, row); for (int y = row - 1; y > 0; y--) for (int x = 0; x < Constants.BlockAreaSizeX; x++) if (_blocks[x, y] != null) { PlaceAt(_blocks[x, y], x, y + 1); RemoveAt(x, y); } _shapeMoveDelayMod -= ShapeMoveDelayModStep; OnLineCleared(); } for (int x = 0; x < Constants.BlockAreaSizeX; x++) if (_blocks[x, 0] != null) { _gameOver = true; OnGameOver(); } }