luaノードイベントの呼び出し

環境はcocos2d-x 3.15 + Xcode v7.3.1 + macOS Sierra v10.12.4です。

cocos2d-xのc++プロジェクトではonEnter()を呼び出させるには、それを以下のようにオーバーライドすれば良いですが、
virtual void onEnter() override;
luaは以下のようにイベントハンドラーを登録する必要があります。

function GameScene:onCreate()
    local function onNodeEvent(event)
        if event == "enter" then
            self:onEnter()
        elseif event == "enterTransitionFinish" then
            self:onEnterTransitionFinish()
        elseif event == "exit" then
            self:onExit()
        elseif event == "cleanup" then
            self:onCleanup()
        end
    end
    self:registerScriptHandler(onNodeEvent)
end
	

これだと、Viewごとに登録する必要があります。よくこういったところに処理を追加するのであれば、src/packages/mvc/ViewBase.luaにある以下のコードを真似して
if self.onCreate then self:onCreate() end
以下のように追加すれば、各ビューで登録せずに呼ばれていいではないでしょうか。

    if self.onEnter then
        local function onNodeEvent(event)
            if event == "enter" then
                self:onEnter()
            end
        end
        self:registerScriptHandler(onNodeEvent)
    end
    if self.onEnterTransitionFinish then
        local function onNodeEvent(event)
            if event == "enterTransitionFinish" then
                self:onEnterTransitionFinish()
            end
        end
        self:registerScriptHandler(onNodeEvent)
    end
    if self.onExit then
        local function onNodeEvent(event)
            if event == "exit" then
                self:onExit()
            end
        end
        self:registerScriptHandler(onNodeEvent)
    end
    if self.onCleanup then
        local function onNodeEvent(event)
            if event == "cleanup" then
                self:onCleanup()
            end
        end
        self:registerScriptHandler(onNodeEvent)
    end

cocos2d-luaでAndroidの戻るボタンを制御

環境はcocos2d-x 3.15 + Xcode v7.3.1 + macOS Sierra v10.12.4です。

cocos2d-luaでAndroidの戻るボタン(back key)に応答するには、以下のをonEnter()に追加すると反応するはずです。

    local function onKeyReleased(keyCode, event)
        if keyCode == cc.KeyCode.KEY_ESCAPE then
            print("back")
            -- cc.Director:getInstance():endToLua()
        end
    end

    local listener = cc.EventListenerKeyboard:create()
    listener:registerScriptHandler(onKeyReleased, cc.Handler.EVENT_KEYBOARD_RELEASED)

    local eventDispatcher = self:getEventDispatcher()
    eventDispatcher:addEventListenerWithSceneGraphPriority(listener, self)

実は上記のコードをonCreate()に入れたことで、戻るボタンを押しても反応しないことで悩みました。
ネットで調べると、似たような問題に直面した人がいたようですが、解決方法がありませんでした。
公式サンプルをよく見ると、onEnter()の呼び出しのタイミングに入れてるので、もしかしたらと思い、結果、図星でした。
そのため、反応しないなぁと思ったら、追加の場所を確認してください。

ちなみに、onEnter()やonEnterTransitionFinish()イベントを呼ばさせるには別途実装が必要ですので、luaノートイベントの呼び出しを参考してください。

Windows 10 Update Error 0x800705b4

Windows 10のUpdateで下記のエラーが発生しました。
2017-05 x64 ベース システム用 Windows 10 Version 1607 の累積更新プログラム (KB4019472)
エラーコード: 0x800705b4

私の場合、参考サイトの通り、Windows Update画面の「詳細オプション」をクリックして下記スクリーンショットの「Windowsの更新時に他のMicrosoft製品の更新プログラムも入手します。」をチェックすると、無事アップデートができました。

参考

Fixing Windows 10 Update Error 0x800705b4

sdkbox import googleanalyticsのlocaleエラー

sdkboxを利用してGoogle Analyticsを実装する際に、以下のエラーに恵まれました。

$ sdkbox import googleanalytics
Traceback (most recent call last):
  File "monolith.py", line 2556, in 
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/locale.py", line 543, in getdefaultlocale
    return _parse_localename(localename)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/locale.py", line 475, in _parse_localename
    raise ValueError, 'unknown locale: %s' % localename
ValueError: unknown locale: UTF-8

解決方法は~/.bash_profileに以下の2行を追加:
export LANG=en_US.UTF-8
unset LC_CTYPE


そして、以下のを実行して(‘en_US’, ‘UTF-8’)が出れば問題解決のはずです。

source ~/.bash_profile
python
>>> import locale
>>> locale.getdefaultlocale()

最後に、再度sdkbox import googleanalytics実行して

  _______ ______  _     _ ______   _____  _     _
  |______ |     \ |____/  |_____] |     |  \___/ 
  ______| |_____/ |    \_ |_____] |_____| _/   \_
 Copyright (c) 2016 SDKBOX Inc. v1.0.1.22
 test speed of hosts...
 - test host main: 463.11KB/s.
 - test host china: 38.19KB/s.
 choose the fastest server 'main', speed is 463.11KB/s.
 downloading package sdkbox-googleplayservices_v2.3.13.5.tar.gz
[###################################] 100%
 Installation Successful :)
 downloading package sdkbox-googleanalytics_v2.3.13.5.tar.gz
[###################################] 100%
 Please reference the online documentation to finish the integration:
http://sdkbox-doc.github.io/en/plugins/googleanalytics/v3-lua/
 Installation Successful :)

になるかと。

参考

https://github.com/matplotlib/matplotlib/issues/5420/

luaにカスタマイズのc++クラスを使う

