Помогите понять в чем проблема, пожалуйста -.-
Снаряд создается с небольшим смещением от героя(правее или левее) и летит по дуге в точку каста.
Смещение = 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
27
6 лет назад
Отредактирован MpW
0
Darknessay, мб Рексара взломать? пен доту смотри
код опен дота
// OpenDota 6.41 deprotected by NETRAT and DioD
// inspired by everyone who posted on forum threads and feedback page
// based on OpenDota 6.32b, deprotected by DimonT, NETRAT and TheBloodiest
// http://dimon.xgm.ru/opendota/
// Visit our modmaking community at http://xgm.ru/

// Objects used:
// 'A0O1' = Wild Axes (Beastmaster : Rexxar)
// 'A04R' = Marker (Nether Ward 4,Lightning Bolter,Nether Ward 3,Nether Ward 2,Vengeance Death caster,...)
// 'e01T' = Boomerang
// 'Amrf' = Crow Form (Medivh)

// DEBUG Trigger Number : 34
function WildAxesSpell takes nothing returns boolean
	return GetSpellAbilityId()=='A0O1'
endfunction

function WildAxesTreeCut takes nothing returns nothing
	call KillDestructable(GetEnumDestructable())
endfunction

function WildAxesDamage takes unit pWho,real pxx,real pyy,group pVictims returns nothing
	local group lGroup=CreateGroup()
	local unit lTMP
	local rect lMx=Rect(pxx-150,pyy-150,pxx+150,pyy+150)
	call GroupEnumUnitsInRange(lGroup,pxx,pyy,150,null)
	loop
		set lTMP=FirstOfGroup(lGroup)
		exitwhen lTMP==null
		if(IsUnitInGroup(lTMP,pVictims)==false and IsUnitEnemy(lTMP,GetOwningPlayer(pWho))and IsUnitVisible(lTMP,GetOwningPlayer(pWho)))then
			if(GetUnitAbilityLevel(lTMP,'A04R')!=1 and GetUnitState(lTMP,UNIT_STATE_LIFE)>0 and IsUnitType(lTMP,UNIT_TYPE_STRUCTURE)==false)then
				call GroupAddUnit(pVictims,lTMP)
				call UnitDamageTarget(pWho,lTMP,60+GetUnitAbilityLevel(pWho,'A0O1')*30,true,true,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_NORMAL,WEAPON_TYPE_METAL_HEAVY_SLICE)
				call AddSpecialEffectTarget("Objects\\Spawnmodels\\Human\\HumanBlood\\BloodElfSpellThiefBlood.mdl",lTMP,"overhead")
			endif
		endif
		call GroupRemoveUnit(lGroup,lTMP)
	endloop
	call EnumDestructablesInRect(lMx,null,function WildAxesTreeCut)
	call RemoveRect(lMx)
	call DestroyGroup(lGroup)
endfunction

function WildAxesTimer takes nothing returns nothing
	local string lTable=H2Tx(GetExpiredTimer())
	local unit lAxe=GetUnit(lTable,"Axe")
	local unit lCaster=GetUnit(lTable,"Hero")
	local real lAx=GetReal(lTable,"Ax")
	local real lAy=GetReal(lTable,"Ay")
	local real lCx=GetReal(lTable,"Cx")
	local real lCy=GetReal(lTable,"Cy")
	local real lBx=GetReal(lTable,"Bx")
	local real lBy=GetReal(lTable,"By")
	local real laa=GetReal(lTable,"a")
	local real lbb=1-laa
	local boolean lIsPassed=GetBoolean(lTable,"FirstPass")
	local group lCheckGroup=GetGroup(lTable,"AlreadyDamaged")
	call SetUnitX(lAxe,SafeX(lAx*laa*laa+lBx*2*laa*lbb+lCx*lbb*lbb))
	call SetUnitY(lAxe,SafeY(lAy*laa*laa+lBy*2*laa*lbb+lCy*lbb*lbb))
	call WildAxesDamage(lCaster,GetUnitX(lAxe),GetUnitY(lAxe),lCheckGroup)
	if(lIsPassed)then
		call SetReal(lTable,"a",laa-.02)
	else
		call SetReal(lTable,"a",laa+.02)
		call SetReal(lTable,"Ax",GetUnitX(lCaster))
		call SetReal(lTable,"Ay",GetUnitY(lCaster))
	endif
	if(laa<0 and lIsPassed)then
		call SetBoolean(lTable,"FirstPass",false)
		call SetReal(lTable,"Bx",lAx+300*Cos(Atan2(lCy-lAy,lCx-lAx)+GetReal(lTable,"AngleOffset")))
		call SetReal(lTable,"By",lAy+300*Sin(Atan2(lCy-lAy,lCx-lAx)+GetReal(lTable,"AngleOffset")))
	endif
	if(laa>1 and lIsPassed==false)then
		call PauseTimer(GetExpiredTimer())
		call DestroyGroup(lCheckGroup)
		call FastFlush(lTable)
		call RemoveUnit(lAxe)
		call DestroyTimer(GetExpiredTimer())
	endif
