Форум программистов, компьютерный форум, киберфорум
SFML
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/3: Рейтинг темы: голосов - 3, средняя оценка - 5.00
396 / 32 / 7
Регистрация: 09.01.2019
Сообщений: 140

Создание изометрической карты

02.07.2024, 16:17. Показов 701. Ответов 9

Студворк — интернет-сервис помощи студентам
Доброго времени суток.
Пытаюсь создать изометрический тайлмап, причём тайлы беру изначально неизометрические, уже в процессе "проворачивая" их.
Результат приемлем, но карта при этом становится "ромбом".
Возможно ли посоветовать, как сделать так, чтобы пустые 4 стороны этого "ромба" заполнялись, при таком раскладе?
Пример кода, текстура прилагаются
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#include <vector>
#include <SFML/Graphics.hpp>
 
#define TILE_SIZE 32
#define MAP_WIDTH 16
#define MAP_HEIGHT 16
 
const int level[] =
{
    0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
    0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    1, 1, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3,
    0, 1, 0, 0, 0, 0, 3, 3, 3, 0, 1, 1, 1, 0, 0, 0,
    0, 1, 1, 0, 3, 3, 3, 0, 0, 0, 1, 1, 1, 0, 0, 0,
    0, 0, 1, 0, 3, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0,
    0, 0, 1, 0, 3, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1,
    0, 0, 1, 0, 3, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
    0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
    0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    1, 1, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3,
    0, 1, 0, 0, 0, 0, 3, 3, 3, 0, 1, 1, 1, 0, 0, 0,
    0, 1, 1, 0, 3, 3, 3, 0, 0, 0, 1, 1, 1, 0, 0, 0,
    0, 0, 1, 0, 3, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0,
    0, 0, 1, 0, 3, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1,
    0, 0, 1, 0, 3, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1
};
 
sf::Texture* pTileset;
 
std::vector<sf::Vertex> GenerateIsometricVertices(int size, unsigned width, unsigned height)
{
    std::vector<sf::Vertex> vertices;
 
    for (size_t i = 0; i < width; ++i)
        for (size_t j = 0; j < height; ++j)
        {
            int tileNumber = level[i + j * width];
            
            int tu = tileNumber % (pTileset->getSize().x / size);
            int tv = tileNumber / (pTileset->getSize().x / size);
 
 
            sf::Vector2f topLeft(i * size, j * size);
            sf::Vector2f topRight((i + 1) * size, j * size);
            sf::Vector2f bottomRight((i + 1) * size, (j + 1) * size);
            sf::Vector2f bottomLeft(i * size, (j + 1) * size);
 
            vertices.emplace_back(topLeft, sf::Color::White, sf::Vector2f(tu * size, tv * size));
            vertices.emplace_back(topRight, sf::Color::White, sf::Vector2f((tu + 1) * size, tv * size));
            vertices.emplace_back(bottomRight, sf::Color::White, sf::Vector2f((tu + 1) * size, (tv + 1) * size));
            vertices.emplace_back(bottomLeft, sf::Color::White, sf::Vector2f(tu * size, (tv + 1) * size));
        }
 
// Translate to isometric
    for(auto& v : vertices)
    {
        float isoX = v.position.x - v.position.y;
        float isoY = (v.position.x + v.position.y) * 0.5f;
 
        v.position = { isoX, isoY };
    }
 
    return vertices;
}
 
int main()
{
    sf::RenderWindow window(sf::VideoMode(1100, 800), "The Game!");
    window.setFramerateLimit(60u);
 
    sf::Texture tileset;
    if (!tileset.loadFromFile("tileset.png"))
        return -1;
 
    pTileset = &tileset;
 
    auto vertices = GenerateIsometricVertices(TILE_SIZE, MAP_WIDTH, MAP_HEIGHT); 
 
    sf::Transformable transform;
    transform.setOrigin(MAP_WIDTH << 4, MAP_HEIGHT << 4); 
    transform.setPosition(800, 400);
    
    while (window.isOpen())
    {
        sf::Event event;
        while (window.pollEvent(event))
        {
            if (event.type == sf::Event::Closed || sf::Keyboard::isKeyPressed(sf::Keyboard::Escape))
                window.close();
        }
 
        sf::RenderStates states;
        states.texture = pTileset;
        states.transform = transform.getTransform();
        
 
        window.clear();
        window.draw(vertices.data(), vertices.size(), sf::Quads, states);
        window.display();
    }
 
    return 0;
}
Изображения
 
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
02.07.2024, 16:17
Ответы с готовыми решениями:

Постороение куба в изометрической проекции
Здравствуйте! Задача, поставленная передо мной: посторить куб в изометрической проекции и повернуть его по оси OY(вертикальная ось),не...

