我正在尝试制作一个可以运行模拟的程序。我希望模拟能够沿着设定的路径移动一个小图像或精灵,比如从一个角落移动到另一个角落,就像它正在绘制它一样。我也希望在按下键盘上的键时触发模拟,但是在移动图像后刷新图像时遇到了一些困难。
例如,我希望图像向左移动50个像素,然后向上移动50个像素,然后向右移动50个像素,然后向下移动50个像素,在每次移动后刷新屏幕上的图像,仅按一次“1”键盘上的键。
这是我到目前为止的代码,主要是从教程中提取的,目前只是每次按下时将图像移动4个像素,我不确定如何从这里开始:
int main(int argc, char ** argv)
{
// variables
bool quit = false;
SDL_Event event;
int x = 360;
int y = 240;
// init SDL
SDL_Init(SDL_INIT_VIDEO);
SDL_Window * window = SDL_CreateWindow("SDL2 Keyboard/Mouse events", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 800, 600, 0);
SDL_Renderer * renderer = SDL_CreateRenderer(window, -1, 0);
SDL_Surface * image = SDL_LoadBMP("Star.bmp");
SDL_Texture * texture = SDL_CreateTextureFromSurface(renderer, image);
SDL_FreeSurface(image);
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
// handle events
while (!quit)
{
switch (event.type)
{
case SDL_QUIT:
quit = true;
break;
case SDL_KEYDOWN:
switch (event.key.keysym.sym)
{
case SDLK_1:
x-=4;
break;
case SDLK_2:
x+=4;
break;
case SDLK_3:
y-=4;
break;
case SDLK_4:
y+=4;
break;
}
break;
}
SDL_Rect dstrect = {x, y, 75, 75};
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, texture, NULL, &dstrect);
SDL_RenderPresent(renderer);
}
// cleanup SDL
SDL_DestroyTexture(texture);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
答案 0 :(得分:0)
一个好的起点是跟踪每个while循环的delta时间,(尝试使用gettimeofday())
然后可以使用线性插值在位置之间转换对象。
按键按下:(向右移动)
if(doTransition == false)
{
doTransition = true;
startX = x;
startY = y;
endX = x + 50;
endY = Y;
}
每个循环:
if(doTransition == true)
{
tick += deltaTime;
float tval = MIN(tick / duration, 1);
x = startX + (endX - startX) * tval;
y = startY + (endY - startY) * tval;
if(tval == 1)
{
//finished transition
doTransition = false;
}
}
startX是按下键时图像的x位置
endX是转换结束时所需的x位置