Natural movement via angle restraint

Started by XDumbnBassX, February 05, 2009, 04:37:22 PM

Previous topic - Next topic

XDumbnBassX

ive always loved playing with little bits of experimental code, unfortunatley i never do anything with this stuff other than watch the demos run for hours on end. heres some more stuff to checkout.

I wrote this code to simulate plant growth initially, then it turned into some kind of lightning bolt generator, then a more natural looking random movement simulator. now its multipurpose thanks to a few settings haha.

each of the following examples are the same code, just with different settings.

ball of lightning mouse follower
; PROJECT : vines
; AUTHOR  : jeff
; CREATED : 1/28/2009
; EDITED  : 2/5/2009
; ---------------------------------------------------------------------
Setfps 60
//mouse off

Surf1=New3DImage(GetScreenWidth(),GetScreenHeight())

Type bolt
   lastX#
   lastY#
lastAngle#
EndType

// settings /////////////
Global maxbolts = 100
Global maxAngleDiff = 55
Global fadeOutVal# = 0.93
Global maxMoveDist = 70
Global chaseMouse = 1
/////////////////////////

Dim bolts(maxbolts) as bolt
Global boltCount = 0

function newX(startX#, theAngle#, moveSpeed#)
Dim retAngle as float
retAngle# = startX# + (cos((theAngle#)) * moveSpeed#)
endfunction retAngle#

function newY(startY#, theAngle#, moveSpeed#)
Dim retAngle as float
retAngle# = startY# + (sin((theAngle#)) * moveSpeed#)
endfunction retAngle#

function addSeg(startX#, startY#, startAngle#)
bolts(boltCount).lastX# = startX#
bolts(boltCount).lastY# = startY#
bolts(boltCount).lastAngle# = startAngle#
boltCount = boltCount + 1
endfunction

function drawSeg(startX#, startY#, startAngle#)
dim retAngle as float
dim retX as float
dim retY as float
dim angDiff as float
dim moveLen as float
dim retObj as bolt

if chaseMouse = 1
moveLen# = RndRange(1, maxMoveDist)
retAngle# = GetAngle2D(startX#, startY#, mouseX(), mouseY())
retAngle# = retAngle# + RndRange(maxAngleDiff*-1, maxAngleDiff)
retX# = newX(startX#, retAngle#, moveLen#)
retY# = newY(startY#, retAngle#, moveLen#)
else
retAngle# = startAngle# + RndRange(maxAngleDiff*-1, maxAngleDiff)
if retAngle# < 0 then retAngle# = retAngle# + 360
if retAngle# > 360 then retAngle# = retAngle# - 360

moveLen# = RndRange(1, maxMoveDist)
retX# = newX(startX#, retAngle#, moveLen#)
retY# = newY(startY#, retAngle#, moveLen#)

if retX# > getscreenwidth() or retX# < 0
retAngle# = startAngle# + (angDiff# - 180)
if retAngle# < 0 then regAngle# = retAngle# + 360
if retAngle# > 360 then retAngle# = retAngle# - 360

retX# = newX(startX#, retAngle#, moveLen#)
retY# = newY(startY#, retAngle#, moveLen#)
endif

if retY# > getscreenwidth() or retY# < 0
retAngle# = startAngle# + (angDiff# - 180)
if retAngle# < 0 then regAngle# = retAngle# + 360
if retAngle# > 360 then retAngle# = retAngle# - 360

retX# = newX(startX#, retAngle#, moveLen#)
retY# = newY(startY#, retAngle#, moveLen#)
endif
endif

line startX#, startY#, retX#, retY#

retObj.lastX# = retX#
retObj.lastY# = retY#
retObj.lastAngle# = retAngle#
endfunction retObj

// add all bolts
for i = 1 to maxbolts
addSeg(RndRange(1,getscreenwidth()), RndRange(1,getscreenheight()), RndRange(0,360))
next

Do
cls 0
DrawAlphaImage Surf1,0,0,fadeOutVal#,0

For i = 0 to boltCount
dim retbolt as bolt
retbolt = drawSeg(bolts(i).lastX#, bolts(i).lastY#, bolts(i).lastAngle#)

bolts(i).lastX# = retbolt.lastX#
bolts(i).lastY# = retbolt.lastY#
bolts(i).lastAngle# = retbolt.lastAngle#
Next i

CopyRect 0,0,0,GetScreenWidth(),GetScreenHeight(),Surf1,0,0
sync
loop


Random snakey movements
; PROJECT : vines
; AUTHOR  : jeff
; CREATED : 1/28/2009
; EDITED  : 2/5/2009
; ---------------------------------------------------------------------
Setfps 60
//mouse off

Surf1=New3DImage(GetScreenWidth(),GetScreenHeight())

Type bolt
   lastX#
   lastY#
lastAngle#
EndType

// settings /////////////
Global maxbolts = 20
Global maxAngleDiff = 25
Global fadeOutVal# = 0.9
Global maxMoveDist = 20
Global chaseMouse = 0
/////////////////////////

Dim bolts(maxbolts) as bolt
Global boltCount = 0

function newX(startX#, theAngle#, moveSpeed#)
Dim retAngle as float
retAngle# = startX# + (cos((theAngle#)) * moveSpeed#)
endfunction retAngle#

function newY(startY#, theAngle#, moveSpeed#)
Dim retAngle as float
retAngle# = startY# + (sin((theAngle#)) * moveSpeed#)
endfunction retAngle#

function addSeg(startX#, startY#, startAngle#)
bolts(boltCount).lastX# = startX#
bolts(boltCount).lastY# = startY#
bolts(boltCount).lastAngle# = startAngle#
boltCount = boltCount + 1
endfunction

function drawSeg(startX#, startY#, startAngle#)
dim retAngle as float
dim retX as float
dim retY as float
dim angDiff as float
dim moveLen as float
dim retObj as bolt

if chaseMouse = 1
moveLen# = RndRange(1, maxMoveDist)
retAngle# = GetAngle2D(startX#, startY#, mouseX(), mouseY())
retAngle# = retAngle# + RndRange(maxAngleDiff*-1, maxAngleDiff)
retX# = newX(startX#, retAngle#, moveLen#)
retY# = newY(startY#, retAngle#, moveLen#)
else
retAngle# = startAngle# + RndRange(maxAngleDiff*-1, maxAngleDiff)
if retAngle# < 0 then retAngle# = retAngle# + 360
if retAngle# > 360 then retAngle# = retAngle# - 360

moveLen# = RndRange(1, maxMoveDist)
retX# = newX(startX#, retAngle#, moveLen#)
retY# = newY(startY#, retAngle#, moveLen#)

if retX# > getscreenwidth() or retX# < 0
retAngle# = startAngle# + (angDiff# - 180)
if retAngle# < 0 then regAngle# = retAngle# + 360
if retAngle# > 360 then retAngle# = retAngle# - 360

retX# = newX(startX#, retAngle#, moveLen#)
retY# = newY(startY#, retAngle#, moveLen#)
endif

if retY# > getscreenwidth() or retY# < 0
retAngle# = startAngle# + (angDiff# - 180)
if retAngle# < 0 then regAngle# = retAngle# + 360
if retAngle# > 360 then retAngle# = retAngle# - 360

retX# = newX(startX#, retAngle#, moveLen#)
retY# = newY(startY#, retAngle#, moveLen#)
endif
endif

line startX#, startY#, retX#, retY#

retObj.lastX# = retX#
retObj.lastY# = retY#
retObj.lastAngle# = retAngle#
endfunction retObj

// add all bolts
for i = 1 to maxbolts
addSeg(RndRange(1,getscreenwidth()), RndRange(1,getscreenheight()), RndRange(0,360))
next

Do
cls 0
DrawAlphaImage Surf1,0,0,fadeOutVal#,0

For i = 0 to boltCount
dim retbolt as bolt
retbolt = drawSeg(bolts(i).lastX#, bolts(i).lastY#, bolts(i).lastAngle#)

bolts(i).lastX# = retbolt.lastX#
bolts(i).lastY# = retbolt.lastY#
bolts(i).lastAngle# = retbolt.lastAngle#
Next i

CopyRect 0,0,0,GetScreenWidth(),GetScreenHeight(),Surf1,0,0
sync
loop


tons of tiny bugs
; PROJECT : vines
; AUTHOR  : jeff
; CREATED : 1/28/2009
; EDITED  : 2/5/2009
; ---------------------------------------------------------------------
Setfps 60
//mouse off

Surf1=New3DImage(GetScreenWidth(),GetScreenHeight())

Type bolt
   lastX#
   lastY#
lastAngle#
EndType

// settings /////////////
Global maxbolts = 500
Global maxAngleDiff = 45
Global fadeOutVal# = 0.7
Global maxMoveDist = 10
Global chaseMouse = 0
/////////////////////////

Dim bolts(maxbolts) as bolt
Global boltCount = 0

function newX(startX#, theAngle#, moveSpeed#)
Dim retAngle as float
retAngle# = startX# + (cos((theAngle#)) * moveSpeed#)
endfunction retAngle#

function newY(startY#, theAngle#, moveSpeed#)
Dim retAngle as float
retAngle# = startY# + (sin((theAngle#)) * moveSpeed#)
endfunction retAngle#

function addSeg(startX#, startY#, startAngle#)
bolts(boltCount).lastX# = startX#
bolts(boltCount).lastY# = startY#
bolts(boltCount).lastAngle# = startAngle#
boltCount = boltCount + 1
endfunction

function drawSeg(startX#, startY#, startAngle#)
dim retAngle as float
dim retX as float
dim retY as float
dim angDiff as float
dim moveLen as float
dim retObj as bolt

if chaseMouse = 1
moveLen# = RndRange(1, maxMoveDist)
retAngle# = GetAngle2D(startX#, startY#, mouseX(), mouseY())
retAngle# = retAngle# + RndRange(maxAngleDiff*-1, maxAngleDiff)
retX# = newX(startX#, retAngle#, moveLen#)
retY# = newY(startY#, retAngle#, moveLen#)
else
retAngle# = startAngle# + RndRange(maxAngleDiff*-1, maxAngleDiff)
if retAngle# < 0 then retAngle# = retAngle# + 360
if retAngle# > 360 then retAngle# = retAngle# - 360

moveLen# = RndRange(1, maxMoveDist)
retX# = newX(startX#, retAngle#, moveLen#)
retY# = newY(startY#, retAngle#, moveLen#)

if retX# > getscreenwidth() or retX# < 0
retAngle# = startAngle# + (angDiff# - 180)
if retAngle# < 0 then regAngle# = retAngle# + 360
if retAngle# > 360 then retAngle# = retAngle# - 360

retX# = newX(startX#, retAngle#, moveLen#)
retY# = newY(startY#, retAngle#, moveLen#)
endif

if retY# > getscreenwidth() or retY# < 0
retAngle# = startAngle# + (angDiff# - 180)
if retAngle# < 0 then regAngle# = retAngle# + 360
if retAngle# > 360 then retAngle# = retAngle# - 360

retX# = newX(startX#, retAngle#, moveLen#)
retY# = newY(startY#, retAngle#, moveLen#)
endif
endif

line startX#, startY#, retX#, retY#

retObj.lastX# = retX#
retObj.lastY# = retY#
retObj.lastAngle# = retAngle#
endfunction retObj

// add all bolts
for i = 1 to maxbolts
addSeg(RndRange(1,getscreenwidth()), RndRange(1,getscreenheight()), RndRange(0,360))
next

Do
cls 0
DrawAlphaImage Surf1,0,0,fadeOutVal#,0

For i = 0 to boltCount
dim retbolt as bolt
retbolt = drawSeg(bolts(i).lastX#, bolts(i).lastY#, bolts(i).lastAngle#)

bolts(i).lastX# = retbolt.lastX#
bolts(i).lastY# = retbolt.lastY#
bolts(i).lastAngle# = retbolt.lastAngle#
Next i

CopyRect 0,0,0,GetScreenWidth(),GetScreenHeight(),Surf1,0,0
sync
loop


spastic worms
; PROJECT : vines
; AUTHOR  : jeff
; CREATED : 1/28/2009
; EDITED  : 2/5/2009
; ---------------------------------------------------------------------
Setfps 60
//mouse off

Surf1=New3DImage(GetScreenWidth(),GetScreenHeight())

Type bolt
   lastX#
   lastY#
lastAngle#
EndType

// settings /////////////
Global maxbolts = 100
Global maxAngleDiff = 120
Global fadeOutVal# = 0.9
Global maxMoveDist = 10
Global chaseMouse = 0
/////////////////////////

Dim bolts(maxbolts) as bolt
Global boltCount = 0

function newX(startX#, theAngle#, moveSpeed#)
Dim retAngle as float
retAngle# = startX# + (cos((theAngle#)) * moveSpeed#)
endfunction retAngle#

function newY(startY#, theAngle#, moveSpeed#)
Dim retAngle as float
retAngle# = startY# + (sin((theAngle#)) * moveSpeed#)
endfunction retAngle#

function addSeg(startX#, startY#, startAngle#)
bolts(boltCount).lastX# = startX#
bolts(boltCount).lastY# = startY#
bolts(boltCount).lastAngle# = startAngle#
boltCount = boltCount + 1
endfunction

function drawSeg(startX#, startY#, startAngle#)
dim retAngle as float
dim retX as float
dim retY as float
dim angDiff as float
dim moveLen as float
dim retObj as bolt

if chaseMouse = 1
moveLen# = RndRange(1, maxMoveDist)
retAngle# = GetAngle2D(startX#, startY#, mouseX(), mouseY())
retAngle# = retAngle# + RndRange(maxAngleDiff*-1, maxAngleDiff)
retX# = newX(startX#, retAngle#, moveLen#)
retY# = newY(startY#, retAngle#, moveLen#)
else
retAngle# = startAngle# + RndRange(maxAngleDiff*-1, maxAngleDiff)
if retAngle# < 0 then retAngle# = retAngle# + 360
if retAngle# > 360 then retAngle# = retAngle# - 360

moveLen# = RndRange(1, maxMoveDist)
retX# = newX(startX#, retAngle#, moveLen#)
retY# = newY(startY#, retAngle#, moveLen#)

if retX# > getscreenwidth() or retX# < 0
retAngle# = startAngle# + (angDiff# - 180)
if retAngle# < 0 then regAngle# = retAngle# + 360
if retAngle# > 360 then retAngle# = retAngle# - 360

retX# = newX(startX#, retAngle#, moveLen#)
retY# = newY(startY#, retAngle#, moveLen#)
endif

if retY# > getscreenwidth() or retY# < 0
retAngle# = startAngle# + (angDiff# - 180)
if retAngle# < 0 then regAngle# = retAngle# + 360
if retAngle# > 360 then retAngle# = retAngle# - 360

retX# = newX(startX#, retAngle#, moveLen#)
retY# = newY(startY#, retAngle#, moveLen#)
endif
endif

line startX#, startY#, retX#, retY#

retObj.lastX# = retX#
retObj.lastY# = retY#
retObj.lastAngle# = retAngle#
endfunction retObj

// add all bolts
for i = 1 to maxbolts
addSeg(RndRange(1,getscreenwidth()), RndRange(1,getscreenheight()), RndRange(0,360))
next

Do
cls 0
DrawAlphaImage Surf1,0,0,fadeOutVal#,0

For i = 0 to boltCount
dim retbolt as bolt
retbolt = drawSeg(bolts(i).lastX#, bolts(i).lastY#, bolts(i).lastAngle#)

bolts(i).lastX# = retbolt.lastX#
bolts(i).lastY# = retbolt.lastY#
bolts(i).lastAngle# = retbolt.lastAngle#
Next i

CopyRect 0,0,0,GetScreenWidth(),GetScreenHeight(),Surf1,0,0
sync
loop


the key to all this stuff is the code that restricts each 'nodes' (bug, bolt, snake, w/e) movement to a certain amount of degrees in either direction, this gives the movement more of a natural look rather than things just blasting all over the place with no obvious direction.