Can't modify XNA Vector components
I have a class called Sprite, and ballSprit开发者_开发问答e is an instance of that class. Sprite has a Vector2 property called Position.
I'm trying to increment the Vector's X component like so:
ballSprite.Position.X++;
but it causes this error:
Cannot modify the return value of 'WindowsGame1.Sprite.Position' because it is not a variable
Is it not possible to set components like this? The tooltip for the X and Y fields says "Get or set ..." so I can't see why this isn't working.
The problem is that ballSprite.Position
returns a struct, so when you access it, it creates a copy of it due to the value semantics. ++ attempts to modify that value, but it'll be modifying a temporary copy - not the actual struct stored in your Sprite.
You have to take the value from reading the Position and put it into a local variable, change that local variable, and then assign the local variable back into Position, or use some other, similar way of doing it (maybe hiding it as some IncrementX
method).
Vector2D v;
v = ballSprite.Position;
v.X++;
ballSprite.Position = v;
Another, more generic solution, might be to add another Vector2 to your Position. The + operator is overloaded, so you could create a new vector with the change you want, and then add that to the vector instead of updating the indiviudal components one at a time.
You can do
Position = new Vector2(Position.X + 1, Position.Y );
or
Position += new Vector2( 1.0f, 0.0f );
or
Position.X += 1.0f;
An easy alternative is this:
instead of: sprite.Position.X = 10;
use: sprite.Position = new Vector2(10, sprite.Position.Y);
instead of: sprite.Position.Y = 10;
use: sprite.Position = new Vector2(sprite.Position.X, 10);
instead of: sprite.Position.X += 10;
use: sprite.Position += new Vector2(0, 10);
instead of: sprite.Position.Y += 10;
use: sprite.Position += new Vector2(10, 0);
In stead of using new Vector2(...)
to add 2 vectors, you can also use Vector2.UnitX:
ballSprite.Position.X += 1; // error
ballSprite.Position += Vector2.UnitX; // solution
It's very useful when you want to move directional. For example, if you want to move only horizontal:
Vector2 offset = new Vector2(2, 4);
ballsprite.Position += offset * Vector2.UnitX;
In this example, the value of speed.Y
won't be added to the position of the sprite. Why?
offset == new Vector2(2, 4)
UnitX == new Vector2(1, 0)
--------------------------------
The above Vectors are multiplied
which results into the following
--------------------------------
offset * UnitX
(X: 2, Y: 4) * (X: 1, Y: 0)
(X: 2 * 1, ... Y: 4 * 0)
(X: 2, Y: 0) <-- result
Another advantage of doing it this way is readability. At least that is what I think. See it for yourself:
// multiple ways of incrementing ballspeeds X coordinate.
ballSprite.Position += Vector2.UnitX;
ballSprite.Position += new Vector2(1, 0);
ballSprite.Position = new Vector2(ballSprite.Position.X + 1, ballSprite.Position.Y);
Vector2 temp = ballSprite.Position;
temp.X++;
ballSprite.Position = temp;
Of course, there is also a Vector2.UnitY for vertical movement. Combine these static fields together with Vector2.Zero and Vector2.One, and you can write easy-to-understand code.
When I'm working with Vector2
s and directions, I use the following table:
<--- X coordinate --->
-1 0 +1
| |
-Vector2.One | -Vector2.UnitY | -1
(X:-1, Y:-1) | (X: 0, Y:-1) |
| | ^
----------------+----------------+---------------- |
| |
-Vector2.UnitX | Vector2.Zero | +Vector2.UnitX 0 Y coordinate
(X:-1, Y: 0) | (X: 0, Y: 0) | (X:+1, Y: 0)
| | |
----------------+----------------+---------------- V
| |
| +Vector2.UnitY | +Vector2.One +1
| (X: 0, Y:+1) | (X:+1, Y:+1)
| |
精彩评论