Помогите понять в чем проблема, пожалуйста -.-
Снаряд создается с небольшим смещением от героя(правее или левее) и летит по дуге в точку каста.
Смещение = 45 либо -45(рандомно), это же и поворот снаряда исходный.
По формуле мана снаряда устанавливается как = значение, которое должно вычитаться от его текущего поворота, чтобы он собственно летел по дуге, поворачиваясь.
Так вот, почему то финальный угол, который должен быть равен +-90(типа полный поворот снаряда к концу пути = дуга), в итоге равняется 115(где то при 1000 расстояния), а сам снаряд, кажется, долетает расстояние до точки каста, но не формирует полную дугу - чем дальше точка каста. Т.е. он умирает левее или правее точки каста(на глаз, где то на 250-500 от точки каста, при расстоянии в 2000).
Я думаю дело в неверных расчетах с 3.14, но что не так?
Запуск:
Движение(каждые 0.03):

Принятый ответ

Кстати можно двигать так:
скрины формулы
пример с топорами
движение по эллипсу, Rx и Ry отличаются
есть еще формулы по ссылке и ссылке но здесь больше сложностей
есть форму скорпа
function geoArc takes real wayAbsolute returns real
    return sin((bj_PI / 2.0) * wayAbsolute)
endfunction

function GeoArcBetweenReal takes real wayMin, real wayMax, real wayNow returns real
    return geoArc((wayNow-wayMin) / (wayMax-wayMin))
endfunction

function GeoArcRelative takes real wayMin, real wayMax, real wayNow, real resultMin, real resultMax returns real
    return (GeoArcBetweenReal(wayMin,wayMax,wayNow) * (resultMax-resultMin)) + resultMin
