嗨起來
最近有一款日本小游戲劝篷,比較火,就是我標題中寫的這款游戲民宿。用音量來控制角色的移動和跳躍娇妓。感興趣的可以看看這篇文章http://mp.weixin.qq.com/s/5kwX_h-Z6tS5SVJ_S-B6wg
那作為一個資深程序猿,看到這款游戲的第一想法活鹰,肯定是探究下背后的原理了9 !V救骸(但我的第一想法卻是錄了個視頻發(fā)給朋友娛樂着绷。。赖舟。)
寫了個小Demo
大致效果如下:
效果圖
<li>小精靈的行動通過獲取麥克風采集到的音量來控制
<li>小精靈只能上下移動蓬戚,代表跳躍和墜落
<li>下面的白色溝壑,是一個UIView宾抓,通過移動溝壑子漩,來制造小精靈前進的錯覺豫喧。
<li>白色UIView在滾動出屏幕后再次從屏幕右側出現,以達到重復出現陷阱的目的
<li>通過判斷角色是否落在了溝壑上來進行游戲失敗的處理
麥克風的調用
麥克風輸入AVFoundation框架幢泼,所以我們導入:
#import <AVFoundation/AVFoundation.h>
再加兩個屬性紧显,一個用于引用我們調用的麥克風,一個用于定期檢測麥克風的音量大小缕棵。
// 檢測音量的定時器
@property (nonatomic, strong) NSTimer *levelTimer;
// 麥克風
@property (nonatomic, strong) AVAudioRecorder *recorder;
請求麥克風權限孵班,并開始錄音
# pragma mark - 麥克風相關
- (void)askForRecorder {
// 獲取麥克風權限
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
/* 不需要保存錄音文件 */
NSURL *url = [NSURL fileURLWithPath:@"/dev/null"];
NSDictionary *settings = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithFloat: 44100.0], AVSampleRateKey,
[NSNumber numberWithInt: kAudioFormatAppleLossless], AVFormatIDKey,
[NSNumber numberWithInt: 2], AVNumberOfChannelsKey,
[NSNumber numberWithInt: AVAudioQualityMax], AVEncoderAudioQualityKey,
nil];
NSError *error;
self.recorder = [[AVAudioRecorder alloc] initWithURL:url settings:settings error:&error];
if (self.recorder) {
[self.recorder prepareToRecord];
self.recorder.meteringEnabled = YES;
[self.recorder record];
self.levelTimer = [NSTimer scheduledTimerWithTimeInterval:0.01 target: self selector: @selector(levelTimerCallback:) userInfo: nil repeats: YES];
} else {
NSLog(@"%@", [error description]);
}
}
這里iOS10需要在info.plist中加入申請麥克風權限的描述,防止崩潰
<key>NSMicrophoneUsageDescription</key>
<string>讓我調用下相機唄~</string>
timer調用的方法招驴,就能獲取麥克風的音量了
/* 該方法確實會隨環(huán)境音量變化而變化篙程,但具體分貝值是否準確暫時沒有研究 */
- (void)levelTimerCallback:(NSTimer *)timer {
[self.recorder updateMeters];
float level; // The linear 0.0 .. 1.0 value we need.
float minDecibels = -80.0f; // Or use -60dB, which I measured in a silent room.
float decibels = [self.recorder averagePowerForChannel:0];
if (decibels < minDecibels)
{
level = 0.0f;
}
else if (decibels >= 0.0f)
{
level = 1.0f;
}
else
{
float root = 2.0f;
float minAmp = powf(10.0f, 0.05f * minDecibels);
float inverseAmpRange = 1.0f / (1.0f - minAmp);
float amp = powf(10.0f, 0.05f * decibels);
float adjAmp = (amp - minAmp) * inverseAmpRange;
level = powf(adjAmp, 1.0f / root);
}
/* level 范圍[0 ~ 1], 轉為[0 ~120] 之間 */
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"%f", level*120);
});
}
額外再補全UI邏輯就OK了。
附上Demo
https://github.com/ZhaoheMHz/SpeakerDemo 可以在這個基礎上增加陷阱的隨機寬度别厘、角色跳躍高度根據聲音大小來調整等虱饿,能完善好,也是個不錯的仿品触趴。