endfunction

function WildAxesSettings takes nothing returns nothing
	local unit lCaster=GetTriggerUnit()
	local real lCasterX=GetUnitX(lCaster)
	local real lCasterY=GetUnitY(lCaster)
	local real lTargetX=GetLocationX(GetSpellTargetLoc())
	local real lTargetY=GetLocationY(GetSpellTargetLoc())
	local unit lAxe1=CreateUnit(GetOwningPlayer(lCaster),'e01T',lCasterX,lCasterY,270.)
	local unit lAxe2=CreateUnit(GetOwningPlayer(lCaster),'e01T',lCasterX,lCasterY,270.)
	local string lTable1
	local string lTable2
	local timer lTimer1=CreateTimer()
	local timer lTimer2=CreateTimer()
	if GetSpellTargetUnit()!=null then
		set lTargetX=GetUnitX(GetSpellTargetUnit())
		set lTargetY=GetUnitY(GetSpellTargetUnit())
	endif
	call UnitAddAbility(lAxe1,'Amrf')
	call UnitRemoveAbility(lAxe1,'Amrf')
	call SetUnitFlyHeight(lAxe1,150,0)
	call UnitAddAbility(lAxe2,'Amrf')
	call UnitRemoveAbility(lAxe2,'Amrf')
	call SetUnitFlyHeight(lAxe2,150,0)
	set lTable1=H2Tx(lTimer1)
	call SetHandle(lTable1,"Hero",lCaster)
	call SetHandle(lTable1,"Axe",lAxe1)
	call SetHandle(lTable1,"AlreadyDamaged",CreateGroup())
	call SetReal(lTable1,"Ax",lCasterX)
	call SetReal(lTable1,"Ay",lCasterY)
	call SetReal(lTable1,"Cx",lTargetX)
	call SetReal(lTable1,"Cy",lTargetY)
	call SetReal(lTable1,"Bx",lCasterX+300*Cos(Atan2(lTargetY-lCasterY,lTargetX-lCasterX)+45))
	call SetReal(lTable1,"By",lCasterY+300*Sin(Atan2(lTargetY-lCasterY,lTargetX-lCasterX)+45))
	call SetReal(lTable1,"a",1)
	call SetReal(lTable1,"AngleOffset",-45)
	call SetBoolean(lTable1,"FirstPass",true)
	set lTable2=H2Tx(lTimer2)
	call SetHandle(lTable2,"Hero",lCaster)
	call SetHandle(lTable2,"Axe",lAxe2)
	call SetHandle(lTable2,"AlreadyDamaged",CreateGroup())
	call SetReal(lTable2,"Ax",lCasterX)
	call SetReal(lTable2,"Ay",lCasterY)
	call SetReal(lTable2,"Cx",lTargetX)
	call SetReal(lTable2,"Cy",lTargetY)
	call SetReal(lTable2,"Bx",lCasterX+300*Cos(Atan2(lTargetY-lCasterY,lTargetX-lCasterX)-45))
	call SetReal(lTable2,"By",lCasterY+300*Sin(Atan2(lTargetY-lCasterY,lTargetX-lCasterX)-45))
	call SetReal(lTable2,"a",1)
	call SetReal(lTable2,"AngleOffset",45)
	call SetBoolean(lTable2,"FirstPass",true)
	call TimerStart(lTimer1,.025,true,function WildAxesTimer)
	call TimerStart(lTimer2,.025,true,function WildAxesTimer)
endfunction

function WildAxesInit takes nothing returns nothing
	local trigger ltt=CreateTrigger()
	call TriggerRegisterAnyUnitEventBJ(ltt,EVENT_PLAYER_UNIT_SPELL_EFFECT)
	call TriggerAddCondition(ltt,Condition(function WildAxesSpell))
	call TriggerAddAction(ltt,function WildAxesSettings)
endfunction


function InitTrig_Wild_Axes takes nothing returns nothing
endfunction
код новой доты
function R92 takes nothing returns boolean
	return GetSpellAbilityId()==1093685041
endfunction

function LWI takes nothing returns boolean
return true
endfunction

function T5I takes destructable d returns boolean
return GetDestructableTypeId(d)==1314157667 or GetDestructableTypeId(d)==1314157687 or GetDestructableTypeId(d)==1096053874 or GetDestructableTypeId(d)==1110454322 or GetDestructableTypeId(d)==1110454323 or GetDestructableTypeId(d)==1110454325
endfunction

function QDI takes nothing returns nothing
if T5I(GetEnumDestructable())and IsDestructableAliveBJ(GetEnumDestructable())then
set JJ=JJ+1
call KillDestructable(GetEnumDestructable())
endif
endfunction

function QEI takes real x,real y,real d returns integer
local rect r=Rect(x-d,y-d,x+d,y+d)
set JJ=0
call EnumDestructablesInRect(r,Condition(function LWI),function QDI)
call RemoveRect(r)
set r=null
return JJ
endfunction



function PAI takes real x1,real y1,real x2,real y2 returns real
return SquareRoot(((x1-x2)*(x1-x2))+((y1-y2)*(y1-y2)))
endfunction





function RGI takes real y returns real
local real RDI=GetRectMinY(bj_mapInitialPlayableArea)+50
if(y<RDI)then
return RDI
endif
set RDI=GetRectMaxY(bj_mapInitialPlayableArea)-50
if(y>RDI)then
return RDI
endif
return y
endfunction

function RCI takes real x returns real
local real RDI=GetRectMinX(bj_mapInitialPlayableArea)+50
if(x<RDI)then
return RDI
endif
set RDI=GetRectMaxX(bj_mapInitialPlayableArea)-50
if(x>RDI)then
return RDI
endif
return x
endfunction

function MCI takes group g returns nothing

local integer i=GetHandleId(g)-UY

if i<0 or i>120 then

	set OJ=true

else

	call GroupClear(g)

	set QY[i]=false

	set IJ=i

endif

endfunction

function RA2 takes unit R7I,real x,real y,group WVO returns nothing
local group GK1=MDI()
local unit V11
call QEI(x,y,150)
call GroupEnumUnitsInRange(GK1,x,y,150,Condition(function LWI))
loop
set V11=FirstOfGroup(GK1)
exitwhen V11==null
if(IsUnitInGroup(V11,WVO)==false and IsUnitEnemy(V11,GetOwningPlayer(R7I)))then
if(GetUnitAbilityLevel(V11,1093678162)!=1 and GetUnitState(V11,UNIT_STATE_LIFE)>0 and IsUnitType(V11,UNIT_TYPE_STRUCTURE)==false)then
call GroupAddUnit(WVO,V11)
call UnitDamageTarget(R7I,V11,60+GetUnitAbilityLevel(R7I,1093685041)*30,true,true,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_NORMAL,WEAPON_TYPE_METAL_HEAVY_SLICE)
call AddSpecialEffectTarget("Objects\\Spawnmodels\\Human\\HumanBlood\\BloodElfSpellThiefBlood.mdl",V11,"overhead")
endif
endif
call GroupRemoveUnit(GK1,V11)
endloop
call MCI(GK1)
endfunction

function RB2 takes nothing returns nothing
local integer MKI=GetHandleId(GetExpiredTimer())
local unit RC2=(LoadUnitHandle(XY,(MKI),(290))) //дайми
local unit N0I=(LoadUnitHandle(XY,(MKI),(14))) //кастер
//координаты кастера
local real Ax=(LoadReal(XY,(MKI),(284)))
local real Ay=(LoadReal(XY,(MKI),(285)))
//координаты цели
local real Cx=(LoadReal(XY,(MKI),(286)))
local real Cy=(LoadReal(XY,(MKI),(287)))

local real Bx=(LoadReal(XY,(MKI),(288)))
local real By=(LoadReal(XY,(MKI),(289)))

local real a=(LoadReal(XY,(MKI),(137)))

local real b=1-a

local boolean RD2=(LoadBoolean(XY,(MKI),(291)))

local group WVO=(LoadGroupHandle(XY,(MKI),(133)))

local real RE2=RMaxBJ(PAI(Ax,Ay,Cx,Cy)/1300,0.4)

call SetUnitX(RC2,RCI(Ax*a*a+Bx*2*a*b+Cx*b*b))
call SetUnitY(RC2,RGI(Ay*a*a+By*2*a*b+Cy*b*b))

call RA2(N0I,GetUnitX(RC2),GetUnitY(RC2),WVO)

if(RD2)then

	call SaveReal(XY,(MKI),(137),((a-.02/RE2)*1.0))

else
	
call SaveReal(XY,(MKI),(137),((a+.02/RE2)*1.0))

	call SaveReal(XY,(MKI),(284),((GetUnitX(N0I))*1.0))

	call SaveReal(XY,(MKI),(285),((GetUnitY(N0I))*1.0))

endif

if(a<0 and RD2)then

	call SaveBoolean(XY,(MKI),(291),(false))

	call SaveReal(XY,(MKI),(288),((Ax+300*Cos(Atan2(Cy-Ay,Cx-Ax)+(LoadReal(XY,(MKI),(292)))))*1.0))

	call SaveReal(XY,(MKI),(289),((Ay+300*Sin(Atan2(Cy-Ay,Cx-Ax)+(LoadReal(XY,(MKI),(292)))))*1.0))

endif

if(a>1 and RD2==false)then

	call PauseTimer(GetExpiredTimer())
	
call MCI(WVO)

	call FlushChildHashtable(XY,(MKI))

	call RemoveUnit(RC2)

	call DestroyTimer(GetExpiredTimer())

endif

endfunction

function LGI takes nothing returns nothing
call DisplayTimedTextToPlayer(GetEnumPlayer(),0,U2,YJ,XJ)
endfunction

function LHI takes force LZI,real KLI,string LVI returns nothing
set XJ=LVI
set YJ=KLI
call ForForce(LZI,function LGI)
endfunction

function MDI takes nothing returns group
local integer i=IJ
loop
	exitwhen i==IJ-1
	if QY[i]==false then		
        set IJ=i+1
        if IJ==120 then
			set IJ=0
        endif
        set QY[i]=true		
        return PY[i]
    endif
	set i=i+1
	if i==120 then
		set i=0
	endif

endloop

call LHI(P2,5.00,"|c00ff0303CRITICAL ERROR: FOUND NO AVAILABLE GROUPS|r")
call LHI(P2,5.00,"|c00ff0303Send this replay to IceFrog@gmail.com|r")
return CreateGroup()

endfunction

function QTI takes unit N0I,integer QRI returns nothing
call UnitAddAbility(N0I,QRI)
call UnitMakeAbilityPermanent(N0I,true,QRI)
endfunction

function RF2 takes nothing returns nothing
local unit R7I=GetTriggerUnit()
//координаты кастера
local real Ax=GetUnitX(R7I)
local real Ay=GetUnitY(R7I)
//координаты цели
local real Cx=GetLocationX(GetSpellTargetLoc())
local real Cy=GetLocationY(GetSpellTargetLoc())
//создать dummy
local unit RG2=CreateUnit(GetOwningPlayer(R7I),1697657172,Ax,Ay,270.0)
local unit RH2=CreateUnit(GetOwningPlayer(R7I),1697657172,Ax,Ay,270.0)
//вводят для хэндлов дайми (это нужно для ключа хэша)
local integer RZ2
local integer RV2
//создаем для каждого дайми таймер
local timer RW2=CreateTimer()
local timer RX2=CreateTimer()

if GetSpellTargetUnit()!=null then
	set Cx=GetUnitX(GetSpellTargetUnit())
    set Cy=GetUnitY(GetSpellTargetUnit())
endif

//добавляет какие-то способности для дайми (видимо дает способность ворона - летать)
call QTI(RG2,1097691750) 
call UnitRemoveAbility(RG2,1097691750)
call SetUnitFlyHeight(RG2,150,0)

call QTI(RH2,1097691750)
call UnitRemoveAbility(RH2,1097691750)
call SetUnitFlyHeight(RH2,150,0)

