このページの本文へ

日曜プログラマーのための「Clovaスキルつくり隊!」 第6回

21の問題と7つの正解を持つ音を使ったゲーム作り

鳴った音の音階を当てる「絶対音感ゲーム」スキルをつくってみよう

2019年10月03日 13時00分更新

文● ASCII編集部

  • この記事をはてなブックマークに追加
  • 本文印刷

 というわけで、さっそく見て行きましょう。できあがったのがこちらのスキルです。

 ソースコードはこちら(リスト1)。Node.js(サーバー側でJavaScriptを使う言語)で書かれています。

const clova = require('@line/clova-cek-sdk-nodejs');
const express = require('express');

//①音階ファイルを用意
const scaleList = [
{
noteName:'ド',
file:[
'/PATH/TO/C3.mp3',
'/PATH/TO/C4.mp3',
'/PATH/TO/C5.mp3',
]
},
{
noteName:'レ',
file:[
'/PATH/TO/D3.mp3',
'/PATH/TO/D4.mp3',
'/PATH/TO/D5.mp3',
]
},
{
noteName:'ミ',
file:[
'/PATH/TO/E3.mp3',
'/PATH/TO/E4.mp3',
'/PATH/TO/E5.mp3',
]
},
{
noteName:'ファ',
file:[
'/PATH/TO/F3.mp3',
'/PATH/TO/F4.mp3',
'/PATH/TO/F5.mp3',
]
},
{
noteName:'ソ',
file:[
'/PATH/TO/G3.mp3',
'/PATH/TO/G4.mp3',
'/PATH/TO/G5.mp3',
]
},
{
noteName:'ラ',
file:[
'/PATH/TO/A3.mp3',
'/PATH/TO/A4.mp3',
'/PATH/TO/A5.mp3',
]
},
{
noteName:'シ',
file:[
'/PATH/TO/B3.mp3',
'/PATH/TO/B4.mp3',
'/PATH/TO/B5.mp3',
]
},
];

const clovaSkillHandler = clova.Client
.configureSkill()

//起動時
.onLaunchRequest(responseHelper => {
responseHelper.setSpeechList([
{
lang: 'ja',
type: 'PlainText',
value: '絶対音感、を起動しました。ピアノの音を聞いた後、音階を答えるゲームです。'
},
{
lang: 'ja',
type: 'PlainText',
value: '再生、または、スタート、の掛け声で、音を流します。'
}
]);
})

//ユーザーからの発話が来たら反応する箇所
.onIntentRequest(async responseHelper => {
//セッション情報を取得
const note_session = responseHelper.getSessionAttributes();
console.log(note_session);

const intent = responseHelper.getIntentName();
switch (intent) {
//読んで
case 'OnkanIntent':
//②音階をランダムで取得する。
const random_note = Math.floor(Math.random() * Object.keys(scaleList).length);

//③オクターブのファイルをランダムで取得する。
const random_file = Math.floor(Math.random() * Object.keys(scaleList[random_note]['file']).length);

//④セッション情報の保存
responseHelper.setSessionAttributes({note:random_note, file:random_file});

//⑤音を再生する
responseHelper.setSimpleSpeech({
lang: '',
type: 'URL',
value: scaleList[random_note]['file'][random_file]
});
break;
//解答
case 'AnswerIntent':
if (Object.keys(note_session).length == 0) {
responseHelper.setSimpleSpeech({
lang: 'ja',
type: 'PlainText',
value: '再生した音がありません。',
});
break;
}

//スロットから解答した音名を取得する。
const scaleSlot = responseHelper.getSlot('FirstScaleSlot');

//セッションからscaleListの音名を取得する。
const noteName = scaleList[note_session['note']]['noteName'];

//⑥スロットの値とセッションの値がすべて一致していたら正解
if (scaleSlot === noteName) {
responseHelper.setSimpleSpeech({
lang: 'ja',
type: 'PlainText',
value: '正解です。',
});
} else {
responseHelper.setSpeechList([
{
lang: 'ja',
type: 'PlainText',
value: '不正解です。',
},
{
lang: 'ja',
type: 'PlainText',
value: '正解は、' + noteName + '、です。',
},
{
lang: 'ja',
type: 'PlainText',
value: '次のゲームをするには、再生、または、スタート、と言ってください。もう一度聞きたい場合は、もう一度、または、リピート、と言ってみてください。',
},
]);
}
break;
//もう一度
case 'RepeatIntent':
if (Object.keys(note_session).length == 0) {
responseHelper.setSimpleSpeech({
lang: 'ja',
type: 'PlainText',
value: '再生した音がありません。',
});
break;
}

//セッションから音楽ファイルを取得する。
responseHelper.setSimpleSpeech({
lang: '',
type: 'URL',
value: scaleList[note_session['note']]['file'][note_session['file']]
});
break;
//使い方
case 'Clova.GuideIntent':
responseHelper.setSpeechList([
{
lang: 'ja',
type: 'PlainText',
value: '再生、または、スタート、の掛け声で、音を流します。'
},
{
lang: 'ja',
type: 'PlainText',
value: 'リピート、または、もう一度、と言うと、もう一度同じ音を流します。'
},
{
lang: 'ja',
type: 'PlainText',
value: '解答は、ピアノの音を聞いた後、その音階を答えてください。'
}
]);
break;
case 'Clova.FallbackIntent':
default:
responseHelper.setSimpleSpeech({
lang: 'ja',
type: 'PlainText',
value: '始めるには、再生、または、スタート、といってみてください。'
});
break;
}

console.log('Intent:' + intent);
})

//終了時
.onSessionEndedRequest(responseHelper => {
const sessionId = responseHelper.getSessionId();
})
.handle();

const app = new express();
const port = process.env.PORT || 3000;

//リクエストの検証を行う場合。環境変数APPLICATION_ID(値はClova Developer Center上で入力したExtension ID)が必須
const clovaMiddleware = clova.Middleware({applicationId: 'YOUR_APPLICATION_ID'});
app.post('/PATH/TO/DEV', clovaMiddleware, clovaSkillHandler);

app.listen(port, () => console.log(`Server running on `));

 どんな命令が実行されているかは、「//」で始まる行に書いてあるコメントを参照してください。

 それでは、今回のプログラムのポイントを少し詳しくみていきましょう。

カテゴリートップへ

この連載の記事