でらうま倶楽部

バカってゆうか、ゲームを作る事しか能の無いプログラマの、面白おかしな日々を綴ってみる実験。

2010年01月

正しく活用したい自分の時間。

photo1自宅に辿り着いてご飯にありつけたのが午前2時。
お米を炊くトコスタートだと時間掛る。

さすがにちょっと悲しい…(涙)

今夜も相変わらずの白菜スープと、真イワシの塩焼き。やっぱ一匹で丁度良い分量だった。程良くおなかいっぱい。

さて、ちょこっと作業しますかね。


部長、昼間は事務所でメインの業務をこなしつつ、自宅では基礎研究的な事を進めてます。Emacs導入だったり、新企画の準備だったり、まぁいろいろ。

根っからゲームを作るのが好きっだってのもありますが、プログラマもそうやって鍛えとかないと新しいモノを生み出せないと思うんだよね。

何か新しい発想を思い付くとまずプログラマに相談するじゃん。そのとき「わかりません」って返事をしてたらダメで、せめて「検討してみます」とか「○○という技術が転用できそうだからちょっとやってみます」とか返せないとダメなんじゃないか?と思ってそうしてるんだけど、そういう日々の積み重ねがスキルアップにも繋がると信じての事。

過去個人的に興味があって買ったMacが仕事で大活躍した事もあったし、今回はメイン業務に支障をまったく出さずにテキストエディタをEmacsに乗り換えられた訳。

有名な、ナムコのベラボーマンとか塊魂って、実は勤務時間外で産み出されたゲーム。時としてそういう状況の方が尖がったモノが出来あがるいい例だと思います。

グーグルの20%ルールもそんな好例。


ま、ぶっちゃけ何カ月も同じ事を続けとると飽きるというのが一番の問題だからなんだけどさ(笑)

ちょっと残念だったXcode3.2.2

photo
iPadの発表と一緒に、開発環境のXcodeも新しくなっていますな。
まだSDKはβバージョンですが、部長の狙いはXcode3.2.2。

細かいバグフィックスとかされとるバージョンなので、もしかしたら?
と思いつつ、いそいそとADCにアクセスしてダウンロードしてインストール。

インストールはVisualStudioよか格段に楽。確認事項が少ないって事はいい事だ。
Xcode3.2.2はむしろ不安になるくらいあっさりインストールできて起動したよ。

で、今開発中のプロジェクトを開いてみたら、なんかフツーに開けるしコンパイルできるし、なんか大丈夫っぽい?

Interface Builderで、色設定のパレットを開いたまんまにしてボタンやテキストを編集すると、背景色やらの色設定が勝手に書き換えられてしまって困ってたんですが…無事に直ってるね~。

他にも細かい不具合が直ってていい感じ。

でも編集結果をInterface Builderで保存しないとXcodeに反映されないのは相変わらず。惜しいなぁ。バグレポには上がってるので、早く直らないかしらん(古いバージョンだとXcode側で保存しますか?って聞いてくれた)


で、ここでちょっとショックな事が。
これまではサポートされとったiPhone2.2.1向けのサポートが無くなっとる!

ウチの弟、PC持ってないのにiPhoneだけは持ってていまだにOS2.2.1なんですケド…。

そういう人向けのビルド設定ってどーやるんだろ。きっとあると思うので、Appleのサポートの人にメール投げつつ、とりあえずはXcode3.2.2の導入はしばらくおあずけー。


アンインストールはコンソールを立ち上げて

$ sudo /Developer/Library/uninstall-devtools --mode=all

って実行。その後再起動して、Xcode3.2.1を再インストールしたのでした。
バージョンダウンも楽チンなOSXですな(笑)

海の向こうからこんにちは。iPad

photo1
遂に発表されたね。iPad

部長的にはフルスペックのOSXが動かないのと、9.7型液晶はやや小さいのが微妙。

おっきいiPhoneだがね。
でも実物みたらグラグラっときちゃうんだろーなー。やばいよなー。


この仕様で499ドルは安い。
国内でも5万円切るのかな?タッチパッド式WindowsPCなんて、平気で20万とかするからなー。いきなし買う気が失せる。任天堂だって新ハードの値段にはすっごく気をつけてますよ。2万5千円をひとつの基準としてると思います。購買意欲を引き出すには値段のお得感は大事。

iPhone/iPod touchのアプリがそのまま動く!
これは嬉しい誤算。そんで、iPad専用アプリも同じ環境で開発できてAppStoreで公開できるんだよね。きっと。iPhone/iPod touch向けのアプリもそろそろ飽和気味?と言ってる人もいるだけに、iPadの登場がアプリ市場に新しい風を吹きこむ感じ。部長的にも追い風。

フルサイズキーボードはどうなの?
触ってみないとなんともですが…入力しやすさとか打鍵感とかね。両手を使うとなると、本体を机の上に置く訳じゃん?画面は自分の方に斜めに向いてて欲しいような、そーでもないよーな。

国内でのキャリアは?
今回は自由にキャリアが選べるっぽいiPad。さすがに今回はdocomoも黙っていないでしょう。そんで、auはどーするんだろね。でも個人的には3Gは要らんかな。Wi-Fiがついてたらそれで充分。国内は6月くらいに発売予定という噂なので、それまで目が離せませんな。


寝室のベッドの上でiPad片手にWebサーフィン…妄想が膨らみまくりんぐ(笑)

みんなも気づけばどーって事ない事。

photo1今夜は真イワシの塩焼きでした。
たまにはプログラム以外の話題も書きます。

帰りに立ち寄ったスーパーで絶賛半額セールだったんだけど、鮮度はなかなか。塩をパラパラっと振ってグリルで焼く事5、6分。まだワタに火が通ってない…?くらいの絶妙な焼き加減で完成!

