向上和向下缩放精灵以产生跳跃的错觉

时间:2013-12-01 07:08:23

标签: c# xna scale sprite monogame

我有一些我编写的代码可行,但我觉得它可能会更好,并希望得到一些反馈。

我的目标是在按下按钮时及时按下Sprite Scale并及时退回,以便在游戏的“自上而下”视图中提供跳跃的幻觉。就像角色跳出屏幕一样。我已经知道如何绘制缩放图像我对时序方面的逻辑更感兴趣。

这很有效,只是不确定它是最好的。想想也许有一些方程,一个数学朋友告诉我可能是一个线性方程或像抛物线或二阶方程。数学不太好。

反正。

类属性

private double _jumpingStartedAt;
private double _totalJumpTimeInSeconds = 0.7;
private double _totalJumpFrames = 14;
private double _timeSinceLastScale;
private double _jumpingHalfWayAt;

第一次按下按钮时,我启动“跳转逻辑”。每次跳跃运行一次。我的想法是,我将标记“开始”时间,并通过totalJumpTimeInSeconds确定“中途”时间。

_jumpingStartedAt = gameTime.TotalGameTime.TotalSeconds;
_jumpingHalfWayAt = _jumpingStartedAt + MillisecondsBetweenFrame() * (_totalJumpFrames / 2);

然后在每个Update()上运行此操作,直到我的“跳转”完成或isJumping = false。这里的逻辑是我将每1个“帧”向上扩展,直到中间点然后缩小。

_timeSinceLastScale += gameTime.ElapsedGameTime.TotalSeconds;
if (_timeSinceLastScale > MillisecondsBetweenFrame() && gameTime.TotalGameTime.TotalSeconds < _jumpingHalfWayAt)
{
     Scale += 0.2f;
     _timeSinceLastScale = 0;
}
else if (gameTime.TotalGameTime.TotalSeconds > _jumpingHalfWayAt)
{
     Scale -= 0.2f;
     if (Scale < 1.0) Scale = 1; //probably don't need this was worried if it went passed 0
     if (Scale == 1.0) _isJumping = false;
}

private double SecondsBetweenFrame()
{
    return _totalJumpTimeInSeconds / this._totalJumpFrames;
}

现在这个有效,但对我来说似乎有点费解。

1 个答案:

答案 0 :(得分:2)

跳跃时拉伸图像 - 侧视图

是的,它非常复杂,你创造了什么。

我认为你的精灵在跳跃时也会上下移动。您有某种Vector2 velocity,在每次更新时都会更改dv = gravityAcceleration * dt,因此您需要Vector2 position更改dp = velocity * dt。如果是这样,我宁愿使用我的velocity.Y值来计算精灵应该如何伸展。我认为这更自然。而且您的代码将变得更加简单。

这是一张更好地描述我的意思的图片:

Jump

然而,你可能在这里遇到另一个问题:只是在跳跃开始时你的精灵会突然变得高速,当仍然靠近地面时,这会导致它在地板上穿过一会儿。为了防止你可以人为地将你的精灵向上移动所需的最小跳跃时间值。问题由下图描述:

Floor crossing

你可以很好地看到,第一个伸展的球向上移动了一点,但还不够。您必须计算拉伸前后尺寸之间的差异,然后将精灵向上移动该距离。

如果你这样做,你的Update应该缩短到几行。我相信你可以自己做简单的计算。


更容易接近

...除非你喜欢你的精灵表现得像想要的那样。然后你可以根据你的Y位置修改比例:

if (KeyboardState.IsKeyDown(Keys.Space))
{
    isJumping = true;
    jumpStartPosition = Position;        
}

if (!isJumping) Scale = 1f;
else 
{
    Scale = StretchFactor * (Position.Y - jumpStartPosition.Y);
}

其中: - isJumpingbool, - jumpStartPositionVector2, - Position是精灵的Vector2属性, - StretchFactor是精灵的float属性,告知它有多长。

并且您还需要具有跳转结束条件 - 例如,当精灵的Position.Y变得小于jumpStartPosition.Y时。但一般来说这个解决方案(以及你的解决方案)都有一个缺点 - 如果你想从一个高度开始跳转并在另一个高度结束它会有问题:

enter image description here

所以我宁愿推荐我的第一个解决方案。在那里你可以通过碰撞检查制作停止跳跃条件。


跳跃时拉伸图像 - 自上而下视图

无赖。由于最初并没有指明它是一个自上而下的游戏,就像那些第一个GTA一样,我真的误解了这个问题,所以答案并不合适。所以答案就是现在。

如果你想要现实,你应该使用一些基本的透视原则。当我们看到从顶部跳跃的角色时,它会更接近我们,因此它的图像会增长。为什么?请看下面的图片。

Jump

透视工作需要两件事:透视中心和屏幕。透视中心是一个点,所有&#34;射线&#34;正在穿越。 &#34;雷&#34;是从世界上任何一点到我们眼睛中心的一条线。现在屏幕是飞机,正在创建3D世界的图像。现实世界的各点正沿着光线投射到屏幕上。当然你的游戏是伪3d游戏,但在这种情况下它并不重要。

z 增长时,精灵更接近透视中心。如果你想象从透视中心射线到精灵的边缘,光线的角度会改变,因为它与透视中心的距离会变小。并且角度的改变使得屏幕上的点图像移动。这就是图像增长或变小的原因。

现在我们可以想知道:好吧,现在怎么把它变成数字?请看下面的图片:

Perspective

我故意通过 -C 翻译整个世界,因此透视中心的 z 坐标可能变为0.这使得计算更简单。我们试图找到的是 x&#39; - 屏幕上点的坐标。设Z * = | z - C |。如果我们看一下这张照片就很清楚,我们可以通过非常简单的比例找到我们需要的东西:

Calculations

使用相同的方法,您可以计算 y&#39; 。如果您的角色始终位于屏幕的中心,那么您需要的只是 x&#39; / x = y&#39; / y = S ,即您的比例。这是因为在这种情况下 x 实际上是精灵的半宽,而 y 是半高。但是,如果你的角色能够在屏幕上自由移动,你可能需要扩展和扩展。翻译它,所以它会更自然:

Scale + translate

白色方块是地面精灵,灰色方块是跳跃精灵。在这种情况下,您必须知道 l (左), r (右), t (顶部)和 b (底部)精灵边界的坐标(上下指Y轴,而不是Z轴)。然后使用相同的比例,你可以得到 l&#39; r&#39; t&#39; b&#39 ; - 精灵在屏幕上的图像边界。从这些数据中,您应该能够计算出尺度和平移。

注意: L 是我们计算的参数,您必须自己选择。假设屏幕具有恒定宽度 Ws 和高度 Hs L 严格对应于 FOV (视野) )。您也可以使用比例获取它。所以 L =(cos( FOV / 2)* Ws )/ 2。我建议 FOV = 60度。如果你将FOV设得太大,你可能会遇到fisheye问题。