Fix game over, add username and persistent scoreboard
This commit is contained in:
parent
17f1d0f108
commit
51cd3adb9c
13 changed files with 247 additions and 17 deletions
42
Tetris/Migrations/20220607174015_initialSetup.Designer.cs
generated
Normal file
42
Tetris/Migrations/20220607174015_initialSetup.Designer.cs
generated
Normal file
|
@ -0,0 +1,42 @@
|
|||
// <auto-generated />
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using Tetris.Models;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Tetris.Migrations
|
||||
{
|
||||
[DbContext(typeof(ScoreContext))]
|
||||
[Migration("20220607174015_initialSetup")]
|
||||
partial class initialSetup
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder.HasAnnotation("ProductVersion", "7.0.0-preview.4.22229.2");
|
||||
|
||||
modelBuilder.Entity("Tetris.Models.Score", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("Points")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("UserName")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Scores");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
35
Tetris/Migrations/20220607174015_initialSetup.cs
Normal file
35
Tetris/Migrations/20220607174015_initialSetup.cs
Normal file
|
@ -0,0 +1,35 @@
|
|||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Tetris.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class initialSetup : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Scores",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "INTEGER", nullable: false)
|
||||
.Annotation("Sqlite:Autoincrement", true),
|
||||
Points = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
UserName = table.Column<string>(type: "TEXT", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Scores", x => x.Id);
|
||||
});
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "Scores");
|
||||
}
|
||||
}
|
||||
}
|
39
Tetris/Migrations/ScoreContextModelSnapshot.cs
Normal file
39
Tetris/Migrations/ScoreContextModelSnapshot.cs
Normal file
|
@ -0,0 +1,39 @@
|
|||
// <auto-generated />
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using Tetris.Models;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Tetris.Migrations
|
||||
{
|
||||
[DbContext(typeof(ScoreContext))]
|
||||
partial class ScoreContextModelSnapshot : ModelSnapshot
|
||||
{
|
||||
protected override void BuildModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder.HasAnnotation("ProductVersion", "7.0.0-preview.4.22229.2");
|
||||
|
||||
modelBuilder.Entity("Tetris.Models.Score", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("Points")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("UserName")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Scores");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
|
@ -28,6 +28,16 @@ public class Game : INotifyPropertyChanged {
|
|||
}
|
||||
}
|
||||
|
||||
private bool _playing = true;
|
||||
|
||||
public bool Playing {
|
||||
get => _playing;
|
||||
set {
|
||||
_playing = value;
|
||||
OnPropertyChanged("Playing");
|
||||
}
|
||||
}
|
||||
|
||||
private Grid _grid;
|
||||
|
||||
public Grid Grid => _grid;
|
||||
|
@ -78,8 +88,14 @@ public class Game : INotifyPropertyChanged {
|
|||
return;
|
||||
|
||||
_grid.PrintTetrominoe(_currentTetrominoe);
|
||||
_currentTetrominoe = _nextTetrominoe;
|
||||
_nextTetrominoe = GetNewTetrominoe();
|
||||
|
||||
if (Playing) {
|
||||
_currentTetrominoe = _nextTetrominoe;
|
||||
_nextTetrominoe = GetNewTetrominoe();
|
||||
} else {
|
||||
_currentTetrominoe = null;
|
||||
_nextTetrominoe = null;
|
||||
}
|
||||
}
|
||||
|
||||
public Tetrominoe GetNewTetrominoe() {
|
||||
|
@ -87,6 +103,14 @@ public class Game : INotifyPropertyChanged {
|
|||
return new Tetrominoe(_grid, tetrominoes[_random.Next(tetrominoes.Count)]);
|
||||
}
|
||||
|
||||
public void SaveGame() {
|
||||
Console.WriteLine("Game over");
|
||||
using var db = new ScoreContext();
|
||||
var score = new Score{Points = Score, UserName = UserName};
|
||||
db.Scores.Add(score);
|
||||
db.SaveChanges();
|
||||
}
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
protected virtual void OnPropertyChanged(string propertyName)
|
||||
|
|
11
Tetris/Models/Score.cs
Normal file
11
Tetris/Models/Score.cs
Normal file
|
@ -0,0 +1,11 @@
|
|||
namespace Tetris.Models;
|
||||
|
||||
public class Score {
|
||||
public int Id { get; set; }
|
||||
public int Points { get; set; }
|
||||
public string UserName { get; set; }
|
||||
|
||||
public override string ToString() {
|
||||
return UserName + ": " + Points;
|
||||
}
|
||||
}
|
12
Tetris/Models/ScoreContext.cs
Normal file
12
Tetris/Models/ScoreContext.cs
Normal file
|
@ -0,0 +1,12 @@
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Tetris.Models;
|
||||
|
||||
public class ScoreContext : DbContext {
|
||||
public DbSet<Score> Scores { get; set; }
|
||||
|
||||
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
||||
{
|
||||
optionsBuilder.UseSqlite(@"Data Source=.\Resources\db.sl3");
|
||||
}
|
||||
}
|
|
@ -20,11 +20,21 @@
|
|||
<EmbeddedResource Include="Resources\tetrominoes.json">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</EmbeddedResource>
|
||||
<None Remove="Resources\db.sl3" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="EntityFramework" Version="6.4.4" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.0-preview.4.22229.2" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.0-preview.4.22229.2">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.0-preview.4.22229.2" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||
<PackageReference Include="Pastel" Version="3.0.0" />
|
||||
<PackageReference Include="System.Configuration.ConfigurationManager" Version="7.0.0-preview.4.22229.4" />
|
||||
<PackageReference Include="System.Data.SQLite.EF6" Version="1.0.116" />
|
||||
<PackageReference Include="WriteableBitmapEx" Version="1.6.8" />
|
||||
</ItemGroup>
|
||||
|
||||
|
|
|
@ -6,7 +6,19 @@
|
|||
mc:Ignorable="d"
|
||||
Title="GameWindow" Width="{Binding Width}" Height="{Binding Height}" KeyDown="UIElement_OnKeyDown">
|
||||
<Grid Background="Black">
|
||||
<TextBlock Text="{Binding ScoreText}" Foreground="White" FontSize="32" />
|
||||
<StackPanel>
|
||||
<TextBlock Text="{Binding ScoreText}" Foreground="White" FontSize="32" />
|
||||
<TextBlock Text="{Binding UserNameText}" Foreground="White" FontSize="32" />
|
||||
<TextBlock Text="Scoreboard :" Foreground="White" FontSize="32" Margin="0 10 0 0" />
|
||||
<ListView ItemsSource="{Binding ScoreBoard}" Background="Black" HorizontalAlignment="Left" MaxWidth="500">
|
||||
<ListView.ItemContainerStyle>
|
||||
<Style TargetType="{x:Type ListViewItem}">
|
||||
<Setter Property="Background" Value="Black" />
|
||||
<Setter Property="Foreground" Value="White" />
|
||||
</Style>
|
||||
</ListView.ItemContainerStyle>
|
||||
</ListView>
|
||||
</StackPanel>
|
||||
<Image Source="{Binding Source}" />
|
||||
</Grid>
|
||||
</Window>
|
|
@ -13,11 +13,19 @@ public partial class GameWindow
|
|||
DataContext = new GameViewModel();
|
||||
}
|
||||
|
||||
public void Start(string userName) {
|
||||
GameViewModel.Game.UserName = userName;
|
||||
Show();
|
||||
}
|
||||
|
||||
[DllImport("kernel32.dll")]
|
||||
private static extern bool AttachConsole(int dwProcessId);
|
||||
|
||||
private void UIElement_OnKeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (!GameViewModel.Game.Playing)
|
||||
return;
|
||||
|
||||
switch (e.Key)
|
||||
{
|
||||
// If key is space
|
||||
|
|
|
@ -10,7 +10,12 @@
|
|||
<Grid>
|
||||
<Image Source="pack://application:,,,/Resources/tetris.png" Stretch="Fill" HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center" />
|
||||
<Button Click="StartButton_OnClick" HorizontalAlignment="Center" VerticalAlignment="Center" Width="100"
|
||||
Height="50" Content="Start" Margin="0 200 0 0" />
|
||||
<StackPanel>
|
||||
<TextBox HorizontalAlignment="Center" VerticalAlignment="Center" TextAlignment="Center" Width="100"
|
||||
Height="20" Margin="0 200 0 0" Name="UserName" Text="{Binding UserName, Mode=TwoWay,
|
||||
UpdateSourceTrigger=LostFocus}" />
|
||||
<Button Click="StartButton_OnClick" HorizontalAlignment="Center" VerticalAlignment="Center" Width="100"
|
||||
Height="50" Content="Start" Margin="0 10 0 0" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Window>
|
|
@ -1,6 +1,8 @@
|
|||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Tetris.Models;
|
||||
using Tetris.ViewsModels;
|
||||
|
||||
namespace Tetris.Views;
|
||||
|
@ -10,8 +12,9 @@ namespace Tetris.Views;
|
|||
/// </summary>
|
||||
public partial class MainWindow
|
||||
{
|
||||
public MainWindow()
|
||||
{
|
||||
public MainWindow() {
|
||||
using var db = new ScoreContext();
|
||||
db.Database.Migrate();
|
||||
AttachConsole(-1);
|
||||
DataContext = new ViewModel();
|
||||
InitializeComponent();
|
||||
|
@ -23,7 +26,7 @@ public partial class MainWindow
|
|||
private void StartButton_OnClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Console.WriteLine("Start game...");
|
||||
new GameWindow().Show();
|
||||
new GameWindow().Start(((ViewModel) DataContext).UserName);
|
||||
Close();
|
||||
}
|
||||
}
|
|
@ -1,8 +1,7 @@
|
|||
|
||||
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Windows.Controls;
|
||||
using System.Linq;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Threading;
|
||||
|
@ -30,12 +29,11 @@ public class GameViewModel : INotifyPropertyChanged
|
|||
private readonly int _height = (Game.Grid.MaxGrid.Y + 1) * Multiplier;
|
||||
private readonly WriteableBitmap _writeableBitmap;
|
||||
private readonly int _colorLine = 0xFFFFFF;
|
||||
private bool _isPaused;
|
||||
private uint _countDown;
|
||||
private string _scoreText = "";
|
||||
private string _userNameText = "";
|
||||
|
||||
public GameViewModel()
|
||||
{
|
||||
public GameViewModel() {
|
||||
_writeableBitmap = BitmapFactory.New(_width, _height);
|
||||
|
||||
var dispatcherRenderTimer = new DispatcherTimer
|
||||
|
@ -67,11 +65,29 @@ public class GameViewModel : INotifyPropertyChanged
|
|||
}
|
||||
}
|
||||
|
||||
public List<Score> ScoreBoard {
|
||||
get {
|
||||
using var db = new ScoreContext();
|
||||
return db.Scores.ToList();
|
||||
}
|
||||
}
|
||||
|
||||
public string UserNameText
|
||||
{
|
||||
get => _userNameText;
|
||||
set
|
||||
{
|
||||
_userNameText = value;
|
||||
OnPropertyChanged("UserNameText");
|
||||
}
|
||||
}
|
||||
|
||||
private void Render(object? sender, EventArgs eventArgs)
|
||||
{
|
||||
_writeableBitmap.Lock();
|
||||
_writeableBitmap.Clear(Colors.Black);
|
||||
ScoreText = "Score: " + Game.Score;
|
||||
UserNameText = "Username: " + Game.UserName;
|
||||
|
||||
var colorGrid = Game.Grid.CGrid;
|
||||
for (var x = 0; x < Game.Grid.MaxGrid.X + 1; x++)
|
||||
|
@ -113,7 +129,7 @@ public class GameViewModel : INotifyPropertyChanged
|
|||
|
||||
private void Update(object? sender, EventArgs eventArgs)
|
||||
{
|
||||
if (_isPaused)
|
||||
if (!Game.Playing)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -135,7 +151,9 @@ public class GameViewModel : INotifyPropertyChanged
|
|||
|
||||
if (Game.HitTop())
|
||||
{
|
||||
_isPaused = true;
|
||||
Game.Playing = false;
|
||||
Game.PrintTetrominoe();
|
||||
Game.SaveGame();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,6 +6,17 @@ public class ViewModel : INotifyPropertyChanged
|
|||
{
|
||||
public event PropertyChangedEventHandler? PropertyChanged;
|
||||
|
||||
private string _userName = "Player";
|
||||
|
||||
public string UserName {
|
||||
get { return _userName; }
|
||||
set
|
||||
{
|
||||
_userName = value;
|
||||
OnPropertyChanged("UserName");
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void OnPropertyChanged(string propertyName)
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
|
|
Reference in a new issue