set RZ2=GetHandleId(RW2) //хэндл таймера
call SaveUnitHandle(XY,(RZ2),(14),(R7I)) //кастер
call SaveUnitHandle(XY,(RZ2),(290),(RG2)) //дайми
call SaveGroupHandle(XY,(RZ2),(133),(MDI())) //добавляет созданную группу, функция MDI какие-то счетчики делает и прочую херню
//сохраняем координаты кастера
call SaveReal(XY,(RZ2),(284),((Ax)*1.0))
call SaveReal(XY,(RZ2),(285),((Ay)*1.0))
//сохраняем координаты цели
call SaveReal(XY,(RZ2),(286),((Cx)*1.0))
call SaveReal(XY,(RZ2),(287),((Cy)*1.0))
//сохраняем 
call SaveReal(XY,(RZ2),(288),((Ax+300*Cos(Atan2(Cy-Ay,Cx-Ax)+45))*1.0))
call SaveReal(XY,(RZ2),(289),((Ay+300*Sin(Atan2(Cy-Ay,Cx-Ax)+45))*1.0))
call SaveReal(XY,(RZ2),(137),((1)*1.0))
call SaveReal(XY,(RZ2),(292),((-45)*1.0))
call SaveBoolean(XY,(RZ2),(291),(true))

set RV2=GetHandleId(RX2)
call SaveUnitHandle(XY,(RV2),(14),(R7I))
call SaveUnitHandle(XY,(RV2),(290),(RH2))
call SaveGroupHandle(XY,(RV2),(133),(MDI()))
call SaveReal(XY,(RV2),(284),((Ax)*1.0))
call SaveReal(XY,(RV2),(285),((Ay)*1.0))
call SaveReal(XY,(RV2),(286),((Cx)*1.0))
call SaveReal(XY,(RV2),(287),((Cy)*1.0))
call SaveReal(XY,(RV2),(288),((Ax+300*Cos(Atan2(Cy-Ay,Cx-Ax)-45))*1.0))
call SaveReal(XY,(RV2),(289),((Ay+300*Sin(Atan2(Cy-Ay,Cx-Ax)-45))*1.0))
call SaveReal(XY,(RV2),(137),((1)*1.0))
call SaveReal(XY,(RV2),(292),((45)*1.0))
call SaveBoolean(XY,(RV2),(291),(true))

call TimerStart(RW2,.025,true,function RB2)
call TimerStart(RX2,.025,true,function RB2)

endfunction

function Q8I takes nothing returns boolean
	return true
endfunction

function Q9I takes trigger t,playerunitevent QAI returns nothing
local integer L9I=0
loop
	call TriggerRegisterPlayerUnitEvent(t,Player(L9I),QAI,Condition(function Q8I))
	set L9I=L9I+1
exitwhen L9I==16
endloop
endfunction