身から溢れる肉汁(でいいのかなぁ)と表面に付いた塩が混じり合ってなんとも食欲をそそります。

たまらん!(自画自賛モード)

でもちょっと量が多かったかな?食べてる途中で満腹。イワシは一匹で良かったか。すっかり胃が小さくなっとる…というか、血糖値がさっさと上がる体質に なっとる。


料理って、その人の人となりが反映されると思うんだよね。効率第一の人は自炊もそんな感じだし、華やかな雰囲気の人は料理も華やか。

そして、料理は仕事は直結しとる!部長、料理はチャッチャと手早く同時進行で進めて、完成時にはキッチンシンクもスッキリ。な感じなのですが、仕事もそんなふうに進めます。

料理の上手な人は仕事も上手?あくまで自分の周りの人からの統計だけど、世の中的にはどーなんだろ。


そうそうそれで、この時期洗い物がしんどいくてねぇ。水が冷たい…てか痛い(涙)
ウチは湯沸かし器が備わってないしどーする?我慢?いやいや我慢はありえないでしょ。プログラマだって手荒れは天敵だもん!ってしばらく悩んでたんですがー。ついに対策を見つけました。

単に風呂上がりに取りかかる(笑)
体がホカホカだから水が冷たくない!超楽!

気づけばなぁーんだって感じ(笑)でも自分的にはスッゲー発見。
どんな些細な事でもスッキリ解決!な部長。

iPhoneアプリでコードの最適化を無駄にしない為に。

photo1iPhoneアプリのプロジェクトも佳境を迎えておりまして、そろそろリリースに向けて最後のスパートを始めようかな?という雰囲気です。

ランチの荒み方にも拍車が掛っておりますな。

そんな状況なので、プログラムの方もリリースビルドでメモリリークやパフォーマンス、そして余計な開発用のコードが紛れ込んだりしてないかのチェックを始めてます。

巷ではコードの最適化についての言及もよく見掛けるので、ちょっと調べてみました。

結論から言うと、GCC4.0の最適化は並みじゃないので、はっきりいって中途半端な最適化っぽい書き方は邪魔です。忘れましょう。

デバッグビルドでは差が出ますが、リリースビルドに至ってはカリカリにチューニングされたコードが出力されます。長い歴史の中で研究され続けている分野ですから、部長も含めてそのへんの人間がちょっと聞きかじった知識でどうにかなる訳ないんだよね。

inlineで宣言した関数だろうが、static宣言した関数だろうがもうバッサリ(ただ、最近の研究結果(pdf)ではむしろ static 宣言の方が最適化され易いそうな)

浮動小数を扱う型も、doubleとfloatで特に?という雰囲気だし、定数をうっかり1.0と宣言しても1.0fと宣言しても、GCCが前後の流れから最適な型に定義し直してくれる場合が多々あります。

それより目を向けて欲しいのが…iPhone向けに提供されているライブラリ関数の sin() と sinf() とで明らかに処理時間に差があるって事。なぜかこれらの関数に言及した最適化の話は少ないよね。

sin() とか fabs() とか round() とか。引数や戻り値がdoubleになってる関数!

これらの関数はfloat版も用意されとるんで、sinf()、fabsf()、roundf()に置き替えた方がはるかに楽にパフォーマンスを稼げます。

今プロジェクトでは、Chipmunkに習ってこうしてます。

#define cpfsqrt sqrtf
#define cpfsin sinf
#define cpfcos cosf
#define cpfacos acosf
#define cpfatan2 atan2f
#define cpfmod fmodf
#define cpfexp expf
#define cpfpow powf
#define cpffloor floorf
#define cpfceil ceilf
#define cpfabs fabsf
#define cpfround roundf

しょせんゲームで扱う小数の精度なんて float で充分。そうでもないプロジェクトに携わってる方々、大変申し訳ない。お察しします。

なので、部長の場合自分のプログラムで扱う小数の型は float に統一しています。N64やPS2のあたりからそうしてるかな?

コード出力の過程での最適化は面倒だしコンパイラに依存するのでコンパイラに任せ、それよりも普段からアルゴリズム面での最適化を心掛けましょう。

絶対的な計算量を減らす為のアプローチを常に考える。日々の経験と勉強だと思います。


余談ですが80年代の男子を夢中にさせたシューティング、ゼビウス。さぞやカリカリにチューニングされたプログラムだろうと思ってました。

XOR A
とやると、最短時間でAレジスタを0にできるのですが、

LD A,0
ってフツーに書いてあった。処理時間も使うメモリも倍じゃん。なんだろ。そんなに最適化されてなくて、ごくごくフツーのコードだったんだよね。でもゲームは社会現象になるくらいヒットしたよね~。

ゲームプログラミングに大事な事は、もちょっと別の所にあるって事なんだな。

ちゃんとしたAPIを使ってiPhoneスナップショットを実現する

photo1写真は先日差し入れて貰ったお菓子!部長難しい事はよく判らんがとにかく大変美味しゅうございました…。差し入れて下さった方、ほんとうにご馳走様です。

普段、事務所の人間は差し入れに対してゆったり構える派なんだけど。これは一瞬で無くなったね。


で、iPhone関連です。今回は実機上でスナップショットを取得する方法。

UIImage *image = [UIImage imageWithCGImage:UIGetScreenImage()];
よくみかけるこの処理だとうまくいかない。最新の開発環境ではダメか?


UIGraphicsBeginImageContext(self.view.bounds.size);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
でもこういう風に実装したら動きました。素晴らしい。UIViewController内で実行します。いいよね?これで。

ゲーム画面を取り込んで画面切り替え演出に使うのはもはや常套手段ですが、これでiPhoneもその仲間入り(笑)

