Game Programming Challenge: Write a reusable 2D vector class

  • (2 Pages)
  • +
  • 1
  • 2

27 Replies - 22806 Views - Last Post: 17 January 2013 - 03:47 AM

#1 stayscrisp  Icon User is offline

  • フカユ
  • member icon

Reputation: 998
  • View blog
  • Posts: 4,173
  • Joined: 14-February 08

Game Programming Challenge: Write a reusable 2D vector class

Post icon  Posted 22 September 2011 - 02:39 AM

*
POPULAR

Hey, this is the first in a series of challenges to help people learn some of the basics in game programming. We see a lot of beginners doing movement in this way:

float xspeed = 0;
float yspeed = 0;
float xpos = 0;
float ypos = 0;

player.xpos += xspeed;
player.ypos += yspeed;

// etc.



For a start it doesn't really look very nice. It also is not reusable, and you have to make it even more convoluted to do some of the more advanced math needed in games. The better alternative is to use vectors. Using vectors we can do movement something like this:

2DVector speed;
2DVector position;

player.position += player.speed;



You will probably have realised that this is going to require knowledge of overloaded operators among other things. This should be a great challenge and I look forward to seeing what people can come up with. Other functions that could be included are dot product, normalise etc.

Extra points for creating a template class so you can easily switch between ints, floats and doubles depending on how much precision you want. Use any language you want but C++ would be great :) Feel free to ask questions within this thread so we can all collaborate.

Happy coding!

Is This A Good Question/Topic? 7
  • +

Replies To: Game Programming Challenge: Write a reusable 2D vector class

#2 cfoley  Icon User is offline

  • Cabbage
  • member icon

Reputation: 1940
  • View blog
  • Posts: 4,027
  • Joined: 11-December 07

Re: Game Programming Challenge: Write a reusable 2D vector class

Posted 22 September 2011 - 04:08 AM

I'll enter this Java one I made for a game physics engine. I've done a few strange things. First, it is immutable which I guess sends alarm bells ringing for most game developers. I did it to see of Java can cope. Turns out it copes nicely. Second, I save the minimum state I have to. Every time you want an angle, it calculates it again. I did this to avoid the possibility of inconsistant states, and I'll only optimise if it ever becomes a bottleneck. Finally, there are no overloaded operators in Java but you will see things like add, subtract, multiply. Oh, and angles are in degrees. I like it that way. ;)

Spoiler


And here is my Trig utility class that it uses. It's probably the only class I wrote 11 years ago that I still use today.

Spoiler

Was This Post Helpful? 3
  • +
  • -

#3 baavgai  Icon User is offline

  • Dreaming Coder
  • member icon

Reputation: 5777
  • View blog
  • Posts: 12,591
  • Joined: 16-October 07

Re: Game Programming Challenge: Write a reusable 2D vector class

Posted 22 September 2011 - 08:15 AM

A lot of the fun of C++ is all the uber overloading...

Technically, a Vector would be both the position and the direction. Which got me to thinking that a ++ operator would be fun.

Here's the code:
Spoiler


And the sample output, to show how much fun that ++ operator can be:
pos = (0,0)
delta = [1,1]
v = <(0,0)-[1,1]>

v++
v = <(1,1)-[1,1]>

v--
v = <(0,0)-[1,1]>

v=Vec2D(5,6,7,8)
v = <(5,6)-[7,8]>

v++
v = <(12,14)-[7,8]>

v++
v = <(19,22)-[7,8]>



I'll get you a templated one, maybe. This was just amusing.
Was This Post Helpful? 1
  • +
  • -

#4 Shane Hudson  Icon User is offline

  • D.I.C Technophile
  • member icon

Reputation: 343
  • View blog
  • Posts: 1,286
  • Joined: 06-December 09

Re: Game Programming Challenge: Write a reusable 2D vector class

Posted 22 September 2011 - 08:53 AM

I am not sure if I will have time to give this a go, but will be interesting to see what people come up with. I have always done:

var velocity = 10;
var direction = 'x';

if (direction == 'x')
{
   player.x += velocity;
}
else
{
   player.y += velocity;
}



Which quite frankly is dreadful!
Was This Post Helpful? 0
  • +
  • -

#5 ishkabible  Icon User is offline

  • spelling expret
  • member icon




Reputation: 1622
  • View blog
  • Posts: 5,709
  • Joined: 03-August 09

Re: Game Programming Challenge: Write a reusable 2D vector class

Posted 22 September 2011 - 08:56 AM

ill defiantly do this when i got home, im gonna make a normal method to i think :P
Was This Post Helpful? 0
  • +
  • -

#6 AdamSpeight2008  Icon User is online

  • MrCupOfT
  • member icon


Reputation: 2240
  • View blog
  • Posts: 9,412
  • Joined: 29-May 08

Re: Game Programming Challenge: Write a reusable 2D vector class

