RubyMotionでは外部ライブラリも使えるので,ちょっとゲームでも作ってみようかと思って,ちょうど手元にcocos2d for iPhoneレッスンノートとかがあるのでcocos2dで試してみました.
cocos2dのダウンロード・インストール
http://www.cocos2d-iphone.org/download からダウンロード
Stable Versionのcocos2d-iphone-1.0.1.tar.gz を落として解凍する.
$ motion create cocos2dTest
$ cd cocos2dTest
$ mkdir vendor
$ cp -R ~/cocos2d-iphone-1.0.1 ./vendor/cocos2d-iphone
XCodeテンプレートをインストールします.
$ cd ./vendor/cocos2d-iphone
$ sh install-templates.sh -f -u
XCodeで作れるテンプレートをRubyMotionで動くようにする
ひとまず,cocos2dを参考にコードを書きます.
Xcodeを立ちあげてFile>New>Projectをします.
テンプレート選択画面はiOS>cocos2d>cocos2dを選びます.
AppDelegate.mとRootViewController.mとHelloWorldLayer.m を参考に変換します.
./app/app_delegate.rb
class AppDelegate
def application(application, didFinishLaunchingWithOptions:launchOptions)
@window = UIWindow.alloc.initWithFrame UIScreen.mainScreen.bounds
director = CCDirector.sharedDirector
@vc = RootViewController.alloc.initWithNibName nil, bundle:nil
@vc.wantsFullScreenLayout = true
glView = EAGLView.viewWithFrame(
@window.bounds,
pixelFormat:KEAGLColorFormatRGB565,
depthFormat:0)
director.setOpenGLView glView
director.setDeviceOrientation KCCDeviceOrientationPortrait
director.setAnimationInterval 1.0/60
director.setDisplayFPS true
@vc.setView glView
@window.addSubview @vc.view
@window.makeKeyAndVisible
CCTexture2D.setDefaultAlphaPixelFormat KCCTexture2DPixelFormat_RGBA8888
CCDirector.sharedDirector.runWithScene HelloWorldLayer.scene
true
end
def application(application, willResignActive:launchOptions)
CCDirector.sharedDirector.pause
end
def application(application, didBecomeActive:launchOptions)
CCDirector.sharedDirector.resume
end
def application(application, didReceiveMemoryWarning:launchOptions)
CCDirector.sharedDirector.purgeCachedData
end
def application(application, didEnterBackground:launchOptions)
CCDirector.sharedDirector.stopAnimation
end
def application(application, willEnterForeground:launchOptions)
CCDirector.sharedDirector.startAnimation
end
def application(application, willTerminate:launchOptions)
director = CCDirector.sharedDirector.
director.openGLView.removeFromSuperview
@vc.release
@window.release
director.end
end
def application(application, significantTimeChange:launchOptions)
end
end
./app/root_view_controller.rb
class RootViewController < UIViewController
end
./app/hello_world_layer.rb
class HelloWorldLayer < CCLayer
def self.scene
scene = CCScene.node
layer = HelloWorldLayer.node
scene.addChild layer
scene
end
def init
super
@label = CCLabelTTF.labelWithString(
"Hello World",
fontName:"Marker Felt",
fontSize: 64)
size = CCDirector.sharedDirector.winSize
@label.position = [size.width/2, size.height/2]
self.addChild @label
self
end
end
Rakefileの設定
外部ライブラリを使う場合は,Rakefileの編集が必要.
vendorの設定と,OpenGLESやAVFoundationなどのframeworkの設定や依存ライブラリの設定です.
Rakefile
$:.unshift("/Library/RubyMotion/lib")
require 'motion/project'
Motion::Project::App.setup do |app|
# Use `rake config' to see complete project settings.
app.name = 'cocos2dTest'
app.vendor_project("vendor/cocos2d-iphone",
:xcode,
:xcodeproj => "cocos2d-ios.xcodeproj",
:target => "cocos2d",
:products => ["libcocos2d.a"],
:headers_dir => "cocos2d")
app.frameworks += [
"OpenGLES",
"OpenAL",
"AVFoundation",
"AudioToolbox",
"QuartzCore"]
app.libs << "/usr/lib/libz.dylib"
app.interface_orientations = [:landscape_right]
end
vendor_project で外部ライブラリのパスを指定し,2つ目の引数を:xcodeにしてxcode projectを指定します.
.aで提供されている場合は,:staticにすると良いです.
RubyMotionでの詰まりどころ
本来なら,ここでrakeすればcocos2dがビルドされて,app内がビルドされて無事に動くのですが,
Objective-C stub for message `viewWithFrame:pixelFormat:depthFormat:' type `@@:{CGRect={CGPoint=ff}{CGSize=ff}}@I' not precompiled. Make sure you properly link with the framework or library that defines this message.
というエラーが出てシミュレータが終了してしまいました.
これは,./app/app_delegate.rbのEAGLView.viewWithFrameでEAGLView viewWithFrame:pixelFormat:depthFormat:がRuby側から見えてないようです.
RubyMotionでは,定義を参照するために,gen_bridge_metadataというのを使って*.bridgesupportというファイルを作っています.
しかし,Rakefileで指定した:headers_dir => "cocos2d"の直下しか見ずにgen_bridge_metadataをしているようです.
しかし,それだとcocos2d/Platforms/iOSとかの下の定義が参照出来ずにエラーになっているようです.
(EAGLView.hはcocos2d/Platforms/iOSの下にあります.)
そのため,/Library/RubyMotion/lib/motion/project/vendor.rb を編集するか,自分でcocos2d-iphone.bridgesupportファイルを生成する必要があります.
ひとまず,bridgesupportを生成するスクリプトを走らせることにしました.
def sh(command)
system(command)
end
path = Dir.getwd
source_files = Dir.glob('**/*.{c,m,cpp,cxx,mm,h}')
headers = source_files.select { |p| File.extname(p) == '.h' }
bs_files = []
unless headers.empty?
bs_file = File.basename(path) + '.bridgesupport'
if !File.exist?(bs_file) or headers.any? { |h| File.mtime(h) > File.mtime(bs_file) }
includes = headers.map { |p| "-I" + File.dirname(p) }.uniq.join(' ')
sh "/usr/bin/gen_bridge_metadata --format complete --no-64-bit --cflags \"-I. #{includes}\" #{headers.join(' ')} -o \"#{bs_file}\""
end
bs_files << bs_file
end
そして,改めてrakeします.
同じエラーが出ました.orz.
一応,生成されたbridgesupportを見ても確かに元のものよりは定義が増えているのですが,EAGLViewに関するものが増えておらず,ダメなようです.
cocos2dのForumを見ると,cocos2d-iphone/cocos2d/Platform/iOSをcocos-2d-iphone直下に持ってきてrakeするとかアドホックな方法で成功はしているらしいですが,cocos2dのソース側も色々とPath変更をしていたりでめんどくさそうでやりたくないです.
というわけで,まだ問題は解決出来ていないです.

0 comments:
コメントを投稿