wpf主界面游戏引擎实现

2.GameEntityView.xaml

<UserControl x:Class="PrimalEditor.Editors.GameEntityView"

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

xmlns:local="clr-namespace:PrimalEditor.Editors"

xmlns:vm="clr-namespace:PrimalEditor.Components"

mc:Ignorable="d" Background="{StaticResource Editor.Window.GrayBrush3}"

d:DesignHeight="450" d:DesignWidth="800">

<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled">

<ScrollViewer.Style>

<Style TargetType="ScrollViewer">

<Style.Triggers>

<Trigger Property="DataContext" Value="{x:Null}">

<Setter Property="Visibility" Value="Collapsed"/>

</Trigger>

</Style.Triggers>

</Style>

</ScrollViewer.Style>

<StackPanel>

<Border Height="32">

<ToggleButton x:Name="addComponent" VerticalAlignment="Center"

HorizontalAlignment="Left" Margin="5,0,0,0">

<ToggleButton.Content>

<DockPanel>

<TextBlock Text="Add Component" Margin="5,0"/>

<Path Margin="3,0,2,0"

Data="M0,0 L0,2 L4,6 L8,2 L8,0 L4,4 z"

HorizontalAlignment="Center" Fill="Black"

VerticalAlignment="Center"

/>

</DockPanel>

</ToggleButton.Content>

</ToggleButton>

</Border>

<Grid>

<Grid.ColumnDefinitions>

<ColumnDefinition Width="78"/>

<ColumnDefinition/>

<ColumnDefinition Width="Auto"/>

</Grid.ColumnDefinitions>

<TextBlock Text="Name" Grid.Column="0" Margin="5,0,0,0"/>

<TextBox Text="{Binding Name}" Grid.Column="1" Tag="{Binding RenameCommand}"/>

<StackPanel Orientation="Horizontal" Grid.Column="2">

<TextBlock Text="Enabled" Margin="5,0,0,0"/>

<CheckBox IsChecked="{Binding IsEnabled}" Command="{Binding IsEnabledCommand}"

CommandParameter="{Binding IsChecked,RelativeSource={RelativeSource Self}}"

Margin="5,0" VerticalAlignment="Center"/>

</StackPanel>

</Grid>

<ItemsControl ItemsSource="{Binding Components}">

<ItemsControl.ItemsPanel>

<ItemsPanelTemplate>

<StackPanel/>

</ItemsPanelTemplate>

</ItemsControl.ItemsPanel>

</ItemsControl>

</StackPanel>

</ScrollViewer>

</UserControl>

2.GameEntityView.xaml.cs

using PrimalEditor.Components;

using PrimalEditor.GameProject;

using PrimalEditor.Utilities;

using System.Globalization;

using System.Windows;

using System.Windows.Controls;

using System.Windows.Controls.Primitives;

using System.Windows.Data;

using System.Windows.Input;

namespace PrimalEditor.Editors

{

public class NullableBoolToBoolConverter : IValueConverter

{

public object Convert(object value, Type targetType, object parameter, CultureInfo culture)

{

return value is bool b && b == true;

}

public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)

{

return value is bool b && b == true;

}

}

/// <summary>

/// GameEntityView.xaml 的交互逻辑

/// </summary>

public partial class GameEntityView : UserControl

{

private Action _undoAction;

private string _propertyName;

public static GameEntityView Instance { get; private set; }

public GameEntityView()

{

InitializeComponent();

DataContext = null;

Instance = this;

DataContextChanged += (_, __) =>

{

if (DataContext != null)

{

(DataContext as MSEntity).PropertyChanged += (s, e) => _propertyName = e.PropertyName;

}

};

}

private Action GetRenameAction()

{

var vm = DataContext as MSEntity;

var selection = vm.SelectedEntities.Select(entity => (entity, entity.Name)).ToList();

return new Action(() =>

{

selection.ForEach(item => item.entity.Name = item.Name);

(DataContext as MSEntity).Refresh();

});

}

private Action GetIsEnabledAction()

{

var vm = DataContext as MSEntity;

var selection = vm.SelectedEntities.Select(entity => (entity, entity.IsEnabled)).ToList();

return new Action(() =>

{

selection.ForEach(item => item.entity.IsEnabled = item.IsEnabled);

(DataContext as MSEntity).Refresh();

});

}

private void OnName_TextBox_GotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)

