最近在学python,我想未来成为一个爬虫工程师吧
创娱点餐助手
来创娱半年多了,一直觉的这边的包餐福利挺好的,虽然没有什么大鱼大肉,但是能让员工自己点餐的方式还是挺人性化的,菜单的种类还挺多,基本可以满足我的各种口味吧。但是有一点点瑕疵的是,公司的点餐网站似乎永远不那么人性化,公司500多号人,不要求你做的界面多好看,但是起码要满足同事们的基本需求吧,每次点餐都搞得挺麻烦的。而且界面用户体验很差。
公司的点餐系统是网页形式的,但是页面巨丑,而且每次选择一个菜项都是一个好长好长的下拉框,而且没有随机点餐的功能,没有自动分类的功能,周一到周五的午餐和晚餐每次都要从一个长长的下拉框选择,要是有不小心刷新了网页或是关闭了就要重新开始选择。公司大群里也经常能看到有同事吐槽这个东西。于是我就想我是程序员啊,我完全可以不用他的点餐系统,自己开发一个,只要从它的内网上获取菜单数据,然后自己选择好提交都它的网站后台就行了啊!越想越兴奋,
马上就开干了。然后就有了如下点餐助手C#开发 哈哈。


看起来虽然简陋,但是我感觉比公司运维做的网页版好多了,起码可以帮助有选择困难的同事,随机选择自己喜欢的类型,还不必每次都去选择每天的饭菜。当然为了人性化,如果随机到自己不喜欢的饭菜还是可以自己再自主选择的,而且还加入了2种搭配方式,一开始本来是想自己用的,但是当我发给行政MM后他们都觉得很棒,索性直接发给全公司人用好了哈哈。上面还有关键字过滤功能,我会在下一个版本中完善它。
protobuf
UGUI屏幕点击关闭Tips小技巧
在做MMORPG 游戏中在UI上会有很多的Tips弹窗的UI,策划的需求是点击Tips外面要关闭这个Tips那么我们首先想到的做法是,获取点击的区域或者对象判断是否点击是 tipsUI如果是则不关闭,
如果不是则关闭Tips,那么这样的做法有很多,其中一个是设置一个透明image背景,然后在这个Image上添加Button组件,当点击这个背景时关闭这个tips弹窗,当然这个背景要扩展到整个屏幕,
然后要设置成透明的这样才能不挡住其他UI。
但是我感觉这样的方法好像多了一个几个步骤而且有点麻烦,既然我们只要一个透明带raycasts的背景而已,那么用一个空的Text组件也是一样可以实现。把字体和文字都设置为空,这样既可以不用设置透明度也可以达到一个点击屏幕的效果。
RectMask2D和Mask
最近项目中做UI,用的比较多的Scroll Rect这个组件,发现他是通过一个遮罩来显示Scroll Rect里的内容的,在UGUI中Scroll View自动创建的遮罩用的是Mask组件,但是我通过搜索发现还有
RectMask2D这个组件,然后我用上去发现效果是一样的。查了一下U3D的文档:
the limitations of RectMask2D control are:
-
It only works in 2D space 它只能工作在2D空间中
-
It will not properly mask elements that are not coplanar 它不能遮罩不在一个平面上的元素
The advantages of RectMask2D are:
-
It does not use the stencil buffer 它不会使用模板缓存
-
No extra draw calls 不会增加额外的 draw calls
-
No material changes 不会有材质的变化
-
Fast performance 速度更快的显示
是这样解释的,这简直是神器啊,比原来的Mask好用多了,但是前提是你用不到3D UI这个功能,那么如果你是做普通的2D UI 使用这个组件做遮罩是完全没有问题的而且还可以减少draw calls数量于是我测试了一下。
使用了Mask组件的Scroll View,draw calls是5

使用了RectMask2D组件的Scroll View,draw calls是4

