### Gamedev - Moving an object from point A to point B

his is more a beginner gamedev question... If this isn't the place to ask please let me know! Thank you

I want to create a function that places my game object at a given strating point (Point A) and move it towards and end point (Point B):

void Object::Move( Vector2 point_a, Vector2 point_b )
{
... // Set object's position to the starting point (point a)
this->position.x = point_a.x;
this->position.y = point_a.y

... //Move it towards point B
}

The main problem I have with this approach and the true reason behind my question here is that since the game is running its update loop constantly, say 60 times a second, the initial position gets reset over and over back to point A and that won't let my Object to move. I thought about creating a bool within the object's definition that becomes true once the position has been set but I don't want to include something like that in it but I can't figure out any other way to do it. Which is why I'm here.

Thanks for taking the time.
 since the game is running its update loop constantly, say 60 times a second, the initial position gets reset over and over back to point A and that won't let my Object to move
The game updating at a regular rate should not mean that initial positions get reset.

Your function's behavior is odd.
Let's say you have a Player at position C.
You call Player.Move(A, B);
So now position C is thrown away, and the player's position becomes A, and then presumably increments toward B a little bit, depending on your timestep. So you're trying to do two different things at once, and in effect failing to do either effectively.

I would expect a function called "Move" to not abruptly reset any positions. You may want to consider using a 'velocity' vector. For example,

 ``12345`` ``````void Object::Move(Vector2 velocity) { this->position.x += velocity.x; this->position.y += velocity.y; }``````

So in each iteration in your loop, you need to call Move to move the character over a bit more each timestep.

____________________________

Or, another thing to consider. If you know you want to move to a particular target, then you can calculate this and move towards it by a given speed.

 ``12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182`` ``````// Example program #include #include struct Vector2 { double x; double y; }; Vector2 operator*(double scale, const Vector2& vec) { return Vector2{scale * vec.x, scale * vec.y}; } std::ostream& operator<<(std::ostream& os, const Vector2& vec) { return os << "(" << vec.x << ", " << vec.y << ")"; } Vector2 operator+(const Vector2& a, const Vector2& b) { return Vector2{a.x + b.x, a.y + b.y}; } Vector2 operator-(const Vector2& a, const Vector2& b) { return Vector2{a.x - b.x, a.y - b.y}; } Vector2 operator/(const Vector2& vec, double scale) { return Vector2{vec.x / scale, vec.y / scale}; } double magntiude_squared(const Vector2& vec) { return vec.x * vec.x + vec.y * vec.y; } Vector2 normalize(const Vector2& vec) { if (vec.x == 0.0 && vec.y == 0.0) return Vector2{0.0, 0.0}; return vec / std::sqrt(magntiude_squared(vec)); } class Object { public: void MoveTowards(const Vector2& target, double speed); Vector2 position; }; void Object::MoveTowards(const Vector2& target, double speed) { Vector2 delta = target - this->position; if (magntiude_squared(delta) < speed * speed) { // set to target if our speed would go beyond the target this->position = target; } else { this->position = this->position + speed * normalize(delta); } } int main() { double timestep = 1.0 / 60.0; // or whatever... see "fix your timestep" article Object player; player.position = Vector2{100, 100}; Vector2 target {200, 300}; double speed = 320; for (int i = 0; i < 50; i++) { player.MoveTowards(target, speed * timestep); std::cout << player.position << '\n'; } }``````

 ```(102.385, 104.77) (104.77, 109.541) (107.155, 114.311) (109.541, 119.081) (111.926, 123.851) (114.311, 128.622) (116.696, 133.392) (119.081, 138.162) (121.466, 142.933) (123.851, 147.703) (126.237, 152.473) (128.622, 157.243) (131.007, 162.014) (133.392, 166.784) (135.777, 171.554) (138.162, 176.324) (140.547, 181.095) (142.933, 185.865) (145.318, 190.635) (147.703, 195.406) (150.088, 200.176) (152.473, 204.946) (154.858, 209.716) (157.243, 214.487) (159.628, 219.257) (162.014, 224.027) (164.399, 228.798) (166.784, 233.568) (169.169, 238.338) (171.554, 243.108) (173.939, 247.879) (176.324, 252.649) (178.71, 257.419) (181.095, 262.189) (183.48, 266.96) (185.865, 271.73) (188.25, 276.5) (190.635, 281.271) (193.02, 286.041) (195.406, 290.811) (197.791, 295.581) (200, 300) (200, 300) (200, 300) (200, 300) (200, 300) (200, 300) (200, 300) (200, 300) (200, 300) ```
Last edited on
Yeah you're right, now that you mention it what I had in mind sounds kind of dumb now.
Thanks a lot for taking the time to make such a good example I appreciate the heads up and the help. I'll take a very close look to the code
I would recommend something like this, instead. It more easily handles variable frame times while maintaining constant speed:
 ``123456789101112131415161718192021222324252627282930313233343536373839`` ``````class Actor{ Point2D position; Point2D source; Point2D destination; double movement_start_time = 0; double movement_length = 0; bool moving = false; public: void move_to(double current_time, const Point2D &destination, double movement_length){ this->source = this->position; this->destination = destination; this->movement_start_time = current_time; this->movement_length = movement_length; this->moving = true; } void update(double current_time){ if (!this->moving) return; auto t = current_time - this->movement_start_time; if (t >= this->movement_length){ this->position = this->destination; this->moving = false; return; } this->position = this->source + (this->destination - this->source) * (t / this->movement_length); } void draw(); }; void game_loop(){ actors.front().move_to(0, {10, 10}, 1); //move to (10, 10) in 1 second while (true){ double current_time = get_game_time(); for (auto &actor : actors) actor.update(current_time); for (auto &actor : actors) actor.draw(); } }``````
Topic archived. No new replies allowed.