我是c ++和游戏编程的初学者,我正在尝试创建一个接受来自用户的一系列键盘输入的游戏,并且在按下回车时应该根据按下的键显示精灵中的精灵的动作。
我正在使用SDL 2并且每按一次键就可以移动我的精灵但是我想等待所有输入,然后在用户按下ENTER键后连续显示所有动作。到目前为止,我想出了如下所示的代码。
(我使用了一个计数器变量来保存按下任意箭头键的次数,以及一个用于在屏幕上存储其位置和速度的精灵类。)
SDL_Event e;
bool quit = false;
bool startSprite = false;
Sprite sprite1;
while (!quit)
{
while (SDL_PollEvent(&e) && startSprite== false)
{
if (e.type == SDL_QUIT)
{
quit = true;
}
if (e.type == SDL_KEYDOWN || e.type == SDL_KEYUP)
{
//true if ENTER key is pressed
if (e.key.keysym.sym == SDLK_RETURN)
{
startSprite = true;
}
//Handle input for the sprite
sprite1.handleEvent(e);
}
}
//if the ENTER key is pressed
if(startSprite==true)
{
//Clear the window
SDL_RenderClear(renderer);
drawTiles(xTiles, yTiles, background, renderer);
//if the counter > 0, loop through and display each movement until the
//total count number is reached
if(count>0)
{
for(int i=0;i<count;i++)
{
sprite1.move();
//display the image
drawImages(image, image2, image3, sprite1, renderer);
//Update the screen
SDL_RenderPresent(renderer);
}
count=0;
}
//startSprite==false;
}
处理精灵事件的代码
void Sprite::handleEvent( SDL_Event& e )
{
//If a key was pressed
if( e.type == SDL_KEYDOWN ) //&& e.key.repeat == 0
{
//Adjust the velocity
switch( e.key.keysym.sym )
{
case SDLK_UP: mVelY -= SPRITE_VEL; break;
case SDLK_DOWN: mVelY += SPRITE_VEL; break;
case SDLK_LEFT: mVelX -= SPRITE_VEL; break;
case SDLK_RIGHT: mVelX += SPRITE_VEL; break;
case SDLK_RETURN: startSprite=true; break;
}
count++;
}
//If a key was released
else if( e.type == SDL_KEYUP ) //&& e.key.repeat == 0
{
//Adjust the velocity
switch( e.key.keysym.sym )
{
case SDLK_UP: mVelY += SPRITE_VEL; break;
case SDLK_DOWN: mVelY -= SPRITE_VEL; break;
case SDLK_LEFT: mVelX += SPRITE_VEL; break;
case SDLK_RIGHT: mVelX -= SPRITE_VEL; break;
case SDLK_RETURN: startSprite=true; break;
}
}
}
精灵类的移动功能
void Sprite::move()
{
//Move the sprite left or right
mPosX += mVelX;
//If the sprite went too far to the left or right
if( ( mPosX < 0 ) || ( mPosX + SPRITE_WIDTH > SCREEN_WIDTH ) )
{
//Move back
mPosX -= mVelX;
}
//Move the sprite up or down
mPosY += mVelY;
//If the sprite went too far up or down
if( ( mPosY < 0 ) || ( mPosY + SPRITE_HEIGHT > SCREEN_HEIGHT ) )
{
//Move back
mPosY -= mVelY;
}
}
然而这并不起作用,因为startSprite由于某种原因没有设置为true,我的代码永远不会离开while循环。
如果我从while循环语句中删除条件,则按顺序按箭头键然后按Enter键没有任何反应
和然后如果我按箭头键移动精灵,精灵会随着每次按键移动。我完全糊涂了,整天都在这里。我似乎无法弄清楚我哪里出错了。
答案 0 :(得分:0)
我打算在评论中写这个,但它变得太长了。它可能不是您正在寻找的答案......
如果你想到你的代码中的逻辑,当你按下一个未输入的键时会发生什么会发生handleEvent将运行并且速度将被调整,当你最后按下enter时,移动循环需要超过并开始移动精灵,但是......如果你按下一次又一次,速度将保持不变,因为这些动作相互抵消,并且移动将是两次没有。
您需要做的是推迟处理事件,直到您完全按下返回,这样您才能在输入后开始处理事件。
如果您将事件添加到std::queue<SDL_Event>
(使用queue.push_back(e)
),则可以在按Enter后循环检索它们,并且对于每个事件调用,handleEvent 和移动函数,如果你真的想看到逐步执行的移动,可能会有一点延迟。
它看起来像这样:
while (!queue.empty())
{
SDL_Event e = queue.front();
sprite1.handleEvent(e);
SDL_RenderClear(renderer);
drawTiles(xTiles, yTiles, background, renderer);
sprite1.move();
drawImages(image, image2, image3, sprite1, renderer);
SDL_Delay(200); // possible delay.
SDL_RenderPresent(renderer);
queue.pop();
}