Sloppy's Blog


  • Home

  • About

  • Archives
Sloppy's Blog

NodeJS连接Redis

Posted on 2016-08-11

Redis服务器

  • 我们下载最新的redis进行编译(http://redis.io/)
  • 我是在MacOSX上进行编译的,打开终端,切换到下载目录,运行tar命令进行解压
  • cd到redis目录,运行:make && make install
  • 启动Redis服务器,运行命令:redis-server redis.conf (我修改了conf文件里的bind,默认是127.0.0.1,我修改成了一个内网地址,因为我将在Windows上编写NodeJs进行连接操作)

NodeJS

  • 下载安装NodeJs(http://nodejs.org)
  • 安装redis module,运行命令:npm install -g redis
  • 在D盘目录创建文件夹:redis,新建NodeJS文件:test.js,内容如下:

      // redis 链接
      var redis   = require('redis');
      var client  = redis.createClient('6379', '10.10.10.88');// 内网IP地址
      // redis 链接错误
      client.on("error", function(error) {
          console.log(error);
      });
      client.on("connect", runSample);
      function runSample() {
          // Set a value
          client.set("foo", "Hello World", function (err, reply) {
             console.log(reply.toString());
          });
          // Get a value
          client.get("foo", function (err, reply) {
              console.log(reply.toString());
              //client.quit();
          });
      }
      
  • 打开命令行,切换到D:\redis,运行命令:node test.js (可以会提示找不到redis module的错误,那先运行命令:node link redis)

是不是在终端打印出现我们想要的信息了

Sloppy's Blog

基本的Git命令添加本地文件及代码到Github

Posted on 2016-07-28

我们有时候,需要将一些本地的代码,或者工具代码,添加到Github上进行备份。或者Share给其他的朋友,这里,我们就需要添加本地代码到github的repositories.这里我们分几个简单步骤来实现

1, 下载windows客户端,mac用户可以省略,自带了下载windows客户端。

2, 参加之前的设置,生成本地本限的账户:Git的一些相关设置及操作命令

3, 登陆Github.com,创建一个新的repository.记住地址

4,如果本地以前没有Push过文件,参照如下的步骤

* git init #初始化
* git add README.md #添加说明文件,如果本地有。可以省略。如果要添加所有文件,可以git add .
* git commit -m "first commit" #添加上传说明
* git remote add origin git@github.com:coolexp/CustomTools.git # 添加到远程关联你的res,换成对应的自己的git res
* git push -u origin master # 上传到远程

如果之前push过。可以省略第一步
Sloppy's Blog

Cocos2d-x Console使用

Posted on 2016-07-20

从cocos2d-x 3.0开始。cocos2d-x提供了一个不错的功能,Console,可以通过命令终端进行一些对游戏的调试,测试,控制,下面我们来看看具体怎么使用,

新建项目

  • 运行命令行 cocos new ConsoleTest -l cpp -d c:\cocos 的命令,创建一个空的项目,
  • 修改AppDelegate.cpp的applicationDidFinishLaunching部分,在最后添加如下代码:

    Director::getInstance()->getConsole()->listenOnTCP(5678);

下面,我们来演示,从游戏内输出到电脑终端的功能,方便进行调试
在游戏需要的地方,在关闭按钮添加如下代码,去掉关闭功能,添加代码,Director::getInstance()->getConsole()->log(“Click Me\n”);我们可以认为,如果终端输出click me,说明游戏执行到此地方了,如果没有输出,就说明程序出bug了,进而进行代码的排错,调试

我这里运用的是mac系统,打开命令行,进行如下操作:

  • 连接游戏,命令行输入:nc localhost 5678
  • 接着输入:debugmsg on
  • touch游戏中的关闭按钮,终端上是不是显示出来了?

扩展

当然我们可以,参加Console类,添加command,可以对游戏的一些控制功能,当然,最后调用cocos2d-x的类操作,建议通过Director::getInstance()->getScheduler()->performFunctionInCocosThread,送到GL线程进行执行。
当然,对应的手机调试,请把localhost换成对应的手机ip地址,确保手机跟电脑在同一个局域网内

Mac自带nc命令,windows用户下载:@下载nc

Sloppy's Blog

NodeJS C++扩展入门(1)

Posted on 2016-07-20

环境的准备

  • NodeJS本身的安装
  • NodeJS的c++扩展是借助node-gyp进行编译的,所以我们需要安装node-gyp,在命令行下输入:npm install node-gyp -g(可能需翻墙)

新建一个文件夹,作为我们的主目录,这里我们新建一个hello目录,

  • 编写binding.gyp文件,内容如下:
          {
            'targets': [
              {
                'target_name': 'hello',
                'sources': [
                    'src\hello.cc'
                ]
              }
            ]
          }
      
  • 编写cpp文件,我们取名叫hello.cc吧,内容如下:
  •   include 
      include 
      using v8::FunctionCallbackInfo;
      using v8::Isolate;
      using v8::Local;
      using v8::Object;
      using v8::String;
      using v8::Value;
      void Method(const FunctionCallbackInfo& args) {
          Isolate* isolate = args.GetIsolate();
          args.GetReturnValue().Set(String::NewFromUtf8(isolate, "Hello world"));
      }
      void init(Local exports) {
          NODE_SET_METHOD(exports, "hello", Method);
      }
      NODE_MODULE(hello, init)
      

编译

在Hello目录位置打开命令行:输入命令:node-gyp configure build,不出意外,一会显示ok字样

编写test.js进行测试:


const addon = require(‘./build/Release/hello.node’);
console.log(addon.hello()); // ‘Hello world’

在命令行输入:node test.js 打印出 ‘Hello world’

参考资料:https://nodejs.org/dist/latest-v4.x/docs/api/addons.html

Sloppy's Blog

Cocos2d-x Lua添加自定义回调方法,配置自定义的manual方法

Posted on 2016-07-15

在cocos2d-x Lua开发过程中,有时候会遇到自己的类需要调用Lua的方法,也就是说在c++类文件中,执行Lua的方法,可是直接在c++类里,设置LUA_FUNCTION回调方法,会导致genbindings.py出现error,这主要是由于需要引用lua.h文件,象下面这样(基于上篇的lua调用c++编译):

添加新的自定义类文件

新建CESprite.h,CESprite.cpp文件,新建内容如下:

// 添加头文件
class CESprite :public cocos2d::Sprite {
public:
    static CESprite* createWithData(const std::string& file);
    virtual void onEnter();
};
CESprite.cpp:
// 添加头文件 "CESprite.h"
// 添加头文件"scripting/lua-bindings/manual/CCLuaEngine.h"

using namespace cocos2d;

CESprite* CESprite::createWithData(const std::string& file) {
    CESprite* sp = new CESprite();
    sp->initWithFile(file);
    sp->autorelease();
    return sp;
}

void CESprite::onEnter() {
    Sprite::onEnter();
    // 执行回调
}

添加Lua回调方法

修改代码如下:

class CESprite :public cocos2d::Sprite {
public:
    static CESprite* createWithData(const std::string& file);
    virtual void onEnter();
    void setLuaHandler(LUA_FUNCTION handler);
private:
    LUA_FUNCTION handler;
};
运行genbindings.py,报错,出现lua.h找不到,可能有的朋友们,尝试将LUA_FUNCTION改成int,genbindings.py此时也能成功,但是运行后会出现nil value错误,Lua下面这样的调用:
local function cpp_call(msg)
    print("cpp_call")
    print(msg)
end
local sp = CESprite:createWithData("res/diamond3.png")
sp:setLuaHandler(cpp_call)

运行报错,怎么办?修改生成的lua_coolexp_auto.cpp里的setLuaHandler方法把arg0的获取修改成这样:
LUA_FUNCTION arg0 = toluafix_ref_function(tolua_S, 2, 0);运行,成功,并获取预期结果,可是还有问题,每个都会自动生成,每次都要去个性,太麻烦了,有没有更好的解决方法呢?答案是有,我们编写自己的manual,这里面我们可以参考cocos2d_manual.cpp.

添加动态的Lua方法,新建自己的lua_coolexp_manual.hpp文件

  • 去掉设置setLuaHandler的回调方法
    class CESprite :public cocos2d::Sprite {
    public:
      static CESprite* createWithData(const std::string& file);
      virtual void onEnter();
    };
    

添加执行回调Lua方法:
CESprite.cpp:

// 添加头文件 "CESprite.h"
// 添加头文件"scripting/lua-bindings/manual/CCLuaEngine.h"

using namespace cocos2d;

CESprite* CESprite::createWithData(const std::string& file) {
    CESprite* sp = new CESprite();
    sp->initWithFile(file);
    sp->autorelease();
    return sp;
}

void CESprite::onEnter() {
    Sprite::onEnter();
    // 执行回调
    LUA_FUNCTION handler = ScriptHandlerMgr::getInstance()->getObjectHandler((void*)this, ScriptHandlerMgr::HandlerType::EVENT_CUSTIOM);
    if (handler != 0) {
        // 第一种调用方法
        cocos2d::CommonScriptData data(handler, "Hello Lua");
        cocos2d::ScriptEvent scriptEvent(cocos2d::kCommonEvent, &data);
        cocos2d::LuaEngine::getInstance()->sendEvent(&scriptEvent);
        // 第二种调用方法
        cocos2d::LuaEngine::getInstance()->getLuaStack()->clean();
        cocos2d::LuaEngine::getInstance()->getLuaStack()->pushString("From CPP call lua");
        cocos2d::LuaEngine::getInstance()->getLuaStack()->executeFunctionByHandler(handler, 1);
        cocos2d::LuaEngine::getInstance()->getLuaStack()->clean();
    }
}
Lua的文件,就是上面的不变,可以添加在MainScene.lua里 * 在scripting目录下添加lua_coolexp_manual.hpp,lua_coolexp_manual.cpp文件,文件参考下载[@下载参考文件](data/lua_coolexp_manual.zip),具体的内容就不说明了。应该都能看得懂 * 最后在AppDelegate.cpp添加如下代码,注意顺序不要错了
 //register custom function
//LuaStack* stack = engine->getLuaStack();
register_all_coolexp(stack->getLuaState()); // 第一步
register_all_coolexp_manual(stack->getLuaState());// 第二步
  • 项目结构如下:
    HelloLuaGame
Sloppy's Blog

cocos2d-x绑定lua调用c++类

Posted on 2016-07-15

继上个cocos2d绑定js调用C++原生类后,今天继续出个Lua调用C++绑定类的文章,之前项目一直是手工Copy,c++的生成Lua中间层发现好麻烦,昨天借鉴js的修改,自动生成到项目结构中,省去修改,Copy的麻烦,不过吐槽下,Lua的genbindings.py,跟Js的genbindings.py感觉可以完全统一起来吗。为什么要分成两个,而且两个文件的风格不是一个人写的吗。一个留了custom_args的接口,一个不留。希望cocos团队能改进下。好了,开始(环境变量之类的,跟之前JS项目一样,也是基于cocos2d-x 3.11.1 Windows64)
PS:我的Android NDK用android-ndk-r10e不行的。结果我只能用r9d,主要是generate.py里引用的问题。llvm的版本不对

新建项目

运行命令行:
cocos new -l lua -d c:\cocos HelloLuaGame

新建c++类文件

三个文件,ErayUIHelper.h,ErayUIHper.cpp,Eray.h
ErayUIHelper.h:

#pragma once
#include "cocos2d.h"
class ErayUIHelper {
public:
    static void log(const std::string& value, cocos2d::Node* parent);
};

ErayUIHelper.cpp的实现如下:

#include "ErayUIHelper.h"
#include "scripting/lua-bindings/manual/CCLuaEngine.h"
using namespace cocos2d;
void ErayUIHelper::log(const std::string& value, cocos2d::Node* parent) {
    CCLOG("ErayUIHelper:%s",value.c_str());
    auto sp = Sprite::create("diamond2.png");
    parent->addChild(sp);
    sp->setPosition(Vec2(300.0f, 200.0f));
    LuaEngine::getInstance()->executeGlobalFunction("call_fromcpp");
}
Eray.h的内容就非常简单。主要是以后有其他的类,也包含到这个文件中
#pragma once
#include "ErayUIHelper.h"

添加ini文件

转到cocos2d-x/tools/tolua,根据对应的ini,新建一个coolexp.ini,可以跟上篇的JS中的ini一模一样,根据上篇一样,在genbindings.py添加frameworks_root变量,同时修改bindings-generator下的generator.py文件,添加script_path,可以参考JS篇

下面重要,tolua/genbindings.py,没有,这也是我吐槽的原因,没有我们来添加吧,大概在172行左右,添加如下代码:

# 打包自己的类绑定
custom_cmd_args = {'coolexp.ini': ('coolexp', 'lua_coolexp_auto'),
}
if len(custom_cmd_args) > 0:
    # 修改打包后文件至自定义的路径,跟coolexp.ini的目录一致
    output_dir = '%s/runtime-src/Classes/custom/scripting/auto' % frameworks_root 
    for key in custom_cmd_args.keys():
        args = custom_cmd_args[key]
        cfg = '%s/%s' % (tolua_root, key)
        print 'Generating bindings for %s...' % (key[:-4])
        command = '%s %s %s -s %s -t %s -o %s -n %s' % (python_bin, generator_py, cfg, args[0], target, output_dir, args[1])
        _run_cmd(command)
对了,不要用普通的记事本,修改python文件,因为他有严格的格式。不然会因为格式报错。 命令行下 运行tolua目录下的 genbindings.py 不出意外,应该会出现succeeds字样, ## 编译项目 打开proj.win32/HelloLuaGame.sln,添加文件,lua_coolexp_auto.hpp lua_coolexp_auto.cpp 在AppDelegate.cpp里添加 register_all_coolexp(stack->getLuaState());,当前要引用头文件:lua_coolexp_auto.hpp 编译项目。好了。 ## 添加c++调用Lua部分的代码 我们在src/目录下,修改main.lua文件,添加内容:
cc.exports.call_fromcpp = function()
    print("call_from cpp")
end

运行项目,在场景上会出现一张图片,控制台会出现相关的字符打印

最后的项目结构图,应该是这样的:
HelloLuaGame

Sloppy's Blog

Cocos2d-x生成JS绑定

Posted on 2016-07-13

cocos2d-x 的JS及Lua的绑定还是比较简单的。而且官方也提供了文档,以下是lua的Lua绑定官方教程:
@查看Lua教程当然JS跟LUA是差不多的。下面我们需要在绑定之前做点准备:(我是基于Cocos2d-x 3.11.1,windows 10 64位)

准备工作

  • 下载cocos2d-x 3.11.1
  • 下载apache-ant,android-sdk,android-ndk
  • 下载python 2.7.3,Cheetah-2.4.4,PyYAML-3.11.win32-py2.7,(这里虽然我是64位操作系统,但是我用的是还是Python32位,建议朋友们也用这个版本,不然会出现奇怪的问题)
  • 运行cocos2d目录下的setup.py,设置对应的androidsdk,ndk,ant相关的root目录,设置d:\cocos2d-x-3.11.1\tools\cocos2d-console\bin Path环境变更,当然这一步可以不做,
  • 安装python,设置环境变量path:c:\Python27
  • 创建js项目,启动cmd命令行,运行命令:{cocos new -l js -d c:\cocos HelloJsGame} ,不包括大括号,创建后,HelloJsGame\frameworks\cocos2d-x\tools目录下没有bindings-generator这个目录,可以自己从cocos2d-x 3.11.1的源目录copy过来。

编写代码

打开HelloJsGame.sln,文件,新建一个类文件ErayUIHelper.h,ErayUIHelper.cpp,添加一个简单的方法:

Header file:
static void log(const std::string& value);

cpp File:
void ErayUIHelper::log(const std::string& value) {
    CCLOG("ErayUIHelper::log:%s",value.c_str());
}

开始生成绑定

  • 打开项目目录:\frameworks\cocos2d-x\tools\tojs,随便找其中一个ini文件,自己改名,我这里改成coolexp.ini,具体内容可以参考这些ini自己写,我的在这里下载@下载ini文件,这里我加了一个script_path的字段,内容是:custom/scripting/auto/,我是为了让生成的文件自动放到我的项目目录下,不然放在cocos2d-x/cocos的scripting目录下,不好管理,
  • 修改genbindings文件,添加一个变量,在原来的project_root变量下面一行,可以自己搜索,内容是:
    frameworks_root = os.path.abspath(os.path.join(os.path.dirname(file), ‘..’, ‘..’,’..’))

  • 同样修改上面的py文件,添加内容:config.set(‘DEFAULT’, ‘framework_dir’, frameworks_root)

  • 修改genbindings.py里的custom_cmd_args为:custom_cmd_args = {‘coolexp.ini’: (‘coolexp’, ‘jsb_coolexp_auto’),}
  • 修改项目下面的:frameworks\cocos2d-x\tools\bindings-generator\generator.py,在main函数里添加如下代码获取自定义目录:

      # add custom path
      scriptPath = "scripting/js-bindings/auto/"
      try:
          scriptPath = config.get(s, 'script_path')
      except:
          print "parse cocos-ini"
    
  • 在gen_opts对象里添加一键值:script_path’: scriptPath,在Generator构造函数里添加:
    self.script_path= opts[‘script_path’]

  • 修改项目目录frameworks\cocos2d-x\tools\bindings-generator\targets\spidermonkey\templates\layout_head.c第一行为:
    #include “${script_path}${out_file}.hpp”

  • 生成绑定,运行命令:genbindings.py,过一会会看见success相关的字样

修改项目

  • CPP部分:在项目里,添加,custom/scripting/auto/jsb_coolexp_auto.hpp,cpp文件,修改AppDelegate.cpp文件,在sc->start(),前添加代码:sc->addRegisterCallback(register_all_coolexp);,当前要include “custom/scripting/auto/jsb_coolexp_auto.hpp”
  • JS部分:直接在ctor构造函数里添加:ErayUIHelper.log(“from JS”);,运行项目,是不是在控制台输出了“ErayUIHelper::log:from JS”

好了,上面是演示JS调用C++,下面作为简单调用

c++调用JS

这里演示一个最快速的方法,我们在app.js文件里添加全局函数:


function callfromcpp(a,b){
cc.log(“callfromcpp:%d,%d”,a,b);
}

然后修改ErayUIHelper.log方法:


添加头文件:#include “scripting/js-bindings/manual/ScriptingCore.h”
void ErayUIHelper::log(const std::string& value, cocos2d::Node* parent) {
CCLOG(“ErayUIHelper::%s”,value.c_str());
ScriptingCore::getInstance()->evalString(“callfromcpp(2,3)”);
}

运行,是不是在控制台输出:callfromcpp 2,3
最后的项目结构图:HelloJSGame

对应的文件参考下载@下载参考文件

Sloppy's Blog

Cocos2d-x 模糊的几种写法

Posted on 2016-06-30

Cocos2d利用shader实现模糊的效果,本身自带的例子已经给出,同时,我也参考了一下网上其他的写法,因为自带的在某些Android机子上会Crash

1,example_Blur.fsh,位置test目录下

2,第二种写法:可以直接定义 vec2 v_blurTexCoords[14];
参考:http://xissburg.com/faster-gaussian-blur-in-glsl/

3,第三种写法:
参考:https://github.com/Jam3/glsl-fast-gaussian-blur

Sloppy's Blog

Hello Toml

Posted on 2016-06-17

一般的配置文件都是json,xml,YAML,etc.今天刚好又看见一个极简的TOML,顺道就写了一个简单的测试程序,做下标记

基于CPP,添加开TinyToml的头文件,这个是一个Head Only的Lib,下载地址为:https://github.com/coolexp/tinytoml
新建一个文件,Config.toml,内容如下:

    s1 = "HelloToml" # test data

测试代码:

    #include头文件
    std::string v=FileUtils::getInstance()->getStringFromFile("Config.toml");#cocos2d-x的文件帮助类,用ifstream也可以。
    std::stringstream ss(v);
    toml::internal::Parser p(ss);
    const toml::Value& vp = p.parse();
    const toml::Value* x = vp.find("s1");
    if (x && x->is()) {
        std::string valueStr = x->as();
    }

参考链接:
https://github.com/toml-lang/toml
https://github.com/mayah/tinytoml

Sloppy's Blog

cocos2d-x中的EventDispatcher慎用setEnabled

Posted on 2016-06-15

起因:这几天在Android(小米4)上测试游戏,当游戏正在加载资源场景时,如果我此时立即按下电源键锁屏,再按电源键,解锁屏,回到游戏,就会出现一个奇怪的问题,游戏内的字体糊掉了,成了一个个的小方块,部分图片及动画会出现渲染不出来。而且通过控制台可以明显看见OpenGL Error的打印。
解决:

  • 首先怀疑肯定是线程里调用了OpenGL的相关代码。经查,游戏内没有出现如些的代码。由于我们用的是cocos2d-x 3.7.1,怀疑是不是该版本的BUG,看cocos2d-x Github上的ChangeLog,搜索,Google,都找不跟这种现象的相关答案。
  • 找了半天。没有结果,而且游戏中是有的加载场景出现,有的加载场景不出现,好了,没办法。看中LogCat的输出,貌似看到区别了,游戏中我们监听了一个事件,叫EVENT_RENDERER_RECREATED,如果设置setEnable为false,所有的相关事件不会被触发,cocos底层也接收这些事件进一行一重置的工作。

我们的代码象这样:

std thread([=](){
    cocos2d::Director::getInstance()->getEventDispatcher()->setEnabled(false);
    // 加载资源代码,耗时已经久,等待加载完才执行下面语句,此时关闭电源,再开启电源回到游戏,就会出现了
    cocos2d::Director::getInstance()->getEventDispatcher()->setEnabled(true);
})
1…3456
Sloppy

Sloppy

54 posts
7 tags
© 2017 Sloppy
Powered by Hexo
Theme - NexT.Muse