gpt4 book ai didi

ios - 使用 spritekit 为 2d 平台游戏添加移动平台的轻松进出

转载 作者:搜寻专家 更新时间:2023-11-01 06:32:29 27 4
gpt4 key购买 nike

你好,

我正在使用 spritekit 为 iOS 制作一个 2d 平台游戏。我有移动平台,让我的角色可以随着平台移动。

我不能只使用 skactions 来移动我的平台,因为角色不会随着平台移动。

问题:
我将如何添加缓入和缓出功能以拥有平台???模拟:SKactionTimeMode.easeInEaseOut

当前解决方案:
我面前没有代码,但对于左/右移动平台,这几乎就是我正在做的。这将在平台 update() 方法中运行。

If platform.position.x < xPositionIWantNodeToStopGoingLeft {
velAmount = -velAmount
}
else if platform.position.x > xPositionIWantNodeToStopGoingRight {
velAmount = -velAmount
}
platform.physicsBody?.velocity = SKVector(dx: velAmount, dy: velAmount
platform.position.y = staticYPosition

只是为了澄清,这很好用。如果有更好的方法来做到这一点,我会全力以赴。但这会产生锯齿状的停止和转弯感觉。我想要那种轻松进出的感觉,让平台感觉更自然。

谢谢你的帮助!!!

最佳答案

缓入出功能
如果我们将平台从一侧移动到另一侧的时间视为一个单位(可能是 10 秒或 17 帧,没关系,我们现在以单位工作)。
我们对距离做同样的事情。平台必须在一单位时间内移动一单位距离。
这个回答时间是t位置是时间的函数,写为 f(t)是时间的平台位置t .
对于简单的直线运动,函数就是 f(t)=t .所以在时间t=0移动的距离为 0,在时间 0.5(中途)时,距离为 0.5(中途),依此类推。
所以让我们把它变成更实用的东西。
请原谅我的 swift 我从来没有使用过它(我相信你可以纠正我弄错的任何语法)。

// First normalise the distance and time (make them one unit long)
// get the distance
let distance = Double(xPositionStopGoingLeft - xPositionStopGoingRight);

// use that and the velocity to get the time to travel
let timeToTravel = distance / Double(velAmountX);

// first we have a frame ticker
gameTick += 1; // that ticks for every frame

// We can assume that the platform is always moving back and forth

// Now is the unit time where at now = 2 the platform has move there and back
// at 3 it has move across again and at 4 back again.
let now = Double(gameTick) / timeToTravel; // normalize time.

// get the remainder of 2 as from 0-1 is moving forward and 1-2 is back
let phase = now % 2.0;

// We also need the unit time for the function f(t)=t
let t = abs(phase - 1);
if phase >= 1 { t = 1 - t } // reverse for return

// implement the function f(t) = t where f(t) is dist
let dist = t

// and convert back to pixel distance
platform.position.x = Int(dist * distance + Double(xPositionStopGoingLeft));

这就是线性平台。要改变运动,我们需要做的就是改变函数 f(t)=?。 , 在上面它的行 let dist = t为了便于使用,有一个方便的功能可用于大多数简单的应用程序 f(t) = t * t / ((t * t) + (1 - t) * ( 1 - t))有一些 t*t哪些是权力, t 2 或 t^2 的幂。 swift 其 pow(t,2)所以将上面的代码重写为代码
let dist = pow(t,2) / (pow(t,2) + pow((1-t),2);
这在开始和结束时提供了很好的轻松因为经过的距离和时间是恒定的,中间点的速度 t = 0.5必须更大才能 catch 缓慢的开始和结束。 (旁注,获取上述函数的导数可以让您在每个时间点锻炼速度 f'(t) = speed(t) = 2(-(t-1)t)^(2-1) /(t^2+(1-t)^2)^2 )
这个函数太好了,0.5 时刻的速度是 2,与功率相同(对于线性行程,它是 1)。该函数的一个方便属性是中间点的速度始终与功率相同。如果你想让它在中点移动得非常快,比如快 4 倍,那么你可以使用 4 的幂
让 dist = pow(t,4)/(pow(t,4) + pow((1-t),4);
如果你只想让它加速一点,比如中心速度的 1.2 倍,那么功率是 1.2
let dist = pow(t,1.2) / (pow(t,1.2) + pow((1-t),1.2);   
所以现在我们可以引入另一个术语, maxSpeed这是归一化的 maxSpeed (更准确地说,它是 t=0.5 时的速度,因为它可能比 1 慢,但我们需要最大速度)
let maxSpeed = Double(velAmountX + 3) / Double(velAmountX); // 3 pixels per frame faster
和函数 f(t) = t^m / (t^m + (1-t)^m)其中 m 是 maxSpeed .
并作为代码
让 dist = pow(t,maxSpeed )/(pow(t,maxSpeed ) + pow((1-t),maxSpeed);
所以把它们放在一起
// the next 3 lines can be constats
let distance = Double(xPositionStopGoingLeft - xPositionStopGoingRight);
let timeToTravel = distance / Double(velAmountX);
let maxSpeed = Double(velAmountX + 3) / Double(velAmountX);

gameTick += 1; // that ticks for every frame

let now = Double(gameTick) / timeToTravel; // normalize time.
let phase = now % 2.0;
let t = abs(phase - 1);
if phase >= 1 { t = 1 - t } // reverse for return

// the next line is the ease function
let dist = pow(t, maxSpeed) / (pow(t, maxSpeed) + pow((1-t) ,maxSpeed);

// position the platform
platform.position.x = Int(dist * distance + Double(xPositionStopGoingLeft));
现在您可以在任何刻度上计算平台的位置。如果您想减慢整个游戏的速度并将帧步进到一半,它仍然可以工作。如果你加快游戏速度 gameTick += 2它仍然有效。
最大速度也可以低于线速度。如果您希望平台在中心位置为正常速度的一半 t=0.5套装 maxSpeed = 0.5在中途点,速度将减半。为了让一切工作在开始和结束时轻松自如,冲进冲出会更快。 (也适用于反向)
帮助也许是一个视觉表示
enter image description here
图像显示了平台随着时间的推移来回移动。距离约为60像素,时间可以是1分钟。因此,在 1 分钟时,它将是右侧的 2 分钟,在左侧,依此类推。
然后我们通过只看一个部分的运动来标准化运动和时间。
enter image description here
该图表示从左到右的移动,距离为 1,时间为 1。它刚刚被缩放以适合单位框(1 x 1 框)。
红线代表直线运动 f(t)=t (恒定速度)。在任何时间点,您越过击中线向下移动,您可以找到行进的距离。
绿线代表缓动功能 f(t)=t*t/(t*t+(1-t)*(1-t))它的工作原理相同。在任何时间点扫描以找到绿线并向下移动以获得距离。函数 f(t) 为你做这件事。
使用 maxSpeed,dist 0.5 处的线的陡度会发生变化,更陡峭的坡度代表更快的行驶。

关于ios - 使用 spritekit 为 2d 平台游戏添加移动平台的轻松进出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45282678/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com