Posted 22 September 2011 - 09:31 AM

I think there already is Vector class in the Framework, but I've created my own.
Spoiler



Left for the other to implement DotProduct (as Extension Methods)

Install with NuGet: Vector2D
Was This Post Helpful? 1
  • +
  • -

#7 stayscrisp  Icon User is offline

  • フカユ
  • member icon

Reputation: 998
  • View blog
  • Posts: 4,173
  • Joined: 14-February 08

Re: Game Programming Challenge: Write a reusable 2D vector class

Posted 23 September 2011 - 01:14 AM

View PostShane Hudson, on 22 September 2011 - 04:53 PM, said:

I am not sure if I will have time to give this a go, but will be interesting to see what people come up with. I have always done:

var velocity = 10;
var direction = 'x';

if (direction == 'x')
{
   player.x += velocity;
}
else
{
   player.y += velocity;
}



Which quite frankly is dreadful!


Ouch! My eyes! :P
Was This Post Helpful? 0
  • +
  • -

#8 anonymous26  Icon User is offline

  • D.I.C Lover

Reputation: 0
  • View blog
  • Posts: 3,638
  • Joined: 26-November 10

Re: Game Programming Challenge: Write a reusable 2D vector class

Posted 23 September 2011 - 05:17 AM

Look out for speed-critical sections as well in your code. If using C++ a very common method for finding the appropriate function calls for applying your implementations to various types and other situations where you can have naming conflicts would be to make use of namespaces:


namespace Vector
{
    class Vector2D
    {
       // ...
    }
}



This could also be manipulated in such a way to get around using templates which are generally a big no-no in any speed-critical section of code.

I'm also seeing a fear of callback functionality that will drastically improve the flexibility of your implementations. And last but not least, let's not forget the use of design patterns like singleton (as always suggested) to keep track of your various instances.

Enjoy! :)
Was This Post Helpful? 0
  • +
  • -

#9 Viske  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 24
  • View blog
  • Posts: 70
  • Joined: 07-June 11

Re: Game Programming Challenge: Write a reusable 2D vector class

Posted 23 September 2011 - 05:34 AM

Well, here's my (admittedly, horrible) attempt at a generic Vector class using Java. Was good to brush up on my maths, I'd forgotten a lot of it.

public class Vector<T extends Number> {
	private T x;
	private T y;
	
	public Vector(T x, T y) {
		this.x = x;
		this.y = y;
	}
	
	public T getX() {
		return x;
	}
	
	public T getY() {
		return y;
	}
	
	public double getMagnitude() {
		return Math.sqrt(x.doubleValue() * x.doubleValue() + y.doubleValue() * y.doubleValue());
	}
	
	public double getDistance(Vector vect) {
		double dx = (x.doubleValue() - vect.getX().doubleValue());
		double dy = (y.doubleValue() - vect.getY().doubleValue());
		return Math.sqrt(dx*dx + dy*dy);
	}
	
	public Vector<T> normalise() {
		if (getMagnitude() != 1) {
			return new Vector(x.doubleValue() / getMagnitude(),
					          y.doubleValue() / getMagnitude());
		}
		else
			return this);
	}
	
	public boolean equals(Object vect) {
		if (vect == null)
			return false;
		if (this == vect)
			return true;
			
		Vector temp = (Vector) vect;
		return (x.doubleValue() == temp.getX().doubleValue()) && (y.doubleValue() == temp.getY().doubleValue());
	}
	
	public double dotProduct(Vector vect) {
		return (x.doubleValue() * vect.getX().doubleValue() +
				y.doubleValue() * vect.getY().doubleValue());
	}
	public double dotProduct(Vector vect, Vector other) {
		return (vect.getX().doubleValue() * other.getX().doubleValue() +
				vect.getY().doubleValue() * other.getY().doubleValue());
	}
	
	public double getAngle(Vector vect) {
		return Math.acos(dotProduct(this.normalise(), vect.normalise()));
	}
	
	public Vector<T> subtract(Vector<T> vect) {
		if (vect.getX() instanceof Double) {
			return new Vector(x.doubleValue() - vect.getX().doubleValue(),
					y.doubleValue() - vect.getY().doubleValue());
		}
		else if (vect.getY() instanceof Float) {
			return new Vector(x.floatValue() - vect.getX().floatValue(),
					y.floatValue() - vect.getY().floatValue());
		}
		else {
			return new Vector(x.intValue() - vect.getX().intValue(),
					y.intValue() - vect.getY().intValue());
		}
	}
	
	public Vector<T> add(Vector<T> vect) {
		if (vect.getX() instanceof Double) {
			return new Vector(x.doubleValue() + vect.getX().doubleValue()
					, y.doubleValue() + vect.getY().doubleValue());
		}
		else if (vect.getY() instanceof Float) {
			return new Vector(x.floatValue() + vect.getX().floatValue(),
					y.floatValue() + vect.getY().floatValue());
		}
		else {
			return new Vector(x.intValue() + vect.getX().intValue(),
					y.intValue() + vect.getY().intValue());
		}
	}
}


