XGM Forum
Сайт - Статьи - Проекты - Ресурсы - Блоги

Форуме в режиме ТОЛЬКО ЧТЕНИЕ. Вы можете задать вопросы в Q/A на сайте, либо создать свой проект или ресурс.
Вернуться   XGM Forum > Warcraft> Академия: форум для вопросов
Ник
Пароль
Войти через VK в один клик
Сайт использует только имя.

Ответ
 
Ежик

offline
Опыт: 2,536
Активность:
2 вопроса \\Jass
Хочу узнать как делать 2 функции. А нужно их соеденить.
В общем при моём событии надо выбрать всех юнитов(врагов) в радиусе 99999 (вся карта) от моего юнита(u) и добавить в локальный отряд(g). Потом выявить самого ближнего юнита в группе от (u) и обратится к этому выбранному юниту.
Старый 26.10.2010, 18:17
Klop
Папа римский
offline
Опыт: 13,006
Активность:
Ежик,
в функции отряда проверяй дистанцию между Пикнутым и твоим юнитом и заноси их в массив,затем проверяй на самую маленькую дистанцию
цикл - Кол-во пикнутых юнитов-1
if Mas[i] > Mas[i+1] then Min = Mas[i] else Mas[i+1]

я смогу сделать пример,но только вечером,щас у меня нет времени ты пользуешся JNGP?

Вообще вместо массива лучше думаю использовать Hashtable,но тогда обязательно в конце его надо будет очищать
Старый 26.10.2010, 19:49
ManWhoKnows
just another wc3 modmaker
offline
Опыт: 915
Активность:
самый простой и ресурсоёмкий метод - решать перебором всех врагов через цикл, и сравнивать их расстояния до u. можно использовать, если функция вызывается редко. в ином же случае - это будет жутко неудобно и лагово. найти оптимальное решение задачи гораздо проще если знать её контекст. может быть в твоём случае подойдёт организация движка, который будет следить за всем юнитами на карте, может быть можно решить с помощью триггеров.
так что ты расскажи поподробней.
p.s. если чтото придёт в голову, обязательно напишу.
Старый 26.10.2010, 19:54
Master_chan
Полуночный командир
offline
Опыт: 15,660
Активность:
Mr_KLOP:
Вообще вместо массива лучше думаю использовать Hashtable
нет не лучше

Отредактировано Master_chan, 26.10.2010 в 20:17.
Старый 26.10.2010, 19:57
ManWhoKnows
just another wc3 modmaker
offline
Опыт: 915
Активность:
и вообще, как я сказал выше, это плохой метод, если врагов будет много функция вернёт тебе не ближайшего врага а supremeLAG
и если уж на то пошло, и очень хочется сделать перебор, ни массив, ни тем более, хэштаблица вообще не нужны.

Отредактировано ManWhoKnows, 26.10.2010 в 21:18.
Старый 26.10.2010, 19:59
Ежик

offline
Опыт: 2,536
Активность:
Mr_KLOP,
Был бы благодарен. Подожду конечно) JNPG есть.
Мне что нужно,используется спелл и выбирается ближайший юнит, и приминяющий юнит бежит к этому юниту.Может есть возможность зделать легче?
Старый 26.10.2010, 20:03
spellwerk

