Results 1 to 8 of 8

Thread: moving sprites

  1. #1

    moving sprites

    Can someone show me some code to move a sprite from it's
    current position to new position?? A sort of Sprite.Moveto(x,y) procedure

  2. #2

    moving sprites

    Have you tried the DirectX component sets yet? In case you haven't I highly recommend those. DelphiX for example is not very hard and comes with some great samples. Among those examples, you'll also find the answer to your question.

  3. #3

    moving sprites

    I had a look but the samples don't do what i'm asking
    what I need to is have a sprite at say (100,30) and then tell it to move to
    location (200,300) but move in a stright line at agiven speed and i need to know when it gets there

  4. #4

    moving sprites

    I'm not sure there's a componentset that has a function you described. But why don't you write it yourself? Moving a sprite in a straight line at a given speed is a very simple procedure.

    Code:
    if player.x < 400 then
         player.x &#58;= player.x + player.speed 
    else
    begin
        showmessage&#40;'I''m home'&#41;
        timer1.enabled &#58;= false // else you get this message forever  ;&#41; 
    end;
    this should get you started...

  5. #5

    moving sprites

    I think that i'm not making my self clear on what i'm asking so i'll
    try agian the sprite is at (100,30) i tell it to goto (200,100) and in some amout of steps it will get to the position (200,100) so the x value has moved 100 pixels and the y value has moved 70 pixels but the x and y
    get to their positions at the same time I hope this makes sence..

  6. #6

    moving sprites

    The task varies depending on whether your updates occur at a fixed time or with delta time.

    First, let's consider the fixed time-per-updates (e.g. if your updates happened in response to a timer tick). You have two values to calculate:

    The amount that the x value will change per tick
    The amount that the y value will change per tick

    This is simple enough -- you want to calculate the difference in x (and y):
    destination - current position. Divide each value by the amount of updates that are wanted to get how much to move the sprites each tick. For example (untested code):

    [pascal]type
    TSprite = record
    x: Single;
    y: Single;
    SpeedX: Single;
    SpeedY: Single;
    DestX: Single;
    DestY: Single;
    end;

    procedure SetSpriteDestination(var Sprite: TSprite; NewX, NewY: Single;
    Updates: Integer);
    var
    NewSpeedX: Single;
    NewSpeedY: Single;
    begin
    // we want to move to (NewX, NewY). Calculate the differences
    // to get the total amount to move (positive or negative). Once
    // we know how far to move, we want a division, since we don't
    // want to move over there in one go!
    NewSpeedX := (NewX - Sprite.X) / Updates;
    NewSpeedY := (NewY - Sprite.Y) / Updates;

    Sprite.SpeedX := NewSpeedX;
    Sprite.SpeedY := NewSpeedY;
    Sprite.DestX := NewX;
    Sprite.DestY := NewY;
    end;

    const
    VERY_SMALL_NUMBER = 0.1e-6;

    procedure UpdateSprite(var Sprite: TSprite);
    begin
    // check whether we've reached the destination
    if (abs(Sprite.DestX - Sprite.X) <= VERY_SMALL_NUMBER) and
    (abs(Sprite.DestY - Sprite.Y) <= VERY_SMALL_NUMBER) then
    begin
    Sprite.SpeedX := 0;
    Sprite.SpeedY := 0;
    Sprite.X := Sprite.DestX;
    Sprite.Y := Sprite.DestY;
    end
    else
    begin
    // move there!
    Sprite.X := Sprite.X + Sprite.SpeedX;
    Sprite.Y := Sprite.Y + Sprite.SpeedY;
    end;
    end;[/pascal]

    Note that you shouldn't compare floating point numbers directly for
    equality -- instead, use an epsilon value as above. Floating point numbers
    can have small inaccuracies creeping in over time, so the numbers may be
    (e.g.) 0.00000002 instead of just 0.0 depending on the operations you use. Play around with the small number to toggle the "close enough" factor. I forget good values (the value 0.1e-6 is probably much too small here, try making it a bigger number...).

    Things are a little more complicated if you use delta time. For this, do the following: think about how far you want to go in a given amount of time (note: time, rather than updates). Keep a track of the current amount of time that's passed that's passed. Then, it's pretty straightforward to calculate the amount to move. I'll explain how later today once I get back home (got work to do ).
    "All paid jobs absorb and degrade the mind."
    <br />-- Aristotle

  7. #7

    Another option

    An alternative is to calculate the angle between the Current Position and the Destination Position, then move you sprite at this angle at whatever speed towards its destination. The following code shows you how. BTW the following GetAngle code is of my own concoction since I couldn't remeber the proper way so don't laugh if it's horribly unoptimised or just plain silly.


    Code:
    function GetAngle&#40;SPos,FPos&#58; TPoint&#41;&#58; Real; 
    var 
    Lgt,Hgt&#58; Real; 
    Rad,Deg&#58; Real; 
    begin 
    Deg&#58;=0; 
    Lgt&#58;=FPos.X-SPos.X; 
    If Lgt=0 Then Lgt&#58;=0.01; 
    Hgt&#58;=FPos.Y-SPos.Y; 
    If Hgt=0 Then Hgt&#58;=0.01; 
    Rad&#58;=ArcTan&#40;Hgt/Lgt&#41;; 
    //Top Left Corner 
    If &#40;FPos.X<SPos.X&#41; and &#40;FPos.Y<SPos.Y&#41; Then Deg&#58;=Rad*&#40;180/Pi&#41;+180; 
    //Top Right Corner 
    If &#40;FPos.X>=SPos.X&#41; and &#40;FPos.Y<SPos.Y&#41; Then Deg&#58;=Rad*&#40;180/Pi&#41;+360; 
    //Bottom Left Corner 
    If &#40;FPos.X<SPos.X&#41; and &#40;FPos.Y>=SPos.Y&#41; Then Deg&#58;=Rad*&#40;180/Pi&#41;+180; 
    //Bottom Right Corner 
    If &#40;FPos.X>=SPos.X&#41; and &#40;FPos.Y>=SPos.Y&#41; Then Deg&#58;=Rad*&#40;180/Pi&#41;; 
    GetAngle&#58;=Deg; 
    end;
    after we use our GetAngle procedure like so

    Code:
    Angle&#58;=GetAngle&#40;Point&#40;CurPos.X,CurPos.Y&#41;,Point&#40;DestPos.X,DestPos.Y&#41;&#41;;
    (BTW if this doesn't seem to work properly, try switching the order in which you parse the vars into the getangle function e.g dest first then curpos. I forget which way round they go I think this is correct)
    we can then use this angle to move the object towards the destination with the following code. Again, this code is my own and I have no idea whether it's the best way of doing things but it's my way of doing things.

    Code:
    CurPos.X&#58;=Round&#40;Speed*Cos&#40;&#40;Angle&#41;*Pi/180&#41;&#41;+CurPos.X; 
    CurPos.Y&#58;=Round&#40;Speed*Sin&#40;&#40;Angle&#41;*Pi/180&#41;&#41;+CurPos.Y;
    The pi/180 converts the result of the Cos/Sin into Degrees, the standard return for these are in Radians. Let me know what you think.
    [/i]
    Isometric game development blog http://isoenginedev.blogspot.com/

  8. #8

    moving sprites

    Crisp_N_Dry: your function looks okay, apart from the formatting It would be useful for times when the destination changed a lot (maybe homing missiles or whatever), though that would need a little modification to ensure it doesn't overshoot.

    I totally forgot to mention the delta time way to go from point a to point b. Ooops! One method is to keep the time passed and total time expected. You could then calculate a percent of time passed and multiply it with the given vectors (i.e., calculate one percent of the horizontal movement required, then one percent of the vertical movement). This would be standard interpolation, a + t(b - a). This would be pretty much guaranteed to find the spot

    The alternative would be a bit similar to Crisp_N_Dry's method, in that each sprite has a speed, so it's not known how long it will take. This involves the usual stuff, multiplying a vector by the speed and the time passed (IIRC!), with an annoying check to ensure that the person doesn't overshoot (since they may move too far depending on how much time has passed).

    The advantage of using an angle is that you can keep the old one, and gradually "turn" towards where you want to go - handy for vehicle-like turning circles, I'd suppose (without having tested that assumption).
    "All paid jobs absorb and degrade the mind."
    <br />-- Aristotle

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •