C# 鼠标移动:单击“精灵”;“步行”;点击指向
我对C#和XNA非常陌生,编程也很好(就像我可以学习教程一样,但我自己创建它的大部分过程仍然非常困难)。现在,我正在周而复始地试图找出如何做这件“简单”的事情 这里的想法,这将是一个塔防游戏;现在我正在做基本的工作。我有一个小精灵,他会用键盘输入移动,现在我想点击屏幕上的某个地方,让他“走”到那个点。只是我不懂逻辑。我可以按一下,他会跟着我跳过去C# 鼠标移动:单击“精灵”;“步行”;点击指向,c#,mouse,user-input,game-physics,C#,Mouse,User Input,Game Physics,我对C#和XNA非常陌生,编程也很好(就像我可以学习教程一样,但我自己创建它的大部分过程仍然非常困难)。现在,我正在周而复始地试图找出如何做这件“简单”的事情 这里的想法,这将是一个塔防游戏;现在我正在做基本的工作。我有一个小精灵,他会用键盘输入移动,现在我想点击屏幕上的某个地方,让他“走”到那个点。只是我不懂逻辑。我可以按一下,他会跟着我跳过去 if (aMouse.LeftButton == ButtonState.Pressed) { Position.X = aMouse.X;
if (aMouse.LeftButton == ButtonState.Pressed)
{
Position.X = aMouse.X;
Position.Y = aMouse.Y;
}
从我读到的关于其他鼠标输入的内容来看,我想我需要某种循环(可能是bool?)将精灵移动到一个方向,并且必须运行一个检查,看看他是否达到了那个点。但是,在鼠标单击并创建循环、运行检查之后获得该点……我不知道。您需要添加一些实例变量:
Point2D targetPos;
还有一些常数:
const Point2D speed;
运行Update()循环时,通过向当前位置添加速度向量(当然方向正确)来更新当前位置,直到距离目标位置在预定义阈值内(通常根据速度向量计算阈值-如果从当前位置到目标位置的距离小于速度向量的长度,则您处于您的位置)。在这种情况下,使用布尔值会很好。单击鼠标时,设置另一个实例变量(移动)设置为true,一旦到达目标位置,请将“移动”设置为false。我假设您有三件事:
// dx, dy are delta x and delta y. It's how far in each direction
// the player must travel
// note, I fixed a typo where they were desired - desired... should be
// desired - current, as they are now
float dx = desiredX - currentX;
float dy = desiredY - currentY;
// d uses the pythagorean theorum to find the distance between current and desired
float d = sqrt(dx*dx + dy*dy);
// fac is how far along that line between desired and current will you move
float fac = d / speed;
// mx is the component of the dx line proportional to the size of fac : d
// which means it's how far in the x direction you'll move
float mx = dx * fac;
float my = dy * fac;
// the new postition is the old position plus the move value
float newPositionX = dx + mx;
float newPositionY = dy + my;
人们回答你的问题的层次很低。有时从更高的层次思考问题会有所帮助 你需要的是一种状态管理。计算机科学中的术语是有限状态机。但现在不要费心去查它。一开始它相当枯燥和混乱:) 你的角色目前有一种状态——“站着”。您需要添加并处理“步行到目的地”状态 从我读到的其他鼠标输入,我想我需要某种循环 你需要一个循环,叫做游戏循环。如果您正在使用XNA,您已经有了一个。但你走对了方向 每次通过游戏循环时,您都应该处理当前状态,并检查所谓的状态转换。当你把你的世界从一个状态改变到另一个状态时。例如,当你单击鼠标时,你希望这个家伙开始移动 在您的游戏循环中,您检查鼠标单击是否刚刚发生。如果有,则设置一些数据(移动到哪里),并通过将其状态设置为“步行到目的地”来告诉他开始步行。下一次更新,您将处理该状态 当您的角色处于“步行到指定”状态时,您需要根据上次游戏更新后经过的时间量更新其位置。在XNA中,这是为您计算的。如果您没有使用XNA,那么您必须检查自己。您可以使用类似于
Stopwatch
类的内容,并检查appead
字段
如果角色位于目的地,则需要将其切换回“原地不动”状态
如果您收到另一次鼠标单击,则由您决定是否希望“步行到目的地”状态关注它。如果您确实注意到了这一点,那么设置的数据类型与从“原地不动”状态转换时的数据类型相同
因此,您需要以下变量:
Point2D targetPos;
- 计时器,用于查找自上次游戏循环以来经过的时间(XNA提供给您)
- 当前播放机状态(可能是
)enum
- 当前播放机位置(向量)
- 玩家的行走速度(可能是一个浮子),以每秒(或毫秒)单位测量
- “步行到目的地”状态的数据-目标位置(另一个向量)
- 与用户输入相关的数据(自上次更新以来发生的鼠标事件、这些单击的位置等)
我不会讨论向量数学,因为其他人已经讨论了如何计算部分运动。重复这些答案毫无意义。它基本上可以归结为在你的当前位置和目标位置之间建立一个向量,并将其乘以/除以你的行走速度(将其切割到一次更新中移动的距离)。我发现这段代码非常有用。。。此外,我还额外添加了几行代码,以防止某些情况发生。例如,有时方向为0.83,速度可能会因地形/天气等游戏因素而改变。。。。如果速度低于1,精灵可能根本不会移动,甚至移动方向错误
if (Vector2.Distance(Position, TargetPosition) > 2.0f)
{
velocity = Vector2.Subtract(TargetPosition, Position);
velocity.Normalize();
/// Now no matter which direction we are going we are always moving @ sprite.Speed
/// at velocity or speed below 1 - problems occur where the unit may not move at all!!
if(current_Speed < 1)
{
Vector2 temp = (velocity * 10) * (current_Speed * 10);
Position += temp / 10;
}
else
{
Vector2 temp = velocity * current_Speed;
Position += temp;
}
//convert to int to render sprite to pixel perfect..
Position = new Vector2((int)Position.X, (int)Position.Y);
}
if(矢量2.距离(位置,目标位置)>2.0f)
{
速度=矢量2。减去(目标位置,位置);
速度。归一化();
///现在,无论我们朝哪个方向前进,我们都在移动@sprite.Speed
///在速度或速度低于1时-如果装置可能根本不移动,则会出现问题!!
如果(当前速度<1)
{
矢量2温度=(速度*10)*(当前速度*10);
位置+=温度/10;
}
其他的
{
矢量2温度=速度*