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

}

}

}

相关推荐
棉晗榜9 小时前
WPF印章水印, Border怎么悬浮在其他控件上面,类似盖章一样
wpf
张人玉10 小时前
LiveCharts WPF MVVM 图表开发笔记
大数据·分布式·wpf·livecharts
武藤一雄10 小时前
一款基于WPF开发的BEJSON转换工具
windows·c#·json·wpf
DoomGT10 小时前
Audio - UE5中的音效播放重启问题
游戏·ue5·游戏引擎·虚幻·虚幻引擎
一线灵12 小时前
Axmol 开发环境快速搭建指南 (新)
游戏引擎
Poetinthedusk14 小时前
设计模式-模板方法模式
windows·设计模式·c#·wpf·模板方法模式
一线灵14 小时前
跨平台游戏引擎 Axmol-2.11.0 发布
游戏引擎
Robot侠14 小时前
ROS1从入门到精通 2:ROS1核心概念详解(节点、话题、服务一网打尽)
unity·游戏引擎·ros·机器人操作系统
feiduoge1 天前
教程 41 - 增强纹理映射(采样器)
windows·游戏引擎·图形渲染
feiduoge1 天前
教程 37 - 法线贴图
windows·游戏引擎·图形渲染