0

我想在我正在进行的演示项目中实现高分标签。
我声明整数和长整数如下:

SKLabelNode *_scoreLabel;
int _meter;
SKLabelNode *_highScoreLabel;
NSInteger _meter1;

然后在- (id)initWithSize:(CGSize)size我添加声明标签并添加nsuser默认值:

[self initScoreLabel];
[self initHighScoreLabel];

_meter1 = [[NSUserDefaults standardUserDefaults] integerForKey:@"HighScoreSaved"];
if (_meter > _meter1) {
  [[NSUserDefaults standardUserDefaults] setInteger:_meter1 forKey:@"HighScoreSaved"];
}

这也是我添加标签的方式:

- (void)initHighScoreLabel {
  _meter1 = 0;
  _highScoreLabel = [SKLabelNode labelNodeWithFontNamed:@"Thonburi-Bold"];
  _highScoreLabel.text = @"0 High Score";
  _highScoreLabel.fontSize = 20.0;
  // _scoreLabel.verticalAlignmentMode = SKLabelHorizontalAlignmentModeRight;// | SKLabelVerticalAlignmentModeBaseline;
  _highScoreLabel.position = CGPointMake(450, self.frame.size.height - _highScoreLabel.frame.size.height * 1.5);
  [self addChild:_highScoreLabel];
}

然后在game over我添加高分:

_meter1 = [[NSUserDefaults standardUserDefaults] integerForKey:@"HighScoreSaved"];

if (_meter > _meter1) {
  [[NSUserDefaults standardUserDefaults] setInteger:_meter forKey:@"HighScoreSaved"];
}

最后在- (void)update:(NSTimeInterval)currentTime我添加更新如下:

- (void)update:(NSTimeInterval)currentTime {
  if (_isGameOver) {
    return;
  }

  if (_lastUpdateTime) {
    _dt = currentTime - _lastUpdateTime;
  } else {
    _dt = 0;
  }
  _lastUpdateTime = currentTime;

  // Runner faster than normal
  if (_runnerState == incredible) {
    _meter += INCREDIBLE_BG_POINTS_PER_SEC / BG_POINTS_PER_SEC;
    _meter1 += INCREDIBLE_BG_POINTS_PER_SEC / BG_POINTS_PER_SEC;
  } else {
    ++_meter;
    ++_meter1;
  }
  _scoreLabel.text = [NSString stringWithFormat:@"%d Meters", _meter];
  _highScoreLabel.text = [NSString stringWithFormat:@"%li High Score",(long) _meter1];

  [self checkCollisions];
}

标签显示在正确的位置,并将分数加上高分。
但只有在玩家死亡后一次。

玩家第一次死亡,高分更新,但如果玩家第二次死亡,高分只显示第一次更新。

有人可以帮助我了解我做错了什么吗?

编辑:

我确实添加了一些口号,一切都以正确的方式进行。分数更新和高分加起来但仍然只有一次。这是整个游戏场景类。谁能看到我哪里出错了?

#import "MyScene.h"
#import "SKTAudio.h"
#import "Levels.h"
#import "StartScene.h"
#import "EndScene.h"

// the position X of the runner on the screen
static const float RUNNER_X = 120.0;
static const float RUNNER_HEIGHT = 56.0;
static const float JUMP_HEIGHT = 100.0;

// background scrolling speed
static const float BG_POINTS_PER_SEC = 200.0;
static const float INCREDIBLE_BG_POINTS_PER_SEC = 600.0;

static const int COINS_PER_MAP = 10;
static const int ROCKS_PER_MAP = 2;
static const float BG_WIDTH = 1440;

static const int COIN_RANDOM_FACTOR = (int) (BG_WIDTH / COINS_PER_MAP * 2);
static const int ROCK_RANDOM_FACTOR = (int) (BG_WIDTH / ROCKS_PER_MAP * 2);


#define BG_NAME @"bg"
#define GROUND_NAME @"ground"
#define COIN_NAME @"coin"
#define ROCK_NAME @"rock"
#define RUNNER_ANIMATION_KEY @"runnerAnimation"
#define RUNNER_EMITTER @"runnerEmitter"

enum RunnerState {
    running,
    jumping,
    crouching,
    incredible
};

static inline CGPoint CGPointAdd(const CGPoint a,
                                 const CGPoint b) {
    return CGPointMake(a.x + b.x, a.y + b.y);
}

static inline CGPoint CGPointMultiplyScalar(const CGPoint a,
                                            const CGFloat b) {
    return CGPointMake(a.x * b, a.y * b);
}

@interface MyScene() {
    SKSpriteNode *_runner;
    SKAction *_runningAnimation;
    SKAction *_jumpAnimation;
    SKAction *_crouchAnimation;
    SKAction *_coinAnimation;
    SKEmitterNode *_runnerEmitter;

    SKLabelNode *_scoreLabel;
    int _meter;
    SKLabelNode *_highScoreLabel;
    NSInteger _meter1;
    SKLabelNode *_coinsLabel;
    int _coins;

    NSTimeInterval _lastUpdateTime;
    // time diff
    NSTimeInterval _dt;

    CGFloat _groundHalfHeight;

    enum RunnerState _runnerState;
    SKNode *_bgLayer;

    BOOL _isGameOver;
}
@end

@implementation MyScene

- (id)initWithSize:(CGSize)size {
    if (self = [super initWithSize:size]) {
        /* Setup your scene here */

        _bgLayer = [SKNode node];
        [self addChild:_bgLayer];
        [self initMap];

        [self initScoreLabel];
        [self initHighScoreLabel];
        [self initCoinsLabel];

        // adding background sound effect
        [[SKTAudio sharedInstance] playBackgroundMusic:@"background.mp3"];

        [self initRunnerAnimation];
        [_runner runAction:[SKAction repeatActionForever:_runningAnimation] withKey:RUNNER_ANIMATION_KEY];
        _runnerState = running;

        [self initRunnerParticle];

        [self initJumpAnimation];
        [self initCrouchAnimation];
        [self initCoinAnimation];
        _meter1 = [[NSUserDefaults standardUserDefaults] integerForKey:@"HighScoreSaved"];

        if (_meter > _meter1) {
            [[NSUserDefaults standardUserDefaults] setInteger:_meter1 forKey:@"HighScoreSaved"];
        }

        // coins for fist map
        // [self generateRandomCoins:_ground.size.width/4];

        // coins for second map
        // int x = _ground.position.x;
        // [self generateRandomCoins:x];

        // rocks for second map
        // [self generateRandomRocks:x];
    }
    return self;
}

- (void)initRunnerParticle {
    _runnerEmitter = [NSKeyedUnarchiver unarchiveObjectWithFile:
                      [[NSBundle mainBundle] pathForResource:@"RunnerParticle" ofType:@"sks"]];
    _runnerEmitter.position = CGPointMake(_runner.size.width / 2.0, _runner.size.height / 2.0);
    _runnerEmitter.name = RUNNER_EMITTER;
}

- (void)initCoinsLabel {
    _coins = 0;
    _coinsLabel = [SKLabelNode labelNodeWithFontNamed:@"Thonburi-Bold"];
    _coinsLabel.text = @"Coins: 0";
    _coinsLabel.fontSize = 20.0;
    // _coinsLabel.verticalAlignmentMode = SKLabelHorizontalAlignmentModeLeft;// | SKLabelVerticalAlignmentModeBaseline;
    _coinsLabel.position = CGPointMake(50, self.frame.size.height - _coinsLabel.frame.size.height * 1.5);
    [self addChild:_coinsLabel];
}

- (void)initScoreLabel {
    _meter = 0;
    _scoreLabel = [SKLabelNode labelNodeWithFontNamed:@"Thonburi-Bold"];
    _scoreLabel.text = @"0 Meter";
    _scoreLabel.fontSize = 20.0;
    // _scoreLabel.verticalAlignmentMode = SKLabelHorizontalAlignmentModeRight;// | SKLabelVerticalAlignmentModeBaseline;
    _scoreLabel.position = CGPointMake(250, self.frame.size.height - _scoreLabel.frame.size.height * 1.5);
    [self addChild:_scoreLabel];

}
- (void)initHighScoreLabel {
    _meter1 = 0;
    _highScoreLabel = [SKLabelNode labelNodeWithFontNamed:@"Thonburi-Bold"];
    _highScoreLabel.text = @"0 High Score";
    _highScoreLabel.fontSize = 20.0;
    // _scoreLabel.verticalAlignmentMode = SKLabelHorizontalAlignmentModeRight;// | SKLabelVerticalAlignmentModeBaseline;
    _highScoreLabel.position = CGPointMake(450, self.frame.size.height - _highScoreLabel.frame.size.height * 1.5);
    [self addChild:_highScoreLabel];

}

- (void)initMap {
    // adding the background
    for (int i = 0; i < 2; ++i) {
        SKSpriteNode *map = [SKSpriteNode spriteNodeWithImageNamed:[NSString stringWithFormat:@"Map0%d", i]];
        map.anchorPoint = CGPointZero;
        map.position = CGPointMake(i * map.size.width, 0);;
        map.name = BG_NAME;
        [_bgLayer addChild:map];
    }

    // adding the ground
    SKSpriteNode *ground;
    for (int i = 0; i < 2; ++i) {
        ground = [SKSpriteNode spriteNodeWithImageNamed:[NSString stringWithFormat:@"Ground0%d", i]];
        ground.anchorPoint = CGPointZero;
        ground.position = CGPointMake(i * ground.size.width, 0);;
        ground.name = GROUND_NAME;
        _groundHalfHeight = ground.size.height / 2.0;
        [_bgLayer addChild:ground];
    }
}

- (void)initRunnerAnimation {
    // adding the runner
    _runner = [SKSpriteNode spriteNodeWithImageNamed:@"runner0"];
    _runner.anchorPoint = CGPointZero;
    _runner.position = CGPointMake(RUNNER_X, self.frame.origin.y + _groundHalfHeight + RUNNER_HEIGHT / 2.0);
    [self addChild:_runner];

    // adding running animation
    NSMutableArray *textures = [NSMutableArray arrayWithCapacity:8];
    for (int i = 0; i < 8; i++) {
        NSString *textureName = [NSString stringWithFormat:@"runner%d", i];
        SKTexture *texture = [SKTexture textureWithImageNamed:textureName];
        [textures addObject:texture];
    }

    _runningAnimation = [SKAction animateWithTextures:textures timePerFrame:0.1];
}

- (void)initCrouchAnimation {
    // adding crouch animation
    _crouchAnimation = [SKAction animateWithTextures:@[[SKTexture textureWithImageNamed:@"runnerCrouch0"]] timePerFrame:1.4 resize:YES restore:YES];
}

- (void)initJumpAnimation {
    // adding jump animation
    NSMutableArray *jumpUpTextures = [NSMutableArray arrayWithCapacity:4];
    for (int i = 0; i < 4; i++) {
        NSString *textureName = [NSString stringWithFormat:@"runnerJumpUp%d", i];
        SKTexture *texture = [SKTexture textureWithImageNamed:textureName];
        [jumpUpTextures addObject:texture];
    }

    SKAction *jumpUpAnimation = [SKAction animateWithTextures:jumpUpTextures timePerFrame:0.2 resize:YES restore:YES];
    SKAction *moveUpAction = [SKAction moveByX:0 y:JUMP_HEIGHT duration:0.8];
    SKAction *jumpUpAction = [SKAction group:@[jumpUpAnimation, moveUpAction]];

    NSMutableArray *jumpDownTextures = [NSMutableArray arrayWithCapacity:2];
    for (int i = 0; i < 2; i++) {
        NSString *textureName = [NSString stringWithFormat:@"runnerJumpDown%d", i];
        SKTexture *texture = [SKTexture textureWithImageNamed:textureName];
        [jumpDownTextures addObject:texture];
    }

    SKAction *jumpDownAnimation = [SKAction animateWithTextures:jumpDownTextures timePerFrame:0.3 resize:YES restore:YES];
    SKAction *moveDownAction = [SKAction moveByX:0 y:-JUMP_HEIGHT duration:0.6];
    SKAction *jumpDownAction = [SKAction group:@[jumpDownAnimation, moveDownAction]];

    _jumpAnimation = [SKAction sequence:@[jumpUpAction, jumpDownAction]];
}

- (void)initCoinAnimation {
    // adding coin animation
    NSMutableArray *coinTextures = [NSMutableArray arrayWithCapacity:8];
    for (int i = 0; i < 8; i++) {
        NSString *textureName = [NSString stringWithFormat:@"coin%d", i];
        SKTexture *texture = [SKTexture textureWithImageNamed:textureName];
        [coinTextures addObject:texture];
    }
    _coinAnimation = [SKAction animateWithTextures:coinTextures timePerFrame:0.1];
}

- (void)moveBackground {
    CGPoint bgVelocity;
    if (_runnerState == incredible) {
        bgVelocity = CGPointMake(-INCREDIBLE_BG_POINTS_PER_SEC, 0);
    }
    else {
        bgVelocity = CGPointMake(-BG_POINTS_PER_SEC, 0);
    }
    CGPoint amtToMove = CGPointMultiplyScalar(bgVelocity, _dt);

    // move the map
    [_bgLayer enumerateChildNodesWithName:BG_NAME usingBlock:^(SKNode *node, BOOL *stop) {
        SKSpriteNode *bg = (SKSpriteNode *) node;
        bg.position = CGPointAdd(bg.position, amtToMove);
        if (bg.position.x <= -bg.size.width) {
            int x = (int) (bg.position.x + bg.size.width * 2);
            bg.position = CGPointMake(x, bg.position.y);

            // NSLog(@"%f %f", bg.position.x, bg.size.width);
            // coins for new map
            [self generateRandomCoins:x];
            [self generateRandomRocks:x];
        }
    }];

    // move the ground
    [_bgLayer enumerateChildNodesWithName:GROUND_NAME usingBlock:^(SKNode *node, BOOL *stop) {
        SKSpriteNode *ground = (SKSpriteNode *) node;
        ground.position = CGPointAdd(ground.position, amtToMove);
        if (ground.position.x <= -ground.size.width) {
            int x = (int) (ground.position.x + ground.size.width * 2);
            ground.position = CGPointMake(x, ground.position.y);
        }
    }];

    [self moveObject:COIN_NAME to:amtToMove];
    [self moveObject:ROCK_NAME to:amtToMove];
}

- (void)moveObject:(NSString *)name to:(CGPoint)amtToMove {
    // move coins
    [_bgLayer enumerateChildNodesWithName:name usingBlock:^(SKNode *node, BOOL *stop) {
        SKSpriteNode *coin = (SKSpriteNode *) node;
        coin.position = CGPointAdd(coin.position, amtToMove);
        if (coin.position.x <= -coin.size.width) {
            // off the screen, remove itself
            [coin removeFromParent];
        }
    }];
}

- (void)didMoveToView:(SKView *)view {
    UISwipeGestureRecognizer *swipeUpGestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipeUp:)];
    swipeUpGestureRecognizer.direction = UISwipeGestureRecognizerDirectionUp;
    [self.view addGestureRecognizer:swipeUpGestureRecognizer];

    UISwipeGestureRecognizer *swipeDownGestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipeDown:)];
    swipeDownGestureRecognizer.direction = UISwipeGestureRecognizerDirectionDown;
    [self.view addGestureRecognizer:swipeDownGestureRecognizer];

    UISwipeGestureRecognizer *swipeRightGestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipeRight:)];
    swipeRightGestureRecognizer.direction = UISwipeGestureRecognizerDirectionRight;
    [self.view addGestureRecognizer:swipeRightGestureRecognizer];
}

- (void)handleSwipeRight:(UISwipeGestureRecognizer *)recognizer {
    NSLog(@"Swipe Right!");
    [self startIncredibleMode];
}

- (void)startIncredibleMode {
    if (_runnerState != running) {
        return;
    }
    _runnerState = incredible;
    // stop it after 5 sec
    SKAction *wait = [SKAction waitForDuration:5.0];
    [_runner runAction:wait completion:^{
        _runnerState = running;
        [_runner removeChildrenInArray:@[_runnerEmitter]];
    }];
    [_runner addChild:_runnerEmitter];
}

- (void)handleSwipeUp:(UISwipeGestureRecognizer *)recognizer {
    NSLog(@"Swipe Up!");
    [self jump];
}

- (void)jump {
    if (_runnerState != running) {
        return;
    }
    _runnerState = jumping;
    [_runner removeActionForKey:RUNNER_ANIMATION_KEY];
    [_runner runAction:_jumpAnimation completion:^{
        [_runner removeAllActions];
        [_runner runAction:[SKAction repeatActionForever:_runningAnimation] withKey:RUNNER_ANIMATION_KEY];
        _runnerState = running;
    }];
    [self runAction:[SKAction playSoundFileNamed:@"jump.mp3" waitForCompletion:NO]];
}

- (void)handleSwipeDown:(UISwipeGestureRecognizer *)recognizer {
    NSLog(@"Swipe Down!");
    [self crouch];
}

- (void)crouch {
    if (_runnerState != running) {
        return;
    }
    _runnerState = crouching;
    [_runner removeActionForKey:RUNNER_ANIMATION_KEY];
    [_runner runAction:_crouchAnimation completion:^{
        [_runner removeAllActions];
        [_runner runAction:[SKAction repeatActionForever:_runningAnimation] withKey:RUNNER_ANIMATION_KEY];
        _runnerState = running;
    }];
    [self runAction:[SKAction playSoundFileNamed:@"crouch.mp3" waitForCompletion:NO]];
}


- (void)generateRandomCoins:(int)x {
    for (int i = 0; i < COINS_PER_MAP; ++i) {
        x += (arc4random() % COIN_RANDOM_FACTOR);
        SKSpriteNode *coin = [SKSpriteNode spriteNodeWithImageNamed:@"coin0"];
        coin.position = CGPointMake(x, _groundHalfHeight + RUNNER_HEIGHT / 2.0);
        coin.anchorPoint = CGPointZero;
        coin.name = COIN_NAME;
        [coin runAction:[SKAction repeatActionForever:_coinAnimation]];
        [_bgLayer addChild:coin];
    }
}

- (void)generateRandomRocks:(int)x {
    SKSpriteNode *rock = [SKSpriteNode spriteNodeWithImageNamed:@"rock"];
    int x1 = x + (arc4random() % ROCK_RANDOM_FACTOR);
    rock.position = CGPointMake(x1, _groundHalfHeight + RUNNER_HEIGHT / 2.0);
    rock.anchorPoint = CGPointZero;
    rock.name = ROCK_NAME;
    [_bgLayer addChild:rock];

    int x2 = x + (arc4random() % ROCK_RANDOM_FACTOR);
    SKSpriteNode *hathpace = [SKSpriteNode spriteNodeWithImageNamed:@"hathpace"];
    hathpace.position = CGPointMake(x2, _groundHalfHeight + RUNNER_HEIGHT * 1.5);
    hathpace.name = ROCK_NAME;
    [_bgLayer addChild:hathpace];
}

- (void)checkCollisions {
    // Check the coins
    [_bgLayer enumerateChildNodesWithName:COIN_NAME
                               usingBlock:^(SKNode *node, BOOL *stop) {
                                   SKSpriteNode *coin = (SKSpriteNode *) node;
                                   if (CGRectIntersectsRect(coin.frame, _runner.frame)) {
                                       [self runAction:[SKAction playSoundFileNamed:@"pickup_coin.mp3" waitForCompletion:NO]];
                                       _coinsLabel.text = [NSString stringWithFormat:@"Coins: %d", ++_coins];
                                       [coin removeFromParent];
                                   }
                               }];

    // Check the rocks
    [_bgLayer enumerateChildNodesWithName:ROCK_NAME
                               usingBlock:^(SKNode *node, BOOL *stop) {
                                   SKSpriteNode *rock = (SKSpriteNode *) node;
                                   CGRect smallerFrame = CGRectInset(rock.frame, 20, 20);
                                   if (CGRectIntersectsRect(_runner.frame, smallerFrame)) {
                                       if (_runnerState == incredible) {
                                           [rock removeFromParent];
                                       }
                                       else {
                                           [self gameOver];
                                       }
                                   }
                               }];
}

- (void)gameOver {
    NSLog(@"GameOver");
    _isGameOver = YES;
    [_runner removeActionForKey:RUNNER_ANIMATION_KEY];
    EndScene *endScene = [[EndScene alloc] initWithSize:self.size showStartButton:YES];
    SKTransition *reveal = [SKTransition flipHorizontalWithDuration:2.0];
    [self.view presentScene:endScene transition:reveal];

    _meter1 = [[NSUserDefaults standardUserDefaults] integerForKey:@"HighScoreSaved"];

    if (_meter > _meter1) {
        [[NSUserDefaults standardUserDefaults] setInteger:_meter forKey:@"HighScoreSaved"];
    }
}

- (void)update:(NSTimeInterval)currentTime {
    if (_isGameOver) {
        return;
    }

    if (_lastUpdateTime) {
        _dt = currentTime - _lastUpdateTime;
    } else {
        _dt = 0;
    }
    _lastUpdateTime = currentTime;

    // Runner faster than normal
    if (_runnerState == incredible) {
        _meter += INCREDIBLE_BG_POINTS_PER_SEC / BG_POINTS_PER_SEC;
        _meter1 += INCREDIBLE_BG_POINTS_PER_SEC / BG_POINTS_PER_SEC;
    }
    else {
        ++_meter;
        ++_meter1;
    }
    _scoreLabel.text = [NSString stringWithFormat:@"%d Meters", _meter];
    _highScoreLabel.text = [NSString stringWithFormat:@"%li High Score",(long) _meter1];

    [self checkCollisions];
    [self moveBackground];
}
@end
4

3 回答 3

1

看起来您从未将 isGameOver 设置为 NO。您的更新方法可能会在每次运行时返回。

于 2014-02-27T03:29:00.200 回答
1

最简单的方法是向方法添加NSLog消息- (void)update:(NSTimeInterval)currentTime并查看玩家死亡后发生了什么,同时检查_isGameOver变量对我来说看起来很可疑:)

于 2014-02-25T18:10:36.197 回答
0

我找到了解决方案,相信我,我会因为没有看到这一点而自责。整个代码都在工作,除了(void)update:(NSTimeInterval)currentTime我添加的部分++_meter1;是完全不必要的,因为此时不需要添加任何高分。在这部分我只需要更新分数。无论如何,分数加高分的加法正在发生(id)initWithSize:(CGSize)size,我错误地编码了。我刚刚评论了++_meter1;它,它就像一个魅力。

于 2014-02-28T17:34:53.937 回答