Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Logic question regarding movement.  (Read 1211 times)

0 Members and 2 Guests are viewing this topic.

PreDominance

  • Newbie
  • *
  • Posts: 2
    • View Profile
Logic question regarding movement.
« on: May 28, 2014, 07:31:47 pm »
Greetings SFML,

I'm creating a simple tower defense game as my first-ever C++ project. It's going decently smoothly, however I've hit a logic bump in the movement of minions.

Each minion has a member variable of type std::vector<Tile> path, which is their path. path[0] represents the start, path[path.size()] represents the end.
Currently my logic does something like:
  • Loop through path. If path contains the minion, we've found its tile.
  • Obtain tile path[i+1] (OOB exceptions handled). Obtain midpoint (Tile.getMidPoint()).
  • If midpoint.x > minion.getPosition().x, move right. else if less, move left. etc for .y values.

The problem is that since I only check for tile.contains(), it "moves on" to the next tile just when entering the new one. This is a problem for corners, where I end up with something like this:


Here the minions start going left, rather than following the path.

Any help/ideas are appreciated!

Jesper Juhl

  • Hero Member
  • *****
  • Posts: 1405
    • View Profile
    • Email
Re: Logic question regarding movement.
« Reply #1 on: May 28, 2014, 07:35:51 pm »
... variable of type std::vector<Tile> path, which is their path. path[0] represents the start, path[path.size()] represents the end.
Don't you mean path[path.size() - 1] is the end?

PreDominance

  • Newbie
  • *
  • Posts: 2
    • View Profile
Re: Logic question regarding movement.
« Reply #2 on: May 28, 2014, 07:48:44 pm »
Yeah, my bad.

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Re: Logic question regarding movement.
« Reply #3 on: May 28, 2014, 07:54:29 pm »
Any help/ideas are appreciated!
You don't say what you actually want to achieve, only how ;)

If the idea is to walk along a predefined path, you can regard the tile centers as waypoints. You always move towards them, until you're in a distance that can't become any smaller. This requires some vector algebra:
// Given:
sf::Vector2f nextTileCenter = ...;
sf::Vector2f minionPosition = ...;
float minionSpeed = ...; // constant

// To compute:
float distanceToWalk = minionSpeed * elapsedTime;
sf::Vector2f direction = unitVector(nextTileCenter - minionPosition);
minionPosition += direction * distanceToWalk;

// Check if distance is small enough:
if (length(nextTileCenter - minionPosition) <= distanceToWalk / 2.f)
{
    // Advance to next tile, so direction changes
}

It looks complicated, but it's actually simpler because you have no case differentiation on the direction. I'd suggest you use a fixed elapsed time for robustness, otherwise the game logic depends on the framerate and is non-deterministic.

unitVector() and length() are self-explananatory functions, they exist ready-to-use in my library Thor (the Vectors module can even be used without installing the library, just include the file).

There are some tweaks like comparing the squares for distances or adding a floating-point epsilon for the half distance to walk, but that should show the main principle.
« Last Edit: May 28, 2014, 07:57:09 pm by Nexus »
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development: