Compare commits

...
8 Commits
Author SHA1 Message Date
anime 2ad6ebf38d added all 2026-01-12 14:41:24 +06:00
anime 96deb8b393 corrected moving ship added moving camera 2025-12-29 18:59:06 +06:00
anime 47fe0c4719 added ship control 2025-12-11 21:14:39 +06:00
leyla da8946e9ef moving ship 2025-12-11 15:13:35 +06:00
anime c02273d29d added ship velocity using dragging volume 2025-12-10 20:58:10 +06:00
anime fec7e08c2b added dragging scroll button for music volume 2025-12-10 20:39:09 +06:00
anime 0f937e2e02 added music volume bar, without logic 2025-12-09 21:12:54 +06:00
Vladislav Khorev b768b27d49 update readme 2025-12-08 00:15:11 +03:00
7 changed files with 336 additions and 59 deletions

No files matched your search

+1 -1
View File
@@ -8,7 +8,7 @@ namespace ZL {
int Environment::windowHeaderHeight = 0;
int Environment::width = 0;
int Environment::height = 0;
float Environment::zoom = 6.f;
float Environment::zoom = 20.f;
bool Environment::leftPressed = false;
bool Environment::rightPressed = false;
+299 -57
View File
@@ -1,4 +1,4 @@
#include "Game.h"
#include "Game.h"
#include "AnimatedModel.h"
#include "BoneAnimatedModel.h"
#include "Utils.h"
@@ -17,13 +17,15 @@ namespace ZL
const char* CONST_ZIP_FILE = "";
#endif
Matrix3f rotateShipMat = Matrix3f::Identity();
Vector4f generateRandomQuaternion(std::mt19937& gen)
{
// Ðàñïðåäåëåíèå äëÿ ãåíåðàöèè ñëó÷àéíûõ êîîðäèíàò êâàòåðíèîíà
// Распределение для генерации случайных координат кватерниона
std::normal_distribution<> distrib(0.0, 1.0);
// Ãåíåðèðóåì ÷åòûðå ñëó÷àéíûõ ÷èñëà èç íîðìàëüíîãî ðàñïðåäåëåíèÿ N(0, 1).
// Íîðìàëèçàöèÿ ýòîãî âåêòîðà äàåò ðàâíîìåðíîå ðàñïðåäåëåíèå ïî 4D-ñôåðå (ò.å. êâàòåðíèîí åäèíè÷íîé äëèíû).
// Генерируем четыре случайных числа из нормального распределения N(0, 1).
// Нормализация этого вектора дает равномерное распределение по 4D-сфере (т.е. кватернион единичной длины).
Vector4f randomQuat = {
(float)distrib(gen),
(float)distrib(gen),
@@ -35,25 +37,25 @@ namespace ZL
}
// --- Îñíîâíàÿ ôóíêöèÿ ãåíåðàöèè ---
// --- Основная функция генерации ---
std::vector<BoxCoords> generateRandomBoxCoords(int N)
{
// Êîíñòàíòû
// Константы
const float MIN_DISTANCE = 3.0f;
const float MIN_DISTANCE_SQUARED = MIN_DISTANCE * MIN_DISTANCE; // Ðàáîòàåì ñ êâàäðàòîì ðàññòîÿíèÿ
const float MIN_DISTANCE_SQUARED = MIN_DISTANCE * MIN_DISTANCE; // Работаем с квадратом расстояния
const float MIN_COORD = -100.0f;
const float MAX_COORD = 100.0f;
const int MAX_ATTEMPTS = 1000; // Îãðàíè÷åíèå íà êîëè÷åñòâî ïîïûòîê, ÷òîáû èçáåæàòü áåñêîíå÷íîãî öèêëà
const int MAX_ATTEMPTS = 1000; // Ограничение на количество попыток, чтобы избежать бесконечного цикла
std::vector<BoxCoords> boxCoordsArr;
boxCoordsArr.reserve(N); // Ðåçåðâèðóåì ïàìÿòü
boxCoordsArr.reserve(N); // Резервируем память
// 1. Èíèöèàëèçàöèÿ ãåíåðàòîðà ïñåâäîñëó÷àéíûõ ÷èñåë
// Èñïîëüçóåì Mersenne Twister (mt19937) êàê âûñîêîêà÷åñòâåííûé ãåíåðàòîð
// 1. Инициализация генератора псевдослучайных чисел
// Используем Mersenne Twister (mt19937) как высококачественный генератор
std::random_device rd;
std::mt19937 gen(rd());
// 2. Îïðåäåëåíèå ðàâíîìåðíîãî ðàñïðåäåëåíèÿ äëÿ êîîðäèíàò [MIN_COORD, MAX_COORD]
// 2. Определение равномерного распределения для координат [MIN_COORD, MAX_COORD]
std::uniform_real_distribution<> distrib(MIN_COORD, MAX_COORD);
int generatedCount = 0;
@@ -63,53 +65,53 @@ namespace ZL
bool accepted = false;
int attempts = 0;
// Ïîïûòêà íàéòè ïîäõîäÿùèå êîîðäèíàòû
// Попытка найти подходящие координаты
while (!accepted && attempts < MAX_ATTEMPTS)
{
// Ãåíåðèðóåì íîâûå ñëó÷àéíûå êîîðäèíàòû
// Генерируем новые случайные координаты
Vector3f newPos(
(float)distrib(gen),
(float)distrib(gen),
(float)distrib(gen)
);
// Ïðîâåðêà ðàññòîÿíèÿ äî âñåõ óæå ñóùåñòâóþùèõ îáúåêòîâ
accepted = true; // Ïðåäïîëàãàåì, ÷òî ïîäõîäèò, ïîêà íå äîêàçàíî îáðàòíîå
// Проверка расстояния до всех уже существующих объектов
accepted = true; // Предполагаем, что подходит, пока не доказано обратное
for (const auto& existingBox : boxCoordsArr)
{
// Ðàñ÷åò âåêòîðà ðàçíîñòè
// Расчет вектора разности
Vector3f diff = newPos - existingBox.pos;
// Ðàñ÷åò êâàäðàòà ðàññòîÿíèÿ
// Расчет квадрата расстояния
float distanceSquared = diff.squaredNorm();
// Åñëè êâàäðàò ðàññòîÿíèÿ ìåíüøå êâàäðàòà ìèíèìàëüíîãî ðàññòîÿíèÿ
// Если квадрат расстояния меньше квадрата минимального расстояния
if (distanceSquared < MIN_DISTANCE_SQUARED)
{
accepted = false; // Îòêëîíÿåì, ñëèøêîì áëèçêî
break; // Íåò ñìûñëà ïðîâåðÿòü äàëüøå, åñëè îäíî íàðóøåíèå íàéäåíî
accepted = false; // Отклоняем, слишком близко
break; // Нет смысла проверять дальше, если одно нарушение найдено
}
}
if (accepted)
{
// 2. Ãåíåðèðóåì ñëó÷àéíûé êâàòåðíèîí
// 2. Генерируем случайный кватернион
Vector4f randomQuat = generateRandomQuaternion(gen);
// 3. Ïðåîáðàçóåì åãî â ìàòðèöó âðàùåíèÿ
// 3. Преобразуем его в матрицу вращения
Matrix3f randomMatrix = QuatToMatrix(randomQuat);
// 4. Äîáàâëÿåì îáúåêò ñ íîâîé ñëó÷àéíîé ìàòðèöåé
// 4. Добавляем объект с новой случайной матрицей
boxCoordsArr.emplace_back(BoxCoords{ newPos, randomMatrix });
generatedCount++;
}
attempts++;
}
// Åñëè ïðåâûøåíî ìàêñèìàëüíîå êîëè÷åñòâî ïîïûòîê, âûõîäèì èç öèêëà,
// ÷òîáû èçáåæàòü çàâèñàíèÿ, åñëè N ñëèøêîì âåëèêî èëè äèàïàçîí ñëèøêîì ìàë.
// Если превышено максимальное количество попыток, выходим из цикла,
// чтобы избежать зависания, если N слишком велико или диапазон слишком мал.
if (!accepted) {
std::cerr << "Ïðåäóïðåæäåíèå: Íå óäàëîñü ñãåíåðèðîâàòü " << N << " îáúåêòîâ. Ñãåíåðèðîâàíî: " << generatedCount << std::endl;
std::cerr << "Предупреждение: Не удалось сгенерировать " << N << " объектов. Сгенерировано: " << generatedCount << std::endl;
break;
}
}
@@ -173,8 +175,8 @@ void Game::setup() {
spaceshipTexture = std::make_unique<Texture>(CreateTextureDataFromPng("./resources/DefaultMaterial_BaseColor.png", CONST_ZIP_FILE));
spaceshipBase = LoadFromTextFile02("./resources/spaceship005.txt", CONST_ZIP_FILE);
spaceshipBase.RotateByMatrix(QuatToMatrix(QuatFromRotateAroundY(M_PI / 2.0)));
//spaceshipBase.Move(Vector3f{ -0.52998, -13, 0 });
spaceshipBase.Move(Vector3f{ -0.52998, -10, 10 });
spaceshipBase.RotateByMatrix(QuatToMatrix(QuatFromRotateAroundY(M_PI / 2.0)));
spaceship.AssignFrom(spaceshipBase);
spaceship.RefreshVBO();
@@ -193,7 +195,66 @@ void Game::setup() {
boxRenderArr[i].RefreshVBO();
}
buttonTexture = std::make_unique<Texture>(CreateTextureDataFromPng("./resources/button.png", CONST_ZIP_FILE));
button.data.PositionData.push_back({ 100, 100, 0 });
button.data.PositionData.push_back({ 100, 150, 0 });
button.data.PositionData.push_back({ 300, 150, 0 });
button.data.PositionData.push_back({ 100, 100, 0 });
button.data.PositionData.push_back({ 300, 150, 0 });
button.data.PositionData.push_back({ 300, 100, 0 });
button.data.TexCoordData.push_back({ 0,0 });
button.data.TexCoordData.push_back({ 0,1 });
button.data.TexCoordData.push_back({ 1,1 });
button.data.TexCoordData.push_back({ 0,0 });
button.data.TexCoordData.push_back({ 1,1 });
button.data.TexCoordData.push_back({ 1,0 });
button.RefreshVBO();
musicVolumeBarTexture = std::make_unique<Texture>(CreateTextureDataFromPng("./resources/musicVolumeBarTexture.png", CONST_ZIP_FILE));
musicVolumeBar.data.PositionData.push_back({ 1190, 100, 0 });
musicVolumeBar.data.PositionData.push_back({ 1190, 600, 0 });
musicVolumeBar.data.PositionData.push_back({ 1200, 600, 0 });
musicVolumeBar.data.PositionData.push_back({ 1190, 100, 0 });
musicVolumeBar.data.PositionData.push_back({ 1200, 600, 0 });
musicVolumeBar.data.PositionData.push_back({ 1200, 100, 0 });
musicVolumeBar.data.TexCoordData.push_back({ 0,0 });
musicVolumeBar.data.TexCoordData.push_back({ 0,1 });
musicVolumeBar.data.TexCoordData.push_back({ 1,1 });
musicVolumeBar.data.TexCoordData.push_back({ 0,0 });
musicVolumeBar.data.TexCoordData.push_back({ 1,1 });
musicVolumeBar.data.TexCoordData.push_back({ 1,0 });
musicVolumeBar.RefreshVBO();
musicVolumeBarButtonTexture = std::make_unique<Texture>(CreateTextureDataFromPng("./resources/musicVolumeBarButton.png", CONST_ZIP_FILE));
float musicVolumeBarButtonButtonCenterY = 350.0f;
musicVolumeBarButton.data.PositionData.push_back({ musicVolumeBarButtonButtonCenterX - musicVolumeBarButtonButtonRadius, musicVolumeBarButtonButtonCenterY - musicVolumeBarButtonButtonRadius, 0 });
musicVolumeBarButton.data.PositionData.push_back({ musicVolumeBarButtonButtonCenterX - musicVolumeBarButtonButtonRadius, musicVolumeBarButtonButtonCenterY + musicVolumeBarButtonButtonRadius, 0 });
musicVolumeBarButton.data.PositionData.push_back({ musicVolumeBarButtonButtonCenterX + musicVolumeBarButtonButtonRadius, musicVolumeBarButtonButtonCenterY + musicVolumeBarButtonButtonRadius, 0 });
musicVolumeBarButton.data.PositionData.push_back({ musicVolumeBarButtonButtonCenterX - musicVolumeBarButtonButtonRadius, musicVolumeBarButtonButtonCenterY - musicVolumeBarButtonButtonRadius, 0 });
musicVolumeBarButton.data.PositionData.push_back({ musicVolumeBarButtonButtonCenterX + musicVolumeBarButtonButtonRadius, musicVolumeBarButtonButtonCenterY + musicVolumeBarButtonButtonRadius, 0 });
musicVolumeBarButton.data.PositionData.push_back({ musicVolumeBarButtonButtonCenterX + musicVolumeBarButtonButtonRadius, musicVolumeBarButtonButtonCenterY - musicVolumeBarButtonButtonRadius, 0 });
musicVolumeBarButton.data.TexCoordData.push_back({ 0,0 });
musicVolumeBarButton.data.TexCoordData.push_back({ 0,1 });
musicVolumeBarButton.data.TexCoordData.push_back({ 1,1 });
musicVolumeBarButton.data.TexCoordData.push_back({ 0,0 });
musicVolumeBarButton.data.TexCoordData.push_back({ 1,1 });
musicVolumeBarButton.data.TexCoordData.push_back({ 1,0 });
musicVolumeBarButton.RefreshVBO();
renderer.InitOpenGL();
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
@@ -230,6 +291,7 @@ void Game::drawCubemap()
renderer.shaderManager.PopShader();
CheckGlError();
}
void Game::drawShip()
{
static const std::string defaultShaderName = "default";
@@ -251,6 +313,22 @@ void Game::drawShip()
renderer.LoadIdentity();
renderer.TranslateMatrix({ 0,0, -1.0f * Environment::zoom });
// Используем зафиксированную камеру для отрисовки, если lock активен
// Это обеспечит правильную ориентацию модели относительно начальной позиции камеры
if (shipMoveLockActive) {
///Matrix3f inverseLockedCamera = InverseMatrix(lockedCameraMat);
renderer.RotateMatrix(lockedCameraMat);
} else {
renderer.RotateMatrix(Environment::inverseShipMatrix);
}
renderer.RotateMatrix(rotateShipMat);
// Компенсируем начальный поворот модели на 90° вокруг Y, чтобы модель смотрела в направлении движения
// Модель изначально повёрнута на M_PI / 2.0 вокруг Y, поэтому добавляем компенсацию
Vector4f correctionQuat = QuatFromRotateAroundY(M_PI / 2.0f);
renderer.RotateMatrix(correctionQuat);
glBindTexture(GL_TEXTURE_2D, spaceshipTexture->getTexID());
renderer.DrawVertexRenderStruct(spaceship);
@@ -305,6 +383,78 @@ void Game::drawBoxes()
CheckGlError();
}
void Game::UpdateVolumeKnob() {
float musicVolumeBarButtonButtonCenterY = volumeBarMinY + musicVolume * (volumeBarMaxY - volumeBarMinY);
auto& pos = musicVolumeBarButton.data.PositionData;
pos[0] = { musicVolumeBarButtonButtonCenterX - musicVolumeBarButtonButtonRadius, musicVolumeBarButtonButtonCenterY - musicVolumeBarButtonButtonRadius, 0 };
pos[1] = { musicVolumeBarButtonButtonCenterX - musicVolumeBarButtonButtonRadius, musicVolumeBarButtonButtonCenterY + musicVolumeBarButtonButtonRadius, 0 };
pos[2] = { musicVolumeBarButtonButtonCenterX + musicVolumeBarButtonButtonRadius, musicVolumeBarButtonButtonCenterY + musicVolumeBarButtonButtonRadius, 0 };
pos[3] = { musicVolumeBarButtonButtonCenterX - musicVolumeBarButtonButtonRadius, musicVolumeBarButtonButtonCenterY - musicVolumeBarButtonButtonRadius, 0 };
pos[4] = { musicVolumeBarButtonButtonCenterX + musicVolumeBarButtonButtonRadius, musicVolumeBarButtonButtonCenterY + musicVolumeBarButtonButtonRadius, 0 };
pos[5] = { musicVolumeBarButtonButtonCenterX + musicVolumeBarButtonButtonRadius, musicVolumeBarButtonButtonCenterY - musicVolumeBarButtonButtonRadius, 0 };
musicVolumeBarButton.RefreshVBO();
}
void Game::UpdateVolumeFromMouse(int mouseX, int mouseY) {
int uiX = mouseX;
int uiY = Environment::height - mouseY;
Environment::shipVelocity = (musicVolume - 0.2) * (20.0);
if (uiY < volumeBarMinY || uiY > volumeBarMaxY)
{
return;
}
float t = (uiY - volumeBarMinY) / (volumeBarMaxY - volumeBarMinY);
if (t < 0.0f) t = 0.0f;
if (t > 1.0f) t = 1.0f;
musicVolume = t;
UpdateVolumeKnob();
}
void Game::drawUI()
{
static const std::string defaultShaderName = "default";
static const std::string envShaderName = "env";
static const std::string vPositionName = "vPosition";
static const std::string vTexCoordName = "vTexCoord";
static const std::string textureUniformName = "Texture";
glClear(GL_DEPTH_BUFFER_BIT);
renderer.shaderManager.PushShader(defaultShaderName);
renderer.RenderUniform1i(textureUniformName, 0);
renderer.EnableVertexAttribArray(vPositionName);
renderer.EnableVertexAttribArray(vTexCoordName);
renderer.PushProjectionMatrix(Environment::width, Environment::height, -1, 1);
renderer.PushMatrix();
renderer.LoadIdentity();
glBindTexture(GL_TEXTURE_2D, buttonTexture->getTexID());
renderer.DrawVertexRenderStruct(button);
glBindTexture(GL_TEXTURE_2D, musicVolumeBarTexture->getTexID());
renderer.DrawVertexRenderStruct(musicVolumeBar);
glBindTexture(GL_TEXTURE_2D, musicVolumeBarButtonTexture->getTexID());
renderer.DrawVertexRenderStruct(musicVolumeBarButton);
renderer.PopMatrix();
renderer.PopProjectionMatrix();
renderer.DisableVertexAttribArray(vPositionName);
renderer.DisableVertexAttribArray(vTexCoordName);
renderer.shaderManager.PopShader();
CheckGlError();
}
void Game::drawScene() {
static const std::string defaultShaderName = "default";
static const std::string envShaderName = "env";
@@ -323,6 +473,8 @@ void Game::drawScene() {
drawShip();
drawBoxes();
//drawUI();
CheckGlError();
}
@@ -345,40 +497,83 @@ void Game::processTickCount() {
float diffx = Environment::tapDownCurrentPos.v[0] - Environment::tapDownStartPos.v[0];
float diffy = Environment::tapDownCurrentPos.v[1] - Environment::tapDownStartPos.v[1];
if (isDraggingShip) {
// Движение корабля
if (abs(diffy) > 5.0 || abs(diffx) > 5.0) //threshold
{
float velocity = sqrtf(diffx * diffx + diffy * diffy);
if (abs(diffy) > 5.0 || abs(diffx) > 5.0) //threshold
{
Environment::shipVelocity = velocity * delta / 100;
float rotationPower = sqrtf(diffx * diffx + diffy * diffy);
// SDL screen Y направлен вниз, поэтому инвертируем diffy
// Движение по -Z (вперёд в локальных координатах камеры)
// diffx: вправо = положительное, влево = отрицательное
// diffy: вниз = положительное, вверх = отрицательное (в SDL)
// Для логики: вверх на экране (отрицательный diffy) = движение вперёд (-Z)
// Вправо на экране (положительный diffx) = поворот вправо (вокруг +Y)
//std::cout << rotationPower << std::endl;
// Вычисляем угол поворота вокруг Y (горизонтальный поворот)
// atan2(x, z) где x - это -diffx (инвертированное для правильного направления), z - это -diffy (вверх/вниз, инвертированное)
// Вверх (diffy < 0) должно давать угол 0 (вперёд), вправо (diffx > 0) должно давать правильное направление
float angleY = atan2(-diffx, -diffy); // угол поворота вокруг Y (инвертируем diffx для правильного направления)
float deltaAlpha = rotationPower * delta * M_PI / 500000.f;
// Создаём кватернион для поворота вокруг Y (горизонтальный поворот)
Vector4f quat = { 0, sin(angleY * 0.5f), 0, cos(angleY * 0.5f) };
rotateShipMat = QuatToMatrix(quat);
Vector3f rotationDirection = { diffy, diffx, 0 };
// Фиксируем ориентацию камеры при первом реальном движении
if (!shipMoveLockActive) {
lockedCameraMat = Environment::shipMatrix;
shipMoveLockActive = true;
}
}
else
{
Environment::shipVelocity = 0;
}
}
else if (isDraggingCamera) {
// Вращение камеры
if (abs(diffy) > 5.0 || abs(diffx) > 5.0) //threshold
{
float rotationPower = sqrtf(diffx * diffx + diffy * diffy);
rotationDirection = rotationDirection.normalized();
float deltaAlpha = rotationPower * delta * M_PI / 500000.f;
Vector4f rotateQuat = {
rotationDirection.v[0] * sin(deltaAlpha * 0.5f),
rotationDirection.v[1] * sin(deltaAlpha * 0.5f),
rotationDirection.v[2] * sin(deltaAlpha * 0.5f),
cos(deltaAlpha * 0.5f) };
Vector3f rotationDirection = { diffy, diffx, 0 };
Matrix3f rotateMat = QuatToMatrix(rotateQuat);
rotationDirection = rotationDirection.normalized();
Environment::shipMatrix = MultMatrixMatrix(Environment::shipMatrix, rotateMat);
Environment::inverseShipMatrix = InverseMatrix(Environment::shipMatrix);
Vector4f rotateQuat = {
rotationDirection.v[0] * sin(deltaAlpha * 0.5f),
rotationDirection.v[1] * sin(deltaAlpha * 0.5f),
rotationDirection.v[2] * sin(deltaAlpha * 0.5f),
cos(deltaAlpha * 0.5f) };
Matrix3f rotateMat = QuatToMatrix(rotateQuat);
Environment::shipMatrix = MultMatrixMatrix(Environment::shipMatrix, rotateMat);
Environment::inverseShipMatrix = InverseMatrix(Environment::shipMatrix);
// Обновляем начальную позицию для плавного вращения
Environment::tapDownStartPos.v[0] = Environment::tapDownCurrentPos.v[0];
Environment::tapDownStartPos.v[1] = Environment::tapDownCurrentPos.v[1];
}
}
}
if (fabs(Environment::shipVelocity) > 0.01f)
{
Vector3f velocityDirection = { 0,0, -Environment::shipVelocity*delta / 1000.f };
Vector3f velocityDirectionAdjusted = MultMatrixVector(Environment::shipMatrix, velocityDirection);
// Получаем локальное перемещение в координатах камеры
Vector3f localMove = MultMatrixVector(rotateShipMat, Vector3f{0, 0, -Environment::shipVelocity * delta / 1000.f});
Environment::shipPosition = Environment::shipPosition + velocityDirectionAdjusted;
// Выбираем матрицу камеры: зафиксированную (если lock активен) или текущую
Matrix3f camMat = lockedCameraMat;//////shipMoveLockActive ? lockedCameraMat : Environment::shipMatrix;
// Переводим локальное перемещение в мировые координаты
Vector3f worldMove = MultMatrixVector(camMat, localMove);
Environment::shipPosition = Environment::shipPosition + worldMove;
}
lastTickCount = newTickCount;
@@ -405,23 +600,69 @@ void Game::update() {
}
else if (event.type == SDL_MOUSEBUTTONDOWN) {
// 1. Îáðàáîòêà íàæàòèÿ êíîïêè ìûøè
Environment::tapDownHold = true;
// Êîîðäèíàòû íà÷àëüíîãî íàæàòèÿ
Environment::tapDownStartPos.v[0] = event.button.x;
Environment::tapDownStartPos.v[1] = event.button.y;
// Íà÷àëüíàÿ ïîçèöèÿ òàêæå ñòàíîâèòñÿ òåêóùåé
Environment::tapDownCurrentPos.v[0] = event.button.x;
Environment::tapDownCurrentPos.v[1] = event.button.y;
// 1. Обработка нажатия кнопки мыши
int mx = event.button.x;
int my = event.button.y;
std::cout << mx << " " << my << '\n';
int uiX = mx;
int uiY = Environment::height - my;
if (mx < 400 && my > 400)
{
Environment::tapDownHold = true;
isDraggingShip = true;
isDraggingCamera = false;
// Сбрасываем lock при новом нажатии, чтобы новый drag снова фиксировал камеру при первом движении
shipMoveLockActive = false;
// Координаты начального нажатия
Environment::tapDownStartPos.v[0] = event.button.x;
Environment::tapDownStartPos.v[1] = event.button.y;
// Начальная позиция также становится текущей
Environment::tapDownCurrentPos.v[0] = event.button.x;
Environment::tapDownCurrentPos.v[1] = event.button.y;
}
else
{
Environment::tapDownHold = true;
isDraggingShip = false;
isDraggingCamera = true;
// Координаты начального нажатия
Environment::tapDownStartPos.v[0] = event.button.x;
Environment::tapDownStartPos.v[1] = event.button.y;
// Начальная позиция также становится текущей
Environment::tapDownCurrentPos.v[0] = event.button.x;
Environment::tapDownCurrentPos.v[1] = event.button.y;
}
}
else if (event.type == SDL_MOUSEBUTTONUP) {
// 2. Îáðàáîòêà îòïóñêàíèÿ êíîïêè ìûøè
// 2. Обработка отпускания кнопки мыши
isDraggingVolume = false;
Environment::tapDownHold = false;
Environment::shipVelocity = 0;
// Сбрасываем lock камеры при отпускании мыши
shipMoveLockActive = false;
// Если была повернута камера, синхронизируем ориентацию корабля с камерой
// Корабль должен смотреть в том же направлении, что и камера (без дополнительного вращения)
if (isDraggingCamera) {
rotateShipMat = Matrix3f::Identity();
}
isDraggingShip = false;
isDraggingCamera = false;
}
else if (event.type == SDL_MOUSEMOTION) {
// 3. Îáðàáîòêà ïåðåìåùåíèÿ ìûøè
// 3. Обработка перемещения мыши
int mx = event.motion.x;
int my = event.motion.y;
if (Environment::tapDownHold) {
// Îáíîâëåíèå òåêóùåé ïîçèöèè, åñëè êíîïêà óäåðæèâàåòñÿ
// Обновление текущей позиции, если кнопка удерживается
Environment::tapDownCurrentPos.v[0] = event.motion.x;
Environment::tapDownCurrentPos.v[1] = event.motion.y;
}
@@ -440,6 +681,7 @@ void Game::update() {
}
else if (event.type == SDL_KEYUP)
{
if (event.key.keysym.sym == SDLK_i)
{
Environment::shipVelocity += 1.f;
+26
View File
@@ -32,6 +32,7 @@ private:
void drawCubemap();
void drawShip();
void drawBoxes();
void drawUI();
SDL_Window* window;
SDL_GLContext glContext;
@@ -56,6 +57,31 @@ private:
std::vector<BoxCoords> boxCoordsArr;
std::vector<VertexRenderStruct> boxRenderArr;
std::shared_ptr<Texture> buttonTexture;
VertexRenderStruct button;
std::shared_ptr<Texture> musicVolumeBarTexture;
VertexRenderStruct musicVolumeBar;
std::shared_ptr<Texture> musicVolumeBarButtonTexture;
VertexRenderStruct musicVolumeBarButton;
bool isDraggingVolume = false;
bool isDraggingShip = false;
bool isDraggingCamera = false;
bool shipMoveLockActive = false;
Matrix3f lockedCameraMat = Matrix3f::Identity();
float musicVolume = 1.0f;
float volumeBarMinX = 1190.0f;
float volumeBarMaxX = 1200.0f;
float volumeBarMinY = 100.0f;
float volumeBarMaxY = 600.0f;
float musicVolumeBarButtonButtonCenterX = 1195.0f;
float musicVolumeBarButtonButtonRadius = 25.0f;
void UpdateVolumeFromMouse(int mouseX, int mouseY);
void UpdateVolumeKnob();
};
} // namespace ZL
+1 -1
View File
@@ -148,7 +148,7 @@ embuilder build sdl2 sdl2_ttf sdl2_image sdl2_image_jpg sdl2_image_png
emcc main.cpp Game.cpp Environment.cpp BoneAnimatedModel.cpp Math.cpp Renderer.cpp TextModel.cpp ShaderManager.cpp TextureManager.cpp Utils.cpp OpenGlExtensions.cpp -O2 -std=c++14 -pthread -sUSE_PTHREADS=1 -sPTHREAD_POOL_SIZE=4 -sTOTAL_MEMORY=4294967296 -sINITIAL_MEMORY=3221225472 -sMAXIMUM_MEMORY=4294967296 -sALLOW_MEMORY_GROWTH=1 -I./thirdparty/libzip-1.11.3/build-emcmake/install/include -L./thirdparty/libzip-1.11.3/build-emcmake/install/lib -lzip -lz -sUSE_SDL_IMAGE=2 -sUSE_SDL=2 -sUSE_LIBPNG=1 --preload-file space-game001.zip -o space-game001.html
emcc main.cpp Game.cpp Environment.cpp BoneAnimatedModel.cpp ZLMath.cpp Renderer.cpp TextModel.cpp ShaderManager.cpp TextureManager.cpp Utils.cpp OpenGlExtensions.cpp -O2 -std=c++14 -pthread -sUSE_PTHREADS=1 -sPTHREAD_POOL_SIZE=4 -sTOTAL_MEMORY=4294967296 -sINITIAL_MEMORY=3221225472 -sMAXIMUM_MEMORY=4294967296 -sALLOW_MEMORY_GROWTH=1 -I./thirdparty/libzip-1.11.3/build-emcmake/install/include -L./thirdparty/libzip-1.11.3/build-emcmake/install/lib -lzip -lz -sUSE_SDL_IMAGE=2 -sUSE_SDL=2 -sUSE_LIBPNG=1 --preload-file space-game001.zip -o space-game001.html
emrun --no_browser --port 8080 .
```
BIN
View File
Binary file not shown.
Binary file not shown.
Binary file not shown.