使用了RectMask2D组件比Mask组件draw calls少了1个,这在移动设备中是非常重要的优化啊。
rawget,rawset不对元表进行操作
有时候在lua中获取一个table的值并不想去查找元表那么可以用rawget(table,i)去获取想要的值,这次一次对原始值的访问。
如果想要设置一个table的值而不对其元表进行操作,则可以使用rawset(table,k,value)进行设置。
KSFramework
新公司,新项目,新的框架,这又将是一个挑战。
现在我们项目用的是 KSFramework+Xlua ,KSFramework是一个Unity 5 Asset Bundle开发框架和工具集,专注于运行时热重载,本身是使用了SLua作为脚本引擎。但是我们项目中给它改成了XLua作为脚本引擎,因为xlua效率方面比slua似乎更高一点,而且在KSframework中把slua换成xlua也是非常方便的,即使换成ulua也是可以的。
但是最近发现的是 在xlua里面只要出错 在手机端里游戏就会出现闪退,打出的PC包也是直接崩溃掉,之前用tolua的时候一般lua代码报错是不会导致游戏直接崩溃的。
这一点确实很蛋疼。
在lua中实现类的思想
在lua中是没有类的概念的但是可以使用table和元表来实现类和类的继承,多继承。
代码如下:
--clsname 类名
-- ... 父类或者是被继承的类
function class(clsname, ...) --此函数用来返回一个类(其实就是一个表)
local cls = {}
local args = {...} --保存父类列表
if #args > 0 then
setmetatable(cls, {__index= --设置此类的元表并把元表的 __index 设为一个函数,此函数用来查找父类中的变量或函数
function(_, k)
for i, v in ipairs(args) do
if v[k] ~= nil then
return v[k]
end
end
end})
end
cls.classname = clsname --设置好类名
cls.New = function() --定义一个实例化对象的函数(其实就是创建一个新表)
local instance = {}
setmetatable(instance, {__index=cls}) --设置此对象的元表的__index方法 为这个类。
instance.classtype = cls -- 设置此类的类型(其实就是这个元表)
return instance
end
return cls --最好返回这个类(这个表)
end
使用方法如下:
local CParent = class("CParent") --定义一个父类
local CSon = class("CSon", CParent) --定义子类继承自父类
local son = CSon.New() --创建一个孩子对象,此对象具有父类的所有属性
protobuf协议字段优化后的处理
特色
我们的游戏项目中使用了protobuf协议,但是由于协议优化了的缘故,当服务器发送字段值等于0 的时候,客户端协议解析出来后看不到这个值为0零的字段,但是如果直接用“.“去访问是可以访问的。于是问题就来了当我们数据需要更新的时候,如果在lua中 直接 for in pairs 去获得解析到的数据的键值,如果这个键的值是0 的话那么那么将会获取不到,也就是说这个时候无法判断这个字段是否是 0 ,还是根本服务器就没有发送过来。
于是我们就使用看 按位与的方式去检测和判断 服务器是否发了这个字段,对此,如果是需要更新的协议服务器都要多发一个mask 字段 这是一个 二进制转换后的十进制数,协议字段按照顺序,如果发了,,则这个位置为1,否则为0,如协议:
//申请入帮
message C2GSApplyJoinOrg {
optional uint32 orgid = 1;
optional uint32 flag = 2;
}
如果服务器发送了 orgid = 10 , flag = 0 过来,那么客户端只能看到 orgid = 10 这个字段,而看不到 flag 这个。
所以在客户端中我们就做了如下处理:
--dOri 是服务发送过来经过客户端解析后的数据
function CNetCtrl.DecodeMaskData(self, dOri)
local d = {}
local lKey = {"orgid","flag"}
if lKey then
local iMask = dOri.mask --服务发送时带一个二进制的mask字段
if iMask then
local right = 1
for i=1, #lKey do
right = right * 2
if MathBit.andOp(iMask, right) ~= 0 then
local key = lKey[i]
d[key] = dOri[key]
end
end
-- table.print(d, "CNetCtrl解析mask: "..sType)
return d
end
end
return dOri
end
function MathBit.__base(left, right, op)
if left < right then
left, right = right, left
end
local res = 0
local shift = 1
while left ~= 0 do
local ra = left % 2
local rb = right % 2
res = shift * op(ra,rb) + res
shift = shift * 2
left = math.modf( left / 2) --相当于右移一位
right = math.modf( right / 2)
end
return res
end
function MathBit.andOp(left, right)
return MathBit.__base(left, right, MathBit.__andBit)
end
function MathBit.__andBit(left,right) --按位相与
return (left == 1 and right == 1) and 1 or 0
end
这样处理完成之后的数据 客户端就是可以打印出来查看了。并且可以直接使用for in pairs 去打印他们为0的值。
2D场景坐骑飞行效果
最近在公司做一个坐骑系统里面有一个飞行的功能,一开始觉得应该是提高他的Y轴,后来发现效果并不明显,于是觉得如果要在2D场景中实现纵深的效果,还是要有大小比例的变化才能看上去 有高度。
于是把飞行的模型放大到 1.2 倍,发现效果还不是很明显,于是又把今天拉伸了 一点 效果才明显一点了,发现其他2D游戏的飞行中还带有云层效果看上去 效果就好多了。而且这个跟你坐的坐骑也有很大的关系
如果本身不是飞行的东西 你坐上去感觉就很怪异了。
所以总结得出要在2D场景中实现坐骑的飞行效果 1.放大模型 2.拉伸镜头 3.加入云彩特效或其他