vladfaust
offline
Опыт:
12,814Активность: |
Опять кривой полет!
Смотрите сами.
» Код
UF
Vector
Projectile
Cast
По более-менее ровной поверхности все ок. А когда на гору указываю... Смотрите:
UPD: Дело в том, что на ровном рельефе снаряд отлично летит в летающего юнита. А на неровном... Значит что-то с получением высоты местности... Отредактировано inadequate_, 04.07.2012 в 00:30. |
04.07.2012, 00:12 | #1
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
DualShock
offline
Опыт:
4,983Активность: |
Не вникался в твой код, но насколько я понял тебе нужно сделать движение снаряда по параболе (без физики).
Посоветую библиотеку с wc3c.net (XE) =О, сам юзаю: Зачем изобретать велосипед когда уже давно всё сделано?
» xefx
Нужна для создания дамми-снарядов с помощью спец-эффектов и полным контролем над ними (в том числе масштабирование и изменения цвета). Помогает избегать тонн даммиков в одной карте.
» xemissle
Это походу то что тебе нужно: Расширение предыдущей библиотеки, позволяет запускать снаряд по траектории в точку, за юнитом, с определённой высоты, хит в цель отслеживается и т. д. Траектория задаётся как в РО например 0.15, со скоростью снаряда аналогично. Но я не думаю что ты это будешь юзать, т. к. код ты пишешь не на vjass :C
Сам код:
» xefx
((код jass
library xefx initializer init requires xebasic, optional xedummy
************************************************** xefx 0.9 -------- Recommended: ARGB (adds ARGBrecolor method) For your movable fx needs ************************************************** ==================================================
globals private constant integer MAX_INSTANCES = 8190 change accordingly. Delay in order to show the death animation of the effect correctly when xefx is destroyed.
You may need to increase this if you are using effects with longer death animations. private constant real MIN_RECYCLE_DELAY = 4.0 The delay does not need to be exact so we do cleanup in batches instead of individually.
This determines how often the recycler runs, should be less than MIN_RECYCLE_DELAY. private constant real RECYCLE_INTERVAL = 0.5 if this is true and the xedummy library is present, units will be recycled instead of removed.
private constant boolean RECYCLE_DUMMY_UNITS = false//true private timer recycler endglobals private struct recyclebin
unit u private recyclebin next=0
private static recyclebin array list private static integer readindex=1 private static integer writeindex=0 private static integer count=0 static method Recycle takes nothing returns nothing
local recyclebin this = .list[readindex] loop exitwhen this==0 static if RECYCLE_DUMMY_UNITS and LIBRARY_xedummy then call XE_ReleaseDummyUnit(this.u) else call RemoveUnit(this.u) endif set this.u=null set .count=.count-1 call this.destroy() set this=this.next endloop set .list[readindex]=0 set .writeindex=.readindex set .readindex=.readindex+1 if .readindex>R2I(MIN_RECYCLE_DELAY/RECYCLE_INTERVAL+1.0) then set .readindex=0 endif if count!=0 then call TimerStart(recycler, RECYCLE_INTERVAL, false, function recyclebin.Recycle) endif endmethod static method create takes unit u returns recyclebin local recyclebin this=recyclebin.allocate() if .count==0 then call TimerStart(recycler, RECYCLE_INTERVAL, false, function recyclebin.Recycle) endif set .count=.count+1 set .u=u call SetUnitOwner(u,Player(15),false) set .next=.list[.writeindex] set .list[.writeindex]=this return this endmethod endstruct private function init takes nothing returns nothing
set recycler=CreateTimer() endfunction struct xefx[MAX_INSTANCES]
public integer tag=0 private unit dummy private effect fx=null private real zang=0.0 private integer r=255 private integer g=255 private integer b=255 private integer a=255 private integer abil=0
static method create takes real x, real y, real facing returns xefx
local xefx this=xefx.allocate() static if RECYCLE_DUMMY_UNITS and LIBRARY_xedummy then set this.dummy= XE_NewDummyUnit(Player(15), x,y, facing*bj_RADTODEG) else set this.dummy= CreateUnit(Player(15), XE_DUMMY_UNITID, x,y, facing*bj_RADTODEG) call UnitAddAbility(this.dummy,XE_HEIGHT_ENABLER) call UnitAddAbility(this.dummy,'Aloc') call UnitRemoveAbility(this.dummy,XE_HEIGHT_ENABLER) call SetUnitX(this.dummy,x) call SetUnitY(this.dummy,y) endif return this endmethod method operator owner takes nothing returns player
return GetOwningPlayer(this.dummy) endmethod method operator owner= takes player p returns nothing
call SetUnitOwner(this.dummy,p,false) endmethod method operator teamcolor= takes playercolor c returns nothing
call SetUnitColor(this.dummy,c) endmethod method operator scale= takes real value returns nothing
call SetUnitScale(this.dummy,value,value,value) endmethod ! textmacro XEFX_colorstuff takes colorname, colorvar
method operator $colorname$ takes nothing returns integer return this.$colorvar$ endmethod method operator $colorname$= takes integer value returns nothing set this.$colorvar$=value call SetUnitVertexColor(this.dummy,this.r,this.g,this.b,this.a) endmethod ! endtextmacro ! runtextmacro XEFX_colorstuff("red","r") ! runtextmacro XEFX_colorstuff("green","g") ! runtextmacro XEFX_colorstuff("blue","b") ! runtextmacro XEFX_colorstuff("alpha","a") method recolor takes integer r, integer g , integer b, integer a returns nothing
set this.r=r set this.g=g set this.b=b set this.a=a call SetUnitVertexColor(this.dummy,this.r,this.g,this.b,this.a) endmethod implement optional ARGBrecolor
method operator abilityid takes nothing returns integer
return this.abil endmethod method operator abilityid= takes integer a returns nothing
if(this.abil!=0) then call UnitRemoveAbility(this.dummy,this.abil) endif if(a!=0) then
call UnitAddAbility(this.dummy,a) endif set this.abil=a endmethod method operator abilityLevel takes nothing returns integer return GetUnitAbilityLevel( this.dummy, this.abil) endmethod method operator abilityLevel= takes integer newLevel returns nothing call SetUnitAbilityLevel(this.dummy, this.abil, newLevel) endmethod method flash takes string fx returns nothing
call DestroyEffect(AddSpecialEffectTarget(fx,this.dummy,"origin")) endmethod method operator xyangle takes nothing returns real
return GetUnitFacing(this.dummy)*bj_DEGTORAD endmethod method operator xyangle= takes real value returns nothing call SetUnitFacing(this.dummy,value*bj_RADTODEG) endmethod method operator zangle takes nothing returns real
return this.zang endmethod method operator zangle= takes real value returns nothing
local integer i=R2I(value*bj_RADTODEG+90.5) set this.zang=value if(i>=180) then set i=179 elseif(i<0) then set i=0 endif call SetUnitAnimationByIndex(this.dummy, i ) endmethod method operator x takes nothing returns real
return GetUnitX(this.dummy) endmethod method operator y takes nothing returns real return GetUnitY(this.dummy) endmethod method operator z takes nothing returns real return GetUnitFlyHeight(this.dummy) endmethod method operator z= takes real value returns nothing
call SetUnitFlyHeight(this.dummy,value,0) endmethod method operator x= takes real value returns nothing
call SetUnitX(this.dummy,value) endmethod method operator y= takes real value returns nothing
call SetUnitY(this.dummy,value) endmethod method operator fxpath= takes string newpath returns nothing
if (this.fx!=null) then call DestroyEffect(this.fx) endif if (newpath=="") then set this.fx=null else set this.fx=AddSpecialEffectTarget(newpath,this.dummy,"origin") endif endmethod
method hiddenReset takes string newfxpath, real newfacing returns nothing local real x = GetUnitX(this.dummy) local real y = GetUnitY(this.dummy) local real z = this.z local real za = this.zangle local integer level = this.abilityLevel set .fxpath=null static if RECYCLE_DUMMY_UNITS and LIBRARY_xedummy then if(this.abil!=0) then call UnitRemoveAbility(this.dummy,this.abil) endif call recyclebin.create(this.dummy) set this.dummy=XE_NewDummyUnit(Player(15), x,y, newfacing*bj_RADTODEG) else call RemoveUnit(this.dummy) set this.dummy= CreateUnit(Player(15), XE_DUMMY_UNITID, x,y, newfacing*bj_RADTODEG) call UnitAddAbility(this.dummy,XE_HEIGHT_ENABLER) call UnitAddAbility(this.dummy,'Aloc') call UnitRemoveAbility(this.dummy,XE_HEIGHT_ENABLER) call SetUnitX(this.dummy,x) call SetUnitY(this.dummy,y) endif set .fxpath=newfxpath if(level != 0) then call UnitAddAbility(this.dummy, this.abil) call SetUnitAbilityLevel(this.dummy, this.abil, level) endif set this.z = z set zangle = za endmethod method destroy takes nothing returns nothing
if(this.abil!=0) then call UnitRemoveAbility(this.dummy,this.abil) endif if(this.fx!=null) then call DestroyEffect(this.fx) set this.fx=null endif call recyclebin.create(this.dummy) set this.dummy=null call this.deallocate() endmethod method hiddenDestroy takes nothing returns nothing
call ShowUnit(dummy,false) call destroy() endmethod endstruct endlibrary ))
» xemissle
((код jass
library xemissile requires xefx, xebasic
**************************************************************** * * xemissile 0.9 * ------------- * A xemissile object is a special effect that moves like a * WC3's attack or spell missile. * * Please use .terminate() instead of .destroy() this ensures * that it will be safe to destroy it (else you would have to * worry about destroying it during the animation loop/etc.) * * This struct is used similarly to xecollider. Instead of just * creating the xemissile (which works, but it would only be a * xefx that can move like a missile) you probably need to make * it do something special when it reaches its target... * For this reason, you need to make a new struct extending * xemissile that declares an onHit method, you may also declare * a loopControl method. * **************************************************************** ===========================================================================
So, this exists merely so you can declare your own event handler methods if interfaces make your brain blow out, please skip the next four lines. private interface eventHandler method onHit takes nothing returns nothing defaults nothing method loopControl takes nothing returns nothing defaults nothing endinterface =========================================================================== private struct missile extends eventHandler
private delegate xefx fx movement duration parameter.
private real time xy movement parameters. private real mx private real my private real mvx private real mvy private real mvxy = 1.0 z movement parameters. private real mz private real mvz private real maz private static location l = Location(0.0,0.0) target parameters. private real tx = 0.0 private real ty = 0.0 private real tz = 0.0 private unit tu = null public real zoffset = 0.0 private boolean update = true private boolean launched = false private boolean dead = false public method operator x takes nothing returns real return .mx endmethod public method operator y takes nothing returns real return .my endmethod public method operator z takes nothing returns real call MoveLocation(.l, .mx,.my) return mz-GetLocationZ(.l) endmethod public method operator x= takes real r returns nothing set .update=true set .mx=r endmethod public method operator y= takes real r returns nothing set .update=true set .my=r endmethod public method operator z= takes real r returns nothing set .update=true call MoveLocation(.l, .mx,.my) set .mz=r+GetLocationZ(.l) endmethod public method operator speed takes nothing returns real
return .mvxy/XE_ANIMATION_PERIOD endmethod public method operator speed= takes real newspeed returns nothing local real factor=newspeed*XE_ANIMATION_PERIOD/.mvxy if newspeed<=0.0 then debug call BJDebugMsg("xemissile speed error: speed must be a non-zero positive value.") return endif set .mvxy=newspeed*XE_ANIMATION_PERIOD if .launched then set .time=.time/factor set .mvx=.mvx*factor set .mvy=.mvy*factor set .mvz=.mvz*factor set .maz=.maz*factor*factor endif endmethod public method operator targetUnit takes nothing returns unit
return this.tu endmethod public method operator targetUnit= takes unit u returns nothing set .update=true set .tu=u set .tx=GetUnitX(u) set .ty=GetUnitY(u) call MoveLocation(.l, .tx,.ty) set .tz=GetUnitFlyHeight(u)+GetLocationZ(.l)+.zoffset endmethod public method setTargetPoint takes real x, real y, real z returns nothing set .update=true set .tu=null set .tx=x set .ty=y call MoveLocation(.l, .tx,.ty) set .tz=z+GetLocationZ(.l) endmethod -------- Missile launcher
public method launch takes real speed, real arc returns nothing
local real dx=.tx-.mx local real dy=.ty-.my local real d=SquareRoot(dx*dx+dy*dy) local real a=Atan2(dy, dx) local real dz=.tz-.mz set .mvxy=speed*XE_ANIMATION_PERIOD if speed<=0.0 then debug call BJDebugMsg("xemissile launch error: speed must be a non-zero positive value.") return elseif d>0.0 then set .time=d/speed else set .time=XE_ANIMATION_PERIOD endif set .mvz=( (d*arc)/(.time/4.0) + dz/.time )*XE_ANIMATION_PERIOD Do some mathemagics to get a proper arc. set .dead=.dead and not(.launched) In case this is called from the onHit method to bounce the missile.
if not .dead and not .launched then set .launched=true set .V[.N]=this set .N=.N+1 if(.N==1) then call TimerStart(.T, XE_ANIMATION_PERIOD, true, xemissile.timerLoopFunction ) endif endif endmethod -------- Constructors and destructors static method create takes real x, real y, real z, real a returns missile
local missile this=missile.allocate() set .mx=x set .my=y call MoveLocation(.l, x,y) set .mz=z+GetLocationZ(.l) set .fx = xefx.create(x,y,a)
set .fx.z = z return this endmethod private boolean silent=false
private method destroy takes nothing returns nothing if(this.silent) then call this.fx.hiddenDestroy() else call this.fx.destroy() endif call .deallocate() endmethod method terminate takes nothing returns nothing
set this.dead=true set this.fx.zangle=0.0 set this.fxpath="" endmethod declare hiddenDestroy so people don't call directly on the delegate xefx method hiddenDestroy takes nothing returns nothing set silent = true call terminate() endmethod -------- Main engine
private static timer T
private static integer N=0 private static xemissile array V private static code timerLoopFunction I use a code var so create can be above the timerloop function, more readable private static method timerLoop takes nothing returns nothing
local integer i=0 local integer c=0 local thistype this local real dx local real dy local real d local real a loop
exitwhen (i==.N ) set this=.V[i] adopt-a-instance
if .dead then set .launched=false set this.fx.zangle=0.0 call .destroy() else if .tu!=null and GetUnitTypeId(.tu)!=0 then set .update=true set .tx=GetUnitX(.tu) set .ty=GetUnitY(.tu) call MoveLocation(.l, .tx,.ty) set .tz=GetUnitFlyHeight(.tu)+GetLocationZ(.l)+.zoffset endif if .update then set .update=false set dx=.tx-.mx set dy=.ty-.my set d=SquareRoot(dx*dx+dy*dy) set a=Atan2(dy,dx) if d>0.0 then set .time=d/.mvxy*XE_ANIMATION_PERIOD else set .time=XE_ANIMATION_PERIOD endif set .mvx=Cos(a)*.mvxy set .mvy=Sin(a)*.mvxy set .fx.xyangle=a set .maz=2*((.tz-.mz)/.time/.time*XE_ANIMATION_PERIOD*XE_ANIMATION_PERIOD-(.mvz*XE_ANIMATION_PERIOD)/.time) endif set .mx=.mx+.mvx set .my=.my+.mvy set a=.maz/2.0 set .mvz=.mvz+a set .mz=.mz+.mvz set .mvz=.mvz+a set .fx.x=.mx
set .fx.y=.my call MoveLocation(.l, .mx,.my) set .fx.z=.mz-GetLocationZ(.l) set .fx.zangle=Atan2(.mvz, .mvxy) set .time=.time-XE_ANIMATION_PERIOD if .time<=0.0 then set .dead=true call this.onHit() if .dead then set .fxpath="" endif endif set .V[c]=this
set c=c+1 if( this.loopControl.exists and not this.dead ) then call this.loopControl() endif endif set i=i+1 endloop set .N=c if(c==0) then call PauseTimer(.T) endif endmethod static method onInit takes nothing returns nothing
set .timerLoopFunction = (function missile.timerLoop) set .T=CreateTimer() endmethod endstruct ===========================================================================
struct xemissile extends missile
public static method create takes real x,real y,real z, real tx,real ty,real tz returns xemissile local xemissile xm = xemissile.allocate(x,y,z, Atan2(ty-y,tx-x)) call xm.setTargetPoint(tx,ty,tz) return xm endmethod endstruct struct xehomingmissile extends xemissile
public static method create takes real x,real y,real z, unit target,real zoffset returns xehomingmissile local xehomingmissile xm = xehomingmissile.allocate(x,y,z, GetUnitX(target), GetUnitY(target), 0.0) set xm.zoffset=zoffset set xm.targetUnit=target return xm endmethod endstruct endlibrary )) Тонны документации и примеры можешь посмотреть в карте по линку выше. Отредактировано DualShock, 04.07.2012 в 01:35. |
04.07.2012, 01:04 | #2
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
prog
offline
Опыт:
32,865Активность: |
Это ты еще с водой и декорациями не сталкивался в этом контексте, наверно.
Да, проблемы с картой высот имеют место быть.
Как лечить сейчас не вспомню, давно было. Но для некоторых проблем, связанных с этим, я так решения и не нашел, приходилось их маскировать. |
04.07.2012, 01:04 | #3
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
vladfaust
offline
Опыт:
12,814Активность: |
|
04.07.2012, 01:14 | #4
+0/−1
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
Arti
offline
Опыт:
11,196Активность: |
inadequate_, что бы в нем нормально,не поверхностно разобратся надо где то минут 20-30(мне по крайней мере), врятли кто то будет ето делать... Выреж основные части, а лучше преепроверь всё сам. |
04.07.2012, 23:21 | #5
+1/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
vladfaust
offline
Опыт:
12,814Активность: |
Arti, я проверил. В прямом ландшафте даже в летающего юнита летит нормально, с векторами все в порядке. Глюк с варом, я хз. |
04.07.2012, 23:53 | #6
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
DualShock
offline
Опыт:
4,983Активность: |
Хотел чё нить помутить, но у мну ругается на это и не сохраняет. Что за callback? missing return |
05.07.2012, 00:20 | #7
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
vladfaust
offline
Опыт:
12,814Активность: |
DualShock, скачай последнюю версию cjass |
05.07.2012, 00:44 | #8
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
Hate
конь вакуумный
offline
Опыт:
43,117Активность: |
попробуй поставить тип движения плывущий
сам проверить не могу, тоже фигня с callback |
05.07.2012, 08:44 | #9
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
Master_chan
Полуночный командир
offline
Опыт:
15,660Активность: |
inadequate_:
Учишься изобретать велосипеды? Лучше бы продебажил сам. Пока думал что бы тебе гневного написать, решил проблему. Смени тип движения дамми на пеший и после создания дамми в структуре допиши
Черная магия не иначе. |
05.07.2012, 12:08 | #10
+1/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
vladfaust
offline
Опыт:
12,814Активность: |
Master_chan, гений, чо. Браво! Все заработало) Спасибо!!! |
05.07.2012, 13:00 | #11
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
ScorpioT1000
Работаем
offline
Опыт: отключен
|
inadequate_, я тебе в самом начале это сказал, до того как ты две темы создал |
05.07.2012, 13:19 | #12
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
vladfaust
offline
Опыт:
12,814Активность: |
ScorpioT1000, прости. Честно. Прости. Спасибо. |
05.07.2012, 13:46 | #13
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|