Beispiel #1
0
        private void MergePiece()
        {
            var coords = PieceUtils.GetCoords(currentPiece, currentRotation);

            var color = (byte)(1 + currentIndex % 7);

            for (int i = 0; i < coords.Length; i++)
            {
                var coord = coords[i];
                coord.x += currentX;
                coord.y += currentY;

                if (ValidCoord(coord.x, coord.y))
                {
                    board[coord.x + coord.y * BoardWidth] = color;
                }
            }

            merging    = true;
            mergeY     = BoardHeight - 1;
            mergeTime  = Console.FrameCounter;
            mergeCombo = 0;

            moves.Add(new PieceMove(currentPiece, currentX, currentY, currentRotation));
        }
Beispiel #2
0
        private bool HasCollision(int dirX, int dirY)
        {
            var coords = PieceUtils.GetCoords(currentPiece, currentRotation);

            for (int i = 0; i < coords.Length; i++)
            {
                var coord = coords[i];
                coord.x += currentX + dirX;
                coord.y += currentY + dirY;

                if (coord.x < 0)
                {
                    return(true);
                }

                if (coord.x >= BoardWidth)
                {
                    return(true);
                }

                if (coord.y >= BoardHeight)
                {
                    return(true);
                }

                if (ValidCoord(coord.x, coord.y))
                {
                    var offset = coord.x + coord.y * BoardWidth;
                    if (board[offset] > 0)
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
Beispiel #3
0
        public override void Update(ConsoleInputState input)
        {
            var blitter = Console.Blitter;

            for (int i = 0; i < Console.LayerCount; i++)
            {
                blitter.Reset();
                blitter.SetTargetLayer((byte)i);

                blitter.SetRenderMode(RetroPixelMode.Depth);
                blitter.Clear(0);

                blitter.SetRenderMode(RetroPixelMode.Brightness);
                blitter.Clear(128);

                blitter.SetRenderMode(RetroPixelMode.Color);
                blitter.Clear((byte)(i == 0 ? 5 : 0));
            }

            switch (menuState)
            {
            case MenuState.Error:
            {
                blitter.Reset();

                int  textPos   = 8;
                byte textColor = 1;

                blitter.EnableDropShadow(RetroDropShadowFlags.Right | RetroDropShadowFlags.Down, 2);
                blitter.DrawText(textPos, 4, "ERROR", fontTileset, textColor);
                blitter.DrawText(textPos, 16, errorMsg, fontTileset, textColor);
                blitter.DisableDropShadow();
            }
            break;

            case MenuState.Wait:
            {
                blitter.Reset();

                int  textPos   = 8;
                byte textColor = 1;

                blitter.EnableDropShadow(RetroDropShadowFlags.Right | RetroDropShadowFlags.Down, 2);
                blitter.DrawText(textPos, 4, "Waiting for wallet...", fontTileset, textColor);
                blitter.DisableDropShadow();
            }
            break;

            case MenuState.Boards:
            {
                currentBoard = boardList[boardIndex];

                blitter.Reset();

                int  textPos   = 8;
                int  lineSkip  = 12;
                byte textColor = 1;

                blitter.DrawLine(4, lineSkip + 2, Console.ResolutionX - 4, lineSkip + 2, 4);

                blitter.EnableDropShadow(RetroDropShadowFlags.Right | RetroDropShadowFlags.Down, 2);
                for (int i = 0; i < 3; i++)
                {
                    string caption;
                    string value;

                    switch (i)
                    {
                    case 0:
                        caption = "Board";
                        value   = $"\"{currentBoard.Name}\"";
                        break;

                    case 1:
                        caption = "Cost";
                        value   = $"{UnitConversion.ToDecimal(currentBoard.Cost, currentBoard.Decimals)} {currentBoard.Symbol}";
                        break;

                    case 2:
                        caption = "Pot";
                        value   = $"{UnitConversion.ToDecimal(currentBoard.Pot, currentBoard.Decimals)} {currentBoard.Symbol}";
                        break;

                    default:
                        caption = "???";
                        value   = "";
                        break;
                    }

                    blitter.DrawText(textPos, lineSkip * i, caption, fontTileset, textColor);
                    blitter.DrawText(textPos + 100, lineSkip * i, value, fontTileset, textColor);
                }

                blitter.DisableDropShadow();

                //blitter.DrawTile(80, 10, iconTileset, 0);

                if (input.pressed.HasFlag(ConsoleInputFlags.Left))
                {
                    boardIndex--;
                    if (boardIndex < 0)
                    {
                        boardIndex = boardList.Count - 1;
                    }
                }
                else
                if (input.pressed.HasFlag(ConsoleInputFlags.Right))
                {
                    boardIndex++;
                    if (boardIndex >= boardList.Count)
                    {
                        boardIndex = 0;
                    }
                }
                else
                if (input.pressed.HasFlag(ConsoleInputFlags.A))
                {
                    menuState = MenuState.Wait;

                    var address = wallet.GetAddress();
                    var script  = new ScriptBuilder().
                                  AllowGas(address, Address.Null, 100000, 999).
                                  CallContract("tetros", "StartGame", currentBoard.Name).
                                  SpendGas(address).
                                  EndScript();
                    wallet.ExecuteTransaction($"Pay {UnitConversion.ToDecimal(currentBoard.Cost, currentBoard.Decimals)} {currentBoard.Symbol} to start match", script, "lunar", (hash) =>
                        {
                            if (hash != Hash.Null)
                            {
                                menuState = MenuState.Game;
                                ClearBoard();
                            }
                            else
                            {
                                PushError("Could not pay :(");
                            }
                        });
                    return;
                }

                break;
            }

            case MenuState.Game:
            {
                int boardOfsX = 4;
                int boardOfsY = PieceSize;

                var currentSpeed = 1 + lines / 100;
                if (currentSpeed > MaxSpeed)
                {
                    currentSpeed = MaxSpeed;
                }

                // draw board
                blitter.Reset();
                byte borderColor = 2;
                var  boardTop    = boardOfsY;
                var  boardBottom = boardOfsY + BoardHeight * PieceSize;
                var  boardLeft   = boardOfsX;
                var  boardRight  = boardOfsX + BoardWidth * PieceSize;
                blitter.DrawLine(boardLeft, boardBottom, boardRight, boardBottom, borderColor);
                blitter.DrawLine(boardLeft, boardTop, boardLeft, boardBottom, borderColor);
                blitter.DrawLine(boardRight, boardTop, boardRight, boardBottom, borderColor);

                for (int j = 0; j < BoardHeight; j++)
                {
                    for (int i = 0; i < BoardWidth; i++)
                    {
                        var color = board[i + j * BoardWidth];
                        if (color > 0)
                        {
                            blitter.DrawTile(boardOfsX + i * PieceSize, boardOfsY + j * PieceSize, blockTileset, gameover ? 0 : color);
                        }
                    }
                }

                if (!gameover)
                {
                    if (merging)
                    {
                        var nextTime = mergeTime + 5;

                        if (Console.FrameCounter >= nextTime)
                        {
                            do
                            {
                                bool full = true;

                                for (int i = 0; i < BoardWidth; i++)
                                {
                                    var offset = i + mergeY * BoardWidth;
                                    if (board[offset] == 0)
                                    {
                                        full = false;
                                        break;
                                    }
                                }

                                if (full)
                                {
                                    var offset = (BoardWidth - 1) + mergeY * BoardWidth;

                                    while (offset > BoardWidth)
                                    {
                                        board[offset] = board[offset - BoardWidth];
                                        offset--;
                                    }

                                    mergeCombo++;
                                    break;
                                }
                                else
                                {
                                    mergeY--;
                                }
                            } while (mergeY > 0);

                            if (mergeY <= 0)
                            {
                                merging = false;

                                if (mergeCombo > 0)
                                {
                                    int bonus;

                                    switch (mergeCombo)
                                    {
                                    case 1:
                                        bonus = 40;
                                        break;

                                    case 2:
                                        bonus = 100;
                                        break;

                                    case 3:
                                        bonus = 300;
                                        break;

                                    default:
                                        bonus = 1200;
                                        break;
                                    }

                                    var dropDistance = dropping ? currentY - dropY : 0;
                                    bonus += dropDistance;

                                    score += bonus;
                                    lines += mergeCombo;
                                }

                                GeneratePiece();
                            }
                            else
                            {
                                mergeTime = Console.FrameCounter;
                            }
                        }
                    }
                    else
                    {
                        int dropSpeed = dropping ? 0 : (MaxSpeed - currentSpeed);
                        var nextTime  = currentTime + dropSpeed;
                        if (Console.FrameCounter >= nextTime)
                        {
                            currentTime = Console.FrameCounter;

                            if (HasCollision(0, 1))
                            {
                                MergePiece();
                            }
                            else
                            {
                                currentY++;
                            }
                        }

                        var coords = PieceUtils.GetCoords(currentPiece, currentRotation);

                        var  delta = (Console.FrameCounter - spawnTime) / 16f;
                        byte alpha;
                        if (delta > 1)
                        {
                            alpha = 255;
                        }
                        else
                        {
                            alpha = (byte)(delta * 255);
                        }

                        // draw falling piece
                        blitter.Reset();
                        for (int i = 0; i < coords.Length; i++)
                        {
                            var coord = coords[i];
                            coord.x += currentX;
                            coord.y += currentY;
                            blitter.DrawTile(boardOfsX + coord.x * PieceSize, boardOfsY + coord.y * PieceSize, blockTileset, 1 + currentIndex % 7, RetroTransform.None, alpha);
                        }
                    }
                }

                if (!gameover)
                {
                    if (!dropping && input.pressed.HasFlag(ConsoleInputFlags.Left))
                    {
                        if (!HasCollision(-1, 0))
                        {
                            currentX--;
                        }
                    }
                    else
                    if (!dropping && input.pressed.HasFlag(ConsoleInputFlags.Right))
                    {
                        if (!HasCollision(1, 0))
                        {
                            currentX++;
                        }
                    }
                    else
                    if (!dropping && input.pressed.HasFlag(ConsoleInputFlags.Down))
                    {
                        dropping = true;
                        dropY    = currentY;
                    }
                    else
                    if (input.pressed.HasFlag(ConsoleInputFlags.Up))
                    {
                        var prevRot = currentRotation;

                        int maxRotation;

                        switch (currentPiece)
                        {
                        case PieceKind.TrioL:
                            maxRotation = 3;
                            break;

                        case PieceKind.TetraO:
                            maxRotation = 0;
                            break;

                        default:
                            maxRotation = 4;
                            break;
                        }

                        currentRotation++;
                        if (currentRotation >= maxRotation)
                        {
                            currentRotation = 0;
                        }

                        if (HasCollision(0, 0))
                        {
                            currentRotation = prevRot;
                        }
                    }
                }
                else
                {
                    if (input.pressed.HasFlag(ConsoleInputFlags.A))
                    {
                        menuState = MenuState.Boards;
                    }
                }

                var textPos = boardRight + 4;

                DrawTextLine(textPos, 0, "Score", score);
                DrawTextLine(textPos, 1, "Lines", lines);
                DrawTextLine(textPos, 2, "Speed", currentSpeed);

                break;
            }
            }
        }