UnderwareDESIGN

PlayBASIC => Game Design => Topic started by: ShadowCentaur on April 05, 2011, 09:47:49 PM

Title: A simple model of walking jointed legs
Post by: ShadowCentaur on April 05, 2011, 09:47:49 PM
I'm coding movement for a simple stick figure character. Rather than manually create images for his movement, I'm coding it in mathematically. Here is a snippet demonstrating my current model for a pair of legs jointed at the knees. Does anyone have ideas to improve upon this model? Specifically, I'd like the speed of oscillation and amplitude of oscillation to be affected by player speed, but I'm still tossing around how to make the parameters vary with speed. So (ideally) when the player is moving slowly, the legs move slowly and to small angles, but when moving quickly the legs move faster and go higher into the air when stepping.



[pbcode]



thetamax=-60;theta is angle between thigh and horizontal
thetamin=-120
thetaA=(thetamax-thetamin)/2;distance/2=amplitude of oscillation
theta0=(thetamax+thetamin)/2;average value of oscillation (thetaA*sin(x)+theta0)
thighl=100;length of thigh


phimax=180;phi is angle between thighs and shins
phimin=140
phiA=(phimax-phimin)/2
phi0=(phimax+phimin)/2

print phi0
print phiA
shinl=100;length of shins


direction=1;direction of +1 if moving right, -1 if moving left

do
   cls
       print "hit space to reverse direction"
   ;hit space to reverse direction
   if(spacekey()=1)
      text x0,y0-20,"walking left"
      direction=-1
   else
      text x0,y0-20,"walking right"   
      direction=1
   endif
         

   
   x0=mousex()
   y0=mousey()
   
   time=timer()/6
   
   ;right knee
   theta1=theta0+thetaA*sin(time+90)
   x1=x0+thighl*cos(theta1)
   y1=y0-thighl*sin(theta1)
   
   ;right foot
   
   phi3=phiA*sin(time+80)+phi0+phiA-direction*phiA
   psi=phi3-(180-theta1)
   x3=x1+shinl*cos(psi)
   y3=y1-shinl*sin(psi)
   
   ;left knee
   theta2=theta0+thetaA*sin(time-90)
   x2=x0+thighl*cos(theta2)
   y2=y0-thighl*sin(theta2)
   
   ;left foot
   phi4=phiA*sin(time-80)+phi0+phiA-direction*phiA
   psi=phi4-(180-theta2)
   x4=x2+shinl*cos(psi)
   y4=y2-shinl*sin(psi)
   
   
   ;draw lines for bones
   line x0,y0,x1,y1;right thigh
   line x0,y0,x2,y2;left thigh

   line x1,y1,x3,y3;right calf
   line x2,y2,x4,y4;left calf

   text x3,y3,"R"
   text x4,y4,"L"
   
   

   sync
loop





[/pbcode]

Title: Re: A simple model of walking jointed legs
Post by: kevin on April 05, 2011, 11:16:03 PM
 That's neat !



