From f238c1a720adfcde85cf857d730e4aff5a99cdb8 Mon Sep 17 00:00:00 2001 From: Ziedelth Date: Thu, 7 Apr 2022 15:30:48 +0200 Subject: [PATCH 1/5] Change to binding element --- Views/GameWindow.xaml | 4 +- Views/GameWindow.xaml.cs | 2 +- .../{GameModel.cs => GameViewModel.cs} | 103 ++++++++++-------- 3 files changed, 58 insertions(+), 51 deletions(-) rename ViewsModels/{GameModel.cs => GameViewModel.cs} (70%) diff --git a/Views/GameWindow.xaml b/Views/GameWindow.xaml index 66e917f..6c1731d 100644 --- a/Views/GameWindow.xaml +++ b/Views/GameWindow.xaml @@ -4,8 +4,8 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" mc:Ignorable="d" - Title="GameWindow" Height="450" Width="800"> + Title="GameWindow" Width="{Binding Width}" Height="{Binding Height}"> - + \ No newline at end of file diff --git a/Views/GameWindow.xaml.cs b/Views/GameWindow.xaml.cs index 2d3ddcf..616691a 100644 --- a/Views/GameWindow.xaml.cs +++ b/Views/GameWindow.xaml.cs @@ -10,7 +10,7 @@ public partial class GameWindow : Window { AttachConsole(-1); InitializeComponent(); - new GameModel((int)Width, (int)Height, ImageControl); + DataContext = new GameViewModel(); } [DllImport("kernel32.dll")] diff --git a/ViewsModels/GameModel.cs b/ViewsModels/GameViewModel.cs similarity index 70% rename from ViewsModels/GameModel.cs rename to ViewsModels/GameViewModel.cs index 6e8771e..3069105 100644 --- a/ViewsModels/GameModel.cs +++ b/ViewsModels/GameViewModel.cs @@ -1,49 +1,56 @@ -using System; -using System.Windows.Controls; -using System.Windows.Media; -using System.Windows.Media.Imaging; -using System.Windows.Threading; - -namespace Tetris.ViewsModels; - -public class GameModel -{ - private const int RendererHertz = 5; - private const int GameRendererHertz = (1 / RendererHertz) * 1000; - private readonly WriteableBitmap _writeableBitmap; - - public GameModel(int width, int height, Image image) - { - _writeableBitmap = BitmapFactory.New(width, height); - image.Source = _writeableBitmap; - - 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, 25) - }; - - dispatcherUpdateTimer.Tick += Update; - dispatcherUpdateTimer.Start(); - } - - private void Render(object? sender, EventArgs eventArgs) - { - _writeableBitmap.Lock(); - _writeableBitmap.Clear(Colors.Black); - - _writeableBitmap.Unlock(); - } - - private void Update(object? sender, EventArgs eventArgs) - { - - } +using System; +using System.ComponentModel; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Threading; + +namespace Tetris.ViewsModels; + +public class GameViewModel : INotifyPropertyChanged +{ + public event PropertyChangedEventHandler? PropertyChanged; + + private const int RendererHertz = 5; + private const int GameRendererHertz = (1 / RendererHertz) * 1000; + private readonly int _width = 480, _height = 640; + private readonly WriteableBitmap _writeableBitmap; + + public GameViewModel() + { + _writeableBitmap = BitmapFactory.New(_width, _height); + // image.Source = _writeableBitmap; + + 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, 25) + }; + + dispatcherUpdateTimer.Tick += Update; + dispatcherUpdateTimer.Start(); + } + + public int Width => _width; + public int Height => _height; + public ImageSource Source => _writeableBitmap; + + private void Render(object? sender, EventArgs eventArgs) + { + _writeableBitmap.Lock(); + _writeableBitmap.Clear(Colors.Black); + + _writeableBitmap.Unlock(); + } + + private void Update(object? sender, EventArgs eventArgs) + { + + } } \ No newline at end of file From 1c80d4c05ab9b5a3112592c97802c4c91f746ce3 Mon Sep 17 00:00:00 2001 From: Ziedelth Date: Thu, 7 Apr 2022 17:24:00 +0200 Subject: [PATCH 2/5] Update --- Models/Grid.cs | 2 ++ ViewsModels/GameViewModel.cs | 37 +++++++++++++++++++++++++++++++++--- 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/Models/Grid.cs b/Models/Grid.cs index d4adda9..976b479 100644 --- a/Models/Grid.cs +++ b/Models/Grid.cs @@ -8,6 +8,8 @@ namespace Tetris.Models; public class Grid { private Color[,] _grid; + public Color[,] CGrid => (Color[,]) _grid.Clone(); + public Point MinGrid => new Point(0,0); public Point MaxGrid => new Point(_grid.GetLength(0)-1, _grid.GetLength(1)-1); diff --git a/ViewsModels/GameViewModel.cs b/ViewsModels/GameViewModel.cs index 3069105..3fdbbf7 100644 --- a/ViewsModels/GameViewModel.cs +++ b/ViewsModels/GameViewModel.cs @@ -1,8 +1,13 @@ -using System; + + +using System; using System.ComponentModel; +using System.Drawing; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Threading; +using Tetris.Models; +using Color = System.Drawing.Color; namespace Tetris.ViewsModels; @@ -15,10 +20,14 @@ public class GameViewModel : INotifyPropertyChanged private readonly int _width = 480, _height = 640; private readonly WriteableBitmap _writeableBitmap; + private const int GridWidth = 10; + private const int GridHeight = 20; + private static readonly Grid Grid = new(new Color[GridWidth, GridHeight]); + private readonly Tetrominoe _currentTetrominoe = new(Grid, "J", new Point(10, 10), 0, Color.Aqua); + public GameViewModel() { _writeableBitmap = BitmapFactory.New(_width, _height); - // image.Source = _writeableBitmap; var dispatcherRenderTimer = new DispatcherTimer { @@ -46,11 +55,33 @@ public class GameViewModel : INotifyPropertyChanged _writeableBitmap.Lock(); _writeableBitmap.Clear(Colors.Black); + for (var x = 0; x < GridWidth; x++) + { + for (var y = 0; y < GridHeight; y++) + { + var color = Grid.CGrid[x, y]; + _writeableBitmap.SetPixel(x, y, color.R, color.G, color.B); + } + } + + var tetrominoeWidth = _currentTetrominoe.Shape.GetLength(0); + var tetrominoeHeight = _currentTetrominoe.Shape.GetLength(1); + + for (int x = 0; x < tetrominoeWidth; x++) + { + for (int y = 0; y < tetrominoeHeight; y++) + { + if (!_currentTetrominoe.Shape[x, y]) continue; + var color = _currentTetrominoe.Color; + _writeableBitmap.FillRectangle(_currentTetrominoe.Coordinates.X * 10, _currentTetrominoe.Coordinates.Y * 10, _currentTetrominoe.Coordinates.X * 10 + 10, _currentTetrominoe.Coordinates.Y * 10 + 10, color.ToArgb()); + } + } + _writeableBitmap.Unlock(); } private void Update(object? sender, EventArgs eventArgs) { - + _currentTetrominoe.GoDown(); } } \ No newline at end of file From 562589fc723569bdff1a616798bbb83b3b8465d3 Mon Sep 17 00:00:00 2001 From: Ziedelth Date: Wed, 4 May 2022 10:40:15 +0200 Subject: [PATCH 3/5] Fix and update --- Views/GameWindow.xaml | 4 ++-- Views/GameWindow.xaml.cs | 35 +++++++++++++++++++++++++++++++++-- ViewsModels/GameViewModel.cs | 21 +++++++++++---------- 3 files changed, 46 insertions(+), 14 deletions(-) diff --git a/Views/GameWindow.xaml b/Views/GameWindow.xaml index 6c1731d..4014365 100644 --- a/Views/GameWindow.xaml +++ b/Views/GameWindow.xaml @@ -4,8 +4,8 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" mc:Ignorable="d" - Title="GameWindow" Width="{Binding Width}" Height="{Binding Height}"> - + Title="GameWindow" Width="{Binding Width}" Height="{Binding Height}" KeyDown="UIElement_OnKeyDown"> + \ No newline at end of file diff --git a/Views/GameWindow.xaml.cs b/Views/GameWindow.xaml.cs index 616691a..6c7f75d 100644 --- a/Views/GameWindow.xaml.cs +++ b/Views/GameWindow.xaml.cs @@ -1,18 +1,49 @@ -using System.Runtime.InteropServices; +using System; +using System.Runtime.InteropServices; using System.Windows; +using System.Windows.Input; using Tetris.ViewsModels; namespace Tetris.Views; public partial class GameWindow : Window { + private static readonly GameViewModel GameViewModel = new GameViewModel(); + public GameWindow() { AttachConsole(-1); InitializeComponent(); - DataContext = new GameViewModel(); + DataContext = GameViewModel; } [DllImport("kernel32.dll")] private static extern bool AttachConsole(int dwProcessId); + + private void UIElement_OnKeyDown(object sender, KeyEventArgs e) + { + // If key is space + if (e.Key == Key.Space) + { + GameViewModel.CurrentTetrominoe.RotateRight(); + } + + // If key is down + else if (e.Key == Key.Down) + { + GameViewModel.CurrentTetrominoe.GoDown(); + } + + // If key is left + else if (e.Key == Key.Left) + { + GameViewModel.CurrentTetrominoe.GoLeft(); + } + + // If key is right + else if (e.Key == Key.Right) + { + GameViewModel.CurrentTetrominoe.GoRight(); + } + } } \ No newline at end of file diff --git a/ViewsModels/GameViewModel.cs b/ViewsModels/GameViewModel.cs index 3fdbbf7..201319b 100644 --- a/ViewsModels/GameViewModel.cs +++ b/ViewsModels/GameViewModel.cs @@ -3,6 +3,7 @@ using System; using System.ComponentModel; using System.Drawing; +using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Threading; @@ -17,17 +18,18 @@ public class GameViewModel : INotifyPropertyChanged private const int RendererHertz = 5; private const int GameRendererHertz = (1 / RendererHertz) * 1000; - private readonly int _width = 480, _height = 640; + private const int Width = 25; + private const int Height = 50; private readonly WriteableBitmap _writeableBitmap; - private const int GridWidth = 10; - private const int GridHeight = 20; + private const int GridWidth = 25; + private const int GridHeight = 50; private static readonly Grid Grid = new(new Color[GridWidth, GridHeight]); - private readonly Tetrominoe _currentTetrominoe = new(Grid, "J", new Point(10, 10), 0, Color.Aqua); + private readonly Tetrominoe _currentTetrominoe = new(Grid, "J", new Point(25 / 2, 0), 0, Color.Aqua); public GameViewModel() { - _writeableBitmap = BitmapFactory.New(_width, _height); + _writeableBitmap = BitmapFactory.New(Width, Height); var dispatcherRenderTimer = new DispatcherTimer { @@ -39,16 +41,15 @@ public class GameViewModel : INotifyPropertyChanged var dispatcherUpdateTimer = new DispatcherTimer { - Interval = new TimeSpan(0, 0, 0, 0, 25) + Interval = new TimeSpan(0, 0, 0, 0, 100) }; dispatcherUpdateTimer.Tick += Update; dispatcherUpdateTimer.Start(); } - - public int Width => _width; - public int Height => _height; + public ImageSource Source => _writeableBitmap; + public Tetrominoe CurrentTetrominoe => _currentTetrominoe; private void Render(object? sender, EventArgs eventArgs) { @@ -73,7 +74,7 @@ public class GameViewModel : INotifyPropertyChanged { if (!_currentTetrominoe.Shape[x, y]) continue; var color = _currentTetrominoe.Color; - _writeableBitmap.FillRectangle(_currentTetrominoe.Coordinates.X * 10, _currentTetrominoe.Coordinates.Y * 10, _currentTetrominoe.Coordinates.X * 10 + 10, _currentTetrominoe.Coordinates.Y * 10 + 10, color.ToArgb()); + _writeableBitmap.SetPixel(_currentTetrominoe.Coordinates.X + x, _currentTetrominoe.Coordinates.Y + y, color.R, color.G, color.B); } } From 38e3b197baa801538cfb00507e34f9d14ca2d192 Mon Sep 17 00:00:00 2001 From: Ziedelth Date: Wed, 4 May 2022 11:08:04 +0200 Subject: [PATCH 4/5] Add HD --- Views/GameWindow.xaml.cs | 10 ++++----- ViewsModels/GameViewModel.cs | 41 +++++++++++++++++++----------------- 2 files changed, 27 insertions(+), 24 deletions(-) diff --git a/Views/GameWindow.xaml.cs b/Views/GameWindow.xaml.cs index 6c7f75d..dda3d64 100644 --- a/Views/GameWindow.xaml.cs +++ b/Views/GameWindow.xaml.cs @@ -8,7 +8,7 @@ namespace Tetris.Views; public partial class GameWindow : Window { - private static readonly GameViewModel GameViewModel = new GameViewModel(); + private static readonly GameViewModel GameViewModel = new(); public GameWindow() { @@ -25,25 +25,25 @@ public partial class GameWindow : Window // If key is space if (e.Key == Key.Space) { - GameViewModel.CurrentTetrominoe.RotateRight(); + GameViewModel.Game.CurrentTetrominoe?.RotateRight(); } // If key is down else if (e.Key == Key.Down) { - GameViewModel.CurrentTetrominoe.GoDown(); + GameViewModel.Game.CurrentTetrominoe?.GoDown(); } // If key is left else if (e.Key == Key.Left) { - GameViewModel.CurrentTetrominoe.GoLeft(); + GameViewModel.Game.CurrentTetrominoe?.GoLeft(); } // If key is right else if (e.Key == Key.Right) { - GameViewModel.CurrentTetrominoe.GoRight(); + GameViewModel.Game.CurrentTetrominoe?.GoRight(); } } } \ No newline at end of file diff --git a/ViewsModels/GameViewModel.cs b/ViewsModels/GameViewModel.cs index 201319b..5232abb 100644 --- a/ViewsModels/GameViewModel.cs +++ b/ViewsModels/GameViewModel.cs @@ -16,20 +16,18 @@ public class GameViewModel : INotifyPropertyChanged { public event PropertyChangedEventHandler? PropertyChanged; + public static readonly Game Game = new("...", new Grid(new Color[25, 50])); + private const int RendererHertz = 5; private const int GameRendererHertz = (1 / RendererHertz) * 1000; - private const int Width = 25; - private const int Height = 50; + 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; - private const int GridWidth = 25; - private const int GridHeight = 50; - private static readonly Grid Grid = new(new Color[GridWidth, GridHeight]); - private readonly Tetrominoe _currentTetrominoe = new(Grid, "J", new Point(25 / 2, 0), 0, Color.Aqua); - public GameViewModel() { - _writeableBitmap = BitmapFactory.New(Width, Height); + _writeableBitmap = BitmapFactory.New(_width, _height); var dispatcherRenderTimer = new DispatcherTimer { @@ -49,32 +47,32 @@ public class GameViewModel : INotifyPropertyChanged } public ImageSource Source => _writeableBitmap; - public Tetrominoe CurrentTetrominoe => _currentTetrominoe; private void Render(object? sender, EventArgs eventArgs) { _writeableBitmap.Lock(); _writeableBitmap.Clear(Colors.Black); - for (var x = 0; x < GridWidth; x++) + for (var x = 0; x < Game.Grid.MaxGrid.X + 1; x++) { - for (var y = 0; y < GridHeight; y++) + for (var y = 0; y < Game.Grid.MaxGrid.Y + 1; y++) { - var color = Grid.CGrid[x, y]; - _writeableBitmap.SetPixel(x, y, color.R, color.G, color.B); + var color = Game.Grid.CGrid[x, y]; + _writeableBitmap.FillRectangle(x * Multiplier, y * Multiplier, x * Multiplier + Multiplier, y * Multiplier + Multiplier, color.ToArgb()); } } - var tetrominoeWidth = _currentTetrominoe.Shape.GetLength(0); - var tetrominoeHeight = _currentTetrominoe.Shape.GetLength(1); + 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++) { - if (!_currentTetrominoe.Shape[x, y]) continue; - var color = _currentTetrominoe.Color; - _writeableBitmap.SetPixel(_currentTetrominoe.Coordinates.X + x, _currentTetrominoe.Coordinates.Y + y, color.R, color.G, color.B); + var currentPiece = Game.CurrentTetrominoe!; + if (currentPiece.Shape[x, y] == false) continue; + var color = currentPiece.Color; + _writeableBitmap.FillRectangle((currentPiece.Coordinates.X + x) * Multiplier, (currentPiece.Coordinates.Y + y) * Multiplier, (currentPiece.Coordinates.X + x) * Multiplier + Multiplier, (currentPiece.Coordinates.Y + y) * Multiplier + Multiplier, color.ToArgb()); } } @@ -83,6 +81,11 @@ public class GameViewModel : INotifyPropertyChanged private void Update(object? sender, EventArgs eventArgs) { - _currentTetrominoe.GoDown(); + Game.CurrentTetrominoe?.GoDown(); + + if (Game.HitBottom()) + { + Game.PrintTetrominoe(); + } } } \ No newline at end of file From f93055315a7e1a698de4cf4428774dabfb6beb85 Mon Sep 17 00:00:00 2001 From: Ziedelth Date: Wed, 4 May 2022 11:34:46 +0200 Subject: [PATCH 5/5] Update --- ViewsModels/GameViewModel.cs | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/ViewsModels/GameViewModel.cs b/ViewsModels/GameViewModel.cs index 5232abb..4d5aac4 100644 --- a/ViewsModels/GameViewModel.cs +++ b/ViewsModels/GameViewModel.cs @@ -2,8 +2,6 @@ using System; using System.ComponentModel; -using System.Drawing; -using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Threading; @@ -16,7 +14,7 @@ public class GameViewModel : INotifyPropertyChanged { public event PropertyChangedEventHandler? PropertyChanged; - public static readonly Game Game = new("...", new Grid(new Color[25, 50])); + public static readonly Game Game = new("...", new Grid(new Color[20, 40])); private const int RendererHertz = 5; private const int GameRendererHertz = (1 / RendererHertz) * 1000; @@ -53,12 +51,16 @@ public class GameViewModel : INotifyPropertyChanged _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++) { - var color = Game.Grid.CGrid[x, y]; - _writeableBitmap.FillRectangle(x * Multiplier, y * Multiplier, x * Multiplier + Multiplier, y * Multiplier + Multiplier, color.ToArgb()); + 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()); } } @@ -72,10 +74,13 @@ public class GameViewModel : INotifyPropertyChanged var currentPiece = Game.CurrentTetrominoe!; if (currentPiece.Shape[x, y] == false) continue; var color = currentPiece.Color; - _writeableBitmap.FillRectangle((currentPiece.Coordinates.X + x) * Multiplier, (currentPiece.Coordinates.Y + y) * Multiplier, (currentPiece.Coordinates.X + x) * Multiplier + Multiplier, (currentPiece.Coordinates.Y + y) * Multiplier + Multiplier, color.ToArgb()); + + 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(); }