It depends what the application is. If you don't care about other processes, you could simply use a FOR loop to change its position:
SPSET 0, 0
VAR StartX%=0, FinalX%=150
FOR I% = StartX% TO FinalX%
SPOFS ID, I%, 100
VSYNC 1
NEXT
Or you could move it smoothly with a smoothing function
' takes two arguments for the range and one for the position
' adapted from en.wikipedia.org/wiki/Smoothstep#Variations
DEF SMOOTHSTEP(Lower#, Upper#, X#)
' adjust X to a normalized range of 0 to 1
X# = MAX(MIN((X# - Lower#)/(Upper# - Lower#), 0.0), 1.0)
RETURN X# * X# * X# * ( X# * (X# * 6 - 15) + 10)
END
' and then our blocking loop again
SPSET 0, 0
VAR StartX%=0, FinalX%=150
FOR I% = StartX% TO FinalX%
SPOFS ID, I% * SMOOTHSTEP(StartX%, FinalX%, I%), 100
VSYNC 1 'frame sync
NEXT
If you want this to run while something else is happening, or while the player still has control, it's a little trickier.
The idea is to call a routine that updates the sprite's movement once per frame, but that means we have to keep track of its
state outside of the routine. You could do it with global variables or sprite variables or, in some applications, just by the position of the sprite alone. I'll use a global array here simply because it's easier, but I suggest using SPVAR for a cleaner alternative.
For a scalable solution, we'll also use the nifty CALL command, which can evaluate functions tied to any sprite and passes the sprite ID as CALLIDX automatically.
' the first dimension will be an index into sprite IDs,
' and for the purposes of this example, we'll treat the
' second dimension as a velocity vector
DIM STATEARRAY[2,2]
DEF MYMOVEFUNCTION
SPOFS CALLIDX OUT X,Y ' this OUT syntax gets the current position
SPOFS CALLIDX, X + STATEARRAY[CALLIDX,0], Y + STATEARRAY[CALLIDX, 1]
END
SPSET 1,54
STATEARRAY[1,0] = 2 'x velocity [of sprite #1]
STATEARRAY[1,1] = 1 'y velocity [of sprite #1]
SPFUNC 1, "MYMOVEFUNCTION" 'assign MYMOVEFUNCTION to sprite 1
WHILE 1 'loop forever
PRINT "Non-Blocking!"
'evaluate callbacks (i.e. the one on sprite 1)
CALL SPRITE
VSYNC 1
WEND 'end while block
To make it stop once it actually gets to the position, you can add a check for the position (perhaps the desired position goes into new cells of the state array) that sets the sprite's velocity to 0 or something.
Trinitro21 pointed out that SPANIM can also be used to move a sprite.
The basic format here is SPANIM ID,"XY",-time,FinalX,FinalY [optionally, more times and coordinates can be added]
SPSET 0,5
SPANIM 0,"XY",-60,50,50
You'll still have to figure out how to control if it's in another loop, though.