offline
Опыт: 4,869
Активность:
а если последовательно выбирать войнов на расстоянии 100, потом 200, 300 и так пока не найдешь
Старый 26.10.2010, 20:45
ManWhoKnows
just another wc3 modmaker
offline
Опыт: 915
Активность:
Чтобы не насоветовали ещё чего, вот:
((код jass
#include "cj_types_priv.j"
globals
boolexpr enemy_filter
player filter_player
endglobals
boolean enemy_filter_c () {
if IsPlayerEnemy(GetOwningPlayer(GetFilterUnit()),filter_player) {return true}
return false
}
unit NearEnemy(unit u) {
group g = CreateGroup()
unit n
real dist,r,d,x1,y1
if enemy_filter == null {enemy_filter = Condition(function enemy_filter_c)}
filter_player = GetOwningPlayer(u)
GroupEnumUnitsInRect(g,bj_mapInitialPlayableArea,enemy_filter)
n = FirstOfGroup(g)
if n == null {return null}
x1 = GetUnitX(u)
y1 = GetUnitY(u)
d = x1 - GetUnitX(n)
r = y1 - GetUnitY(n)
dist = SquareRoot(d * d + r * r)
u = n
GroupRemoveUnit(g,n)
loop {
n = FirstOfGroup(g)
exitwhen n == null
d = x1 - GetUnitX(n)
r = y1 - GetUnitY(n)
r = SquareRoot(d * d + r * r)
if r < dist {
dist = r
u = n
}
GroupRemoveUnit(g,n)
}
DestroyGroup(g)
g = null
return u
}
))
в итоге ты получаешь функцию NearEnemy(unit u) которая возвратит ближайшего врага юнита u
Старый 26.10.2010, 20:58
Ежик

