I am developing an iPhone version of this game. http://www.students.uni-mainz.de/rathb000/Fillit/Game.html
我正在开发这个游戏的iPhone版本。 http://www.students.uni-mainz.de/rathb000/Fillit/Game.html
I am using an NSTimer to change the position of the ship by 1 pixel and the time interval for the timer is 0.002.
我使用NSTimer将船的位置改变1个像素,计时器的时间间隔为0.002。
However, i have noticed that the ship doesnt move faster if i reduce the time interval furthur. Infact, there is no difference between 0.05 and 0.002. Is there is a restriction on the minimum time you have to give as NSTimeInterval?
但是,我注意到如果我减少时间间隔,船只不会移动得更快。事实上,0.05和0.002之间没有差别。您必须作为NSTimeInterval提供的最短时间是否有限制?
The ship currently moves too slow for the game to be exciting.
目前这艘船的移动速度太慢,不足以让游戏变得令人兴奋。
Also, the movement of birds (which is also achieved by NSTimer) becomes slow when i press any button for moving the ship.
此外,当我按任何按钮移动船时,鸟类的移动(这也是由NSTimer实现)变得缓慢。
Any idea about how this can be solved?
有关如何解决这个问题的任何想法?
6 个解决方案
#1
NSTimer is not a real-time mechanism; it fires as part of the run loop and is not ideal for creating smooth, fluid animations. However, there is an SDK that is part of the iPhone OS called Core Animation - it provides a library of functions for performing smooth animation of layers and views. Here is a reasonably good series of video tutorials that you may find useful. There is also an excellent book called Core Animation for Mac OS X and iPhone that you may find useful.
NSTimer不是一个实时机制;它作为运行循环的一部分发射,并不是创建平滑流畅动画的理想选择。但是,有一个SDK是iPhone OS的一部分,名为Core Animation--它提供了一个函数库,用于执行图层和视图的平滑动画。这是一系列相当不错的视频教程,您可能会发现它们非常有用。还有一本名为Core Animation for Mac OS X和iPhone的优秀书籍,您可能会发现它很有用。
There is also the core animation documentation from Apple that describes how to use the CABasicAnimation class to animate properties of any layer or view. Here is an example of an explicit layer animation from the docs:
Apple还提供了核心动画文档,描述了如何使用CABasicAnimation类为任何图层或视图的属性设置动画。以下是文档中显式图层动画的示例:
CABasicAnimation *theAnimation;
theAnimation=[CABasicAnimation animationWithKeyPath:@"opacity"];
theAnimation.duration=3.0;
theAnimation.repeatCount=1;
theAnimation.autoreverses=NO;
theAnimation.fromValue=CATransform3DTranslate(0,0,0);
theAnimation.toValue=CATransform3DTranslate(20,20,0);
[theLayer addAnimation:theAnimation forKey:@"animateTransform"];
#2
From NSTimer
docs:
来自NSTimer的文档:
A timer is not a real-time mechanism; it fires only when one of the run loop modes to which the timer has been added is running and able to check if the timer’s firing time has passed. Because of the various input sources a typical run loop manages, the effective resolution of the time interval for a timer is limited to on the order of 50-100 milliseconds. If a timer’s firing time occurs while the run loop is in a mode that is not monitoring the timer or during a long callout, the timer does not fire until the next time the run loop checks the timer. Therefore, the actual time at which the timer fires potentially can be a significant period of time after the scheduled firing time.
计时器不是实时机制;只有当添加了计时器的其中一个运行循环模式正在运行并且能够检查计时器的触发时间是否已经过去时,它才会触发。由于典型的运行循环管理各种输入源,因此定时器的时间间隔的有效分辨率被限制在50-100毫秒的量级。如果在运行循环处于不监视定时器的模式或长调出期间发生定时器的触发时间,则定时器在下次运行循环检查定时器之前不会触发。因此,计时器可能发射的实际时间可能是在计划的发射时间之后的重要时间段。
Maybe you can try moving the UIView
using UIView
animations instead of a timer.
也许您可以尝试使用UIView动画而不是计时器来移动UIView。
#3
You could consider increasing the distance size: move the ship 3 or 4 pixels every .05 seconds rather than 1 pixel every .002 seconds.
您可以考虑增加距离大小:每隔0.05秒移动船舶3或4个像素,而不是每.002秒移动1个像素。
#4
In my opinion, you should be using the same timestep globally across all entities in your game, not a timestep exclusively for the player's ship. If the ship is moving too slowly with your timestep, increase the amount of distance it is moving per frame.
在我看来,你应该在游戏中的所有实体中使用相同的时间步长,而不是专门针对玩家船只的时间步长。如果船舶在您的时间步长中移动太慢,请增加每帧移动的距离。
Really, you should be thinking of moving your player's ship in terms of pixels/second. When the NSTimer event fires, get the elapsed time since the last update. Use this elapsed time to move your game entities. For instance, if your update timestep is 0.05 seconds and you want to move the player's ship 100 pixels per second, then you should move it 100 * 0.05 = 5 pixels in this update. This method will account for varying size timesteps and your game entities will always appear to moving at a consistent speed, even if your timer mechanism is not that consistent.
真的,你应该考虑以像素/秒为单位移动玩家的船。触发NSTimer事件时,获取自上次更新以来经过的时间。使用此经过时间移动游戏实体。例如,如果您的更新时间步长为0.05秒,并且您想要将播放器的每秒移动100像素,那么您应该在此更新中将其移动100 * 0.05 = 5像素。此方法将考虑不同大小的时间步长,即使您的计时器机制不一致,您的游戏实体也总是以一致的速度移动。
#5
Not only is NSTimer not the right tool for this type of animation your design is wrong.
NSTimer不仅不是用于此类动画的正确工具,而且您的设计也是错误的。
A timer with an inteval of 0002 fires 500 times per second. That's a crazy way to animate this game.
inteval为0002的计时器每秒发射500次。这是制作这款游戏的疯狂方式。
I suggest you read up on 2D game design and find out a better way to do collision detection - like anonymous suggests you should have a collision rectangle round the ship rather than relying on the actual pixels.
我建议你阅读2D游戏设计,找出更好的碰撞检测方法 - 比如匿名建议你应该在船上有一个碰撞矩形,而不是依赖于实际的像素。
You should also check out Cocos-2D for iPhone
您还应该查看适用于iPhone的Cocos-2D
#6
Figured this out.
想出这个。
Had to use Core Animation to move the ship and made the birds move by NSTimer. Works fine this way but only upto a certain limit. Birds again slow down when the speed of the ship increases more than a certain limit.
不得不使用核心动画来移动船只并使鸟类移动NSTimer。这种方式工作正常,但只有一定的限制。当船的速度增加超过一定限度时,鸟类再次减速。
#1
NSTimer is not a real-time mechanism; it fires as part of the run loop and is not ideal for creating smooth, fluid animations. However, there is an SDK that is part of the iPhone OS called Core Animation - it provides a library of functions for performing smooth animation of layers and views. Here is a reasonably good series of video tutorials that you may find useful. There is also an excellent book called Core Animation for Mac OS X and iPhone that you may find useful.
NSTimer不是一个实时机制;它作为运行循环的一部分发射,并不是创建平滑流畅动画的理想选择。但是,有一个SDK是iPhone OS的一部分,名为Core Animation--它提供了一个函数库,用于执行图层和视图的平滑动画。这是一系列相当不错的视频教程,您可能会发现它们非常有用。还有一本名为Core Animation for Mac OS X和iPhone的优秀书籍,您可能会发现它很有用。
There is also the core animation documentation from Apple that describes how to use the CABasicAnimation class to animate properties of any layer or view. Here is an example of an explicit layer animation from the docs:
Apple还提供了核心动画文档,描述了如何使用CABasicAnimation类为任何图层或视图的属性设置动画。以下是文档中显式图层动画的示例:
CABasicAnimation *theAnimation;
theAnimation=[CABasicAnimation animationWithKeyPath:@"opacity"];
theAnimation.duration=3.0;
theAnimation.repeatCount=1;
theAnimation.autoreverses=NO;
theAnimation.fromValue=CATransform3DTranslate(0,0,0);
theAnimation.toValue=CATransform3DTranslate(20,20,0);
[theLayer addAnimation:theAnimation forKey:@"animateTransform"];
#2
From NSTimer
docs:
来自NSTimer的文档:
A timer is not a real-time mechanism; it fires only when one of the run loop modes to which the timer has been added is running and able to check if the timer’s firing time has passed. Because of the various input sources a typical run loop manages, the effective resolution of the time interval for a timer is limited to on the order of 50-100 milliseconds. If a timer’s firing time occurs while the run loop is in a mode that is not monitoring the timer or during a long callout, the timer does not fire until the next time the run loop checks the timer. Therefore, the actual time at which the timer fires potentially can be a significant period of time after the scheduled firing time.
计时器不是实时机制;只有当添加了计时器的其中一个运行循环模式正在运行并且能够检查计时器的触发时间是否已经过去时,它才会触发。由于典型的运行循环管理各种输入源,因此定时器的时间间隔的有效分辨率被限制在50-100毫秒的量级。如果在运行循环处于不监视定时器的模式或长调出期间发生定时器的触发时间,则定时器在下次运行循环检查定时器之前不会触发。因此,计时器可能发射的实际时间可能是在计划的发射时间之后的重要时间段。
Maybe you can try moving the UIView
using UIView
animations instead of a timer.
也许您可以尝试使用UIView动画而不是计时器来移动UIView。
#3
You could consider increasing the distance size: move the ship 3 or 4 pixels every .05 seconds rather than 1 pixel every .002 seconds.
您可以考虑增加距离大小:每隔0.05秒移动船舶3或4个像素,而不是每.002秒移动1个像素。
#4
In my opinion, you should be using the same timestep globally across all entities in your game, not a timestep exclusively for the player's ship. If the ship is moving too slowly with your timestep, increase the amount of distance it is moving per frame.
在我看来,你应该在游戏中的所有实体中使用相同的时间步长,而不是专门针对玩家船只的时间步长。如果船舶在您的时间步长中移动太慢,请增加每帧移动的距离。
Really, you should be thinking of moving your player's ship in terms of pixels/second. When the NSTimer event fires, get the elapsed time since the last update. Use this elapsed time to move your game entities. For instance, if your update timestep is 0.05 seconds and you want to move the player's ship 100 pixels per second, then you should move it 100 * 0.05 = 5 pixels in this update. This method will account for varying size timesteps and your game entities will always appear to moving at a consistent speed, even if your timer mechanism is not that consistent.
真的,你应该考虑以像素/秒为单位移动玩家的船。触发NSTimer事件时,获取自上次更新以来经过的时间。使用此经过时间移动游戏实体。例如,如果您的更新时间步长为0.05秒,并且您想要将播放器的每秒移动100像素,那么您应该在此更新中将其移动100 * 0.05 = 5像素。此方法将考虑不同大小的时间步长,即使您的计时器机制不一致,您的游戏实体也总是以一致的速度移动。
#5
Not only is NSTimer not the right tool for this type of animation your design is wrong.
NSTimer不仅不是用于此类动画的正确工具,而且您的设计也是错误的。
A timer with an inteval of 0002 fires 500 times per second. That's a crazy way to animate this game.
inteval为0002的计时器每秒发射500次。这是制作这款游戏的疯狂方式。
I suggest you read up on 2D game design and find out a better way to do collision detection - like anonymous suggests you should have a collision rectangle round the ship rather than relying on the actual pixels.
我建议你阅读2D游戏设计,找出更好的碰撞检测方法 - 比如匿名建议你应该在船上有一个碰撞矩形,而不是依赖于实际的像素。
You should also check out Cocos-2D for iPhone
您还应该查看适用于iPhone的Cocos-2D
#6
Figured this out.
想出这个。
Had to use Core Animation to move the ship and made the birds move by NSTimer. Works fine this way but only upto a certain limit. Birds again slow down when the speed of the ship increases more than a certain limit.
不得不使用核心动画来移动船只并使鸟类移动NSTimer。这种方式工作正常,但只有一定的限制。当船的速度增加超过一定限度时,鸟类再次减速。