【问题标题】:xcode sprite kit background musicxcode sprite kit 背景音乐
【发布时间】:2014-07-12 15:20:37
【问题描述】:

我有一个使用 sprite kit 制作的游戏,我添加了一个 30 秒的音频文件,作为我使用 av 音频播放器的游戏的背景音乐无限循环。当游戏从某个状态切换时,我想停止并从我的场景文件开始播放音乐。

这是我的视图 controller.m 文件,我在其中添加了停止音乐方法

@implementation ViewController

- (void)viewDidLayoutSubviews 
{
    [super viewDidLayoutSubviews];

    NSError *error;
    NSURL *backgroundMusicUrl = [[NSBundle mainBundle] URLForResource:@"game" withExtension:@"wav"];
    _backgroundMusicPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:backgroundMusicUrl error:&error];
    _backgroundMusicPlayer.numberOfLoops =  -1;
    [_backgroundMusicPlayer prepareToPlay];
    [_backgroundMusicPlayer play];

    SKView * skView = (SKView *)self.view;

    // Create and configure the scene.
    SKScene * scene = [MyScene sceneWithSize:skView.bounds.size];
    scene.scaleMode = SKSceneScaleModeAspectFill;

    // Present the scene.
    [skView presentScene:scene];
}

-(void)stopMusic
{
    [_backgroundMusicPlayer pause];
}

然后在我的 scene.m 文件中,我尝试调用 stop music 方法,但是背景音乐并没有停止播放。

-(void)switchToTutorial{

    [[ViewController alloc] stopMusic];

    _gameState = GameStateTutorial;

    //remove unwatnted nodes
    for (int i = 0; i < _mainMenu.count; i++)
    {
        SKSpriteNode *chosenNode = [_mainMenu objectAtIndex:i];
        [chosenNode removeFromParent];
    }

    for (int i = 0; i < _mainMenuButtons.count; i++)
    {
        SKSpriteNode *chosenNode = [_mainMenuButtons objectAtIndex:i];
        [chosenNode removeFromParent];
    }
    [self setupTutorial];
}

【问题讨论】:

标签: ios objective-c audio


【解决方案1】:

问题出在这一行:

[[ViewController alloc] stopMusic];

您正在创建一个新的 ViewController 实例,但应该将 stopMusic 消息发送到当前使用的实例。

实现这一点的一种方法是在场景中拥有一个 ViewController 类型的属性并将 viewController 设置为它。

在 MyScene.h 中

@class ViewController; //below the #import
...
@property(weak) ViewController *viewController;

在 MyScene.m 中

#import "ViewController.h"
...
[self.viewController stopMusic]

在 ViewController.m 中

MyScene * scene = [MyScene sceneWithSize:skView.bounds.size];
scene.viewController = self;

这种方法的问题是您必须为每个场景传递 ViewController。也许有一个静态的AVAudioPlayer 和两个静态方法来启动和停止音乐会更容易,然后你可以调用

[ViewController stopMusic];

如果你已经到了那个阶段,你可以考虑创建一个额外的类,即 MusicPlayer 来为你处理所有的音乐。所以你会打电话给

// in ViewControllers viewDidLoad
[MusicPlayer initializePlayer];

//where needed
[MusicPlayer playMusic];
[MusicPlayer stopMusic];

【讨论】:

  • 在 myscene.h 中声明 viewController 属性后,我仍然无法像您说的那样在 view controller.m 中引用它。然后它不允许我在我的 scene.m 中对属性进行停止音乐调用。
  • 抱歉,*scene 当然必须声明为 MyScene,所以编译器知道它是 MyScene。我修改了代码。
  • 你在 ViewController.h 中声明了-(void)stopMusic; 吗?否则场景不知道viewController有这样的方法。
  • 编译器不断让我将 viewController 属性列为 UIviewcontroller 的对象,而不是像您在代码中那样仅列出“ViewController”?这会是个问题吗,因为当我调用 [[ViewController alloc] stopMusic] 时我仍然无法让音乐暂停;
  • 哈哈当然你应该调用 [self.viewController stopMusic] 然后...只需在 myscene 中导入 ViewController.h 以便编译器知道它的存在和方法
猜你喜欢
  • 2022-07-08
  • 1970-01-01
  • 2013-11-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多