Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

コルーチンを使おう

8,212 views

Published on

Published in: Technology
  • Be the first to comment

コルーチンを使おう

  1. 1. コルーチンを使おう
  2. 2. WHO AM I?• ナムアニクラウドと申します• 主にC#でゲームなどのプログラミングをしてます• Twitter: @NumAniCloud Twitterアイコン→
  3. 3. コルーチンとは// イメージ(C#)IEnumerator ShotRoutine(){ Shot(); yield return 0; // ここで抜ける! Shot(); // 続きはあとで実行する}• 関数とかメソッドの仲間です• 途中で抜けて、あとで再開することができるのが特徴です
  4. 4. 実行のイメージ// 定義 // 呼び出しIEnumerator Fiber(){ void Main(){ Shot(); var x = Fiber(); yield return 0; x.MoveNext(); Shot(); Hoge(); Shot(); x.MoveNext(); yield return 0; x.MoveNext(); yield return 0; x.MoveNext();} }
  5. 5. 実行のイメージ// 定義 // 呼び出しIEnumerator Fiber(){ void Main(){ Shot(); var x = Fiber(); yield return 0; x.MoveNext(); Shot(); Hoge(); Shot(); x.MoveNext(); yield return 0; x.MoveNext(); yield return 0; x.MoveNext();} }
  6. 6. 実行のイメージ// 定義 // 呼び出しIEnumerator Fiber(){ void Main(){ Shot(); var x = Fiber(); yield return 0; x.MoveNext(); Shot(); Hoge(); Shot(); x.MoveNext(); yield return 0; x.MoveNext(); yield return 0; x.MoveNext();} }
  7. 7. 実行のイメージ// 定義 // 呼び出しIEnumerator Fiber(){ void Main(){ Shot(); var x = Fiber(); yield return 0; x.MoveNext(); Shot(); Hoge(); Shot(); x.MoveNext(); yield return 0; x.MoveNext(); yield return 0; x.MoveNext();} }
  8. 8. 実行のイメージ// 定義 // 呼び出しIEnumerator Fiber(){ void Main(){ Shot(); var x = Fiber(); yield return 0; x.MoveNext(); Shot(); Hoge(); Shot(); x.MoveNext(); yield return 0; x.MoveNext(); yield return 0; x.MoveNext();} }
  9. 9. 例(C#)ゲームで敵キャラクターの制御をしたい • 下へ移動 void Update(){ • 2秒待つ 下へ移動; • 5回繰り返す 2秒待つ; • 弾を撃つ 5回繰り返す { • 1秒待つ 弾を撃つ; 1秒待つ; } } 理想
  10. 10. 例(C#)ゲームで敵キャラクターの制御をしたい • 下へ移動 void Update(){ • 2秒待つ 下へ移動; • 5回繰り返す 2秒待つ; • 弾を撃つ 5回繰り返す { • 1秒待つ 弾を撃つ;ここで処理を止めたいけど、 1秒待つ;この関数を抜けないと他の関数の処理ができず }ゲーム全体が止まってしまう! } 理想 現実
  11. 11. 例(C#)そこでコルーチン ここでは1秒 = 60フレームIEnumerator Update(){ 下へ移動; for( int i = 0; i < 120; ++i ) void 2秒待つ // Update(){ yield return 0; 下へ移動; for( int i = 0; i < 5; ++i ){ 2秒待つ; 弾を撃つ; 5回繰り返す for( int j = 0; j < 60; ++j ) // 1秒待つ{ yield return 0; 弾を撃つ; } 1秒待つ;} } }
  12. 12. コルーチンなしだと毎フレーム呼び出してもらうしかない ここでは1秒 = 60フレームint t = 0; カウンターが必要void Update(){ if( t == 0 ){ 下へ移動; for文も使えないので、変な条件式を書く } if( t >= 120 && ( t – 120 ) % 60 == 0 && t < 120 + 60 * 5 ){ 弾を撃つ; } ++t; 時間を絶対的に指定}
  13. 13. 使い道• RPGの戦闘シーンなど • プレイヤーの作戦が決まるまで戦闘の進行を止める • エフェクトの表示が終わるまで戦闘の進行を止める• 状態のシーケンスの管理 • 敵が歩いて登場する状態 → 攻撃する状態 → 攻撃が終わって退場する状態• 遅延評価 • 呼び出しが達するまで計算しないことで無駄を省く • 無限の量の計算を途中で打ち切る• ジェネレータ(値を列挙する)
  14. 14. 使い道:遅延評価IEnumerator Fiber(){ void Main(){ Func(); var x = Fiber(); yield return 0; x.MoveNext(); Func(); x.MoveNext(); yield return 0; } HeavyFunc(); // 実行されない yield return 0;}
  15. 15. 使い道:ジェネレータIEnumerator Fiber(){ void Main(){ yield return 3; var x = Fiber(); yield return 1; x.MoveNext(); yield return 4; x.Current; // 3 x.MoveNext(); yield return 1; x.Current; // 1 yield return 5; x.MoveNext();} x.Current; // 4 }
  16. 16. コルーチンを使える言語機能• C#のイテレータ• Luaのコルーチン• Pythonのジェネレータ• Rubyのファイバー• 東方弾幕風スクリプトのマイクロスレッド• (まだあるかも)
  17. 17. ありがとうございました

×