Cocos2d-x mruby binding
iOS, Android인 어느 정도 움직이게 되었기 때문에 공개했습니다.
htps : // 기주 b. 코 m / t Kage / 여기 s2d-by
사용법
위의 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로 재작성한 것입니다.
main.rbrequire "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
HelloWorld.rbclass 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++의 원래의 릴리즈 처리)를 실행해,
인스턴스가 삭제되도록합니다.
이 변의 처리는, Ref.cpp , RubyEngine.cpp 로 구현하고 있습니다.
솔직히, 지금의 구현에 문제 없거나 아직 조금 걱정이므로, 이 경우에 안 되든가, 츳코미를 받을 수 있으면 기쁩니다
에디터
Lua나 JS의 경우 Cocos Code IDE를 사용한 효율적인 개발을 할 수 있지만, mruby binding은 당연히 대응하고 있지 않습니다.
그러나 그것이 불편하기 때문에, mruby binding 용 Sublime Text 플러그인을 만들었습니다.
CocosRubyEditor
이것을 사용하면 다음과 같이 자동 완성이 가능합니다.
Package Control에 등록했기 때문에, "CocosRubyEditor"로 검색하면 나올 것입니다.
정수 등, 현재 상태에서는 보완되지 않는 것이 있습니다만, 그 중 대응할 예정입니다.
TODO
$ git clone https://github.com/tkyaji/cocos2d-ruby
$ cd cocos2d-ruby
$ python setup.py
$ source ~/.bash_profile
$ cocos new MyGame -l ruby
생성한 프로젝트에서 그대로
cocos run
를 실행하면 HelloWorld 샘플이 시작됩니다.$ cocos run -p ios
$ cocos run -p android
내용은 C++판의 HelloWorld를, ruby로 재작성한 것입니다.
main.rb
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
HelloWorld.rb
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++의 원래의 릴리즈 처리)를 실행해,
인스턴스가 삭제되도록합니다.
이 변의 처리는, Ref.cpp , RubyEngine.cpp 로 구현하고 있습니다.
솔직히, 지금의 구현에 문제 없거나 아직 조금 걱정이므로, 이 경우에 안 되든가, 츳코미를 받을 수 있으면 기쁩니다
에디터
Lua나 JS의 경우 Cocos Code IDE를 사용한 효율적인 개발을 할 수 있지만, mruby binding은 당연히 대응하고 있지 않습니다.
그러나 그것이 불편하기 때문에, mruby binding 용 Sublime Text 플러그인을 만들었습니다.
CocosRubyEditor
이것을 사용하면 다음과 같이 자동 완성이 가능합니다.
Package Control에 등록했기 때문에, "CocosRubyEditor"로 검색하면 나올 것입니다.
정수 등, 현재 상태에서는 보완되지 않는 것이 있습니다만, 그 중 대응할 예정입니다.
TODO
Lua나 JS의 경우 Cocos Code IDE를 사용한 효율적인 개발을 할 수 있지만, mruby binding은 당연히 대응하고 있지 않습니다.
그러나 그것이 불편하기 때문에, mruby binding 용 Sublime Text 플러그인을 만들었습니다.
CocosRubyEditor
이것을 사용하면 다음과 같이 자동 완성이 가능합니다.
Package Control에 등록했기 때문에, "CocosRubyEditor"로 검색하면 나올 것입니다.
정수 등, 현재 상태에서는 보완되지 않는 것이 있습니다만, 그 중 대응할 예정입니다.
TODO
cocos new
로 프로젝트를 만들 때 mruby gem을 추가 할 수 있도록 허용 사용해 주시면 기쁩니다.
이상.
Reference
이 문제에 관하여(Cocos2d-x mruby binding), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/tkyaji/items/cbd1c15efcd025925dc0텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)