Я создаю клон понг в C ++ с использованием SDL. Весла готовы и перемещаются в соответствии с пользовательским вводом. Что меня беспокоит, так это то, что ввод странный, я ожидал плавного движения обеих лопастей, но одна лопасть отстает, когда другая лопасть движется, и ускоряется, когда другая не движется. Я сомневаюсь, вызвано ли это не ограничением FPS или странным способом, которым мне удалось получить многократный ввод или оба. Может кто-нибудь сказать мне, что не так в моем коде и как его улучшить?
Мой код:
#include <SDL/SDL.h>
#include <string>
#include "SDL/SDL_image.h"#include <SDL/SDL_ttf.h>
bool quit = false;
bool keyheld[323]={false};
const int SCREEN_WIDTH = 800;
const int SCREEN_HEIGHT = 600;
const int SCREEN_BPP = 32;
int paddle1x = 0;
int paddle1y = 50;
int paddle2x = 600;
int paddle2y = 500;
SDL_Color color = {255,255,255};
SDL_Event event;
SDL_Surface* screen = NULL;
SDL_Surface* timer = NULL;
SDL_Surface* background = NULL;
SDL_Surface* paddle1 =NULL;
SDL_Surface* paddle2 = NULL;
void apply_surface(int x, int y, SDL_Surface* source, SDL_Surface* destination)
{
SDL_Rect offset;
offset.x = x;
offset.y = y;
SDL_BlitSurface(source, NULL,destination, &offset);
}
SDL_Surface *load_image(std::string filename)
{
SDL_Surface* loadedimage = NULL;
SDL_Surface* optimisedimage = NULL;
loadedimage= IMG_Load(filename.c_str());
optimisedimage= SDL_DisplayFormatAlpha(loadedimage);
SDL_FreeSurface(loadedimage);
return optimisedimage;
}
int main(int argc, char *args[])
{
bool quit = false;
bool keyheld[323]={false};
int p1score=0;
int p2score=0;
SDL_Init(SDL_INIT_EVERYTHING);
TTF_Init();
TTF_Font *font=NULL;
screen = SDL_SetVideoMode(SCREEN_WIDTH,SCREEN_HEIGHT,SCREEN_BPP,SDL_SWSURFACE);
background = load_image("background.png");
apply_surface(0,0,background,screen);
paddle1 = load_image("paddle1.png");
apply_surface(paddle1x,paddle1y,paddle1,screen);
paddle2=load_image("paddle2.png");
apply_surface(paddle2x,paddle2y,paddle2,screen);font = TTF_OpenFont("kremlin.ttf", 22);
timer = TTF_RenderText_Solid(font,"Test!",color);
apply_surface(0,0,timer,screen);
SDL_WM_SetCaption("PONG!",NULL);
SDL_Flip(screen);
while(quit==false)
{
if(SDL_PollEvent(&event))
{
SDLKey keyPressed = event.key.keysym.sym;
if(event.type==SDL_QUIT)
{
return 0;
}
else if(event.type==SDL_KEYDOWN)
{
keyheld[keyPressed] = true;
}
else if(event.type==SDL_KEYUP)
{
keyheld[keyPressed] = false;
}}
if(keyheld[SDLK_LEFT])
{
paddle1x--;
apply_surface(0,0,background,screen);
apply_surface(paddle1x,paddle1y,paddle1,screen);
apply_surface(paddle2x,paddle2y,paddle2,screen);
}
if(keyheld[SDLK_RIGHT])
{
paddle1x++;
apply_surface(0,0,background,screen);
apply_surface(paddle1x,paddle1y,paddle1,screen);
apply_surface(paddle2x,paddle2y,paddle2,screen);
}
if(keyheld[SDLK_a])
{
paddle2x--;
apply_surface(0,0,background,screen);
apply_surface(paddle1x,paddle1y,paddle1,screen);
apply_surface(paddle2x,paddle2y,paddle2,screen);
}
if(keyheld[SDLK_d])
{
paddle2x++;
apply_surface(0,0,background,screen);
apply_surface(paddle1x,paddle1y,paddle1,screen);
apply_surface(paddle2x,paddle2y,paddle2,screen);
}
apply_surface(0,0,timer,screen);
SDL_Flip(screen);
SDL_Delay(2);
}
return 0;
}
Проблема в том, что вы обновляете backbuffer для каждого типа движения весла. Если оба весла двигаются, вы обновляете его дважды. Это где вы сталкиваетесь с замедлением. Вы должны обновлять буфер только один раз за каждый кадр. Вот так:
if(keyheld[SDLK_LEFT])
{
paddle1x--;
}
if(keyheld[SDLK_RIGHT])
{
paddle1x++;
}
if(keyheld[SDLK_a])
{
paddle2x--;
}
if(keyheld[SDLK_d])
{
paddle2x++;
}
// Now we do the update. You can always add a flag to see if the update
// really needs to be done and skip it if it doesn't
apply_surface(0,0,background,screen);
apply_surface(paddle1x,paddle1y,paddle1,screen);
apply_surface(paddle2x,paddle2y,paddle2,screen);
apply_surface(0,0,timer,screen);
SDL_Flip(screen);
SDL_Delay(2);
Других решений пока нет …