Moving Around

I was thinking about Command & Conquer this morning, and realized that there’s a very simple feature in that game that I couldn’t work out in my head how to do myself: click on a location on the screen and have an object move towards that location.

There are lots of wrong ways to do this. I started trying to work out on paper how to move a coordinate along a diagonal line, but really that’s the wrong way to think about it. You’re have to add a value to the X and Y coordinate of your object such that it steadily goes towards the new location.

If you take the X and Y distances between the object and the new location, divide those distances by some constant (which is what we’ll just call the “speed” in this example), you have a value to increment X and Y by bit by bit until it reaches the destination (or close enough to the destination).

Completely on accident I implemented this idea such that the object slows down as it approaches the target – this is because I re-calculate the distance after every move of my object. The X and Y distances gets smaller, but the “speed” I divide by stays the same, so the incremental value I add to the X and Y position gets smaller and smaller (so it appears to be approaching slower and slower).

Anyways, here’s a small example using SFML to do the drawing.

#include <SFML/Graphics.hpp>

int main()
{
	sf::RenderWindow window(sf::VideoMode(640, 480), "Click to move");

	//Variables to store the position of the chaser, the
	//target, and the mouse click
	sf::Vector2i clickPosition;
	sf::Vector2f targetPosition;
	sf::Vector2f chaserPosition;

	//variables to store distances between the
	//chaser and target
	float distanceX;
	float distanceY;
	float distance;

	//Speed of the chaser
	float chaserSpeed = 2000;

	//tracking is 1 when I click the mouse, and
	//0 when the chaser hits the target.
	bool tracking = 0;

	//target circle size, color, and initial
	//position
	sf::CircleShape targetCircle;
	targetCircle.setFillColor(sf::Color::Red);
	targetCircle.setRadius(10.f);
	targetCircle.setPosition(0.f, 0.f);

	//chaser circle size, color, and initial
	//position
	sf::CircleShape chaserCircle;
	chaserCircle.setFillColor(sf::Color::Blue);
	chaserCircle.setRadius(10.f);
	chaserCircle.setPosition(100.f, 100.f);

	while (window.isOpen())
	{
		sf::Event event;
		while (window.pollEvent(event))
		{
			if (event.type == sf::Event::Closed)
				window.close();

			if (event.type == sf::Event::MouseButtonPressed)
			{
				//If the mouse is clicked, get the position
				clickPosition = sf::Mouse::getPosition(window);

				//Set the target circle to that mouse click position
				targetCircle.setPosition((float)clickPosition.x, (float)clickPosition.y);

				//set tracking to 1 to enable tracking
				tracking = 1;

				//print useful debug info
				printf("Tracking...\n");

				//print useful debug info
				printf("click X: %i, click Y: %i\n", clickPosition.x, clickPosition.y);

			}
		}

		if (tracking)
		{
			//We'll need the target and chaser positions
			targetPosition = targetCircle.getPosition();
			chaserPosition = chaserCircle.getPosition();

			//get the X and Y distance between the chaser
			//and target
			distanceX = targetPosition.x - chaserPosition.x;
			distanceY = targetPosition.y - chaserPosition.y;

			//calculate the distance between the chaser
			//and target
			distance = sqrt(distanceX * distanceX + distanceY * distanceY);

			//update the position of the chaser by adding incremental
			//values to its current X and Y position.
			chaserCircle.setPosition(chaserPosition.x + (distanceX / chaserSpeed), chaserPosition.y + (distanceY / chaserSpeed));

			//if the distance is close, stop tracking
			if (distance < 10)
			{
				tracking = 0;
				printf("End tracking, distance %f\n", distance);
			}

		}

		window.clear();
		window.draw(chaserCircle);
		window.draw(targetCircle);
		window.display();
	}

	return 0;
}

Neat, huh? I found this site that has some examples of all kinds of movement, but it’s in Javascript: http://www.somethinghitme.com/2013/11/13/snippets-i-always-forget-movement/

I’m itching to make another small game so that I can put some of the ideas in this fantastic SFML game development book, SFML Game Development, into use. The only thing holding me back right now is solidifying my understanding of some of the more advanced C++ the book uses (templates, woof).

This entry was posted in Programming. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s