问题
I have made several rectangles in my XNA program. The next step is to choose them and move them one by one.
To choose them, I use the code
MouseState mouse = Mouse.GetState();
bool IsSelect1=false;
bool IsSelect2 = false;
bool IsSelect3 = false;
int IsSelectNum=0;
//To set the value of IsSelectNum
if ((mouse.X > drawRectangle.X && mouse.X <= mouse.X + currentCharacter.Width
&& mouse.Y >= drawRectangle.Y && mouse.Y <= drawRectangle.Y + currentCharacter.Height)
&& (mouse.LeftButton == ButtonState.Pressed))
{ IsSelectNum = 1; }
else if ((mouse.X > drawRectangle2.X && mouse.X <= mouse.X + currentCharacter2.Width
&& mouse.Y >= drawRectangle2.Y && mouse.Y <= drawRectangle2.Y + currentCharacter2.Height)
&& (mouse.LeftButton == ButtonState.Pressed))
{ IsSelectNum = 2; }
else if ((mouse.X > drawRectangle3.X && mouse.X <= mouse.X + currentCharacter3.Width
&& mouse.Y >= drawRectangle3.Y && mouse.Y <= drawRectangle3.Y + currentCharacter3.Height)
&& (mouse.LeftButton == ButtonState.Pressed))
{ IsSelectNum = 3; }
//To choose figure using switch function
switch (IsSelectNum)
{
case 1:
IsSelect1 = true;
break;
case 2:
IsSelect2 = true;
break;
case 3:
IsSelect3 = true;
break;
default:
break;
}
In order to move them, I use
//If selective, then it can be moved
if (IsSelect1 == true)
{
drawRectangle.X = mouse.X - currentCharacter.Width / 2;
drawRectangle.Y = mouse.Y - currentCharacter.Width / 2;
//To finally locate figure in the top
if (drawRectangle.X <= 70 && drawRectangle.Y <= 15)
{
drawRectangle.X=50;
drawRectangle.Y=10;
IsSelect1 = false;
IsSelectNum = 0;
}
}
else if(IsSelect2==true)
{
drawRectangle2.X = mouse.X - currentCharacter2.Width / 2;
drawRectangle2.Y = mouse.Y - currentCharacter2.Width / 2;
//To finally locate figure in the top
if (drawRectangle2.X >= 250 && drawRectangle2.X <= 320 && drawRectangle2.Y <= 15)
{
drawRectangle2.X = 280;
drawRectangle2.Y = 10;
IsSelect2 = false;
IsSelectNum = 0;
}
}
else if (IsSelect3 == true)
{
drawRectangle3.X = mouse.X - currentCharacter3.Width / 2;
drawRectangle3.Y = mouse.Y - currentCharacter3.Width / 2;
//To finally locate figure in the top
if (drawRectangle3.X >= 400 && drawRectangle3.X <= 520 && drawRectangle3.Y <= 15)
{
drawRectangle3.X = 510;
drawRectangle3.Y = 10;
IsSelect3 = false;
IsSelectNum = 0;
}
}
However, something is not quite right here. After I move one rectangle, and want to move another one. But I can not deselect the previous rectangle. What should I change it please?
More update. Thanks dbc, I fix my code like this
I fix the code as this `bool Select1 = true; bool Select2 = true; bool Select3 = true;
int IsSelectNum=0;
//To set the value of IsSelectNum
if ((mouse.X > drawRectangle.X && mouse.X <= drawRectangle.X + currentCharacter.Width
&& mouse.Y >= drawRectangle.Y && mouse.Y <= drawRectangle.Y + currentCharacter.Height)
&& (mouse.LeftButton == ButtonState.Pressed))
{ IsSelectNum = 1; }
else if ((mouse.X > drawRectangle2.X && mouse.X <= drawRectangle2.X + currentCharacter2.Width
&& mouse.Y >= drawRectangle2.Y && mouse.Y <= drawRectangle2.Y + currentCharacter2.Height)
&& (mouse.LeftButton == ButtonState.Pressed))
{ IsSelectNum = 2; }
else if ((mouse.X > drawRectangle3.X && mouse.X <= drawRectangle3.X + currentCharacter3.Width
&& mouse.Y >= drawRectangle3.Y && mouse.Y <= drawRectangle3.Y + currentCharacter3.Height)
&& (mouse.LeftButton == ButtonState.Pressed))
{ IsSelectNum = 3; }
//To choose figure using switch function
switch (IsSelectNum)
{
case 1:
if(Select1){
drawRectangle.X = mouse.X - currentCharacter.Width / 2;
drawRectangle.Y = mouse.Y - currentCharacter.Width / 2;
//To finally locate figure in the top
if (drawRectangle.X <= 70 && drawRectangle.Y <= 15)
{
drawRectangle.X = 50;
drawRectangle.Y = 10;
Select1 = false;
}
}
break;
case 2:
if (Select2)
{
drawRectangle2.X = mouse.X - currentCharacter2.Width / 2;
drawRectangle2.Y = mouse.Y - currentCharacter2.Width / 2;
//To finally locate figure in the top
if (drawRectangle2.X >= 250 && drawRectangle2.X <= 320 && drawRectangle2.Y <= 15)
{
drawRectangle2.X = 280;
drawRectangle2.Y = 10;
Select2 = false;
}
}
break;
case 3:
if (Select3)
{
drawRectangle3.X = mouse.X - currentCharacter3.Width / 2;
drawRectangle3.Y = mouse.Y - currentCharacter3.Width / 2;
//To finally locate figure in the top
if (drawRectangle3.X >= 400 && drawRectangle3.X <= 520 && drawRectangle3.Y <= 15)
{
drawRectangle3.X = 510;
drawRectangle3.Y = 10;
Select3 = false;
}
}
break;
default:
break;
}
`
It seems ok. Any more suggestion please?
回答1:
It's not clear what you are doing here, but in XNA, MouseState is a state variable not an event variable, so mouse.LeftButton == ButtonState.Pressed stays true as long your user is holding the left mouse button down.
If you want to trigger something when the mouse state changes, e.g. on a downclick, you need to remember the previous state and compare it with the current state. For more details, see for instance this article: XNA Mouse Input and Handling.
Incidcentally, your check(s) to see if a rectangle is selected look fishy. The checks treat X and Y asymmetrically, which seems wrong to me even though you did not define any of these objects for us. Maybe the following would work better?
if ((mouse.X >= drawRectangle.X && mouse.X <= drawRectangle.X + currentCharacter.Width
&& mouse.Y >= drawRectangle.Y && mouse.Y <= drawRectangle.Y + currentCharacter.Height)
You should extract this into a proper method, BTW.
回答2:
While @dbc certainly answers your question, I feel like there's more needed.
I would suggest that you create a rectangle every frame, based on the mouse's X/Y coordinates, and the characters Width/Height. That way, you can use the built-in Rectangle.Intersect or Rectangle.Contains methods.
Also make a List of the Rectangles (or whatever you've got them wrapped in. Blocks, Npcs, w/e). Then, make a method that returns the selected model, like such:
public Rectangle? GetSelected(List<Rectangle> squares)
{
Rectangle mousePosition = new Rectangle(mouseX, mouseY, charWidth, charheight);
foreach (var rect in squares)
{
if (rect.Contains(mousePosition))
{
return rect;
}
}
return null;
}
Then check to see if what GetSelected() returns, is null. If it is, the cursor is not currently hovering over anything. However if it's not, you can now move that said Rectangle around, because you have a reference to it.
Note: This won't actually work with Rectangles, due to the fact that a Rectangle is a Structure. And Structures are NOT being transferred by Reference, but by Value. This means that the rectangle you're getting from GetSelected(), will just be a representation of the square you've selected, but not the actual square. Meaning that if you change the X, Y, Width or Height, it wont be changed in the Rectangles in the list.
This is why I personally always recommend having a wrapper around all Structure types, which you have "connected" to anything. Such as a Vector2 for Position. Have this be a property in a "GameObject" class, and always reference the entire class. This way, when you edit the content of Position, it will still be the right GameObject's position that will get changed.
For more information, I strongly suggest BOTH reading more about the differences between structures and classes, as well as playing around with it yourself to see how it works.
来源:https://stackoverflow.com/questions/24415650/moving-rectangles-one-by-one