我正在尝试创建一个由操纵杆右拇指操纵杆控制的简单鼠标模拟器。我试图让鼠标朝着棒指向的方向移动,压力值的平滑梯度决定了速度,但是在尝试这样做时我遇到了许多障碍。
首先是如何准确地将角度转换为准确的X和Y值。我找不到正确实施角度的方法。我拥有它的方式,对角线可能比红衣主教快得多。 我认为我需要像X值的Math.Cos(角度),以及Y值的Math.Sin(角度)来增加鼠标,但我想不出设置它的方法。
第二,鼠标运动平稳,这可能是两者中更重要的一个。由于SetPosition()函数仅适用于整数,因此像素随时间移动的速率似乎非常有限。我的代码非常基本,只记录1-10的整数值。这不仅会在加速时产生小的“跳跃”,还会限制对角线的移动。 目标是每秒10像素,程序运行100hz,每个周期输出0.1像素。
我想我可以跟踪X和Y值的像素'小数',并在它们构建为整数时将它们添加到轴上,但我想有一种更有效的方法这样做仍然不会激怒SetPosition()函数。
我觉得Vector2对象应该完成这个,但我不知道角度是如何适应的。
示例代码:
//Poll Gamepad and Mouse. Update all variables.
public void updateData(){
padOne = GamePad.GetState(PlayerIndex.One, GamePadDeadZone.None);
mouse = Mouse.GetState();
currentStickRX = padOne.ThumbSticks.Right.X;
currentStickRY = padOne.ThumbSticks.Right.Y;
currentMouseX = mouse.X;
currentMouseY = mouse.Y;
angle = Math.Atan2(currentStickRY, currentStickRX);
vectorX = (int)( currentStickRX*10 );
vectorY = (int)( -currentStickRY*10 );
mouseMoveVector.X = vectorX;
mouseMoveVector.Y = vectorY;
magnitude = Math.Sqrt( Math.Pow( (currentStickRX - 0), 2 ) + Math.Pow( (currentStickRY - 0), 2 ) );
if (magnitude > 1){
magnitude = 1;
}
//Get values not in deadzone range and re-scale them from 0-1
if(magnitude >= deadZone){
activeRange = (magnitude - deadZone)/(1 - deadZone);
}
Console.WriteLine(); //Test Code
}
//Move mouse in in direction at specific rate.
public void moveMouse(){
if (magnitude > deadZone){
Mouse.SetPosition( (currentMouseX + vectorX), (currentMouseY + vectorY));
}
previousStickRX = currentStickRX;
previousStickRY = currentStickRY;
previousActiveRange = activeRange;
}
注意:我正在使用所有xna框架。
无论如何,如果我不正确地解释这些事情,请道歉。我无法为此找到一个好的资源,我搜索的矢量示例只以整数增量和从A点到B点移动。
非常感谢任何部分的帮助。
答案 0 :(得分:1)
我自己没有尝试过,但是从我的观点来看,你应该在读取它们之后对垫轴进行标准化,这样对角线的移动速度就和红衣主教一样。对于第二部分,我会在浮动变量中跟踪鼠标,例如Vector2,并在设置鼠标位置时进行转换(可能更好地舍入)。
public void Start()
{
mousePosV2 = Mouse.GetState().Position.ToVector2();
}
public void Update(float dt)
{
Vector2 stickMovement = padOne.ThumbSticks.Right;
stickMovement.Normalize();
mousePosV2 += stickMovement*dt*desiredMouseSpeed;
/// clamp here values of mousePosV2 according to Screen Size
/// ...
Point roundedPos = new Point(Math.Round(mousePosV2.X), Math.Round(mousePosV2.Y));
Mouse.SetPosition(roundedPos.X, roundedPos.Y);
}