我正在使用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);
任何和所有帮助解决这个混乱将非常感激。感谢。
答案 0 :(得分:0)
我的评论最终解决了OP的问题。提交答案表以供将来参考:
如果main()中的keyPressed()函数被意外地每帧调用,或许它在某种意义上使第二个keyPressed()调用失灵。如果对keyPressed的调用查找自上次调用以来按下的最后一个键,那么第一个调用可能是“接收”该键,然后第二个调用实际上想要接收密钥的是nada。有时虽然你很幸运并在keyPressed()电话号码1和电话号码2之间按下该键。如果这是一个紧凑的循环,这可能是一个简短的窗口,它解释了你有时会“正常工作”的行为。