Построение трехмерной фигуры и её изометрической проекции
Помогите пожалуйста, построить на языке программирования C# трехмерную фигуру и ее изометрическую проекцию ( например призму), желательно...

Разработка изометрической игры в стиле спектрума
Здравствуйте уважаемые знатоки. Нужна помощь понимающих, давным давно была такая старая игрушка на ZX SPECTRUM &quot;Head over Heels&quot;,...

9
 Аватар для zayats80888
6344 / 3515 / 1428
Регистрация: 07.02.2019
Сообщений: 8,981
02.07.2024, 20:46
Цитата Сообщение от EugeneNN Посмотреть сообщение
Возможно ли посоветовать, как сделать так, чтобы пустые 4 стороны этого "ромба" заполнялись, при таком раскладе?
Заполнялись чем? Ну добавь вокруг "спрайты заполнители" или один большой фоновый спрайт...

Цитата Сообщение от EugeneNN Посмотреть сообщение
беру изначально неизометрические, уже в процессе "проворачивая" их.
Это не обязательно делать вручную, можно (и удобнее, например, для обратного преобразования, когда нужно координаты мыши преобразовать в координаты на карте) использовать матрицу изометрической проекции (минимум изменений):
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#include <vector>
#include <SFML/Graphics.hpp>
 
#define TILE_SIZE 32
#define MAP_WIDTH 16
#define MAP_HEIGHT 16
 
const int level[] =
{
    0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
    0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    1, 1, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3,
    0, 1, 0, 0, 0, 0, 3, 3, 3, 0, 1, 1, 1, 0, 0, 0,
    0, 1, 1, 0, 3, 3, 3, 0, 0, 0, 1, 1, 1, 0, 0, 0,
    0, 0, 1, 0, 3, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0,
    0, 0, 1, 0, 3, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1,
    0, 0, 1, 0, 3, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
    0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
    0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    1, 1, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3,
    0, 1, 0, 0, 0, 0, 3, 3, 3, 0, 1, 1, 1, 0, 0, 0,
    0, 1, 1, 0, 3, 3, 3, 0, 0, 0, 1, 1, 1, 0, 0, 0,
    0, 0, 1, 0, 3, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0,
    0, 0, 1, 0, 3, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1,
    0, 0, 1, 0, 3, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1
};
 
sf::Texture* pTileset;
 
std::vector<sf::Vertex> GenerateIsometricVertices(int size, unsigned width, unsigned height)
{
    std::vector<sf::Vertex> vertices;
 
    for (size_t i = 0; i < width; ++i)
        for (size_t j = 0; j < height; ++j)
        {
            int tileNumber = level[i + j * width];
            
            int tu = tileNumber % (pTileset->getSize().x / size);
            int tv = tileNumber / (pTileset->getSize().x / size);
 
 
            sf::Vector2f topLeft(i * size, j * size);
            sf::Vector2f topRight((i + 1) * size, j * size);
            sf::Vector2f bottomRight((i + 1) * size, (j + 1) * size);
            sf::Vector2f bottomLeft(i * size, (j + 1) * size);
 
            vertices.emplace_back(topLeft, sf::Color::White, sf::Vector2f(tu * size, tv * size));
            vertices.emplace_back(topRight, sf::Color::White, sf::Vector2f((tu + 1) * size, tv * size));
            vertices.emplace_back(bottomRight, sf::Color::White, sf::Vector2f((tu + 1) * size, (tv + 1) * size));
            vertices.emplace_back(bottomLeft, sf::Color::White, sf::Vector2f(tu * size, (tv + 1) * size));
        }
/*
// Translate to isometric
    for(auto& v : vertices)
    {
        float isoX = v.position.x - v.position.y;
        float isoY = (v.position.x + v.position.y) * 0.5f;
 
        v.position = { isoX, isoY };
    }
*/
    return vertices;
}
 
