UnderwareDESIGN

PlayBASIC => Resources => Source Codes => Topic started by: kevin on February 26, 2013, 03:37:11 PM

Title: Limb Chain
Post by: kevin on February 26, 2013, 03:37:11 PM
 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)

Title: Re: Limb Chain
Post by: kevin on March 23, 2013, 01:09:52 PM
  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]


Title: Re: Limb Chain
Post by: ATLUS on March 29, 2015, 10:00:27 AM
Nice code!