I phone勉強会 2010_03_06_gameloop

Post on 13-Jul-2015

649 views 0 download

Transcript of I phone勉強会 2010_03_06_gameloop

ゲームループのつくりかた

沖田@tmokita

12年11月17日土曜日

おわび

• いまさらな内容かもしれませんしiPhone固有というところはあまりないです。ごめんなさい。

• ゲーム作りのきっかけになればと思って発表することにしました。その程度です、ごめんなさい。

12年11月17日土曜日

おねがい• 発表の途中でも・よくわからねぇぞ!《゚Д゚》ゴラァア!! とか・細かく説明しろ!《゚Д゚》ゴラァア!! とかあったら随時お気軽にお願いします。

• つっこんでもらったほうが安心します。12年11月17日土曜日

自己紹介

12年11月17日土曜日

沖田知彦@

 tmokita12年11月17日土曜日

本業12年11月17日土曜日

零細ゲームデベロッパ所属

iPhone案件はじめました12年11月17日土曜日

しかし12年11月17日土曜日

不況12年11月17日土曜日

なので12年11月17日土曜日

副業12年11月17日土曜日

iPhoneプログラマ12年11月17日土曜日

関わったアプリ

12年11月17日土曜日

その他はひみつ

12年11月17日土曜日

あらためて12年11月17日土曜日

ゲームループのつくりかた(初級編)

12年11月17日土曜日

目次• はじめに

• 業界用語

• 基本ループの考えかた

• Sceneとかなんとか

• おまけ

12年11月17日土曜日

はじめに

• ゲームの作り方を難しく考えすぎている人が多い

12年11月17日土曜日

が!12年11月17日土曜日

• 実はたいしたことはやっていませんごめんなさい

12年11月17日土曜日

とりあえず知っとけ的な物

12年11月17日土曜日

業界用語• リソース(音とか絵とかバイナリとか、データそのもの)• レイヤー(大きい単位での描画優先順位)• プライオリティ(小さい単位での描画優先順位)• BG(背景)

• スプライト、オブジェ(細かく動くやつ)• フレーム(FPS:フレーム/Sec 60FPS=秒間60回画面更新)

•シーン、モード(各画面)12年11月17日土曜日

リソース(Resource)

• リソースマネージャがあると便利

• 無駄な重複読み込みを防ぐ

• 最適なリソース配置

• 非同期ロードなどの処理

12年11月17日土曜日

レイヤー(Layer)• 描画順番を大きく区切るための構造

• フォトショップのレイヤーとか

手前12年11月17日土曜日

プライオリティ• 同じレイヤー内での描画順番

Layer Layer

> <12年11月17日土曜日

BG,スプライト

BG スプライト(オブジェ)

都合により発表時とは画像を変えてあります

12年11月17日土曜日

以上をふまえて

12年11月17日土曜日

ループの話

12年11月17日土曜日

ゲームの基本は無限ループ

12年11月17日土曜日

基本ループ 1

• int main(){ GameInitialize(); whlie( isGameFinish() ) { GameMainLoop(); } GameFinalize();}

12年11月17日土曜日

iPhoneの場合はタイマーで

12年11月17日土曜日

基本ループ 2• applicationDidFinishLaunching

{ GameInitialize(); SetTimer(1.f/60.f);}

• OnTimer{ GameMainLoop();}

• applicationWillTerminate{ GameFinalize();}

12年11月17日土曜日

ソースコードは壊滅的

12年11月17日土曜日

でも書きます

12年11月17日土曜日

そしてシーン

12年11月17日土曜日

これが今日のメイン

12年11月17日土曜日

Scene

• Webでいうところの各ページ

• 各画面をSceneとして作り最後に接続する

• ex.)タイトル画面ゲームメインエンディング

12年11月17日土曜日

エンディングゲームプレイ画面タイトル画面

シーンのイメージ(あくまでもイメージ)

Title GameMain Ending

都合により発表時とは画像を変えてあります

12年11月17日土曜日

各シーンのつくり方

12年11月17日土曜日

Pattern 1• Switch−Caseでの分岐

while(1) { switch(nScene) { case kSceneTitle: funcTitleScene(); break; case kSceneGameMain: funcGameMainScene(); break; case kSceneEnding: funcEndingScene(); break; }}

12年11月17日土曜日

Pattern 2

• 関数ポインタにする• typedef void (*SceneFunc)(void*);

SceneFunc funcScenes[] = { funcTitleScene, funcGameMainScene, funcEndingScene};

• while(1) { funcScenes[nScene](&arg);}

12年11月17日土曜日

Pattern 3

• 仮想関数にする• CSceneBase sceneArray[] = {

TitleClass, GameMainClass, EndingClass,};