Related Articles/Source Codes

     * Limb Chain (http://www.underwaredesign.com/forums/index.php?topic=4011.0)
     * Simple Rope demo (http://www.underwaredesign.com/forums/index.php?topic=3098.0)

Title: Re: A simple model of walking jointed legs
Post by: monkeybot on April 06, 2011, 03:12:20 PM
nice
Title: Re: A simple model of walking jointed legs
Post by: ShadowCentaur on April 13, 2011, 10:47:50 PM
So I've improved my model a little bit. I went with an exponential taper for the angles with speed. I also added arms with elbows. Frequency varies linearly with stride length and velocity. Tell me what you think. Now that this has mostly gotten done i'm going to work on implementing it in a little game somehow.


[pbcode]

thetamax=-60;theta is angle between thigh and horizontal
thetamin=-120
thetaA=(thetamax-thetamin)/2;distance/2=amplitude of oscillation
theta0=(thetamax+thetamin)/2;average value of oscillation (thetaA*sin(x)+theta0)
thighl=100;length of thigh

phimax=180;phi is angle between thighs and shins
phimin=140
phiA=(phimax-phimin)/2
phi0=(phimax+phimin)/2
shinl=100;length of shins

epsilonmax=-60;angle between arm and horizontal
epsilonmin=-120
epsilonA=(epsilonmax-epsilonmin)/2
epsilon0=(epsilonmax+epsilonmin)/2
arml=70;length of bicep part of arm

mumax=280;angle between arms and forearms
mumin=300
muA=(mumax-mumin)/2
mu0=(mumax+mumin)/2
forearml=70;length of forearms


direction=1;direction of +1 if moving right, -1 if moving left
speed#=0.5



x0=10
do
   
   ;leg angle increases with an 1-e^x pattern, bounded by 80 degrees
   thetaA=80*(1-exp(-speed#/3.0))
   
   ;arm angle increase exponentially, bounded by 90
   epsilonA=90*(1-exp(-speed#/3.0))
   
   mu0=180+110*(1-exp(-speed#/1.5))
   
   ;stride length =2*leglength*sin(leg angle)
   lambda#=2*(thighl+shinl)*sin(thetaA)
   
   
   cls
    print "speed = "+str$(speed#)
   print "stride length= " +str$(lambda#)
   print "radian frequency= " +str$(omega#)
   Print "right click to speed up, left click slow down"
 
         ;put a line of dots for ground reference
  for x=1 to getscreenwidth()
     if mod(x,30)=0
        dot x,getscreenheight()*6/7
     endif
  next x
        
 
     
     ;speed or slow player with mouse
     if RightMouseButton()=1
        speed#=speed#+0.001
     endif
     if LeftmouseButton()=1
        speed#=speed#-0.001
     endif
   
   ;player position (x and y location of hips)
  x0#=x0#+direction*speed#
   y0#=getscreenheight()/2
   
   ;reverse direction when hit walls
   if x0#<0 or x0#>getscreenheight()
      direction=-1*direction
   endif
   
   
   ;time=timer()/6
   time=time+1
   
   
   ;to ensure no large phase jumps when speed changes
   ;set time to zero every once in a while
   if omega#*time>360 then time=0
   
   ;time=wrapvalue(omega#*time,0,360)/omega#
      
   
   ;radian frequency is proportional to speed/stride, with an emperical
   ;"looks about right" constant of 130
   omega#=130*speed#/lambda#
   
   
   ;right knee
   theta1=theta0+thetaA*sin(omega#*time+90)
   x1#=x0#+thighl*cos(theta1)
   y1#=y0#-thighl*sin(theta1)
   
   ;right foot
   
   phi3=phiA*sin(omega#*time+80)+direction*phi0;+phiA-direction*phiA
   psi=phi3-(180-theta1)
   x3#=x1#+shinl*cos(psi)
   y3#=y1#-shinl*sin(psi)
   
   ;left knee
   theta2=theta0+thetaA*sin(omega#*time-90)
   x2#=x0#+thighl*cos(theta2)
   y2#=y0#-thighl*sin(theta2)
   
   ;left foot
   phi4=phiA*sin(omega#*time-80)+direction*phi0;+phiA-direction*phiA
   psi=phi4-(180-theta2)
   x4#=x2#+shinl*cos(psi)
   y4#=y2#-shinl*sin(psi)
   
   ;shoulder
   x5#=x0#
   y5#=y0#-100
   
   ;head
   x6#=x0#+20*direction
   y6#=y5#-50
   
   ;right elbow
   epsilon7=epsilon0+epsilonA*sin(omega#*time+90)
   x7#=x5#+arml*cos(epsilon7)
   y7#=y5#-arml*sin(epsilon7)
   
   ;right hand
   mu9=muA*sin(omega#*time+80)+direction*mu0;+muA-direction*muA
   psi=mu9-(180-epsilon7)
   x9#=x7#+forearml*cos(psi)
   y9#=y7#-forearml*sin(psi)
   
   ;left elbow
   epsilon8=epsilon0+epsilonA*sin(omega#*time-90)
   x8#=x5#+arml*cos(epsilon8)
   y8#=y5#-arml*sin(epsilon8)
   
   ;left hand
   mu10=muA*sin(omega#*time-80)+direction*mu0;+muA-direction*muA
   psi=mu10-(180-epsilon8)
   x10#=x8#+forearml*cos(psi)
   y10#=y8#-forearml*sin(psi)
   
   
   ;draw lines for bones
   line x0#,y0#,x1#,y1#;right thigh
   line x0#,y0#,x2#,y2#;left thigh

   line x1#,y1#,x3#,y3#;right calf
   line x2#,y2#,x4#,y4#;left calf

  line x0#,y0#,x5#,y5#;spine
 
  line x5#,y5#,x7#,y7#;right arm
  line x5#,y5#,x8#,y8#;left arm
 
  line x7#,y7#,x9#,y9#;right forearm
  line x8#,y8#,x10#,y10#;left forearm
 
  circle x6#,y6#,30,0;head

   text x3#,y3#,"R"
   text x4#,y4#,"L"
   
   line x0#+lambda#/2,y0#,x0#-lambda#/2,y0#

   sync
loop





[/pbcode]


Title: Re: A simple model of walking jointed legs
Post by: monkeybot on April 14, 2011, 01:00:08 PM
thats cool.
Title: Re: A simple model of walking jointed legs
Post by: stevmjon on April 15, 2011, 09:37:12 PM
this is pretty good. quite smooth.

can you add a 'bobbing up & down' of the head & torso. this would really top it off.

well done.

  stevmjon
Title: Re: A simple model of walking jointed legs
Post by: LemonWizard on June 17, 2011, 08:27:06 PM
this is interesting but when is anyone going to actually take four to six months to make an actual game in playbasic, I mean, a really big game with alot of levels and good gameplay. Something similiar to maybe say... mario, or mario world, maybe even like...I dunno..

zelda?