У меня есть сетка 300x300 ячеек. Я проверяю каждую ячейку по отдельности, что означает, что я проверяю 90000 ячеек по крайней мере каждую секунду. Я знаю, что одна секунда — это довольно быстро, учитывая, что процессор обрабатывает 300 ^ 2 разных ячеек. Но этот материал просто недостаточно быстр. Я наблюдал за парнем на YouTube, у которого его симуляция обновлялась каждые 20 мс. И у него было 512^2 ячеек. Как это возможно? Оптимизация? Мой компьютер - картошка? Я покажу свой код, если кто-то хочет увидеть, что именно я делаю.
for (int y = GY; y >= 0; y--)
for (int x = 0; x < GX; x++) {
cell* cell_pointer = &grid[x][y];
if (grid[x][y].CellT == type::SAND) {
if (grid[x][y+1].CellT == type::AIR) {
if (y+1 > GY-1) {
continue;
}
cell* cell_below = &grid[x][y+1];
cell_below->Color ={ 255,0,0 };
cell_below->CellT = type::SAND;
cell_pointer->Color ={ 0,0,0 };
cell_pointer->CellT = type::AIR;
}
else if (grid[x+1][y+1].CellT == type::AIR) {
cell* cell_below = &grid[x+1][y+1];
cell_below->Color ={ 255,0,0 };
cell_below->CellT = type::SAND;
cell_pointer->Color ={ 0,0,0 };
cell_pointer->CellT = type::AIR;
}
else if (grid[x-1][y+1].CellT == type::AIR) {
cell* cell_below = &grid[x-1][y+1];
cell_below->Color ={ 255,0,0 };
cell_below->CellT = type::SAND;
cell_pointer->Color ={ 0,0,0 };
cell_pointer->CellT = type::AIR;
}
}
}
Приведенный выше код — это моя функция обновления. Я обновляю ячейки снизу вверх, слева направо. Это симуляция песка, поэтому мы проверяем нижние левые, нижние правые, а также нижние соседние ячейки.
//Square//
SDL_SetRenderDrawColor(renderer, 0, 0, 255, 255);
SDL_RenderClear(renderer);
//////////
int X = floor(mousePos.x/r.w);
int Y = floor(mousePos.y/r.h);
if (left) {
grid[X][Y].CellT = type::SAND;
grid[X][Y].Color ={ 255,0,0 };
}
if (right) {
grid[X][Y].CellT = type::WALL;
grid[X][Y].Color ={ 0,255,0 };
}
for (int y = 0; y < GY; y++)
for (int x = 0; x < GX; x++) {
cell* cell_pointer = &grid[x][y];
SDL_SetRenderDrawColor(renderer, cell_pointer->Color.r, cell_pointer->Color.g, cell_pointer->Color.b, 255);
r.x = cell_pointer->PosG.x;
r.y = cell_pointer->PosG.y;
SDL_RenderFillRect(renderer, &r);
}
SDL_RenderPresent(renderer);
SDL_UpdateWindowSurface(window);
Приведенный выше код — это моя функция рисования. Я использую SDL в качестве графического API. Я получаю положение мыши относительно сетки, поэтому, когда я нажимаю левую или правую кнопку мыши, я могу нарисовать ячейку песка или ячейку стены. Поэтому я проверяю каждую ячейку по отдельности сверху вниз и слева направо, а затем рисую квадрат отдельно, где находится позиция ячейки.
for
дляx
иy
иногда может творить чудеса. - person Mooing Duck   schedule 22.07.2020y-1
до проверкиif (y+1 > GY-1)
, и в этом случае вы читаете за пределами допустимого. - person Mooing Duck   schedule 22.07.2020if
идентичны по коду и различаются только значениями, что означает, что в кэше инструкций содержится в 3 раза больше кода, чем необходимо, что теоретически может снизить производительность. На практике это вряд ли повлияет на что-то заметное. - person Mooing Duck   schedule 22.07.2020cell* cell_below = &grid[x][y+1];
и друзей. Говоря об этом, не тратьте свое время на скорость программы, если у вас не включена средняя или высокая оптимизация. - person user4581301   schedule 22.07.2020SDL_RenderClear(renderer)
, за которой следуют 90kSDL_RenderFillRect
вызовов. Это тонна данных, которые нужно передавать на видеокарту каждый кадр. - person Mooing Duck   schedule 22.07.2020SDL_RenderFillRect()
вызовов на кадр. Вы захотите изменить свой массив цветов состояния CA на стороне процессора, загрузите его в SDL_Texture, а затем нарисуйте ее. Таким образом, у вас будет только (по сути) только один вызов отрисовки графического процессора на кадр. - person genpfault   schedule 22.07.2020