Was This Post Helpful? 1
  • +
  • -

#10 baavgai  Icon User is offline

  • Dreaming Coder
  • member icon

Reputation: 5777
  • View blog
  • Posts: 12,591
  • Joined: 16-October 07

Re: Game Programming Challenge: Write a reusable 2D vector class

Posted 23 September 2011 - 07:14 AM

Version 2.0. Uber template version...

As much as it makes sense to have delta separate from position, it is a bit of a pita. I threw a bunch of overloads at this. I can think of a few more, but it would get silly.

Spoiler

Was This Post Helpful? 1
  • +
  • -

#11 cfoley  Icon User is offline

  • Cabbage
  • member icon

Reputation: 1940
  • View blog
  • Posts: 4,027
  • Joined: 11-December 07

Re: Game Programming Challenge: Write a reusable 2D vector class

Posted 23 September 2011 - 07:37 AM

So vectors have an origin, a magnitude and a direction... which is what I think you were getting at before. But if you work with zero-based vectors (I forget their proper name) you can do away with the origin. and just store (x,y) or (magnitude,angle) as you choose.

You can then compose an object that uses a vector as its position and a vector as its delta. In my physics engine, moving objects have a position vector, a speed vector and an acceleration vector. I think the speed vector is similar to your delta (acceleration being a second order delta). This would make my update() methods similar to your ++ operator, albeit more verbose. The moving object class has an update method that takes no parameters (since it already has the acceleration and speed), so I guess that would be the direct equivalent.
Was This Post Helpful? 0
  • +
  • -

#12 baavgai  Icon User is offline

  • Dreaming Coder
  • member icon

Reputation: 5777
  • View blog
  • Posts: 12,591
  • Joined: 16-October 07

Re: Game Programming Challenge: Write a reusable 2D vector class

Posted 23 September 2011 - 08:26 AM

I believe an orgin (0,0) vector is called a "free vector." Or perhaps bound at zero. I'm not real sure how useful this is to the game mechanics of position. I want to know where I am as well as where I'm going, so the orgin does matter.

You're right that only ++ would makes sense in context, as a vector only travels one direction. Other vector properties are obviously valuable, like changing magnatude directly, rather than mucking about with a second point.

I'm not sure why you need both a position and speed, as that kind of sounds like one vector. Acceleration makes sense, though for a physics engine I guess that could be a few vectors. Gravity and the object's momentum.

I've honestly just looked at your code. I was writing in a happy C++ vacuum, having fun with frameworks. I'd thought to stick to basics. I guess the real test of a given framework would be how easy it is to do a given task. Ball bouncing is good. Hmm...
Was This Post Helpful? 1
  • +
  • -

#13 RevTorA  Icon User is online

  • D.I.C Head
  • member icon

Reputation: 76
  • View blog
  • Posts: 247
  • Joined: 22-April 11

Re: Game Programming Challenge: Write a reusable 2D vector class

Posted 23 September 2011 - 12:15 PM

Vectors have no origin. They have only a direction and magnitude. I'll definitely have to give this a go though :)

Only a line segment would have an actual origin btw.

Edit: I think a matrix class challenge would be a good one too btw, since OpenGL is getting rid of its own matrix operations.

This post has been edited by RevTorA: 23 September 2011 - 12:16 PM

Was This Post Helpful? 0
  • +
  • -

#14 baavgai  Icon User is offline

  • Dreaming Coder
  • member icon

Reputation: 5777
  • View blog
  • Posts: 12,591
  • Joined: 16-October 07

Re: Game Programming Challenge: Write a reusable 2D vector class

Posted 23 September 2011 - 01:14 PM

I supposed you're right. I just think of the arrows with the little dot at the beginning...

So, technically, I guess want my vector class to just be an extension of a point class, with direction and mag worried out? But for a travelling point, I'd want to pair them. I like the ++ or cfoley's update. Need a name for that.

I agree with the matrix class. There are a number of ways to skin that cat. I believe that was my first graphic project, in Pascal. Pity I lost those floppies. Damn, I feel old sometimes. :P
Was This Post Helpful? 0
  • +
  • -

#15 macosxnerd101  Icon User is online

  • Self-Trained Economist
  • member icon




Reputation: 10376
  • View blog
  • Posts: 38,415
  • Joined: 27-December 08

Re: Game Programming Challenge: Write a reusable 2D vector class

Posted 23 September 2011 - 01:18 PM

I'll give this a shot! I took the polar approach, and added in dot and cross products. Which for 2D Vectors, cross-product is just the matrix determinant.

Spoiler

Was This Post Helpful? 1
  • +
  • -

  • (2 Pages)
  • +
  • 1
  • 2