Fistashka & Pipius
Fistashka Fistashka
Привет, Пипиус, представляешь, если бы мы могли запрограммировать игру, где расположение уровней крутилось бы, как волчок, каждый раз при нажатии кнопки? Ты бы взялся за это?
Pipius Pipius
Звучит как сумасшествие, но я люблю сумасшествие. Давай придумаем физический движок, который будет рассматривать карту как жесткое тело, использовать кватернионное вращение вокруг центра масс при каждом нажатии кнопки и обновлять коллайдер в реальном времени. Начну с простого 2D прототипа на SDL, а потом расширю до 3D со своей физической петлей. Не парься насчет интерфейса, если он будет тормозить, я его просто выкину. Готова взяться?
Fistashka Fistashka
Ого, вот это будет ураган! Я за – давайте превратим это в сумасшедшее приключение! Давай только первый кусок кода, и я сразу же вложусь с безумной идеей для обновления коллайдерной сетки. UI оставим по желанию, кому он вообще нужен, когда можно танцевать на грани физики? Вперед!
Pipius Pipius
Привет, дорогая. Слушай, тут какая-то интересная штука с вращением, хочу тебе показать. Может, вечером?
Fistashka Fistashka
Боже мой, отличное начало, но давай поднимем планку! Вместо того, чтобы крутить матрицу рендеринга, используй `SDL_RenderCopyEx`, чтобы вращать каждую плитку вокруг своего центра – так будет гораздо плавнее. А этот твой трюк с косинусом и синусом с масштабированием немного кривой; плитки получится приплюснуть. И, кстати, может, просто веди простейший вектор для центра масс и вращай всё это поле плиток вокруг него, чтобы уровень ощущался как вращающийся карусель. Готова, чтобы ты переделал математику для настоящего вращения и посмотрел, какой хаос получится? Давай!
Pipius Pipius
Понял, забудь про этот хак с матрицей, будем использовать SDL_RenderCopyEx для настоящей ротации. Я буду хранить глобальный центр масс, вращать позицию каждой плитки вокруг него и передавать это в RenderCopyEx. Вот обновлённый кусок: ```c // добавить это вверху typedef struct { double x, y; } Vec2; Vec2 cm = { WIDTH/2.0, HEIGHT/2.0 }; // вращаем точку вокруг cm Vec2 rotatePoint(Vec2 p, double ang) { double s = sin(ang), c = cos(ang); Vec2 np; np.x = (p.x - cm.x)*c - (p.y - cm.y)*s + cm.x; np.y = (p.x - cm.x)*s + (p.y - cm.y)*c + cm.y; return np; } void renderTiles(SDL_Renderer *ren) { for (int i = 0; i < numTiles; ++i) { SDL_Rect dst = tiles[i].rect; Vec2 pos = {dst.x + dst.w/2, dst.y + dst.h/2}; pos = rotatePoint(pos, tiles[i].angle); dst.x = pos.x - dst.w/2; dst.y = pos.y - dst.h/2; SDL_SetRenderDrawColor(ren, 200, 100, 50, 255); SDL_RenderFillRect(ren, &dst); // пока просто заливаем // в будущем заменим на RenderCopyEx с текстурой } } // в основном цикле после обработки ввода for (int i = 0; i < numTiles; ++i) rotateTile(&tiles[i], ROT_SPEED); renderTiles(ren); ``` Теперь каждая плитка вращается вокруг общего центра, и позже ты сможешь заменить заливку на настоящий спрайт через RenderCopyEx. Пора посмотреть на этот хаос.
Fistashka Fistashka
Звучит здорово! 🎉 Только небольшая поправка: следи, чтобы угол поворота оставался в пределах от 0 до 2π, иначе плитки начнут немного... странно вращаться. И когда будешь подменять текстуры, не забудь установить точку вращения в `SDL_RenderCopyEx`, чтобы они крутились именно там, где нужно. Очень жду, когда увижу весь уровень, танцующий сальсу! Не теряй задор!
Pipius Pipius
Пожалуйста, поддерживай угол в пределах от 0 до 2π, добавь короткое условие после rotateTile. При смене текстуры передавай центр тайла вторым параметром в RenderCopyEx – так ось вращения останется на месте, и танцы будут плавными. Ты увидишь, как оживает весь уровень. Следи за расчетами, не давай тайлам плыть. Давай добавим огня на танцполе.
Fistashka Fistashka
Поняла – острые углы, чёткий ритм. Просто загрузи текстуру на каждый тайл, выстави пивот в центр и дай RenderCopyEx поработать. Следим, чтобы ничего не сбивалось, все крутится в такт. Готова превратить это в настоящий рейв? Поехали!