文章目录

  • 关于输入法开发上问题与解决
    • `context.GetSelection`报错`System.StackOverflowException`:
    • 输入法送入宿主程序文本,插入位置与光标位置的问题。
  • AI+与游戏开发
  • 《游戏编程模式》笔记
    • 设计模式
      • 命令模式
      • 撤销与重做
      • 享元模式
  • Unity与Lua同舞
    • 何为Unity
    • 何为Lua
    • Unity X Lua = XLua
    • 为什么选择它
    • 设计思路
    • 关于xlua反复报错This delegate/interface must add to CSharpCallLua : XXX的问题
    • 关于Unity帧数不固定问题

关于输入法开发上问题与解决

context.GetSelection报错System.StackOverflowException:

C#与C++通信需要内存对齐。托管代码与非托管代码之间需要封送数据。需要运用MarshalAs特性1

​ 此属性是可选的,因为每个数据类型都有默认的封送处理行为。 仅当给定类型可以封送到多种类型时,此属性才是必需的。

接口ITfContext中函数需要改为HRESULT GetSelection([In] TfEditCookie ec, [In] uint ulIndex, [In] uint ulCount, [Out] TF_SELECTION[] pSelection, [NullAllowed] out uint pcFetched);函数需要改为HRESULT GetSelection([In] TfEditCookie ec, [In] uint ulIndex, [In] uint ulCount, [Out,MarshalAs(UnmanagedType.LPArray)] TF_SELECTION[] pSelection, [NullAllowed] out uint pcFetched);

输入法送入宿主程序文本,插入位置与光标位置的问题。

之前使用的是ITfContext::GetStart获取到ITfRange,调用ITfRange::SetText来插入文字。插入的位置默认为文章首,个别程序会插入到光标处,并且后退(eg. Windows记事本)。

后改用ITfcontext::GetSelection获取TF_fSelection实例后,通过获取range属性来获取ITfRange。解决了插入问题。

但是,这里出现了光标不向后移动的问题。就算给TfAnchor设置了重力和合并,均改变不了输入以后光标的位置。最后,找到一个开源的输入法——狼毫输入法2——通过阅读源码,才解决问题(ps 通过阅读源码,感觉这个开源代码的写的挺优美的。简简单单的几行就解决问题了。

修改后的相关代码如下:

_selections = new TF_SELECTION[1];var res = _context.GetSelection(ec, 4294967295, 1, _selections, out var pcFetched);
if (pcFetched == 1)
{var range = _selections[0].range;res = range.SetText(ec, 0, _words, _words.Length);range.Collapse(ec, TfAnchor.TF_ANCHOR_END);var selection = new TF_SELECTION{range = range,style = new TF_SELECTIONSTYLE{ase = TfActiveSelEnd.TF_AE_END,fInterimChar = false}};_context.SetSelection(ec, 1, selection);
}

AI+与游戏开发

在2002年,李晓磊等人在动物群体智能行为研究的基础上提出的一种新型方盛优化算法,该算法根据水域中鱼生存数目最多的地方就是本水域中富含营养物质最多的地方这一特点来模拟鱼群的觅食行为而实现寻优。算法主要利用鱼的三大基本行为:觅食、聚群和追尾行为,采用自上而下的寻优模式从构造个体的底层行为开始,通过鱼群中各个体的局部寻优,达到全局最优值在群体中凸显出来的目的3

现在人工智能成功用于游戏的案例有4

  • 孤岛惊魂5 利用AI自动生成地形植被
  • 荒野大镖客 NPC自主交互
  • 动物生态、实时环境渲染

此外还有AI修复古建筑5

《游戏编程模式》笔记

设计模式

命令模式

将一个请求封装为一个对象,从而允许你使用不同的请求、队列或者日志将客户端参数化,同时支持请求操作的撤销与恢复。

命令就是面向对象的回调。

对应代码c++

// 基类
class Command
{public:virtual ~Command(){}virtual void execute(GameActor& actor)=0;
};
class JumpCommand: public Command
{public:virtual void execute(GameActor& actor){actor.jump();}
}
class FireCommand :public Command
{virtual void execute(GameActor& actor){actor.fireGun();}
}
// ...
// 空值命令对象模式
class NullCommand: public Command
{virtual void execute(GameActor& actor){}
}
// 输入处理
class InputHandler
{public:Command* handleInput();// 绑定其他命令private:Command* buttonX_;Command* buttonY_;Command* buttonA_;Command* buttonB_;
}
void InputHnadler: handleInput()
{if (isPressed(BUTTON_X)) return buttonX_;else if (isPressed(BUTTON_Y)) return buttonY_;else if (isPressed(BUTTON_A)) return buttonA_;else if (isPressed(BUTTON_B)) return buttonB_;}// 角色执行命令
Command* command = inputHandler.handleInput();
if(command)
{command->exectue(actor);
}

在命令与角色之间加入间接层,可以使得玩家以及AI操控任意的角色。如果我们把命令序列化,便可以通过网络发送数据流,这个是多人游戏中主要的一部分。

撤销与重做

c++:

// 基类
class Command
{public:virtual ~Command(){}virtual void execute(GameActor& actor)=0;virtual void undo()=0;
};
class MoveUnitCommand: public Command
{public:MoveUnitCommand(Unit* unit,int x,int y): unit_(unit),x_(x),y_(y){}virtual void execute(){unit_->moveTo(x_,y_);}private:Unit* unit_;int x_;int y_;
}

与备忘录相比,节约内存。

重做在游戏中不常见,但回放很常见。

JS实现(使用闭包)

function makeMoveUnitCommand(unit,x,y){var xBefore,yBefore;return function(){execute:function(){xBefore = unit.x();yBefore = unit.y();unit.moveTo(x,y);},undo: function(){unit.moveTo(xBefore,yBefore)}}
}
  • 如果有很多不同的命令类,可以定义一个具体的基类来实现更高层次的方法。命令主要的execute()变成了子类沙盒。
  • 如果在对象分层等那些不明确执行命令的角色情况下,可以将命令下放給其从属对象。可以参考责任链。
  • 同样的命令实例重复,可以使用享元模式。

享元模式

class TreeModel
{private:Mesh mesh_;Texture bark_;Texture leaves_;
}
class Tree
{private:TreeModel* model_;Vector position_;double height_;double thicknes_;Color barkTint_;Color leafTint_;
}

与类型对象模式对比:

 类型对象通过把“类型”对象化,可以尽可能较少定义新类型的数量,而享元模式却更加注重效率。

应用:

TiledMap

* 一般来说,享元对象总是不可变的。

  • 按需创建享元。在接口体上封装,来隐藏构造函数。可以参考工厂方法模式。
  • 查找实例化的享元,对象池模式。
  • 状态模式下,使用享元。以及上一章节提到的命令模式。

Unity与Lua同舞

何为Unity

Unity为Unity Technologies 公司开发的三维游戏制作引擎。其凭借自身的跨平台性与开放性优势已经逐渐成为当今世界范围内的主流游戏引擎6。由于手机游戏的流行,目前2D游戏开发的需求量也越来越大了,因此Unity3D游戏引擎也增加了2D游戏开发的支持7

何为Lua

Lua 是一种轻量小巧的脚本语言,用标准C语言编写并以源代码形式开放, 其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能8

Unity X Lua = XLua

xLua为Unity、 .Net、 Mono等C#环境增加Lua脚本编程的能力,借助xLua,这些Lua代码可以方便的和C#相互调用9

为什么选择它

原因为游戏为横版弹幕游戏设计,弹幕的子弹变化万千,犹如夜空中中热烈绽放的烟花一样,绚丽多彩。需要一个高效的解释性语言去控制每个子弹和怪物的没帧逻辑。而Lua正好胜任此工作。

设计思路

设计为如下:

由于Lua没有类继承,因此写了Class函数来生成实例,利用原型链来实现继承。核心代码如下:

-- 对应新类
function Class(base)base = base or objectlocal result = {}result.is_class = trueresult.init = base.initresult.frame = base.frameresult.kill = base.killresult.base = base--setmetatable(result,_met)return result
end

生成的实例可以由New来直接运行:

function New(obj, ...)local new = Class(obj)new:init(...)return new
end

逻辑定义全在init,由Lua协程来控制每帧操作:

关于xlua反复报错This delegate/interface must add to CSharpCallLua : XXX的问题

添加CSharpCallLua标签。比如:

public class LuaObject : MonoBehaviour
{[XLua.CSharpCallLua]public delegate void KillDelegate(int index);[CSharpCallLua]private delegate void DoFrameDelegate();private LuaEnv luaEnv = null;private DoFrameDelegate DoFrame;public KillDelegate Kill;void Start(){//...DoFrame = luaEnv.Global.Get<DoFrameDelegate>("DoFrame");Kill = luaEnv.Global.GetInPath<KillDelegate>("Kill");}
}

如果还是存在问题的话,清除并重新生成代码。

  1. Xlua-> Clear Generated Code

  2. Xlua-> Generate Code

    即可解决问题。

关于Unity帧数不固定问题

这边只更新Lua更新部分

void Update()
{if (IsRunning){luaEnv?.Tick();var current = Time.realtimeSinceStartup;var needUpdateframeNum = (current - startTime) * 60 - frameNum;if(needUpdateframeNum>45){// 卡Debug.LogError("太卡了!");// 勉勉强强让玩家继续needUpdateframeNum = 1;frameNum = 0;startTime = Time.realtimeSinceStartup;}for (var i=0;i<needUpdateframeNum;i++){DoFrame();frameNum++;}}
}

  1. MarshalAsAttribute 类 (System.Runtime.InteropServices) | Microsoft Docs https://docs.microsoft.com/zh-cn/dotnet/api/system.runtime.interopservices.marshalasattribute?view=netframework-4.8 ↩︎

  2. rime/weasel: 【小狼毫】Rime for Windows ↩︎

  3. 人工鱼群算法详解_wp_csdn的专栏-CSDN博客 https://blog.csdn.net/wp_csdn/article/details/54577567 ↩︎

  4. 《游戏行业发展概况》 https://game.academy.163.com/live?id=ga-1601284961961 ↩︎

  5. AI还原古代遗迹,一文多图带你穿越时空!_进行 https://www.sohu.com/a/413542857_587438 ↩︎

  6. Unity 3D简介 http://c.biancheng.net/unity3d/10/ ↩︎

  7. [Unity2D]游戏引擎介绍_weixin_34204057的博客-CSDN博客 https://blog.csdn.net/weixin_34204057/article/details/86275226 ↩︎

  8. Lua 教程 | 菜鸟教程 https://www.runoob.com/lua/lua-tutorial.html ↩︎

  9. Tencent/xLua: xLua is a lua programming solution for C# ( Unity, .Net, Mono) , it supports android, ios, windows, linux, osx, etc. https://github.com/Tencent/xLua ↩︎

10月9日到10月30日学习总结相关推荐

  1. 惠州全国计算机证书,广东惠州学院2017年9月计算机等级考试报名时间:6月15日-30日...

    惠州学院信息科学技术学院2017年下半年(第49次)全国计算机等级考试(简称NCRE,下同)报考工作于6月15日开始,具体事项如下: 一.考试时间.科目及考试系统 (一)考试时间:2017年9月23日 ...

  2. 分享Silverlight/WPF/Windows Phone一周学习导读(10月30日-11月6日)

    分享Silverlight/WPF/Windows Phone一周学习导读(10月30日-11月6日) 本周Silverlight学习资源更新 Silverlight 定位 niejunhua [学习 ...

  3. 湖州机器人上课时间_【倒计时5天】燃到炸!湖州吾悦广场10月30日开业狂欢指南,请收下...

    Are You Ready ? 开业party潮狂欢 每日精彩表演为你撑满排面 湖州吾悦广场邀您 嗨吃嗨玩嗨购! 开业期间9:30-24:00 来州吾悦开业狂欢盛典 用一首歌就能你 带回那样无忧无虑的 ...

  4. 热血篮球维修服务器是怎么回事,新浪《热血篮球》10月30日停服维护及更新公告...

    新浪<热血篮球>将于10月30日11:00-13:00对所有服务器进行停服维护及版本更新,更新期间将无法登录服务器,请各位玩家尽可能在服务器停机之前下线,以免有错误操作可能带来不必要的损失 ...

  5. 苹果将迎来2018年第四次新品发布季节,时间定为10月30日

    北京时间为2018年10月19日,根据外媒资讯报道,手机巨头苹果公司宣布将会在今年的10月30日再次召开一次新品发布会,此次发布会也正是2018年第四次新品发布会,据透露,此次发布的新品很有可能是最新 ...

  6. SSL2811 2017年10月30日提高组T2 摘Galo(树形dp)

    2017年10月30日提高组T2 摘Galo Description 0v0在野外看到了一棵Galo树,看到食物的0v0瞪大了眼睛,变成了OvO. 这棵Galo树可以看做是一棵以1号点为根的n个点的有 ...

  7. 【历史上的今天】10 月 30 日:英特尔最大失误;图像冒险游戏的发明者诞生;最后一台 Multics 计算机被关闭

    整理 | 王启隆 透过「历史上的今天」,从过去看未来,从现在亦可以改变未来. 今天是 2021 年 10 月 30 日,在 12 年前的今天,两弹一星元勋钱学森逝世,钱老是中国火箭.导弹.航天事业的奠 ...

  8. 鸿图之下服务器维护10月25,更新公告丨《鸿图之下》12月30日维护更新预告

    为了帮助大家更好地体验游戏,我们收集了大家的意见,并计划进行一次维护.此次维护将从12月30日凌晨5点00分开始,预计维护2小时.请各位主公提前安排游戏时间,稍作休息. 平衡性调整 调整张辽自带武技[ ...

  9. 【转载】10月30日,94岁的金庸老爷子去世!

    2018,究竟是啥年? Sir感觉很多华人,都会永远记住这一年. 这一年有很多大师.艺人.文娱名人纷纷逝世,是华人世界的巨大损失. 李敖.李大为.计春华.常宝华.单田芳.朱旭.臧天朔.李咏--(名单太 ...

  10. lol服务器维护9月30,LOL云顶之弈2020年9月30日更新结束时间一览 10.20版本上线

    LOL云顶之弈2020年9月30日的更新内容介绍,今天小编给大家带来的就是云顶之弈10.20版本的更新结束时间一览,希望对大家有所帮助. LOL将在9月30日凌晨3点开始全区停机维护(请注意:2点将关 ...

最新文章

  1. 在java中建个jsp文件_第一个jsp页面
  2. 腾讯公布 23 年前第一间办公室照片
  3. 云计算市场竞争激烈 亚马逊微软IBM阿里业绩亮眼
  4. gentoo rt-thread scons --menuconfig libs/lxdialog/util.o: undefined reference to symbol 'nodelay'
  5. apps-privacy-policy
  6. oracle的隐式游标有哪些,Oracle隐式游标小例子
  7. C++输入函数的应用
  8. 动态 Restful API 生成
  9. mysql数据库表的类型介绍,mysql数据库表的类型介绍
  10. lemur run PLSA
  11. 记一道简单的Java面试题,但答错率很高!
  12. linux服务器配置python环境_服务器python环境配置福利,CentOS ,Linux 一键下载python3和环境配置...
  13. java程序设计_Java程序设计-Object类(笔记)
  14. Gradle在Android中的基本使用
  15. (转载)新浪微博错误提示代码
  16. 最长回文子串 马拉车算法
  17. c语言头文件sys wait.h,错误:sys/wait.h:没有这样的文件或目录
  18. Unity 手机VR GoogleVR 详细配置教程
  19. 泰克TBS1000X示波器仪器的使用
  20. php写的一个超短线选股程序(选股效果还是不错的)

热门文章

  1. Liferay 6.0 R2 run log at first time
  2. Vim编辑器与shell脚本(.sh)
  3. CAD图纸转Word文件,看看这个方法你会吗?
  4. 华为服务器怎么安装win7系统,远程服务器安装win7系统
  5. CSDN 论坛板块升级规则
  6. Data Preprocess
  7. 优优智能客户关系管理系统UUCRM5.0
  8. 走遍中国 —— 大西南
  9. php3.2搭建临时聊天系统,基于swoole搭建聊天室程序
  10. 巨坑警告!去银行写代码千万别去分行