offline
Опыт: 2,536
Активность:
~ManWhoKnows,
Спасибо тебе. Но чтото я не совсем пойму работу кода. Немог ты скинуть это всё в карту? У меня ошибки( в JNPG.
А если зделаеш так,то буду очень блогодарен.
Цитата:
Мне что нужно,используется спелл и выбирается ближайший юнит, и приминяющий юнит бежит к этому юниту.Может есть возможность зделать легче?
Старый 26.10.2010, 21:12
ManWhoKnows
just another wc3 modmaker
offline
Опыт: 915
Активность:
это сиджасс cjass.xgm.ru/files/?cJassSetup.exe
скачай, установи в папку JNPG и юзай. (ты точно также можешь писать и на обычном синтаксисе)
если чтото придёт в голову, обязательно напишу.
кстати, можно заюзать идею с последовательным выбором юнитов на расстоянии, (например 1000, 5000, 10000, вся карта) это ускорит.
Старый 26.10.2010, 21:17
Ежик

offline
Опыт: 2,536
Активность:
Цитата:
кстати, можно заюзать идею с последовательным выбором юнитов на расстоянии, (например 1000, 5000, 10000, вся карта) это ускорит.

Мм. Напиши плиз как должен работать эти функции. Циклом? Или как?
Старый 26.10.2010, 21:37
ManWhoKnows
just another wc3 modmaker
offline
Опыт: 915
Активность:
на основе того что я дал выше, внутрь надо сунуть ещё один цикл. и вместо GroupEnumUnitsInRect
использовать GroupEnumUnitsInRange значение рэндж брать 1000 и прибавлять, скажем, по 4000 каждый цикл, выйдти из цикла когда рэндж будет больше 9000 ^^ и использовать уже оригинальную проверку из той функции что я писал. но
минус такого подхода в том, что чем дальше будет враг, тем медленней будет исполнятся функция.

Отредактировано ManWhoKnows, 26.10.2010 в 22:30.
Старый 26.10.2010, 21:44
Klop
Папа римский
offline
Опыт: 13,006
Активность:
ManWhoKnows, твой метод плох человек не сильно разберается в Jass,от того что ты дал код,он не понимает что там как происходит,он не сможет его использовать так как ему надо,я же свой метод взял на понимании как на простейшом уроке программирования определить минимальное значения массива

т.е сравнить каждый элемент массива и в переменную min его записывать,нечего про быстроту неговорил а только про самый простой способ это реализовать и понимать
Старый 26.10.2010, 23:43
ManWhoKnows
just another wc3 modmaker
offline
Опыт: 915
Активность:
Mr_KLOP, слушай, ты чо вмазался? парой постов выше твои сообщения были понятны, а теперь какой-то поток слов, я вообще не понимаю о чём ты говоришь.
Старый 27.10.2010, 00:24
Klop
Папа римский
offline
Опыт: 13,006
Активность:
ManWhoKnows, ладно забей,я знаю что я карявый мастер джазза и у меня свои логика построения кода я вышлю пример,а автор пусть посмотри что ему лучше быстрота или моё не быстрое

По поводу примера
1. При использовании спелла Удар грома,пикаются все вражеские живие юниты записывается каждый пикнутый юнит в массив Thunder_U с индексом [Thunder_I] который увеличивается на единицу при каждом пике,т.е создался массив пикнутых юнитов
2.Присваиваем переменной min значение первого пикнутого юнита(Thunder_U[1])
3.В карте нестандартный код сделал функцию расчёта дистанции свою без локаций
» Функция Distance
Код:
function Distance takes real x,real y,unit u returns real
    local real px = GetUnitX(u)
    local real py = GetUnitY(u)
    set px = px - x
    set py = py - y
    return SquareRoot(px * px + py * py)
endfunction

4. Запускаю цикл до переменной Thunder_I и проверяю дистанцию юнита min с Thunder_U[i],если дистанция min больше Thunder_U[i],тогда присваиваем min значение Thunder_U[i]
5.После окончания цикла выполняем нужные дейсвия с юнитом min,у меня он Удаляется с карты и вылазит сообщение растояния
6.Обнуляю массив и остальные переменные

Работает долговато,но работает,незнаю если вариант не устраивает ,то хорошо ненадо мне описывать,что он геморойный и не стоит его осуждать,меня это бесит,читаем мой статус

Вроде всё,спасибо за внимание
» Вот мой код
Код:
globals
    unit array Thunder_U
    integer Thunder_I = 0
endglobals
function Thunder_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'AHtc'
endfunction

function FilterThunder takes nothing returns boolean
   return IsUnitAlly(GetFilterUnit(),GetOwningPlayer(GetSpellAbilityUnit())) == false and GetUnitState(GetFilterUnit(), UNIT_STATE_LIFE) >= 0
endfunction

function ThunderPick takes nothing returns nothing
   set Thunder_I = Thunder_I + 1
   set Thunder_U[Thunder_I] = GetEnumUnit()
endfunction

function Thunder_Actions takes nothing returns nothing
   local real x = GetUnitX(GetTriggerUnit())
   local real y = GetUnitY(GetTriggerUnit())
   local integer i = 0
   local unit min = null
   local rect r = bj_mapInitialPlayableArea
   local boolexpr b = Condition(function FilterThunder)
   local group g = CreateGroup()
   set Thunder_I = 0
   call GroupEnumUnitsInRect(g,r,b)
   call ForGroup(g,function ThunderPick)
   call BJDebugMsg(I2S(Thunder_I))
   set min = Thunder_U[1]
   loop
      set i = i + 1
      if Distance(x,y,min)>Distance(x,y,Thunder_U[i]) then
      set min = Thunder_U[i]
      endif
   exitwhen i == Thunder_I
   endloop
   call RemoveUnit(min)
   call BJDebugMsg(R2S(Distance(x,y,min)))
   set i = 1
   loop
   set Thunder_U[i] = null
   exitwhen i == Thunder_I
   endloop
   call DestroyBoolExpr(b)
   call DestroyGroup(g)
   call RemoveRect(r)
   set min = null
   set b = null
   set g = null
   set r = null
endfunction

//===========================================================================
function InitTrig_Thunder takes nothing returns nothing
    set gg_trg_Thunder = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Thunder, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_Thunder, Condition( function Thunder_Conditions ) )
    call TriggerAddAction( gg_trg_Thunder, function Thunder_Actions )
endfunction
Прикрепленные файлы
Тип файла: w3x test.w3x (10.1 Кбайт, 11 просмотров )
Старый 27.10.2010, 00:45
Ответ

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск

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

BB-коды Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход



Часовой пояс GMT +3, время: 03:04.