• while(1) { CSceneBase* currentScene = getCurrentScene(); currentScene->exec();}

12年11月17日土曜日

• 基本的なループはこんなかんじ

12年11月17日土曜日

ためしに

12年11月17日土曜日

•スプライトを一つ保持して描画するシーンを考える

• Class SceneOne{ CSprite* sprite;}

12年11月17日土曜日

必要な処理を考える

• Initialize - 初期化

•Main - 毎フレーム呼ばれる

•Finalize - 終了処理

12年11月17日土曜日

書いてみる• Scene::Initialize

{ sprite = [[CSprite alloc] initWithData:@”texture.png”];}

• Scene::Main(){ [sprite updateParameter]; [sprite draw];}

• Scene::Finalize(){ [sprite release];}

12年11月17日土曜日

できた12年11月17日土曜日

しかし12年11月17日土曜日

あれれのれ?

•非同期ロードは?→「NowLoading」とかは?

•ん?描画ってこれでいいの?

12年11月17日土曜日

• リソースのロードは非同期に行うそのため「ロード要求」と「ロードしたデータのセット」は段階をわけて行う必要がある

• レイヤーやプライオリティを考慮したり高速化のためには描画はまとめて一気に行うほうが都合がよい

12年11月17日土曜日

もういちど考える• Initialize - 初期化

•Loading - リソースのロード中

•PreMain - ロード後メインループ前に一回

• Main - 毎フレーム呼ばれる処理

•Draw - 描画処理

• Finalize - 終了処理

12年11月17日土曜日

も一回書いてみる(1)• Scene::Initialize

{ sprite = [[CSprite alloc] init]; [ResourceManage requestLoad_SpriteData];}

• Scene::Loading(){ [GameSystem requestDraw_NowLoading];}

• Scene::PreMain(){ data = [ResourceManage getLoadedSpriteData()]; [sprite setData:data]; [sprite setLayer:LAYER_0]; [sprite setPriority:100];}

12年11月17日土曜日

も一回書いてみる(2)• Scene::Main

{ [sprite updateParameter];}

• Scene::Draw{ [GameSystem requestDraw:sprite];}

• Scene::Finalize(){ [sprite release];}

12年11月17日土曜日

できた!12年11月17日土曜日

シーン完成!

• 一つのSceneは基本的にこんなかんじ

12年11月17日土曜日

そして12年11月17日土曜日

接続12年11月17日土曜日

Sceneの接続

•Sceneをつなぐ1 現在実行中のシーンの終了2 次のシーンの初期化

12年11月17日土曜日

while(1){CSceneBase* curentScene = getCurrentScene();

// 初期化if( [curentScene isNotInitialize] )

[curentScene Initialize];

//ロード中if( [ResourceManager isLoading] )

[curentScene Loading];

// ロード完了後に一回だけif( [ResourceManager isLoadFinish] )

[currentScene PreMain];

// Loading中にMain、Drawを呼ぶかはご自由に[currentScene Main]; [currentScene Draw];

// シーンのDrawでRequestされたものをレイヤーとプライオリティを考慮して描画[GameSystem DrawRequestedObject];

if( [SceneManager isRequestChange] ){

[currentScene Finalize];[SceneManager setNextScene: getRequestedScene()];

}}

12年11月17日土曜日

ソースコードは壊滅的

12年11月17日土曜日

Tips

• Scene選択できるSceneを作っておく

•できるだけScene単体で動くようにしておく

•→分業&デバッグが楽

12年11月17日土曜日

まとめ12年11月17日土曜日

まとめ• つまりはゲーム用の「便利なタスク」

• ゲーム用としてLoading、Draw、を考慮

• 仕組みを理解すれば各描画パーツに応用可能

12年11月17日土曜日

おまけ12年11月17日土曜日

お!12年11月17日土曜日

こいつ12年11月17日土曜日

できるな!12年11月17日土曜日

と思わせる小ワザ• メモリプールをつくる(実は大技)

• 構造体は無駄なく並べる

• 2の累乗の剰余は&でマスク

• 2の累乗を掛ける(割る)ときはシフト

• キー入力のバリエーションをつくる

12年11月17日土曜日

キー入力

• Normal - 押している間だけOn

• Repeat - 押した瞬間と一定時間後にOn

• Trig - 押した瞬間だけOn

• EndTrig - 離した瞬間だけOn

12年11月17日土曜日

これで12年11月17日土曜日

できるね!12年11月17日土曜日

やったね!12年11月17日土曜日

おめでとう!

12年11月17日土曜日

ありがとうございました

12年11月17日土曜日

• いずれどこかで中級編を・・・

• tmokita@gmail.com

• Twitter : tmokita

12年11月17日土曜日