Управление вставкой мрамора в кривую очередь C++C++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Управление вставкой мрамора в кривую очередь C++

Сообщение Anonymous »

Я пытаюсь создать копию игры Zuma на C++ с помощью SFML. Я создал цепочку точек и создал VertexArray с помощью LineStrip. В каждом кадре я обновляю положение каждого шарика, используя коэффициент и индекс точки. Коэффициент используется для размещения шарика между сохраненным индексом и следующей точкой. У меня также есть список шариков:

Код: Выделить всё

vector billes;

struct Marble {
Vector2f coord;
float size;
Color color;
float speed;
int pathPosition;
float factor;
float angle;
};
Вот основной цикл обновления шариков:

Код: Выделить всё

for (size_t i = 0; i < billes.size(); ++i) {
float distance = calculerDistanceEntrePoints(chemin[billes[i].pathPosition], chemin[billes[i].pathPosition + 1]);
float vitesseAjustee = vitesse / distance;
billes[i].coord = interpolerPoints(chemin[billes[i].pathPosition], chemin[billes[i].pathPosition + 1], billes[i].factor);

if (billes[i].factor >= 1.0f) {
billes[i].factor = 0.0f;
billes[i].pathPosition += 1;
if (billes[i].pathPosition >= chemin.size() - 1) {
billes.erase(billes.begin() + i);
--i; // To avoid skipping the next marble
}
} else {
billes[i].factor += (vitesseAjustee * 10) * dt;
}

float distanceRestante = (taille / 55) / calculerDistanceEntrePoints(chemin[0], chemin[1]);
if (i == billes.size() - 1 && billes[i].factor + 0.05 >= distanceRestante * 2 && nombreBilles < 50) {
billes.push_back(newMarble(chemin[0], taille / 55, 0));
nombreBilles += 1;
}
}
Вот используемые вспомогательные функции:

Код: Выделить всё

float calculerDistanceEntrePoints(Vector2f p1, Vector2f p2) {
Vector2f difference = p2 - p1;
return std::sqrt(difference.x * difference.x + difference.y * difference.y);
}

Vector2f interpolerPoints(Vector2f pointA, Vector2f pointB, float avancement) {
return Vector2f(pointA.x + (pointB.x - pointA.x) * avancement, pointA.y + (pointB.y - pointA.y) * avancement);
}

// Function to calculate the position of a marble
Vector2f calculerPositionBille(Marble bille, Vector2f positionCarre) {
float rayonCercle = bille.size;
return Vector2f(positionCarre.x - rayonCercle, positionCarre.y - rayonCercle);
}

// Function to calculate a point on a spiral
Vector2f calculerPointSpirale(float angle, float rayon, Vector2f centreFenetre) {
return Vector2f(centreFenetre.x / 2 + rayon * cos(angle), centreFenetre.y / 2 + rayon * sin(angle));
}
Это работает хорошо, хотя я думаю, что это могло бы быть чище. Однако мне нужно стрелять шариками и вставлять их в цепочку. Это работает, но шарик не установлен в нужной точке, и следующие шарики не двигаются должным образом.

Я пытаюсь сделать по-другому функция вроде этой:

Код: Выделить всё

void deplacerBilles(vector& billes, size_t index, const vector& chemin) {
for (int i = index; i >= 0; i--) {
if (billes[i].pathPosition >= chemin.size() - 1) {
continue; // Évite les indices invalides
}

// Distance entre la position actuelle et la prochaine position sur le chemin
float distance = calculerDistanceEntrePoints(chemin[billes[i].pathPosition], chemin[billes[i].pathPosition + 1]);

// Avancer le facteur de déplacement de la bille
if ((billes[i].factor + billes[i].size / distance) >= 1.0f) {
// Si la bille dépasse la position actuelle, on passe à la suivante
billes[i].pathPosition += 1;
float distanceRestante = (billes[i].factor + (billes[i].size / distance));             // factor actuelle + distance a parcourir = objectif
// mais  >= 1 donc 1-distance restante = distance restante a partir
// de pathPosition+1 et ensuite il faut exprimer cela en fonction
// de longueur pathPosition et pathPosition +1
billes[i].factor = (((1 - distanceRestante)*calculerDistanceEntrePoints(chemin[billes[i].pathPosition], chemin[billes[i].pathPosition + 1]))/distance);

if (billes[i].pathPosition >= chemin.size() - 1) {
// Si la bille dépasse la fin du chemin, on l'enlève
billes.erase(billes.begin() + i);
}
} else {
billes[i].factor += billes[i].size / distance;
}
}
}

bool collisionTab(Marble& bille, vector& billes, const vector& chemin) {
for (size_t i = 0; i < billes.size(); ++i) {
if (collision(bille, billes[i])) {
bille.pathPosition = billes[i].pathPosition;
bille.factor = billes[i].factor;
billes.insert(billes.begin() + i, bille);
deplacerBilles(billes, i, chemin);
return true; // Collision détectée
}
}
return false;
}

И извините за мой уровень английского и французский код, ахах ^^
Вот ссылка на zip-файл: Zuma.zip

Подробнее здесь: https://stackoverflow.com/questions/785 ... le-suivant
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»