News:

Building a 3D Ray Tracer  By stevmjon

Main Menu

A simple model of walking jointed legs

Started by ShadowCentaur, April 05, 2011, 09:47:49 PM

Previous topic - Next topic

ShadowCentaur

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.



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








If you ever need me, click your heels three times and press Ctrl + Alt + Del.

kevin

#1
 That's neat !



Related Articles/Source Codes

     * Limb Chain
     * Simple Rope demo



ShadowCentaur

#3
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.


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


Login required to view complete source code



If you ever need me, click your heels three times and press Ctrl + Alt + Del.


stevmjon

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
It's easy to start a program, but harder to finish it...

I think that means i am getting old and get side tracked too easy.

LemonWizard

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?