int main()
{
    sf::RenderWindow window(sf::VideoMode(1100, 800), "The Game!");
    window.setFramerateLimit(60u);
 
    sf::Texture tileset;
    if (!tileset.loadFromFile("tileset.png"))
        return -1;
 
    pTileset = &tileset;
 
    auto vertices = GenerateIsometricVertices(TILE_SIZE, MAP_WIDTH, MAP_HEIGHT); 
 
    sf::Transformable transform;
    transform.setOrigin(MAP_WIDTH << 4, MAP_HEIGHT << 4); 
    transform.setPosition(800, 400);
 
    sf::Transform iso(1.0f, -1.0f, 0.0f, 0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f);
 
    while (window.isOpen())
    {
        sf::Event event;
        while (window.pollEvent(event))
        {
            if (event.type == sf::Event::Closed || sf::Keyboard::isKeyPressed(sf::Keyboard::Escape))
                window.close();
        }
 
        sf::RenderStates states;
        states.texture = pTileset;
        states.transform = transform.getTransform();
        states.transform.combine(iso);
 
        window.clear();
        window.draw(vertices.data(), vertices.size(), sf::Quads, states);
        window.display();
    }
 
    return 0;
}
0
396 / 32 / 7
Регистрация: 09.01.2019
Сообщений: 140
03.07.2024, 09:10  [ТС]
Цитата Сообщение от zayats80888 Посмотреть сообщение
Заполнялись чем? Ну добавь вокруг "спрайты заполнители" или один большой фоновый спрайт...
Этими же тайлами. Как я на скорую руку прикинул, это не получится засунуть в единый двумерный массив, надо будет ещё 4 массива генерировать с размерностями примерно 1/4 от основного, на стороны "ромба"?
Или брать уже готовые изометрические тайлы? Просто хотелось рисовать карты в редакторе в обычной проекции, а рендерить уже в изометрии, но вот этот ромб прям добивает.

Цитата Сообщение от zayats80888 Посмотреть сообщение
Это не обязательно делать вручную, можно использовать матрицу изометрической проекции
Вот за это спасибо огромное, как-то даже в голову не приходило =)
0
 Аватар для zayats80888
6344 / 3515 / 1428
Регистрация: 07.02.2019
Сообщений: 8,981
03.07.2024, 09:26
EugeneNN, опять не понял, что значит этими же тайлами? Карта ограничена, за ней нет ничего.
И почему четыре массива, когда одного хватит?
0
396 / 32 / 7
Регистрация: 09.01.2019
Сообщений: 140
03.07.2024, 09:56  [ТС]
Карту я беру из двумерного массива. При рендере "проворачиваю", по итогу она рисуется "ромбом", с четырьмя пустыми областями. Чтобы их заполнить тайлами с этой же текстуры, чтобы карта, по итогу, рендерилась нормальным четырёхугольником, что предпочтительнее сделать - взять изначально изометрические тайлы, или же ещё 4 подмассива лепить по углам?
Миниатюры
Создание изометрической карты  
0
 Аватар для zayats80888
6344 / 3515 / 1428
Регистрация: 07.02.2019
Сообщений: 8,981
03.07.2024, 11:53
EugeneNN, ты хочешь лесенкой заполнить? Я не видел, чтобы так кто-то делал, так что дело твое.

Если же хочешь ровный прямоугольник, то придется граничные спрайты половинить по диагонали, т.е. одним треогульником вместо двух.
0
396 / 32 / 7
Регистрация: 09.01.2019
Сообщений: 140
03.07.2024, 12:20  [ТС]
Цитата Сообщение от zayats80888 Посмотреть сообщение
Если же хочешь ровный прямоугольник, то придется граничные спрайты половинить по диагонали, т.е. одним треогульником вместо двух.
Да половинить-то не проблема, OpenGL сам обрежет, я бы их и не трогал.
Основной мотив: рисовать карту в редакторе обычными тайлами, а рендерить в изометрии. Тот же TiledMapEditor, если открыть создание изометрической карты, предлагает сразу сетку-карту "ромбом", вот спасибо, думаю, это я и сам могу так нарисовать.

Приложил скрины, для понимания, как хотелось бы реализовать, "ромб", соответственно, сейчас как есть
Изображения
  
0
 Аватар для zayats80888
6344 / 3515 / 1428
Регистрация: 07.02.2019
Сообщений: 8,981
03.07.2024, 18:10
Цитата Сообщение от EugeneNN Посмотреть сообщение
Приложил скрины, для понимания, как хотелось бы реализовать
Так а проблема в чем, не пойму? Не получается ромбовидную карту в прямоугольный массив запихнуть или что?
0
396 / 32 / 7
Регистрация: 09.01.2019
Сообщений: 140
03.07.2024, 18:37  [ТС]
Цитата Сообщение от zayats80888 Посмотреть сообщение
Не получается ромбовидную карту в прямоугольный массив запихнуть или что?
Дано: двумерный массив чисел. По ним тайлами рисуем обычную top-down карту.
В коде я "проворачиваю" карту, для создания эффекта изометрии. При этом она рисуется "ромбом" - т.к. все тайлы смещаются, и образуются четыре пустые области.

Прошу подсказать варианты заполнения этих областей так, чтобы получилась прямоугольная карта, без пустых мест. В Heroes IV играли? Вот там изометрия, но карта прямоугольная, а не ромбом, хотя тайлы (если извлечь ресурсы), представлены НЕизометрическими спрайтами.
0
 Аватар для zayats80888
