[RubyMotion] cocos2dをRubyMotionで使ってみた(迷宮編)

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.mRootViewController.mHelloWorldLayer.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.rbEAGLView.viewWithFrameEAGLView viewWithFrame:pixelFormat:depthFormat:がRuby側から見えてないようです.



RubyMotionでは,定義を参照するために,gen_bridge_metadataというのを使って*.bridgesupportというファイルを作っています.



しかし,Rakefileで指定した:headers_dir => "cocos2d"の直下しか見ずにgen_bridge_metadataをしているようです.
しかし,それだとcocos2d/Platforms/iOSとかの下の定義が参照出来ずにエラーになっているようです.
EAGLView.hcocos2d/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/iOScocos-2d-iphone直下に持ってきてrakeするとかアドホックな方法で成功はしているらしいですが,cocos2dのソース側も色々とPath変更をしていたりでめんどくさそうでやりたくないです.



というわけで,まだ問題は解決出来ていないです.

0 comments: