Найти в Дзене
Степан Гончаров

Содание зоны видимоси игрового персонажа

Когда-то давно я проводил подобную операцию для создания 3D игры еще 3 года назад. С помощью данной функции реализовывались трассировка и рей-кастинг лучей. делалось всё просто, у нас было направление персонажа, его позиция и игол луча, исходящего из персонажа, после него на каждый пиксель прямой происходила операция определения столкновения с элементом карты, после чего возвращалась длина луча.
Это была очень требовательная операция и по фпс можно понять, что добавлять такое в игру ради красоты не самый оптимизированный путь

ВКонтакте | ВКонтакте

выход из данной ситуации заключался в нахождении крайних точек столкновения с объектом

Но такой метод был бы ошибочным, так как в случае слишком продолженной стены столкновение просто не определилось бы.

Тогда я пришел к выводу, что можно брать те же самые лучи исходящие из объекта, но вместо безумного счета пересечения на пиксель я решил находить позицию пересечения прямых

-2

Так как угла грани столкновения у нас всего 2, х или у пересечения нам заведомо будет известен, после чего мы находим вторую часть позиции.

Данный путь гораздо оптимизированнее и позволяет сохранить достойный показатель фпс.

Результатом являлся класс


class Viewes {
public:
ConvexShape viev;
vector<int>l;
int len(int x1, int x2, int y1, int y2) {
return pow(pow(x1 - x2, 2) + pow(y1 - y2, 2), 0.5);
}
int f1(float a, int x, int x2, int y, int y2) {
if (len(x, x2, y, y2) > len(x + cos(a)*4, x2, y + sin(a)*4, y2)) {
return 1;
}
return 0;
}
int f2(int x, int y, int m[512][4]) {
for (int i = 0; i < 512; i++) {
if (x >= m[i][0] - 2 and x <= m[i][0] + m[i][2] + 2 and y >= m[i][1] - 2 and y <= m[i][1] + m[i][3] + 2) {
return 1;
}
}
return 0;
}

void func(int x, int y, float a, int p[2048][4], int num, int walls[512][4]) {
l.clear();
for (int i = -50; i < 50; i++) {
float x1 = x, y1 = y, x2 = x + 1000000 * cos(a + i * radian), y2 = y + sin(a + i * radian) * 1000000;
float k1 = k(x1, y1, x2, y2);
float b1 = b(x1, y1, x2, y2);
int lmin = 4300;
for (int j = 0; j < num; j++) {
if (p[j][0] == p[j][2]) {
float x3 = p[j][0];
float y3 = k1 * x3 + b1;
float a3 = alfa(x, y, x3, y3);
if (y3 > p[j][1] and y3 < p[j][3]) {
if (pow(pow(x - x3, 2) + pow(y - y3, 2), 0.5) < lmin) {
if (f1(a, x, x3, y, y3) == 1) {
if (f2(x3, y3, walls) == 1) {
lmin = pow(pow(x - x3, 2) + pow(y - y3, 2), 0.5);
}
}
}
}
}
if (p[j][1] == p[j][3]) {
float x3 = (p[j][1] - b1)/k1;
float y3 = p[j][1];
float a3 = alfa(x, y, x3, y3);
if (x3 > p[j][0] and x3 < p[j][2]) {
if (pow(pow(x - x3, 2) + pow(y - y3, 2), 0.5) < lmin){
if (f1(a, x, x3, y, y3) == 1) {
if (f2(x3, y3, walls) == 1) {
lmin = pow(pow(x - x3, 2) + pow(y - y3, 2), 0.5);
}
}
}
}
}
}
l.push_back(lmin);
}
}
void Draw(int x, int y, float a, RenderWindow& win) {

vector<Vertex> line1;
for (int i = -50; i < 50; i++) {
line1.push_back(Vertex(sf::Vector2f(x + l[i + 50] * cos(a + i * radian), y + l[i + 50] * sin(a + i * radian)), Color::Color(0, 0, 0, 200)));
line1.push_back(Vertex(sf::Vector2f(x + 4300 * cos(a + i * radian), y + 4300 * sin(a + i * radian)), Color::Color(0,0,0,200)));
}
Vertex line[200];
for (int i = 0; i < line1.size(); i++) {
line[i] = line1[i];
}
Vertex line2[7];
line2[0] = Vertex(sf::Vector2f(x, y), Color::Color(0, 0, 0, 200));
line2[1] = Vertex(sf::Vector2f(x + 4300 * cos(a + 48 * radian), y + 4300 * sin(a + 48 * radian)), Color::Color(0, 0, 0, 200));
line2[2] = Vertex(sf::Vector2f(x + 4300 * cos(a + 50 * radian+90 * radian), y + 4300 * sin(a + 50 * radian + 90 * radian)), Color::Color(0, 0, 0, 200));
line2[3] = Vertex(sf::Vector2f(x + 4300 * cos(a + 50 * radian + 90 * radian + 90 * radian), y + 4300 * sin(a + 50 * radian + 90 * radian + 90 * radian)), Color::Color(0, 0, 0, 200));
line2[4] = Vertex(sf::Vector2f(x + 4300 * cos(a - 50 * radian), y + 4300 * sin(a - 50 * radian)), Color::Color(0, 0, 0, 200));
line2[5] = Vertex(sf::Vector2f(x, y), Color::Color(0, 0, 0, 200));


for (Vertex i : line2) {
i.color = Color::Color(0, 0, 0, 75);
}


win.draw(line, 198, TrianglesStrip);
win.draw(line2, 6, TriangleFan);

}
};

-3