× [PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。 |
アクションゲームの主人公の移動について作ってみた。
iPhoneのアクションゲームの移動操作については、いろいろな方法がある。 たとえば左右キーのバーチャルボタンがあって、キーを押すとそっちに主人公が歩くタイプがある。キーじゃなくてレバーになってる場合もある。 でもこれは、正確にキーやレバーの場所をタッチしないといけない。これは結構難しい。 普通ボタンの位置は見ずにゲームプレイするから、だんだんずれていっちゃう。 特に、右へ行きたいときはつい右の方をタッチするようになるから、ずれは思いのほかすぐ起きる。 タッチしたときに感触もないから、ずれてしまうのは防ぐのが難しい。 PR |
開発日記カテゴリーで書くのは久しぶり?
今日は 作成中の試作ゲームを Objective-C 依存を無くすように書き換えていた。 #import を #include に直す NSMutableArray を std::vector に直す UITouch オブジェクトは、必要なメンバだけを抜き出して独自構造体に変える などなど。 どうしても依存してしまう部分としては、 画像の読み込み部分 CGImageRef image = [UIImage imageNamed:[NSString stringWithFormat:@"%s", fname]].CGImage; 入力受け取り - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 大元はViewControllerクラスから呼び出している など。 描画部分は、OpenGLなので依存は無いようになっている 拡張子を.mmから.cppに変えられればいいんだろう、というだけでもない。 中で #include <Foundation/Foundation.h> とか呼んでたら、結局iOS下でしか動かないわけで。 NS*** とかもちゃんと排除しておくこと。 |
意外と頭を悩ますのがスクロールとスケーリング。
個々は難しくないんだが、両方混ざると厄介。 しかも、瞬間でなく滑らかにスクロール&スケーリングしてほしい。やっぱりiPhoneだもんね。 今回のルール ・スケーリングは2段階 ・縮小表示では、全体を映す。つまり、スクロールしない ・拡大表示では、一部分を映す。スクロールする ・滑らかにスケーリングする ・ダブルタップした点を中心にスケーリングする。スケーリング中に外側が見えてしまわないようにする ・スクロールは1マスずつ ・外側が見えてしまわないようスクロールする |
先日の数値描画機能を使って、問題番号を表示するようにした。
すると、問題の名前も書きたくなった。 で、アルファベットの大文字を書けるようにした。 数値と文字で別々なのも効率が悪いので、結局、ascii文字コード表全部を描画できる機能を作り、2つは削除した。
数値を描画したいときは、
のようにする。 itoa()を使えば楽じゃん、と最初は思ったのだが、 itoa()は標準じゃないそうだ。atoi()は標準だけど。 http://ja.wikipedia.org/wiki/Itoa itoaを使うと、数値の先頭に0を付けるとかできないし、floatは自分で変換するよりないということなどを考えると、結局snprintf()でやるのが良さそうだ。 |
問題番号を表すため、数字だけでも自前で描画しようと思い、実装。(文字はいずれ考える必要がある)
//定義 void drawDigitsAlignRight(Point_t point, float height, int num); ゲーム側からの使い方================= 描画座標と、数字のサイズ(縦のみ指定。横は自動で決める)と、表示する数値を指定。 右寄せで描画する。point で指定した座標が、一の位の数字の右上にあたる。 右寄せにしたのは、実装しやすかったのと、実際に使う回数がこちらのほうが多そうだったから。 int型変数の10進数での桁数を求める関数って用意されていないんだろうか。 この関数の定義は、DrawHelperという機能群の中に入れることにした。 描画機能自体にこの便利機能が入っているのはおかしいからだ。 ゲーム開始時に、DrawHelperの初期化を呼ぶコードを追加。 実装======================= uv座標を指定して描画できる機能をGL描画機構に追加。 テクスチャは、 0123456789-+., と等間隔に描いたもの。サイズは縦横ともに2の累乗数。 桁の下から順に右から描画していく。 難しいことは特にない。 |
ゲームステートの遷移の際に、必要な情報をどう渡すか
例えば、タイトル画面で問題番号を選択し、ゲーム画面に遷移してその番号をロードするような場合。 問題番号を渡す必要がある。 1.リザルト構造体を生成し、そのまま渡す
これだと、GameクラスがTitleクラスを知っていなければならない。 そこは互いに独立していたい。 2.リザルト構造体を生成し、バラして渡す
これだと、TitleクラスとGameクラスにいちいちアクセサ関数を用意しなければならないので面倒。 3.フレンドクラスにして、すべてが見えているクラスが個々に渡す
このあたりが一番良さそう。 Gameクラスにもちゃんと同じ変数を用意して、値コピーするというところがポイント。 毎回Titleクラスに参照しにいくのは良くない。Titleクラスがないと動作しなくなる可能性があるから。 Titleクラス、Gameクラスにおいては、CGameMainクラスは前方宣言だけしていれば良く、インクルードの必要は無い。だから新たな依存関係も生まれない。 |
OpenGLを使用する際の大まかな流れ。
最低限必要なことだけ抜き出しています。 エラーチェックなどは一切省いてあります。 XCodeで、OpenGLプロジェクトとして作成すると自動で作られるコードです。 ViewController シェーダ周りの初期化を行う。 シェーダの中身に何が書いてあるか、ゲーム側でどう描画するかなどは関知しない。 |
OpenGLESプロジェクト
XCode で、新規プロジェクト→iOS→OpenGLESを選択 すると、もうOpenGLESで描画のされたサンプルが生成される。 これを自分のいいように書き換えていく。 その際の注意点。 シェーダの変数名は合っているか position と a_positionとか Shader.vsh/fsh と、 loadShaders() のglBindAttribLocation()の引数など CoreGraphics.frameworkを追加したか CG***()関数を使う場合 _CG***()が定義されていない、というようなエラーが出る programオブジェクトをちゃんと渡しているか loadShaders() の program = glCreateProgram(); |
| ホーム |
|