endfunction
вызываешь GeoArcRelative(тут начало отсчета, тут конец отсчета, тут место где находится сейчас, тут минимальный нужный результат, тут максимальный нужный результат) возвращает значение между последними двумя относительно того, как далеко wayNow переместилась между первыми двумя
вобще это в 2D, а надо в 3D - добавь полярные координаты, или сделай отдельно для каждого измерения...
ну у тебя есть Z допустим пол это 50, потолок (самый верх параболы) - это 300
юнит идет от точки 0 до точки 1000, вот он идет, идет, где он щас находится пусть будет X
set unitZ = GeoArcRelative(0, 1000, X, 50, 300)
wayMin - минимальная расстояние (можно поставить ноль)
wayMax - максимальная точка (ставите нужный размер длины дуги)
wayMin и wayMax образуют отрезок (длину дуги)
wayNow - текущее положение точки
resultMin - минимальная высота
resultMax - максимальная высота
карта
еще есть бросок Tiny из доты и бросок из Пуджа Варс (надыбил на форуме). Код очень отличается от типичной параболы у нас на сайте в алгоритмах, там за основу счетчик берется. Мне понравился бросок из Пуджа Варс. Все эти примеры скинул в карту Только в наработке с Toss Tinny, которую скинул, есть небольшая накладка, там у него два скила (спешил и не посмотрел), и нужно поменять id-приказ у канала, тогда будет все ок (не знаю, почему дал ему вторую, мне казалось крута сравнить, щас не кажется)
`
ОЖИДАНИЕ РЕКЛАМЫ...

Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
0
19
6 лет назад
0
Clamp:
типа такого?
Да, прямо как у Дианы)
Maniac_91:
Вместо округления pi попробуй перевести в радианы 180 градусов (как-то так: "DEGTORAD(180)").
Все равно откос.
0
30
6 лет назад
0
Вечером если будет минутка - накидаю двигалку.

большинство функций мне приходится искать на гуи и конвертировать
JNGP на что с его Function List?
0
19
6 лет назад
0
Clamp:
JNGP на что с его Function List?
Короче говоря, это дело привычки. Мне не особо вперлось БЖшки раскрывать, а так, все возможные утечки я устраняю.
Вроде БЖ максимум работу замедляет своими вечными пересылками, но утечек там никаких нет?
Вот ты говоришь "функшен лист", но чтобы найти там функцию, ты должен хотя бы примерно знать её название)
Я потихоньку пишу себе в шапку карты различные функции и должен сказать, что мне очень неудобно ориентироваться в чистом коде, но возможно я таким путем привыкну и начну писать по пацански перса в 1 триггер)
0
23
6 лет назад
0
сдались вас... я вот не учил анг. языка но варик понимаю потому что я изучил основа программирование за 1 месяц а дальше уже можно сотворить....
а если будете тянуть типо не знаете как называете функция то вы с какого языка пришли?
геттеры сеттеры функции основа поучить
0
19
6 лет назад
0
pro100master:
Но я же не об этом задал вопрос :\
0
23
6 лет назад
0
Darknessay, единсвеный если ты учил геометрия то изи решения
3
30
6 лет назад
3
Смещение = 45 либо -45, это же и поворот снаряда исходный.
Что это значит? Ты уравниваешь 45 единиц длинны и 45 градусов поворота?
Лучше нарисуй схему с указанием всех углов и зависимостей величин, мб и сам решишь в процессе.
0
27
6 лет назад
0
Clamp, тоже не понял, когда мне говорил.
0
19
6 лет назад
Отредактирован Darknessay
0
Clamp:
Поясню:
1- Берется угол АБ( от кастера к таргету)
2- Под углом АБ+45, смещенно на 50 ед. расстояния создается снаряд(С). Снаряд создается с поворотом ЛИЦА = СБ+45 сразу - для удобства, потому что я понимаю, что иначе угол будет не +45.
Так что про угол АБ забываем, чтобы не запутываться. Дальше используем только СБ.
3- Снаряд стоит в точке С, лицом повернут по углу СБ+45.
4- Снаряд начинает двигаться в направлении собственного лица. Каждый тик таймера 0.03, снаряд сдвигается на 70 ед. и должен постоянно поворачивать на N угла(поворота) для того, чтобы его траектория образовала дугу.

Нужно вычислить 2 значения:
1 - реал, который будет отниматься от угла поворота снаряда каждый тик таймера, для того чтобы снаряд летел по дуге.
2 - реал времени, который понадобится снаряду для того, чтобы долететь до точки Б по дуге.
ДА ЧТО ЗА?
Не могу новую картинку прикрепить к тому комменту -_-
Короче да, мне нужна кушка Дианы. Только я не помню, оно летит в точку каста, или там фикс. расстояние? Вроде в точку каста. Если да, то да, кушка Дианы.
Разве что, у меня снаряд создается не в самом герое, а чуть рядом, но мы всё равно начинаем считать всю фигню относительно позиции снаряда(и угла СБ соответственно), а не относительно АБ.

Блин, вот я гомункул. "Дуга, которая должна образоваться" - она, конечно же, не между АБ, а между СБ должна образоваться такой формы, ибо АБ уже не учитывается после спавна снаряда. Просто в паинте я не смог бы "наклонить" сплюснутое кольцо

Если честно, то я уже запарился это обьяснять, ибо не знаю как еще проще обьяснить:
(Предыдущие слова не учитывайте, по новой)
Снаряд вылетает под углом АБ+45, за каждый тик таймера должен поворачивать(угол его поворота должен отниматься), чтобы в конце пути он ударился в точку Б(т.е. его угол ПОВОРОТА в конце должен получиться АБ-45).
Получается, нам нужно вычислить время, за которое снаряд пролетает от А до Б >>ПО ДУГЕ<<(дуга длиннее прямого полета, т.е. и времени чуть больше), потом на основе этого времени выдать снаряду лайфтаймер и получить как раз таки значение угла, которое будет отниматься для образования самой дуги в полете.
Загруженные файлы
2
27
6 лет назад
Отредактирован MpW
2
примерно сделал, Ушло 5-10 часов на это математикой занимался, тригонометрию чутка подучил, пытался вставить и прочее.
угол дуги можно отсчитать если знать расстояние между кастером и целью и высоту дуги.
Парабола не только для прыжков подходит, но и для 2D движения.
Подойдет? время таймера не забудь изменить, просто для себя в качестве проверки делал.
Можно еще через эллипс сделать, но я так и не понял как там. Перечитывал статьи про эллипс, столько времени на эллипс убил.
раскрыть
Хотел сделать что-то вроде эллипса, используя нашу параболу, Проблема такая, летит плавно. Но эллипс по неведомым причинам становится огромным (юнит частенько за пределы карты вылезает), и поэтому не достигает точки. Проверка не может длину нормально проверить (если задать предел расстояния между кастером и целью 1000, то юнит где-то на половине дуги эллипса останавливается) =( возможно ошибка в моей невнимательности. Поэтому эллипс не смог заюзать
код
function Trig_Cast_Conditions takes nothing returns boolean
return( GetSpellAbilityId() == 'A000' )
endfunction

function ParabolaZ takes real h, real d, real x returns real
  return (4 * h / d) * (d - x) * (x / d)
endfunction

function Trig_Cast_Actions1 takes nothing returns nothing
//запущенный таймер и его id-хэндл
local timer t = GetExpiredTimer()
local integer id = GetHandleId(t)

local unit dummy = LoadUnitHandle(udg_Hash,id,0) //dummy

local real angle = LoadReal(udg_Hash,id,1) //угол поворота
local real h = LoadReal(udg_Hash,id,2) //высота дуги
local real d1 = LoadReal(udg_Hash,id,3) //длина дуги
local real e = LoadReal(udg_Hash,id,4) 
//координаты кастера = начальная точка дуги A
local real x1 = LoadReal(udg_Hash,id,5) 
local real y1 = LoadReal(udg_Hash,id,6)
//конечная точка дуги A2
local real x2 = LoadReal(udg_Hash,id,7)
local real y2 = LoadReal(udg_Hash,id,8)
//определение длины d2 между dummy и конечной точкой A1
local real dx = x2-GetUnitX(dummy)
local real dy = y2-GetUnitY(dummy)
local real d2 = SquareRoot(dx*dx + dy*dy)

//ввожу переменные для будущих вычислений
local real p //достаю нужную высоту с помощью функции параболы
local real A //угол параболы = не пригодился.
local real D //длина эллипса = не пригодился.
local real x
local real y



//на каждый тик таймера отодвигаем на 50 единиц (можно задать больше или меньше, например 70 или 100 на ваше усмотрение)
//e - пройденная длина от начальной A1 точки дуги, с помощью ее достаем нужную высоту p
set e = e + 50. 
set p = ParabolaZ(h,d1,e)
set A = p/e
set D = SquareRoot(e*e* ((1-Cos(A)*2)/2)+ p*p* ((1+Cos(A)*2)/2))


set x = x1 + (e * Cos(angle) - p * Sin(angle)) //e*Cos(angle+A)
set y = y1 + (e * Sin(angle) + p * Cos(angle)) //p*Sin(angle+A)
call SaveReal(udg_Hash,id,4,e) //расстояние от dummy до конечной точки дуги
if GetRectMinX(bj_mapInitialPlayableArea) < x1 and GetRectMaxX(bj_mapInitialPlayableArea) > x1 and GetRectMinY(bj_mapInitialPlayableArea) < y1 and GetRectMaxY(bj_mapInitialPlayableArea) > y1 then
    call SetUnitX(dummy,x)
    call SetUnitY(dummy,y)
else
    set d2 = 0
endif
call BJDebugMsg("дистанция между точками dummy и конечной точки дуги d: " + R2S(d2))
call BJDebugMsg("мнимая дистанция (пройденный путь от начальной точки дуги) e: " + R2S(e))
call BJDebugMsg("длина элипса D: " + R2S(D))
call BJDebugMsg("угол дуги А: " + R2S(A* bj_RADTODEG))

if d2 <= 50 then
    call PauseTimer(t)
    call DestroyTimer(t)
    call FlushChildHashtable(udg_Hash,id)
endif

set t = null
set dummy = null

endfunction

function Trig_Cast_Actions takes nothing returns nothing
//кастер
local unit u = GetTriggerUnit()
//координаты кастера
local real x1 = GetUnitX(u)
local real y1 = GetUnitY(u)
//угол поворота кастера
local real angle = GetUnitFacing(u) * bj_DEGTORAD
//длина дуги = задаем нужную длину дуги
local real d = 1000.
//высота дуги = задаем нужную высоту дуги
local real h = 300
//координаты конечной точки типа цели или точки. В данном случае, берем точку впереди на d
//Примечание: Если вы берете координаты точки каста, то нужно будет высчитать длину дуги
//У дуги две крайние точки: A1 = точка кастера, A2 = конечная точка
local real x2 = x1 + d * Cos(angle)
local real y2 = y1 + d * Sin(angle)
//рандом определяет по какой траектории дуги будет лететь вправо или влево
local integer Random = GetRandomInt(0,1)
//dummy-юнит, снаряд
local unit dummy = CreateUnit(GetTriggerPlayer(),'ewsp',x1,y1,GetUnitFacing(u))
local timer t = CreateTimer()
local integer id = GetHandleId(t)

if Random == 1 then //Если Random равен единице, то делаем высоту отрицательной. Тогда будет лететь в другую сторону
    set h = h * (-1)
endif

call SaveUnitHandle(udg_Hash,id,0,dummy)
call SaveReal(udg_Hash,id,1,angle)
call SaveReal(udg_Hash,id,2,h)
call SaveReal(udg_Hash,id,3,d)
call SaveReal(udg_Hash,id,4,0) //счетчик. сохраняем ноль. считывает нужное расстояние от начало A1 до конца A2 дуги
call SaveReal(udg_Hash,id,5,x1)
call SaveReal(udg_Hash,id,6,y1)
call SaveReal(udg_Hash,id,7,x2)
call SaveReal(udg_Hash,id,8,y2)

call TimerStart(t,0.4,true,function Trig_Cast_Actions1)

set u = null
set dummy = null
set t = null

endfunction

//===========================================================================
function InitTrig_Cast takes nothing returns nothing
    set gg_trg_Cast = CreateTrigger(  )
    call TriggerRegisterPlayerUnitEventSimple( gg_trg_Cast, Player(0), EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_Cast, Condition( function Trig_Cast_Conditions ) )
    call TriggerAddAction( gg_trg_Cast, function Trig_Cast_Actions )
endfunction
Кстати я как всегда немного поспешил, нужно исправить вот тут
раскрыть
if d2 <= 50 then
    call PauseTimer(t)
    call DestroyTimer(t)
    call FlushChildHashtable(udg_Hash,id)
endif
изменить строчку вместо 50 поставить 150
if d2 <= 150 then
Загруженные файлы
0
23
6 лет назад
0
Опен дота и узнай код рексара который кидает топором вот там и бери =)
Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.