Cocos2d-x mruby binding
Cocos2d-xのmruby bindngを開発しています。
iOS、Androidである程度動くようになったので公開しました。
https://github.com/tkyaji/cocos2d-ruby
使い方
上記のgithubリポジトリからcloneしてください。
$ git clone https://github.com/tkyaji/cocos2d-ruby
あとは通常のCocos2d-xの使い方と同じです。
setup.py
スクリプトを実行し、環境変数をロードします。
$ cd cocos2d-ruby
$ python setup.py
$ source ~/.bash_profile
cocos new
コマンドでプロジェクトを作ります。
-l
オプションでruby
を指定すると、mruby bindingのプロジェクトができます。
$ cocos new MyGame -l ruby
なお、Cocos2d-x本家のリポジトリからforkしているので、C++やLuaも使用できます。
HelloWorld
生成したプロジェクトで、そのままcocos run
を実行すると、HelloWorldのサンプルが起動します。
$ cocos run -p ios
$ cocos run -p android
中身はC++版のHelloWorldを、rubyで書き換えたものです。
require "HelloWorld"
def main
# size define
resources = {
small: {
size: {w: 480, h: 320},
directory: "res/iphone"
},
medium: {
size: {w: 1024, h: 768},
directory: "res/ipad"
},
large: {
size: {w: 2048, h: 1536},
directory: "res/ipadhd"
}
}
design_resolution_size = resources[:small][:size]
director = CC::Director.get_instance
glview = director.get_open_glview
if ! glview
glview = CC::GLViewImpl.create("Ruby Empty Test")
director.set_open_gl_view(glview)
end
glview.set_design_resolution_size(design_resolution_size[:w], design_resolution_size[:h], ResolutionPolicy.NO_BORDER)
frame_size = glview.get_frame_size
ssize = resources[:small][:size]
msize = resources[:medium][:size]
target_res = resources[:small]
if frame_size.height > msize[:h]
target_res = resources[:large]
elsif frame_size.height > ssize[:h]
target_res = resources[:medium]
end
target_size = target_res[:size]
director.set_content_scale_factor([target_size[:h] / design_resolution_size[:h], target_size[:w] / design_resolution_size[:w]].min)
futils = CC::FileUtils.get_instance
futils.add_search_path(target_res[:directory])
director.set_display_stats(true)
director.set_animation_interval(1.0 / 60)
scene = HelloWorld.scene
director.run_with_scene(scene)
end
main
class HelloWorld < CC::Layer
include CC
TITLE_FONT_SIZE = 20;
def self.scene
# 'scene' is an autorelease object
scene = Scene.create
# 'layer' is an autorelease object
layer = HelloWorld.create
#add layer as a child to scene
scene.add_child(layer)
# return the scene
return scene
end
def initialize
init
end
def init
director = Director.get_instance
visible_size = director.get_visible_size
visible_vec2 = Vec2.new(visible_size.width, visible_size.height)
origin = director.get_visible_origin
# 1. add a menu item with "X" image, which is clicked to quit the program
# you may modify it.
# add a "close" icon to exit the progress. it's an autorelease object
close_item = MenuItemImage.create("CloseNormal.png", "CloseSelected.png", Proc.new {|sender|
p "Exit button clicked"
})
content_size = close_item.get_content_size
content_vec2 = Vec2.new(content_size.width, content_size.height)
close_item.set_position(origin + visible_vec2 - content_vec2 / 2)
# create menu, it's an autorelease object
menu = Menu.create(close_item)
menu.set_position(Vec2.ZERO)
self.add_child(menu, 1)
# 2. add your codes below...
# add a label shows "Hello World"
# create and initialize a label
label = Label::create_with_system_font("Hello World", "Arial", TITLE_FONT_SIZE)
# position the label on the center of the screen
label.set_position(origin.x + visible_size.width / 2, origin.y + visible_size.height - label.get_content_size.height)
# add the label as a child to this layer
self.add_child(label, 1)
# add "HelloWorld" splash screen"
sprite = Sprite.create("HelloWorld.png")
# position the sprite on the center of the screen
tmp_size = visible_size / 2
sprite.set_position(Vec2.new(tmp_size.width, tmp_size.height) + origin)
# add the sprite as a child to this layer
self.add_child(sprite)
end
end
main.rbに書いてある処理は、実際はAppDelegate.cppに書いた方が良いと思いますが、
サンプルなのであえてRuby側に書いています。
メソッド名はスネークケースに、isXXX
はXXX?
に変換しています。
(binding-generator実行時の設定で、この変換は無効化して生成できます)
コールバックはProc
で実装します。
メモリ管理
Lua Bindingでは、C++と同様、状況によってはretain、releaseでリファレンスカウンタを操作する必要があります。
mruby Bindingでは、retain、releaseは不要で、Ruby側で全て管理してくれるように実装しています。
具体的には、retain、releaseが呼び出された際に、mrubyでラップしたインスタンスだった場合、
C++のリファレンスカウンタ(RC)は増やさずに、代わりにRuby側に作ったRCをインクリメントしているイメージです。
Ruby側のRCが0になったタイミングで、C++側のRCをデクリメント(つまりC++の元のrelease処理)を実行し、
インスタンスがdeleteされるようにしています。
この辺の処理は、Ref.cpp、RubyEngine.cpp で実装しています。
正直、今の実装で問題ないかまだ少し心配なので、この場合にダメそうとか、ツッコミをもらえると嬉しいです
エディタ
LuaやJSの場合、Cocos Code IDEを使った効率の良い開発を行えますが、mruby bindingは当然対応していません。
しかしそれだと不便なので、mruby binding用のSublime Textプラグインを作りました。
CocosRubyEditor
これを使うと以下のように自動補完が行えます。
Package Controlに登録したため、"CocosRubyEditor"で検索すると出て来るはずです。
定数等、現状では補完されないものがありますが、そのうち対応する予定です。
TODO
未対応のクラスに対応する
cocos new
でプロジェクトを作る時に、mrubyのgemを追加できるようにする
rubycompileコマンドの実装(バイトコード化と暗号化)
ruby-testプロジェクトの実装
ドキュメント生成する
ios / Android / Mac 以外のプラットフォームに対応
未対応のクラスに対応する
cocos new
でプロジェクトを作る時に、mrubyのgemを追加できるようにする
rubycompileコマンドの実装(バイトコード化と暗号化)
ruby-testプロジェクトの実装
ドキュメント生成する
ios / Android / Mac 以外のプラットフォームに対応
使ってみてもらえると嬉しいです。
以上。
Author And Source
この問題について(Cocos2d-x mruby binding), 我々は、より多くの情報をここで見つけました https://qiita.com/tkyaji/items/cbd1c15efcd025925dc0著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .