News:

Building a 3D Ray Tracer  By stevmjon

Main Menu

Limb Chain

Started by kevin, February 26, 2013, 03:37:11 PM

Previous topic - Next topic

kevin

 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.


PlayBASIC Code: [Select]
   // -------------------------------------------------------------------------
// 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

Login required to view complete source code



Related Articles

    * Simple Rope demo
    * A simple model of walking jointed legs


kevin

#1
  Here's a little example of a spinning egg / octopus looking structure.  

PlayBASIC Code: [Select]
   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






ATLUS