Ios 精灵套件:匀速运动时口吃
我正在用精灵工具包开发一个简单的飞行游戏。一旦太空船达到最大高度和速度,它就会以恒定速度继续飞行。我注意到宇宙飞船在持续的飞行中随机地发出口吃声。我已经在这里阅读了所有关于这个问题的帖子,但是没有任何东西能够100%的解决这个问题 为了测试,我编写了一个非常简单的游戏,其中只包含一艘宇宙飞船和一个简单的云(代码如下)。但即使在这个非常简单的游戏中,太空船仍然会口吃。日志显示,即使飞船以恒定速度飞行,飞船的运动也不是随机恒定的。这就是口吃的原因 希望有人能帮我解决这个问题。谢谢你的建议Ios 精灵套件:匀速运动时口吃,ios,objective-c,sprite-kit,game-physics,Ios,Objective C,Sprite Kit,Game Physics,我正在用精灵工具包开发一个简单的飞行游戏。一旦太空船达到最大高度和速度,它就会以恒定速度继续飞行。我注意到宇宙飞船在持续的飞行中随机地发出口吃声。我已经在这里阅读了所有关于这个问题的帖子,但是没有任何东西能够100%的解决这个问题 为了测试,我编写了一个非常简单的游戏,其中只包含一艘宇宙飞船和一个简单的云(代码如下)。但即使在这个非常简单的游戏中,太空船仍然会口吃。日志显示,即使飞船以恒定速度飞行,飞船的运动也不是随机恒定的。这就是口吃的原因 希望有人能帮我解决这个问题。谢谢你的建议 Spri
Sprite工具包,Objective c,Xcode 8.0,测试设备:iPhone 6-iOS 8.3,iPhone 4s-iOS 9.3.5 CPU:最大21%,内存:最大8MB,每秒:永久60FPS
这里是我的代码(为了简单起见,我将所有代码放在scene类中)
飞行场景
#import <SpriteKit/SpriteKit.h>
@interface FlightScene : SKScene <SKPhysicsContactDelegate>
@end
编辑:
- 我将此添加到
方法中addHero:
_hero.physicsBody.angularDamping = 0.0f;
- 我更改了
,这样飞船就可以立即以最大速度飞行而不起飞触摸开始:
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { if(_hasBegun) return; _hasBegun = YES; _hero.physicsBody.velocity = CGVectorMake(kMaxHeroVelocityX, kMaxHeroVelocityY); }
-(void)touchesbeated:(NSSet*)toucheevent:(UIEvent*)event { 如果(_已开始) 返回; _hasbeated=是; _hero.physicsBody.velocity=CGVectorMake(kMaxHeroVelocityX,kMaxHeroVelocityY); }
- 我运行代码时没有使用
方法。宇宙飞船立即以最大速度飞行而不起飞。它以恒定的速度飞行,因此不需要更新速度updatefling:
- 我尝试了其他方法,比如将更新放在
中。。打开飞行模式。。正如他所说的。。但没有什么能解决这个问题。它仍然不是像@crashoveride777所说的那样100%完美didSimulatePhysics:
- 我运行代码时没有使用
如果还有其他想法,我将不胜感激。这是因为SpriteKit的默认物理和运动/变换处理未按增量时间进行更正。相反,每当由于系统调用或其他中断而导致帧速率下降时,它就会结巴。这些事情在iOS设备上经常发生。iOS系统不断检查网络,监控各种后台活动的其他状态,并对收到的信息做出响应 有两种方法可以解决这个问题
如果你不局限于SpriteKit,或者不需要它的物理,你可以包括另一个物理引擎并使用它。这最终意味着您可以使用SceneKit、核心动画甚至金属来进行渲染。。。。还是斯皮特基特 最明智的两个选择是Box2D和Chipmunk2D 以下是有关将Box2D添加到iOS的教程:
这是花栗鼠2D的快速包装:我的游戏也遇到了同样的问题。似乎它并不特别喜欢持续的运动 你可以尝试的第一件事就是使用
applyForce
而不是直接操纵玩家的速度属性
当我在常规赛中移动球员时,我似乎得到了最好的结果
override func update(_ currentTime: TimeInterval) { ... }
方法
我更新了相机
override func didFinishUpdate() { ... }
在苹果示例游戏Demobot中,他们对相机使用约束。在DidSimulatePhysics之后,约束将得到更新,因此当您手动执行时,didFinishUpdate似乎是最佳位置
还请记住,通过执行以下操作,您将获得一些性能
1)测试时断开手机与mac的连接。只需在插入时通过xCode运行手机就会降低性能
2)测试应用程序时,它处于调试模式,而不是发布模式,这将降低性能
若要在测试时手动更改此设置,请转到您的方案(按以运行应用程序的按钮旁边的按钮)。单击“编辑方案”并在“更改生成配置以发布信息”中单击
请记住,当您完成特定测试时,应该将其更改回。您希望在测试应用程序时运行调试工具
3)确保您的抽签要求非常低。通过确保
ignoresSiblingOrder
在GameViewController中设置为true,默认情况下应为true
而不是根据你的精灵所在的图层给他们不同的位置
e、 g
4)尽可能多地制作物理体,因为它们使用最少的性能
5)更新方法中的代码尽可能少
6)缓存纹理,尤其是在使用纹理动画时
7)如果要大量实例化某些节点,请将它们集合起来。我将回答自己的问题 飞行阶段:
- 起飞
- 一旦太空船达到最高高度和速度,它就会继续飞行 匀速
- 宇宙飞船在持续飞行中随机地发出口吃声
- 由于口吃发生在持续飞行期间,请定义一个变量(
)来控制起飞阶段的结束\u maxreach
- 一旦太空船达到最大高度和速度,设置
\u maxreach=YES
- 通过更新x位置(
)更新恒定飞行updatePosition
override func didFinishUpdate() { ... }
ignoresSiblingOrder
background = 1
sun = 2
clouds = 3
traps, obstacles, objects = 4
player = 5
.
.
// new:
static const CGFloat kMaxSpeed = 5.0f;
@implementation FlightScene
{
.
.
.
// new:
BOOL _maxReached;
}
// new: rename
//- (void)updateFlying
- (void)takeOff
{
if(!_hasBegun)
return;
CGVector oldVel = _hero.physicsBody.velocity;
CGVector newVel = oldVel;
// increase the velocity
newVel.dx += (kMaxHeroVelocityX - newVel.dx) / 10.0f;
newVel.dy += (kMaxHeroVelocityY - newVel.dy) / 10.0f;
// ensure velocity doesn't exceed maximum
newVel.dx = newVel.dx > kMaxHeroVelocityX ? kMaxHeroVelocityX : newVel.dx;
newVel.dy = newVel.dy > kMaxHeroVelocityY ? kMaxHeroVelocityY : newVel.dy;
_hero.physicsBody.velocity = newVel;
}
- (void)limitHeight
{
const CGFloat maxHeight = self.size.height * 0.8f;
// new
if(_hero.position.y >= maxHeight)
{
if(_hero.physicsBody.velocity.dy == kMaxHeroVelocityY)
_maxReached = YES;
if(_hero.position.y > maxHeight)
_hero.position = CGPointMake(_hero.position.x, maxHeight);
}
}
// new: move the hero with constant velocity
- (void)updatePosition
{
CGFloat newX = _hero.position.x + kMaxSpeed;
_hero.position = CGPointMake(newX, _hero.position.y);
}
- (void)updateFlight
{
if(_maxReached) // new
{
[self updatePosition]; // move the hero with constant velocity
}
else
{
[self takeOff];
// ensure height doesn't exceed maximum
[self limitHeight];
}
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
if(_hasBegun)
return;
_hasBegun = YES;
_maxReached = NO; // new
[self updateFlight];
}