Posted: 30th Jan 2014 22:06
Hey guys,

I just created a small piece of code simulating a character walking animation from First Person perspective for this thread and thought I might just as well post it here.
It's pretty simple, but the effect surely adds quite a bit of immersion to any first person game.

+ Code Snippet
Rem Project: Dark Basic Pro Project
Rem Created: Thursday, January 30, 2014
rem Author:  Shellfish Games
Rem ***** Main Source File *****


set display mode 1280,800,32,1
sync on : sync rate 60 : sync


hide mouse


make matrix 1, 100,100, 40,40
position matrix 1, -50, -2, -50
for i = 1 to 200
    make object cube i, 1
    position object i, rnd(50) - rnd(50), rnd(10) - rnd(10), rnd(50) - rnd(50)
next

position camera 0, 0,0,0
point camera 0, 0,0,1

xangle# = 0
yangle# = 0

xp# = 0
yp# = 0
zp# = 0
angp# = 0.0
angp_target# = 0.0
xoff# = 0
yoff# = 0.4
zoff# = 0

do
    
    rem Look
    inc xangle#, mousemovey()*0.2
    inc yangle#, mousemovex()*0.2
    if xangle# > 90.0 then xangle# = 90.0 else if xangle# < -90.0 then xangle# = -90.0 `<- locking the angle
    xrotate camera 0, xangle#
    yrotate camera 0, yangle#
    
    rem Move
    fw = keystate(17) - keystate(31)
    rl = keystate(32) - keystate(30)
    if fw or rl or angp# < angp_target#
        rem Actual Camera position (without walking animation)
        inc xp#, 0.1*(fw*sin(yangle#) + rl*sin(yangle#+90))
        inc zp#, 0.1*(fw*cos(yangle#) + rl*cos(yangle#+90))
        rem Walking Animation
        inc angp#, 4.0 `<- animation speed
        rem Camera Offset (added to actual camera position to achieve walking animation)
        xoff# = 0.6*sin(yangle#+90)*sin(angp#) 
        zoff# = 0.6*cos(yangle#+90)*sin(angp#)
        yoff# = 0.3*sin(2*angp#+90)
        if fw or rl
            rem Active Movement -> Keep Walking Animation Going
            angp_target# = 180*(int(angp#) / 180) + 180 `next 
        else
            rem No active Movement -> just finish walking animation
            if angp# > angp_target# then angp# = angp_target# 
        endif
    endif
    position camera 0, xp#+xoff#,yp#+yoff#,zp#+zoff#
    
    
    rem Info
    set cursor 0,0
    print "FPS: ", screen fps()
    print 
    print "Press WASD to Move"
    print "Move Mouse to Look Around"

    sync
loop


Use or alter it however you like.

Cheers.
Posted: 30th Jan 2014 22:44
Smart way to simulate the walking . I like it !!
Posted: 31st Jan 2014 10:51
That's pretty neat. I did a little ad-hoc modification to add rolling into turns:

+ Code Snippet
Rem Project: Dark Basic Pro Project
Rem Created: Thursday, January 30, 2014
rem Author:  Shellfish Games
Rem ***** Main Source File *****


set display mode desktop width(), desktop height(),32,1
sync on : sync rate 60 : sync


hide mouse


make matrix 1, 100,100, 40,40
position matrix 1, -50, -2, -50
for i = 1 to 200
    make object cube i, 1
    position object i, rnd(50) - rnd(50), rnd(10) - rnd(10), rnd(50) - rnd(50)
next

position camera 0, 0,0,0
point camera 0, 0,0,1

xangle# = 0
yangle# = 0

fw as float
rl as float

xp# = 0
yp# = 0
zp# = 0
angp# = 0.0
angp_target# = 0.0
xoff# = 0
yoff# = 0.4
zoff# = 0

do
    
    rem Look
    oyangle# = yangle#
    inc xangle#, mousemovey()*0.2
    inc yangle#, mousemovex()*0.2
    if xangle# > 90.0 then xangle# = 90.0 else if xangle# < -90.0 then xangle# = -90.0 `<- locking the angle
    xrotate camera 0, xangle#
    yrotate camera 0, yangle#
    zrotate camera 0, 0		// undo roll effect
    
    rem Move
    fw = curvevalue(keystate(17) - keystate(31), fw, 8)
    rl = curvevalue(keystate(32) - keystate(30), rl, 8)
    
    // ensure player can come to a stop
    if fw > -0.01 and fw < 0.01 then fw = 0
    if rl > -0.01 and rl < 0.01 then rl = 0
    
    if fw or rl or angp# < angp_target#
        rem Actual Camera position (without walking animation)
        inc xp#, 0.1*(fw*sin(yangle#) + rl*sin(yangle#+90))
        inc zp#, 0.1*(fw*cos(yangle#) + rl*cos(yangle#+90))
        rem Walking Animation
        inc angp#, animspeed# `4.0 `<- animation speed
        rem Camera Offset (added to actual camera position to achieve walking animation)
        // (values toned down a little)
		xoff# = 0.3*sin(yangle#+90)*sin(angp#) 
        zoff# = 0.3*cos(yangle#+90)*sin(angp#)
        yoff# = 0.15*sin(2*angp#+90)
        // threshold speed for deciding if still moving or not.
        if fw < -0.2 or fw > 0.2 or rl < -0.2 or rl > 0.2
            rem Active Movement -> Keep Walking Animation Going
            angp_target# = 180*(int(angp#) / 180) + 180 `next 
            animspeed# = 4.0
        else
            rem No active Movement -> just finish walking animation
            if angp# > angp_target# then angp# = angp_target# 
            animspeed# = animspeed# + 0.25	// speed up a little as finishing
        endif
    endif
    position camera 0, xp#+xoff#,yp#+yoff#,zp#+zoff#
    
    // calculate a point ahead to focus on
    xviewtarg# = xp# + (10.0*sin(yangle#) + 0.01*rl*sin(yangle#+90))
    zviewtarg# = zp# + (10.0*cos(yangle#) + 0.01*rl*cos(yangle#+90))
    yviewtarg# = yp# + yoff#*0.25
    
    // focus directly on it first to read off values
    point camera 0, xviewtarg#, yviewtarg#, zviewtarg#
    yangtarg# = camera angle y(0)
    
    // interp a little between unfocused and focused so player mostly keeps control
    xrotate camera 0, xangle#
    yrotate camera 0, curveangle(yangtarg#, yangle#, 4)
    
    // roll camera slightly with strafing/turning
    // turning roll: +ve tilts into turn, -ve away
    roll# = curvevalue(rl*0.6 + (yangle#-oyangle#)*0.3, roll#, 3)
    roll camera right 0, roll#
    
    
    rem Info
    set cursor 0,0
    print "FPS: ", screen fps()
    print 
    print "Press WASD to Move"
    print "Move Mouse to Look Around"
    
    // magic anti-nausea reticule
    dot screen width()/2, screen height()/2, 0xffffffff
    dot screen width()/2-3, screen height()/2, 0xff808080
    dot screen width()/2+3, screen height()/2, 0xff808080
    dot screen width()/2, screen height()/2-3, 0xff808080
    dot screen width()/2, screen height()/2+3, 0xff808080

    sync
loop


bit queasy-making tho <_>
Posted: 31st Jan 2014 12:23
Nice, and now you can run as well.

+ Code Snippet
Rem Project: Dark Basic Pro Project
Rem Created: Thursday, January 30, 2014
rem Author:  Shellfish Games
Rem ***** Main Source File *****


set display mode desktop width(), desktop height(),32,1
sync on : sync rate 60 : sync


hide mouse


make matrix 1, 100,100, 40,40
position matrix 1, -50, -2.4, -50
for i = 1 to 200
    make object cube i, 1
    position object i, rnd(50) - rnd(50), rnd(10) - rnd(10), rnd(50) - rnd(50)
next

position camera 0, 0,0,0
point camera 0, 0,0,1

xangle# = 0
yangle# = 0

fw as float
rl as float

xp# = 0
yp# = 0
zp# = 0
angp# = 0.0
angp_target# = 0.0
xoff# = 0
yoff# = 0.4
zoff# = 0

do
    
    rem Look
    oyangle# = yangle#
    inc xangle#, mousemovey()*0.2
    inc yangle#, mousemovex()*0.2
    if xangle# &gt; 90.0 then xangle# = 90.0 else if xangle# &lt; -90.0 then xangle# = -90.0 `&lt;- locking the angle
    xrotate camera 0, xangle#
    yrotate camera 0, yangle#
    zrotate camera 0, 0        // undo roll effect
    
    rem Move
    
    speed# = 1.0 + 0.8*shiftkey()
    
    fw = curvevalue(keystate(17) - keystate(31), fw, 8)
    rl = curvevalue(keystate(32) - keystate(30), rl, 8)
    
    // ensure player can come to a stop
    if fw &gt; -0.01 and fw &lt; 0.01 then fw = 0
    if rl &gt; -0.01 and rl &lt; 0.01 then rl = 0
    
    if fw or rl or angp# &lt; angp_target#
        rem Actual Camera position (without walking animation)
        if fw and rl then fac# = 0.707 else fac# = 1.0 `1/sqrt(2) to avoid diagonal movement being faster than straight movement 
        inc xp#, 0.1*fac#*speed#*(fw*sin(yangle#) + rl*sin(yangle#+90))
        inc zp#, 0.1*fac#*speed#*(fw*cos(yangle#) + rl*cos(yangle#+90))
        rem Walking Animation
        inc angp#, animspeed#*speed# `4.0 `&lt;- animation speed
        rem Camera Offset (added to actual camera position to achieve walking animation)
        // (values toned down a little)
        xoff# = 0.3*sin(yangle#+90)*sin(angp#) 
        zoff# = 0.3*cos(yangle#+90)*sin(angp#)
        yoff# = 0.15*sin(2*angp#+90)
        // threshold speed for deciding if still moving or not.
        if fw &lt; -0.2 or fw &gt; 0.2 or rl &lt; -0.2 or rl &gt; 0.2
            rem Active Movement -&gt; Keep Walking Animation Going
            angp_target# = 180*(int(angp#) / 180) + 180 `next 
            animspeed# = 4.0
        else
            rem No active Movement -&gt; just finish walking animation
            if angp# &gt; angp_target# then angp# = angp_target# 
            animspeed# = animspeed# + 0.25    // speed up a little as finishing
        endif
    endif
    position camera 0, xp#+xoff#,yp#+yoff#,zp#+zoff#
    
    // calculate a point ahead to focus on
    xviewtarg# = xp# + (10.0*sin(yangle#) + 0.01*rl*sin(yangle#+90))
    zviewtarg# = zp# + (10.0*cos(yangle#) + 0.01*rl*cos(yangle#+90))
    yviewtarg# = yp# + yoff#*0.25
    
    // focus directly on it first to read off values
    point camera 0, xviewtarg#, yviewtarg#, zviewtarg#
    yangtarg# = camera angle y(0)
    
    // interp a little between unfocused and focused so player mostly keeps control
    xrotate camera 0, xangle#
    yrotate camera 0, curveangle(yangtarg#, yangle#, 4)
    
    // roll camera slightly with strafing/turning
    // turning roll: +ve tilts into turn, -ve away
    roll# = curvevalue(rl*0.6 + (yangle#-oyangle#)*0.3, roll#, 3)
    roll camera right 0, roll#
    
    
    rem Info
    set cursor 0,0
    print "FPS: ", screen fps()
    print 
    print "Press WASD to Move"
    print "Move Mouse to Look Around"
    print "Shift to Sprint"
    
    // magic anti-nausea reticule
    dot screen width()/2, screen height()/2, 0xffffffff
    dot screen width()/2-3, screen height()/2, 0xff808080
    dot screen width()/2+3, screen height()/2, 0xff808080
    dot screen width()/2, screen height()/2-3, 0xff808080
    dot screen width()/2, screen height()/2+3, 0xff808080

    sync
loop
Posted: 12th Feb 2014 14:06
Really nice so far

Now here's the fun part: Implement Timer Based Movement into this
Posted: 12th Feb 2014 15:33
+ Code Snippet
Rem Project: Dark Basic Pro Project
Rem Created: Thursday, January 30, 2014
rem Author:  Shellfish Games
Rem ***** Main Source File *****


set display mode desktop width(), desktop height(),32,0
sync on : sync rate 0 : sync


hide mouse


make matrix 1, 100,100, 40,40
position matrix 1, -50, -2.4, -50
for i = 1 to 200
    make object cube i, 1
    position object i, rnd(50) - rnd(50), rnd(10) - rnd(10), rnd(50) - rnd(50)
next

position camera 0, 0,0,0
point camera 0, 0,0,1

xangle# = 0
yangle# = 0

fw as float
rl as float

xp# = 0
yp# = 0
zp# = 0
angp# = 0.0
angp_target# = 0.0
xoff# = 0
yoff# = 0.4
zoff# = 0

tnew = timer()
fulltsteps_new = tnew/20

do

    told = tnew
    tnew = timer()
    tdif = tnew - told
    tfac# = tdif/16.667
    fulltsteps_old = fulltsteps_new
    fulltsteps_new = tnew/20
    fulltsteps = fulltsteps_new - fulltsteps_old
    
    
    rem Look
    oyangle# = yangle#
    inc xangle#, mousemovey()*0.2
    inc yangle#, mousemovex()*0.2
    if xangle# &gt; 90.0 then xangle# = 90.0 else if xangle# &lt; -90.0 then xangle# = -90.0 `&lt;- locking the angle
    xrotate camera 0, xangle#
    yrotate camera 0, yangle#
    zrotate camera 0, 0        // undo roll effect
    
    rem Move
    
    speed# = tfac#*(1.0 + 0.8*shiftkey())
    
    for i = 1 to fulltsteps
        fw = curvevalue(keystate(17) - keystate(31), fw, 8)
        rl = curvevalue(keystate(32) - keystate(30), rl, 8)
    next
    
    // ensure player can come to a stop
    if fw &gt; -0.01 and fw &lt; 0.01 then fw = 0
    if rl &gt; -0.01 and rl &lt; 0.01 then rl = 0
    
    if fw or rl or angp# &lt; angp_target#
        rem Actual Camera position (without walking animation)
        if fw and rl then fac# = 0.707 else fac# = 1.0 `1/sqrt(2) to avoid diagonal movement being faster than straight movement 
        inc xp#, 0.1*fac#*speed#*(fw*sin(yangle#) + rl*sin(yangle#+90))
        inc zp#, 0.1*fac#*speed#*(fw*cos(yangle#) + rl*cos(yangle#+90))
        rem Walking Animation
        inc angp#, animspeed#*speed# `4.0 `&lt;- animation speed
        rem Camera Offset (added to actual camera position to achieve walking animation)
        // (values toned down a little)
        xoff# = 0.3*sin(yangle#+90)*sin(angp#) 
        zoff# = 0.3*cos(yangle#+90)*sin(angp#)
        yoff# = 0.15*sin(2*angp#+90)
        // threshold speed for deciding if still moving or not.
        if fw &lt; -0.2 or fw &gt; 0.2 or rl &lt; -0.2 or rl &gt; 0.2
            rem Active Movement -&gt; Keep Walking Animation Going
            angp_target# = 180*(int(angp#) / 180) + 180 `next 
            animspeed# = 4.0
        else
            rem No active Movement -&gt; just finish walking animation
            if angp# &gt; angp_target# then angp# = angp_target# 
            animspeed# = animspeed# + 0.25*fulltsteps    // speed up a little as finishing
        endif
    endif
    position camera 0, xp#+xoff#,yp#+yoff#,zp#+zoff#
    
    // calculate a point ahead to focus on
    xviewtarg# = xp# + (10.0*sin(yangle#) + 0.01*rl*sin(yangle#+90))
    zviewtarg# = zp# + (10.0*cos(yangle#) + 0.01*rl*cos(yangle#+90))
    yviewtarg# = yp# + yoff#*0.25
    
    // focus directly on it first to read off values
    point camera 0, xviewtarg#, yviewtarg#, zviewtarg#
    yangtarg# = camera angle y(0)
    
    // interp a little between unfocused and focused so player mostly keeps control
    xrotate camera 0, xangle#
    yrotate camera 0, curveangle(yangtarg#, yangle#, 4)
    
    // roll camera slightly with strafing/turning
    // turning roll: +ve tilts into turn, -ve away
    for i = 1 to fulltsteps
        roll# = curvevalue(rl*0.6 + (yangle#-oyangle#)*0.3, roll#, 3)
        roll camera right 0, roll#
    next
    
    
    rem Info
    set cursor 0,0
    print "FPS: ", screen fps()
    print
    print "Time Factor: ", tfac#
    print "Full Time Steps: ", fulltsteps
    print 
    print "Press WASD to Move"
    print "Move Mouse to Look Around"
    print "Shift to Sprint"
    
    // magic anti-nausea reticule
    dot screen width()/2, screen height()/2, 0xffffffff
    dot screen width()/2-3, screen height()/2, 0xff808080
    dot screen width()/2+3, screen height()/2, 0xff808080
    dot screen width()/2, screen height()/2-3, 0xff808080
    dot screen width()/2, screen height()/2+3, 0xff808080

    sync
loop


Well, sort of. I think the whole movement works well enough now, only the camera rolling thing still seems to depend on the FPS rate.