using System; using System.ComponentModel; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Threading; using Tetris.Models; using Color = System.Drawing.Color; namespace Tetris.ViewsModels; public class GameViewModel : INotifyPropertyChanged { public event PropertyChangedEventHandler? PropertyChanged; public static readonly Game Game = new("...", new Grid(new Color[20, 40])); private const int RendererHertz = 5; private const int GameRendererHertz = (1 / RendererHertz) * 1000; private const int Multiplier = 10; private readonly int _width = (Game.Grid.MaxGrid.X + 1) * Multiplier; private readonly int _height = (Game.Grid.MaxGrid.Y + 1) * Multiplier; private readonly WriteableBitmap _writeableBitmap; public GameViewModel() { _writeableBitmap = BitmapFactory.New(_width, _height); var dispatcherRenderTimer = new DispatcherTimer { Interval = new TimeSpan(0, 0, 0, 0, GameRendererHertz) }; dispatcherRenderTimer.Tick += Render; dispatcherRenderTimer.Start(); var dispatcherUpdateTimer = new DispatcherTimer { Interval = new TimeSpan(0, 0, 0, 0, 100) }; dispatcherUpdateTimer.Tick += Update; dispatcherUpdateTimer.Start(); } public ImageSource Source => _writeableBitmap; private void Render(object? sender, EventArgs eventArgs) { _writeableBitmap.Lock(); _writeableBitmap.Clear(Colors.Black); var colorGrid = Game.Grid.CGrid; for (var x = 0; x < Game.Grid.MaxGrid.X + 1; x++) { for (var y = 0; y < Game.Grid.MaxGrid.Y + 1; y++) { if (colorGrid[x, y] == Color.Empty) continue; var startX = x * Multiplier; var startY = y * Multiplier; _writeableBitmap.FillRectangle(startX, startY, startX + Multiplier, startY + Multiplier, colorGrid[x, y].ToArgb()); } } var tetrominoeWidth = Game.CurrentTetrominoe?.Shape.GetLength(0); var tetrominoeHeight = Game.CurrentTetrominoe?.Shape.GetLength(1); for (int x = 0; x < tetrominoeWidth; x++) { for (int y = 0; y < tetrominoeHeight; y++) { var currentPiece = Game.CurrentTetrominoe!; if (currentPiece.Shape[x, y] == false) continue; var color = currentPiece.Color; var startX = (currentPiece.Coordinates.X + x) * Multiplier; var startY = (currentPiece.Coordinates.Y + y) * Multiplier; _writeableBitmap.FillRectangle(startX, startY, startX + Multiplier, startY + Multiplier, color.ToArgb()); } } _writeableBitmap.Unlock(); } private void Update(object? sender, EventArgs eventArgs) { Game.CurrentTetrominoe?.GoDown(); if (Game.HitBottom()) { Game.PrintTetrominoe(); } } }