Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » sprite move to a position

This thread is locked; no one can reply to it. rss feed Print
sprite move to a position
Cyberlooter
Member #11,133
July 2009

hello!
i would like to make a moving sprite...

#SelectExpand
1 else if(al_key_down(&m_keyboardState, ALLEGRO_KEY_H) ) 2 { 3 for(int i = 0 ; i < 100 ; i++) 4 { 5 m_positionX += 1; 6 } 7 }

i want a sprite to move 100 units.. but he moves way toooo fast... i would like to make a slow movement like a moving platform ::)

and how to make something like that:
sprite move to x 500, y 500 then wait for 5 secods and move to x 200 y 200...??

StevenVI
Member #562
July 2000
avatar

  1. Put your game in a continuous loop.

  2. Break up all your logic into "frames" (like in a movie) rather than trying to do it all at once.

  3. Use a timer to regulate the number of logic frames performed each second. A typical value is 60 frames per second.

Reviewing the example programs that come with Allegro might provide an insight into how to accomplish this.

__________________________________________________
Skoobalon Software
[ Lander! v2.5 ] [ Zonic the Hog v1.1 ] [ Raid 2 v1.0 ]

Cyberlooter
Member #11,133
July 2009

well i have no idea how to slow down my sprite movements... my sprite moves randomly but it is tooo fast i would like to move every one or two seconds

#SelectExpand
1void Ship::Think( void ) 2{ 3 if(m_positionX < 0 || m_positionX > al_get_display_width() || m_positionY < 0 || m_positionY > al_get_display_height() ) 4 { 5 m_positionX = al_get_display_width() / 2; 6 m_positionY = al_get_display_height() / 2; 7 } 8 9 int dir = rand() % 7 + 1; 10 11 switch(dir) 12 { 13 case 1: 14 m_positionX = 50; 15 m_positionY = 100; 16 break; 17 18 case 2: 19 m_positionX = 200; 20 m_positionY = 300; 21 break; 22 23 case 3: 24 m_positionX = 600; 25 m_positionY = 200; 26 break; 27 28 case 4: 29 m_positionX = 450; 30 m_positionY = 500; 31 break; 32 33 case 5: 34 m_positionX = 100; 35 m_positionY = 150; 36 break; 37 38 case 6: 39 m_positionX = 150; 40 m_positionY = 300; 41 break; 42 43 case 7: 44 m_positionX = 200; 45 m_positionY = 500; 46 break; 47 48 default: 49 break; 50 } 51}

and timer class.. i have no idea what to do about this:

#SelectExpand
2#ifndef TIMER_H 3#define TIMER_H 4 5#include <allegro5/allegro.h> 6 7class Timer 8{ 9public: 10 Timer(); 11 12 float GetStartTime( void ); 13 float GetDeltaTime( void ); 14 15private: 16 float m_previousTime; 17}; 18 19#endif TIMER_H

#SelectExpand
3#include "Timer.h" 4 5Timer::Timer() 6{ 7 m_previousTime = 0.0f; 8} 9 10float Timer::GetStartTime( void ) 11{ 12 return al_current_time() / 1000.0f; 13} 14 15float Timer::GetDeltaTime( void ) 16{ 17 float thisTime = GetStartTime(); 18 float deltaTime = thisTime - m_previousTime; 19 m_previousTime = thisTime; 20 21 return deltaTime; 22}

OnlineCop
Member #7,919
October 2006
avatar

In your original post, you had a loop that, for as long as the key was held down, the X coordinate was updated. However, you did not have any sort of timing delay that said, "if the key is STILL down, wait for 0.1 seconds before updating the X coordinate again." So it's just going as fast as possible.

(EDIT: fixed)
An outer loop should be handling your timing. Your inner loop should detect whether the mouse key is still being held down.

If so, evaluate whether your character has moved all 100 pixels. If not, move the X coordinate once (but not more; don't have it inside a while loop). If you have already moved all 100 pixels, either wait until the user releases the key, or (if your logic is setup this way), wait a predetermined amount, then reset the "character has moved" counter to 0, and repeat the "move 100 pixels" logic.

For your next post, you appear to only be storing your current position, but not a "destination" position. I would suggest having both.

If your ship is to move to a specific location, your "destination_x - current_x" will tell you both the direction your ship needs to move, as well as whether you need to keep moving, or (if the numbers are equal) whether to just sit where you're at.

If the user presses a key and releases it very quickly, do you want them to stop moving, or continue toward their destination? If you want them to stop, you can simply set the "destination_x" to wherever the ship is currently; your logic will continue to try to move the ship to its destination, but since you're now "there", you don't have to move anymore.

Cyberlooter
Member #11,133
July 2009

well looks like i will have to use some math stuff to get destination movements working :)

i have got one question.. how do i slow down my application? i would like to start the void Ship::Think( void ) function every 0.5 second.. so my sprite doesnt blink anymore... i want him to teleport every 0.5 second...

#SelectExpand
1while(m_gameApplicationRunning) 2 { 3 OnEvent(); 4 OnThink(); 5 OnDraw(); 6 }

it is possible to slow down my keyboard states in allegro? for example when i push F1 button just once for a little... the console looks like that:

F1 - button
F1 - button
F1 - button
F1 - button
F1 - button

i dont know why it counted 5 clicks :o

#SelectExpand
2else if(al_key_down(&m_keyboardState, ALLEGRO_KEY_F1) ) 3 { 4 std::cout << "F1 - button" << std::endl; 5 }

or should i call al_set_timer_speed(myTimer, 0.5)??

OnlineCop
Member #7,919
October 2006
avatar

  1. Are you drawing directly to the screen, or to a buffer? With Allegro 5, you usually have multiple buffers: one is being currently displayed to the screen, and the other(s) are being drawn to in the background, to prevent flickering/tearing that occurs when you try to draw to the screen directly.

  2. Your logic for the key down problem is probably due to the fact that you're hitting the logic for "is the key down?" several times very quickly, but you don't have something that says "the key WAS down the last time I polled the keyboard, and it's STILL down now, so ignore the key for now." When you finally release the key, your "key_was_down" will be set to false, and the next time you enter that function, you'll have "the key WASN'T down the last time I polled the keyboard, but it's down NOW, so run this logic loop."

    Essentially:

    #SelectExpand
    1 int old_key_f1 = 0; 2 3 ... 4 5 int current_key_f1 = al_key_down(&m_keyboardState, ALLEGRO_KEY_F1); 6 7 // F1 key is held down 8 if(current_key_f1) 9 { 10 // Check whether F1 key was held down the last time this was called: 11 // - If it WASN'T, go ahead and do the logic here 12 // - If it WAS, ignore the key press until the user releases it 13 if(old_key_f1 == 0) 14 { 15 // F1 wasn't pressed previously 16 old_key_f1 = 1; 17 18 // Your logic here... 19 std::cout << "F1 - button" << std::endl; 20 } 21 } 22 else 23 { 24 // F1 key is not being held down: 25 // - Reset the "old_key_f1" so the next key press will allow the 26 // function above to be called 27 old_key_f1 = 0; 28 }

    This may need some adjusting. If you want the ship to move while the key is still being held down, but pause for some "key repeat delay" amount of time, you can change the line from

    #SelectExpand
    13 if(old_key_f1 == 0)

    to

    #SelectExpand
    13 if(old_key_f1 == 0 || current_time > key_f1_pressed_time + key_repeat_delay)

  3. i have got one question.. how do i slow down my application?

    Use a timer to regulate the number of logic frames performed each second. A typical value is 60 frames per second.

Go to: