[英]Multiple ints - They don't work at the same time (Obj-C)
我正在做一個簡單的小游戲。
我有兩個整數:
1)使對象的位置在Y軸和X軸上隨機生成的一種方法。
2)一種用於評分功能。
我使用NSTimers來使對象移動,並且使樂譜每秒增加1。
問題在於,當這兩種情況同時存在時,游戲就會被竊聽,並且計時器開始變得瘋狂。 如果刪除計分int / timer,則對象將完美移動。 反之亦然。
我似乎找不到該問題,因為它應該可以工作。
有任何想法嗎?
ViewController.h:
int scoreNumber;
int randomPosition;
ViewController.m:
#define IsIphone4 ( fabs( ( double )[ [ UIScreen mainScreen ] bounds ].size.height - ( double )480 ) < DBL_EPSILON )
#define IsIphone5 ( fabs( ( double )[ [ UIScreen mainScreen ] bounds ].size.height - ( double )568 ) < DBL_EPSILON )
#define IsIphone6 ( fabs( ( double )[ [ UIScreen mainScreen ] bounds ].size.height - ( double )667 ) < DBL_EPSILON )
#define IsIphone6Plus ( fabs( ( double )[ [ UIScreen mainScreen ] bounds ].size.height - ( double )736 ) < DBL_EPSILON )
- (void)obstaclesMoving {
obstacle.center = CGPointMake(obstacle.center.x - 1, obstacle.center.y);
obstacle2.center = CGPointMake(obstacle2.center.x - 1, obstacle2.center.y);
obstacle3.center = CGPointMake(obstacle3.center.x - 1, obstacle3.center.y);
if (IsIphone4) {
if (obstacle.center.x < 0) {
randomPosition = arc4random_uniform(60);
randomPosition = randomPosition + 70;
obstacle.center = CGPointMake(320, randomPosition);
}
if (obstacle2.center.x < 0) {
randomPosition = arc4random_uniform(60);
randomPosition = randomPosition + 360;
obstacle2.center = CGPointMake(320, randomPosition);
}
if (obstacle3.center.x < 0) {
randomPosition = arc4random_uniform(100);
randomPosition = randomPosition + 215;
obstacle3.center = CGPointMake(320, randomPosition);
}
}
if (IsIphone5) {
if (obstacle.center.x < 0) {
randomPosition = arc4random_uniform(60);
randomPosition = randomPosition + 70;
obstacle.center = CGPointMake(320, randomPosition);
}
if (obstacle2.center.x < 0) {
randomPosition = arc4random_uniform(60);
randomPosition = randomPosition + 448;
obstacle2.center = CGPointMake(320, randomPosition);
}
if (obstacle3.center.x < 0) {
randomPosition = arc4random_uniform(100);
randomPosition = randomPosition + 259;
obstacle3.center = CGPointMake(320, randomPosition);
}
}
if (IsIphone6) {
if (obstacle.center.x < 0) {
randomPosition = arc4random_uniform(60);
randomPosition = randomPosition + 70;
obstacle.center = CGPointMake(375, randomPosition);
}
if (obstacle2.center.x < 0) {
randomPosition = arc4random_uniform(60);
randomPosition = randomPosition + 547;
obstacle2.center = CGPointMake(375, randomPosition);
}
if (obstacle3.center.x < 0) {
randomPosition = arc4random_uniform(100);
randomPosition = randomPosition + 309;
obstacle3.center = CGPointMake(375, randomPosition);
}
}
if (IsIphone6Plus) {
if (obstacle.center.x < 0) {
randomPosition = arc4random_uniform(60);
randomPosition = randomPosition + 70;
obstacle.center = CGPointMake(414, randomPosition);
}
if (obstacle2.center.x < 0) {
randomPosition = arc4random_uniform(60);
randomPosition = randomPosition + 616;
obstacle2.center = CGPointMake(414, randomPosition);
}
if (obstacle3.center.x < 0) {
randomPosition = arc4random_uniform(100);
randomPosition = randomPosition + 343;
obstacle3.center = CGPointMake(414, randomPosition);
}
}
}
- (IBAction)characterUp:(id)sender {
characterDrop = 5;
}
- (IBAction)characterDown:(id)sender {
characterDrop = -5;
}
- (void)characterMoving {
character.center = CGPointMake(character.center.x, character.center.y - characterDrop);
characterDrop = characterDrop - 0.1;
if ((CGRectIntersectsRect(character.frame, ground.frame)) && (characterDrop < -1)) {
[self gameOver];
//Sound for G.O.
}
if ((CGRectIntersectsRect(character.frame, roof.frame)) && (characterDrop < -1)) {
[self gameOver];
//Sound for G.O.
}
}
- (IBAction)startGame:(id)sender {
startGameButton.hidden = YES;
characterMovement = [NSTimer scheduledTimerWithTimeInterval:0.02 target:self selector:@selector(characterMoving) userInfo:nil repeats:YES];
characterDrop = -5;
obstacleTimer = [NSTimer scheduledTimerWithTimeInterval:0.0055 target:self selector:@selector(obstaclesMoving) userInfo:nil repeats:YES];
scorer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(scoring) userInfo:nil repeats:YES];
}
- (void)scoring {
scoreNumber = scoreNumber + 1;
scoreLabelInGame.text = [NSString stringWithFormat:@"%i", scoreNumber];
scoreLabelGameOver.text = [NSString stringWithFormat:@"%i", scoreNumber];
}
- (void)gameOver {
if (scoreNumber > bestScoreNumber) {
[[NSUserDefaults standardUserDefaults] setInteger:scoreNumber forKey:@"bestScoreSaved"];
bestScoreLabel.text = [NSString stringWithFormat:@"New best: %i", scoreNumber];
}
character.hidden = YES;
obstacle.hidden = YES;
obstacle2.hidden = YES;
obstacle3.hidden = YES;
startGameButton.hidden = YES;
scoreLabelInGame.hidden = YES;
characterUpButton.hidden = YES;
characterDownButton.hidden = YES;
scoreLabelGameOver.hidden = NO;
bestScoreLabel.hidden = NO;
gameOverLabel.hidden = NO;
restartGameButton.hidden = NO;
backButton.hidden = NO;
[characterMovement invalidate];
[obstacleTimer invalidate];
[obstacleTimer2 invalidate];
[obstacleTimer3 invalidate];
[obstacleTimer4 invalidate];
[scorer invalidate];
}
- (void)viewDidLoad {
bestScoreNumber = [[NSUserDefaults standardUserDefaults] integerForKey:@"bestScoreSaved"];
bestScoreLabel.text = [NSString stringWithFormat:@"Best: %li", (long)bestScoreNumber];
scoreNumber = 0;
scoreLabelGameOver.hidden = YES;
bestScoreLabel.hidden = YES;
gameOverLabel.hidden = YES;
restartGameButton.hidden = YES;
backButton.hidden = YES;
[super viewDidLoad];
// Do any additional setup after loading the view.
}
我認為更干凈的方法是移至CADisplayLink
或單個NSTimer
並將視圖移出其調用的選擇器。
/* Add _amountOfTicks as an instance Variable */
{
int _amountOfTicks;
int scoreNumber;
int randomPosition;
}
/* replace timers in startGame */
CADisplayLink *displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(tick)];
displayLink.frameInterval = 1;
[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
- (void)tick {
_amountOfTicks++;
if (_amountOfTicks > 16){
_amountOfTicks = 1;
}
if (_amountOfTicks == 2) {
[self characterMoving]
}
if (_amountOfTicks == 4) {
[self obstaclesMoving]
}
if (_amountOfTicks == 16) {
[self scoring]
}
}
同樣,在下面的方法中,您將center.x減小了1,然后在檢查宏時將其改回正下方的屏幕寬度。
- (void)obstaclesMoving {
obstacle.center = CGPointMake(obstacle.center.x - 1, obstacle.center.y); /* reduce by 1 */
obstacle2.center = CGPointMake(obstacle2.center.x - 1, obstacle2.center.y);
obstacle3.center = CGPointMake(obstacle3.center.x - 1, obstacle3.center.y);
if (IsIphone4) {
if (obstacle.center.x < 0) {
randomPosition = arc4random_uniform(60);
randomPosition = randomPosition + 70;
obstacle.center = CGPointMake(320, randomPosition); /* changes it back to screen width which makes what you did up above useless */
}
}
從文檔 :
計時器時間間隔的有效分辨率限制在50到100毫秒之間
我的猜測是這可能是問題。
如果需要每1秒增加一次分數,為什么要每0.0055
秒調用一次該函數?
您還需要移動[super viewDidLoad];
在viewDidLoad
函數的頂部。
同樣,如@rmaddy所述,您不應明確檢查屏幕尺寸。
我可以告訴您,運行分辨率為1/180秒的計時器會給您帶來麻煩。 由於該框架最多每60秒更新一次,因此用戶不會看到它。 無法保證計時器實際上會經常運行(很可能不會)。
您不能使用這樣的計時器。 您只能使用它們來觸發事件,然后需要准確檢查事件的時間和應該做什么。
可能發生的情況是您設法打開了自動布局。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.