我的角色 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 动画 - 为啥我的文本会抖动?

在 Sprite Kit 中为我的角色设置动画?

为啥我的角色没有使用此代码移动?

Sprite Kit 和 Pathfinding,iPad 和 iPhone 的区别?

ActionScript 3使用Sprite实现图层的问题

为啥我的左右移动动画不起作用?