Skip to content

Instantly share code, notes, and snippets.

@ScottLilly
Created March 5, 2021 21:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ScottLilly/73386968a73657e88185578006a43d9f to your computer and use it in GitHub Desktop.
Save ScottLilly/73386968a73657e88185578006a43d9f to your computer and use it in GitHub Desktop.
Lesson 18.5: Update game loading and saving
<Window x:Class="WPFUI.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:viewModels="clr-namespace:Engine.ViewModels;assembly=Engine"
d:DataContext="{d:DesignInstance viewModels:GameSession}"
mc:Ignorable="d"
FontSize="11pt"
Title="{Binding GameDetails.Title}" Height="768" Width="1024"
KeyDown="MainWindow_OnKeyDown"
Closing="MainWindow_OnClosing">
<Window.Resources>
<BooleanToVisibilityConverter x:Key="BooleanToVisibility" />
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="225"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="250"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<!-- Menu -->
<Menu Grid.Row="0" Grid.Column="0"
Grid.ColumnSpan="2"
FontSize="11pt"
Background="AliceBlue">
<MenuItem Header="File">
<MenuItem Header="New Game"
Click="StartNewGame_OnClick"/>
<MenuItem Header="Save Game"
Click="SaveGame_OnClick"/>
<Separator/>
<MenuItem Header="Exit"
Click="Exit_OnClick"/>
</MenuItem>
<MenuItem Header="Help">
<MenuItem Header="Help"
IsEnabled="False"/>
<Separator/>
<MenuItem Header="About"
IsEnabled="False"/>
</MenuItem>
</Menu>
<!-- Player stats -->
<Grid Grid.Row="1" Grid.Column="0" Background="Aquamarine">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Label Grid.Row="0" Grid.Column="0" Content="Name:"/>
<Label Grid.Row="0" Grid.Column="1" Content="{Binding CurrentPlayer.Name}"/>
<Label Grid.Row="1" Grid.Column="0" Content="Hit points:"/>
<Label Grid.Row="1" Grid.Column="1" Content="{Binding CurrentPlayer.CurrentHitPoints}"/>
<Label Grid.Row="2" Grid.Column="0" Content="Gold:"/>
<Label Grid.Row="2" Grid.Column="1" Content="{Binding CurrentPlayer.Gold}"/>
<Label Grid.Row="3" Grid.Column="0" Content="XP:"/>
<Label Grid.Row="3" Grid.Column="1" Content="{Binding CurrentPlayer.ExperiencePoints}"/>
<Label Grid.Row="4" Grid.Column="0" Content="Level:"/>
<Label Grid.Row="4" Grid.Column="1" Content="{Binding CurrentPlayer.Level}"/>
<!-- Player Attributes -->
<ListBox Grid.Row="5" Grid.Column="0"
Grid.ColumnSpan="2"
Background="Aquamarine"
BorderThickness="0"
Grid.IsSharedSizeScope="True"
ItemsSource="{Binding CurrentPlayer.Attributes}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="Description"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding DisplayName}"
HorizontalAlignment="Left"
MinWidth="100"/>
</Grid>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="ModifiedValue"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding ModifiedValue}"
HorizontalAlignment="Right"/>
</Grid>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
<!-- Gameplay -->
<Grid Grid.Row="1" Grid.Column="1"
Background="Beige">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="3*"/>
<ColumnDefinition Width="2*"/>
</Grid.ColumnDefinitions>
<!-- Game Messages -->
<Border Grid.Row="0" Grid.Column="0"
Grid.RowSpan="2"
BorderBrush="Gainsboro"
BorderThickness="1">
<RichTextBox x:Name="GameMessages"
Background="Beige"
VerticalScrollBarVisibility="Auto">
<RichTextBox.Resources>
<Style TargetType="{x:Type Paragraph}">
<Setter Property="Margin" Value="0"/>
</Style>
</RichTextBox.Resources>
</RichTextBox>
</Border>
<!-- Location information -->
<Border Grid.Row="0" Grid.Column="1"
BorderBrush="Gainsboro"
BorderThickness="1">
<Grid Margin="3">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0"
HorizontalAlignment="Center"
Text="{Binding CurrentLocation.Name}"/>
<Image Grid.Row="1"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Height="125"
Width="125"
Source="{Binding CurrentLocation.ImageName,
Converter={StaticResource FileToBitmapConverter}}"/>
<TextBlock Grid.Row="2"
HorizontalAlignment="Center"
Text="{Binding CurrentLocation.Description}"
TextWrapping="Wrap"/>
</Grid>
</Border>
<!-- Monster information -->
<Border Grid.Row="1" Grid.Column="1"
BorderBrush="Gainsboro"
BorderThickness="1">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock Grid.Row="0"
HorizontalAlignment="Center"
Height="Auto"
Text="{Binding CurrentMonster.Name}" />
<Image Grid.Row="1"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Height="125"
Width="125"
Source="{Binding CurrentMonster.ImageName,
Converter={StaticResource FileToBitmapConverter}}"/>
<StackPanel Grid.Row="2"
Visibility="{Binding HasMonster, Converter={StaticResource BooleanToVisibility}}"
HorizontalAlignment="Center"
Orientation="Horizontal">
<TextBlock>Current Hit Points:</TextBlock>
<TextBlock Text="{Binding CurrentMonster.CurrentHitPoints}" />
</StackPanel>
</Grid>
</Border>
</Grid>
<!-- Inventory, Quests, and Recipes -->
<Grid Grid.Row="2" Grid.Column="0"
Background="BurlyWood">
<TabControl x:Name="PlayerDataTabControl">
<TabItem Header="Inventory"
x:Name="InventoryTabItem">
<DataGrid ItemsSource="{Binding CurrentPlayer.Inventory.GroupedInventory}"
AutoGenerateColumns="False"
HeadersVisibility="Column">
<DataGrid.Columns>
<DataGridTextColumn Header="Description"
Binding="{Binding Item.Name, Mode=OneWay}"
Width="*"/>
<DataGridTextColumn Header="Qty"
IsReadOnly="True"
Width="Auto"
Binding="{Binding Quantity, Mode=OneWay}"/>
<DataGridTextColumn Header="Price"
Binding="{Binding Item.Price, Mode=OneWay}"
Width="Auto"/>
</DataGrid.Columns>
</DataGrid>
</TabItem>
<TabItem Header="Quests"
x:Name="QuestsTabItem">
<DataGrid ItemsSource="{Binding CurrentPlayer.Quests}"
AutoGenerateColumns="False"
HeadersVisibility="Column">
<DataGrid.Columns>
<DataGridTextColumn Header="Name"
Binding="{Binding PlayerQuest.Name, Mode=OneWay}"
Width="*">
<DataGridTextColumn.CellStyle>
<Style TargetType="DataGridCell">
<Setter Property="ToolTip"
Value="{Binding PlayerQuest.ToolTipContents}"/>
</Style>
</DataGridTextColumn.CellStyle>
</DataGridTextColumn>
<DataGridTextColumn Header="Done?"
Binding="{Binding IsCompleted, Mode=OneWay}"
Width="Auto"/>
</DataGrid.Columns>
</DataGrid>
</TabItem>
<TabItem Header="Recipes"
x:Name="RecipesTabItem">
<DataGrid ItemsSource="{Binding CurrentPlayer.Recipes}"
AutoGenerateColumns="False"
HeadersVisibility="Column">
<DataGrid.Columns>
<DataGridTextColumn Header="Name"
Binding="{Binding Name, Mode=OneWay}"
Width="*">
<DataGridTextColumn.CellStyle>
<Style TargetType="DataGridCell">
<Setter Property="ToolTip"
Value="{Binding ToolTipContents}"/>
</Style>
</DataGridTextColumn.CellStyle>
</DataGridTextColumn>
<DataGridTemplateColumn MinWidth="75">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button Click="OnClick_Craft"
Width="55"
Content="Craft"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</TabItem>
</TabControl>
</Grid>
<!-- Action controls -->
<Grid Grid.Row="2" Grid.Column="1"
Background="Lavender">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="255" />
</Grid.ColumnDefinitions>
<!-- Combat Controls -->
<Grid Grid.Row="0" Grid.Column="0"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="150"/>
<ColumnDefinition Width="10"/>
<ColumnDefinition Width="50"/>
</Grid.ColumnDefinitions>
<ComboBox Grid.Row="0" Grid.Column="0"
Visibility="{Binding HasMonster, Converter={StaticResource BooleanToVisibility}}"
ItemsSource="{Binding CurrentPlayer.Inventory.Weapons}"
SelectedItem="{Binding CurrentPlayer.CurrentWeapon}"
DisplayMemberPath="Name"/>
<Button Grid.Row="0" Grid.Column="2"
Visibility="{Binding HasMonster, Converter={StaticResource BooleanToVisibility}}"
Content="Use"
Click="OnClick_AttackMonster"/>
<ComboBox Grid.Row="1" Grid.Column="0"
Visibility="{Binding CurrentPlayer.Inventory.HasConsumable, Converter={StaticResource BooleanToVisibility}}"
ItemsSource="{Binding CurrentPlayer.Inventory.Consumables}"
SelectedItem="{Binding CurrentPlayer.CurrentConsumable}"
DisplayMemberPath="Name"/>
<Button Grid.Row="1" Grid.Column="2"
Visibility="{Binding CurrentPlayer.Inventory.HasConsumable, Converter={StaticResource BooleanToVisibility}}"
Content="Use"
Click="OnClick_UseCurrentConsumable"/>
</Grid>
<!-- Movement Controls -->
<Grid Grid.Row="0" Grid.Column="1">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Button Grid.Row="0" Grid.Column="1"
Height="25" Width="65" Margin="10"
Click="OnClick_MoveNorth"
Visibility="{Binding HasLocationToNorth, Converter={StaticResource BooleanToVisibility}}"
Content="North"/>
<Button Grid.Row="1" Grid.Column="0"
Height="25" Width="65" Margin="10"
Click="OnClick_MoveWest"
Visibility="{Binding HasLocationToWest, Converter={StaticResource BooleanToVisibility}}"
Content="West"/>
<Button Grid.Row="1" Grid.Column="1"
Height="25" Width="65" Margin="10"
Click="OnClick_DisplayTradeScreen"
Visibility="{Binding HasTrader, Converter={StaticResource BooleanToVisibility}}"
Content="Trade"/>
<Button Grid.Row="1" Grid.Column="2"
Height="25" Width="65" Margin="10"
Click="OnClick_MoveEast"
Visibility="{Binding HasLocationToEast, Converter={StaticResource BooleanToVisibility}}"
Content="East"/>
<Button Grid.Row="2" Grid.Column="1"
Height="25" Width="65" Margin="10"
Click="OnClick_MoveSouth"
Visibility="{Binding HasLocationToSouth, Converter={StaticResource BooleanToVisibility}}"
Content="South"/>
</Grid>
</Grid>
</Grid>
</Window>
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using Engine.EventArgs;
using Engine.Models;
using Engine.Services;
using Engine.ViewModels;
using Microsoft.Win32;
using WPFUI.Windows;
namespace WPFUI
{
public partial class MainWindow : Window
{
private const string SAVE_GAME_FILE_EXTENSION = "soscsrpg";
private readonly MessageBroker _messageBroker = MessageBroker.GetInstance();
private readonly Dictionary<Key, Action> _userInputActions =
new Dictionary<Key, Action>();
private GameSession _gameSession;
public MainWindow(Player player, int xLocation = 0, int yLocation = 0)
{
InitializeComponent();
InitializeUserInputActions();
SetActiveGameSessionTo(new GameSession(player, xLocation, yLocation));
}
private void OnClick_MoveNorth(object sender, RoutedEventArgs e)
{
_gameSession.MoveNorth();
}
private void OnClick_MoveWest(object sender, RoutedEventArgs e)
{
_gameSession.MoveWest();
}
private void OnClick_MoveEast(object sender, RoutedEventArgs e)
{
_gameSession.MoveEast();
}
private void OnClick_MoveSouth(object sender, RoutedEventArgs e)
{
_gameSession.MoveSouth();
}
private void OnClick_AttackMonster(object sender, RoutedEventArgs e)
{
_gameSession.AttackCurrentMonster();
}
private void OnClick_UseCurrentConsumable(object sender, RoutedEventArgs e)
{
_gameSession.UseCurrentConsumable();
}
private void OnGameMessageRaised(object sender, GameMessageEventArgs e)
{
GameMessages.Document.Blocks.Add(new Paragraph(new Run(e.Message)));
GameMessages.ScrollToEnd();
}
private void OnClick_DisplayTradeScreen(object sender, RoutedEventArgs e)
{
if(_gameSession.CurrentTrader != null)
{
TradeScreen tradeScreen = new TradeScreen();
tradeScreen.Owner = this;
tradeScreen.DataContext = _gameSession;
tradeScreen.ShowDialog();
}
}
private void OnClick_Craft(object sender, RoutedEventArgs e)
{
Recipe recipe = ((FrameworkElement)sender).DataContext as Recipe;
_gameSession.CraftItemUsing(recipe);
}
private void InitializeUserInputActions()
{
_userInputActions.Add(Key.W, () => _gameSession.MoveNorth());
_userInputActions.Add(Key.A, () => _gameSession.MoveWest());
_userInputActions.Add(Key.S, () => _gameSession.MoveSouth());
_userInputActions.Add(Key.D, () => _gameSession.MoveEast());
_userInputActions.Add(Key.Z, () => _gameSession.AttackCurrentMonster());
_userInputActions.Add(Key.C, () => _gameSession.UseCurrentConsumable());
_userInputActions.Add(Key.I, () => SetTabFocusTo("InventoryTabItem"));
_userInputActions.Add(Key.Q, () => SetTabFocusTo("QuestsTabItem"));
_userInputActions.Add(Key.R, () => SetTabFocusTo("RecipesTabItem"));
_userInputActions.Add(Key.T, () => OnClick_DisplayTradeScreen(this, new RoutedEventArgs()));
}
private void MainWindow_OnKeyDown(object sender, KeyEventArgs e)
{
if(_userInputActions.ContainsKey(e.Key))
{
_userInputActions[e.Key].Invoke();
}
}
private void SetTabFocusTo(string tabName)
{
foreach(object item in PlayerDataTabControl.Items)
{
if (item is TabItem tabItem)
{
if (tabItem.Name == tabName)
{
tabItem.IsSelected = true;
return;
}
}
}
}
private void SetActiveGameSessionTo(GameSession gameSession)
{
// Unsubscribe from OnMessageRaised, or we will get double messages
_messageBroker.OnMessageRaised -= OnGameMessageRaised;
_gameSession = gameSession;
DataContext = _gameSession;
// Clear out previous game's messages
GameMessages.Document.Blocks.Clear();
_messageBroker.OnMessageRaised += OnGameMessageRaised;
}
private void StartNewGame_OnClick(object sender, RoutedEventArgs e)
{
Startup startup = new Startup();
startup.Show();
Close();
}
private void SaveGame_OnClick(object sender, RoutedEventArgs e)
{
SaveGame();
}
private void Exit_OnClick(object sender, RoutedEventArgs e)
{
Close();
}
private void MainWindow_OnClosing(object sender, CancelEventArgs e)
{
AskToSaveGame();
}
private void AskToSaveGame()
{
YesNoWindow message =
new YesNoWindow("Save Game", "Do you want to save your game?");
message.Owner = GetWindow(this);
message.ShowDialog();
if(message.ClickedYes)
{
SaveGame();
}
}
private void SaveGame()
{
SaveFileDialog saveFileDialog =
new SaveFileDialog
{
InitialDirectory = AppDomain.CurrentDomain.BaseDirectory,
Filter = $"Saved games (*.{SAVE_GAME_FILE_EXTENSION})|*.{SAVE_GAME_FILE_EXTENSION}"
};
if (saveFileDialog.ShowDialog() == true)
{
SaveGameService.Save(_gameSession, saveFileDialog.FileName);
}
}
}
}
using System;
using System.Collections.Generic;
using System.IO;
using Engine.Factories;
using Engine.Models;
using Engine.ViewModels;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace Engine.Services
{
public static class SaveGameService
{
public static void Save(GameSession gameSession, string fileName)
{
File.WriteAllText(fileName,
JsonConvert.SerializeObject(gameSession, Formatting.Indented));
}
public static GameSession LoadLastSaveOrCreateNew(string fileName)
{
if (!File.Exists(fileName))
{
throw new FileNotFoundException($"Filename: {fileName}");
}
// Save game file exists, so create the GameSession object from it.
try
{
JObject data = JObject.Parse(File.ReadAllText(fileName));
// Populate Player object
Player player = CreatePlayer(data);
int x = (int)data[nameof(GameSession.CurrentLocation)][nameof(Location.XCoordinate)];
int y = (int)data[nameof(GameSession.CurrentLocation)][nameof(Location.YCoordinate)];
// Create GameSession object with saved game data
return new GameSession(player, x, y);
}
catch
{
throw new FormatException($"Error reading: {fileName}");
}
}
private static Player CreatePlayer(JObject data)
{
Player player =
new Player((string)data[nameof(GameSession.CurrentPlayer)][nameof(Player.Name)],
(int)data[nameof(GameSession.CurrentPlayer)][nameof(Player.ExperiencePoints)],
(int)data[nameof(GameSession.CurrentPlayer)][nameof(Player.MaximumHitPoints)],
(int)data[nameof(GameSession.CurrentPlayer)][nameof(Player.CurrentHitPoints)],
GetPlayerAttributes(data),
(int)data[nameof(GameSession.CurrentPlayer)][nameof(Player.Gold)]);
PopulatePlayerInventory(data, player);
PopulatePlayerQuests(data, player);
PopulatePlayerRecipes(data, player);
return player;
}
private static IEnumerable<PlayerAttribute> GetPlayerAttributes(JObject data)
{
List<PlayerAttribute> attributes =
new List<PlayerAttribute>();
foreach(JToken itemToken in (JArray)data[nameof(GameSession.CurrentPlayer)]
[nameof(Player.Attributes)])
{
attributes.Add(new PlayerAttribute(
(string)itemToken[nameof(PlayerAttribute.Key)],
(string)itemToken[nameof(PlayerAttribute.DisplayName)],
(string)itemToken[nameof(PlayerAttribute.DiceNotation)],
(int)itemToken[nameof(PlayerAttribute.BaseValue)],
(int)itemToken[nameof(PlayerAttribute.ModifiedValue)]));
}
return attributes;
}
private static void PopulatePlayerInventory(JObject data, Player player)
{
foreach(JToken itemToken in (JArray)data[nameof(GameSession.CurrentPlayer)]
[nameof(Player.Inventory)]
[nameof(Inventory.Items)])
{
int itemId = (int)itemToken[nameof(GameItem.ItemTypeID)];
player.AddItemToInventory(ItemFactory.CreateGameItem(itemId));
}
}
private static void PopulatePlayerQuests(JObject data, Player player)
{
foreach(JToken questToken in (JArray)data[nameof(GameSession.CurrentPlayer)]
[nameof(Player.Quests)])
{
int questId =
(int)questToken[nameof(QuestStatus.PlayerQuest)][nameof(QuestStatus.PlayerQuest.ID)];
Quest quest = QuestFactory.GetQuestByID(questId);
QuestStatus questStatus = new QuestStatus(quest);
questStatus.IsCompleted = (bool)questToken[nameof(QuestStatus.IsCompleted)];
player.Quests.Add(questStatus);
}
}
private static void PopulatePlayerRecipes(JObject data, Player player)
{
foreach(JToken recipeToken in
(JArray)data[nameof(GameSession.CurrentPlayer)][nameof(Player.Recipes)])
{
int recipeId = (int)recipeToken[nameof(Recipe.ID)];
Recipe recipe = RecipeFactory.RecipeByID(recipeId);
player.Recipes.Add(recipe);
}
}
}
}
<Window x:Class="WPFUI.Startup"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WPFUI"
xmlns:viewModels="clr-namespace:Engine.Models;assembly=Engine"
d:DataContext="{d:DesignInstance viewModels:GameDetails}"
mc:Ignorable="d"
FontSize="11pt"
Title="{Binding Title}" Height="400" Width="400">
<Grid Margin="10,10,10,10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Button Grid.Row="0" Grid.Column="0"
Margin="0,5,0,5"
HorizontalAlignment="Center"
Width="125"
Content="Start new game"
Click="StartNewGame_OnClick"/>
<Button Grid.Row="1" Grid.Column="0"
Margin="0,5,0,5"
HorizontalAlignment="Center"
Width="125"
Content="Load saved game"
Click="LoadSavedGame_OnClick"/>
<Button Grid.Row="2" Grid.Column="0"
Margin="0,5,0,5"
HorizontalAlignment="Center"
Width="125"
Content="Exit"
Click="Exit_OnClick"/>
</Grid>
</Window>
using System;
using System.Windows;
using Engine.Services;
using Engine.ViewModels;
using Microsoft.Win32;
namespace WPFUI
{
public partial class Startup : Window
{
private const string SAVE_GAME_FILE_EXTENSION = "soscsrpg";
public Startup()
{
InitializeComponent();
DataContext = GameDetailsService.ReadGameDetails();
}
private void StartNewGame_OnClick(object sender, RoutedEventArgs e)
{
CharacterCreation characterCreationWindow = new CharacterCreation();
characterCreationWindow.Show();
Close();
}
private void LoadSavedGame_OnClick(object sender, RoutedEventArgs e)
{
OpenFileDialog openFileDialog =
new OpenFileDialog
{
InitialDirectory = AppDomain.CurrentDomain.BaseDirectory,
Filter = $"Saved games (*.{SAVE_GAME_FILE_EXTENSION})|*.{SAVE_GAME_FILE_EXTENSION}"
};
if (openFileDialog.ShowDialog() == true)
{
GameSession gameSession =
SaveGameService.LoadLastSaveOrCreateNew(openFileDialog.FileName);
MainWindow mainWindow =
new MainWindow(gameSession.CurrentPlayer,
gameSession.CurrentLocation.XCoordinate,
gameSession.CurrentLocation.YCoordinate);
mainWindow.Show();
Close();
}
}
private void Exit_OnClick(object sender, RoutedEventArgs e)
{
Close();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment