diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000000000000000000000000000000000000..3ca38edde04307fece14c670476b70493a6b4c30 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "ThirdParty/IMEHelper"] + path = ThirdParty/IMEHelper + url = https://github.com/ryancheung/MonoGame.IMEHelper.git diff --git a/CLEditor/CLEngine.Editor.csproj b/CLEditor/CLEngine.Editor.csproj index 39785dd9ea2c4ffc348faac6adefde412b30ef27..1063f3778ef0d2c546a653d9941edc6b6d402eac 100644 --- a/CLEditor/CLEngine.Editor.csproj +++ b/CLEditor/CLEngine.Editor.csproj @@ -253,7 +253,7 @@ VisualScriptingNode.xaml - + @@ -269,6 +269,7 @@ + diff --git a/CLEditor/core/CommandBindings.cs b/CLEditor/core/CommandBindings.cs deleted file mode 100644 index 76f87008789c6428de64dc71f2d856885546d3c9..0000000000000000000000000000000000000000 --- a/CLEditor/core/CommandBindings.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System.Windows.Input; - -namespace CLEngine.Editor.core -{ - public static class CommandBindings - { - public static readonly RoutedUICommand FullDebug = new RoutedUICommand("完整调试", "FullDebug", typeof(MainWindow)); - public static readonly RoutedUICommand ToCollisionBlock = new RoutedUICommand("碰撞阻挡", "ToCollisionBlock", typeof(MainWindow)); - } -} \ No newline at end of file diff --git a/CLEditor/core/EditorCommands.cs b/CLEditor/core/EditorCommands.cs index 8ccb3c69ffcd3e658d69d13cdca330609b120aa9..e07809f70b087ec50fe38b6716f2750dd650afe2 100644 --- a/CLEditor/core/EditorCommands.cs +++ b/CLEditor/core/EditorCommands.cs @@ -12,6 +12,7 @@ using CLEngine.Editor.controls; using CLEngine.Editor.model; using CLEngine.Editor.windows; using CLEngine.Core; +using CLEngine.Core.framework; using Clipboard = System.Windows.Clipboard; using MessageBox = System.Windows.Forms.MessageBox; @@ -172,14 +173,12 @@ namespace CLEngine.Editor.core { SceneManager.GameProject = CProject.Load(filename); - //File.Copy("Farseer Engine MonoGame OpenGL.dll", SceneManager.GameProject.ProjectPath + "\\Farseer Engine MonoGame OpenGL.dll", true); File.Copy("CLEngine.Core.dll", SceneManager.GameProject.ProjectPath + "\\CLEngine.Core.dll", true); File.Copy("Project Templates\\CLEngine.Core.xml", SceneManager.GameProject.ProjectPath + "\\CLEngine.Core.xml", true); File.Copy("Project Templates\\CLEngine.Windows.exe", SceneManager.GameProject.ProjectPath + "\\CLEngine.Windows.exe", true); CHelper.CopyDirectory("Project Templates\\libs", SceneManager.GameProject.ProjectPath + "", true); File.Copy("Xceed.Wpf.Toolkit.dll", SceneManager.GameProject.ProjectPath + "\\Xceed.Wpf.Toolkit.dll", true); - //File.Copy("OpenTK.dll", SceneManager.GameProject.ProjectPath + "\\OpenTK.dll", true); - // load user settings: + if (!File.Exists(SceneManager.GameProject.ProjectPath + "\\_userPrefs.pgb")) { UserPreferences.Instance = new UserPreferences(); @@ -196,7 +195,10 @@ namespace CLEngine.Editor.core EditorHandler.SceneTreeView.CreateView(); EditorHandler.ProjectTreeView.CreateView(); - CompilerWindow cf = new CompilerWindow(); + // 加载游戏框架数据库 + FrameworkManager.LoadAllData(); + + CompilerWindow cf = new CompilerWindow(); cf.ShowDialog(); bool success = cf.Result; @@ -206,13 +208,11 @@ namespace CLEngine.Editor.core { LoadLastScene(); - EditorCommands.ShowOutputMessage("工程加载成功"); - - //kryptonNavigator1.SelectedIndex = 1; + ShowOutputMessage("工程加载成功"); } else { - EditorCommands.ShowOutputMessage("项目加载脚本错误"); + ShowOutputMessage("项目加载脚本错误"); } EditorHandler.Settings = new IniFile(SceneManager.GameProject.ProjectPath + "\\settings.ini"); diff --git a/CLEditor/core/converts/EditorImageConvert.cs b/CLEditor/core/converts/EditorImageConvert.cs new file mode 100644 index 0000000000000000000000000000000000000000..594f72ab80e9d48c459a635757786719b1796d02 --- /dev/null +++ b/CLEditor/core/converts/EditorImageConvert.cs @@ -0,0 +1,32 @@ +using System; +using System.Globalization; +using System.IO; +using System.Windows.Data; +using System.Windows.Media.Imaging; +using CLEngine.Core; + +namespace CLEngine.Editor.core.converts +{ + /// + /// 编辑器内路径转图片 + /// + public class EditorImageConvert : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + if (value is string path) + { + // 先转绝对路径 + var relativePath = Path.Combine(SceneManager.GameProject.ProjectPath, path); + return new BitmapImage(new Uri(relativePath, UriKind.Absolute)); + } + + return null; + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + return null; + } + } +} \ No newline at end of file diff --git a/CLEditor/model/GlobalCommands.cs b/CLEditor/model/GlobalCommands.cs index 9542c4d6a48468e312ddaeea5f3166e78f932c1d..915f08f834ef8e4c5f05dd67cb5d17949e7edc11 100644 --- a/CLEditor/model/GlobalCommands.cs +++ b/CLEditor/model/GlobalCommands.cs @@ -1,106 +1,106 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; using CLEngine.Core; namespace CLEngine.Editor.model { - public static class GlobalCommands - { - public static void RemoveEmptyFolders(string path, SearchOption searchOption) - { - foreach (string dirPath in Directory.GetDirectories(path, "*", SearchOption.AllDirectories)) - { - if (Directory.GetFiles(dirPath).Count() == 0 && Directory.GetDirectories(dirPath).Count() == 0) - Directory.Delete(dirPath); - } - } + public static class GlobalCommands + { + public static void RemoveEmptyFolders(string path, SearchOption searchOption) + { + foreach (var dirPath in Directory.GetDirectories(path, "*", SearchOption.AllDirectories)) + { + if (!Directory.GetFiles(dirPath).Any() && !Directory.GetDirectories(dirPath).Any()) + Directory.Delete(dirPath); + } + } - public static bool DeployProject(string projectPath, string destinationPath, string platform) - { - List blockedDirs = new List(); - blockedDirs.Add("bin"); - blockedDirs.Add("obj"); + [SuppressMessage("ReSharper", "StringLiteralTypo")] + public static bool DeployProject(string projectPath, string destinationPath, string platform) + { + var blockedDirs = new List {"bin", "obj", ".git", ".vs"}; - List blockedFileExtensions = new List(); - blockedFileExtensions.Add(".cs"); - blockedFileExtensions.Add(".clengine"); - blockedFileExtensions.Add(".csproj"); - blockedFileExtensions.Add(".sln"); + var blockedFileExtensions = new List {".cs", ".csproj", ".sln"}; - switch (platform.ToLower()) - { - case "windows": - // creates shadow directories - foreach (string dirPath in Directory.GetDirectories(projectPath, "*", SearchOption.AllDirectories)) - { - Directory.CreateDirectory(dirPath.Replace(projectPath, destinationPath)); - } + switch (platform.ToLower()) + { + case "windows": + // creates shadow directories + foreach (string dirPath in Directory.GetDirectories(projectPath, "*", SearchOption.AllDirectories)) + { + Directory.CreateDirectory(dirPath.Replace(projectPath, destinationPath)); + } - // clear blocked directories from the root folder: - foreach (string dirPath in Directory.GetDirectories(destinationPath, "*", SearchOption.TopDirectoryOnly)) - { - if (blockedDirs.Contains(System.IO.Path.GetFileName(dirPath))) - Directory.Delete(dirPath, true); - } + // clear blocked directories from the root folder: + foreach (string dirPath in Directory.GetDirectories(destinationPath, "*", SearchOption.TopDirectoryOnly)) + { + if (blockedDirs.Contains(Path.GetFileName(dirPath))) + Directory.Delete(dirPath, true); + } - // copy all the files - foreach (string path in Directory.GetFiles(projectPath, "*.*", SearchOption.AllDirectories)) - { - string filename = System.IO.Path.GetFileName(path); - string ext = System.IO.Path.GetExtension(path); - if (!blockedFileExtensions.Contains(ext) && - Directory.Exists(System.IO.Path.GetDirectoryName(path.Replace(projectPath, destinationPath)))) - { - if (filename.ToLower().Equals("CLEngine.Windows.exe")) - { - File.Copy(path, System.IO.Path.GetDirectoryName(path.Replace(projectPath, destinationPath)) + "\\" + SceneManager.GameProject.ProjectName + ".exe", true); - } - else - { - File.Copy(path, path.Replace(projectPath, destinationPath), true); - } - } - } + // copy all the files + foreach (string path in Directory.GetFiles(projectPath, "*.*", SearchOption.AllDirectories)) + { + string filename = Path.GetFileName(path); + string ext = Path.GetExtension(path); + if (!blockedFileExtensions.Contains(ext) && + Directory.Exists(Path.GetDirectoryName(path.Replace(projectPath, destinationPath)))) + { + if (filename != null && filename.ToLower().Equals("CLEngine.Windows.exe")) + { + File.Copy(path, Path.GetDirectoryName(path.Replace(projectPath, destinationPath)) + "\\" + SceneManager.GameProject.ProjectName + ".exe", true); + } + else + { + File.Copy(path, path.Replace(projectPath, destinationPath), true); + } + } + } - RemoveEmptyFolders(destinationPath, SearchOption.AllDirectories); + RemoveEmptyFolders(destinationPath, SearchOption.AllDirectories); + CHelper.ChangeSettingsToRelease(destinationPath); + ResBuilder.Build("DesktopGL", projectPath, destinationPath); + return true; + case "windowsstore": + // creates shadow directories + foreach (string unused in Directory.GetDirectories(projectPath, "*", SearchOption.AllDirectories)) + Directory.CreateDirectory(destinationPath.Replace(projectPath, destinationPath)); - return true; - case "windowsstore": - // creates shadow directories - foreach (string dirPath in Directory.GetDirectories(projectPath, "*", SearchOption.AllDirectories)) - Directory.CreateDirectory(destinationPath.Replace(projectPath, destinationPath)); + //Copy all the files + foreach (string path in Directory.GetFiles(projectPath, "*.*", SearchOption.AllDirectories)) + { + if (!Directory.Exists(Path.GetDirectoryName(path.Replace(projectPath, destinationPath)))) + { + Directory.CreateDirectory(Path.GetDirectoryName(path.Replace(projectPath, destinationPath)) ?? throw new InvalidOperationException()); + } - //Copy all the files - foreach (string path in Directory.GetFiles(projectPath, "*.*", SearchOption.AllDirectories)) - { - if (!Directory.Exists(System.IO.Path.GetDirectoryName(path.Replace(projectPath, destinationPath)))) - { - Directory.CreateDirectory(System.IO.Path.GetDirectoryName(path.Replace(projectPath, destinationPath))); - } + if (path.ToLower().EndsWith(".scene")) + { + GameScene scene = (GameScene)CHelper.DeserializeObject(path); + CHelper.SerializeObjectXML(path.Replace(projectPath, destinationPath), scene); + } + else if (path.ToLower().EndsWith(".clengine")) + { + CProject gp = (CProject)CHelper.DeserializeObject(path); + CHelper.SerializeObjectXML(path.Replace(projectPath, destinationPath), gp); + } + else + { + File.Copy(path, path.Replace(projectPath, destinationPath), true); + } + } - if (path.ToLower().EndsWith(".scene")) - { - GameScene scene = (GameScene)CHelper.DeserializeObject(path); - CHelper.SerializeObjectXML(path.Replace(projectPath, destinationPath), scene); - } - else if (path.ToLower().EndsWith(".clengine")) - { - CProject gp = (CProject)CHelper.DeserializeObject(path); - CHelper.SerializeObjectXML(path.Replace(projectPath, destinationPath), gp); - } - else - { - File.Copy(path, path.Replace(projectPath, destinationPath), true); - } - } + RemoveEmptyFolders(destinationPath, SearchOption.AllDirectories); + CHelper.ChangeSettingsToRelease(destinationPath); + ResBuilder.Build("DesktopGL", projectPath, destinationPath); - RemoveEmptyFolders(destinationPath, SearchOption.AllDirectories); + return true; + } - return true; - } - - return false; - } - } + return false; + } + } } \ No newline at end of file diff --git a/CLEditor/model/ResBuilder.cs b/CLEditor/model/ResBuilder.cs new file mode 100644 index 0000000000000000000000000000000000000000..166e11dd21342076c32e27b4d889b938d3921824 --- /dev/null +++ b/CLEditor/model/ResBuilder.cs @@ -0,0 +1,119 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; +using System.IO; + +namespace CLEngine.Editor +{ + [SuppressMessage("ReSharper", "StringLiteralTypo")] + public class ResBuilder + { + public static Dictionary image = new Dictionary { { "png", true },{ "jpg", true },{ "bmp", true }, + {"dds",true } }; + + public static Dictionary AllSupportTypes = new Dictionary{ + { "png", true },{ "jpg", true },{ "bmp", true },{ "dds", true },{ "wav", true }, { "mp3", true }, { "ogg", true } + }; + public static Dictionary sound = new Dictionary { { "wav", true }, { "mp3", true }, { "ogg", true } }; + public static void Build(string platform, string ori, string dest, bool compile = false) + { + if (!compile) return; + + var root = new DirectoryInfo(Path.Combine(ori, "Content")); + var files = root.GetFiles(); + FileInfo file; + var max = files.Length; + string Name; + var d = Path.Combine(dest, "Content"); + var Names = new Dictionary(); + foreach (var t in files) + { + file = t; + Name = Path.GetFileNameWithoutExtension(file.Name); + if (Names.ContainsKey(Name)) + { + throw new Exception("有资源重名"); + } + + Names.Add(Name, true); + } + + using (var sw = new StreamWriter(d + "\\\\Content.mgcb")) + { + sw.WriteLine("\n#----------------------------- Global Properties ----------------------------#\n"); + sw.WriteLine("/outputDir:.\\\n/intermediateDir:.\\\n/platform:" + platform); + sw.WriteLine("/config:\n/profile:Reach\n/compress:True\n"); + sw.WriteLine("#-------------------------------- References --------------------------------#\n"); + sw.WriteLine("#---------------------------------- Content ---------------------------------#"); + for (var i = 0; i < max; i++) + { + file = files[i]; + Name = Path.GetExtension(file.Name); + if (!AllSupportTypes.ContainsKey(Name)) continue; + + sw.WriteLine("\n#begin " + file.Name); + if (image.ContainsKey(Name)) + { + sw.WriteLine("/importer:TextureImporter\n/processor:TextureProcessor"); + sw.WriteLine("/processorParam:ColorKeyColor=255,0,255,255"); + sw.WriteLine("/processorParam:ColorKeyEnabled=True"); + sw.WriteLine("/processorParam:GenerateMipmaps=False"); + sw.WriteLine("/processorParam:PremultiplyAlpha=True"); + sw.WriteLine("/processorParam:ResizeToPowerOfTwo=False"); + sw.WriteLine("/processorParam:MakeSquare=False"); + sw.WriteLine("/processorParam:TextureFormat=Color"); + } + else if (sound.ContainsKey(Name)) + { + switch (Name) + { + case "mp3": + sw.WriteLine("/importer:Mp3Importer"); + sw.WriteLine("/processor:SongProcessor"); + break; + case "wav": + sw.WriteLine("/importer:WavImporter"); + sw.WriteLine("/processor:SoundEffectProcessor"); + break; + case "ogg": + sw.WriteLine("/importer:OggImporter"); + sw.WriteLine("/processor:SongProcessor"); + break; + } + sw.WriteLine("/processorParam:Quality=Best"); + } + sw.WriteLine("/build:" + file.Name + ";" + file.Name); + } + } + + var p = new Process + { + StartInfo = new ProcessStartInfo("C:\\Program Files (x86)\\MSBuild\\MonoGame\\v3.0\\Tools\\MGCB.exe", + "/w:" + dest + " /@:" + Path.Combine(d, "Content.mgcb")) + { + CreateNoWindow = true, UseShellExecute = false, RedirectStandardOutput = true + } + }; + p.Exited += (sender, args) => + { + root = new DirectoryInfo(d); + files = root.GetFiles(); + max = files.Length; + for (var i = 0; i < max; i++) + { + file = files[i]; + Name = Path.GetExtension(file.Name); + if (Name == ".mgcontent" || AllSupportTypes.ContainsKey(Name.Substring(1))) + { + File.Delete(file.FullName); + } + } + + File.Delete(Path.Combine(d + "Content.mgcb")); + }; + p.Start(); + p.WaitForExit(); + } + } +} diff --git a/CLEditor/viewmodel/DataBaseViewModel.cs b/CLEditor/viewmodel/DataBaseViewModel.cs index 888d480863a8c58be39b6c8d805f44b22ce96637..4f1c4b13612025fb19bf4b9b11a3e6aeaec76e87 100644 --- a/CLEditor/viewmodel/DataBaseViewModel.cs +++ b/CLEditor/viewmodel/DataBaseViewModel.cs @@ -1,8 +1,14 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Collections.ObjectModel; +using System.Linq; +using System.Windows.Forms; +using CLEngine.Core; using CLEngine.Core.framework; +using CLEngine.Editor.windows; using GalaSoft.MvvmLight; using GalaSoft.MvvmLight.Command; +using MessageBox = System.Windows.Forms.MessageBox; namespace CLEngine.Editor.viewmodel { @@ -25,11 +31,174 @@ namespace CLEngine.Editor.viewmodel public List GenderTypes { get { return FrameworkSettings.GenderTypes; } } + /// + /// 物品分类 + /// + public List ItemTypes + { + get { return FrameworkSettings.ItemTypes.Keys.ToList(); } + } + + /// + /// 物品子类 + /// + public ObservableCollection ItemChildTypes { get; set; } + + /// + /// 职业列表 + /// + public List OccupationTypes { + get { return FrameworkSettings.OccupationTypes; } + } + + /// + /// 背包图标浏览 + /// + public RelayCommand BagBrowserCommand { get; set; } + /// + /// 掉落图标浏览 + /// + public RelayCommand DropBrowserCommand { get; set; } + /// + /// 保存数据按钮 + /// + public RelayCommand SaveCommand { get; set; } + + private string _iconPath; + + public string IconPath + { + get { return _iconPath; } + set + { + _iconPath = value; + RaisePropertyChanged(() => IconPath); + } + } + + private string _dropIconPath; + + public string DropIconPath + { + get { return _dropIconPath; } + set + { + _dropIconPath = value; + RaisePropertyChanged(() => DropIconPath); + } + } public DataBaseViewModel() { - ItemObjects = new ObservableCollection(); + ItemObjects = GetItemObjects(); AddItemCommand = new RelayCommand(AddItemAction); + ItemChildTypes = new ObservableCollection(); + // 我们需要数据通知子类发生变化 + ItemChildTypes.CollectionChanged += (sender, args) => { RaisePropertyChanged(() => ItemChildTypes); }; + + BagBrowserCommand = new RelayCommand(BagBrowserAction); + DropBrowserCommand = new RelayCommand(DropBrowserAction); + SaveCommand = new RelayCommand(SaveAction); + } + + private ObservableCollection GetItemObjects() + { + var itemObjects = new ObservableCollection(); + if (ItemManager.WorldItem.Count <= 0) return itemObjects; + + foreach (var itemObject in ItemManager.WorldItem) + { + itemObjects.Add(itemObject.Value); + } + + return itemObjects; + } + + private void SaveAction() + { + FrameworkManager.SaveData("item"); + } + + private void DropBrowserAction() + { + var fileSelectDialog = new OpenFileDialog(); + var itemObject = (ItemObject)DataBaseWindow.ItemListInstance.SelectedItem; + if (itemObject != null) + { + itemObject.DropIconPath = ProcessDialog(fileSelectDialog, "Icon\\"); + DropIconPath = itemObject.DropIconPath; + } + } + + private void BagBrowserAction() + { + var fileSelectDialog = new OpenFileDialog(); + var itemObject = (ItemObject)DataBaseWindow.ItemListInstance.SelectedItem; + if (itemObject != null) + { + itemObject.IconPath = ProcessDialog(fileSelectDialog, "Icon\\"); + IconPath = itemObject.IconPath; + } + } + + private string ProcessDialog(OpenFileDialog ofd, string specificFolder = "") + { + var result = ofd.ShowDialog(); + if (result == DialogResult.OK || result == DialogResult.Yes) + { + string destFolder = (SceneManager.GameProject.ProjectPath + "\\Content\\" + specificFolder).Trim(); + string filename = System.IO.Path.GetFileName(ofd.FileName); + + bool fileOnDirectory = ofd.FileName.StartsWith(SceneManager.GameProject.ProjectPath); + + if (!System.IO.Directory.Exists(destFolder) && !fileOnDirectory) + System.IO.Directory.CreateDirectory(destFolder); + + if (!System.IO.File.Exists(destFolder + filename) || fileOnDirectory) + return this.SetNewPath(ofd.FileName, destFolder, specificFolder, filename); + + var overwriteResult = MessageBox.Show("带有名称的文件 " + filename + " 已经存在。 你想覆盖它吗?", "警告", MessageBoxButtons.YesNoCancel); + if (overwriteResult == DialogResult.Yes) + return this.SetNewPath(ofd.FileName, destFolder, specificFolder, filename, true); + } + + return null; + } + + private string SetNewPath(string srcPath, string destFolder, string specificFolder, string filename, bool overwrite = false) + { + try + { + bool fileOnDirectory = srcPath.StartsWith(SceneManager.GameProject.ProjectPath); + + if (!fileOnDirectory) + System.IO.File.Copy(srcPath, destFolder + filename, overwrite); + + string relativePath = (@"\Content\" + specificFolder + filename).Trim(); + if (fileOnDirectory) + relativePath = srcPath.Replace(SceneManager.GameProject.ProjectPath, string.Empty); + + if (relativePath.StartsWith("\\")) + relativePath = relativePath.Substring(1, relativePath.Length - 1); + + return relativePath; + } + catch (Exception ex) + { + MessageBox.Show(ex.Message); + return null; + } + } + + /// + /// 清除子类数据并重新赋值 + /// + /// + public void ClearItemChildTypes(object value) + { + ItemChildTypes.Clear(); + foreach (var itemType in FrameworkSettings.ItemTypes[value.ToString()]) + ItemChildTypes.Add(itemType); } private void AddItemAction() diff --git a/CLEditor/viewmodel/MainViewModel.cs b/CLEditor/viewmodel/MainViewModel.cs index 0c47662ce2651311c13d39b32c88eb5df4bdce3e..05274f0b7b3af5f0c6c8808dabcf5185604d9d39 100644 --- a/CLEditor/viewmodel/MainViewModel.cs +++ b/CLEditor/viewmodel/MainViewModel.cs @@ -10,6 +10,7 @@ using Microsoft.Xna.Framework; using System.Collections.Generic; using System.Windows.Forms; using System.Windows.Media; +using CLEngine.Core.framework; namespace CLEngine.Editor.ViewModel { @@ -50,6 +51,9 @@ namespace CLEngine.Editor.ViewModel /// Ϸݿ /// public RelayCommand DataBaseCommand { get; set; } + /// + /// ¼֪ͨ + /// public NotificationMessageManager Manager { get; set; } = App.Manager; public MainViewModel() diff --git a/CLEditor/windows/DataBaseWindow.xaml b/CLEditor/windows/DataBaseWindow.xaml index 6bb08a0933d92db120fb8121d8cffc15ebc09898..a757d1ac93e034e9517496f32b620b251bbc1872 100644 --- a/CLEditor/windows/DataBaseWindow.xaml +++ b/CLEditor/windows/DataBaseWindow.xaml @@ -7,144 +7,106 @@ xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit" xmlns:Options="http://schemas.microsoft.com/winfx/2006/xaml/presentation/options" xmlns:controls="clr-namespace:CLEngine.Editor.controls" xmlns:framework="clr-namespace:CLEngine.Core.framework;assembly=CLEngine.Core" + xmlns:xcad="http://schemas.xceed.com/wpf/xaml/avalondock" + xmlns:converts="clr-namespace:CLEngine.Editor.core.converts" x:Class="CLEngine.Editor.windows.DataBaseWindow" mc:Ignorable="d" DataContext="{Binding DataBase, Source={StaticResource Locator}}" - Title="游戏数据库" Height="768" Width="1366" Background="{DynamicResource PanelBackground}"> + Title="游戏数据库" Height="800" Width="1366" Background="{DynamicResource PanelBackground}"> + + + + + - - - + - - + diff --git a/CLEditor/windows/DataBaseWindow.xaml.cs b/CLEditor/windows/DataBaseWindow.xaml.cs index 7206cae7058d8b97cb11297fbcf95018a28b1ef6..b92d9a7d37ffb17798f34922be5c5a96134da1ce 100644 --- a/CLEditor/windows/DataBaseWindow.xaml.cs +++ b/CLEditor/windows/DataBaseWindow.xaml.cs @@ -1,17 +1,7 @@ -using CLEngine.Core; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows; +using System.Windows; using System.Windows.Controls; -using System.Windows.Data; -using System.Windows.Documents; -using System.Windows.Input; -using System.Windows.Media; -using System.Windows.Media.Imaging; -using System.Windows.Shapes; +using CLEngine.Core.framework; +using CLEngine.Editor.viewmodel; namespace CLEngine.Editor.windows { @@ -20,14 +10,38 @@ namespace CLEngine.Editor.windows /// public partial class DataBaseWindow : Window { - public DataBaseWindow() + public static ListBox ItemListInstance; + + public DataBaseWindow() { InitializeComponent(); - } + ItemListInstance = ItemList; + ClassificationComboBox.SelectionChanged += ClassificationComboBoxOnSelectionChanged; + ItemList.SelectionChanged += ItemListOnSelectionChanged; + } - private void CloseBtn_Click(object sender, RoutedEventArgs e) - { - this.Close(); - } + /// + /// 物品列表选择发生改变 + /// + /// + /// + private void ItemListOnSelectionChanged(object sender, SelectionChangedEventArgs e) + { + if (DataContext is DataBaseViewModel dataBase) + { + dataBase.IconPath = (ItemList.SelectedValue as ItemObject)?.IconPath; + dataBase.DropIconPath = (ItemList.SelectedValue as ItemObject)?.DropIconPath; + } + } + + /// + /// 分类下拉框值发生改变 + /// + /// + /// + private void ClassificationComboBoxOnSelectionChanged(object sender, SelectionChangedEventArgs e) + { + (DataContext as DataBaseViewModel)?.ClearItemChildTypes(ClassificationComboBox.SelectedValue); + } } } diff --git a/CLEditor/windows/SceneHierarchyTreeView.xaml.cs b/CLEditor/windows/SceneHierarchyTreeView.xaml.cs index ba86a80eb95c25e9e349ac8c4e39b97c69a5dcf1..8ae201132dced31ba122791100eaf26517ab069a 100644 --- a/CLEditor/windows/SceneHierarchyTreeView.xaml.cs +++ b/CLEditor/windows/SceneHierarchyTreeView.xaml.cs @@ -1,29 +1,27 @@ using System; using System.Collections.Generic; -using System.IO; +using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Reflection; -using System.Threading; -using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Input; using System.Windows.Media; -using System.Windows.Threading; using CLEngine.Editor.controls; using CLEngine.Editor.core; using CLEngine.Core; using CLEngine.Core.attributes; using CLEngine.Core.components; -using SharpDX.Direct3D9; using Sprite = CLEngine.Core.Sprite; +using CLEngine.Core.framework; namespace CLEngine.Editor.windows { /// /// SceneHierarchyTreeView.xaml 的交互逻辑 /// - public partial class SceneHierarchyTreeView : UserControl + [SuppressMessage("ReSharper", "LocalizableElement")] + public partial class SceneHierarchyTreeView { #region fields @@ -85,14 +83,14 @@ namespace CLEngine.Editor.windows addComponentItem = EditorUtils.CreateMenuItem("添加组件", (ImageSource)FindResource("ComponentIcon")); MenuItem createObjectItem = EditorUtils.CreateMenuItem("创建新对象...", (ImageSource)FindResource("GameObjectIcon_Sprite")); MenuItem panelCreateObjectItem = EditorUtils.CreateMenuItem("创建新对象...", (ImageSource)FindResource("GameObjectIcon_Sprite")); - MenuItem addFromStateItem = EditorUtils.CreateMenuItem("从状态添加...", null); - MenuItem panelAddFromStateItem = EditorUtils.CreateMenuItem("从状态添加...", null); + MenuItem addFromStateItem = EditorUtils.CreateMenuItem("从状态添加..."); + MenuItem panelAddFromStateItem = EditorUtils.CreateMenuItem("从状态添加..."); saveStateItem = EditorUtils.CreateMenuItem("保存状态...", (ImageSource)FindResource("SaveIcon")); MenuItem cutItem = EditorUtils.CreateMenuItem("剪切", (ImageSource)FindResource("CutIcon")); MenuItem copyItem = EditorUtils.CreateMenuItem("复制", (ImageSource)FindResource("CopyIcon")); MenuItem pasteItem = EditorUtils.CreateMenuItem("粘贴", (ImageSource)FindResource("PasteIcon")); MenuItem panelPasteItem = EditorUtils.CreateMenuItem("粘贴", (ImageSource)FindResource("PasteIcon")); - MenuItem deleteItem = EditorUtils.CreateMenuItem("删除", null); + MenuItem deleteItem = EditorUtils.CreateMenuItem("删除"); renameItem = EditorUtils.CreateMenuItem("重命名", (ImageSource)FindResource("RenameIcon")); moveUpItem = EditorUtils.CreateMenuItem("上移", (ImageSource)FindResource("MoveUpIcon")); moveDownItem = EditorUtils.CreateMenuItem("下移", (ImageSource)FindResource("MoveDownIcon")); @@ -157,10 +155,8 @@ namespace CLEngine.Editor.windows private void SelectOnClick(MouseButtonEventArgs e) { - DragDropTreeViewItem ClickedTreeViewItem = new DragDropTreeViewItem(); - - //find the original object that raised the event - UIElement ClickedItem = VisualTreeHelper.GetParent(e.OriginalSource as UIElement) as UIElement; + //find the original object that raised the event + UIElement ClickedItem = VisualTreeHelper.GetParent((UIElement) e.OriginalSource) as UIElement; //find the clicked TreeViewItem while ((ClickedItem != null) && !(ClickedItem is DragDropTreeViewItem)) @@ -168,7 +164,7 @@ namespace CLEngine.Editor.windows ClickedItem = VisualTreeHelper.GetParent(ClickedItem) as UIElement; } - ClickedTreeViewItem = ClickedItem as DragDropTreeViewItem; + var ClickedTreeViewItem = (DragDropTreeViewItem) ClickedItem; if (ClickedTreeViewItem != null) { ClickedTreeViewItem.IsSelected = true; @@ -244,7 +240,7 @@ namespace CLEngine.Editor.windows { if (addToSelectedParent) { - GameObject _gameObject = (GameObject)(SelectedItem as DragDropTreeViewItem).Tag; + GameObject _gameObject = (GameObject)SelectedItem.Tag; if (_gameObject.Transform.Parent == null) SceneManager.ActiveScene.GameObjects.Add(gameObject); else @@ -252,7 +248,7 @@ namespace CLEngine.Editor.windows } else { - GameObject _gameObject = (GameObject)(SelectedItem as DragDropTreeViewItem).Tag; + GameObject _gameObject = (GameObject)SelectedItem.Tag; _gameObject.Children.Add(gameObject); } } @@ -339,7 +335,7 @@ namespace CLEngine.Editor.windows { ItemLostFocus(); - selectedForEditing = (SelectedItem as DragDropTreeViewItem); + selectedForEditing = SelectedItem; if (selectedForEditing == null) return; @@ -349,8 +345,8 @@ namespace CLEngine.Editor.windows tb.Text = lastSelectedItem.Tag.ToString(); tb.Focusable = true; - (selectedForEditing.Header as StackPanel).Children.RemoveAt(2); - (selectedForEditing.Header as StackPanel).Children.Add(tb); + (selectedForEditing.Header as StackPanel)?.Children.RemoveAt(2); + (selectedForEditing.Header as StackPanel)?.Children.Add(tb); selectedForEditing.CanDrag = false; tb.Select(0, tb.Text.Length); @@ -415,9 +411,12 @@ namespace CLEngine.Editor.windows typeof(TreeViewItem).GetMethod("Select", BindingFlags.NonPublic | BindingFlags.Instance); - selectMethod.Invoke(dObject, new object[] { true }); + selectMethod?.Invoke(dObject, new object[] { true }); + } + catch + { + // ignored } - catch { } } void node_MouseUp(object sender, MouseButtonEventArgs e) @@ -446,7 +445,7 @@ namespace CLEngine.Editor.windows return; } - this.ContextMenu = panelContextMenu; + ContextMenu = panelContextMenu; // 设置所有这些图层游戏对象 foreach (GameObject gameObject in SceneManager.ActiveScene.GameObjects) @@ -487,7 +486,7 @@ namespace CLEngine.Editor.windows /// internal ImageSource GameObjectImageSource(GameObject gameObject) { - if ((gameObject is Sprite) || (gameObject is AnimatedSprite) || gameObject is AnimationObject) + if ((gameObject is Sprite) || gameObject is AnimationObject) return (ImageSource)FindResource("GameObjectIcon_Sprite"); else if (gameObject is BMFont) return (ImageSource)FindResource("GameObjectIcon_Text"); @@ -506,12 +505,12 @@ namespace CLEngine.Editor.windows private void ItemLostFocus() { - if (lastSelectedItem != null && lastSelectedItem.Header != null && (lastSelectedItem.Header as StackPanel).Children.Count >= 2 + if (lastSelectedItem != null && lastSelectedItem.Header != null && ((StackPanel) lastSelectedItem.Header).Children.Count >= 2 && (lastSelectedItem.Header as StackPanel).Children[2] is TextBox) { // update the current name: if (lastSelectedItem.Tag is GameObject) - (lastSelectedItem.Tag as GameObject).Name = ((lastSelectedItem.Header as StackPanel).Children[2] as TextBox).Text; + (lastSelectedItem.Tag as GameObject).Name = ((lastSelectedItem.Header as StackPanel).Children[2] as TextBox)?.Text; // remove the text box (lastSelectedItem.Header as StackPanel).Children.RemoveAt(2); @@ -542,6 +541,7 @@ namespace CLEngine.Editor.windows AddFromState(); } + [SuppressMessage("ReSharper", "RedundantNameQualifier")] void contextMenu_Opened(object sender, RoutedEventArgs e) { // check disabled : @@ -562,80 +562,80 @@ namespace CLEngine.Editor.windows } addComponentItem.Items.Clear(); - CMenuItem item = null; + CMenuItem item; if (SceneManager.ScriptsAssembly == null) { addComponentItem.Visibility = System.Windows.Visibility.Collapsed; return; } - else - { - addComponentItem.Visibility = System.Windows.Visibility.Visible; - //ObjectComponent dummy = new ObjectComponent(); - try - { - foreach (var type in SceneManager.ScriptsAssembly.GetTypes()) - { - // 是否是gameobjectcomponent? - if (type.IsSubclassOf(typeof(ObjectComponent))) - { - string fullname = type.FullName; - CMenuItem lastItem = addComponentItem; - - if (fullname != type.Name && fullname.Contains('.')) - { - string[] splitted = fullname.Split('.'); - int scount = splitted.Count() - 1; - - for (int i = 0; i < scount; i++) - { - item = null; - string camelCaseFix = CHelper.SplitCamelCase(splitted[i]); - - for (int j = 0; j < lastItem.Items.Count; j++) - { - if ((lastItem.Items[j] as CMenuItem).TagText.Equals(camelCaseFix)) - { - item = lastItem.Items[j] as CMenuItem; - break; - } - } - - if (item == null) - { - item = EditorUtils.CreateMenuItem(camelCaseFix, null); - item.TagText = camelCaseFix; - lastItem.Items.Insert(0, item); - } - - lastItem = item; - } - } - - string camelCase = CHelper.SplitCamelCase(type.Name); - CMenuItem newItem = EditorUtils.CreateMenuItem(camelCase, (ImageSource)FindResource("ComponentItemIcon")); - newItem.Tag = type; - newItem.TagText = camelCase; - newItem.Click += newItem_Click; - - SearchAndAttachInfo(newItem, type); - - lastItem.Items.Add(newItem); - } - } - } - catch (Exception exception) - { - Console.WriteLine(exception); - } - + addComponentItem.Visibility = System.Windows.Visibility.Visible; + + //ObjectComponent dummy = new ObjectComponent(); + try + { + foreach (var type in SceneManager.ScriptsAssembly.GetTypes()) + { + // 是否是gameobjectcomponent? + if (!type.IsSubclassOf(typeof(ObjectComponent))) continue; + + var fullname = type.FullName; + var lastItem = addComponentItem; + + var contains = false; + const char c = '.'; + if (fullname != null) + { + foreach (var c1 in fullname) + { + if (!Equals(c1, c)) continue; + + contains = true; + break; + } + + if (fullname != type.Name && contains) + { + var splitted = fullname.Split('.'); + var scount = splitted.Count() - 1; + + for (var i = 0; i < scount; i++) + { + var camelCaseFix = CHelper.SplitCamelCase(splitted[i]); + + item = (from object t in lastItem.Items where ((CMenuItem) t).TagText.Equals(camelCaseFix) select t).Cast().FirstOrDefault(); + + if (item == null) + { + item = EditorUtils.CreateMenuItem(camelCaseFix); + item.TagText = camelCaseFix; + lastItem.Items.Insert(0, item); + } + + lastItem = item; + } + } + } + + var camelCase = CHelper.SplitCamelCase(type.Name); + var newItem = EditorUtils.CreateMenuItem(camelCase, (ImageSource)FindResource("ComponentItemIcon")); + newItem.Tag = type; + newItem.TagText = camelCase; + newItem.Click += newItem_Click; + + SearchAndAttachInfo(newItem, type); + + lastItem.Items.Add(newItem); + } } - - CMenuItem luaSubItem; - luaSubItem = EditorUtils.CreateMenuItem("Lua脚本", - (ImageSource) FindResource("ComponentItemIcon")); + catch (Exception exception) + { + Console.WriteLine(exception); + } + + var luaSubItem = EditorUtils.CreateMenuItem("Lua脚本", + (ImageSource) FindResource("ComponentItemIcon")); luaSubItem.Tag = typeof(LuaObject); luaSubItem.TagText = typeof(LuaObject).Name; luaSubItem.Click += newItem_Click; @@ -645,12 +645,11 @@ namespace CLEngine.Editor.windows addComponentItem.Items.Add(luaSubItem); // System Components : - CMenuItem subItem; addComponentItem.Items.Add(new Separator()); item = EditorUtils.CreateMenuItem("物理"); - subItem = EditorUtils.CreateMenuItem("刚体", (ImageSource)FindResource("ComponentItemIcon")); + var subItem = EditorUtils.CreateMenuItem("刚体", (ImageSource)FindResource("ComponentItemIcon")); subItem.Tag = typeof(PhysicalBody); subItem.TagText = typeof(PhysicalBody).Name; subItem.Click += newItem_Click; @@ -701,26 +700,24 @@ namespace CLEngine.Editor.windows } - private void SearchAndAttachInfo(CMenuItem item, Type type) + private void SearchAndAttachInfo(FrameworkElement item, MemberInfo type) { - System.Reflection.MemberInfo info; - object[] attributes; + MemberInfo info = type; + var attributes = info.GetCustomAttributes(typeof(Info), true); - info = type; - attributes = info.GetCustomAttributes(typeof(Info), true); - - if (attributes.Count() > 0) - item.ToolTip = (attributes[0] as Info).Value.Replace("\\n", Environment.NewLine); + var count = attributes.Length; + if (count > 0) + item.ToolTip = (attributes[0] as Info)?.Value.Replace("\\n", Environment.NewLine); } void newItem_Click(object sender, RoutedEventArgs e) { - CMenuItem _sender = (CMenuItem)sender; + var _sender = (CMenuItem)sender; foreach (var ti in TreeViewExtension.GetSelectedTreeViewItems(treeView)) { - ObjectComponent component = (ObjectComponent)Activator.CreateInstance((Type)_sender.Tag, new object[] { /* params here */ }); - GameObject gameObject = (GameObject)ti.Tag; + var component = (ObjectComponent)Activator.CreateInstance((Type)_sender.Tag, new object[] { /* params here */ }); + var gameObject = (GameObject)ti.Tag; if (!gameObject.AddComponent(component)) { MessageBox.Show("该组件未添加到 " + gameObject.Name + ", 要求未得到满足", "错误", MessageBoxButton.OK, MessageBoxImage.Error); @@ -732,22 +729,22 @@ namespace CLEngine.Editor.windows } } - void createObjectItem_Click(object sender, RoutedEventArgs e) + private void createObjectItem_Click(object sender, RoutedEventArgs e) { - new AddNewItemWindow(SelectedItem as UIElement).ShowDialog(); + new AddNewItemWindow(SelectedItem).ShowDialog(); } - void treeView_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) + private void treeView_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { SelectOnClick(e); } - void treeView_MouseRightButtonDown(object sender, MouseButtonEventArgs e) + private void treeView_MouseRightButtonDown(object sender, MouseButtonEventArgs e) { SelectOnClick(e); } - void treeView_OnDragDropSuccess(DragDropTreeViewItem source, DragDropTreeViewItem target, System.ComponentModel.CancelEventArgs e) + private void treeView_OnDragDropSuccess(DragDropTreeViewItem source, DragDropTreeViewItem target, System.ComponentModel.CancelEventArgs e) { if (!(source.Tag is GameObject)) { @@ -755,7 +752,7 @@ namespace CLEngine.Editor.windows return; } - List movedItems = TreeViewExtension.GetSelectedTreeViewItems(treeView); + var movedItems = TreeViewExtension.GetSelectedTreeViewItems(treeView); // 验证移动的物品是否不会放在他们的任何子物体或自己的子物体身上 foreach (var ti in movedItems) { @@ -767,60 +764,56 @@ namespace CLEngine.Editor.windows return; } - if (DragDropTreeView.TreeContainsNode(treeView, tx, target)) - { - e.Cancel = true; - return; - } + if (!DragDropTreeView.TreeContainsNode(treeView, tx, target)) continue; + e.Cancel = true; + return; } - if (target.Tag is GameObject) + if (target.Tag is GameObject tag) { foreach (var ti in movedItems) { - GameObject _source = ti.Tag as GameObject; + var _source = ti.Tag as GameObject; // no parent? - if (_source.Transform.Parent == null) + if (_source != null && _source.Transform.Parent == null) { SceneManager.ActiveScene.GameObjects.Remove(_source, false); } else { - GameObject parent = (ti.Parent as DragDropTreeViewItem).Tag as GameObject; - parent.Children.Remove(_source, false); + var parent = (ti.Parent as DragDropTreeViewItem)?.Tag as GameObject; + parent?.Children.Remove(_source, false); } if (DragDropHelper.insertionPlace == DragDropHelper.InsertionPlace.Center) { - (target.Tag as GameObject).Children.Insert(0, _source); + tag.Children.Insert(0, _source); } else { - int index = 0; - - // no parent? - if ((target.Tag as GameObject).Transform.Parent == null) + // no parent? + var index = 0; + if (tag.Transform.Parent == null) { - index = SceneManager.ActiveScene.GameObjects.IndexOf(target.Tag as GameObject); + index = SceneManager.ActiveScene.GameObjects.IndexOf(tag); } else - { - GameObject parent = (target.Parent as DragDropTreeViewItem).Tag as GameObject; - index = parent.Children.IndexOf(target.Tag as GameObject); - } + { + if ((target.Parent as DragDropTreeViewItem)?.Tag is GameObject parent) index = parent.Children.IndexOf(tag); + } if (DragDropHelper.insertionPlace == DragDropHelper.InsertionPlace.Top) index++; - if ((target.Tag as GameObject).Transform.Parent == null) + if (tag.Transform.Parent == null) { SceneManager.ActiveScene.GameObjects.Insert(index, _source); } else { - GameObject parent = (target.Parent as DragDropTreeViewItem).Tag as GameObject; - parent.Children.Insert(index, _source); + var parent = (target.Parent as DragDropTreeViewItem)?.Tag as GameObject; + parent?.Children.Insert(index, _source); } } @@ -833,26 +826,27 @@ namespace CLEngine.Editor.windows } } - void visibilityToggleImage_MouseUp(object sender, MouseButtonEventArgs e) + [SuppressMessage("ReSharper", "PossibleNullReferenceException")] + private void visibilityToggleImage_MouseUp(object sender, MouseButtonEventArgs e) { - object tag = (sender as Image).Tag; + var tag = (sender as Image)?.Tag; - if (tag is GameObject) + if (tag is GameObject gameObject) { - (tag as GameObject).Visible = !(tag as GameObject).Visible; + gameObject.Visible = !gameObject.Visible; } - if (!(tag as GameObject).Visible) + if (tag != null && !(tag as GameObject).Visible) { - (sender as Image).Source = hiddenItemIcon; + ((Image) sender).Source = hiddenItemIcon; } else { - (sender as Image).Source = visibleItemIcon; + ((Image) sender).Source = visibleItemIcon; } } - void node_MouseDoubleClick(object sender, MouseButtonEventArgs e) + private void node_MouseDoubleClick(object sender, MouseButtonEventArgs e) { //if (lastSelectedItem != null && lastSelectedItem.Tag != null) //{ @@ -866,7 +860,7 @@ namespace CLEngine.Editor.windows //} } - void tb_LostFocus(object sender, RoutedEventArgs e) + private void tb_LostFocus(object sender, RoutedEventArgs e) { ItemLostFocus(); lastSelectedItem.CanDrag = true; @@ -880,77 +874,87 @@ namespace CLEngine.Editor.windows } - void moveDownItem_Click(object sender, RoutedEventArgs e) + private void moveDownItem_Click(object sender, RoutedEventArgs e) { - GameObject gameObject = (GameObject)(SelectedItem as DragDropTreeViewItem).Tag; + var gameObject = (GameObject)SelectedItem.Tag; // no parent? - if (!((SelectedItem as DragDropTreeViewItem).Parent is DragDropTreeView)) + if (!(SelectedItem.Parent is DragDropTreeView)) { - DragDropTreeViewItem parentNode = (SelectedItem as DragDropTreeViewItem).Parent as DragDropTreeViewItem; + var parentNode = SelectedItem.Parent as DragDropTreeViewItem; - int index = (parentNode.Tag as GameObject).Children.FindIndex(o => o.GetHashCode() == gameObject.GetHashCode()); + if (parentNode != null) + { + var index = ((GameObject) parentNode.Tag).Children.FindIndex(o => o.GetHashCode() == gameObject.GetHashCode()); - // already on bottom? - if (index == 0) - return; + // already on bottom? + if (index == 0) + return; - GameObject parent = (GameObject)parentNode.Tag; + var parent = (GameObject)parentNode.Tag; - // Shift objects - GameObject topObject = parent.Children[index - 1]; - parent.Children.Delete(topObject); - parent.Children.Insert(index, topObject); + // Shift objects + var topObject = parent.Children[index - 1]; + parent.Children.Delete(topObject); + parent.Children.Insert(index, topObject); + } //// Shift in treeview - DragDropTreeViewItem topNode = (DragDropTreeViewItem)parentNode.Items[parentNode.Items.IndexOf(SelectedItem) + 1]; + if (parentNode == null) return; + + var topNode = (DragDropTreeViewItem)parentNode.Items[parentNode.Items.IndexOf(SelectedItem) + 1]; parentNode.Items.Remove(topNode); parentNode.Items.Insert(parentNode.Items.IndexOf(SelectedItem), topNode); } else { - int index = SceneManager.ActiveScene.GameObjects.FindIndex(o => o.GetHashCode() == gameObject.GetHashCode()); + var index = SceneManager.ActiveScene.GameObjects.FindIndex(o => o.GetHashCode() == gameObject.GetHashCode()); // already on bottom? if (index == 0) return; // Shift objects - GameObject topObject = SceneManager.ActiveScene.GameObjects[index - 1]; + var topObject = SceneManager.ActiveScene.GameObjects[index - 1]; SceneManager.ActiveScene.GameObjects.Delete(topObject); SceneManager.ActiveScene.GameObjects.Insert(index, topObject); //// Shift in treeview - DragDropTreeViewItem topNode = (DragDropTreeViewItem)treeView.Items[treeView.Items.IndexOf(SelectedItem) + 1]; + var topNode = (DragDropTreeViewItem)treeView.Items[treeView.Items.IndexOf(SelectedItem) + 1]; treeView.Items.Remove(topNode); treeView.Items.Insert(treeView.Items.IndexOf(SelectedItem), topNode); } } - void moveUpItem_Click(object sender, RoutedEventArgs e) + private void moveUpItem_Click(object sender, RoutedEventArgs e) { - GameObject gameObject = (GameObject)(SelectedItem as DragDropTreeViewItem).Tag; + var gameObject = (GameObject)SelectedItem.Tag; // no parent? - if (!((SelectedItem as DragDropTreeViewItem).Parent is DragDropTreeView)) + if (!(SelectedItem.Parent is DragDropTreeView)) { - DragDropTreeViewItem parentNode = (SelectedItem as DragDropTreeViewItem).Parent as DragDropTreeViewItem; + var parentNode = SelectedItem.Parent as DragDropTreeViewItem; - int index = (parentNode.Tag as GameObject).Children.FindIndex(o => o.GetHashCode() == gameObject.GetHashCode()); + if (parentNode != null) + { + var index = ((GameObject) parentNode.Tag).Children.FindIndex(o => o.GetHashCode() == gameObject.GetHashCode()); - // already on bottom? - if (index == (parentNode.Tag as GameObject).Children.Count - 1) - return; + // already on bottom? + if (index == ((GameObject) parentNode.Tag).Children.Count - 1) + return; - GameObject parent = (GameObject)parentNode.Tag; + var parent = (GameObject)parentNode.Tag; - // Shift objects - GameObject topObject = parent.Children[index + 1]; - parent.Children.Delete(topObject); - parent.Children.Insert(index, topObject); + // Shift objects + var topObject = parent.Children[index + 1]; + parent.Children.Delete(topObject); + parent.Children.Insert(index, topObject); + } //// Shift in treeview - DragDropTreeViewItem topNode = (DragDropTreeViewItem)parentNode.Items[parentNode.Items.IndexOf(SelectedItem) - 1]; + if (parentNode == null) return; + + var topNode = (DragDropTreeViewItem)parentNode.Items[parentNode.Items.IndexOf(SelectedItem) - 1]; parentNode.Items.Remove(topNode); parentNode.Items.Insert(parentNode.Items.IndexOf(SelectedItem) + 1, topNode); } @@ -974,10 +978,10 @@ namespace CLEngine.Editor.windows } } - void deleteItem_Click(object sender, RoutedEventArgs e) + private void deleteItem_Click(object sender, RoutedEventArgs e) { - List selected = TreeViewExtension.GetSelectedTreeViewItems(treeView); - string message = "您确定要删除所选的游戏对象吗?"; + var selected = TreeViewExtension.GetSelectedTreeViewItems(treeView); + var message = "您确定要删除所选的游戏对象吗?"; if (selected.Count > 1) { message = "您确定要删除所选的游戏对象吗?"; @@ -988,11 +992,10 @@ namespace CLEngine.Editor.windows TreeViewExtension.UnselectAll(treeView); foreach (var t in selected) { - GameObject gameObject = (GameObject)(t as DragDropTreeViewItem).Tag; //(GameObject)(SelectedItem as DragDropTreeViewItem).Tag; - DragDropTreeViewItem parentNode = (t as DragDropTreeViewItem).Parent as DragDropTreeViewItem; + DragDropTreeViewItem parentNode = (t as DragDropTreeViewItem)?.Parent as DragDropTreeViewItem; if (parentNode == null) { - SceneManager.ActiveScene.GameObjects.Remove((t as DragDropTreeViewItem).Tag as GameObject); + SceneManager.ActiveScene.GameObjects.Remove((t as DragDropTreeViewItem)?.Tag as GameObject); treeView.Items.Remove(t); } else @@ -1012,28 +1015,31 @@ namespace CLEngine.Editor.windows Paste(); } - void copyItem_Click(object sender, RoutedEventArgs e) + private void copyItem_Click(object sender, RoutedEventArgs e) { - List toCopy = new List(); - foreach (TreeViewItem ti in TreeViewExtension.GetSelectedTreeViewItems(treeView)) + var toCopy = new List(); + foreach (var ti in TreeViewExtension.GetSelectedTreeViewItems(treeView)) { - var gameObject = (ti.Tag as GameObject); - gameObject.SaveComponentValues(); - toCopy.Add(gameObject); - + if (ti.Tag is GameObject gameObject) + { + gameObject.SaveComponentValues(); + toCopy.Add(gameObject); + } } Clipboard.SetData("GameObject", toCopy); } - void cutItem_Click(object sender, RoutedEventArgs e) + private void cutItem_Click(object sender, RoutedEventArgs e) { - List toCopy = new List(); + var toCopy = new List(); foreach (TreeViewItem ti in TreeViewExtension.GetSelectedTreeViewItems(treeView)) { - var gameObject = (ti.Tag as GameObject); - gameObject.SaveComponentValues(); - toCopy.Add(gameObject); + if (ti.Tag is GameObject gameObject) + { + gameObject.SaveComponentValues(); + toCopy.Add(gameObject); + } DragDropTreeViewItem parentNode = ti.Parent as DragDropTreeViewItem; if (parentNode == null) @@ -1061,7 +1067,7 @@ namespace CLEngine.Editor.windows if (fbd.ShowDialog() == System.Windows.Forms.DialogResult.OK) { - (SelectedItem.Tag as GameObject)?.Save(fbd.SelectedPath + "//" + (SelectedItem.Tag as GameObject)?.Name + ".state"); + (SelectedItem.Tag as GameObject)?.Save(fbd.SelectedPath + "//" + (SelectedItem.Tag as GameObject).Name + ".state"); } } @@ -1071,7 +1077,7 @@ namespace CLEngine.Editor.windows if (treeView.SelectedItem != null && e.LeftButton == MouseButtonState.Pressed) { - (treeView.SelectedItem as TreeViewItem).IsSelected = false; + ((TreeViewItem) treeView.SelectedItem).IsSelected = false; TreeViewExtension.UnselectAll(treeView); } } @@ -1115,7 +1121,7 @@ namespace CLEngine.Editor.windows { foreach (TreeViewItem item in TreeViewExtension.GetExpandedTreeViewItems(treeView)) { - object tag = (item as DragDropTreeViewItem).Tag; + object tag = (item as DragDropTreeViewItem)?.Tag; if (tag is GameObject) { if (!EditorHandler.SelectedGameObjects.Contains((tag as GameObject))) diff --git a/Engine/CLEngine.Core/CHelper.cs b/Engine/CLEngine.Core/CHelper.cs index 8bded647422f2ef6b6c302fb95a7c20ebeed02da..c48bf05254c4071a3a1051fdc2a95dbf5c979ef9 100644 --- a/Engine/CLEngine.Core/CHelper.cs +++ b/Engine/CLEngine.Core/CHelper.cs @@ -12,79 +12,79 @@ using System.Xml; namespace CLEngine.Core { - /// - /// 一个静态类,为游戏开发编辑器或引擎提供有用的方法 - /// - public static class CHelper - { - private static readonly string _updaterPath = Path.Combine(Application.StartupPath, "qupdater.exe"); + /// + /// 一个静态类,为游戏开发编辑器或引擎提供有用的方法 + /// + public static class CHelper + { + private static readonly string _updaterPath = Path.Combine(Application.StartupPath, "qupdater.exe"); /// /// /// /// - public static int CheckNewFiles() - { - return RunUpdater("-checkforupdates", true); - } + public static int CheckNewFiles() + { + return RunUpdater("-checkforupdates", true); + } /// /// /// - public static void RunUpdater() - { - RunUpdater(string.Empty, false); - } - - private static int RunUpdater(string arguments, bool waitForExit) - { - try - { - var info = new FileInfo(_updaterPath); - if (!info.Exists) - { - return 0; - } - - var info2 = new ProcessStartInfo { FileName = info.FullName }; - if (info.Directory != null) info2.WorkingDirectory = info.Directory.FullName; - info2.Arguments = arguments; - var process = new Process { StartInfo = info2 }; - process.Start(); - if (!waitForExit) - { - return 0; - } - process.WaitForExit(); - - return process.ExitCode; - } - catch (Exception) - { - // ignored - } - - return 0; - } + public static void RunUpdater() + { + RunUpdater(string.Empty, false); + } + + private static int RunUpdater(string arguments, bool waitForExit) + { + try + { + var info = new FileInfo(_updaterPath); + if (!info.Exists) + { + return 0; + } + + var info2 = new ProcessStartInfo { FileName = info.FullName }; + if (info.Directory != null) info2.WorkingDirectory = info.Directory.FullName; + info2.Arguments = arguments; + var process = new Process { StartInfo = info2 }; + process.Start(); + if (!waitForExit) + { + return 0; + } + process.WaitForExit(); + + return process.ExitCode; + } + catch (Exception) + { + // ignored + } + + return 0; + } #if WIN public static void SerializeObject(string filename, object objectToSerialize) - { - try - { - MemoryStream stream = new MemoryStream(); - BinaryFormatter formatter = new BinaryFormatter(); - formatter.AssemblyFormat = System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Simple; - formatter.Serialize(stream, objectToSerialize); - byte[] serializedData = stream.ToArray(); - - File.WriteAllBytes(filename, serializedData); - } - catch (Exception ex) - { - Console.Write(string.Format("错误!\n错误信息: {0}\n{1}", ex.Message, ex.StackTrace)); - } - } + { + try + { + MemoryStream stream = new MemoryStream(); + BinaryFormatter formatter = new BinaryFormatter(); + formatter.AssemblyFormat = System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Simple; + formatter.Serialize(stream, objectToSerialize); + byte[] serializedData = stream.ToArray(); + + File.WriteAllBytes(filename, serializedData); + } + catch (Exception ex) + { + Console.Write(string.Format("错误!\n错误信息: {0}\n{1}", ex.Message, ex.StackTrace)); + } + } #elif WINRT public async static void SerializeObject(string filename, object objectToSerialize) { @@ -93,78 +93,78 @@ namespace CLEngine.Core #endif #if WIN - public static void SerializeObjectXML(string filename, object objectToSerialize) - { - try - { - MemoryStream stream = new MemoryStream(); - DataContractSerializer serializer = new DataContractSerializer(objectToSerialize.GetType(), null, - int.MaxValue, false, true, null); - - var settings = new XmlWriterSettings() - { - Indent = true, - IndentChars = "\t" - }; - - settings.NamespaceHandling = NamespaceHandling.OmitDuplicates; - //settings.OutputMethod = XmlOutputMethod.Xml; - settings.ConformanceLevel = ConformanceLevel.Fragment; - - using (XmlDictionaryWriter writer = - XmlDictionaryWriter.CreateDictionaryWriter(XmlWriter.Create(stream, settings))) - { - serializer.WriteObject(writer, objectToSerialize, new MyCustomerResolver()); - } - - byte[] serializedData = stream.ToArray(); - File.WriteAllBytes(filename, serializedData); - - //var emptyNamepsaces = new XmlSerializerNamespaces(new[] { XmlQualifiedName.Empty }); - //var serializer = new XmlSerializer(objectToSerialize.GetType()); - //var settings = new XmlWriterSettings(); - //settings.Indent = true; - //settings.OmitXmlDeclaration = true; - - //MemoryStream stream = new MemoryStream(); - //using (var writer = XmlWriter.Create(stream, settings)) - //{ - // serializer.Serialize(writer, objectToSerialize, emptyNamepsaces); - //} - - //byte[] serializedData = stream.ToArray(); - //File.WriteAllBytes(filename, serializedData); - - //stream.Dispose(); - } - catch (Exception ex) - { - Console.Write(string.Format("Error!\nError Message: {0}\n{1}", ex.Message, ex.StackTrace)); - } - } + public static void SerializeObjectXML(string filename, object objectToSerialize) + { + try + { + MemoryStream stream = new MemoryStream(); + DataContractSerializer serializer = new DataContractSerializer(objectToSerialize.GetType(), null, + int.MaxValue, false, true, null); + + var settings = new XmlWriterSettings() + { + Indent = true, + IndentChars = "\t" + }; + + settings.NamespaceHandling = NamespaceHandling.OmitDuplicates; + //settings.OutputMethod = XmlOutputMethod.Xml; + settings.ConformanceLevel = ConformanceLevel.Fragment; + + using (XmlDictionaryWriter writer = + XmlDictionaryWriter.CreateDictionaryWriter(XmlWriter.Create(stream, settings))) + { + serializer.WriteObject(writer, objectToSerialize, new MyCustomerResolver()); + } + + byte[] serializedData = stream.ToArray(); + File.WriteAllBytes(filename, serializedData); + + //var emptyNamepsaces = new XmlSerializerNamespaces(new[] { XmlQualifiedName.Empty }); + //var serializer = new XmlSerializer(objectToSerialize.GetType()); + //var settings = new XmlWriterSettings(); + //settings.Indent = true; + //settings.OmitXmlDeclaration = true; + + //MemoryStream stream = new MemoryStream(); + //using (var writer = XmlWriter.Create(stream, settings)) + //{ + // serializer.Serialize(writer, objectToSerialize, emptyNamepsaces); + //} + + //byte[] serializedData = stream.ToArray(); + //File.WriteAllBytes(filename, serializedData); + + //stream.Dispose(); + } + catch (Exception ex) + { + Console.Write(string.Format("Error!\nError Message: {0}\n{1}", ex.Message, ex.StackTrace)); + } + } #endif #if WIN - public static object DeserializeObject(string filename) - { - try - { - byte[] bytes = File.ReadAllBytes(filename); - - MemoryStream stream = new MemoryStream(bytes); - BinaryFormatter formatter = new BinaryFormatter(); - formatter.AssemblyFormat = System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Simple; - formatter.Binder = new VersionConfigToNamespaceAssemblyObjectBinder(); - - return (Object) formatter.Deserialize(stream); - } - catch (Exception ex) - { - Console.Write(string.Format("反序列化时出错!\n错误信息: {0}\n{1}", ex.Message, ex.StackTrace)); - return null; - } - - } + public static object DeserializeObject(string filename) + { + try + { + byte[] bytes = File.ReadAllBytes(filename); + + MemoryStream stream = new MemoryStream(bytes); + BinaryFormatter formatter = new BinaryFormatter(); + formatter.AssemblyFormat = System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Simple; + formatter.Binder = new VersionConfigToNamespaceAssemblyObjectBinder(); + + return (Object)formatter.Deserialize(stream); + } + catch (Exception ex) + { + Console.Write(string.Format("反序列化时出错!\n错误信息: {0}\n{1}", ex.Message, ex.StackTrace)); + return null; + } + + } #elif WINRT public static object DeserializeObject(Type type, string filename) { @@ -179,209 +179,224 @@ namespace CLEngine.Core } #endif - private static readonly Random random = new Random(); - private static readonly object syncLock = new object(); + private static readonly Random random = new Random(); + private static readonly object syncLock = new object(); - public static int RandomNumber(int min, int max) - { - lock (syncLock) - { - return random.Next(min, max); - } - } + public static int RandomNumber(int min, int max) + { + lock (syncLock) + { + return random.Next(min, max); + } + } - /// - /// 创建从一个文件或文件夹到另一个文件或文件夹的相对路径 - /// - /// - /// - /// - public static String MakeExclusiveRelativePath(String fromPath, String toPath) - { - if (String.IsNullOrEmpty(fromPath)) throw new ArgumentNullException("fromPath"); - if (String.IsNullOrEmpty(toPath)) throw new ArgumentNullException("toPath"); + /// + /// 创建从一个文件或文件夹到另一个文件或文件夹的相对路径 + /// + /// + /// + /// + public static String MakeExclusiveRelativePath(String fromPath, String toPath) + { + if (String.IsNullOrEmpty(fromPath)) throw new ArgumentNullException("fromPath"); + if (String.IsNullOrEmpty(toPath)) throw new ArgumentNullException("toPath"); #if WIN - return toPath.Replace(fromPath, string.Empty).TrimStart(System.IO.Path.DirectorySeparatorChar); + return toPath.Replace(fromPath, string.Empty).TrimStart(System.IO.Path.DirectorySeparatorChar); #elif WINRT return toPath.Replace(fromPath, string.Empty).TrimStart('\\'); #endif - } + } - public static string EncryptMD5(string input) - { + public static string EncryptMD5(string input) + { #if WIN - MD5 md5Hasher = MD5.Create(); - byte[] data = md5Hasher.ComputeHash(Encoding.UTF8.GetBytes(input)); - - // 创建一个新的Stringbuilder来收集字节 - // 并创建一个字符串。 - StringBuilder sBuilder = new StringBuilder(); - - // 循环遍历散列数据的每个字节 - // 并将每个格式化为十六进制字符串。 - for (int i = 0; i < data.Length; i++) - { - sBuilder.Append(data[i].ToString("x2")); - } - - // 返回十六进制字符串 - return sBuilder.ToString(); + MD5 md5Hasher = MD5.Create(); + byte[] data = md5Hasher.ComputeHash(Encoding.UTF8.GetBytes(input)); + + // 创建一个新的Stringbuilder来收集字节 + // 并创建一个字符串。 + StringBuilder sBuilder = new StringBuilder(); + + // 循环遍历散列数据的每个字节 + // 并将每个格式化为十六进制字符串。 + for (int i = 0; i < data.Length; i++) + { + sBuilder.Append(data[i].ToString("x2")); + } + + // 返回十六进制字符串 + return sBuilder.ToString(); #elif WINRT // TODO: throw new NotImplementedException(); #endif - } + } #if WIN - /// - /// 将整个目录复制到目标 - /// - /// Source directory path - /// Destination path - /// Copy sub directories - public static void CopyDirectory(string sourceDirName, string destDirName, bool copySubDirs) - { - DirectoryInfo dir = new DirectoryInfo(sourceDirName); - DirectoryInfo[] dirs = dir.GetDirectories(); - - // 如果源目录不存在,则抛出异常 - if (!dir.Exists) - { - throw new DirectoryNotFoundException( - "源目录不存在或找不到: " - + sourceDirName); - } - - // 如果目标目录不存在,请创建它 - if (!Directory.Exists(destDirName)) - { - Directory.CreateDirectory(destDirName); - } - - // 获取要复制的目录的文件内容 - FileInfo[] files = dir.GetFiles(); - - foreach (FileInfo file in files) - { - // 创建文件新副本的路径 - string temppath = System.IO.Path.Combine(destDirName, file.Name); - - // 复制文件 - file.CopyTo(temppath, true); - } - - // 如果copySubDirs为true,则复制子目录 - if (copySubDirs) - { - foreach (DirectoryInfo subdir in dirs) - { - // Create the subdirectory. - string temppath = System.IO.Path.Combine(destDirName, subdir.Name); - - // Copy the subdirectories. - CopyDirectory(subdir.FullName, temppath, copySubDirs); - } - } - } + /// + /// 将整个目录复制到目标 + /// + /// Source directory path + /// Destination path + /// Copy sub directories + public static void CopyDirectory(string sourceDirName, string destDirName, bool copySubDirs) + { + DirectoryInfo dir = new DirectoryInfo(sourceDirName); + DirectoryInfo[] dirs = dir.GetDirectories(); + + // 如果源目录不存在,则抛出异常 + if (!dir.Exists) + { + throw new DirectoryNotFoundException( + "源目录不存在或找不到: " + + sourceDirName); + } + + // 如果目标目录不存在,请创建它 + if (!Directory.Exists(destDirName)) + { + Directory.CreateDirectory(destDirName); + } + + // 获取要复制的目录的文件内容 + FileInfo[] files = dir.GetFiles(); + + foreach (FileInfo file in files) + { + // 创建文件新副本的路径 + string temppath = System.IO.Path.Combine(destDirName, file.Name); + + // 复制文件 + file.CopyTo(temppath, true); + } + + // 如果copySubDirs为true,则复制子目录 + if (copySubDirs) + { + foreach (DirectoryInfo subdir in dirs) + { + // Create the subdirectory. + string temppath = System.IO.Path.Combine(destDirName, subdir.Name); + + // Copy the subdirectories. + CopyDirectory(subdir.FullName, temppath, copySubDirs); + } + } + } #endif - public static string SplitCamelCase(string str) - { - string camelCase = Regex.Replace(Regex.Replace(str, @"(\P{Ll})(\P{Ll}\p{Ll})", "$1 $2"), - @"(\p{Ll})(\P{Ll})", "$1 $2"); - - // 删除双空格并返回 - return Regex.Replace(camelCase, @"\s+", " "); - - } - } + public static string SplitCamelCase(string str) + { + string camelCase = Regex.Replace(Regex.Replace(str, @"(\P{Ll})(\P{Ll}\p{Ll})", "$1 $2"), + @"(\p{Ll})(\P{Ll})", "$1 $2"); -#if WIN - internal sealed class VersionConfigToNamespaceAssemblyObjectBinder : SerializationBinder - { - /// - /// - /// - /// - /// - /// - public override Type BindToType(string assemblyName, string typeName) - { - Type typeToDeserialize = null; + // 删除双空格并返回 + return Regex.Replace(camelCase, @"\s+", " "); - try - { - string ToAssemblyName = assemblyName.Split(',')[0]; - - Assembly[] Assemblies = AppDomain.CurrentDomain.GetAssemblies(); - foreach (Assembly ass in Assemblies) - { - if (ass.FullName.Split(',')[0] == ToAssemblyName) - { - typeToDeserialize = ass.GetType(typeName); - - break; - } - } - } + } - catch (System.Exception exception) - { - throw exception; - } + /// + /// 改变Settings.ini文件为release模式 + /// + public static void ChangeSettingsToRelease(string path) + { + var destination = Path.Combine(path, "settings.ini"); + var iniFile = new IniFile(destination); + if (!File.Exists(destination)) + return; + + iniFile.IniWriteValue("Profile", "Visible", "False"); + iniFile.IniWriteValue("Console", "Visible", "False"); + iniFile.IniWriteValue("Console", "WriteToConsole", "False"); + } + } - return typeToDeserialize; - } - } +#if WIN + internal sealed class VersionConfigToNamespaceAssemblyObjectBinder : SerializationBinder + { + /// + /// + /// + /// + /// + /// + public override Type BindToType(string assemblyName, string typeName) + { + Type typeToDeserialize = null; + + try + { + string ToAssemblyName = assemblyName.Split(',')[0]; + + Assembly[] Assemblies = AppDomain.CurrentDomain.GetAssemblies(); + foreach (Assembly ass in Assemblies) + { + if (ass.FullName.Split(',')[0] == ToAssemblyName) + { + typeToDeserialize = ass.GetType(typeName); + + break; + } + } + } + + catch (System.Exception exception) + { + throw exception; + } + + return typeToDeserialize; + } + } #endif - public class MyCustomerResolver : DataContractResolver - { - public override bool TryResolveType(Type dataContractType, Type declaredType, - DataContractResolver knownTypeResolver, out XmlDictionaryString typeName, - out XmlDictionaryString typeNamespace) - { - //return knownTypeResolver.TryResolveType(dataContractType, declaredType, null, out typeName, out typeNamespace); - //XmlDictionary dictionary = new XmlDictionary(); - //typeName = dictionary.Add(dataContractType.FullName); - //typeNamespace = dictionary.Add(dataContractType.Namespace); - ////knownTypeResolver.TryResolveType(dataContractType, declaredType, null, out typeName, out typeNamespace); - //return true; - - //if (dataContractType == typeof(Customer)) - //{ - // XmlDictionary dictionary = new XmlDictionary(); - // typeName = dictionary.Add("SomeCustomer"); - // typeNamespace = dictionary.Add("http://tempuri.com"); - // return true; - //} - //else - //{ - // return knownTypeResolver.TryResolveType(dataContractType, declaredType, null, out typeName, out typeNamespace); - //} - - string name = dataContractType.Name; - string namesp = dataContractType.Namespace; - typeName = new XmlDictionaryString(XmlDictionary.Empty, name, 0); - typeNamespace = new XmlDictionaryString(XmlDictionary.Empty, namesp, 0); - - return true; - } - - public override Type ResolveName(string typeName, string typeNamespace, Type declaredType, - DataContractResolver knownTypeResolver) - { - //Console.Info(typeNamespace + "." + typeName); - //Type tx = declaredType; - //Console.Info(tx); - //Type t = Assembly.GetExecutingAssembly().GetType(typeName); - //return t; - //Debug.Info("TESTE::: " + typeName + "::" + declaredType.Name); - //return declaredType; - - //Debug.Info("TESTE: " + typeNamespace + "." + typeName + " (" + declaredType + ")"); - Type t = SceneManager.ScriptsAssembly.GetType(typeNamespace + "." + typeName); + public class MyCustomerResolver : DataContractResolver + { + public override bool TryResolveType(Type dataContractType, Type declaredType, + DataContractResolver knownTypeResolver, out XmlDictionaryString typeName, + out XmlDictionaryString typeNamespace) + { + //return knownTypeResolver.TryResolveType(dataContractType, declaredType, null, out typeName, out typeNamespace); + //XmlDictionary dictionary = new XmlDictionary(); + //typeName = dictionary.Add(dataContractType.FullName); + //typeNamespace = dictionary.Add(dataContractType.Namespace); + ////knownTypeResolver.TryResolveType(dataContractType, declaredType, null, out typeName, out typeNamespace); + //return true; + + //if (dataContractType == typeof(Customer)) + //{ + // XmlDictionary dictionary = new XmlDictionary(); + // typeName = dictionary.Add("SomeCustomer"); + // typeNamespace = dictionary.Add("http://tempuri.com"); + // return true; + //} + //else + //{ + // return knownTypeResolver.TryResolveType(dataContractType, declaredType, null, out typeName, out typeNamespace); + //} + + string name = dataContractType.Name; + string namesp = dataContractType.Namespace; + typeName = new XmlDictionaryString(XmlDictionary.Empty, name, 0); + typeNamespace = new XmlDictionaryString(XmlDictionary.Empty, namesp, 0); + + return true; + } + + public override Type ResolveName(string typeName, string typeNamespace, Type declaredType, + DataContractResolver knownTypeResolver) + { + //Console.Info(typeNamespace + "." + typeName); + //Type tx = declaredType; + //Console.Info(tx); + //Type t = Assembly.GetExecutingAssembly().GetType(typeName); + //return t; + //Debug.Info("TESTE::: " + typeName + "::" + declaredType.Name); + //return declaredType; + + //Debug.Info("TESTE: " + typeNamespace + "." + typeName + " (" + declaredType + ")"); + Type t = SceneManager.ScriptsAssembly.GetType(typeNamespace + "." + typeName); #if WINRT if (t == null) @@ -390,18 +405,18 @@ namespace CLEngine.Core t = declaredType.GetType().GetTypeInfo().Assembly.GetType(typeNamespace + "." + typeName); } #endif - //if (typeName == "Single") - // return typeof(Single); - //else if (typeName == "Boolean") - // return typeof(Boolean); - //else if (typeName.ToLower() == "string") - // return typeof(string); - //else if (typeName.ToLower() == "float") - // return typeof(float); - //else if (typeName.ToLower() == "int32") - // return typeof(Int32); - - return t; - } - } + //if (typeName == "Single") + // return typeof(Single); + //else if (typeName == "Boolean") + // return typeof(Boolean); + //else if (typeName.ToLower() == "string") + // return typeof(string); + //else if (typeName.ToLower() == "float") + // return typeof(float); + //else if (typeName.ToLower() == "int32") + // return typeof(Int32); + + return t; + } + } } \ No newline at end of file diff --git a/Engine/CLEngine.Core/CLEngine.Core.csproj b/Engine/CLEngine.Core/CLEngine.Core.csproj index c4bb1bf437aa339cdc142aba2a32344a419ee007..95e34c7299c659cdb82b296af9671c81f344b648 100644 --- a/Engine/CLEngine.Core/CLEngine.Core.csproj +++ b/Engine/CLEngine.Core/CLEngine.Core.csproj @@ -293,18 +293,21 @@ + + - + + + - diff --git a/Engine/CLEngine.Core/CProject.cs b/Engine/CLEngine.Core/CProject.cs index 6064761328d53c1c7e0d07f854b165b4d4ec5182..29aeb62f8af321dc7d2eb6d6592f57ab6639856f 100644 --- a/Engine/CLEngine.Core/CProject.cs +++ b/Engine/CLEngine.Core/CProject.cs @@ -161,5 +161,12 @@ namespace CLEngine.Core get { return debug; } set { debug = value; } } + /// + /// 获取工程路径 + /// + /// + public string GetPath(){ + return projectPath; + } } } \ No newline at end of file diff --git a/Engine/CLEngine.Core/GameObject.cs b/Engine/CLEngine.Core/GameObject.cs index 953a82862c264eb583148954d434812c49f257bd..ef5cb842f211496416d5e6807a781e8306875d36 100644 --- a/Engine/CLEngine.Core/GameObject.cs +++ b/Engine/CLEngine.Core/GameObject.cs @@ -1171,8 +1171,9 @@ namespace CLEngine.Core { formatter.Serialize(stream, this); stream.Seek(0, SeekOrigin.Begin); - var obj = formatter.Deserialize(stream); - (obj as GameObject)?.Initialize(); + var obj = (GameObject) formatter.Deserialize(stream); + obj.Initialize(); + SceneManager.ActiveScene.GameObjects.Add(obj); return obj; } } diff --git a/Engine/CLEngine.Core/TextureLoader.cs b/Engine/CLEngine.Core/TextureLoader.cs index 3848b049832d17582a790fe824d52d388be171a0..864ce8c20563ba50ef2bf5b07e6a2c611d85d749 100644 --- a/Engine/CLEngine.Core/TextureLoader.cs +++ b/Engine/CLEngine.Core/TextureLoader.cs @@ -1,6 +1,5 @@ using System.Collections.Generic; using System.IO; -using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; namespace CLEngine.Core @@ -12,9 +11,14 @@ namespace CLEngine.Core /// public static class TextureLoader { - private static Dictionary textures = new Dictionary(); - private static Dictionary colorTextures = new Dictionary(); + private static readonly Dictionary _textures = new Dictionary(); + /// + /// 从游戏目录中的Content文件夹下加载资源 + /// 这是一个相对路径 + /// + /// + /// public static Texture2D FromContent(string filename) { if (SceneManager.GameProject == null) return null; @@ -24,12 +28,18 @@ namespace CLEngine.Core #endif } + /// + /// 从路径加载资源 + /// 这是一个绝对路径 + /// + /// + /// public static Texture2D FromFile(string filename) { if (SceneManager.GraphicsDevice == null) return null; // 图像是否已经加载到内存中了 - if (!textures.ContainsKey(filename) || SceneManager.IsEditor) + if (!_textures.ContainsKey(filename) || SceneManager.IsEditor) { #if WIN FileInfo aTexturePath = new FileInfo(filename); @@ -42,7 +52,7 @@ namespace CLEngine.Core fs.Close(); // 在字典中存储加载的纹理 - textures[filename] = texture; + _textures[filename] = texture; #elif WINRT if(!MetroHelper.AppDataFileExists(filename)) return null; @@ -50,18 +60,20 @@ namespace CLEngine.Core { Texture2D texture = Texture2D.FromStream(SceneManager.GraphicsDevice, stream); - textures[filename] = texture; + _textures[filename] = texture; } #endif } - return textures[filename]; + return _textures[filename]; } + /// + /// 清理所有图片缓存 + /// public static void Clear() { - textures.Clear(); - colorTextures.Clear(); + _textures.Clear(); } } } \ No newline at end of file diff --git a/Engine/CLEngine.Core/components/EventObject.cs b/Engine/CLEngine.Core/components/EventObject.cs deleted file mode 100644 index f1896f1f5bb31a4a53f28117eec97c32fcafe715..0000000000000000000000000000000000000000 --- a/Engine/CLEngine.Core/components/EventObject.cs +++ /dev/null @@ -1,731 +0,0 @@ -using System; -using System.ComponentModel; -using System.Diagnostics.CodeAnalysis; -using System.Runtime.Serialization; -using CLEngine.Core.components; -using CLEngine.Editor.core; -using Microsoft.Xna.Framework; -using Microsoft.Xna.Framework.Graphics; -using Microsoft.Xna.Framework.Input; -using RoyT.AStar; - -namespace CLEngine.Core -{ - /// - /// 事件阵营 - /// -#if WIN - [Serializable] -#endif - [DataContract] - - public enum Camp - { - /// - /// 自身 - /// - Self, - /// - /// 敌人 - /// - Enemy, - /// - /// 友方 - /// - Friendly, - /// - /// 中立 - /// - Neutral, - } - - /// - /// 移动事件参数 - /// - public class EventMove : EventArgs - { - /// - /// 移动方向 - /// - public Vector2 Direction; - /// - /// 是否正在移动 - /// - public bool IsMove; - /// - /// 哪个键按下 - /// 0: 无按键 - /// 1: 左键 - /// 2:右键 - /// - public int KeyCode; - - /// - /// - /// - /// - /// - /// - public EventMove(Vector2 direction, bool isMove = false, int keyCode = 0) - { - Direction = direction; - IsMove = isMove; - KeyCode = keyCode; - } - } - - /// - /// 事件对象 - /// 记录事件的一系列数据 - /// -#if WIN - [Serializable] -#endif - [DataContract] - public class EventObject : ExtendedObjectComponent - { - [DataMember] private Camp _camp; - [DataMember] private object _attachData; - [DataMember] private int _hp = 100; - [DataMember] private int _exp; - [DataMember] private int _nextExp = 100; - [DataMember] private int _level; - [DataMember] private int _mp = 100; - [DataMember] private bool _hasCollider; - [DataMember] private string _objectName; - [DataMember] private bool _hasDelayCamera; - [DataMember] private float _delaySpeed = 0.1f; - [DataMember] private float _leftSpeed = 100; - [DataMember] private float _rightSpeed = 100; - [DataMember] private bool _lockMap = true; - [DataMember] private float _moveSpeed = 100; - [NonSerialized] private bool _isMove = false; - - private const float DirectionRotationOffset = 22.5f; - /// - /// 目标移动坐标 - /// - private Vector2 _targetPos = Vector2.Zero; - /// - /// 下一步移动坐标 - /// - private Vector2 _nextPos = Vector2.Zero; - - /// - /// 事件的阵营 - /// -#if WIN - [Category("事件属性")] - [DisplayName("阵营"), Description("事件的阵营")] -#endif - public Camp Camp - { - get { return _camp;} - set { _camp = value; } - } - - /// - /// 附加属性 - /// -#if WIN - [Browsable(false)] -#endif - public object AttachData - { - get { return _attachData; } - set { _attachData = value; } - } - - /// - /// 事件的血量 - /// -#if WIN - [Category("事件属性")] - [DisplayName("血量"), Description("事件的血量")] -#endif - public int Hp - { - get { return _hp; } - set - { - _hp = value; - if (_hp <= 0) - { - _hp = 0; - OnDead?.Invoke(this, EventArgs.Empty); - } - } - } - - /// - /// 事件的蓝量 - /// -#if WIN - [Category("事件属性")] - [DisplayName("蓝量"), Description("事件的蓝量")] -#endif - public int Mp - { - get { return _mp; } - set { _mp = value; } - } - - /// - /// 事件的经验 - /// -#if WIN - [Category("事件属性")] - [DisplayName("经验"), Description("事件的经验")] -#endif - public int Exp - { - get { return _exp;} - set { _exp = value; } - } - - /// - /// 事件的下一级升级所需经验 - /// -#if WIN - [Category("事件属性")] - [DisplayName("升级所需经验"), Description("事件的下一级升级所需经验")] -#endif - public int NextExp - { - get { return _nextExp; } - set - { - _nextExp = value; - if (_nextExp >= NextExp) - { - _nextExp = _nextExp - NextExp; - _level += 1; - OnLevel?.Invoke(this, EventArgs.Empty); - } - } - } - - /// - /// 事件是否有自己的碰撞器 - /// -#if WIN - [Category("事件属性")] - [DisplayName("是否添加碰撞器"), Description("事件是否有自己的碰撞器")] -#endif - public bool HasCollider - { - get { return _hasCollider; } - set { _hasCollider = value; } - } - - /// - /// 事件等级 - /// -#if WIN - [Category("事件属性")] - [DisplayName("等级"), Description("事件等级")] -#endif - public int Level - { - get { return _level; } - set { _level = value; } - } - -#if WIN - [Category("相机属性")] - [DisplayName("相机延迟跟随"), Description("相机是否延迟跟随")] -#endif - public bool HasDelayCamera - { - get { return _hasDelayCamera; } - set { _hasDelayCamera = value; } - } - -#if WIN - [Category("相机属性")] - [DisplayName("相机跟随速度")] -#endif - public float DelaySpeed - { - get { return _delaySpeed; } - set { _delaySpeed = value; } - } - -#if WIN - [Category("事件属性")] - [DisplayName("左键移动速度")] -#endif - public float LeftSpeed - { - get { return _leftSpeed; } - set { _leftSpeed = value; } - } - -#if WIN - [Category("事件属性")] - [DisplayName("右键移动速度")] -#endif - public float RightSpeed - { - get { return _rightSpeed; } - set { _rightSpeed = value; } - } - -#if WIN - [Category("相机属性")] - [DisplayName("锁定地图边界")] -#endif - public bool LockMap - { - get { return _lockMap; } - set { _lockMap = value; } - } - -#if WIN - [Category("事件属性")] - [DisplayName("移动速度"), Description("事件通用移动速度,用于自动寻路")] -#endif - public float MoveSpeed - { - get { return _moveSpeed; } - set { _moveSpeed = value; } - } - - private GameObject _bindGameObject; - - /// - /// 事件死亡 - /// - public EventHandler OnDead; - - /// - /// 事件升级 - /// - public EventHandler OnLevel; - - /// - /// 事件移动 - /// - public EventHandler OnMove; - - /// - /// 初始化 - /// - public override void Initialize() - { - base.Initialize(); - - //if (!SceneManager.IsEditor) - //{ - // foreach (var activeSceneGameObject in SceneManager.ActiveScene.GameObjects) - // { - // if (activeSceneGameObject is MapObject map) - // { - // map.EventObjects.Add(this); - // break; - // } - // } - //} - } - - private void CheckOpacity() - { - var tileMap = GetTileMap(); - var tilePos = tileMap.GetTilePos(GameObject.Transform.Position); - if (tileMap.OpacityGrid[(int)tilePos.X][(int)tilePos.Y] == 1) - { - if (GameObject is AnimationObject animation) - { - animation.Color = Color.FromNonPremultiplied(255, 255, 255, 96); - } - } - else - { - if (GameObject is AnimationObject animation) - { - animation.Color = Color.FromNonPremultiplied(255, 255, 255, 255); - } - } - } - - /// - /// 事件移动到指定坐标 - /// - /// - /// - /// - public void MoveToTarget(Vector2 target, bool convert = false, bool forceMove = false) - { - if (_isMove && !forceMove) - return; - - var tiledMap = GetTileMap(); - var transform = GameObject.Transform; - var start = tiledMap.GetTilePos(transform.Position); - - var convertPos = target; - if (convert) - convertPos = tiledMap.GetTilePos(target); - - // 可能存在性能问题 - var path = tiledMap.Grid.GetPath(new Position((int) start.X, (int) start.Y), - new Position((int) convertPos.X, (int) convertPos.Y), MovementPatterns.Full, 200); - - if (path.Length < 2) - { - _targetPos = Vector2.Zero; - _nextPos = Vector2.Zero; - return; - } - - _nextPos = new Vector2(path[1].X, path[1].Y); - _targetPos = target; - } - - private MapObject GetTileMap() - { - foreach (var activeSceneGameObject in SceneManager.ActiveScene.GameObjects) - { - if (activeSceneGameObject is MapObject map) - return map; - } - - return null; - } - - /// - /// 更新 - /// - /// - public override void Update(GameTime gameTime) - { - base.Update(gameTime); - - if (SceneManager.IsEditor) - return; - - // 主角控制 - SelfController(); - // 检查移动 - CheckMove(); - // 检查透明 - CheckOpacity(); - } - - #region Overrides of ObjectComponent - - private void CheckMove() - { - if (_targetPos == Vector2.Zero) - return; - - // 移动状态开始 - _isMove = true; - - // 获取绑定物体的属性 - var transform = GameObject.Transform; - - var tileMap = GetTileMap(); - //var targetWorldPos = tileMap.GetWorldPos(_targetPos); - var nextWorldPos = tileMap.GetWorldPos(_nextPos); - var nextRandians = transform.LookAt(nextWorldPos, false); - var nextDegrees = MathHelper.ToDegrees(nextRandians); - var direction = ConvertToDirection(nextDegrees); - - float speed; - if (Mouse.GetState().LeftButton == ButtonState.Pressed) - speed = _leftSpeed; - else if (Mouse.GetState().RightButton == ButtonState.Pressed) - speed = _rightSpeed; - else - speed = _moveSpeed; - - transform.Translate(direction * speed * Time.deltaTime); - - // 无法精确到每位相等 当坐标接近目标时则停下 - if (Math.Abs(transform.Position.X - nextWorldPos.X) <= speed * Time.deltaTime && - Math.Abs(transform.Position.Y - nextWorldPos.Y) <= speed * Time.deltaTime) - { - // 强制移动目标至下一格子坐标点 - transform.Position = nextWorldPos; - // 清空下一格子坐标点 - _nextPos = Vector2.Zero; - // 重新计算下一个目标点 - MoveToTarget(_targetPos, false, true); - // 结束移动状态 - _isMove = false; - } - - } - - private void SelfController() - { - if (Camp == Camp.Self) - { - var camera = SceneManager.ActiveCamera; - var mouseWorldPosition = Camera.ToWorld(Mouse.GetState().Position.ToVector2()); - - var direction = Vector2.Zero; - var isLeft = Mouse.GetState().LeftButton == ButtonState.Pressed; - var isMove = false; - if (Mouse.GetState().LeftButton == ButtonState.Pressed || - Mouse.GetState().RightButton == ButtonState.Pressed) - { - var randians = GameObject.Transform.LookAt(mouseWorldPosition, false); - var degrees = MathHelper.ToDegrees(randians); - - direction = ConvertToDirection(degrees); - - isMove = true; - - // TODO: 寻路会因为鼠标指向障碍而找不到路径 需要指定一个离鼠标最近且离主角最近的一个无障碍坐标点 - var mouseWorldPos = Camera.ToWorld(Mouse.GetState().Position.ToVector2()); - MoveToTarget(mouseWorldPos, true); - //Move(direction, isLeft ? _leftSpeed : _rightSpeed); - } - - var keyCode = 0; - if (isMove) - keyCode = isLeft ? 1 : 2; - - OnMove?.Invoke(this, new EventMove(direction, isMove, keyCode)); - - if (_hasDelayCamera) - { - var x = MathHelper.Lerp(camera.Position.X, GameObject.Transform.Position.X, _delaySpeed); - var y = MathHelper.Lerp(camera.Position.Y, GameObject.Transform.Position.Y, _delaySpeed); - camera.Position = new Vector2(x, y); - } - else - { - camera.Position = Transform.Position; - } - - if (_lockMap) - { - var x = camera.Position.X; - var y = camera.Position.Y; - var halfScreenWidth = SceneManager.Graphics.PreferredBackBufferWidth / 2; - var halfScreenHeight = SceneManager.Graphics.PreferredBackBufferHeight / 2; - var map = GetMap(); - - //左边界 - if (x < halfScreenWidth) - x = halfScreenWidth; - - if (x > map.Texture.Width - halfScreenWidth) - x = map.Texture.Width - halfScreenWidth; - - if (y < halfScreenHeight) - y = halfScreenHeight; - - if (y > map.Texture.Height - halfScreenHeight) - y = map.Texture.Height - halfScreenHeight; - - if (ClampToBound()) - camera.Position = new Vector2(x, y); - } - } - } - - /// - /// 寻找一个离坐标点最近且无障碍的点 - /// - /// - private Vector2 CheckOrGetNearPos(Vector2 worldPos) - { - var map = GetTileMap(); - var tilePos = map.GetTilePos(worldPos); - if (CheckIsCollider(tilePos)) - { - var nearPos = worldPos; - var start = map.GetTilePos(GameObject.Transform.Position); - - return nearPos; - - //// 只寻找它周围最多10格范围 - //// 我们还需要从小往大进行搜寻 - //var searchZRange = 0; - //var searchFRange = 0; - //while (Math.Abs(searchZRange) < 5 && Math.Abs(searchFRange) < 5) - //{ - // // 搜寻分正负 - // searchZRange++; - // searchFRange--; - - // // 先从离主角近的一边开始计算 - // var randians = Transform.LookAt(worldPos, false); - // var degrees = MathHelper.ToDegrees(randians); - // var direction = ConvertToDirection(degrees); - // if (direction.X < 0 && direction.Y < 0) - // { - // nearPos = SearchPos(tilePos, searchFRange, searchFRange); - // if (nearPos != Vector2.Zero) - // return nearPos; - // } - - // if (direction.X < 0 && direction.Y > 0) - // { - // nearPos = SearchPos(tilePos, searchFRange, searchZRange); - // if (nearPos != Vector2.Zero) - // return nearPos; - // } - - // if (direction.X > 0 && direction.Y < 0) - // { - // nearPos = SearchPos(tilePos, searchZRange, searchFRange); - // if (nearPos != Vector2.Zero) - // return nearPos; - // } - - // if (direction.X > 0 && direction.Y > 0) - // { - // nearPos = SearchPos(tilePos, searchZRange, searchFRange); - // if (nearPos != Vector2.Zero) - // return nearPos; - // } - - // // 还需要进行计算周围剩下的点位 - // // 我们需要排除第一个点位 还需要找到后面搜寻的顺序 - // // 从第一个点位向两边进行扩散寻找 - // for (int i = 0; i < searchZRange; i++) - // { - // for (int j = searchFRange; j < 0; j++) - // { - - // } - // } - //} - - return nearPos; - } - - return worldPos; - } - - private Vector2 SearchPos(Vector2 tilePos, int searchX, int searchY) - { - var map = GetTileMap(); - var searchPos = new Vector2(tilePos.X + searchX, tilePos.Y + searchY); - if (!CheckIsCollider(searchPos)) - return map.GetWorldPos(searchPos); - - return Vector2.Zero; - } - - private bool CheckIsCollider(Vector2 tilePos) - { - var map = GetTileMap(); - - return map.CollisionGrid[(int) tilePos.X][(int) tilePos.Y] == 1; - } - - /// - /// 绘制 - /// - /// - /// - public override void Draw(GameTime gameTime, SpriteBatch spriteBatch) - { - base.Draw(gameTime, spriteBatch); - - if (_hasCollider) - { - var map = GetMap(); - var bound = new Point(map.TileWidth, map.TileHeight); - spriteBatch.Begin(SpriteSortMode.Deferred, null, null, null, null, null, - SceneManager.ActiveCamera.TransformMatrix); - //Primitives.DrawBox(spriteBatch, - // new Rectangle((Transform.Position - bound.ToVector2() / 2).ToPoint(), bound), Color.Red, 1); - //Primitives.DrawBoxFilled(spriteBatch, - // new Rectangle((Transform.Position - bound.ToVector2() / 2).ToPoint(), bound), - // Color.FromNonPremultiplied(255, 0, 0, 128)); - Primitives.DrawBox(spriteBatch, - new Rectangle((Transform.Position).ToPoint(), bound), Color.Red, 1); - Primitives.DrawBoxFilled(spriteBatch, - new Rectangle((Transform.Position).ToPoint(), bound), - Color.FromNonPremultiplied(255, 0, 0, 128)); - spriteBatch.End(); - } - } - - #endregion - - private bool ClampToBound() - { - var camera = SceneManager.ActiveCamera; - var x = camera.Position.X; - var y = camera.Position.Y; - var halfScreenWidth = SceneManager.Graphics.PreferredBackBufferWidth / 2; - var halfScreenHeight = SceneManager.Graphics.PreferredBackBufferHeight / 2; - var map = GetMap(); - - //左边界 - if (x < halfScreenWidth) - return true; - - if (x > map.Texture.Width - halfScreenWidth) - return true; - - if (y < halfScreenHeight) - return true; - - if (y > map.Texture.Height - halfScreenHeight) - return true; - - return false; - } - - private MapObject GetMap() - { - foreach (var activeSceneGameObject in SceneManager.ActiveScene.GameObjects) - { - if (activeSceneGameObject is MapObject map) - return map; - } - - return null; - } - - private Vector2 ConvertToDirection(float degrees) - { - var direction = Vector2.Zero; - - if (degrees > -90 + DirectionRotationOffset && degrees <= -45 + DirectionRotationOffset) - { - direction = new Vector2(1, -1); - } - else if (degrees > -135 + DirectionRotationOffset && degrees <= -90 + DirectionRotationOffset) - { - direction = new Vector2(0, -1); - } - else if (degrees > -180 + DirectionRotationOffset && degrees <= -135 + DirectionRotationOffset) - { - direction = new Vector2(-1, -1); - } - else if (degrees > -45 + DirectionRotationOffset && degrees <= 0 + DirectionRotationOffset) - { - direction = new Vector2(1, 0); - } - else if (degrees > 0 + DirectionRotationOffset && degrees <= 45 + DirectionRotationOffset) - { - direction = new Vector2(1, 1); - } - else if (degrees > 45 + DirectionRotationOffset && degrees <= 90 + DirectionRotationOffset) - { - direction = new Vector2(0, 1); - } - else if (degrees > 90 + DirectionRotationOffset && degrees <= 135 + DirectionRotationOffset) - { - direction = new Vector2(-1, 1); - } - else if ((degrees > 135 + DirectionRotationOffset && degrees <= 180) || - (degrees > -180 && degrees <= -135 + DirectionRotationOffset)) - { - direction = new Vector2(-1, 0); - } - - return direction; - } - } -} \ No newline at end of file diff --git a/Engine/CLEngine.Core/framework/EventManager.cs b/Engine/CLEngine.Core/framework/EventManager.cs index c46d8a45b6e833fbcd1fa0eadc33f34c2c6ae257..df5dec7ec5b38888ee1e4c502cba90f524ad1aa1 100644 --- a/Engine/CLEngine.Core/framework/EventManager.cs +++ b/Engine/CLEngine.Core/framework/EventManager.cs @@ -3,64 +3,51 @@ using Microsoft.Xna.Framework; namespace CLEngine.Core.framework { - /// - /// 事件管理类 - /// - public static class EventManager - { - private static List eventObjects = new List(); + /// + /// 事件管理类 + /// + public static class EventManager + { + private static List eventObjects = new List(); - /// - /// 添加事件 - /// - /// 事件 - public static EventObject AddEvent() - { - var eventObject = new EventObject(); - eventObjects.Add(eventObject); + /// + /// 添加事件 + /// + /// 事件 + public static EventObject AddEvent() + { + var eventObject = new EventObject(); + eventObjects.Add(eventObject); - return eventObject; - } + return eventObject; + } - /// - /// 移除事件 - /// - /// 事件 - public static void RemoveEvent(EventObject eventObject) - { - eventObjects.Remove(eventObject); - } + /// + /// 移除事件 + /// + /// 事件 + public static void RemoveEvent(EventObject eventObject) + { + eventObjects.Remove(eventObject); + } - /// - /// 绑定对象 - /// - /// 事件 - /// 对象 - public static void BindObject(this EventObject eventObject, GameObject gameObject) - { - eventObject.GameObject = gameObject; - } + /// + /// 绑定对象 + /// + /// 事件 + /// 对象 + public static void BindObject(this EventObject eventObject, GameObject gameObject) + { + eventObject.GameObject = gameObject; + } - /// - /// 释放对象 - /// - /// 事件 - public static void ReleaseObject(this EventObject eventObject) - { - eventObject.GameObject = null; - } - - /// - /// 移动对象 - /// - /// 事件 - /// 移动目标 - /// 是否转换为格子坐标 - /// 是否强制移动 - public static void Move(this EventObject eventObject, Vector2 target, bool convert = false, - bool forceMove = false) - { - eventObject.MoveToTarget(target, convert, forceMove); - } - } + /// + /// 释放对象 + /// + /// 事件 + public static void ReleaseObject(this EventObject eventObject) + { + eventObject.GameObject = null; + } + } } \ No newline at end of file diff --git a/Engine/CLEngine.Core/framework/HeroObject.cs b/Engine/CLEngine.Core/framework/EventObject.cs similarity index 51% rename from Engine/CLEngine.Core/framework/HeroObject.cs rename to Engine/CLEngine.Core/framework/EventObject.cs index 35e219c8b8929d69e6109f090257dac78bb89f01..988ac0aba123b5b055190723d2e544adeb911108 100644 --- a/Engine/CLEngine.Core/framework/HeroObject.cs +++ b/Engine/CLEngine.Core/framework/EventObject.cs @@ -1,19 +1,21 @@ using System; using System.Collections.Generic; -using System.Linq; using System.Runtime.Serialization; -using System.Text; -using System.Threading.Tasks; namespace CLEngine.Core.framework { + /// + /// + /// #if WIN [Serializable] #endif [DataContract] - public class HeroObject + public class EventObject : GameObject { [DataMember] private string _name; + [DataMember] private List _bindItem; + [DataMember] private GameObject _gameObj; [DataMember] private int _hp; [DataMember] private int _maxHp; [DataMember] private int _mp; @@ -24,8 +26,62 @@ namespace CLEngine.Core.framework [DataMember] private int _maxExp; [DataMember] private string _gender; [DataMember] private string _occupation; - [DataMember] private List _skill; - [DataMember] private List _event = new List { }; + [DataMember] private Dictionary _skill; + [DataMember] private Dictionary _state; + [DataMember] private SkillObject _onSkill; + + /// + /// 添加技能 + /// + /// + public void AddSkill(string name) + { + var skill = SkillManager.GetWorldSkill(name); + if (skill == null) + { + throw new Exception("技能'" + name + "'不存在!"); + } + _skill.Add(name, skill); + } + /// + /// 删除技能 + /// + /// + public void RemoveSkill(string name) + { + _skill.Remove(name); + } + /// + /// 通过列表添加技能 + /// + /// + public void AddSkillByList(List list) + { + foreach (var skill in list) + { + AddSkill(skill); + } + } + /// + /// 通过列表删除技能 + /// + /// + public void RemoveSkillByList(List list) + { + foreach (var skill in list) + { + RemoveSkill(skill); + } + } + + /// + /// 状态表 + /// + public Dictionary State { get { return _state; } private set { _state = value; } } + /// + /// 技能表 + /// + public Dictionary Skill { get { return _skill; } private set { _skill = value; } } /// /// 升级所需最大经验值 /// @@ -51,10 +107,6 @@ namespace CLEngine.Core.framework /// public int Lv { get { return _lv; } set { _lv = value; } } /// - /// 技能数组 - /// - public List Skill { get { return _skill; } set { _skill = value; } } - /// /// 最大法力值 /// public int MaxMp { get { return _maxMp; } set { _maxMp = value; } } @@ -71,8 +123,16 @@ namespace CLEngine.Core.framework /// public int Hp { get { return _hp; } set { _hp = value; } } /// - /// 人物名 + /// 游戏对象 + /// + public GameObject GameObject { get { return _gameObj; } set { _gameObj = value; } } + /// + /// 事件名 /// public string Name { get { return _name; } set { _name = value; } } + /// + /// 绑定的物品 + /// + public List BindItem { get { return _bindItem; } set { _bindItem = value; } } } } diff --git a/Engine/CLEngine.Core/framework/FrameworkManager.cs b/Engine/CLEngine.Core/framework/FrameworkManager.cs new file mode 100644 index 0000000000000000000000000000000000000000..8f141203f65ab8abe476aa60e9d560f8959836ec --- /dev/null +++ b/Engine/CLEngine.Core/framework/FrameworkManager.cs @@ -0,0 +1,146 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.IO; +using System.Linq; +using System.Windows.Forms; + +namespace CLEngine.Core.framework +{ + /// + /// 框架管理器 + /// + public static class FrameworkManager + { + private static readonly Dictionary _dataFrameworks; + + static FrameworkManager() + { + _dataFrameworks = new Dictionary(); + RegisterDataFramework("item", new ItemManager()); + RegisterDataFramework("skill", new SkillManager()); + } + + /// + /// 注册事件框架 + /// + /// 事件名 + /// 事件数据 + public static void RegisterDataFramework(string name, IDataFramework framework) + { + _dataFrameworks.Add(name, framework); + } + + /// + /// 取消注册事件框架 + /// + /// 框架名 + /// 是否成功 + public static bool UnRegisterDataFramework(string name) + { + return _dataFrameworks.Remove(name); + } + + /// + /// 获取数据框架 + /// + /// 数据类型 + /// 数据名称 + /// 数据 + public static T GetDataFramework(string name) where T : IDataFramework + { + return (T)_dataFrameworks[name]; + } + + /// + /// 加载所有数据 + /// + [SuppressMessage("ReSharper", "ForCanBeConvertedToForeach")] + public static void LoadAllData() + { + var dataFrameworkList = _dataFrameworks.ToList(); + // 不要使用foreach 列表发生更改时会报错 + for (int i = 0; i < dataFrameworkList.Count; i++) + dataFrameworkList[i].Value.LoadData(); + } + + /// + /// 保存所有数据 + /// + public static void SaveAllData() + { + foreach (var dataFramework in _dataFrameworks) + dataFramework.Value.SaveData(); + } + + /// + /// 保存指定数据 + /// + /// + public static void SaveData(string name) + { + try + { + _dataFrameworks[name].SaveData(); + } + catch (Exception e) + { + MessageBox.Show(e.StackTrace); + } + } + + /// + /// 改变指定数据 + /// + /// 名称 + /// 数据 + public static void ChangeData(string name, T data) where T : IDataFramework + { + _dataFrameworks[name] = data; + } + + /// + /// 加载数据 + /// + /// 文件名 + public static object LoadFrameworkData(string name) + { + if (string.IsNullOrEmpty(SceneManager.GameProject.ProjectPath)) + throw new Exception("未加载工程前无法加载游戏数据"); + + var dataPath = Path.Combine(SceneManager.GameProject.ProjectPath, "Content", "Data"); + try + { + var path = Path.Combine(dataPath, name + ".data"); + + return File.Exists(path) ? CHelper.DeserializeObject(path) : null; + } + catch (Exception e) + { + throw new Exception(e.Message, e); + } + } + + /// + /// 保存数据 + /// + /// 文件名 + /// 数据 + public static void SaveFrameworkData(string name, object type) + { + if (string.IsNullOrEmpty(SceneManager.GameProject.ProjectPath)) + throw new Exception("未加载工程前无法保存游戏数据"); + + var dataPath = Path.Combine(SceneManager.GameProject.ProjectPath, "Content", "Data"); + try + { + Directory.CreateDirectory(dataPath); + CHelper.SerializeObject(Path.Combine(dataPath, name + ".data"), type); + } + catch (Exception e) + { + throw new Exception(e.Message, e); + } + } + } +} \ No newline at end of file diff --git a/Engine/CLEngine.Core/framework/FrameworkSettings.cs b/Engine/CLEngine.Core/framework/FrameworkSettings.cs index 20fbb5ba06faf48d421f32f8636fe2f70e3521de..3a6db8c47faa4247238a43c14d950598e9411636 100644 --- a/Engine/CLEngine.Core/framework/FrameworkSettings.cs +++ b/Engine/CLEngine.Core/framework/FrameworkSettings.cs @@ -34,8 +34,8 @@ namespace CLEngine.Core.framework /// 物品列表 /// public static Dictionary> ItemTypes = new Dictionary>{ - {"物品",new List{"消耗品","任务用品","材料","礼包" } }, - {"装备",new List{"武器","鞋子","帽子","衣服","裤子","首饰","戒指" } }, + {"物品",new List{"消耗品","任务用品","材料","礼包" } }, + {"装备",new List{"武器","鞋子","帽子","衣服","裤子","首饰","戒指" } }, }; /// @@ -43,8 +43,17 @@ namespace CLEngine.Core.framework /// public static List GenderTypes = new List() { + "无", "男", "女" }; + + /// + /// 职业列表 + /// + public static List OccupationTypes = new List() + { + + }; } } \ No newline at end of file diff --git a/Engine/CLEngine.Core/framework/IDataFramework.cs b/Engine/CLEngine.Core/framework/IDataFramework.cs new file mode 100644 index 0000000000000000000000000000000000000000..e15dececc26ca59d660c5745f6d2c6e9f8f327e2 --- /dev/null +++ b/Engine/CLEngine.Core/framework/IDataFramework.cs @@ -0,0 +1,19 @@ +namespace CLEngine.Core.framework +{ + /// + /// 数据框架接口 + /// 用于读取/加载数据 + /// + public interface IDataFramework + { + /// + /// 加载数据 + /// + void LoadData(); + + /// + /// 保存数据 + /// + void SaveData(); + } +} \ No newline at end of file diff --git a/Engine/CLEngine.Core/framework/ItemManager.cs b/Engine/CLEngine.Core/framework/ItemManager.cs index 795b62f068c0a02539d3fc75ae0a661e41601600..169e638045211ad2b9a857076726241e4014cc7b 100644 --- a/Engine/CLEngine.Core/framework/ItemManager.cs +++ b/Engine/CLEngine.Core/framework/ItemManager.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.IO; +using System.Runtime.Serialization; using Path = System.IO.Path; namespace CLEngine.Core.framework @@ -8,26 +9,35 @@ namespace CLEngine.Core.framework /// /// 物品管理器 /// - public static class ItemManager +#if WIN + [Serializable] +#endif + [DataContract] + public class ItemManager : IDataFramework { /// /// 全局物品 /// - private static Dictionary _worldItem; + [DataMember] private static Dictionary _worldItem; /// /// 玩家背包 /// - private static List _playerItem; + [DataMember] private static List _playerItem; /// /// 全局物品Id /// - public static int WorldId { get; private set; } + [DataMember] public static int WorldId { get; private set; } + + /// + /// 全局物品 + /// + public static Dictionary WorldItem => _worldItem; static ItemManager() { _worldItem = new Dictionary(); - _playerItem = new List(); - WorldId = 1; + _playerItem = new List(); + WorldId = 1; } /// @@ -38,7 +48,7 @@ namespace CLEngine.Core.framework var item = new ItemObject(name) { Id = WorldId }; _worldItem.Add(name, item); - WorldId++; + WorldId++; return item; } @@ -78,46 +88,25 @@ namespace CLEngine.Core.framework /// /// 保存全局物品 /// - public static void SaveWorldItem() + public void SaveData() { - if (string.IsNullOrEmpty(SceneManager.GameProject.ProjectPath)) - throw new Exception("未加载工程前无法保存物品信息"); - - var itemPath = Path.Combine(SceneManager.GameProject.ProjectPath, "Content", "Items"); - Directory.CreateDirectory(itemPath); - try - { - CHelper.SerializeObject(Path.Combine(itemPath, "worldItem.db"), _worldItem); - CHelper.SerializeObject(Path.Combine(itemPath, "worldId.db"), WorldId); - Logger.Info("物品保存成功"); - } - catch (Exception e) - { - throw new Exception(e.Message, e); - } + FrameworkManager.SaveFrameworkData("worldItem", _worldItem); + FrameworkManager.SaveFrameworkData("playerItem", _playerItem); + FrameworkManager.SaveFrameworkData("worldId", WorldId); } /// /// 加载全局物品 /// - private static void LoadWorldItem() + public void LoadData() { - if (string.IsNullOrEmpty(SceneManager.GameProject.ProjectPath)) - throw new Exception("未加载工程前无法加载物品信息"); - - var itemPath = Path.Combine(SceneManager.GameProject.ProjectPath, "Content", "Items"); - try - { - _worldItem = - (Dictionary) CHelper.DeserializeObject(Path.Combine(itemPath, "worldItem.db")); - WorldId = (int) CHelper.DeserializeObject(Path.Combine(itemPath, "worldId.db")); - Logger.Info("物品加载成功"); - } - catch (Exception e) - { - throw new Exception(e.Message, e); - } + _worldItem = (Dictionary)FrameworkManager.LoadFrameworkData("worldItem") ?? new Dictionary(); + _playerItem = (List)FrameworkManager.LoadFrameworkData("playerItem") ?? new List(); + var worldId = FrameworkManager.LoadFrameworkData("worldId"); + if (worldId != null) + WorldId = (int)worldId; } + /// /// 世界物品中通过名称找物品 /// @@ -247,7 +236,7 @@ namespace CLEngine.Core.framework } } } - if (!is_finish||(!have&&item.OnlyGetOne)) + if (!is_finish || (!have && item.OnlyGetOne)) { onget.Number = number; _playerItem.Add(onget); diff --git a/Engine/CLEngine.Core/framework/ItemObject.cs b/Engine/CLEngine.Core/framework/ItemObject.cs index 41c1a7c8e4388fd1a24fa71a4595984bb96d4df1..52d15b1f5b74ccd218a233dd361e187f4c712387 100644 --- a/Engine/CLEngine.Core/framework/ItemObject.cs +++ b/Engine/CLEngine.Core/framework/ItemObject.cs @@ -1,6 +1,7 @@ using System; using System.Runtime.Serialization; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using Microsoft.Xna.Framework.Graphics; using System.IO; using Microsoft.Xna.Framework; @@ -13,7 +14,10 @@ namespace CLEngine.Core.framework /// public class ItemEventArgs : EventArgs { - int userId; + /// + /// + /// + public int userId; /// /// @@ -32,6 +36,7 @@ namespace CLEngine.Core.framework [Serializable] #endif [DataContract] + [SuppressMessage("ReSharper", "ArrangeAccessorOwnerBody")] public class ItemObject { /// @@ -76,7 +81,6 @@ namespace CLEngine.Core.framework [DataMember] private int _addAtkSpeed; [DataMember] private int _addAtkRange; [DataMember] private Dictionary _customProp; - [DataMember] private Image _guiIcon; [DataMember] private bool _isGuiShow; [DataMember] private int _lv; [DataMember] private string _child; @@ -101,21 +105,54 @@ namespace CLEngine.Core.framework [DataMember] private float _magicUseSpeed; [DataMember] private string _classification; [DataMember] private bool _onlyStoreOne; + [DataMember] private string _dropIconPath; + [NonSerialized] private Image _guiIcon; [NonSerialized] private Texture2D _texture; + [NonSerialized] private Texture2D _dropIcon; private int _positionInBag; /// + /// 掉落图标路径 + /// + public string DropIconPath + { + get { return _dropIconPath; } + set + { + _dropIconPath = value; + if (string.IsNullOrEmpty(_dropIconPath)) + { + _dropIcon = null; + return; + } + var path = Path.Combine(SceneManager.GameProject.ProjectPath, _dropIconPath); + if (File.Exists(path)) + { + _dropIcon = TextureLoader.FromContent(_dropIconPath); + } + else + { + _dropIcon = null; + Console.WriteLine("文件" + _dropIconPath + "不存在"); + } + } + } + /// + /// 掉落图标 + /// + public Texture2D DropIcon { get { return _dropIcon; } set { _dropIcon = value; } } + /// /// 仓库唯一 /// - public bool OnlyStoreOne{ get{ return _onlyStoreOne; }set{ _onlyStoreOne = value; } } + public bool OnlyStoreOne { get { return _onlyStoreOne; } set { _onlyStoreOne = value; } } /// /// 分类 /// - public string Classification{ get{ return _classification; }set{ _classification = value; } } + public string Classification { get { return _classification; } set { _classification = value; } } /// /// 施法速率 /// - public float MagicUseSpeed{ get{ return _magicUseSpeed; }set{ _magicUseSpeed = value; } } + public float MagicUseSpeed { get { return _magicUseSpeed; } set { _magicUseSpeed = value; } } /// /// 闪避率 /// @@ -123,19 +160,19 @@ namespace CLEngine.Core.framework /// /// 命中率 /// - public float HitAccuracy{ get{ return _hitAccuracy; }set{ _hitAccuracy = value; } } + public float HitAccuracy { get { return _hitAccuracy; } set { _hitAccuracy = value; } } /// /// 背包唯一 /// - public bool OnlyGetOne{ get{ return _onlyGetOne; }set{ _onlyGetOne = value; } } + public bool OnlyGetOne { get { return _onlyGetOne; } set { _onlyGetOne = value; } } /// /// 冷却时间 /// - public int CD{ get { return _cd; }set { _cd = value; } } + public int CD { get { return _cd; } set { _cd = value; } } /// /// 回复法力值 /// - public int Mp{ get{ return _mp; }set{ _mp = value; } } + public int Mp { get { return _mp; } set { _mp = value; } } /// /// 附加属性:魔法防御 /// @@ -260,14 +297,17 @@ namespace CLEngine.Core.framework if (string.IsNullOrEmpty(_iconPath)) { IconTex = null; + return; } - else if (File.Exists(_iconPath)) + + var path = Path.Combine(SceneManager.GameProject.ProjectPath, _iconPath); + if (File.Exists(path)) { IconTex = TextureLoader.FromContent(_iconPath); } else { - throw new Exception("文件" + _iconPath + "不存在"); + Console.WriteLine("文件" + path + "不存在"); } } } @@ -356,7 +396,7 @@ namespace CLEngine.Core.framework { if (_customProp.ContainsKey(name)) { - throw new Exception("自定义值" + name + "不允许重复"); + Console.WriteLine("自定义值" + name + "不允许重复"); } _customProp[name] = customprop; } @@ -417,6 +457,9 @@ namespace CLEngine.Core.framework { return _name; } + /// + /// + /// public ItemObject() { SalePercent = 1f; diff --git a/Engine/CLEngine.Core/framework/SkillManager.cs b/Engine/CLEngine.Core/framework/SkillManager.cs new file mode 100644 index 0000000000000000000000000000000000000000..b9d00924b29fc3928d09441ce1c273e3a0574f8a --- /dev/null +++ b/Engine/CLEngine.Core/framework/SkillManager.cs @@ -0,0 +1,87 @@ +using System; +using System.Collections.Generic; +using System.Runtime.Serialization; + +namespace CLEngine.Core.framework +{ + /// + /// 技能管理器 + /// +#if WIN + [Serializable] +#endif + [DataContract] + public class SkillManager : IDataFramework + { + /// + /// 全局技能 + /// + [DataMember] private static Dictionary _worldSkill; + + static SkillManager() + { + _worldSkill = new Dictionary(); + } + + /// + /// 添加技能 + /// + /// 技能名 + /// 技能 + public static SkillObject AddSkill(string name) + { + var skill = new SkillObject(); + _worldSkill.Add(name, skill); + + return skill; + } + + /// + /// 删除技能 + /// + /// 技能名 + public static void RemoveSkill(string name) + { + _worldSkill.Remove(name); + } + + /// + /// 获取技能列表 + /// + /// 技能列表 + public static List GetSkillList() + { + var skillList = new List(); + foreach (var skill in _worldSkill) + skillList.Add(skill.Value); + + return skillList; + } + + /// + /// 通过名称获取世界技能 + /// + /// + /// + public static SkillObject GetWorldSkill(string name) + { + return _worldSkill[name]; + } + + /// + /// 加载数据 + /// + public void LoadData() + { + _worldSkill = (Dictionary)FrameworkManager.LoadFrameworkData("skills") ?? new Dictionary(); + } + + /// + /// 保存数据 + /// + public void SaveData() + { + FrameworkManager.SaveFrameworkData("skills", _worldSkill); + } + } +} \ No newline at end of file diff --git a/Engine/CLEngine.Core/framework/SkillObject.cs b/Engine/CLEngine.Core/framework/SkillObject.cs index 98b5dc535adc3c0ad705d05e80d6692979648594..b2b1834db2cdd51d46107cbee11e847d5a742a7a 100644 --- a/Engine/CLEngine.Core/framework/SkillObject.cs +++ b/Engine/CLEngine.Core/framework/SkillObject.cs @@ -1,5 +1,8 @@ -using System; +using FairyGUI; +using Microsoft.Xna.Framework.Graphics; +using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Runtime.Serialization; using System.Text; @@ -11,16 +14,57 @@ namespace CLEngine.Core.framework [Serializable] #endif [DataContract] + public class SkillEventArgs : EventArgs + { + public int userId; + public SkillEventArgs(int id) + { + userId = id; + } + } public class SkillObject { - [DataMember]private string _name; - [DataMember]private string _iconPath; - [DataMember]private float _coolingTime; - [DataMember]private int _useHp; - [DataMember]private int _useMp; - [DataMember]private string _description; - [DataMember]private int _castingDistance; - [DataMember]private float _castingSpeed; + /// + /// 使用技能事件 + /// + public EventHandler Use; + /// + /// 技能冷却改变事件 + /// + public EventHandler Cooling; + /// + /// 冷却完成事件 + /// + public EventHandler FinishCooling; + + [DataMember] private string _name; + [DataMember] private string _iconPath; + [DataMember] private float _coolingTime; + [DataMember] private float _currentTime = 0; + [DataMember] private int _useHp; + [DataMember] private int _useMp; + [DataMember] private string _description; + [DataMember] private int _castingDistance; + [DataMember] private float _castingSpeed; + [DataMember] private int _userId; + [NonSerialized] private Image _icon; + [NonSerialized] private Texture2D _iconTex; + /// + /// 当前冷却时间 + /// + public float CurrentTime { get { return _currentTime; } set { _currentTime = value; } } + /// + /// 技能使用者id + /// + public int UserId { get { return _userId; } set { _userId = value; } } + /// + /// 游戏图标 + /// + public Texture2D IconTex { get { return _iconTex; } set { _iconTex = value; } } + /// + /// fui图标 + /// + public Image Icon { get { return _icon; } set { _icon = value; } } /// /// 技能名称 /// @@ -35,7 +79,24 @@ namespace CLEngine.Core.framework public string IconPath { get { return _iconPath; } - set { _iconPath = value; } + set + { + _iconPath = value; + if (string.IsNullOrEmpty(_iconPath)) + { + _iconTex = null; + return; + } + var path = Path.Combine(SceneManager.GameProject.ProjectPath, _iconPath); + if (File.Exists(path)) + { + IconTex = TextureLoader.FromContent(_iconPath); + } + else + { + throw new Exception("文件" + path + "不存在"); + } + } } /// /// 技能冷却时间 @@ -111,5 +172,35 @@ namespace CLEngine.Core.framework Target, Mouse } + /// + /// 触发使用技能事件 + /// + public void TrigUse() + { + if (Use != null) + { + Use.Invoke(this, new SkillEventArgs(_userId)); + } + } + /// + /// 触发技能冷却刷新事件 + /// + public void TrigCooling() + { + if (Cooling != null) + { + Cooling.Invoke(this, new SkillEventArgs(_userId)); + } + } + /// + /// 触发技能冷却完成事件 + /// + public void TrigFinishCooling() + { + if (FinishCooling != null) + { + FinishCooling.Invoke(this, new SkillEventArgs(_userId)); + } + } } } diff --git a/Engine/CLEngine.Core/framework/StateManager.cs b/Engine/CLEngine.Core/framework/StateManager.cs new file mode 100644 index 0000000000000000000000000000000000000000..34572bf3965c2438431ba4c9aa83c66b2e8d2318 --- /dev/null +++ b/Engine/CLEngine.Core/framework/StateManager.cs @@ -0,0 +1,214 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Runtime.Serialization; +using Path = System.IO.Path; + +namespace CLEngine.Core.framework +{ + /// + /// 状态管理器 + /// +#if WIN + [Serializable] +#endif + [DataContract] + public class StateManager : IDataFramework + { + /// + /// 全局状态 + /// + [DataMember] private static Dictionary _worldState; + /// + /// 玩家状态 + /// + [DataMember] private static List _playerState; + /// + /// 全局状态Id + /// + [DataMember] public static int WorldId { get; private set; } + + /// + /// 全局状态 + /// + public static Dictionary WorldState => _worldState; + + static StateManager() + { + _worldState = new Dictionary(); + _playerState = new List(); + WorldId = 1; + } + + /// + /// 创建状态 + /// + public static StateObject CreateState(string name) + { + var State = new StateObject(name) { Id = WorldId }; + _worldState.Add(name, State); + + WorldId++; + + return State; + } + + /// + /// 删除状态 + /// + /// + /// + public static StateObject RemoveState(string name) + { + var State = new StateObject(name); + _worldState.Remove(name); + + return State; + } + + /// + /// 删除状态 + /// + /// + /// + public static bool RemoveState(StateObject State) + { + foreach (var StateObject in _worldState) + { + if (StateObject.Value == State) + { + _worldState.Remove(StateObject.Key); + return true; + } + } + + return false; + } + + /// + /// 保存全局状态 + /// + public void SaveData() + { + FrameworkManager.SaveFrameworkData("worldState", _worldState); + FrameworkManager.SaveFrameworkData("playerState", _playerState); + FrameworkManager.SaveFrameworkData("worldId", WorldId); + } + + /// + /// 加载全局状态 + /// + public void LoadData() + { + _worldState = (Dictionary)FrameworkManager.LoadFrameworkData("worldState") ?? new Dictionary(); + _playerState = (List)FrameworkManager.LoadFrameworkData("playerState") ?? new List(); + var worldId = FrameworkManager.LoadFrameworkData("worldId"); + if (worldId != null) + WorldId = (int)worldId; + } + + /// + /// 世界状态中通过名称找状态 + /// + /// + /// + public static StateObject WorldFindStateByName(string name) + { + return _worldState[name]; + } + /// + /// 世界状态中通过编号找状态 + /// + /// + /// + public static StateObject WorldFindStateById(int id) + { + foreach (var State in _worldState) + { + if (State.Value.Id == id) + { + return State.Value; + } + } + return null; + } + /// + /// 状态表中通过名字找状态,返回第一个找到的 + /// + /// + /// + public static StateObject PlayerFindStateByName(string name) + { + var max = _playerState.Count; + StateObject State; + for (int i = 0; i < max; i++) + { + State = _playerState[i]; + if (State.Name == name) + { + return State; + } + } + return null; + } + /// + /// 状态表中通过名字找状态,返回所有符合的状态 + /// + /// + /// + public static List PlayerFindAllStateByName(string name) + { + var max = _playerState.Count; + var Statelist = new List(); + StateObject State; + for (int i = 0; i < max; i++) + { + State = _playerState[i]; + if (State.Name == name) + { + Statelist.Add(State); + } + } + return Statelist; + } + /// + /// 状态表中通过编号找状态,返回第一个找到的 + /// + /// + /// + public static StateObject PlayerFindStateById(int id) + { + var max = _playerState.Count; + StateObject State; + for (int i = 0; i < max; i++) + { + State = _playerState[i]; + if (State.Id == id) + { + return State; + } + } + return null; + } + /// + /// 状态表中通过编号找状态,返回所有找到的 + /// + /// + /// + public static List PlayerFindAllStateById(int id) + { + var max = _playerState.Count; + var Statelist = new List(); + StateObject State; + for (int i = 0; i < max; i++) + { + State = _playerState[i]; + if (State.Id == id) + { + Statelist.Add(State); + } + } + return Statelist; + } + } +} \ No newline at end of file diff --git a/Engine/CLEngine.Core/framework/StateObject.cs b/Engine/CLEngine.Core/framework/StateObject.cs index c1d5b6bb20c0fb5fdd07ef30d4022e6f14987b93..73586c2052cc34f9af07a43e32187439ae642fe0 100644 --- a/Engine/CLEngine.Core/framework/StateObject.cs +++ b/Engine/CLEngine.Core/framework/StateObject.cs @@ -32,30 +32,38 @@ namespace CLEngine.Core.framework [DataMember] private int _affectHp; [DataMember] private int _affectMp; [DataMember] private int _affectSpeed; - + [DataMember] private int _id; + /// + /// ID + /// + public int Id { get { return _id; } internal set { _id = value; } } /// /// 持续时间 /// - public int ContinueTime{ get{ return _continueTime; }set{ _continueTime = value; } } + public int ContinueTime { get { return _continueTime; } set { _continueTime = value; } } /// /// 是否只生效一次 /// - public bool IsAffectOnce{ get{ return _isAffectOnce; }set{ _isAffectOnce = value; } } + public bool IsAffectOnce { get { return _isAffectOnce; } set { _isAffectOnce = value; } } /// /// 名称 /// - public string Name{ get{ return _name; }set{ _name = value; } } + public string Name { get { return _name; } set { _name = value; } } /// /// 对生命值影响 /// - public int AffectHp{ get{ return _affectHp; }set{ _affectHp = value; } } + public int AffectHp { get { return _affectHp; } set { _affectHp = value; } } /// /// 对法力值影响 /// - public int AffectMp{ get{ return _affectMp; }set{ _affectMp = value; } } + public int AffectMp { get { return _affectMp; } set { _affectMp = value; } } /// /// 对速度影响 /// - public int AffectSpeed{ get{ return _affectSpeed; }set{ _affectSpeed = value; } } + public int AffectSpeed { get { return _affectSpeed; } set { _affectSpeed = value; } } + public StateObject(string name) + { + Name = name; + } } } diff --git a/Engine/CLEngine.Core/gameObjects/MapObject.cs b/Engine/CLEngine.Core/gameObjects/MapObject.cs index 57a5ac68d02fb2df54ec9e8999145f4779b71c4e..9becb46ff22b2d81e21daadd559f8f442f24737c 100644 --- a/Engine/CLEngine.Core/gameObjects/MapObject.cs +++ b/Engine/CLEngine.Core/gameObjects/MapObject.cs @@ -1,14 +1,11 @@ using System; using System.Collections.Generic; -using System.Collections.ObjectModel; using System.ComponentModel; using System.IO; using System.Runtime.Serialization; -using System.Windows.Forms; -using CLEngine.Core.components; using CLEngine.Core.design; +using CLEngine.Core.framework; using CLEngine.Editor.core; -using FarseerPhysics.Dynamics; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using RoyT.AStar; diff --git a/Engine/CLEngine.Core/gui/Core/Text/TextField.cs b/Engine/CLEngine.Core/gui/Core/Text/TextField.cs index 840704188dae32b50e45dc2281c392ed6f14e6eb..80f47cd32251b70728836e0594fe3ae46edd3605 100644 --- a/Engine/CLEngine.Core/gui/Core/Text/TextField.cs +++ b/Engine/CLEngine.Core/gui/Core/Text/TextField.cs @@ -43,6 +43,7 @@ namespace FairyGUI bool _textChanged; int _yOffset; float _fontSizeScale; + string _parsedText; float _globalScale; Bitmap _canvas; NTexture _texture; @@ -60,6 +61,12 @@ namespace FairyGUI -1, 1, 1, 1 }; + static float[] BOLD_OFFSET = new float[] + { + -0.5f, 0f, 0.5f, 0f, + 0f, -0.5f, 0f, 0.5f + }; + public TextField() { _touchDisabled = true; @@ -71,6 +78,7 @@ namespace FairyGUI _wordWrap = false; _text = string.Empty; + _parsedText = string.Empty; _elements = new List(0); _lines = new List(1); @@ -95,6 +103,14 @@ namespace FairyGUI if (_richTextField is InputTextField) { _input = true; + EnableCharPositionSupport(); + } + } + + public void EnableCharPositionSupport() + { + if (_charPositions == null) + { _charPositions = new List(); _textChanged = true; } @@ -161,10 +177,15 @@ namespace FairyGUI { _text = ToolSet.FormatCRLF(value); _textChanged = true; - _html = false; + _html = true; } } + public string parsedText + { + get { return _parsedText; } + } + /// /// /// @@ -251,8 +272,11 @@ namespace FairyGUI } set { - _strokeColor = value; - graphics.SetMeshDirty(); + if (_strokeColor != value) + { + _strokeColor = value; + graphics.SetMeshDirty(); + } } } @@ -456,10 +480,10 @@ namespace FairyGUI public override void Update() { - base.Update(); - if (_richTextField == null) //如果是richTextField,会在update前主动调用了Rebuild Rebuild(); + + base.Update(); } void ResolveFont() diff --git a/Engine/CLEngine.Core/gui/UI/GProgressBar.cs b/Engine/CLEngine.Core/gui/UI/GProgressBar.cs index 35f9d3dd96ea73e498171b6afdfb513e8de28240..eecee9a56b5dffd38aadbc67f7e47c2236b17fef 100644 --- a/Engine/CLEngine.Core/gui/UI/GProgressBar.cs +++ b/Engine/CLEngine.Core/gui/UI/GProgressBar.cs @@ -13,7 +13,7 @@ namespace FairyGUI ProgressTitleType _titleType; bool _reverse; - GTextField _titleObject; + GObject _titleObject; GMovieClip _aniObject; GObject _barObjectH; GObject _barObjectV; @@ -154,20 +154,12 @@ namespace FairyGUI { if (_barObjectH != null) { - if ((_barObjectH is GImage) && ((GImage)_barObjectH).fillMethod != FillMethod.None) - ((GImage)_barObjectH).fillAmount = percent; - else if ((_barObjectH is GLoader) && ((GLoader)_barObjectH).fillMethod != FillMethod.None) - ((GLoader)_barObjectH).fillAmount = percent; - else + if (!SetFillAmount(_barObjectH, percent)) _barObjectH.width = (int)Math.Round(fullWidth * percent); } if (_barObjectV != null) { - if ((_barObjectV is GImage) && ((GImage)_barObjectV).fillMethod != FillMethod.None) - ((GImage)_barObjectV).fillAmount = percent; - else if ((_barObjectV is GLoader) && ((GLoader)_barObjectV).fillMethod != FillMethod.None) - ((GLoader)_barObjectV).fillAmount = percent; - else + if (!SetFillAmount(_barObjectH, percent)) _barObjectV.height = (int)Math.Round(fullHeight * percent); } } @@ -175,11 +167,7 @@ namespace FairyGUI { if (_barObjectH != null) { - if ((_barObjectH is GImage) && ((GImage)_barObjectH).fillMethod != FillMethod.None) - ((GImage)_barObjectH).fillAmount = 1 - percent; - else if ((_barObjectH is GLoader) && ((GLoader)_barObjectH).fillMethod != FillMethod.None) - ((GLoader)_barObjectH).fillAmount = 1 - percent; - else + if (!SetFillAmount(_barObjectH, percent)) { _barObjectH.width = (int)Math.Round(fullWidth * percent); _barObjectH.x = _barStartX + (fullWidth - _barObjectH.width); @@ -187,11 +175,7 @@ namespace FairyGUI } if (_barObjectV != null) { - if ((_barObjectV is GImage) && ((GImage)_barObjectV).fillMethod != FillMethod.None) - ((GImage)_barObjectV).fillAmount = 1 - percent; - else if ((_barObjectV is GLoader) && ((GLoader)_barObjectV).fillMethod != FillMethod.None) - ((GLoader)_barObjectV).fillAmount = 1 - percent; - else + if (!SetFillAmount(_barObjectH, percent)) { _barObjectV.height = (int)Math.Round(fullHeight * percent); _barObjectV.y = _barStartY + (fullHeight - _barObjectV.height); @@ -202,6 +186,18 @@ namespace FairyGUI _aniObject.frame = (int)Math.Round(percent * 100); } + bool SetFillAmount(GObject bar, float amount) + { + if ((bar is GImage) && ((GImage)bar).fillMethod != FillMethod.None) + ((GImage)bar).fillAmount = amount; + else if ((bar is GLoader) && ((GLoader)bar).fillMethod != FillMethod.None) + ((GLoader)bar).fillAmount = amount; + else + return false; + + return true; + } + override protected void ConstructExtension(ByteBuffer buffer) { buffer.Seek(0, 6); @@ -209,7 +205,7 @@ namespace FairyGUI _titleType = (ProgressTitleType)buffer.ReadByte(); _reverse = buffer.ReadBool(); - _titleObject = GetChild("title") as GTextField; + _titleObject = GetChild("title"); _barObjectH = GetChild("bar"); _barObjectV = GetChild("bar_v"); _aniObject = GetChild("ani") as GMovieClip; diff --git a/Engine/CLEngine.Core/gui/UI/GSlider.cs b/Engine/CLEngine.Core/gui/UI/GSlider.cs index c8adcf3d774df7c42022a93d771b93bccf0e85df..ab09514d00eaea75bda005f610cf8247ddf45c83 100644 --- a/Engine/CLEngine.Core/gui/UI/GSlider.cs +++ b/Engine/CLEngine.Core/gui/UI/GSlider.cs @@ -14,7 +14,7 @@ namespace FairyGUI ProgressTitleType _titleType; bool _reverse; - GTextField _titleObject; + GObject _titleObject; GObject _barObjectH; GObject _barObjectV; float _barMaxWidth; @@ -127,7 +127,7 @@ namespace FairyGUI switch (_titleType) { case ProgressTitleType.Percent: - _titleObject.text = (int)Math.Round(percent * 100) + "%"; + _titleObject.text = Math.Floor(percent * 100) + "%"; break; case ProgressTitleType.ValueAndMax: @@ -150,20 +150,12 @@ namespace FairyGUI { if (_barObjectH != null) { - if ((_barObjectH is GImage) && ((GImage)_barObjectH).fillMethod != FillMethod.None) - ((GImage)_barObjectH).fillAmount = percent; - else if ((_barObjectH is GLoader) && ((GLoader)_barObjectH).fillMethod != FillMethod.None) - ((GLoader)_barObjectH).fillAmount = percent; - else + if (!SetFillAmount(_barObjectH, percent)) _barObjectH.width = (int)Math.Round(fullWidth * percent); } if (_barObjectV != null) { - if ((_barObjectV is GImage) && ((GImage)_barObjectV).fillMethod != FillMethod.None) - ((GImage)_barObjectV).fillAmount = percent; - else if ((_barObjectV is GLoader) && ((GLoader)_barObjectV).fillMethod != FillMethod.None) - ((GLoader)_barObjectV).fillAmount = percent; - else + if (!SetFillAmount(_barObjectH, percent)) _barObjectV.height = (int)Math.Round(fullHeight * percent); } } @@ -171,11 +163,7 @@ namespace FairyGUI { if (_barObjectH != null) { - if ((_barObjectH is GImage) && ((GImage)_barObjectH).fillMethod != FillMethod.None) - ((GImage)_barObjectH).fillAmount = 1 - percent; - else if ((_barObjectH is GLoader) && ((GLoader)_barObjectH).fillMethod != FillMethod.None) - ((GLoader)_barObjectH).fillAmount = 1 - percent; - else + if (!SetFillAmount(_barObjectH, percent)) { _barObjectH.width = (int)Math.Round(fullWidth * percent); _barObjectH.x = _barStartX + (fullWidth - _barObjectH.width); @@ -183,11 +171,7 @@ namespace FairyGUI } if (_barObjectV != null) { - if ((_barObjectV is GImage) && ((GImage)_barObjectV).fillMethod != FillMethod.None) - ((GImage)_barObjectV).fillAmount = 1 - percent; - else if ((_barObjectV is GLoader) && ((GLoader)_barObjectV).fillMethod != FillMethod.None) - ((GLoader)_barObjectV).fillAmount = 1 - percent; - else + if (!SetFillAmount(_barObjectH, percent)) { _barObjectV.height = (int)Math.Round(fullHeight * percent); _barObjectV.y = _barStartY + (fullHeight - _barObjectV.height); @@ -196,6 +180,18 @@ namespace FairyGUI } } + bool SetFillAmount(GObject bar, float amount) + { + if ((bar is GImage) && ((GImage)bar).fillMethod != FillMethod.None) + ((GImage)bar).fillAmount = amount; + else if ((bar is GLoader) && ((GLoader)bar).fillMethod != FillMethod.None) + ((GLoader)bar).fillAmount = amount; + else + return false; + + return true; + } + override protected void ConstructExtension(ByteBuffer buffer) { buffer.Seek(0, 6); @@ -203,7 +199,7 @@ namespace FairyGUI _titleType = (ProgressTitleType)buffer.ReadByte(); _reverse = buffer.ReadBool(); - _titleObject = GetChild("title") as GTextField; + _titleObject = GetChild("title"); _barObjectH = GetChild("bar"); _barObjectV = GetChild("bar_v"); _gripObject = GetChild("grip"); diff --git a/Engine/CLEngine.Core/gui/UI/ScrollPane.cs b/Engine/CLEngine.Core/gui/UI/ScrollPane.cs index 9efa7e4299587a78e2b1ae3445fee9f28497ef56..0a6046a4bd859fca6a37c7051ad3708830041069 100644 --- a/Engine/CLEngine.Core/gui/UI/ScrollPane.cs +++ b/Engine/CLEngine.Core/gui/UI/ScrollPane.cs @@ -560,6 +560,8 @@ namespace FairyGUI if (!_pageMode) return 0; + _owner.EnsureBoundsCorrect(); + int page = (int)Math.Floor(_xPos / _pageSize.X); if (_xPos - page * _pageSize.X > _pageSize.X * 0.5f) page++; @@ -583,6 +585,11 @@ namespace FairyGUI /// 是否使用缓动到达目标。 public void SetCurrentPageX(int value, bool ani) { + if (!_pageMode) + return; + + _owner.EnsureBoundsCorrect(); + if (_overlapSize.X > 0) this.SetPosX(value * _pageSize.X, ani); } @@ -605,6 +612,11 @@ namespace FairyGUI } set { + if (!_pageMode) + return; + + _owner.EnsureBoundsCorrect(); + if (_overlapSize.Y > 0) this.SetPosY(value * _pageSize.Y, false); } @@ -617,6 +629,11 @@ namespace FairyGUI /// 是否使用缓动到达目标。 public void SetCurrentPageY(int value, bool ani) { + if (!_pageMode) + return; + + _owner.EnsureBoundsCorrect(); + if (_overlapSize.Y > 0) this.SetPosY(value * _pageSize.Y, ani); } diff --git a/ThirdParty/IMEHelper b/ThirdParty/IMEHelper new file mode 160000 index 0000000000000000000000000000000000000000..db0fb79a6e0996721b3ecbc6514a83c74d4f9a15 --- /dev/null +++ b/ThirdParty/IMEHelper @@ -0,0 +1 @@ +Subproject commit db0fb79a6e0996721b3ecbc6514a83c74d4f9a15