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]
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)
nice
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]
thats cool.
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
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?