Я написал программу, чтобы прыгать вокруг прямоугольника. Я использую SDL_RenderFillRect, чтобы нарисовать прямоугольник, и SDL_RenderPresent, чтобы представить этот прямоугольник, после чего SDL_RenderClear очищает средство визуализации, чтобы сделать все заново. Я использую SDL_GetTicks и SDL_Delay, чтобы заставить его обновляться 60 раз в секунду, но скорость прямоугольника почему-то не ровная, а не плавная. Последние несколько дней я пробовал разные вещи, но ничего не помогло. Есть ли особый способ, которым я должен использовать SDL_RenderPresent, чтобы мое окно регулярно обновлялось?
#include <SDL.h>
#include <math.h>
#include <iostream>
#include <stdio.h>
const int width = 1200;
const int height = 800;
const double PI = 3.141592653589793;
void init();
void quit();
double x = width / 2;
double y = height / 2;
double r = 25;
double vx = 1;
double vy = 1;
double s = 4;
double tickStart = SDL_GetTicks();
double tickEnd = 0;
double tickDelta = 0;
double frameTime = 1001.0 / 60.0;
double delayTime = 0;
int c = 0;
SDL_Window* window;
SDL_Renderer* renderer;
SDL_Event *event;
SDL_Rect rect;
int main(int argc, char* argv[]) {
init();
// main loop
bool running = true;
while (running) {
event = new SDL_Event;
while (SDL_PollEvent(event) != 0) {
if (event->type == SDL_QUIT) {
running = false;
break;
}
}
//renderer
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderClear(renderer);
SDL_SetRenderDrawColor(renderer, 0, 0, 255, 255);
// update position
x = x + vx*s;
y = y + vy*s;
// check wall collision
if (x - r <= 0) {
vx = -vx;
x = r;
}
else if (x + r >= width) {
vx = -vx;
x = width - r;
}
if (y - r <= 0) {
vy = -vy;
y = r;
}
else if (y + r >= height) {
vy = -vy;
y = height - r;
}
// rect
rect.h = rect.w = 2 * r;
rect.x = x - r;
rect.y = y - r;
SDL_RenderFillRect(renderer, &rect);
// present everything at the right time
tickEnd = SDL_GetTicks();
tickDelta = tickEnd - tickStart;
delayTime = frameTime - tickDelta;
std::cout << tickDelta << std::endl;
if (delayTime > 0)
SDL_Delay(delayTime);
tickStart = SDL_GetTicks();
SDL_RenderPresent(renderer);
c++;
}
quit();
return 0;
}
void init()
{
SDL_Init(SDL_INIT_EVERYTHING);
window = SDL_CreateWindow("test", 200, 100, width, height, SDL_WINDOW_SHOWN);
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
}
void quit()
{
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_QUIT;
}
Вызов SDL_Delay () может занять около 15 мс в зависимости от обстоятельств. Рендерер может быть синхронизирован по вертикали путем назначения правого флага: renderer = SDL_CreateRenderer (window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
Других решений пока нет …