• ベストアンサー

Delphiでキューを作りたい

Delphi初心者です。ゲームを制作中なのですが、相談に乗って頂けますでしょうか。 プログラムの骨格は、演算→描画の繰り返しなんですが、演算結果を次々と描画ルーチンに渡すと、描画が間に合わなくなったときに破綻してしまいます。 (描画で使っているコンポーネントがクラッシュしてしまう) そこで、演算部で表示させるものを計算しキューに追加していき、CPUのアイドル時間を見つけてはキューから順次取り出して描画、という方法を試したいと思います。 (オーバーフローしたら破棄する) そこで、スタックとかキューを使ったことがないのですが、単純に配列を使って、 1.データを最後尾に加える 2.データを先頭から出し、順次前に詰める 簡単な方法があったら教えて頂きたいと思います。 (それくらい手動でやれと言われそうですね(^_^;) よろしくお願いいたします。

質問者が選んだベストアンサー

  • ベストアンサー
  • mikiki_7
  • ベストアンサー率100% (2/2)
回答No.3

補足です。 上記ではちょっと説明が足りないようなのでかってに補足させてもらいます 実際のバッファリング処理では 演算の結果 ↓ 描画(描画用のスレッドにてバッファに書き込み) 更新タイミング *作成者指定 ↓ 転送(描画部分のスレッドと同期してる状態が前提) 画面更新 以上のプロセスを経て表示が行なわれます。 これが基本的なバッファリング描画です トリプルバッファリングはこの描画用のバッファが2つになり交互に描画を行なうわけです。 ただ、交互に行なうのでは意味が無いので一部特殊な処理がありますが :-) 前提 演算の結果を描画する場合に転送待ち、描画中のバッファで利用できるバッファが無い時はその回の描画処理をキャンセルする。 演算の結果 ↓ 描画(描画用のスレッドにてバッファに書き込み) 更新タイミング ※画面のリフレッシュレートに併せたかたち ↓ 転送(描画部分のスレッドと同期 ※描画が完了してなければ行なわない。 ↓    この時点で後からの描画処理が完了してるようであればそちらを表示する ↓    後からの描画処理が完了した時点で前のバッファの内容を破棄し描画処理を行なえるように処理) 画面更新 ↓ 描画、転送用のバッファを切り替え 大体こんな感じです ダブルバッファリングですと描画転送が完了してからでないと描画処理が新たに行なえないので物によっては大幅に描画速度が低下します。(フレーム落ちが出ます) トリプルバッファリングですと、描画中に再度描画処理が行なえますのでマシンのパフォーマンスを最大限に発揮できますが、マシンスペックが極端に低いと速度低下が激しくなります。

pythian
質問者

お礼

詳細なご説明、ありがとうございます。簡単そうで実は奥が深いんですね。ゲームプログラミングの専門書で勉強してみたいと思います。まずは簡単なものから始めて、自在にバッファを操れるようになりたいです(自作モノの改良はそれから^^;)。ありがとうございました。

その他の回答 (2)

  • honiyon
  • ベストアンサー率37% (331/872)
回答No.2

こんにちは、honiyonです。  Delphiでしたら、DelphiXを使うと簡単ですよ。  さて、それはさておきキューの実現方法ですが、TStringListクラスはご存じですか?簡単に説明すると、リストボックスみたいに文字列を「リスト」にして保存しておく事の出来るクラスです。(詳しくはヘルプを参照してください)  データが文字列の場合はこれを使えば良いですが、そうでない時は TStringListの抽象クラスにあたる TListをオーバーライドして使えばそんな事も簡単に実現出来ちゃいます。(TListはデータのポインタを保持します)  で、実際の使い方は、 List.Add(Data); で追加して、取り出し時は Data := List[0]; List.Delete(0); こんな感じです。  参考になれば幸いです(..  

pythian
質問者

お礼

なるほど、とても参考になりました。初心者なもので、いまいち直接目に見えないクラスは苦手なもので・・・いろいろと試してみます。ありがとうございました。

  • MarrowG
  • ベストアンサー率53% (41/76)
回答No.1

動きの激しいゲームをコンポーネントだけで作るのはちょっと厳しいかと思いますが…。(^^; 動きの激しいゲームでは以下のようにしているのが普通です。 画面描画用のワークメモリに描画する。 ワークメモリの内容をBITMAPとして画面に一括転送。(WindowsAPIで言えばBitBlt) いわゆるダブルバッファという方法ですが、これだと画面のちらつきが抑えられます。 また画面描画メモリを2つ使用するトリプルバッファという方法もあります。 これは、 1.画面描画用のワークメモリAに描画する。 2.ワークメモリAの内容をBITMAPとして画面に一括転送。 3.画面描画用のワークメモリBに描画する。 4.ワークメモリBの内容をBITMAPとして画面に一括転送。 の繰り返しです。(実際には2と4は1、3終了後に非同期で行うのが普通) これですと、1が間に合わなければ、次に描画するタイミングでは3を行うので、ワークメモリAやBの処理量は半分で済むことになります。 描画コンポーネントで実現するのであれば、ワーク用に2つ、実際の表示用に1つ作成して、上記のようなトリプルバッファ方式を使えば少しはマシになるかと思います。 でも、出来るかどうかわかりませんが…。(汗

pythian
質問者

お礼

単純な描画でそんなに動きは激しくないので、コンポーネントでやっています。自分でバッファリングするほど技量もないもので・・・。(^^; 描画メモリを確保して転送しながらというのは、いつかやってみたいです。もし参考になるページや書籍等ありましたら、教えていただければ幸いです。 もう少し頑張ってみます。ありがとうございました。

関連するQ&A