0

Allegro 4 と C++ を使用してテトリスの簡単なバージョンを作成しています。ほとんどのコードが配置されており、ユーザー入力以外はすべて機能しています。キープレスは、いくつかのランダムな機会にのみゲームによって検出されます. タイミングの問題だと思いますが、捕まえられないようです。関連するコードは次のとおりです...

//Tetris.h


//Tetris class definition...

volatile long tet_counter = 0;

void increment_tet_counter()
{
  tet_counter++;
}
END_OF_FUNCTION(increment_tet_counter);

//this function gets called by the menu class when the user selects the Tetris option
//contains main loop, calls all other functions etc.
void Tetris::show(BITMAP* buffer, int& scr)
{
  LOCK_VARIABLE(tet_counter);
LOCK_FUNCTION(increment_tet_counter);
install_int_ex(increment_tet_counter, BPS_TO_TIMER(120));

while(tet_counter > 0)
{
   if(tet_scr == 1)  //welcome screen logic
   {
     if(key[KEY_E])
     {
       game_init();  //initialize game variables, etc.
       tet_scr = 2;  // go to main game screen
     }
     else if(key[KEY_I])   
     {
       tet_scr = 3;  //go to instructions screen
     }
     else if(key[KEY_Q])  //quit tetris
     {
       scr = 5;  //reference to a variable in the main.cpp, basically reverting the 
                 //main screen to the menu screen upon return
       return;
       }
   }  
   else if(tet_scr == 2)   //main game screen
   {
     if(cannot_move())   //managing auto-block movement, making the last line of blocks 
      {                  //permanent, etc... all of this works fine
       put_block();
       update_score(remove_filled_line());
       get_next_block();
      }
     move_block();  //handles auto-block movement and user input

   if(is_game_over())
    {textprintf_ex(screen, font, 500, 300, WHITE, -1, "GAME OVER!");
     rest(2000);
     tet_scr = 5;
     }

    if(key[KEY_P])  //pause game
      tet_scr = 4;

    if(key[KEY_Q])   //quit game
      tet_scr = 5;
   }

   //else ifs for other screens of the game... all work fine

  tet_counter--;                
}

//drawing functions ... work fine

}

//handles block movement... CPU-generated movement works, user input not detected mot of the time 
void Tetris::move_block()
{ 
 timer = (timer+1) % time_factor; 
 if(timer == time_factor-1)  //move block every couple of seconds
    block_y += 20;
 int k;
 if(keypressed())   //this is where the problem is (i think)
 {                  //the game only picks up the keypresses some of the times
 k = readkey();     //and sometimes when I keep the keypressed for a long time it work
  if(k >> 8 == KEY_DOWN)    //but it's very buggy and erratic and no way to predict
     block_y+=20;           //when it'll work and when it won't
  else if(k >> 8 == KEY_LEFT)
    block_x-=20;
  else if(k >> 8 == KEY_RIGHT)
    block_x+=20;
  else if(k >> 8 == KEY_UP)
    rotate_block();
 } 

 if(block_x < BOARD_X)
    block_x = BOARD_X;
 if(block_x > x_lim)
    block_x = x_lim;

 if(block_y < BOARD_Y)
    block_y = BOARD_Y;
 if(block_y > y_lim)
    block_y = y_lim;

}

//various other functions handling game logic/drawing etc are all working fine

以前とまったく同じ方法でテトリスを実装しましたが、包括的なメニュークラスはありません。.exe を実行するだけで、テトリス ゲームに直面します。その時はそのような問題はありませんでした。したがって、Tetris.h ファイルの外部のコードに関連して、ゲームをいじっている何かがあることは明らかです。私が「keypressed()」を使用する唯一の他の場所は、メインにあります...

while (counter > 0)
   {
         if(keypressed())
         {
           switch(readkey() >> 8)
           {
             case KEY_DOWN:
                  option++;
                  break;
             case KEY_UP:
                  option--;
                  break;
           }
         }

         if (option < 0)
             option = 5;
         else if (option > 5)
             option = 0;

         screen_handler(option, done);  //updates a variable using which the appropriate game is called in show_screen(), pong, breakout, snake are the other games

         counter--;
   }

   show_screen();  //this is where Tetris::show() is called
   blit(main_buffer, screen, 0, 0, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
   clear_bitmap(main_buffer);

この混乱を解決するためのすべての助けをいただければ幸いです。ありがとう。

4

1 に答える 1

0

私のコメントは、OPの問題を解決することになりました。将来の参照用に回答フォームに入れる:

main() 内のその keyPressed() 関数が誤ってすべてのフレームで呼び出されている場合、ある意味で 2 番目の keyPressed() 呼び出しが誤動作している可能性があります。keyPressed への呼び出しが、最後の呼び出し以降に押された最後のキーを検索する場合、最初の呼び出しはそのキーを「受信」している可能性があり、実際にキーを受信したい 2 番目の呼び出しは nada を取得しています。運が良ければ、keyPressed() 呼び出し番号 1 と呼び出し番号 2 の間にそのキーを押すことがあります。これがタイトなループである場合、これは「動作」している動作を説明する短いウィンドウである可能性があります。

于 2013-06-29T16:55:10.900 に答える