{

_propertyName = string.Empty;

_undoAction = GetRenameAction();

}

private void OnName_TextBox_LostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)

{

if (_propertyName == nameof(MSEntity.Name) && _undoAction != null)

{

var vm = DataContext as MSEntity;

var selection = vm.SelectedEntities.Select(entity => (entity, entity.Name)).ToList();

var redoAction = new Action(() =>

{

selection.ForEach(item => item.entity.Name = item.Name);

});

Project.UndoRedo.Add(new UndoRedoAction(_undoAction, redoAction, "Rename game entity"));

_propertyName = null;

};

_undoAction = null;

}

private void OnIsEnabled_CheckBox_Click(object sender, RoutedEventArgs e)

{

var undoAction = GetIsEnabledAction();

var vm = DataContext as MSEntity;

vm.IsEnabled = (sender as CheckBox).IsChecked == true;

var redoAction = GetIsEnabledAction();

Project.UndoRedo.Add(new UndoRedoAction(undoAction, redoAction,

vm.IsEnabled == true ? "Enable game entity" : "Disable game entity"

));

}

private void OnAddComponent_Button_PreviewMouse_LBD(object sender, MouseButtonEventArgs e)

{

var menu = FindResource("addComponentMenu") as ContextMenu;

var btn = sender as ToggleButton;

btn.IsChecked = true;

menu.Placement = PlacementMode.Bottom;

menu.PlacementTarget = btn;

menu.MinWidth = btn.ActualWidth;

menu.IsOpen = true;

}

private void AddComponent(ComponentType componentType, object data)

{

var creationFunction = ComponentFactory.GetCreationFunction(componentType);

var changedEntities = new List<(GameEntity entity, Component component)>();

var vm = DataContext as MSEntity;

foreach (var entity in vm.SelectedEntities)

{

var component = creationFunction(entity, data);

if (entity.AddComponent(component))

{

changedEntities.Add((entity, component));

}

}

if (changedEntities.Any())

{

vm.Refresh();

Project.UndoRedo.Add(new UndoRedoAction(

() =>

{

changedEntities.ForEach(x => x.entity.RemoveComponent(x.component));

(DataContext as MSEntity).Refresh();

},

() =>

{

changedEntities.ForEach(x => x.entity.AddComponent(x.component));

(DataContext as MSEntity).Refresh();

},

$"Add {componentType} component"

));

}

}

private void AddScriptComponent(object sender, RoutedEventArgs e)

{

AddComponent(ComponentType.Script, (sender as MenuItem).Header.ToString());

}

}

}

相关推荐
爱吃小胖橘2 小时前
Unity资源加载模块全解析
开发语言·unity·c#·游戏引擎
ifeng09187 小时前
HarmonyOS实战项目:打造智能家居控制中心(设备发现与控制)
wpf·智能家居·harmonyos
ifeng091810 小时前
HarmonyOS实战项目:开发一个分布式新闻阅读客户端
分布式·wpf·harmonyos
千年奇葩14 小时前
Unity性能优化之:利用CUDA加速Unity实现大规模并行计算。从环境搭建到实战案例
c++·人工智能·unity·游戏引擎·cuda
AA陈超14 小时前
虚幻引擎5 GAS开发俯视角RPG游戏 P06-25 属性信息数据资产
c++·游戏·ue5·游戏引擎·虚幻
张人玉17 小时前
WPF 控件速查 PDF 笔记(可直接落地版)(带图片)
大数据·microsoft·ui·c#·wpf
张人玉18 小时前
WPF 数据绑定详解
windows·c#·wpf
踏上青云路1 天前
WPF 避坑指南
wpf
爱吃小胖橘1 天前
高效对象池设计:提升Unity性能的关键
开发语言·unity·c#·游戏引擎
沉默的记录者1 天前
unity 2021反向遮罩的毛边
unity·游戏引擎