我的角色 Sprite Node 移动时抖动,为啥?
Posted
技术标签:
【中文标题】我的角色 Sprite Node 移动时抖动,为啥?【英文标题】:My character's SpriteNode is shaking when moving, why?我的角色 Sprite Node 移动时抖动,为什么? 【发布时间】:2015-01-28 19:46:44 【问题描述】:我的主角是一个带有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 录制)。你可以很容易地看到这个视频的问题以及这让我头疼(以及我刚刚开始开发的游戏)。
确实,经常(不是每次,有时是完美的)像鬼一样,他变得模糊。我什么都不明白,我没有找到任何解决方案。
我在模拟器和我的设备上试过这个,效果一样。
如果你愿意,我可以发布更多代码,并且可以告诉你一切,我希望有人能找到我做错了什么!
提前感谢!
保罗
编辑 1:
感谢 cmets !
我在屏幕上显示了 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,效果真的更好!这种颤抖的感觉消失了,我现在可以在没有那种糟糕体验的情况下玩了。
BUT 人物跳跃时仍然发生一件事(感谢applyForce
方法):当他向上时,有时他似乎仍然向下,只有 1 个像素这里或那里。它非常特别,我不知道是 Sprite Kit 的真正问题还是我的纹理太大或其他什么。我试着看一下绘制了物理体的动画,实际上有一些垂直抖动(更准确地说,蓝色的矩形似乎在闪烁)。
你对上一期有什么想法吗?
现在水平移动已经很完美了,谢谢大家的帮助。
【问题讨论】:
当我看到你的视频时,我首先想到的是你的动画有问题。检查您的角色动画图像大小。可能这不是问题,但是您可以检查一下。您还可以在代码中显示如何左右移动角色。 您也可以在视图控制器中启用showsPhysics 以及showsNode 和showsDrawCount。调试时很有用。 很酷的艺术!我想我可能知道问题可能是什么。你能关掉那个相机功能然后试着跳来跳去吗?还会卡顿吗? 尝试在 didSimulatePhysics 方法中将相机视图居中。 感谢您的回答!我刚刚编辑了主帖以获取有关您所说内容的更多信息! 【参考方案1】:我遇到了同样的问题(也遵循 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
【讨论】:
非常感谢您的回答!我没有按照你先说的做,但我已经在做你告诉我的第二种方法,所以:self.map.position = viewPoint;
(其他线条只是用来让相机留在地图上)。我试图在 didFinishUpdate 中调用我的相机方法,它真的更好(我在更新方法中这样做)。为了移动我的角色,我有一些布尔值,我在更新方法中测试每一帧,并逐个执行我上面写的内容。你有更好的解决方案吗?非常感谢!
视具体情况而定。如果它现在对你有用,那就坚持下去。如果您能想到一个更清洁的解决方案,或者您当前的解决方案使事情变得困难,那么您应该想出一种不同的方式来做这件事。很高兴我能帮上忙。
我想到了一种新的方法来做到这一点,但我没有想法。我在更新方法中检查的布尔值总是很少,以便施加力并调整角色的纹理和动画。它像这样工作得很好,但如果你有想法,我很乐意尝试改进它。以上是关于我的角色 Sprite Node 移动时抖动,为啥?的主要内容,如果未能解决你的问题,请参考以下文章
Firefox 和 CSS3 动画 - 为啥我的文本会抖动?