CCRepeatForever は CCSequence の中では使えない
やろうとしたら BAD_ACCESS になった。
prog_guide:actions_composition - cocos2d for iPhone
IMPORTANT: CCRepeatForever is not a valid CCIntervalAction. You can't use a CCRepeatForever inside a CCSequence action.
らしい。
導入アニメしたあと、ループさせたいような場合はよくあるからこれできないと不便なきもする。
そう言うことがしたい場合は CCCallFunc
でアニメーションの終了をもらいそこで CCRepeatForever
する。CCCallBlock
っていう Blocks インタフェースあるからそれ使えばメソッド増やさなくてもいいようだ。
cocos2d の Spritesheet の Retina 対応
cocos2d ではメモリ効率よく画像リソースをあつかうために以下のような CSS Sprite っぽい画像に複数リソースを格納して使うことができる。
cocos2d 自体は 0.99.5 から Retina 対応するようで、通常の画像ファイルなら -hd.png
のような suffix で画像を置いておけば自動的にそいつが使われるようになった。
スプライトシートでの対応方法が見つけられなかったので、いろいろ試してみた。
結論から書くと、
- time_num.png
- time_num-hd.png
- time_num.plist
- time_num-hd.plist
とそれぞれファイルを作成する。plist のなかのファイル名は -hd
ありなしに関わらずどちらもおなじ物を指定する必要がある。
そのうえで、
[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:@"time_num.plist"];
CCSpriteBatchNode* time_num = [CCSpriteBatchNode batchNodeWithFile:@"time_num.png"];
[self addChild:time_num];
CCSprite* time = [CCSprite spriteWithSpriteFrameName:@"time_num1.png"];
time.position = ccp(160, 240);
[self addChild:time];
などとすればいいようだ。座標系をただ倍にすればいいような単純な高解像度画像のためにもわざわざ別途plistを用意してあげなければいけないのが若干めんどくさい。
plist 作成が面倒な場合、
CCTexture2D* texture = [[CCTextureCache sharedTextureCache] addImage:@"time_num.png"];
CCSpriteFrame *frame = [CCSpriteFrame frameWithTexture:texture rect:CGRectMake(0, 0, 10, 14)];
というような感じでテクスチャを自前で切り出して使うことも可能のようだが、こっちのほうがコードが煩雑になりそう。
(0.99.5-rc1 でためしてます)
ユニバーサルバイナリ作成用シェルスクリプト
iPhone用にビルドしたライブラリは実機用(armv6/armv7)とシミュレータ用(i386)のユニバーサルバイナリとして作成しておくと使い勝手が良いです。 その分ビルドは面倒になるのですが。。
僕は通常以下のようにしてユニバーサルバイナリを作成してます。
- まずprefixをそれぞれ
~/dev/iphone/lib/curl-7.20.1-armv6
~/dev/iphone/lib/curl-7.20.1-armv7
~/dev/iphone/lib/curl-7.20.1-i386
などとしてそれぞれのアーキテクチャ用にビルドをする - 適当に書いた bundle.sh でユニバーサルバイナリ化
この bundle.sh
は上の例だと
./bundle.sh ~/dev/iphone/lib/curl-7.20.1
として実行すると ~/dev/iphone/lib/curl-7.20.1-armv6
~/dev/iphone/lib/curl-7.20.1-armv7
~/dev/iphone/lib/curl-7.20.1-i386
が全部がっちゃんこした ~/dev/iphone/lib/curl-7.20.1
ができるという寸法です。
この方法だとまだ3つ分手動でビルドするのがめんどくさいので、そこも自動化したいところですね。
PhotoShare にアップロードするだけのアプリ
PhotoShare は写真共有を軸にした SNS のようなサイトで結構好きなのですが。写真をアップロードしたいだけという状況で写真をアップロードしようと公式アプリを立ち上げると自分宛のコメントが来てないかとか、友達の写真が更新されてないかとかチェックするのですぐにアップロード画面にいけずイライラしたりします。
そんなわけでシンプルに PhotoShare にアップロードするだけなアプリを作りました。
先日のたこthon で適当に書き上げたアプリなので本当にアップロードする以外の機能がありませんが、使いながら欲しい物を加えていこうと思ってます。使い方見つつインタフェースも。
iPhone野良レポジトリの作り方
coderepos で野良レポジトリホストしたらいいんじゃね、っと思ったのでちょっとやり方をメモ。
iPhone の野良レポジトリは Debian の apt ベースになってるので、開発者が作った .deb ファイルをホストする感じになるのかな。なのでとりあえずここでは .deb の作り方は省く。
ホストの仕方は簡単で、.deb を同じディレクトリにつっこんでおいて、そのディレクトリ内で Debian の dpkg-dev
パッケージをインストールすると入る dpkg-scanpackages
コマンドを使って
dpkg-scanpackages -m . > Packages
とやるとそのディレクトリの .deb をなめてパッケージ一覧を作ってくれる。これを bzip2 して Packages.bz2 にすれば最低限のレポジトリが完成する。簡単ですね!
ただ、iPhone野良アプリの.debには独自のメタデータがあるので、 dpkg-scanpackages
にそれを理解させるためにちょっと変更する必要はある。
--- /usr/bin/dpkg-scanpackages 2008-12-29 13:46:45.000000000 +0900
+++ dpkg-scanpackages 2008-12-10 14:12:55.000000000 +0900
@@ -25,7 +25,9 @@
my @fieldpri = (qw(Package Package-Type Source Version Kernel-Version
Architecture Subarchitecture Essential Origin Bugs
- Maintainer Installed-Size Installer-Menu-Item),
+ Maintainer Installed-Size Installer-Menu-Item
+ Name Author Homepage Icon
+ ),
@pkg_dep_fields, qw(Filename Size MD5sum Section Priority
Homepage Description Tag));
僕の環境(Debian Lenny)ではこんな感じ。
この dpkg-scanpackages
でつくった Packages.bz2 があるだけで一応レポジトリとしては機能するけど、どうせなのでレポジトリのメタデータなどを置きたいかと思います。
それは同じところに Release
というファイル名で
Origin: Saurik's Example for Cydia
Label: Cydia Example
Suite: stable
Version: 0.9
Codename: tangelo
Architectures: iphoneos-arm
Components: main
Description: An Example Repository from HowTo Instructions
こういうのを置いておけばOKです。各項目の説明は saurik 先生のエントリの Step 4: Repository Metadata (Optional) というところを見るといいと思います。
しかし coderepos は debian ベースではなかった気がするから、どういう場合はどうやるんでしょうね。。
xcode でも toolchain でもビルドできる iPhone アプリ構成を作る手順メモ
まず、xcode で新規プロジェクト作成。Window-Based Application が余計なもの作らないのでおすすめ。
.
|____Classes
| |____my_test_projectAppDelegate.h
| |____my_test_projectAppDelegate.m
|____Info.plist
|____main.m
|____MainWindow.xib
|____my_test_project.xcodeproj
| |____project.pbxproj
| |____typester.mode1v3
| |____typester.pbxuser
|____my_test_project_Prefix.pch
こんなファイル構成ができあがる。
まず、nib ファイルは toolchain 環境では扱えないので MainWindow.xib は削除。Info.plist からも
<key>NSMainNibFile</key>
<string>MainWindow</string>
って部分を削除。nib ファイルを使わないということはすなわち xcode のインターフェースビルダーが使えないということだけどまぁしょうがない。
つぎ、プリコンパイルヘッダ (my_test_project_Prefix.pch
) も僕はいらないので削除。また、project.pbxprojに
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = my_test_project_Prefix.pch;
という部分がDebugとReleaseの二カ所あると思うのでそこを
GCC_PRECOMPILE_PREFIX_HEADER = NO;
に変更。
Classes ってディレクトリ名が気に入らないので、src に変更。xcode側では読み込み直す。
アイコンとかリソースファイル用には resources ってディレクトリを作っておく。
最後に toolchain 用の Makefile をおく。
この時点でファイル構成は
.
|____Info.plist
|____my_test_project.xcodeproj
| |____project.pbxproj
| |____typester.mode1v3
| |____typester.pbxuser
|____main.m
|____Makefile
|____resources
|____src
| |____my_test_projectAppDelegate.h
| |____my_test_projectAppDelegate.m
こんな感じ。
これでどっちでもビルドできるようなアプリを書くことが可能。
めんどくさいので自動化したい。
追記@2008-12-11
project.pbxproj
を直いじりすると、その後 xcode から実機デバッグしようとするとUUIDがちげーよとかいう警告がでるようになるっぽい。(実際にデバッグは出来るのけど)
直いじりするかわりに xcode のプロジェクト設定で GCC_PRECOMPILE_PREFIX_HEADE
とかを編集すれば大丈夫。
KillAppleをCydiaからインストールできるようにしてみた
この間作った KillApple という iPhone のメモリに残ったビルドインアプリケーションを殺すアプリケーションですが、いろんなところでデモするとなかなか好評で、使いたいとおっしゃってくださる方もいたので、Cydiaからインストールできるようにしてみました。
Cydia のソースに
http://apt.unknownplace.org/iphone/
を追加すると、検索に KillApple が引っかかるようになると思いますのでそのままそれをインストールすればOKです。
今後作ったほかのアプリもここで公開していこうかなと思っております。
build-inアプリケーションを殺すだけのアプリ
作ってみた。絶対ありそうだけど。
起動すると
killall -KILL MobilePhone MobileSafari MobileMail MobileMusicPlayer
してすぐに終了するアプリです。
これらの組み込みアプリケーションは終了したつもりでもメモリに残るので、起動したままにすると全体が重くなります。
ホームボタン長押しすれば終了させられるのですがそれもめんどいので、いっぱつで皆殺しにできるものを作りました。
SpringBoard を殺すアプリは KillSB というのがあるんだけど、SpringBoard は再起動に時間がかかるので最後の手段にしておきたい。ほとんどの場合そこまでしなくてもこっちで十分なはず。