Пример #1
0
        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;
        }
Пример #2
0
        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();
                }
        }