Limb Chain
This snippet renders a series of line fragments as one continuous chain of limbs. The most obvious usage for such thing would be animating the legs/arms/bones of a 2d character.
[pbcode]
// -------------------------------------------------------------------------
// KEYS
//
// UP ARROW = Move Back a joint
// Down ARROW = Move forward a joint
// LEFT ARROW = Turn current joint Left
// RIGHT ARROW = Turn Current Joint Right
//
// -------------------------------------------------------------------------
setfps 60
Type tLimb
Size#
Angle#
EndType
Dim Joints(0) as tLimb
// Init a Bunch of Joints
// -----------------------------------
for lp =1 to 10
AddJoint(rndrange(20,100),rnd(30))
next
Angle#=0
Joint=1
// -------------------------------------------------------------------------
// Main Loop Of program
// -------------------------------------------------------------------------
Do
Cls
// Draw the set of limbs
DrawJoints(400,300,Angle#,Joint)
// spin the parent node
Angle#=wrapangle(Angle#,0.5)
// Check if the UP key was pressed
if upkey()
; change joints
Joint=cliprange(Joint-1,1,GetArrayElements(Joints()))
FlushKeys
endif
// Check if the DOWN key was pressed
if downkey()
Joint=cliprange(Joint+1,1,GetArrayElements(Joints()))
FlushKeys
endif
// Check if the LEFT key was pressed
if leftkey()
; turn anto clockwise
TurnJoint(Joint,-5)
endif
// Check if the LEFT key was pressed
if rightkey()
; turn clockwise
TurnJoint(Joint,5)
endif
print "Current Joint #"+Digits$(Joint,2)
Sync
loop
end
// -------------------------------------------------------------------------
// TURN JOINT
// -------------------------------------------------------------------------
Function TurnJoint(INdex,Direction#)
Joints(Index).Angle#=Joints(Index).Angle#+Direction#
EndFunction
// -------------------------------------------------------------------------
// ADD JOINT to chain
// -------------------------------------------------------------------------
Function AddJoint(Size#,Angle#)
Index=GetFreeCell(Joints())
Joints(Index).size=size#
Joints(Index).Angle=angle#
EndFUnction
// -------------------------------------------------------------------------
// DRAW CHAIN OF JOINTS
// -------------------------------------------------------------------------
// This function assumes limbs are in a sequential order starting from
// index 1 to bottom of array
Function DrawJoints(x#,y#,angle#,CurrentJoint)
For Index=1 to Getarrayelements(Joints())
if Joints(Index)
; toggle the colours so we can see the joints a bit easier
if INdex and 1
Colour=$ffffff
else
Colour=$80ff80
endif
; get the size of the ilmb
size#=Joints(Index).size
; wrap it's angle from the existing angle
Angle#=wrapangle(Angle#,Joints(Index).Angle#)
; plots it's polar cords
nx#=CosNewValue(x#,angle#,Size#)
ny#=SinNewValue(y#,angle#,Size#)
; draw the line to prepresent it on screen
linec x#,y#,nx#,ny#,Colour
; check if this is the current point we're moving
; if so, remember it's screen position and draw a circle later to show
if Index=CurrentJoint
CurrentJointX#=x#
CurrentJointY#=y#
CurrentJointFound=true
endif
x#=nx#
y#=ny#
endif
next
; draw the point that currently in focus
if CurrentJointFound=true
circlec CurrentJointX#,CurrentJointY#,5,true,$ff0000
endif
EndFUnction
[/pbcode]
Related Articles
* Simple Rope demo (http://www.underwaredesign.com/forums/index.php?topic=3098.0)
* A simple model of walking jointed legs (http://www.underwaredesign.com/forums/index.php?topic=3649.0)
Here's a little example of a spinning egg / octopus looking structure.
[pbcode]
Dim Angle#(10)
xpos#=GetSurfaceWidth()*0.5
ypos#=GetSurfaceHeight()*0.5
Do
cls
CurrentTime=Timer()
mx#=mousex()
my#=mousey()
Xpos#=curveValue(mx#,Xpos#,50)
Ypos#=curveValue(my#,Ypos#,50)
if CurrentTime>RefreshTIme
ObjectAngle#=wrapangle(ObjectAngle#,rndrange(-90,90))
RefreshTime=CurrentTime+rndrange(1000,2500)
endif
Egg_Thing(Xpos#,Ypos#,ObjectAngle#)
Sync
loop
Function Egg_Thing(X#,Y#,ObjectAngle#)
Radius = 90
RingStepRadius=Radius/3
Circlec x#,y#,Radius,true, $AA8822
Radius2=RAdius
MaxRings=10
Lockbuffer
For ring=1 to MaxRings
Angle#=Angle#(ring)
Angle#=CurveAngle(ObjectANgle#,Angle#,25*ring)
Angle#(ring)=Angle#
ThisRGB=$775511
Scalar#=(MaxRings-ring)/float(MaxRings)
ThisRGB=RgbFade(ThisRgb,100.0*Scalar#)
AngleStep#=360.0/16
for limbs=1 to 16
Newx#=x#+cos(angle#)*RAdius
Newy#=y#+sin(angle#)*RAdius
circlec NewX#,NewY#,Radius2/2,true,ThisRGB ; Radius/4
angle#+=AngleStep#
next
RAdius+=RingStepRadius
RAdius2-=(RAdius2/4)
next
unLockbuffer
EndFunction
[/pbcode]
Nice code!