function V51 takes nothing returns nothing
local trigger t=CreateTrigger()
call Q9I(t,EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(t,Condition(function R92))
call TriggerAddAction(t,function RF2)
endfunction
в новой доте в коде еще кучу глобальных переменных намешаны. мне лень короч разбираться что это за переменные. завтра подробно рассмотрю этот код рексара. мне интересно как он там так двигается. проще взять код из старой опен доты и переделать, и постоянно сравнить с новым. Практически одинаков
дождись клампа
Погоди, так, момент, как может быть парабола не по Z, если при параболе юнит летит по прямой, только высота меняется, а тут он должен лететь дугой?
можно одновременно две вещи сделать (поворачивать дугой, и поднимать по оси Z), просто не знал, что тебе надо.
Загруженные файлы
0
30
6 лет назад
0
Почему ты называешь вектора углами?
0
19
6 лет назад
Отредактирован Darknessay
0
Clamp:
Почему ты называешь вектора углами?
Потому что в варе это называется "угол поворота"(facing angle) - поворот юнита(лицом) в направлени 0-360 градусов.
Я не силен в терминологии. Вектор = направление, верно?

Вы не могли бы еще сюда заглянуть, ребят?
Я подожду разбор кода топоров от Steal Nerves, но пока что забил и кидаю снаряд по прямой+парабола.
Если у меня получится потом раздуплиться в топорах - сделаю дугу, но это мой загон, не принципиально, а вот момент в вопросе выше - вполне себе важная штука(например, герой должен разбрасывать кольцом вокруг себя 8 снарядов, каждый снаряд должен лететь от героя по параболе(типа он их подкинул ,а потом они падают). их исх. высота = 125, и эту высоту я сниму дополнительным таймером, пока они будут лететь, но эта парабола фиксирует высоту и снаряды сразу перемещаются в Z=0.00, а потом от 0 делают свою параболу - ну, а нужно чтобы они стартовали у него над головой, на высоте 125. надеюсь вы поняли.)
Там в вопросе я написал, что мне нужно просто перенастроить эту параболу таким образом, чтобы она не фиксировала высоту юнита, а прибавляла/убавляла, не перебивая собой другие изменения высоты(например, если подкинуть этого же юнита повторно этой функцией). Полагаю, что это всё таки возможно, но там vJass структура+муи, а с моими гуишными знаниями жасса, я боюсь даже пробовать там что то менять)
0
23
6 лет назад
0
чем не угодил узнать растоянии снаряда и цели а также узнать высота снаряда и цели вот 2 параметр который поможет вернуть цель красиво после какого направении скинеш....
Вот смотри берем снаряд и цель
раскрыть
» Формула параболы (учитывающая начальную и конечную высоту)
Автор оригинала - moyack
Автор оптимизированного варианта - Shadow Daemon
h - максимальная высота в прыжке на середине расстояния (x = d / 2),
d - общее расстояние до цели,
x - расстояние от исходной цели до точки, где следует взять высоту по параболе.
library ParabolicMovement2
function ParabolaZ2 takes real y0, real y1, real h, real d, real x returns real
return (2*(y0 + y1 - 2*h)*(x/d - 1) + (y1 - y0))*(x/d) + y0
endfunction
endlibrary
Вариант Shadow Daemon
h - максимальная высота в прыжке,
d - общее расстояние до цели,
x - расстояние от исходной цели до точки, где следует взять высоту по параболе.
library ParabolicMovement2
function ParabolaZ2 takes real y0, real y1, real h, real d, real x returns real
return ((4 * h / d) * (d - x) + y1 - y0) * (x / d) + y0
endfunction
endlibrary
0
19
6 лет назад
Отредактирован Darknessay
0
pro100master:
А теперь встрой это в ту муишную структуру, пожалуйста, так чтобы всё работало... х)
На всякий случай, повторю вопрос еще более конкретно:
Нужно чтобы парабола не фиксировала высоту вообще никак. Вообще никак. Вообще никак.
Только плюс высота / минус высота.
Т.е. получается должно быть что то типа такого:
d=расстояние АБ
h=макс. высота дуги
r=(h/(d/spd)/blabla_formula)
r2=(d/blabla_formula)
А потом каждый тик таймера:
Высота юнита +r
r-r2
Ну и в итоге должно получиться, что высота юнита прибавляется на R каждый тик, а сам R уменьшается, и при достижении середины пути, R будет равен нулю, а дальше - отрицательный, так чтобы юнит снижался.
Короче, я в принципе шарю как это сделать, но я не шарю в муишной структуре - это беда...
0
27
6 лет назад
Отредактирован MpW
0
вот примеры. Ничего нового в них нет. Один пример - код из доты про рексара с топорами, и второй по параболе (там подумал еще и поднимать, и двигать в бок), единственное, что не написал возвращение. Просто лень было.
Darknessay, радиус очень сложно вычислить. Это тебе не окружность или сфера, где идеально круглое. там что вроде овала, эллипса. мб есть какие-то способы, но чтобы сделать = надо знать математику хорошо (там геометрия, тригонометрия, матрица и др)
раскрыть
радиус можно выяснить по теореме пифагора. Помнишь прямоугольный треугольник. Там есть два катета, и гипотенуза (гипотенуза это и есть радиус). горизонтальный катет = d/2, вертикальный катет = h. И там ищи по теореме пифагора. Зная, значения двух катетов, можно еще и узнать и угол (если он нужен).
Загруженные файлы
0
19
6 лет назад
0
Steal nerves:
*человек, рисовавший голых баб на всех уроках, начиная с первого класса*
Я не понимаю этих сложных слов, но щас покажу это умному братишке, чтобы он попытался обьяснить :D
Спасибо тебе за труды. Возвращение там никакое не нужно, полет снаряда в один конец
5
27
6 лет назад
Отредактирован MpW
5
Кстати можно двигать так:
скрины формулы
пример с топорами
движение по эллипсу, 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-приказ у канала, тогда будет все ок (не знаю, почему дал ему вторую, мне казалось крута сравнить, щас не кажется)
Принятый ответ
Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.