XNA 中的滚动屏幕 - 简化数学(轻拂手势)
我一直在来回尝试,但我无法计算出在使用轻弹手势时如何滚动视图(或者更确切地说偏移所有对象)的数学原理。我希望滚动有某种缓出效果。
public override void Update(GameTime gameTime, bool otherScreenHasFocus, bool coveredByOtherScreen)
{
float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds;
//Some math to change 'matrixOffsetY'
//I use 'matrixOffsetY' to offset my objects in Draw()
base.Update(gameTime, otherScreenHasFocus, coveredByOtherScreen);
}
这是手势事件
public override void HandleInput(InputState input)
{
if (input == null)
throw new ArgumentNullException("input");
while (TouchPanel.IsGestureAvailable)
{
GestureSample gesture = TouchPanel.ReadGesture();
switch (gesture.GestureType)
{
case GestureType.Flick:
{
//Set a variable with some math? Using:
//gesture.Delta
//gesture.Delta gives us pixels/sec
break;
}
default: return;
}
}
}
这应该不难,但我脑子冻结了:) 请帮帮我!
I've been trying back and forth, but I can't figure out the math on how to scroll my view (or rather offset all objects) when using the flick gesture. I would like the scrolling to have some kind of ease-out.
public override void Update(GameTime gameTime, bool otherScreenHasFocus, bool coveredByOtherScreen)
{
float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds;
//Some math to change 'matrixOffsetY'
//I use 'matrixOffsetY' to offset my objects in Draw()
base.Update(gameTime, otherScreenHasFocus, coveredByOtherScreen);
}
Here's the gesture event
public override void HandleInput(InputState input)
{
if (input == null)
throw new ArgumentNullException("input");
while (TouchPanel.IsGestureAvailable)
{
GestureSample gesture = TouchPanel.ReadGesture();
switch (gesture.GestureType)
{
case GestureType.Flick:
{
//Set a variable with some math? Using:
//gesture.Delta
//gesture.Delta gives us pixels/sec
break;
}
default: return;
}
}
}
This shouldn't be that hard, but I have a brain-freeze :) Please help me out!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您可以在两个值之间进行“lerp”(线性插值)以逐渐接近(快速开始,缓慢结束)。
我假设你正在二维滚动。所以该位置是一个 Vector2。
尝试这样的事情:
You can "lerp" (linear interpolate) between two values to gradually get closer (starting fast, ending slowly).
I assume you're scrolling in 2D. So the position is a Vector2.
Try something like this:
我假设你所说的“缓出”的意思是它逐渐做它应该做的事情(我不太清楚(我对触摸屏和手势不太了解)。
有几种方法可以做到这一点。你可以采用物理方法并使用牛顿定律并简单地求解微分方程,
我通常做这样的事情(例如用鼠标滚动窗口时逐渐停止)的方法是简单地使用带有参数的函数逐渐降低速度。我可以修改以获得我想要的感觉。
在你的情况下,我已经明白你想要做什么,你只是想根据速度更新位置
(通常你会这样做) 。对于 2D),
X_new = X_old + 速度*dt
velocity = max(0,velocity*0.95 - 0.2)
它的作用是逐渐移动 x 坐标(每次循环时 X_old 都会变成 X_new(通常在线程中执行)),这样它就不会完全停止,而是继续移动直到速度达到零。我使用一个简单的 pow 函数来逐渐减少它,但你可以想出任何类型的函数。
您实际上还可以考虑指针到边缘的距离。我在我的一个程序中这样做,这样当鼠标光标移离边缘时,它滚动的速度取决于多远(所以如果你想滚动一点,你就移动一点,如果你想移动很多,你就移动很多)。
请注意,您必须在线程中处理此问题,可能是因为它会持续发生。您还可以计算加速度并使用简单的物理原理来计算基于它的位置。 x = x0 + x'*t + 1/2*x''*t^2 类型的东西。
I assume you mean by "ease out" that it gradually does what it's suppose to do(which I'm not quite clear on(I don't know much about touchpanels and gestures).
There are several ways to do this. You could take a physical approach and use newton's law and simply solve the differential equation.
The way I generally do things like this(such as a gradual stop when scrolling a window with the mouse), is to simply reduce the speed gradually using some function with parameters that I can modify to get the feel I want.
In your case, I've I get what you trying to do, you simply want to update the position based on the velocity.
Suppose your doing it horizontally(in generally you'll do it for 2D),
X_new = X_old + velocity*dt
velocity = max(0, velocity*0.95 - 0.2)
What this does is gradually move the x coordinate(X_old becomes X_new each time through the loop(which you'll usually do in a thread)) so that instead of stopping completely it continues to move until velocity has reached zero. I use a simple pow function to gradually reduce it but you can come up with any type of function.
You can also actually take into account the distance of the pointer to the edge. I do this in one of my programs so that when the mouse cursor is moved off the edge the speed it scrolls depends on how far(so if you wanna scroll a little you move a little and a lot you move a lot).
Be aware you'll have to handle this in a thread probably because it is something that continues to happen. You could also compute the acceleration and use the simple physics to compute the position based on it. x = x0 + x'*t + 1/2*x''*t^2 type of stuff.
和往常一样,如果是 XNA,Shawn 可能已经解决了您的问题。在几篇文章中,他使用 Lerp、SmoothStep 和其他数学运算,以及 基于物理的方法。这些示例使用游戏状态管理项目,但这些想法可以在任何地方使用。
顺便说一句,您可能需要考虑不要相对于相机移动所有对象。您可以将向量2或向量3的cameraOffset存储在某处,并在SpriteBatch.Begin中使用transformMatrix。当然,如果您使用一两个 spritebatch 循环来绘制所有世界对象,则这是最有用的。
As usual, if it's XNA, Shawn has probably solved your problem already. In a couple of posts he explains transitions using Lerp, SmoothStep and other math operations, and a physics based approach. The examples use the Game State Management project, but the ideas can be used anywhere.
And, by the way, you might want to consider not moving all the objects around relative to the camera. You can store a vector2 or vector3 cameraOffset somewhere and use a transformMatrix in SpriteBatch.Begin. Of course, this is most useful if you use one or two spritebatch cycles to paint all your world objects.