6344 / 3515 / 1428
Регистрация: 07.02.2019
Сообщений: 8,981
03.07.2024, 19:04
Лучший ответ Сообщение было отмечено EugeneNN как решение

Решение

Цитата Сообщение от EugeneNN Посмотреть сообщение
Прошу подсказать варианты заполнения этих областей так, чтобы получилась прямоугольная карта, без пустых мест.
Заполняй и храни в изометрии "прямоугольно" (например, на первом скрине из 7 поста карта 4х8), а читая её, переводи индексы в прямоугольную сетку
(напр., i' = i / 2 + j и j' = j / 2 - i, плюс какое-то смещение на твое усмотрение).
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
03.07.2024, 19:04
Помогаю со студенческими работами здесь

Построение куба в изометрической и диметрической проекции с осями x,y,z
Используя только простейшие функции типа lineto moveto построить на форме куб в изометрической и диметрической проекциях, добавить оси...

как сделать чтобы было в изометрической проекции
unit stereo_; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, DXDraws, ExtCtrls,...

Подскажите движок/фреймворк/библиотеку для создания 2d изометрической игры
Привет, подскажите пожалуйста движок/фреймворк/библиотеку для создания 2d игры, желательно на С++. Пробивал SDL2 в целом он мне...

Создание карты
Приветствую, я пытаюсь сделать карту с помощью html &lt;area&gt; &lt;map&gt; но заказчику надо, чтобы ссылки с area открывались по двойному клику ......

Создание карты
Добрый день, ребят! Итак, такой вопрос, как подойти к созданию карты, которая привязана к координатам GPS, но речь идет о куске карты...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Новые блоги и статьи
Unity 4D
GameUnited 13.06.2025
Четырехмерное пространство. . . Звучит как что-то из научной фантастики, правда? Однако для меня, как разработчика со стажем в игровой индустрии, четвертое измерение давно перестало быть абстракцией из. . .
SSE (Server-Sent Events) в ASP.NET Core и .NET 10
UnmanagedCoder 13.06.2025
Кажется, Microsoft снова подкинула нам интересную фичу в новой версии фреймворка. Работая с превью . NET 10, я наткнулся на нативную поддержку Server-Sent Events (SSE) в ASP. NET Core Minimal APIs. Эта. . .
С днём независимости России!
Hrethgir 13.06.2025
Решил побеседовать, с утра праздничного дня, с LM о завоеваниях. То что она написала о народе, представителем которого я являюсь сам сначала возмутило меня, но дальше только смешило. Это чисто. . .
Лето вокруг.
kumehtar 13.06.2025
Лето вокруг. Наполненное бурями и ураганами событий. На фоне магии Жизни, священной и вечной, неумелой рукой человека рисуется панорама душевного непокоя. Странные серые краски проникают и. . .
Популярные LM модели ориентированы на увеличение затрат ресурсов пользователями сгенерированного кода (грязь -заслуги чистоплюев).
Hrethgir 12.06.2025
Вообще обратил внимание, что они генерируют код (впрочем так-же ориентированы разработчики чипов даже), чтобы пользователь их использующий уходил в тот или иной убыток. Это достаточно опытные модели,. . .
Топ10 библиотек C для квантовых вычислений
bytestream 12.06.2025
Квантовые вычисления - это та область, где теория встречается с практикой на границе наших знаний о физике. Пока большая часть шума вокруг квантовых компьютеров крутится вокруг языков высокого уровня. . .
Dispose и Finalize в C#
stackOverflow 12.06.2025
Работая с C# больше десяти лет, я снова и снова наблюдаю одну и ту же историю: разработчики наивно полагаются на сборщик мусора, как на волшебную палочку, которая решит все проблемы с памятью. Да,. . .
Повышаем производительность игры на Unity 6 с GPU Resident Drawer
GameUnited 11.06.2025
Недавно копался в новых фичах Unity 6 и наткнулся на GPU Resident Drawer - штуку, которая заставила меня присвистнуть от удивления. По сути, это внутренний механизм рендеринга, который автоматически. . .
Множества в Python
py-thonny 11.06.2025
В Python существует множество структур данных, но иногда я сталкиваюсь с задачами, где ни списки, ни словари не дают оптимального решения. Часто это происходит, когда мне нужно быстро проверять. . .
Работа с ccache/sccache в рамках C++
Loafer 11.06.2025
Утилиты ccache и sccache занимаются тем, что кешируют промежуточные результаты компиляции, таким образом ускоряя последующие компиляции проекта. Это означает, что если проект будет компилироваться. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru
OSZAR »