Darthfett
Aerospace/Cybersecurity Software Engineer
- Reaction score
- 615
I played Warlocks about 2 days ago, and I loved the sliding system it used. I've made many sliding abilities in the past (though I haven't really used many of them), and I always liked the idea of just dumping a system into your map, and it works fine right away.
However, this wasn't possible until I came back to mapping and learned about vJass. Everything used to come with implementation instructions, and required you to go through and change all kinds of stuff. I started with vJASS about 2 days ago, and I don't think I'm going to go back now.
I'm working on a system that lets you have universal sliding. Right now, I've only made the basics for the code, but I'm working on making many functions for it, starting with functions that slide a unit, and arrow key movement/sliding.
It works by attaching structs to units, and then having a timer that is always on (unless no units are sliding), moving units towards the velocity and acceleration that is attached to them.
I've gotten it working so that you can simply set units' velocity and acceleration through a few functions, and they will start moving, with just one line of custom script. For Example, if you wanted to make a unit acceleration towards an angle:
I made it so that units simply bounce off of the map bounds, and took a video of it. Take a look:
http://www.youtube.com/watch?v=OFDoLpzfxEI
The unit is stopped by calling StopUnit(whichUnit), so there isn't much use out of it yet, but soon I plan on adding functions like sliding to a unit, sliding to a point, sliding for a distance, sliding for a specific time, etc. This is where the use in the system will be discovered.
Obviously with so much customizability, there will be lag if it is used on many units at once, so it will probably be a system used for abilities, or smaller maps with fewer units.
Now that I've finished talking about it, you can see the coding behind it. (It's long, I know)
As you can see, the attaching is done through the gamecache/local handle vars. I will change this to custom value soon.
Arrow key movement and friction are finished!
Please post comments!
However, this wasn't possible until I came back to mapping and learned about vJass. Everything used to come with implementation instructions, and required you to go through and change all kinds of stuff. I started with vJASS about 2 days ago, and I don't think I'm going to go back now.
I'm working on a system that lets you have universal sliding. Right now, I've only made the basics for the code, but I'm working on making many functions for it, starting with functions that slide a unit, and arrow key movement/sliding.
It works by attaching structs to units, and then having a timer that is always on (unless no units are sliding), moving units towards the velocity and acceleration that is attached to them.
I've gotten it working so that you can simply set units' velocity and acceleration through a few functions, and they will start moving, with just one line of custom script. For Example, if you wanted to make a unit acceleration towards an angle:
Code:
Custom script: call IncUnitAccel(udg_u,60,1)
I made it so that units simply bounce off of the map bounds, and took a video of it. Take a look:
http://www.youtube.com/watch?v=OFDoLpzfxEI
The unit is stopped by calling StopUnit(whichUnit), so there isn't much use out of it yet, but soon I plan on adding functions like sliding to a unit, sliding to a point, sliding for a distance, sliding for a specific time, etc. This is where the use in the system will be discovered.
Obviously with so much customizability, there will be lag if it is used on many units at once, so it will probably be a system used for abilities, or smaller maps with fewer units.
Now that I've finished talking about it, you can see the coding behind it. (It's long, I know)
JASS:
library Cache
globals
gamecache cache = InitGameCache("cache")
endglobals
function LocalVars takes nothing returns gamecache
return cache
endfunction
function H2I takes handle h returns integer
return h
return 0
endfunction
function SetHandleInt takes handle h, string key, integer i returns nothing
call StoreInteger(LocalVars(),I2S(H2I(h)),key,i)
endfunction
function GetHandleInt takes handle h, string key returns integer
return GetStoredInteger(LocalVars(),I2S(H2I(h)),key)
endfunction
endlibrary
library mapdata requires Cache
globals
real minx
real maxx
real miny
real maxy
endglobals
function IsXInMap takes real x returns boolean
return (x > minx and x < maxx)
endfunction
function IsYInMap takes real y returns boolean
return (y > miny and y < maxy)
endfunction
function IsLocInMap takes location l returns boolean
return ((GetLocationX(l) > minx and GetLocationX(l) < maxx) and (GetLocationY(l) > miny and GetLocationY(l) < maxy))
endfunction
endlibrary
library SlidingMovement requires mapdata
globals
group sliders = CreateGroup()
timer autoslide = CreateTimer()
boolean running = false
endglobals
struct movedata
real vel_x = 0
real vel_y = 0
real accel_x = 0
real accel_y = 0
real frict = 1.5
endstruct
function Sign takes real i returns real
if i >= 0 then
return 1
endif
return -1.
endfunction
function Abs takes real a returns real
if (a >= 0) then
return a
else
return -a
endif
endfunction
private function Automove takes nothing returns nothing
local movedata m
local real cur_x = 0
local real cur_y = 0
local unit fog
local group g = CreateGroup()
call GroupAddGroup(sliders,g)
if CountUnitsInGroup(sliders) == 0 then
call PauseTimer(autoslide)
set running = false
endif
loop
set fog = FirstOfGroup(g)
exitwhen fog == null
call GroupRemoveUnit(g,fog)
set m = GetHandleInt(fog,"movedata")
if not ((m.vel_x == 0 and m.accel_x == 0) and (m.vel_y == 0 and m.accel_y == 0)) then
if IsXInMap(GetUnitX(fog) + m.vel_x) then
call SetUnitX(fog,(GetUnitX(fog) + m.vel_x))
else
set m.vel_x = 0 - m.vel_x
endif
if IsYInMap(GetUnitY(fog) + m.vel_y) then
call SetUnitY(fog,(GetUnitY(fog) + m.vel_y))
else
set m.vel_y = 0 - m.vel_y
endif
if (m.frict <= Abs(m.vel_x + m.accel_x)) or (Abs(m.accel_x) != 0 and m.frict < Abs(m.accel_x)) then
set m.vel_x = m.vel_x + m.accel_x - (m.frict * Sign(m.vel_x))
else
set m.vel_x = 0
endif
if (m.frict <= Abs(m.vel_y + m.accel_y)) or (Abs(m.accel_y) != 0 and m.frict < Abs(m.accel_y)) then
set m.vel_y = m.vel_y + m.accel_y - (m.frict * Sign(m.vel_y))
else
set m.vel_y = 0
endif
else
call movedata.destroy(m)
call FlushStoredMission(LocalVars(),I2S(H2I(fog)))
call GroupRemoveUnit(sliders,fog)
endif
endloop
call DestroyGroup(g)
set g = null
endfunction
function MakeUnitSlider takes unit whichUnit returns movedata
local movedata m = GetHandleInt(whichUnit,"movedata")
if m == 0 then
set m = movedata.create()
call SetHandleInt(whichUnit,"movedata",m)
endif
call GroupAddUnit(sliders,whichUnit)
if running == false then
call TimerStart(autoslide,0.04,true,function Automove)
set running = true
endif
return m
endfunction
function StopUnit takes unit whichUnit returns nothing
local movedata m = GetHandleInt(whichUnit,"movedata")
if m != 0 then
call movedata.destroy(m)
call FlushStoredMission(LocalVars(),I2S(H2I(whichUnit)))
call GroupRemoveUnit(sliders,whichUnit)
if CountUnitsInGroup(sliders) == 0 then
call PauseTimer(autoslide)
set running = false
endif
endif
endfunction
function IncUnitVelX takes unit whichUnit, real vel returns movedata
local movedata m = MakeUnitSlider(whichUnit)
set m.vel_x = m.vel_x + vel
return m
endfunction
function IncUnitVelY takes unit whichUnit, real vel returns movedata
local movedata m = MakeUnitSlider(whichUnit)
set m.vel_y = m.vel_y + vel
return m
endfunction
function IncUnitVel takes unit whichUnit, real vel, real ang returns movedata
local movedata m = MakeUnitSlider(whichUnit)
set m.vel_x = m.vel_x + (vel * Cos(ang * bj_DEGTORAD))
set m.vel_y = m.vel_y + (vel * Sin(ang * bj_DEGTORAD))
return m
endfunction
function SetUnitVel takes unit whichUnit, real vel, real ang returns movedata
local movedata m = MakeUnitSlider(whichUnit)
set m.vel_x = (vel * Cos(ang * bj_DEGTORAD))
set m.vel_y = (vel * Sin(ang * bj_DEGTORAD))
return m
endfunction
function IncUnitAccelX takes unit whichUnit, real accel returns movedata
local movedata m = MakeUnitSlider(whichUnit)
set m.accel_x = m.accel_x + accel
return m
endfunction
function IncUnitAccelY takes unit whichUnit, real accel returns movedata
local movedata m = MakeUnitSlider(whichUnit)
set m.accel_y = m.accel_y + accel
return m
endfunction
function IncUnitAccel takes unit whichUnit, real accel, real ang returns movedata
local movedata m = MakeUnitSlider(whichUnit)
set m.accel_x = m.accel_x + (accel * Cos(ang * bj_DEGTORAD))
set m.accel_y = m.accel_y + (accel * Sin(ang * bj_DEGTORAD))
return m
endfunction
function SetUnitAccel takes unit whichUnit, real accel, real ang returns movedata
local movedata m = MakeUnitSlider(whichUnit)
set m.accel_x = (accel * Cos(ang * bj_DEGTORAD))
set m.accel_y = (accel * Sin(ang * bj_DEGTORAD))
return m
endfunction
endlibrary
As you can see, the attaching is done through the gamecache/local handle vars. I will change this to custom value soon.
Arrow key movement and friction are finished!
Please post comments!