在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
今天开始研究WPF + Lua。 总的来说感觉被虐了…… 主要是WPF的UI玩不转。 简单来说,WPF里调Lua这都很好实现。。 问题是!!! 我想在Lua的一条指令里实现 一个对UI控件的操作,然后阻塞在对鼠标的响应上。。(就是有鼠标响应之后再执行下一条语句) 这个花了我一晚的时间……而且还是非常非常丑陋的实现。。基本原理和我之前用HGE实现UI渲染机制同出一辙。。 这实在是丑陋得令我自己都忍不了了,放上丑陋的成果。明天继续研究…… 丑陋的实现原理: 我实现了一个后台线程作为LuaAPI代理线程,Lua在调用C#功能时先走这个线程代理,由于此线程不能对UI控件进行操作(WPF中禁止跨线程访问UI元素。),我用了一个Dispatcher.BeginInvoke的基于UI线程控制的异步机制来把“代理API”转交到UI。 运行画面: 代码: using System; using System.Collections.Generic; using System.Linq; using System.Text; 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.Navigation; using System.Windows.Shapes; using System.Windows.Threading; using System.Threading; using LuaInterface; namespace CodersLife { /// <summary> /// 工具类 /// </summary> class Super { /// <summary> /// 加载图片 /// </summary> /// <param name="address">图片地址</param> /// <returns>图片</returns> static public BitmapSource GetImage(string address) { return new BitmapImage(new Uri(AppDomain.CurrentDomain.BaseDirectory + string.Format("/Resource/Image/{0}", address), UriKind.Relative)); } } /// <summary> /// LuaAPIProxy类 /// </summary> class LuaAPIProxy { public Lua lua = new Lua();//初始化lua虚拟机 public Thread luaThread; public Window1 MainWindow { get; set; } public void Start() { try { //绑定lua函数 lua.RegisterFunction("BackImage", this, this.GetType().GetMethod("BackImage")); lua.RegisterFunction("Music", this, this.GetType().GetMethod("Music")); lua.RegisterFunction("Debug", MainWindow, MainWindow.GetType().GetMethod("Debug")); lua.RegisterFunction("BindRolePic", MainWindow, MainWindow.GetType().GetMethod("BindRolePic")); lua.RegisterFunction("Dialog", this, this.GetType().GetMethod("Dialog")); //启动lua脚本 lua.DoFile("Script/Test.lua"); } catch (System.Exception e) { MessageBox.Show(e.ToString()); } } public delegate void LuaThreadDelegate1s(string s1); public delegate void LuaThreadDelegate2s(string s1, string s2); public void BackImage(string image) { MainWindow.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new LuaThreadDelegate1s(MainWindow.BackImage), image); } public void Music(string music) { MainWindow.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new LuaThreadDelegate1s(MainWindow.Music), music); } //显示角色对话 public void Dialog(string name, string dialog) { MainWindow.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new LuaThreadDelegate2s(MainWindow.Dialog), name, dialog); WaitForClick(); } public bool ClickMutex { get; set; } //阻塞等待用户点击鼠标,会阻塞Lua脚本 public void WaitForClick() { ClickMutex = false; while (!ClickMutex) { Thread.Sleep(10); } } } /// <summary> /// Window1.xaml 的交互逻辑 /// </summary> public partial class Window1 : Window { LuaAPIProxy luaAPIProxy = new LuaAPIProxy(); public delegate void LuaThreadDelegate(); public Window1() { InitializeComponent(); InitLua(); } //初始化lua public void InitLua() { luaAPIProxy.luaThread = new Thread(new ThreadStart(luaAPIProxy.Start)); luaAPIProxy.MainWindow = this; luaAPIProxy.luaThread.Start(); //Dispatcher.BeginInvoke(DispatcherPriority.Normal, new LuaThreadDelegate(LuaAPIProxy.Start)); } //循环播放音乐 public void ReplayMusic(object sender, EventArgs e) { BackMusic.Stop(); BackMusic.Play(); } private void OnUserClick(object sender, System.Windows.Input.MouseButtonEventArgs e) { // TODO: Add event handler implementation here. luaAPIProxy.ClickMutex = true; GameDialog.Visibility = Visibility.Collapsed; } //切换游戏背景图片 public void BackImage(string image) { Brush brushInstance = new ImageBrush { ImageSource = Super.GetImage(image) }; this.Carrier.Background = brushInstance; } //切换音乐 public void Music(string music) { try { this.BackMusic.Stop(); this.BackMusic.Source = new Uri(AppDomain.CurrentDomain.BaseDirectory + string.Format("/Resource/Music/{0}", music), UriKind.Relative); this.BackMusic.Play(); } catch (Exception e) { MessageBox.Show(e.ToString()); } } private Dictionary<string, string> _rolePic = new Dictionary<string, string>(); //绑定角色图片 public void BindRolePic(string name, string pic) { _rolePic.Add(name, pic); } //显示角色对话 public void Dialog(string name,string dialog) { RoleName.Content = name; DialogInfo.Content = dialog; string Pic = _rolePic[name]; Brush brushInstance = new ImageBrush { ImageSource = Super.GetImage(Pic) }; this.RoleHeadPic.Background = brushInstance; GameDialog.Visibility = Visibility.Visible; } //debug public void Debug(string info) { MessageBox.Show("debug info:" + info); } } } LUA代码: BackImage("battle_back.jpg"); |
请发表评论