Cocos2d-x 3.2 Lua 在Android设备闪退问题解决记录

描述:iOS设备运行正常,windows环境下模拟器程序运行正常,但是Android设备大多数都有运行一段时间闪退的问题。

第一次运行android设备上时使用版本3.0,后来升级到3.1.1,再到3.2,Android闪退问题一直存在,尤其是在红米系列设备,几乎必现。
因为对Android开发不是很熟悉,没法直接定位到导致crash的地方,于是请教了同事,后发现是打包的API版本过高,修改后闪退问题有明显好转,但是依然存在,最近项目进度不是那么赶,于是决定要彻底追查这个问题。
继续阅读

Vagrant使用小记

Vagrant是一个虚拟机,并且可以方便的将你系统的目录映射到虚拟机录下,方便你的工作,比如可以在windows下编写,然后到虚拟的linux环境中运行,而不用互相传输。

1 准备工作:

Vagrant:http://www.vagrantup.com/
Virtual Box:https://www.virtualbox.org/
Box资源下载:http://www.vagrantbox.es/
Putyy: http://www.putty.org/
继续阅读

如何进行有效的思考

最近看到知乎一篇文章(原文链接:http://www.zhihu.com/question/23614288/answer/25288450),我关注的倒不是答主给出的答案,而是他给出答案的整个思考过程,见过太多人的思考过程,我觉得有必要针对有效思考这个问题探究下。

看过一本书叫《思考,快与慢》,里头说思考可以分为两种,快思考与慢思考。快思考就是依赖情感、记忆和经验迅速作出判断,它见闻广博,使我们能够迅速对眼前的情况作出反应,如一个熟练掌握四则运算的人看到3X7这个算式的时候会本能的得出21这个思考结果。但它很容易上当,它固守“眼见即为事实”的原则,任由损失厌恶和乐观偏见之类的错觉引导我们作出错误的选择。另一种被称为慢思考,它通过调动注意力来分析和解决问题,并作出决定,它比较慢,不容易出错,比如考试的时候遇到了一种新题型需要解答时。
继续阅读

cocos-lua Scene介绍

cocos-lua里的Scene是对cocos2d的scene进行进一步的逻辑封装,增加常用的功能及方便管理,整个游戏都由一个个Scene来构成,所有的表现代码都应该在Scene里完成,而所有的Scene都由SceneMgr来管理,

SceneMgr

管理场景模版。

管理场景实例。管理结构为由Scene构成的栈,通过LoadScene和UnloadScene完成进栈和出栈,其中第一次加载需要用FiresLoadScene。

接口列表:

继续阅读

金山这几年--如何把游戏做失败(三)

本来前段时间约了几个朋友让他们分享些自己的心得,结果貌似各位都跟我一样也是重度拖延症患者……之前也有朋友跟我反映说我写的都是跟编程技术相关的,没什么兴趣,所以决定这篇写点其他的。

记得飞舟给我们的培训的第一堂课上就问了我们一个问题:你为什么要学习编程?每个人都有自己的初衷,有很多人是因为喜欢技术,而我则是为了可以自己做游戏。

能做出一款让大家喜欢玩并且玩得很开心的游戏是我的梦想。但是很可惜,至今为止我也没有参与过任何一款可以称之为成功的产品,但我却有幸目睹了一些失败产品的历程。成功不可以复制,但是失败可以避免,况且在成功学如此流行的今天,成功游戏的分析多入牛毛,所以这里还是分享些游戏失败的经验吧。

继续阅读

金山这几年--程序员的信仰(二)

“信仰是指对一个人(同样的对他的能力)、事物、神、宗教的教条或教导、没有经验证据的观点(例如拥有强烈的政治信仰)抱有信心和信任。” 维基百科如是说。

做为一名程序员,在金山的经历也使我拥有了一种编程信仰,我相信通过正确的方式方法可以写出优质没有bug的程序(是真的没有bug,而不是自己的声称)。只有你相信了它,你才有了这种可能去做到。

PS:至今还没有人从Tex的bug悬赏金中大幅获利给了我们这种教徒以极大的曙光。

继续阅读

金山这几年--program in project(一)

不知不觉在金山已经呆了近五年,这段时间里犯过很多错误,同时也学到了很多东西,既然已经离开,那也该为这段时间好好的做个回顾。今天就先来谈谈在编程技术这块吧。

首先声明,我谈到的技术相关的东西都是指在项目中的经验,那些纯粹的追求技术的人和在学术上追求的人,这些东西可能对你们来说毫无意义。 ^_^

继续阅读

cocos-lua 架构简介及使用

Github:https://github.com/yestein/cocos-lua

基础接口:

Class:New(base_class, class_name) :用于实现面对对象的类,base_class 若为nil则为完全定义一个新类。

一切的基础--LogicNode

cocos-lua里头所有对象的基础类,也就是所有cocos-lua里的对象都具有它的功能,它包括以下功能:

  • 拥有child和parent
  • 监听事件
  • 查询调用指定名称的函数,用以实现COM
  • 可以接受消息执行,并将消息继续向child传递
  • 打印日志

接口如下:

  • GetParent() --获取父节点
  • AddChild(child_name, child_node, order) --添加子节点
  • RemoveChild(child_name) --删除子节点
  • GetChild(child_name) --获取指定的子节点
  • ForEachChild(callback, …) --迭代遍历每一个子节点
  • DeclareListenEvent(event_type, func_name) --注册事件监听
  • QueryFunction(func_name) --查询指定名称的函数
  • QueryFunctionWithChild(func_name) --查询指定名称的函数(包括所有的子节点)
  • TryCall(func_name, …) --尝试调用指定名称的函数(包括子节点种,若全部没有,则返回nil)
  • ReceiveMessage(msg, …) --对node及其所有子节点都试图调用名为msg的函数
  • Print(log_level, fmt, …) --打印日志
  • AddComponent(child_name, component_name, …) --添加指定名称的组件

事件(event)和消息(message)的区别

event是一个全局的类似信号弹的角色,主要用于不同模块之间的通信。如逻辑模块抛出一个角色伤害事件,表现模块受到事件后对相应的角色做出受伤的表现,如受伤动作,飘出红色伤害值等。event的使用在于抛出event的模块并不知道哪个模块会去处理它,并通过这个来降低模块间的藕合度。

message更类似于一个定向的指示弹,主要用于模块内部的操作。模块收到一个message,首先模块本身对这个message要做出回应,是否要处理,然后继续将这个message传递给它的子模块。如表现模块给角色表现模块发送一个角色受伤的message,角色表现模块受到message之后做出对角色播放受伤动作,然后这个message继续传递给它的子模块如文字飘血模块,文字飘血模块播放一个跳动的数字。message的使用在于模块收到message的时候并不知道自己能不能处理这个message,而需要将message一层层逐级询问子模块,目的在于降低模块内部子模块之间的耦合,方便模块进行组装。
PS:cocos-lua里为了处理message方便,将message的名称定义为处理函数的名称,类似于obj-c。

综上所述,event和message的目的都是为了降低整体代码的藕合度,他们的区别如下:

  • 是否定向。event的发送者不关心谁会接收这个event,而message要求发送者必须知道对谁发送。
  • 是否有序。event的接收者处理顺序是无法预测的,message的可以按指定顺序发送给相应的接收者。

对象池(ObjPool):

Id对象池模版,可以方便的创建一个对象池,提供Add,Remove,Get操作,并返回自增长的对象Id,并会抛出对象诞生和消亡的事件。

PS:在初始化的时候需要指定Obj的Name,因为在有obj被添加和删除的时候会分别抛出“ObjName“Add和”ObjName“Remove的事件。

模块(Module):

Module继承自LogicNode,通过ModuleMgr这个对象池进行管理,若模块需要每帧进行的循环操作可通过自身的函数RegisterActive(module_name, fun_name) 来向游戏世界注册。

场景管理概述:

SceneMgr:
管理场景的对象池,并提供简便的加载和卸载场景接口。

SceneBase:
继承自LogicNode的每个场景模版的基类,内置一些常用操作,如场景的拖动及限制范围,缩放是否加载物理世界等等。

Layer:
每个cocos2d的scene下会有多个Layer,这里对cocos2d的Layer进行了一个管理,可通过指定的name取到指定的layer。
提供接口:AddLayer(创建好一个layer后按指定name往里加入),CreateLayer(直接创建一个指定name的layer),GetLayer
PS:每个场景建立后都会有一个默认的名为“main”的layer。

场景UI

提供2种方法,基于Cocos2d和基于CocoStudio的方法。

CocoSudio:

根据Scene的cocos_ui列表来加载对应UI的JSON文件,格式如下:

Scene.cocos_ui = {
    [JSON文件地址] = {
        name = UI名称(不可重复),
        hide = 0, --加载完成后是否隐藏
        button = {逻辑变量名 = 控件名, ...},
        label = {逻辑变量名 = 控件名, ...},
        labelbmfont = {逻辑变量名 = 控件名, ...},
        ...
    }
}

对于按钮类控件,Scene类会有一个OnCocosButtonEvent处理函数,在有按钮被按下等操作时少辉触发,函数内容自己实现,格式如下:

function Scene:OnCocosButtonEvent(ui_name, button_name, event)
    --body
end

其中ui_name就是刚才填入的UI名称,button_name是刚才填入的逻辑变量名,event有4个,定义在Ui.lua中,分别是

Ui.TOUCH_EVENT_BEGAN    = 0
Ui.TOUCH_EVENT_MOVED    = 1
Ui.TOUCH_EVENT_ENDED    = 2
Ui.TOUCH_EVENT_CANCELED = 3

如何创建一个新的场景模版

这里推荐首先为这个场景单独建立一个lua文件,便于以后管理。然后写入以下代码:

local Scene = SceneMgr:GetClass("场景名", 1)
Scene.property = {} --场景属性,如是否可接受触摸事件,是否可拖动,是否可缩放等

function Scene:_Uninit( ... )
 -- body
end

function Scene:_Init( ... )
 -- body
end

function Scene:OnCocosButtonEvent(ui_name, button_name, event)
    --body
end

这样一个基本的场景模版就创建好了,在需要加载的时候只需要调用 SceneMgr:LoadScene(scene_name) 这个接口即可加载这个场景,如果是游戏世界第一次加载场景则需要调用 SceneMgr:FirstLoadScene(scene_name)

小谈通货膨胀--纸币,银行与中央银行

金属货币的时代过去,接下来纸币出现了。
首先我有一个很大的疑问,既然货币是以铸造成本决定价值,为什么在造纸术普及之后纸币还会具有价值呢?
这里就要说纸币是如何出现的了。金属货币最大的不便就是每次出行都要带大量的货币,很重很不方便。所以出现了早期的钱庄帮你保管它们,同时给你开他们的仓单(也就是电视里经常提到的银票),只要提供仓单就可以去他们管辖区域的网点取出对应的货币,钱庄通过在提取真实货币的时候收取一定服务费存活(其实就可以理解为一个区域联网的货币仓库)。钱庄的出现,于是人们发现交易的时候不用交易金银,交易仓单就好了,其实这就是早期的纸币,如我国宋朝时期的“交子”。

继续阅读

小谈通货膨胀--早期的金属货币

前几日去西电玩的时候,在图书馆借了本书,讲通货膨胀的,看完有种茅塞顿开的感脚,趁着还记得把一些所思所想写下来。说来惭愧,虽然是财经学校毕业的,但是在校期间一点经济相关的知识都没学,这篇文章要是写的有啥不对,还望各位同学给予指正。

什么是通货膨胀?
流通的货币代表的价值量超过了市场上商品的价值总量,从而造成货币贬值。

那货币是怎么诞生的呢?
最早的交换媒介是金属,但是这个交易起来有个很麻烦的问题,那就是每次都要称量,于是出现了铸币。铸币就是按照制定规格去铸造钱币,每个都代表指定的重量。但是这样有个问题,铸币是会磨损的,磨损后就没有以前的重量了怎么办?于是就得有个组织出来打包票说,你放心的用我铸的币,就算磨损了在我这也是按足值算,而一般扮演这样角色的是国家。比如中国最早的统一货币秦朝,就用的半两钱,代表这枚钱币重半两,包括后来的汉朝的五铢钱也是。

继续阅读