Добро пожаловать на Pro Pawn - Портал о PAWN-скриптинге.
Показано с 1 по 9 из 9
  1. #1
    Аватар для LINKINPARK
    Пользователь

    Статус
    Оффлайн
    Регистрация
    24.01.2014
    Сообщений
    27
    Репутация:
    10 ±

    Сетка из 360тыс элементов

    добрый день товарищи. Ума не приложу как правильно назвать тему. Суть такая - Есть идеи как поделить карту СА на 360тыс мелких квадратов размером 10х10? и более того как узнать в каком из квадратов находится игрок!?

  2. #2
    Аватар для DeimoS
    Модератор?

    Статус
    Оффлайн
    Регистрация
    27.01.2014
    Адрес
    Восточный Мордор
    Сообщений
    5,588
    Репутация:
    1984 ±
    Можно хоть так - *click*
    Хоть какую-то более мудрёную формулу применить.

    Узнать можно обычным циклом. Помимо тех 360-и тысяч квадратов, делишь карту так же на более крупные квадраты, а после уже делаешь проверки начиная с самых больших квадратов и по ним отфильтровывая сразу основную.
    То бишь, определяешься с минимальными и максимальными координатами для области, которую будут покрывать твои 360 тысяч квадратов и сначала её делишь на 4 больших. Далее каждый из 4-ёх квадратов делишь ещё на 4 квадрата. И так можно повторить ещё пару раз (чтоб, в итоге, у тебя за один заход проверялось штук по 100 мелких квадратов всего). В итоге ты сможешь сначала проверить то, в каком из первых 4-ёх больших квадратов находится игрок и, тем самым, отфильтровать сразу большое количество ненужных тебе мелких квадратов.

    Так же, если тебе нужно именно постоянно отслеживать в каком квадрате находится игрок, а не при вводе команды, например, то можно запариться и сделать систему, которая будет запоминать в каком квадрате игрок заспавнился/в какой квадрат телепортировался, и уже после этого проверять только текущий квадрат + если игрок не в текущем квадрате - ближайшие к текущему.

    Ну и что в варианте с делением на большие квадраты, что в варианте с отслеживанием текущего квадрата - везде сначала стоит продумать сортировку данных в массиве, который и будет хранить координаты всех квадратов. Так, чтоб ты без особого труда мог определять нужные тебе квадраты (то бишь, распределение данных по массиву должно быть сделано по какому-то чёткому шаблону).
    Последний раз редактировалось DeimoS; 19.05.2021 в 08:13.
    Связаться со мной в VK можно через личные сообщения этой группы
    Заказы не принимаю

    Широко известно, что идеи стоят 0.8333 цента каждая (исходя из рыночной цены 10 центов за дюжину).
    Великих идей полно, на них нет спроса.
    Воплощение идеи в законченную игру требует долгой работы,
    таланта, терпения и креативности, не говоря уж о затратах денег, времени и ресурсов.
    Предложить идею просто, воплотить – вот в чём проблема

    Steve Pavlina

  3. #3
    Аватар для LINKINPARK
    Пользователь

    Статус
    Оффлайн
    Регистрация
    24.01.2014
    Сообщений
    27
    Репутация:
    10 ±
    Цитата Сообщение от DeimoS Посмотреть сообщение
    Можно хоть так - *click*
    Хоть какую-то более мудрёную формулу применить.

    Узнать можно обычным циклом. Помимо тех 360-и тысяч квадратов, делишь карту так же на более крупные квадраты, а после уже делаешь проверки начиная с самых больших квадратов и по ним отфильтровывая сразу основную.
    То бишь, определяешься с минимальными и максимальными координатами для области, которую будут покрывать твои 360 тысяч квадратов и сначала её делишь на 4 больших. Далее каждый из 4-ёх квадратов делишь ещё на 4 квадрата. И так можно повторить ещё пару раз (чтоб, в итоге, у тебя за один заход проверялось штук по 100 мелких квадратов всего). В итоге ты сможешь сначала проверить то, в каком из первых 4-ёх больших квадратов находится игрок и, тем самым, отфильтровать сразу большое количество ненужных тебе мелких квадратов.

    Так же, если тебе нужно именно постоянно отслеживать в каком квадрате находится игрок, а не при вводе команды, например, то можно запариться и сделать систему, которая будет запоминать в каком квадрате игрок заспавнился/в какой квадрат телепортировался, и уже после этого проверять только текущий квадрат + если игрок не в текущем квадрате - ближайшие к текущему.

    Ну и что в варианте с делением на большие квадраты, что в варианте с отслеживанием текущего квадрата - везде сначала стоит продумать сортировку данных в массиве, который и будет хранить координаты всех квадратов. Так, чтоб ты без особого труда мог определять нужные тебе квадраты (то бишь, распределение данных по массиву должно быть сделано по какому-то чёткому шаблону).
    Да мне постоянно нужно отслеживать в каком квадрате сейчас игрок.
    Цикл - слишком затратно, хотя в паре с твоей идеей делить квадрат на подквадраты вполне может быть работоспособной.
    Думал о динам зонах стримера - бред.
    Вариант деления квадрата на подквадраты идея не плохая, мне кажется, я придумал как это реализовать менее затратно и по скорости и ресурсам.
    Еще мне нужно знать центр квадрата, а так же мин/мах Х, У, что бы в нужный момент отмечать квадрат гангзоной.

  4. #4
    Аватар для DeimoS
    Модератор?

    Статус
    Оффлайн
    Регистрация
    27.01.2014
    Адрес
    Восточный Мордор
    Сообщений
    5,588
    Репутация:
    1984 ±
    Цитата Сообщение от LINKINPARK Посмотреть сообщение
    Да мне постоянно нужно отслеживать в каком квадрате сейчас игрок.
    Ну тогда делаешь вообще всё, о чём я писал в предыдущем сообщении. За счёт деления областей быстро находишь тот квадрат, в котором заспавнился игрок, а далее уже проверяешь ближайшие квадраты таймером. В итоге у тебя таймер будет проверять 9 квадратов всего из 360-и тысяч.

    Цитата Сообщение от LINKINPARK Посмотреть сообщение
    Еще мне нужно знать центр квадрата, а так же мин/мах Х, У, что бы в нужный момент отмечать квадрат гангзоной.
    "мин/мах Х, У" тебе и так будут известны (если ещё не понял, то через тот код, который по ссылке был, нужно координаты для квадратов заранее приготовить и записать в массивы, а не генерировать каждый старт сервера), а центр легко находится по формуле "(min_x+max_x)/2.0" (то же самое и для Y-оси)
    Связаться со мной в VK можно через личные сообщения этой группы
    Заказы не принимаю

    Широко известно, что идеи стоят 0.8333 цента каждая (исходя из рыночной цены 10 центов за дюжину).
    Великих идей полно, на них нет спроса.
    Воплощение идеи в законченную игру требует долгой работы,
    таланта, терпения и креативности, не говоря уж о затратах денег, времени и ресурсов.
    Предложить идею просто, воплотить – вот в чём проблема

    Steve Pavlina

  5. #5
    Аватар для LINKINPARK
    Пользователь

    Статус
    Оффлайн
    Регистрация
    24.01.2014
    Сообщений
    27
    Репутация:
    10 ±
    Решение.
    Набросал код на коленке, возможно где-то перепутал плюсы/минусы, возможны и прочие ошибки.
    это код может разделить карту на квадраты от 4-х(если SQUARE_STEP = 3000,0) до 36 000 000 если (если SQUARE_STEP = 1,0)
    так же очень быстро определяет по координатам № квадрата, его центр.

    PHP код:
    #include <a_samp>

    #define SQUARE_STEP 10.0
    #define SQUARE_SIZE 3000.0

    main()
    {
        new
            
    Float2690.0,
            
    Float= -1547.0,
            
    player_square
        
    ;
        
    player_square GetNumberSquare (XY);
        if (
    player_square != -1)
        {
            
    printf ("Игрок в квадрате № %i"player_square+1);
        }
        else 
        {
            print (
    "Игрок за пределами квадрта");
        }
        
    }
    GetNumberSquare (Float:xFloat:y)
    {
        if (
    >= SQUARE_SIZE || <= -SQUARE_SIZE || >= SQUARE_SIZE || <= -SQUARE_SIZE)
        {
            return -
    1;//за границей квадрата
        
    }

        new
            
    number_square floatround ((SQUARE_SIZE*2)/SQUARE_STEP); //макс кол-во квадратов от -3000 до 3000

        
    new
            
    newX floatround ((SQUARE_SIZE+x)/SQUARE_STEPfloatround_floor); //номер квадрата по оси Х
        
    new
            
    newY number_square*floatround ((SQUARE_SIZE-y)/SQUARE_STEPfloatround_floor); //номер квадрата по оси Y
    /*
        printf ("X %f, Y %f", //центр квадрата
            ((float (newX)*SQUARE_STEP)+(SQUARE_STEP/2))-SQUARE_SIZE, // X

            SQUARE_SIZE-((float (newY/number_square)*SQUARE_STEP))-(SQUARE_STEP/2)); // Y

        printf ("MAX X %f MAX Y %f, MIN X %f MIN Y %f", 

            (float (newX)*SQUARE_STEP)-SQUARE_SIZE, // MAX X

            SQUARE_SIZE-(float (newY/number_square)*SQUARE_STEP), //MAX Y

            ((float (newX)*SQUARE_STEP)+SQUARE_STEP)-SQUARE_SIZE, // MIN X

            SQUARE_SIZE-((float (newY/number_square)*SQUARE_STEP))-SQUARE_STEP); // MIN Y    
    */
        
    return newX newY;//возвращаем номер квадрата

    p/s Это очень хороший аналог для постарения ганг-зон с настройками
    PHP код:
    #define SQUARE_STEP 300.0
    #define SQUARE_SIZE 3000.0 
    400 ганг-зон размером 300х300, с моментальным поиском ида гангзоны :)

    DeimoS спасибо, подтолкнул в нужном направлении
    Последний раз редактировалось LINKINPARK; 19.05.2021 в 09:12.

  6. #6
    Аватар для LINKINPARK
    Пользователь

    Статус
    Оффлайн
    Регистрация
    24.01.2014
    Сообщений
    27
    Репутация:
    10 ±
    и вновь я в тупике.. Не понимаю как к каждому квадрату привязать определенное действие.
    например
    PHP код:
    GetPlayerPos (playeridxyz);

    if (
    GetNumberSquare (xy) == 50000)
    {
        
    действие;

    не прописывать же это 360тыс раз)
    EDD:
    Например есть 2е машины, стоят они в квадрате 50 и 151, есть массив с этими машинами
    PHP код:
    new
        
    car [2]; 
    как узнать если я стою в 50 квадрате то это 0 ячейка массива car, а если в 151 то это соответственно 1 ячейка массива.
    массив может иметь более 1000 ячеек

    создать массив такого типа
    car [2][2];
    где car [0] [0] = например модель машины
    car [0] [1] = 151 номер ячейки в которой она находится
    и далее циклом сверять? car [0] [1] == GetNumberSquare (x, y) ??
    Последний раз редактировалось LINKINPARK; 19.05.2021 в 10:39.

  7. #7
    Аватар для LINKINPARK
    Пользователь

    Статус
    Оффлайн
    Регистрация
    24.01.2014
    Сообщений
    27
    Репутация:
    10 ±
    Блин я сам уже запутался чего хочу:)
    Представим такую ситуацию:

    Игрок выбросил АК-47 в квадрате № 666, через некоторое время другой игрок находясь в квадрате 666 этот самый АК-47 забирает себе.
    В одном квадрате может быть несколько вещей, по команде формируется список вещей которые в нем находятся. Ну и естественно в массиве нужно как-то обнулять эти вещи когда их забирают и добавлять когда бросают.

    Массив имеем такой
    PHP код:
    new
        array [
    2000] [20];
    //где 
    array [0] [1] = 0//пусто
    array [0] [1] = 1;// АК-47 
    каким образом срастить 2000 и 3600000:)
    конечно было бы проще обьявить так array [360000] [20]; и использовать array [GetNumberSquare (x, y) [ .. ] = 1/0 но это очень не очень

  8. #8
    Аватар для DeimoS
    Модератор?

    Статус
    Оффлайн
    Регистрация
    27.01.2014
    Адрес
    Восточный Мордор
    Сообщений
    5,588
    Репутация:
    1984 ±
    Для чего ты вообще хочешь всё это разделение делать? Ибо всё то, что ты написал, не требует каких-либо разделений карты на квадраты.

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

    Широко известно, что идеи стоят 0.8333 цента каждая (исходя из рыночной цены 10 центов за дюжину).
    Великих идей полно, на них нет спроса.
    Воплощение идеи в законченную игру требует долгой работы,
    таланта, терпения и креативности, не говоря уж о затратах денег, времени и ресурсов.
    Предложить идею просто, воплотить – вот в чём проблема

    Steve Pavlina

  9. #9
    Аватар для LINKINPARK
    Пользователь

    Статус
    Оффлайн
    Регистрация
    24.01.2014
    Сообщений
    27
    Репутация:
    10 ±
    Цитата Сообщение от DeimoS Посмотреть сообщение
    Для чего ты вообще хочешь всё это разделение делать? Ибо всё то, что ты написал, не требует каких-либо разделений карты на квадраты.

    Касаемо транспорта и оружия - по их координатам и проверяй. В чём проблема?
    Тем более, что для всего, созданного через стример, есть замечательная функция Streamer_GetNearbyItems, которая сама вернёт список нужных вещей в радиусе, отсортируя их, при этом, по расстоянию.
    Да хрен знает зачем я это делаю, 2ва года не писал ничего, решил тряхнуть стариной:)
    изначальная идея была сделать альтернативу долгим циклам в нахождении определенной зоны.
    Вот исправленный код для быстрого нахождения идов 400 зон (для какой нибудь системы банд)
    при его помощи можно легко заполнить карту гангзонами и быстро получать номер гангзоны в которой находится игрок
    PHP код:
    #define SQUARE_STEP 300.0
    #define SQUARE_SIZE 3000.0

    GetNumberSquare (Float:xFloat:y)
    {
        if (
    >= SQUARE_SIZE || <= -SQUARE_SIZE || >= SQUARE_SIZE || <= -SQUARE_SIZE)
        {
            return -
    1;//за границей квадрата
        
    }
        new
            
    number_square floatround ((SQUARE_SIZE*2)/SQUARE_STEP); //макс кол-во квадратов от -3000 до 3000 по оси Х
        
    new
            
    newY floatround ((SQUARE_SIZE-y)/SQUARE_STEPfloatround_floor);//номер квадрата по оси Х
        
    new
            
    newX number_square*floatround ((SQUARE_SIZE+x)/SQUARE_STEPfloatround_floor);//номер квадрата по оси Y
        
    new 
            
    FloatmaxX = ((float (newY)*SQUARE_STEP)+(SQUARE_STEP/2))-SQUARE_SIZE,
            
    FloatmaxY SQUARE_SIZE-((float (newX/number_square)*SQUARE_STEP))-(SQUARE_STEP/2);
        
    printf ("X %f, Y %f"maxXmaxY); //центр квадрата

        
    printf ("minx %f miny %f, maxx %f maxy %f"
            
    maxX-(SQUARE_STEP/2), // minx
            
    maxY-(SQUARE_STEP/2), //minx
            
    maxX+(SQUARE_STEP/2), //maxx
            
    maxY+(SQUARE_STEP/2)); //maxy    

        
    return newX newY;//возвращаем номер квадрата

    А то что я писал в предыдущих постах, это не более чем попытки придумать где и как еще можно использовать эту сетку с миллионами ячеек. Одна голова хорошо, а две лучше. Может как раз вторая голова и придумает применение к этому коду.
    Может быть и я додумаю где и как еще применять это:).

 

 

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •