Moving along a line
BlitzMax Forums/BlitzMax Beginners Area/Moving along a line
| ||
Hi how do I move an image across a line? e.g. x1-10 y1-10 x2-40 y2-50 |
| ||
Using linear interpolation and/or the bressenham line algorithm. (At work don't have example code - there are examples of both in the Code Archives however if I remember correctly). |
| ||
Function TweenLinear#(X1#, X2#, Tween#) Value# = X1# + (Tween# * (X2# - X1#)) Return Value# End Function Start tween at 0, and increase to 1 and the return value will go from X1 to X2. (X2# - X1#) is the length of the line. Multiplying that by Tween# gives us how far to travel along the line from point 1. Adding that to X1# gives us the final position. If you want to move in 2D, you just call that function once to calculate the X and once to calculate the Y. |
| ||
you can use atan to to find which direction to go in given x1,y1 x2,y2 movestep ta=atan(y1-y2,x1-x2) xstep=sin(ta)*movestep ystep=cos(ta)*movestep |
| ||
thanks! the tween function worked |
| ||
For some reason the image stays 1 pixel behind the next set of co-ords until tween reaches 0.5.Function TweenLinear#(X1#, X2#, Tween#) Value = Float(X1# + Float(Tween# * Float(X2# - X1#))) Return Value End Function Graphics 640,480,16,2 SetBuffer BackBuffer() Function create_bloke(name$) a=CreateImage(StringWidth (name),StringHeight(name)) SetBuffer ImageBuffer(a) Text 0,0,name SetBuffer BackBuffer() Return a End Function Type bloke Field x Field y Field speed# Field tween# Field image_handle End Type b.bloke=New bloke b\image_handle=create_bloke("trev") b\speed=.001 b\tween=0 Global destinationx=50 Global destinationy=50 While Not KeyDown(1) Cls For b.bloke=Each bloke b\tween=Float(b\tween+b\speed) b\x=tweenlinear(b\x,destinationx,b\tween) b\y=tweenlinear(b\y,destinationy,b\tween) DrawImage b\image_handle,b\x,b\y If b\x=destinationx And b\y=destinationy RuntimeError "arg" EndIf Next Flip Wend End speed has been tested with different values but a similar result happens with all values. |
| ||
First of all, this is the Blitzmax forum, and that's regular Blitz code. :-) Second, you're using the tween function incorrectly: b\x=tweenlinear(b\x,destinationx,b\tween) By passing b\x to the tween function, you are tweening between the current position of the object and the destination. That's not what you want to do. You want to pass the starting position of the object and the ending position. If you simply want to move an object towards a point, then you should do something entirely different: ; Calculate a normal (a line with a length of 1) which points towards the destination point from the current point. Length# = Sqr((DestinationX#-CurrentX#)^2 + (DestinationY#-CurrentY#)^2) ; (DestinationX#-CurrentX#) and (DestinationY#-CurrentY#) is our vector, but we need it to have a length of 1, so we divide both axes by the vector's length. Nx# = (DestinationX#-CurrentX#) / Length# Ny# = (DestinationY#-CurrentY#) / Length# ; You do not need to calculate the above every frame if your destination point does not move. ; Calculate vector which points in a certain direction and had a length equal to our desired speed: Vx# = Nx# * Speed# Vx# = Nx# * Speed# ; Nor do you need to calculate this every frame if the speed does not change. Now you just move your object like so: b\x = b\x + Vx# b\y = b\y + Vy# Unless you're using frame timing so each frame can take a different amount of time to render in which case you would do this: b\x = b\x + Vx#*SecondsPassed# b\y = b\y + Vy#*SecondsPassed# The only thing is that if you move an object like this, then you can't simply check to see if it is at the right position each frame, because it could skip right over that position. Instead you'll have to check whether the X and Y component are now greater than or less than the desired position depending on which direction you're moving, (the sign of Vx# and Vy# tell you which direction you are moving) and then snap the object to the desired resting point if it has gone beyond these points. |