Archived
1
0
Fork 0

Fix game over, add username and persistent scoreboard

This commit is contained in:
Ethanell 2022-06-07 19:48:44 +02:00
parent 17f1d0f108
commit 51cd3adb9c
13 changed files with 247 additions and 17 deletions

View 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
}
}
}

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

View 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
}
}
}

View file

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

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

View file

@ -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>

View file

@ -6,7 +6,19 @@
mc:Ignorable="d"
Title="GameWindow" Width="{Binding Width}" Height="{Binding Height}" KeyDown="UIElement_OnKeyDown">
<Grid Background="Black">
<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>

View file

@ -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

View file

@ -10,7 +10,12 @@
<Grid>
<Image Source="pack://application:,,,/Resources/tetris.png" Stretch="Fill" HorizontalAlignment="Center"
VerticalAlignment="Center" />
<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 200 0 0" />
Height="50" Content="Start" Margin="0 10 0 0" />
</StackPanel>
</Grid>
</Window>

View file

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

View file

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

View file

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