cocos2d-xのライブラリにカスタマイズのc++クラスを追加し、luaから呼び出せる方法です。
環境はcocos2d-x 3.15 + Xcode v8.3.2 + macOS Sierra v10.12.4です。注1

  1. クラスを作成

    1. プロジェクトルート/frameworks/cocos2d-x/cocos/の下にcustom(任意)というフォルダを作成
    2. customの下にc++のクラスGameData(任意)を作成
    3. Xcodeでプロジェクトを開き、追加したクラス(フォルダごと)をcocos2d_libs.xcodeprojの直下に追加
  2. binding用設定ファイルを作成

    1. プロジェクトルート/frameworks/cocos2d-x/tools/tolua/の下にある比較的簡単な設定ファイルcocos2dx_csloader.iniをコピーしてcustom_game_data.iniにリネーム
    2. custom_cpp.iniを開き、下記のように変更を加え
      • genbinding.pyに使う名前を変更
        [cocos2dx_csloader] を
        [custom_game_data] に変更
      • 自動生成されるc++ブリッジ関数の接頭語
        prefix = cocos2dx_csloader を
        prefix = custom_game_data に変更
      • lua用のモジュール接頭語(ネームスペースと似たもの)
        target_namespace = cc を
        target_namespace = に変更(ネームスペースが必要なければccを削除 ※注2)
      • 生成したc++クラスのヘッダー位置
        headers = %(cocosdir)s/cocos/editor-support/cocostudio/ActionTimeline/CSLoader.h を
        headers = %(cocosdir)s/cocos/custom/GameData.h に変更
      • luaで使うためのクラスですので、スキップする関数はないはず。
        skip = CSLoader::[nodeFromXML nodeFromProtocolBuffers createTimeline nodeWithFlatBuffers createActionTimelineNode createNodeWithDataBuffer createTimelineWithDataBuffer ^createNode$] を
        skip = に変更
    3. プロジェクトルート/frameworks/cocos2d-x/tools/tolua/genbindings.pyを開き、141行あたりにあるcmd_argsキーの最後に上記のcustom_game_data.iniを追加
      ‘custom_game_data.ini’ : (‘custom_game_data’, ‘lua_custom_game_data_auto’), \
      ※もし2番めのパラメーター’custom_game_data’がiniファイル1行目に定義された名前と一致しなければ、Section not found in config file的なエラーができます。
    4. 以下のようにgenbindings.pyを実行してc++のブリッジクラスを生成
      python genbindings.py
      ※ImportError: No module named yamlというようなエラーが出た場合、genbindings.pyと同ディレクトリにあるREADMEを参考にして、以下のコマンドで必要なモジュールをインストール

      • sudo easy_install pip
      • sudo pip install PyYAML
      • sudo pip install Cheetah


      こうすれば、プロジェクトルート/frameworks/cocos2d-x/cocos/scripting/lua-bindings/auto/の下に、lua_custom_game_data_auto.hppとlua_custom_game_data_auto.cppが生成されます。
      c++クラスの関数名変更するたびに、このステップを再実行する必要があります。

  3. 生成されたファイルをプロジェクトに追加

    1. 自動生成されたlua_custom_game_data_auto.hppとlua_custom_game_data_auto.cppをXcodeのプロジェクトのcocos2d_lua_bindings.xcodeproj/autoの直下に追加
    2. cocos2d_lua_bindings.xcodeproj/CCLuaStack.cppに今回追加したクラスへの参照を追加
      #include "scripting/lua-bindings/auto/lua_custom_game_data_auto.hpp"
      同ファイルのbool LuaStack::init(void)関数に新しいクラスを登録
      register_all_custom_game_data(_state);
    3. Android向けに、プロジェクトルート/frameworks/cocos2d-x/cocos/scripting/lua-bindings/proj.android/Android.mkの140行あたりに以下のようにソースファイル参照を追加
      LOCAL_SRC_FILES += ../../../custom/GameData.cpp \
        ../auto/lua_custom_game_data_auto.cpp \
  4. リビルド

    1. プロジェクトをリビルドすれば、luaで以下のように使えるはずです。
      local gameData = GameData:new()
      gameData:getName() --仮にgetName()を実装したとして

※注1: 現時点Xcode8以上のバージョンだと、luaのプロジェクトはiOSシミュレーター上で動きません。
Xcode7以前のバージョンを使うか、iPhone実機もしくはmac(***-desktopプロジェクト)でデバッグ必要があります。
参考:https://github.com/cocos2d/cocos2d-x/issues/17043

2017/05/29追記:上記ページに紹介されたように、luajitをアップデートすれば実行できます。
具体的には、https://github.com/cocos2d/cocos2d-x-3rd-party-libs-bin/blob/v3/lua/luajit/prebuilt/ios/libluajit.aをダウンロードして、プロジェクトルート/frameworks/cocos2d-x/external/lua/luajit/prebuilt/ios/libluajit.aと置き換えれば良いです。

※注2: target_namespaceを指定すれば、ネームスペースをppと仮定して下記の作業が必要になります。

  1. custom_game_data.iniにcpp_namespace = ppを追加
    ※そうしなければ、クラスに定義した関数にもかかわらず、CCLuaStack.cpp: error: undefined reference to的なエラーが出ます。
  2. プロジェクトルート/frameworks/cocos2d-x/tools/bindings-generator/targets/lua/conversions.yamlの20行あたりにあるns_map:のキーの一番最後に
    "pp::": "pp."
    を追加
    ※そうしなければ、The namespace (%s) conversion wasn’t set in ‘ns_map’ section of the conversions.yaml” % namespace_class_nameというようなエラーができます。

参考