
Delphi初心者です。ゲームを制作中なのですが、相談に乗って頂けますでしょうか。
プログラムの骨格は、演算→描画の繰り返しなんですが、演算結果を次々と描画ルーチンに渡すと、描画が間に合わなくなったときに破綻してしまいます。
(描画で使っているコンポーネントがクラッシュしてしまう)
そこで、演算部で表示させるものを計算しキューに追加していき、CPUのアイドル時間を見つけてはキューから順次取り出して描画、という方法を試したいと思います。
(オーバーフローしたら破棄する)
そこで、スタックとかキューを使ったことがないのですが、単純に配列を使って、
1.データを最後尾に加える
2.データを先頭から出し、順次前に詰める
簡単な方法があったら教えて頂きたいと思います。
(それくらい手動でやれと言われそうですね(^_^;)
よろしくお願いいたします。
No.3ベストアンサー
- 回答日時:
補足です。
上記ではちょっと説明が足りないようなのでかってに補足させてもらいます
実際のバッファリング処理では
演算の結果
↓ 描画(描画用のスレッドにてバッファに書き込み)
更新タイミング *作成者指定
↓ 転送(描画部分のスレッドと同期してる状態が前提)
画面更新
以上のプロセスを経て表示が行なわれます。
これが基本的なバッファリング描画です
トリプルバッファリングはこの描画用のバッファが2つになり交互に描画を行なうわけです。
ただ、交互に行なうのでは意味が無いので一部特殊な処理がありますが :-)
前提
演算の結果を描画する場合に転送待ち、描画中のバッファで利用できるバッファが無い時はその回の描画処理をキャンセルする。
演算の結果
↓ 描画(描画用のスレッドにてバッファに書き込み)
更新タイミング ※画面のリフレッシュレートに併せたかたち
↓ 転送(描画部分のスレッドと同期 ※描画が完了してなければ行なわない。
↓ この時点で後からの描画処理が完了してるようであればそちらを表示する
↓ 後からの描画処理が完了した時点で前のバッファの内容を破棄し描画処理を行なえるように処理)
画面更新
↓
描画、転送用のバッファを切り替え
大体こんな感じです
ダブルバッファリングですと描画転送が完了してからでないと描画処理が新たに行なえないので物によっては大幅に描画速度が低下します。(フレーム落ちが出ます)
トリプルバッファリングですと、描画中に再度描画処理が行なえますのでマシンのパフォーマンスを最大限に発揮できますが、マシンスペックが極端に低いと速度低下が激しくなります。
詳細なご説明、ありがとうございます。簡単そうで実は奥が深いんですね。ゲームプログラミングの専門書で勉強してみたいと思います。まずは簡単なものから始めて、自在にバッファを操れるようになりたいです(自作モノの改良はそれから^^;)。ありがとうございました。
No.2
- 回答日時:
こんにちは、honiyonです。
Delphiでしたら、DelphiXを使うと簡単ですよ。
さて、それはさておきキューの実現方法ですが、TStringListクラスはご存じですか?簡単に説明すると、リストボックスみたいに文字列を「リスト」にして保存しておく事の出来るクラスです。(詳しくはヘルプを参照してください)
データが文字列の場合はこれを使えば良いですが、そうでない時は TStringListの抽象クラスにあたる TListをオーバーライドして使えばそんな事も簡単に実現出来ちゃいます。(TListはデータのポインタを保持します)
で、実際の使い方は、 List.Add(Data); で追加して、取り出し時は Data := List[0]; List.Delete(0); こんな感じです。
参考になれば幸いです(..
なるほど、とても参考になりました。初心者なもので、いまいち直接目に見えないクラスは苦手なもので・・・いろいろと試してみます。ありがとうございました。
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つ作成して、上記のようなトリプルバッファ方式を使えば少しはマシになるかと思います。
でも、出来るかどうかわかりませんが…。(汗
単純な描画でそんなに動きは激しくないので、コンポーネントでやっています。自分でバッファリングするほど技量もないもので・・・。(^^;
描画メモリを確保して転送しながらというのは、いつかやってみたいです。もし参考になるページや書籍等ありましたら、教えていただければ幸いです。
もう少し頑張ってみます。ありがとうございました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- 画像編集・動画編集・音楽編集 ボカロの架空窓口の閉鎖という曲で動画を作りたい者です。 1 2022/06/13 18:12
- Visual Basic(VBA) エクセルマクロでアニメを作る方法を教えてください。 1 2023/02/07 14:27
- 美術・アート 【辛口でお願いします(*'ω'*)13才女子作の駄作ですがオリジナル漫画のワンシーンです!】 簡単に 5 2022/10/01 21:25
- 美術・アート ペンタブとオフィス系ソフト 1 2022/10/08 19:27
- その他(プログラミング・Web制作) プログラムの起動、利用について、使用期間を設定する方法 3 2023/08/06 21:03
- 美術・アート 【辛口でお願いします(>人<;)13才女子作の駄作ですがオリジナル漫画のワンシーンです!カラーにして 1 2022/10/05 04:27
- デザイン タブレットパソコンについて。 3 2022/10/22 15:19
- 美術・アート 【2枚目!辛口大丈夫です!オリジナル漫画のワンシーンです!】 もっと迫力のある演出にするにはどんな描 2 2022/09/27 22:27
- システム CPUの問題について 2 2022/07/09 12:04
- 美術・アート トレパク疑惑をかけられにくくするには ここ最近いわゆるトレパク警察のいいがかりがが厳しくなったようで 1 2023/08/21 09:59
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
TextBoxに文字を書いても表示さ...
-
[VB.net] DataGridViewの列ヘッ...
-
word
-
InvalidateRectの使い方について
-
クライアント領域を再描画させ...
-
VC++を使ってCで記述しグラフを...
-
google Colabでmatplotlibの描...
-
VC++プログラムをつかったBMP画...
-
OpenCV処理画像をpictureBoxへ。
-
DXライブラリについて(ゲーム...
-
Delphiでキューを作りたい
-
C#のタブコントロールについて...
-
panelのスクロール表示について
-
VB.netでのライン描画方法がわ...
-
StretchBlt関数について
-
CStaticコントロールの静的イメ...
-
円の描画の太さを指定できるCコ...
-
GDI+のDrawStringを使って文字...
-
WM_PAINTとBitBlt
-
CScrollViewの使用方法について
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
Minecraft 統合版(PC)の描画距...
-
[VB.net] DataGridViewの列ヘッ...
-
word
-
TextBoxに文字を書いても表示さ...
-
VB6,リストボックスの特定行の...
-
NVIDIAのシェーダーキャッシュ
-
panelのスクロール表示について
-
VC++プログラムをつかったBMP画...
-
VBAにGDI+を参照させる方法
-
google Colabでmatplotlibの描...
-
MFCでOnPaintのタイミング
-
MFCのタイマーのつかい方を教え...
-
UpdateData( FALSE); による文...
-
CStaticコントロールの静的イメ...
-
Form1 Load で実行されない。
-
InvalidateRectの使い方について
-
win32api 画面のちらつき
-
c++ ダブルバッファリング、以...
-
CDC(LineTo)で描画した線を透過...
-
BitBltでの表示での問題です。
おすすめ情報