上のソース、
#import <QuartzCore/QuartzCore.h>
が必要なのですが、

#import <Foundation/Foundation.h>
としてアニメーション処理を書いてるソースだとエラーで蹴られる。そ…そうなの?(よくわかってない)
今後検証が必要ですわ。


ちょい昔、UIGetScreenImage()を巡ってひと悶着あったみたいですが、そもそも非公式なAPIを使う方が悪いよね。それは魔法でもなんでもなくって、なんらかの理由があるから非公式になっているのです。PSでもそんなネタがあったよな~。

でもなぜに公開されてないの?っていうAPIも見掛けますが…ま、そんな時はサポートに聞いてみるのが手っ取り早くて正確だと思います。


セガサターンでゲームを作ってた時、ほんの一箇所だけ仕様書に書いてない事をやらかしたせいで、CDプレス工場を止めた経験がある部長が言うんだから間違いない(笑)あん時の社長、元気にしとるかな…。

iPhoneアプリ開発でも押さえときたい3つのポイント。

アプリ開発も佳境!で、さいきんいくつかハマったポイントを紹介。長年の経験とフィーリングで対処してるだけともいう。いろいろ間違っていたらご容赦くださいませ~。

1. Interface Builferを使ってUIを設計してる人がよくハマるポイント


全てのクラスに言える事なのですが、IB上で配置したオブジェクトとプログラムとのやり取りにはアウトレットという仕組みを使います。

@interface MyViewController : UIViewController
{
    IBOutlet id myOkBtn;
    IBOutlet id myCancelBtn;
    IBOutlet id myLabel;
}
@end

たとえば、クラス側でこんな感じに宣言して、IB上で接続、みたいな。

これ、実は内部でretainされているので、

- (void)dealloc
{
    [myOkBtn release];
    [myCancelBtn release];
    [myLabel release];

    [super dealloc];
}

ってやってやらないとメモリリークします。簡単なアプリならUIViewControllerは1つしか作らないので問題は表面化しませんが(アプリ終了時に後始末される)、複雑な画面遷移を設計したり、自前でカスタムクラスを作り始めるとハマるところなのでいまのうちにこうやって書くクセをつけましょう。

っても、Xcodeに付属のパフォーマンスツールでチェックしたら一発で判明しますけどね(笑)


2. 重い初期化を非同期で動かす

ステージセレクト的なのを作ってて、テーブルのセルをタップした瞬間にメインの初期化を呼ぶつくりにしてるのですが、この初期化がメインの処理をブロックする為、一瞬iPhoneが固まったみたいになってしまいます。その場で全画面を再描画する手法も知らないし、iPhoneは基本スレッドが1つしか動いていないので

[NSThread sleepForTimeInterval:0.5];
とかも効果なし。

しょうがないので、UIViewControllerクラスでこうやりました(涙)

- (void)gameEntry:(NSTimer *)aTimer
{
  /*
     ここで重い初期化処理
   */
}

- (void)startMain
{
    /* セルがタップされたら呼ばれる */
    [self.view setUserInteractionEnabled:NO];
    timer = [NSTimer scheduledTimerWithTimeInterval:0.05 target:self selector:@selector(gameEntry:) userInfo:nil repeats:NO];
}

非同期処理とかいろいろ無視!ユーザーインターフェイスを全部止めて、時間差でメソッドを呼んだだけ~。でもこれで希望した通りの振る舞いをしたので結果オーライ!でもこれ多用したら超コードが追っかけづらくなるね。


3. クラスメソッドを上書きする時の注意

- (void)viewDidLoad
{
    [super viewDidLoad];

    /*
        自前の処理
    */
}

みなさん、こんな感じの実装で viewDidLoad はちゃんと約束を守って親クラスのメソッドを呼び出しているのに、

- (void) viewWillAppear:(BOOL)animated;
- (void) viewDidAppear:(BOOL)animated;
- (void)viewWillDisappear:(BOOL)animated;
- (void)viewDidDisappear:(BOOL)animated;

このへんだとスルーしてるっぽい?

- (void) viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

    /*
        自前の処理
    */
}

部長的には、お上品にこうやって書いた方が後々いいような気がしてます。今後のバージョンアップで処理が追加されるかもしれないからね。



でも今の時代、ネット上に溢れるほど情報があってホント助かる。ま、そのぶん間違った解釈のも見掛けますが(汗)反面教師~。

そうそう、ドリームキャストで動くPCエンジンエミュレーターを実装した経験があるのですが、これはさすがにネットで見掛ける情報に正解は無かったねー。
それもそのはずで、当時でさえ正式なハードの仕様書が3冊しか残ってなくて、それも意訳的な箇所が散見してた内容だったのよ。当時は
プログラマーが仕様書読みつつーの、ハードの実際の動を調べつつーの、実装してたんだよね。当時はそんなもんすよ(笑)

でもその仕様書のお陰で巷のエミュレーターのどれよりも正確な挙動をしとるハズなんですが…R-TYPEは横384ドットなのをちゃんとTV画面に引き伸ばして表示してたし(他のエミュレーターでは画面比が変になるか、画面が切れていた)…最初のバージョンで開発が打ち切りとなってしまったのが残念なプロジェクトでした。パフォーマンスにやや難があったけど、200本近く動いてたからね。DCで動くビックリマンとかガンヘッド…!笑。

iPhone開発の場合はXcodeにたいへん優秀なヘルプ(英文)が付属してるので、できればそれを読みこなして欲しい。やっぱオフィシャルな文献が一番頼りになりますよ。


photo1今日のランチはこないだのココアパンだったのですが、食べようとしたらとろけてました…なんたる惨劇。暖房がちゃんと入っていたからね。ドンマイ!

