9

私は古い学校の ASCII DOS プロンプト ゲームを書いています。正直なところ、私は ZZT をエミュレートして、このブランドのゲーム デザインについてもっと学ぼうとしています (時代遅れであっても)。

私はうまくやっています。全画面テキスト モードが機能し、世界を作成して問題なく動き回ることができますが、レンダリングの適切なタイミング方法が見つかりません。

time.h からの delay()s または (clock()-renderBegin)/CLK_TCK チェックを追加しないと、レンダリングが非常に高速になるため、レンダリングとプリレンダリングのコードが高速であることはわかっています。

delay() は使用したくありません。これは、私のナレッジ プラットフォーム固有のものであり、その上、遅延している間はコードを実行できないためです (ユーザー入力や処理など)。だから私はこのようなことをすることにしました:

do {
    if(kbhit()) {
        input = getch();
        processInput(input);
    }

    if(clock()/CLOCKS_PER_SEC-renderTimer/CLOCKS_PER_SEC > RenderInterval) {
        renderTimer = clock();
        render();
        ballLogic();
    }
}while(input != 'p');

「理論的には」うまくいくはずです。問題は、このコードを実行すると (RenderInterval を 0.0333 または 30fps に設定)、どこにも 30fps に近づかず、最大で 18 のようになることです。

RenderInterval を 0.0 に設定して、パフォーマンスが向上するかどうかを確認しようと思いましたが、そうではありませんでした。私は (RenderInterval が 0.0 の場合) 最大で 18 ~ 20 fps になりました。

おそらく、これらすべての clock() メソッドと「これをそれで割る」メソッドを継続的に呼び出しているため、CPU の速度が恐ろしいほど低下していたのかもしれませんが、if ステートメントの括弧から render と ballLogic 呼び出しを取り出し、RenderInterval を0.0 ここでも、非常に高速なレンダリングが得られます。

これは私には意味がありません。なぜなら、if チェックインをそのままにしておくと、動作が遅くなるのではないでしょうか? つまり、まだすべての計算を行う必要があります

ところで、私は Borland の Turbo C++ V1.01 でコンパイルしています。

4

5 に答える 5

2

最高のゲーム体験は、通常、モニターの垂直リトレースと同期することによって実現されます。これにより、タイミングが提供されるだけでなく、少なくともコンピューターに接続された CRT モニターを使用している場合は、画面上でゲームがよりスムーズに実行されます。

80x25 テキスト モードでは、垂直リトレース (VGA 上) が毎秒 70 回発生します。周波数が EGA/CGA で同じだったかどうかは覚えていませんが、Hercules と MDA で 50 Hz だったことは確かです。たとえば 20 フレームの継続時間を測定することで、どの周波数を扱っているかを十分に見積もることができます。

メインループを次のようにします。

  while (playing) {
     do whatever needs to be done for this particular frame
     VSync();
  }

  ...  /* snip */

  /* Wait for vertical retrace */
  void VSync() {
    while((inp(0x3DA) & 0x08));
    while(!(inp(0x3DA) & 0x08));
  }
于 2010-09-05T11:26:00.833 に答える
1
clock()-renderTimer > RenderInterval * CLOCKS_PER_SEC

パーツを事前に計算すると、計算が少し速くなる可能性がありますRenderInterval * CLOCKS_PER_SEC

于 2010-07-22T13:13:34.810 に答える
1

すぐにレンダリングされない理由がわかりました。作成したタイマーは問題ありません。問題は、実際の clock_t の精度が .054547XXX 程度しかないため、18 fps でしかレンダリングできなかったことです。これを修正する方法は、より正確な時計を使用することです...これはまったく別の話です

于 2010-07-24T11:30:03.080 に答える
0

最近の質問に気付いたように、CLOCKS_PER_SECによって制限されています。これは約18です。クロックの離散値ごとに1フレームを取得するため、18fpsに制限されます。

タイミングに画面の垂直帰線区間を使用できます。これは、「ティアリング」(画面の半分が1つのフレームを示し、半分が別のフレームを示す)を回避するため、ゲームでは伝統的です。

于 2010-07-23T15:43:39.070 に答える
0

これはどうですか: x (=clock()) y (=renderTimer) から減算しています。x と y の両方が CLOCKS_PER_SEC で除算されています。

clock()/CLOCKS_PER_SEC-renderTimer/CLOCKS_PER_SEC > RenderInterval

次のように書く方が効率的ではないでしょうか:

( clock() - renderTimer ) > RenderInterval

除算で最初に見た問題は、2 つの long int の間で発生するため、除算から実数を取得できないことでした。secons の問題は、RenderInterval * CLOCKS_PER_SEC を乗算する方が効率的であり、この方法でそれを取り除き、操作を簡素化することです。

ブラケットを追加すると、読みやすくなります。そして、この数式を単純化することで、何が問題なのかを簡単に理解できるようになるでしょう。

于 2010-07-22T13:14:26.323 に答える