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)); }
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); }
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; } } }