あとコーヒー淹れようとしたら途中で豆が切れた。そういうのは事前に言ってくんないと!ドンマイ…。

どんなスケジュールも見落とさない、Emacs org-mode

phot1Emacs上で動くアウトラインプロセッサorg-mode。遂に「アジェンダビュー」に手を出し始めました。ま、統合環境みたいなものです。

org-mode(6.34c)の場合、.emacsに最低限書く設定は以下の通り。

(require 'org-install)
(add-to-list 'auto-mode-alist '("\\.org$" . org-mode))
(global-set-key "\C-ca" 'org-agenda)

そして、.orgファイルを開いた状態でC-c [ (org-agenda-file-to-front)を実行。アジェンダで管理する.orgファイルを指定します。


で、Emacs上でC-caと打つと画面下部にアジェンダビューのメインメニューが表示されます。いろいろ選べますが部長が使うのは

a  Agenda for current week or day
t  List of all TODO entries

の2つだけ。

a を押すと、今週1週間のスケジュール(あれば)が表示されます。
たとえば、何かスケジュールを入力して、C-c C-s として日付を入れます。

* iPhoneアプリデバッグ開始
   SCHEDULED: <2010-01-26 火>
こんな感じ。で、アジェンダビューで a を押すと、

Week-agenda (W04):
Monday     25 January 2010 W04
Tuesday    26 January 2010
  to-do:      Scheduled:  iPhoneアプリデバッグ開始
Wednesday  27 January 2010
Thursday   28 January 2010
Friday     29 January 2010
Saturday   30 January 2010
Sunday     31 January 2010

自動的に.org内を検索して表示してくれます。あー便利!深い場所に書かれたスケジュールも探し出して表示してくれるので、メモる時にいちいちメモリ方を考えなくてよいのが素晴らしい。「スケジューリングする時は、メモってC-c C-s」ただそんだけ。

で、この表示の時に「l(小文字のL)」を押すと、

* DONE HDD買い出し
   CLOSED: [2010-01-25 月 23:28]
と書かれた項目だけを抽出して表示してくれます。これがまた死ぬほどに便利。TODOからDONEに変更になった項目を一日単位で追っかけられるので、今日1日の作業が一瞬で把握できます。

で、そのTODO項目は、メニューで t を押せばズラズラっと表示されるという仕組みです。

なんとも部長の文章能力では2%くらいしか説明できてないアジェンダビュー。とにかくこれはマジで便利なので、スケジュールが散らかりがちなEmacs使い(すくなそう)は是非使ってみておくれやす。

関数テーブルとコールバック処理をObjective-Cで書く。

photo駅のホームで感じる違和感。
あれ?照明が青い…?

とうとう中央線でも導入が始まった青色照明。主に防犯&自殺抑止効果を狙っての事だそうですが、その色のせいなのか、場所のせいなのか(ホーム端)。その場が微妙に場末のキャバレー的雰囲気を醸し出しとって、ちょっと逃げ出したい感じ。

イギリスや関西の実証結果で明らかな効果があったようですし、一人でも思いとどまってくれるのならこの微妙な雰囲気も我慢できるというものです(部長はホーム端付近で電車を待つのがクセなのだ)

特に中央線!

そんな前置きとはまるでカンケーのないプログラムのお話ですが、さいきんの部長のブームは関数テーブルとコールバック。

- (void)hogeFunc
{
}

- (void)hogehogeFunc
{
}

- (void)fugaFunc
{
}

などとメソッドがあるバヤイ、


SEL func_tbl[] = {
    @selector(hogeFunc),
    @selector(hogehogeFunc),
    @selector(fugaFunc),
};

int i;
[self performSelector:func_tbl[i]];

と書けば、func_tbl[]に宣言されたメソッドの3番目を実行とかいう事が可能になります。
たとえば、テーブルで選ばれたインデックスで実行内容を決めたい場合なんかに効果を発揮するんじゃないかな。誰ですか?switch文で分岐しとる人は!

引数を1つ渡す場合は

- (void)fugaFunc:(id)aObj
{
}

とメソッドを書いて、

SEL func_tbl[] = {
    @selector(hogeFunc:),
};
id obj;
[self performSelector:func_tbl[i] withObject:obj];

とします。引数は2つまで許されているので詳しくはXcodeのヘルプを見て下さい。

これを応用すれば、他のクラスから自分のクラスのメソッドをコールバック的に呼び出したり、いろいろ楽できるかと思います。部長は自前で設計したタスク処理で使ってるのだ。

もうちょっと研究を続けます。

意外と話題に上らない、MacにあってWinにない便利な機能。

OSXにはあってWindowsには無い便利な機能。

ありすぎてどれを指しとるかわからんて!(笑)

部長的にイチオシはやっぱ仮想デスクトップ機能なのです。

最近のOSXだと「Spaces」という名称で提供されているこの機能。簡単に説明するとデスクトップ画面をいくつも持つ機能。

後輩から教えて貰ったVirtual Desktop for Win32きっかけで、Windows98時代から愛用してるんですが、これはもっと一般に広まるべき機能だと思う。

photo1部長の環境では、6つの仮想デスクトップ画面が作ってあって、画面1でブラウザを最大化して表示。画面2でEmacs、画面3でPhotoshopとかって起動してあります。

画像は4つのデスクトップ画面を1つにまとめたスナップショットですが、これが別々の画面になっとると思いねぇ。

で、必要に応じてショートカットキー1発で切り替え。いちいちソフトを起動したり、起動中のソフトを探す手間が省けます。一瞬で必要なソフトに切り替えられるから思考が中断されないし、何よりデスクトップが散らからないのが素敵。

デスクトップに大小様々なウィンドウが表示されていると、気が散ってしょうがないんだよねー。それになるだけ画面一杯に表示した方が、より多くの情報を見通せるし。余計な手間は極力省くのがPCと上手につきあう秘訣~。

そんな感じでいったん慣れるともう手放せない仮想デスクトップ。もうデスクトップ画面が一つしかないなんて考えられない!ってくらい便利。

Windowsを使ってて、操作にもどかしさを感じてる人は試してみて損は無いと思う。なんか画面が狭いな、と感じてる人は特に!どんだけ解像度が上がっても、文字って極端に小さくできないからね。読めないから。

DSの2画面に慣れたら他のゲームが物足りないのと一緒?別にそーでもないか。

これが未だにWindowsの標準機能になってないのかが不思議でしょうがない。わざとか?Windows7ではどーなんしょ。


っていうか、デスクトップ画面って個性でるよね。主にソフトを最大化して使う部長は背景一色を好みます。なんか賑やかな画像は気が散って苦手。そして極力没個性的な雰囲気を好みます。余計なデザインや色味も苦手。

このへん、WindowsよりMacのの方が自分の求めとる環境に近くて好き。環境はシンプルじゃないと。

すべての人に言える、ダイエットの絶対的法則

photo日曜日も作業中。部長です。

これがワーカホリックってヤツなのか…?
そうなのか?

ついつい楽しい事に没頭しがちな性分を許して下さい。

そんな時の素敵なお供、飴ちゃん!チェルシー。
おっ、新パッケージ。

ガリガリとプログラムを書いてる合間の甘いおやつはちょうどよい息抜きになります。


息抜きついでに趣味のダイエットネタ。

っていうか、ダイエットのもっとも根本的なルールを理解してない人が多い。知人もことごとく同じ理由でダイエットに失敗しとります。


摂取カロリー < 消費カロリー

はい、以上!

これを生涯守ってたら絶対に太る事はありません。ご飯減らすのが嫌な人は、そのぶん運動量を増やせばいいし、運動が苦手な人はご飯を減らして下さい。

部長が毎日おやつ食べてても太らないのは、カロリーの低いおやつをチョイスしてるし、そのぶんカロリーを消費してるからです。

今日のチェルシー、一袋で約300kcal。17粒入ってたので、1粒約17kcal。一日5粒も食べたら飽きるので、一回のおやつでの摂取カロリーは約85kcal。実はぜんぜんたいした量じゃない。

これがポテチだったりすると…パクパクっと一袋空けて…なんと500kcal!ポテチだと軽ぅく一袋空けられるけど、飴ちゃん一袋だとしんどいよね?部長の場合、こうした細かい工夫を積み重ねたカロリー制限をしとる訳。


RPGゲームだったらHPやMPやEXPとかぜーんぶ数値で見えるのに、残念ながら人間のパラメーターを可視化するのはたいへん難しい。

で も1つだけ簡単にチェックできるパラメーターがあるよね?そ、体重。とにかく毎日体重計に乗ってください。それがダイエット成功の第一歩。

そして、人間の体重をコントロールするのは巨大な石油タンカーを操舵する感覚に似ています。すぐ止まれない。

停船操作をしてから実際に止まるまで2日とか、面舵一杯!って船長が叫んでから実際に方向が変わり始めるのに半日とか、そういう世界。

最低三か月は成果が出ないと思って毎日体重計に乗る!そしてメモる!


ちなみに2、3kgは誤差の範疇と考えよう。だって、水1L=1kg。コーラを500ml飲んだら体重も500g増えます。

さすがのiPhoneアプリでもそれは無理。な事?

photo1現在開発中のiPhoneアプリですが、ちょっと無理してiPhone実機上でレベルデザインが出来る機能を実装してました。もちろんデータはJSONを利用してアプリ専用のディレクトリに書き出しとるので、作ったデータはiPhoneから取り出してサクッとマスターデータとなります。

かなり核心な比喩ですが、ギャラクシアンとかギャラガの敵配置がiPhone上でササっとできちゃうと思いねぇ。あの敵位置がiPhone上でできちゃうと。

全然訳わかん無いですよね。主にプログラムしてない人!

でもさすがに開発中のアプリの開発状況を実況中継的にここでつらつらを書く事ができないので非常にもどかしいのですが、マスターアップした暁にはその全容をここに約束したいと思います(個人的にはソースを公開したい)

そして…過去携わったゲームタイトルのソースも可能であればソースを公開したいのですが、当時会社に属していた以上それも叶わない雰囲気なので、何か別の形で成果物を公開できれば…いいのですが(汗)

個人的には新品で手に入らないゲームのROMバイナリがネットで流通するのはアリだと思ってますし。


ソースを公開するという事。それは、本人的にはそれが過去の産物だという意味を込めています。部長的には次のステップに移行してますよ、と。
まぁそんなにレベルの高い代物ではございませんが、重要なのはそこに至った発想。他の専門分野と違って、どんな難しい実装であっても、プログラムはコピペで100%真似できます。だから商用レベルであってもソースを公開する事に抵抗を感じません。当時から雑誌を含め自分もお世話になっとるでね。

あとは自分に対するプレッシャー。ここまでみんなに教えちゃった…的な。

自分が参考にしてきたソース群に対する恩返しの意味も込めて、iPhoneアプリが完成した暁には、この場を借りてソース公開&解説が出来れば本望。

乞ご期待!

Firefox3.6がIEを駆逐する日。

photo1FirefoxのタブでIEを動かす便利アドオン「IE Tab」が3.6では動きません。

と思っていたら、その改良版Coral IE Tabを見つけました。素晴らしい!これでWindowsUpdateやら○○サイトやら▲▲サイトとかで仕方なくIEを立ち上げる手間が無くなりました。

ちょっと誇張入ってました。

部長の常用アドオンは、Firefoxをマウスのジェスチャで操作するFireGestures、HTMLの構造をチェックしたりデバッグしたりするFirebug、よけいな広告画像をブロックするAdblock Plus、そして、IE Tab。

いろいろなアドオンを導入してる人もいるみだいだけど、部長が日々使うぶんにはFirefoxの基本機能+αで充分。そんなにあっても覚ええられないし(笑)
というか、追加したアドオンが原因で動作が緩慢になったり起動が遅くなったりしてほしくないからね。

何事もシンプルが一番。が信条の部長でした。

時代遅れのデータ管理法とはさっさと縁を切れ。

このブログを読んでくれてる人は、各種データをソースコード内にstaticな構造体で用意するなんてありえない!くらいに思ってる人ばかりだと思いますがメモ。

ゲーム内で扱うデータを極力テキストファイルベースで扱うのには主に3つの理由があると思ってます。
  1. 人間が読める
    パッと見で内容を把握できるから、データの見通しが非常に良いです。バイナリデータとにらめっこにながら「12バイト目が体力値で…」とか無理。
  2. テキストエディタさえあれば編集できる
    Photoshopなどの高価なソフトがなくても、誰でもどこでも編集可能。やろうと思えば iPhone上でだって編集できます。
  3. CVSやgitなどのバージョン管理システムで管理で管理できる
    た とえ複数の人間で同時にデータを触った時でも、データが壊れてしまう事無く全ての変更が正しく反映されます。
今の世の中、JSONを はじめXMLやYAMLなど、様々なテキストベースの規格とそのパーサーが公開されています。以前は自分で実装するしかなかったこれらの便利な仕組み。積極的に使った方がお得だし、開発時間をかなり節約できると思うよ。


photo1さて、このブログでちょくちょく取り上げとるTouchJSON

Objective-Cで書かれた軽量JSONパーサー。もちろんiPhoneでも動きますし、部長もバリバリ使ってます。

なのですが…使ってて困った事が1点。

それは、扱う型が、NSDictionaryやNSArrayだということ。これだと、読み込んだデータを書き換えられません。たとえば、セーブデータとかね。

で、どーするかっていうと、そんなNSDictionaryやNSArrayを一気にNSMutableArrayやNSMutableArrayに変換する関数を見つけてきて、そいつを使っています(というか、ADC内のコラムで見掛けたモノです)


static NSMutableArray* MakeMutableArrayCopy(NSArray *array);
static NSMutableDictionary* MakeMutableDictionaryCopy(NSDictionary *dict);

NSMutableArray* MakeMutableArrayCopy(NSArray *array)
{
    id  copy;
    int i;
   
    // Make copy
    copy = [[NSMutableArray alloc] initWithArray:array copyItems:YES];
    [copy autorelease];
   
    // Enumerate object
    for (i = 0; i < [copy count]; i++) {
        id    object;
       
        object = [copy objectAtIndex:i];
        if ([object isKindOfClass:[NSArray class]]) {
            [copy replaceObjectAtIndex:i
                            withObject:MakeMutableArrayCopy(object)];
        }
        else if ([object isKindOfClass:[NSDictionary class]]) {
            [copy replaceObjectAtIndex:i
                            withObject:MakeMutableDictionaryCopy(object)];
        }
    }
   
    return copy;
}

NSMutableDictionary* MakeMutableDictionaryCopy(NSDictionary *dict)
{
    id copy;

    // Make copy
    copy = [[NSMutableDictionary alloc] initWithDictionary:dict copyItems:YES];
    [copy autorelease];
   
    NSArray *array = [copy allKeys];
    for(id key in array)
    {
        id object = [copy objectForKey:key];
        if ([object isKindOfClass:[NSArray class]])
        {
            [copy setObject:MakeMutableArrayCopy(object) forKey:key];
        }
        else
        if ([object isKindOfClass:[NSDictionary class]])
        {
            [copy setObject:MakeMutableDictionaryCopy(object) forKey:key];
        }
    }
   
    return copy;
}

id MakeMutablePlistCopy(id plist)
{
    id copyPlist;
   
    if ([plist isKindOfClass:[NSArray class]]) {
        copyPlist = MakeMutableArrayCopy(plist);
    }
    else if ([plist isKindOfClass:[NSDictionary class]]) {
        copyPlist = MakeMutableDictionaryCopy(plist);
    }
    else {
        copyPlist = [plist copy];
    }
   
    return copyPlist;
}

人様のコードに少し手を入れた程度なので、見辛いのはご容赦ください(笑)


NSDictionary *dict;    // ←TouchJSONでパースされたデータ
NSMutableDictionary *hoge = MakeMutablePlistCopy(dict);

使う時はたったこんだけ。NSDictionaryだろうがNSArrayだろうが、深くネストされたNSDictionaryやNSArrayも含めてみんなまとめてNSMutable~ に変換してくれます。超便利!再帰で処理してるので、処理の流れを追っかけてみるのも勉強になるでしょう。

戻り値はautorelease属性なので、保持する時はretainしてください。

スッキリ!

真っ先に捨ててしまいたいソフト

今日、M$からIE6~IE8向けの緊急パッチの提供が始まってたけど、ユーザーに「IEをアンインストールする」という選択肢が無いに等しいので、何か あった時にM$頼みなのがしんどい。そしてそんなIEじゃないと閲覧できないサイト(それも開発者向け!)を運営しとるIT企業と、その開発に携わっとる ITゼネコンはもっとしんどい。

photo1そんな調子なんだけどー。ゆうべ導入したFirefox3.6はすこぶる好調。

3.5の時はアドレスバーに何か入力しようとしたとたん、SQLiteがフル稼働して固まってたのがほぼ解決してるね。SQLiteのデータベースを最適化するためだけのアドオンまであったくらいなので、みんな不便に思ってたんだろうね。ま、解決されて何より。

あと、新しくタブで開く時の挙動が変わってる。3.5では常に一番右端に新しいタブが作られていたのが、3.6ではリンク元のタブの右隣りに挿入されるようになってる。ま、これは慣れだな。

あと…もしかしてホイールでのスムーススクロール、若干チューニングされてる?加速の具合とかスクロール量とか…??


Firefoxがあまりに快調なので、さいきんメジャーアップデートしたThunderbird3の重さが際立ってしまって残念。索引をつける作業で固まりがちなのと、メモリ食いなのがちょっと…。

ただ、検索がだだっ速なのはすごく助かってます。ほんと一瞬。このへんの実装とか、技術者的に興味が尽きません。ゲーム開発においても「検索」というキーワードはとても重要だからね。

カーナビなんかの経路検索。あれもいつかは自分で実装してみたい分野。似たような実装を経験していますが…ほんと触れただけ~。アクションゲームだったんだけど、CPUキャラが複雑な地形からほぼ最適なルートを選んでプレイヤーの場所まで辿り着いた時はけっこう感動もんだったよ。そういや再帰処理とか使ったなー。みたいな。

カメラ機能以外にも色々使える便利な描画法。

photoiPhoneカメラの解像度は画面サイズよりもずいぶん高解像度なので、オフスクリーンバッファに縮小描画してから表示、的な手法を使います。

実はこれ、フツーのアプリケーションでもかなり有効に使える手法です。

今作っているアプリは背景画像の上に幾つか部品的な画像を重ねて表示していたのですが、部品にあたる画像は最初の位置こそ重要ですが、それ以降ピクリとも動きません。だったらあらかじめ重ねた画像を用意すればいいじゃん、という訳でオフスクリーンバッファの出番となる訳です。


CGSize size = { 320, 480 };
UIGraphicsBeginImageContext(size);

// オフクリーンに対して好き勝手描画できる
UIImage *img = [UIImage imageNamed:@"hoge.png"];

[img drawAtPoint:CGPointZero];

CGRect rect;
rect.size.width = 50;
rect.size.height = 100;
rect.origin = CGPointMake(100, 100);
[img drawInRect:rect];

// オフスクリーンからUIImageView を生成して表示
UIImage *offScreen = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

UIImageView *imageView = [[UIImageView alloc] initWithImage:offScreen];
[self.view addSubview:imageView];
[imageView release];


たったこれだけ。実装が簡単な割に効果は大きいです。用意した画像のような事が簡単に実現できます。

ゲーム機で同じような事をやろうとすると、VRAMやテクスチャバッファの管理がとてもメンドーでコストがかかるのですが、iPhoneはそれを意識させない作りになっていて本当に楽。これは、長い年月を掛けて培われたAPI群があればこそだと思います。

PS2ももう10年。ゲームデベロッパ的にようやく環境が整った所でPS3とかへの移行を迫られると、開発基盤の無い所は辛いのよ(涙)

空気を読めてた所はPS時代から準備を始めてて、いまようやく楽できてるんじゃないかな。そういう開発環境に対するコスト意識の低い現場は軒並みアップアップしとるそうですが。

「特に問題なし」という事の偉大さ。Firefox3.6

photo1さっそくダウンロードして使ってます。Firefox3.6(WinXP)

てか、主に仕事で管理してるWebサイトの表示チェックです。


まず起動が速い。体感速度的に半分くらいになっとる!

で、YoutubeみたくFLASHが組み込まれとるサイトの表示パフォーマンスもかなり良好。けっこう一瞬。Livedoorのブログの管理画面もかなり軽い(笑)

何気に終了時の処理も軽くなっとる?プラグインの更新なんかでFirefoxを再起動すると、3.5あたりは子供が駄々をこねるかのごとくプロセスが生き残っててゲンナリしてたのですが…それがほとんどないねー。サクッとプロセスが終了します。

Firefoxのタブ内でIEを使うIE Tabが対応しとらん…これは思わぬ誤算。ま、待ちで。他のアドオンは問題無し。

設定画面関連はとくに変わりなし。というか何も無さ過ぎて肩すかし気分。いい事なハズなのになぜか不安になるよ。

新機能のPersonasはかなり出来がよい!いわゆる「テーマ」なのですが、インストールせずとも対象のバナーにマウスを重ねるだけでプレビュー出来てしまう。この仕様を実装した人は天才だと思う。


バージョンアップを重ねるたびにより便利且つトラブルフリーに進化を続けるFirefox。他の商用ソフトも是非見習ってほしいと思う。こんだけ手を入れてて、特に問題無しってのは…記者泣かせなバージョンアップですがホントスゴイ事だと思う。ちなみに、OSXやLinux版はどうなんだろうね。

そうそう、部長が管理しとるWebサイトはどれも問題なくレンダリングされたのだ。実はこれが一番気になってたんだよねー。

もう準備はできたかな?22-2AM

Firefox、photo1はやくも3.6が登場するんだね。

3.5が去年の7月だったから…ちょうど半年。んで、その公開が22日の午前2時。2並びー!モジラさんわざとですか?

ま、北米だと21日午前9時だし、たまたまでしょう。たまたま~(笑)

今回も色々と手が入ってるみたいで、今夜が待ちどおしい。というか、傍から見てるとホント順調に開発が進んでる感じ。スケジュール管理とかバグトラッキングとか、どーやってるのか見当もつきません。てか何人くらいで開発しるんだ…?

Netscape(SGI Indy) → Netscape(Mac) → Mozilla(Mac・Win) → Phoenix(Win) → Firefox(Win)とまあ、ずいぶんと偏りのあるブラウザ遍歴の持ち主ですが(そーでもないって?)、挙動とかキーバインドとかメニューの感じとか。部長的にはFirefoxが使ってていちばん手に馴染むブラウザだね。あとAdblock plusの存在が大きいかな。余計な画像のダウンロードによる帯域の無駄遣いは極力無くしたいし~。

さてさて。今夜は3.6さんいらっしゃ~い。

これは間違えるでしょ。棚に並んだカップ麺。

photo1ランチは久々カップヌードルかな?と手に取ってレジへ。

んで、事務所でセッティングしたとこで感じる違和感。ん?ホワイト…??

ありゃ。間違えた。

これ、期間限定のクリームシチュー味だってさ。欲しかったのはシーフードなんですけどー。見た目がよく似てたから間違えて買ってきたっぽい。あのスパイシーさが欲しかったのに…シチューにそれは求められんて。

なんかさいきん外でボーッとしてんなぁ部長!特定カテゴリ以外まったく興味がないので、オリンピックがどーのとかF1がこーのとか全然知らんよ。

そんな、ホワイトたんを責めないで…!というか3分たったのでさっさと頂きましょー。

あ、これかなりイケますねぇ。大き目クルトンといい、とうもろこしといい、部長の好きな具ばかりで好印象。ぜんぜん美味しいじゃん(笑)そんで、トロ~リシチューが温ったまる……てか熱っ!舌やけどしちった。減点1点!

印象悪し!な出足から、最後は好印象なランチ模様でした。さあ今日も張り切っていきましょう。iPhoneアプリの完成も近いのだ。

さすがに許せんて。国立駅舎問題。

ohiti1国立市がやっきになって取り組んでる「国立駅舎保存大作戦」

国立住まいの部長的に、「今のご時世、こんな無駄遣いってないよね?」って思ってる事~。

数年前、中央線の高架化などに伴って取り壊されることになった国立駅舎。モダン~な三角屋根も見収めですなと思っとったら、なんと国立市が待ったをかけたというお話。

いやいやいや!駅舎の持ち主はJR東日本ですがな。なに勝手な事ぬかしとるねん。

もちろんJR東日本はもとより工事の発注元である東京都も拒否った訳ですが、そこで引き下がらないのが国立市。なんと独自費用で駅舎を保存しちゃおうぜ!という暴挙にでます。

コラーッ!部長(住民)の血税でなに勝手な事しとんねん!

で、解体されたパーツを市の外れに保管。ちょくちょく見学会とか催しとるようですが…いまんとこ復元の目処はたっとらんのよ。つまり、駅舎のパーツの保存という名目で皆の血税がドブに捨てられとる訳。なんじゃそら。そんなん鉄道好きのボランティアに(いるなら)勝手にやらせとけって感じじゃん?公な組織が取り組むような事じゃないと思うのよ。

古くなった自分ちを改築しようとしたら「あなたの家は市の景観にとってとても重要ですから勝手に改装しないでください」っていきなり言われる様なモンですよ。

どーせアレでしょ?国立駅舎を模ったお菓子やら何やらの商品価値が無くなると色々この先問題だよね?って利権団体とかに言われたんじゃないの?

とかって考えもしますよ。

概ね国立市の政治には賛成なのですが、こればっかりは賛同しかねるので、こうして主張してみるテスト。

ま、詳しい経緯はWikiで(笑)
記事検索
電子書籍発売中

「チュートリアル形式で始めるOpenAL」
サウンド怖くない。C++による8つのチュートリアルで始めるOpenALプログラミング。さああなたも、自作アプリに魅力的な音効を添えてみませんか??
⇒Kindle版 ⇒iBooks版


「iPhoneアプリ『ういろう』のレシピ」
ゲームってどうやって作ってるの?? 拙アプリ『ういろう』の製作過程を本にまとめました。もちろんソースコードつき
⇒Kindle版 ⇒iBooks版


『チュートリアル形式で始めるOpenGL[2D編]』
OpenGL怖くない。C++による16のチュートリアルで始めるOpenGLプログラミング[2D編]。さああなたも、ゲーム作りを始めてみませんか?
⇒Kindle版 ⇒iBooks版
自作ゲーム配信中

『Puzzle & Monarch』
「君主候補となって国作り!! ただし制限時間は90秒。」森を作って道をつないで...あなただけの国を作ってみませんか??
⇒AppStore


『BRICK & TRIP』
咄嗟の判断に、あなたの指先はついてこれるか?! 爽快フリックアクション!! 様々な難関をくぐり抜けて旅の終着点を目指そう!!
⇒AppStore


『ういろう』
名古屋土産ういろうがiPhoneで大活躍?! 白ういろうを守れるのはあなただけ。ひゅーん、ぼよよーん!!
⇒AppStore ⇒LITE版


『こなへん』
ヒマラヤ山脈、大西洋、世界で一番深い湖… それって地球のどこにあるのか知ってるかな?『全方位直感地理クイズ』という新ジャンルに挑戦!あ、それ。地球をくーるくるw
⇒AppStore ⇒LITE版


『GEOSPOT』
ヒマラヤ山脈、大西洋、世界で一番深い湖… それって地球のどこにあるのか知ってるかな?『全方位直感地理クイズ』という新ジャンルに挑戦!あ、それ。地球をくーるくるw
⇒Windows ⇒Mac


『TieGunner』
マウス片手に大宇宙へ飛び立とう!『しっぽシューティング』というジャンルを作って頂きました^^; WinでもMacでも動きます。ソースもあるでよw
⇒Windows ⇒Mac
QRコード
QRコード
  • ライブドアブログ