0
\$\begingroup\$

Edit: solved my issue, but look at the other answer

I am stuck with a problem that I cant quite figure out.

When I move my Player to a new point, it does get there, but it vibrates. I can't seem to get it to stop.

I've used an Entity Component System.

This is a function in my Component_Transform class

void direction(float x_pos_str, float y_pos_str, float x_pos_end, float y_pos_end)
    {
        if (x_pos_str < x_pos_end)
        {
            if (x_pos_str != x_pos_end) { velocity.x = 1; }
        }
        if (y_pos_str < y_pos_end)
        {
            if (y_pos_str != y_pos_end) { velocity.y = 1; }
        }
        if (x_pos_str > x_pos_end)
        {
            if (x_pos_str != x_pos_end) { velocity.x = -1; }
        }
        if (y_pos_str > y_pos_end)
        {
            if (y_pos_str != y_pos_end) { velocity.y = -1; }
        }
        if (x_pos_str == x_pos_end)
        {
            velocity.x = 0;
        }
        if (y_pos_str == y_pos_end)
        {
            velocity.y = 0;
        }

This is apart of my Controller_Mouse class

void update() override
    {
        if (Game::event.type == SDL_MOUSEBUTTONDOWN)
        {
            if (SDL_BUTTON_LEFT)
            {


                std::cout << "transform vals: " << transform->position.x <<", " <<transform->position.y << std::endl;
                std::cout << "click vals:     " << Game::event.motion.x << ", " << Game::event.motion.y << std::endl;


                transform->target.x = Game::event.motion.x; transform->target.y = Game::event.motion.y;






            }


        }
        if (Game::event.type == SDL_MOUSEBUTTONUP, SDL_BUTTON_LEFT)
        {
            transform->direction(transform->position.x, transform->position.y, transform->target.x, transform->target.y);

        }
\$\endgroup\$
  • \$\begingroup\$ What happens when x_pos_str is 0.5f and x_pos_end is 1.0f? \$\endgroup\$ – tkausl Aug 30 '17 at 22:16
  • \$\begingroup\$ Yes, but how do I solve this issue? \$\endgroup\$ – Chris Aug 31 '17 at 5:21
1
\$\begingroup\$

This is a quite easy problem to solve.

This happens, because your player overshoots the target. Let's think in a single axis. The player is on the 49.5 point and the target is at 50. The next step you make the player move a unit, so they'll land on 50.5. 50.5 is greater than 50, so it goes back. This repeats forever and makes the player "vibrate".

You shouldn't make the player land exactly at that position, a "close enough" should work well. Continuing with our 1D example, let' make the player only go towards the point, if the distance os greater than pr equal to 1. This way, it'll stop at 49.5.

In 2D you'd solve this by getting the distance between the player's pos and the target, and only move if it's greater than the velocity (I'm abusing the fact, that if √x > √y, then x > y, because the latter is less intensive on the CPU):

    if (x_pos_str < x_pos_end && pow(x_pos_end - x_pos_str, 2) + pow(y_pos_end - y_pos_str, 2) < 1)
    {
        velocity.x = 1; 
    }

Additional notes:

1.) You don't need to check if x_pos_str equals x_pos_end after checking if the former is lower than the latter. If x is smaller than y, then x =/= y.

2.) You should probably look up code conventions. People usually use camelcase (camelCase) instead of underscores (under_scores) for variables. The variables should also habe a more descriptive name.

\$\endgroup\$
  • \$\begingroup\$ Thank you! I'll implement this into my code as soon as I can. \$\endgroup\$ – Chris Aug 31 '17 at 3:52
  • \$\begingroup\$ Also, I'm not quite familiar with 'pow'. Would you please explain it, and what effect it is having on this code? \$\endgroup\$ – Chris Aug 31 '17 at 3:59
  • \$\begingroup\$ I don't know if I'm doing it right, but after implementing your code, my player doesn't move \$\endgroup\$ – Chris Aug 31 '17 at 4:56
  • \$\begingroup\$ The pow function raises the first argument to the second argument's power. So pow(5,2); raises 5 to the 2nd power. \$\endgroup\$ – user1118321 Aug 31 '17 at 5:51
0
\$\begingroup\$

I solved it by doing this

I should note that I use speed, which was not apart of the original post. It is separate from velocity. It is so I can control the individual pacing of things that have the Transform Component

Here is the update function,which explains the relationship

void update() override
    {
        position.x += velocity.x * speed;
        position.y += velocity.y * speed;
    }

And here is the revised Direction function

        if (x_pos_str == x_pos_end || x_pos_str >= x_pos_end - speed || x_pos_str <= x_pos_end + speed)
        {
            velocity.x = 0;
        }
        if (y_pos_str == y_pos_end || y_pos_str >= y_pos_end - speed || y_pos_str <= y_pos_end + speed)
        {
            velocity.y = 0;
        }

        if (x_pos_str < x_pos_end - speed)
        {
            velocity.x = 1;
        }
        if (y_pos_str < y_pos_end - speed)
        {
            velocity.y = 1;
        }


        if (x_pos_str > x_pos_end + speed)
        {
            velocity.x = -1;
        }
        if (y_pos_str > y_pos_end + speed)
        {
            velocity.y = -1;
        }
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.