9

cocos2d の SimpleAudioEngine の機能を、いくつかの効果音をチェーンのように次々と再生できるように拡張しようとしています。拡張機能でこれを実行しようとしました。しかし、すべてのサウンド ファイルの名前を記憶する iVar と、現在再生中のサウンドを記憶する iVar もおそらく必要であることに気付きました。

ただし、カテゴリに iVar を追加できないようです。代わりに拡張子を使用しようとしましたが、クラスの元の .m ファイルにある必要があるようで、それも機能しません。これを可能にする別の方法はありますか?

カテゴリのヘッダー

#import <Foundation/Foundation.h>
@interface SimpleAudioEngine(SoundChainHelper)<CDLongAudioSourceDelegate>
-(void)playSoundChainWithFileNames:(NSString*) filename, ...;
@end

そして、拡張子を持つ .m ファイル:

#import "SoundChainHelper.h"

@interface SimpleAudioEngine() {
    NSMutableArray* soundsInChain;
    int currentSound;
}
@end

@implementation SimpleAudioEngine(SoundChainHelper)

// read in all filenames and start off playing process
-(void)playSoundChainWithFileNames:(NSString*) filename, ... {
    soundsInChain = [[NSMutableArray alloc] initWithCapacity:5];

    va_list params;
    va_start(params,filename);

    while (filename) {
        [soundsInChain addObject:filename];
        filename = va_arg(params, NSString*);
    }
    va_end(params);
    currentSound = 0;
    [self cdAudioSourceDidFinishPlaying:nil];
}

// play first file, this will also always automatically be called as soon as the previous sound has finished playing
-(void)cdAudioSourceDidFinishPlaying:(CDLongAudioSource *)audioSource {
    if ([soundsInChain count] > currentSound) {
        CDLongAudioSource* mySound = [[CDAudioManager sharedManager] audioSourceForChannel:kASC_Right];
        [mySound load:[soundsInChain objectAtIndex:0]];
        mySound.delegate = self;
        [mySound play];
        currentSound++;
    }
}

@end

別の方法として、iVar をコンパイルするプロパティとして定義しようとしました。ただし、それらを合成することも、それらを任意の方法にバインドする他の方法もありません。

この機能を SimpleAudioEngine のカテゴリとして実装しようとしています。これにより、すべてのサウンドの問題を処理するクラスを 1 つだけ覚えればよいようになります。そして、次のように単純なチェーンを作成できるようにします。

[[SimpleAudioEngine sharedEngine] playSoundChainWithFileNames:@"6a_loose1D.mp3", @"6a_loose2D.mp3", @"6a_loose3D.mp3", @"6a_loose4D.mp3", @"6b_won1D.mp3", nil];

同じ/同様の結果が得られる別の方法があれば、私も非常に感謝しています。

4

2 に答える 2

24

インスタンス変数 (または合成された @properties) をカテゴリに追加できないことは正しいです。この制限は、Objective-C ランタイムの連想参照のサポートを使用して回避できます。

このようなもの:

あなたの.hで:

@interface SimpleAudioEngine (SoundChainHelper)
    @property (nonatomic, retain) NSMutableArray *soundsInChain;
@end

あなたの.mで:

#import <objc/runtime.h>
static char soundsInChainKey;

@implementation SimpleAudioEngine (SoundChainHelper)

- (NSMutableArray *)soundsInChain
{
   return objc_getAssociatedObject(self, &soundsInChainKey);
}

- (void)setSoundsInChain:(NSMutableArray *)array
{
    objc_setAssociatedObject(self, &soundsInChainKey, array, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

@end

(標準の免責事項が適用されます。これはブラウザーに入力したもので、テストはしていませんが、以前にこの手法を使用したことがあります。)

私がリンクしたドキュメントには、連想参照がどのように機能するかについてのより多くの情報があります。

于 2012-05-08T16:37:07.787 に答える