0

スペースインベーダーに似た ncurses でゲームを作っています。

これまでのところ、動きと撃墜はありましたが、問題が発生しました。

プレイヤーがレーザーを発射するとき、画面の一方の端からもう一方の端にレーザーが表示されないように、usleep 呼び出しを使用して、レーザーが画面上を移動するのを遅らせています。

usleep を使用してレーザーを遅延させる問題は、レーザーが画面を横切って移動している間、ループが終了するまでプレーヤーが移動できないことを意味します。

私の質問は、ユーザー入力でプレーヤー/カーソルを同時に動かしながら、画面上を移動するレーザーを印刷する別の方法はありますか?

ユーザーが「f」キーを押すと、次のコードは画面上で線 (レーザー) を移動します。ただし、レーザーが画面から離れるまで、ユーザーは再び移動することはできません。

void combat(int y, int x)
{
    do
    {
        mvprintw(y -1, x, "|");
        refresh();
        y--;
        usleep(50000);
        mvprintw(y , x, " ");   
    }
    while(y>0);
}
4

3 に答える 3

0

最も簡単な解決策は、1 つのスリープ命令を含むループを使用してプログラムを作成することです。次に例を示します。

frame_timer = 0;
while (1) {
  if (player_is_alive) {
    move_player();
    move_aliens();
    move_laser_bullets();
    check_collisions();
  }
  else {
    draw_explosion();
    if (explosion_finished) break;
  }
  frame_timer++;
  usleep(20000);  /* Refresh at approximately 50fps */
}
于 2014-07-10T06:52:39.240 に答える
0

この問題は、外部スレッドなしでは簡単に解決できません。レーザーの動きを入力にバインドして (外部入力によって画面を更新する必要がある場合にのみ位置が更新されるように) スリープ機能を削除しても、レーザーは他のすべてから独立している必要があるため、機能しません。

汚いハックには次のものがある可能性があります。

  • 入力int nodelay(WINDOW *win, bool bf)関数が何もブロックしないように、入力関数を非ブロック化します。
  • 特定の (十分に高い) リフレッシュ レート、たとえば 10 FPS (100 ミリ秒のスリープ)
  • レーザーの位置をフレーム数ごとに 1 回だけ更新して、十分にゆっくりと移動させながら、十分な頻度で入力をポーリングできるようにする
于 2014-07-10T03:39:21.847 に答える