我的角色Sprite Node在移动时晃动,为什么?
My character's SpriteNode is shaking when moving, why?
我的主角是一个带有physicsBody的SKSpriteNode,在移动或跳跃时会晃动。
我是通过改变character.physicsBody.velocity.dx
来移动我的角色(为了模拟加速或减速),我用applyImpulse
让他跳起来。
代码:
移动:
[self.physicsBody setVelocity:CGVectorMake(self.physicsBody.velocity.dx - 30, self.physicsBody.velocity.dy)];
跳转:
if (!isJumping)
{
[self.physicsBody applyImpulse:CGVectorMake(0.0f, 6.0f)];
}
此外,我使用了网上找到的一种方法,改变地图上的相机位置,从而跟随角色:
- (void)setViewpointCenter:(CGPoint)position
{
NSInteger x = MAX(position.x, self.size.width / 2);
NSInteger y = MAX(position.y, self.size.height / 2);
x = MIN(x, (self.map.mapSize.width * self.map.tileSize.width) - self.size.width / 2);
y = MIN(y, (self.map.mapSize.height * self.map.tileSize.height) - self.size.height / 2);
CGPoint actualPosition = CGPointMake(x, y);
CGPoint centerOfView = CGPointMake(self.size.width/2, self.size.height/2);
CGPoint viewPoint = CGPointSubtract(centerOfView, actualPosition);
self.map.position = viewPoint;
}
结果 ?
Here it is(从 iPhone 5 使用 QuickTime 录制)。您可以很容易地看到这个视频中的问题,以及这让我(以及我刚刚开始开发的游戏)头疼的程度。
的确,经常(不是每次,有时是完美的)像鬼一样,他变得模糊。我什么都不懂,我找不到任何解决方案。
我在模拟器和我的设备上都试过了,效果一样。
如果你愿意,我可以post更多代码,并且可以告诉你一切,我希望有人能找到我哪里做错了!
提前致谢!
保罗
编辑 1 :
感谢您的意见!
我在屏幕上显示了 8 个绘图,145 个节点,物理方面没有出现真正的问题!
要将我的角色向左移动,我只是 运行 :
-(void)moveToLeft
{
if (isJumping && isOnRightSide)
{
[self.physicsBody setVelocity:CGVectorMake(-self.physicsBody.velocity.dx / 2.0, self.physicsBody.velocity.dy)];
}
[self setIsOnRightSide:NO];
[self setIsStopping:NO];
[self setIsRunning:YES];
[self.physicsBody setVelocity:CGVectorMake(self.physicsBody.velocity.dx - 30, self.physicsBody.velocity.dy)];
}
右边:
-(void)moveToRight
{
if (isJumping && !isOnRightSide)
{
[self.physicsBody setVelocity:CGVectorMake(self.physicsBody.velocity.dx / 2.0, self.physicsBody.velocity.dy)];
}
[self setIsStopping:NO];
[self setIsOnRightSide:YES];
[self setIsRunning:YES];
[self.physicsBody setVelocity:CGVectorMake(self.physicsBody.velocity.dx + 30, self.physicsBody.velocity.dy)];
}
然后:
if (_isStopping)
{
if (isOnRightSide)
{
int ralentissement = MIN(self.physicsBody.velocity.dx, 10);
[self.physicsBody setVelocity:CGVectorMake(self.physicsBody.velocity.dx - ralentissement, self.physicsBody.velocity.dy)];
}
else
{
int ralentissement = MAX(self.physicsBody.velocity.dx, -10);
[self.physicsBody setVelocity:CGVectorMake(self.physicsBody.velocity.dx - ralentissement, self.physicsBody.velocity.dy)];
}
if (abs(self.physicsBody.velocity.dx) < 1)
{
isRunning = NO;
_isStopping = NO;
if (self.hasActions)
[self removeAllActions];
[self.physicsBody setVelocity:CGVectorMake(0, self.physicsBody.velocity.dy)];
}
}
if (isOnRightSide && isRunning && self.physicsBody.velocity.dx < 150 && !_isStopping)
{
[self.physicsBody setVelocity:CGVectorMake(self.physicsBody.velocity.dx + 10, self.physicsBody.velocity.dy)];
}
else if (!isOnRightSide && isRunning && self.physicsBody.velocity.dx > -150 && !_isStopping)
{
[self.physicsBody setVelocity:CGVectorMake(self.physicsBody.velocity.dx - 10, self.physicsBody.velocity.dy)];
}
if (abs(self.physicsBody.velocity.dx) > 150)
{
if (isOnRightSide)
[self.physicsBody setVelocity:CGVectorMake(150, self.physicsBody.velocity.dy)];
else
[self.physicsBody setVelocity:CGVectorMake(-150, self.physicsBody.velocity.dy)];
}
有没有更好的加减速不断加力的方案?
我检查了我所有的图片,它们的尺寸都一样!
我关闭了相机功能,确实抖动停止了!所以这个功能一定是错误的部分,我在raywenderlich上找到了,我不知道如何我可以代替它。你知道如何 ?谢谢!
编辑 2 :
所以,我尝试将我的相机移动方法的调用移动到 didFinishUpdate,并且它确实更好!这种颤抖的感觉消失了,我现在可以在没有那种糟糕经历的情况下玩耍了。
但是 当角色跳跃时还有一件事发生(这要归功于 applyForce
方法):当他在上升时,他似乎仍然有时会下降,这里或那里只有 1 个像素。它非常特别,我不知道是 Sprite Kit 的真正问题,还是我的纹理太大或其他任何问题。我试着看一下绘制物理体的动画,实际上有一些垂直晃动(更确切地说,蓝色矩形似乎在闪烁)。
你对上一期有什么想法吗?
横向移动完美,谢谢大家的帮助。
我遇到了同样的问题(也遵循了 ray 的教程).. 你通过跟随你的角色来使相机动画,这看起来真的很酷,但它会导致卡顿。世界在朝一个方向移动,而角色在朝相反的方向移动,就像跑步机一样,这会导致角色口吃。在雷目前的书中,他做了:
override func didSimulatePhysics() {
let target = getCenterPointWithTarget(player.position)
worldNode.position += (target - worldNode.position) * 0.1
我确定这与您所做的非常相似,对吧?这使得 worldNode 不断地试图赶上玩家的动作。它给了相机那种弹性的感觉。
试着去
worldNode.position = getCenterPointWithTarget(player.position)
如果这解决了问题,那么我们会进一步缩小范围。这里的问题是你失去了很酷的相机缓动效果。
问题是我不知道你在哪里对球员的动作做出改变。我不知道这些是否只是你调用的一次性方法,或者它们 运行你的更新循环。
我将举例说明我在游戏中的做法:
在更新中:
// update ship position
ship.update(self.delta)
我在 didFinishUpdate 中移动了屏幕,所以我确保这是最后发生的事情。希望这会停止任何口吃。
didFinishUpdate
override func didFinishUpdate() {
// move BG Nodes
self.moveBGNodes()
}
moveBGNodes 方法
func moveBGNodes(){
// method that calculates camera position (stops camera at screen edges)
let target = self.pointToCenterViewOn(ship.position)
// ease gameworld into ship's position
gameLayer.position += (target - gameLayer.position) * 0.1
我的主角是一个带有physicsBody的SKSpriteNode,在移动或跳跃时会晃动。
我是通过改变character.physicsBody.velocity.dx
来移动我的角色(为了模拟加速或减速),我用applyImpulse
让他跳起来。
代码:
移动:
[self.physicsBody setVelocity:CGVectorMake(self.physicsBody.velocity.dx - 30, self.physicsBody.velocity.dy)];
跳转:
if (!isJumping)
{
[self.physicsBody applyImpulse:CGVectorMake(0.0f, 6.0f)];
}
此外,我使用了网上找到的一种方法,改变地图上的相机位置,从而跟随角色:
- (void)setViewpointCenter:(CGPoint)position
{
NSInteger x = MAX(position.x, self.size.width / 2);
NSInteger y = MAX(position.y, self.size.height / 2);
x = MIN(x, (self.map.mapSize.width * self.map.tileSize.width) - self.size.width / 2);
y = MIN(y, (self.map.mapSize.height * self.map.tileSize.height) - self.size.height / 2);
CGPoint actualPosition = CGPointMake(x, y);
CGPoint centerOfView = CGPointMake(self.size.width/2, self.size.height/2);
CGPoint viewPoint = CGPointSubtract(centerOfView, actualPosition);
self.map.position = viewPoint;
}
结果 ?
Here it is(从 iPhone 5 使用 QuickTime 录制)。您可以很容易地看到这个视频中的问题,以及这让我(以及我刚刚开始开发的游戏)头疼的程度。
的确,经常(不是每次,有时是完美的)像鬼一样,他变得模糊。我什么都不懂,我找不到任何解决方案。
我在模拟器和我的设备上都试过了,效果一样。
如果你愿意,我可以post更多代码,并且可以告诉你一切,我希望有人能找到我哪里做错了!
提前致谢!
保罗
编辑 1 :
感谢您的意见!
我在屏幕上显示了 8 个绘图,145 个节点,物理方面没有出现真正的问题!
要将我的角色向左移动,我只是 运行 :
-(void)moveToLeft {
if (isJumping && isOnRightSide)
{
[self.physicsBody setVelocity:CGVectorMake(-self.physicsBody.velocity.dx / 2.0, self.physicsBody.velocity.dy)];
}
[self setIsOnRightSide:NO];
[self setIsStopping:NO];
[self setIsRunning:YES];
[self.physicsBody setVelocity:CGVectorMake(self.physicsBody.velocity.dx - 30, self.physicsBody.velocity.dy)];
}
右边:
-(void)moveToRight
{
if (isJumping && !isOnRightSide)
{
[self.physicsBody setVelocity:CGVectorMake(self.physicsBody.velocity.dx / 2.0, self.physicsBody.velocity.dy)];
}
[self setIsStopping:NO];
[self setIsOnRightSide:YES];
[self setIsRunning:YES];
[self.physicsBody setVelocity:CGVectorMake(self.physicsBody.velocity.dx + 30, self.physicsBody.velocity.dy)];
}
然后:
if (_isStopping)
{
if (isOnRightSide)
{
int ralentissement = MIN(self.physicsBody.velocity.dx, 10);
[self.physicsBody setVelocity:CGVectorMake(self.physicsBody.velocity.dx - ralentissement, self.physicsBody.velocity.dy)];
}
else
{
int ralentissement = MAX(self.physicsBody.velocity.dx, -10);
[self.physicsBody setVelocity:CGVectorMake(self.physicsBody.velocity.dx - ralentissement, self.physicsBody.velocity.dy)];
}
if (abs(self.physicsBody.velocity.dx) < 1)
{
isRunning = NO;
_isStopping = NO;
if (self.hasActions)
[self removeAllActions];
[self.physicsBody setVelocity:CGVectorMake(0, self.physicsBody.velocity.dy)];
}
}
if (isOnRightSide && isRunning && self.physicsBody.velocity.dx < 150 && !_isStopping)
{
[self.physicsBody setVelocity:CGVectorMake(self.physicsBody.velocity.dx + 10, self.physicsBody.velocity.dy)];
}
else if (!isOnRightSide && isRunning && self.physicsBody.velocity.dx > -150 && !_isStopping)
{
[self.physicsBody setVelocity:CGVectorMake(self.physicsBody.velocity.dx - 10, self.physicsBody.velocity.dy)];
}
if (abs(self.physicsBody.velocity.dx) > 150)
{
if (isOnRightSide)
[self.physicsBody setVelocity:CGVectorMake(150, self.physicsBody.velocity.dy)];
else
[self.physicsBody setVelocity:CGVectorMake(-150, self.physicsBody.velocity.dy)];
}
有没有更好的加减速不断加力的方案?
我检查了我所有的图片,它们的尺寸都一样!
我关闭了相机功能,确实抖动停止了!所以这个功能一定是错误的部分,我在raywenderlich上找到了,我不知道如何我可以代替它。你知道如何 ?谢谢!
编辑 2 :
所以,我尝试将我的相机移动方法的调用移动到 didFinishUpdate,并且它确实更好!这种颤抖的感觉消失了,我现在可以在没有那种糟糕经历的情况下玩耍了。
但是 当角色跳跃时还有一件事发生(这要归功于 applyForce
方法):当他在上升时,他似乎仍然有时会下降,这里或那里只有 1 个像素。它非常特别,我不知道是 Sprite Kit 的真正问题,还是我的纹理太大或其他任何问题。我试着看一下绘制物理体的动画,实际上有一些垂直晃动(更确切地说,蓝色矩形似乎在闪烁)。
你对上一期有什么想法吗?
横向移动完美,谢谢大家的帮助。
我遇到了同样的问题(也遵循了 ray 的教程).. 你通过跟随你的角色来使相机动画,这看起来真的很酷,但它会导致卡顿。世界在朝一个方向移动,而角色在朝相反的方向移动,就像跑步机一样,这会导致角色口吃。在雷目前的书中,他做了:
override func didSimulatePhysics() {
let target = getCenterPointWithTarget(player.position)
worldNode.position += (target - worldNode.position) * 0.1
我确定这与您所做的非常相似,对吧?这使得 worldNode 不断地试图赶上玩家的动作。它给了相机那种弹性的感觉。
试着去
worldNode.position = getCenterPointWithTarget(player.position)
如果这解决了问题,那么我们会进一步缩小范围。这里的问题是你失去了很酷的相机缓动效果。
问题是我不知道你在哪里对球员的动作做出改变。我不知道这些是否只是你调用的一次性方法,或者它们 运行你的更新循环。
我将举例说明我在游戏中的做法:
在更新中:
// update ship position
ship.update(self.delta)
我在 didFinishUpdate 中移动了屏幕,所以我确保这是最后发生的事情。希望这会停止任何口吃。
didFinishUpdate
override func didFinishUpdate() {
// move BG Nodes
self.moveBGNodes()
}
moveBGNodes 方法
func moveBGNodes(){
// method that calculates camera position (stops camera at screen edges)
let target = self.pointToCenterViewOn(ship.position)
// ease gameworld into ship's position
gameLayer.position += (target - gameLayer.position) * 0.1