2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

日本語プログラミング言語「なでしこ」Advent Calendar 2023

Day 19

なでしこさんで「ひろいもの」を作るよ! ④ ~いろいろ機能を追加して完成~

Last updated at Posted at 2023-12-18

 問題を作成したり、それをダウンロードしたり、またそれをアップロードして遊んだりできるようにする。
 あるいは、なでしこさんの新機能をお試しし、効果音を鳴らしてみたりする。
 あるいはまた、自作のプラグインを使ってみようとしたところ、プラグインを更新し忘れていたことに気づいて反省したりする。

問題を自分で入力する機能

 規定の問題を解くだけでなく、自分で問題を入力することが出来たら便利ですよね。
 雑誌などの問題も、実際に石を拾えるようにしたら、頭の中だけで考えるよりも解答が捗ります。
 また、自分でもっとむじゅかしい問題を考えて、誰かに解かせたり?

問題を入力する

 石のない所を押したら石を置き、有るところを押したら石を消すようにすれば良いだけです。
 問題入力中のフラグを用意して、キャンバスを押した時のイベントに追加します。

描画中キャンバスマウス押した時には
    ,マウス位置取得
    もし問題入力中フラグオンならば
        もし現在データ[][]ならば
            現在データ[][]
        違えば
            現在データ[][]
        ここまで
        拾った履歴[,]配列追加
        盤面描画戻る
    ここまで

 基本的に言えばそれだけ! なので、改めて記事にするようなコトは特に無かった。
 引っ張ったはいいけどどうしよう😅

入力完了する

 入力が完了したら、尋ねるを使って問題名の入力を促し、それをキーにして新しい辞書型変数に登録することにします。
 でも、辞書型変数についても既にやったしねー💧

 問題集も、作成したデータに差し替え、セレクトボックスの内容も書き換え、これで入力した問題を遊べるようになりました。 

ダイアログキャンセル値NULL
  「問題名を入力してください」尋ねる
  問題名それ
  もしそれ=NULLならば戻る
  もしそれならば
    作成データ[問題名]現在データ
    問題集作成データ
    問題一覧問題集辞書キー列挙
    問題セレクト問題一覧セレクトボックスアイテム設定
    問題セレクト問題名テキスト設定
  違えば
    「キャンセルします」二択
    もしそれいいえならば
      戻る
    ここまで
  ここまで

 そういえば、やっぱやめた~ってなった時はどうするかなーと思い、新しいUIを作るほどのことでも無いので、尋ねるでキャンセルを押した時には何もせず戻り(問題入力続行)、問題名を入力せずにOKした場合には問題入力自体をキャンセルしてゲーム画面に戻る、ということにしてみました。

ダイアログキャンセル値

 これは、一番最近のバージョンアップ(v3.4.24)でなでしこさんに追加された最新の機能です☆

👉 なでしこ3 マニュアル > plugin_browser/ダイアログキャンセル値

 実は、v1には元々あった機能です。
 なでしこでは、簡単のため、未入力でOKしたときも、キャンセルをした場合も空文字列が返るようになっています。
 でも、処理を分けたい場合もありますよね。
 そこで、ダイアログキャンセル値です!

 未入力でOKした場合には空文字、キャンセルした場合にはダイアログキャンセル値が返るようになりました。
 ダイアログキャンセル値のデフォルトは空なので、もともとの動作と変わりはありませんが、処理を分けたい! てなった時にはダイアログキャンセル値にベツのものを代入しておくことで判定出来るようになるって寸法です。

 ここではじゃばすくりぷとに合わせてNULLを指定しています。

もっと大きな問題も入力したい

 今の碁盤のサイズは、古典の12問に合わせて作っていますが、もっと大きなサイズの問題も入力できるよう、碁盤の行列数を変更できるようにします。
 行数、列数を入力するエディタを作成し、

👉 なでしこ3 マニュアル > plugin_browser/エディタ作成

 問題作成ボタンを押したらテキスト取得してキャンバスのサイズを変更、碁盤を再描画すれば良いだけです。

問題作成ボタンクリックした時には
    もし問題入力中フラグオフならば
        ゲーム中フラグオフ
        問題入力中フラグオン
        行数行数エディタテキスト取得
        列数列数エディタテキスト取得
        画面サイズ計算
        描画中キャンバス「幅」画面幅DOM属性設定
        描画中キャンバス「高さ」画面高さDOM属性設定
        盤面描画
// ~~~ 略 ~~~

 これで、好きなサイズの問題を入力し、遊ぶことが出来るようになりました!
 やったね🎶

 ・・・と、ここまでやってきてワタクシが欲しかった欲しかった機能は一応ひととおり追加出来たのですが、結局書くことたいして無いじゃん・・・と、ワタクシ途方に暮れてしまいました💧💧💧
 プログラムの内容的にもなでしこの機能的にも、目新しい内容は特になく、唯一、ダイアログキャンセル値の紹介が出来た程度です。
 このままじゃ終われない!

別の問題集を読み込む機能

 せっかくなので、3日目の記事で書いた、ローカルのファイルを読み込むプラグインを実際に使ってみます。

 取り込みます。

!「https://n3s.nadesi.com/plain/nadesiko3-FileReader.js」取り込む

 と、ここで!
 こうして記事を書いておきながら、プラグインの方が新しいものに更新されていなかった! とゆう事実に気がつきました😱
 ダウンロードが使えるようになっていなかったのねん💧
 というわけで、遅まきながら貯蔵庫のプラグインを更新しました。
 ほんとスミマセン🙏🙇‍♀️

作成した問題をダウンロードできるようにする

 さて、気を取り直して・・・
 折角入力しても、今のままではひとたびゲーム画面を閉じたら失われてしまいます。
 いつでも再び遊べるようにしたいです。

 辞書型変数は、JSONエンコードすればテキストダウンロード出来ます。

ダウンロードボタン「ダウンロード」ボタン作成
ダウンロードボタンクリックした時には
    作成データJSONエンコードして「ひろいもの問題集.json」テキストダウンロード
ここまで

 こんだけ!
 一度問題入力をするとセレクトボックスの内容が新しく作成した問題集に差し替わるのですが、以降は連続して問題入力すれば、新しい問題集に追加されていくので、一問だけではなく問題集として作成し、ダウンロードすることが出来ます。

ローカルの問題ファイルを読み込む

 ダウンロードしてもソレを読み込めないと意味無いので、ローカルPCにある問題集を遊べるようにします。
 JSONファイルはUTF-8のテキストとして開き、JSONデコードすれば辞書型変数として使えるようになります。

問題選択ボタンファイル選択作成
問題選択ボタンファイル選択した時には
    ファイル対象[0]
    ファイルテキストファイル開いた時には
        問題集対象JSONデコード
        問題集変更してゲーム開始
    ここまで
ここまで

 こんだけ!
 なお、問題集変更の中で、セレクトボックスの内容更新と、碁盤サイズの変更を行っています。

●問題集変更
    問題一覧問題集辞書キー列挙
    問題セレクト問題一覧セレクトボックスアイテム設定
    行列数カウントして画面サイズ計算
    空データ作成
    描画中キャンバス「幅」画面幅DOM属性設定
    描画中キャンバス「高さ」画面高さDOM属性設定
ここまで

貯蔵庫の問題を読み込む

 良い問題が出来た時、それを貯蔵庫に素材としてアップロードしておけば、ほかの誰かに遊んでもらえるかも知れません。
 貯蔵庫に素材としてアップロードされている問題集を読み込み、差し替えることが出来るようにします。
 これは、最初に問題集をAJAXで取得するのと同じ事なので、特筆することはありません。
 エディタに入力した絶対URLからAJAX_JSON取得するだけです。

素材URLエディタ作成
改行作成
「素材の絶対URLを入力してください:」ラベル作成
素材取得ボタン「読み込む」ボタン作成
素材取得ボタンクリックした時には
    問題集素材URLテキスト取得からAJAX_JSON取得
    問題集変更してゲーム開始
ここまで

 問題入力をして問題集が変わっている状態でhttps://n3s.nadesi.com/image.php?f=384.jsonを読み込むことで元の古典問題集に戻すことができました。
 

そうだ音を鳴らそう!

 折角MML演奏が実装されて、ファイルを用意しなくても音が鳴らせるようになったワケですからそれを利用して効果音を鳴らしてみることにします🎵🎶

👉 📖 なでしこ3 マニュアル > nadesiko3-music/音楽

 MML演奏については、アドベントカレンダー4日目でクジラ飛行机氏自らが紹介して下さっておりますので、そちらも合わせてお読み下さい。

 とりあえず取り込む。

!『拡張プラグイン:music.js@1.0.2』取り込む

プラグイン取り込みの省略記法

 なんと、プラグイン取り込みに省略記法が導入されて、とっても簡単に指定出来るようになっています✨

👉 なでしこ3 マニュアル > 文法/プラグイン取込 > 拡張プラグインの省略記法

 貯蔵庫からはNAKO3プラグインが省略記法で取り込めて、JSプラグインは命名規則に沿って作成して公開すると、公式プラグイン以外もこの省略記法で取り込めるようになるってコトなんですね。
 うーん、JSプラグインはnpmで公開したほうがいいってコトなんですかね~?
 これまで、貯蔵庫で使う前提の物は、貯蔵庫から取り込みでいいかと思ってたんですけどね~。

👉 なでしこ3 マニュアル > FAQ/作ったプラグインをnpmで公開する方法

 でもとりあえず、まずnpmにユーザー登録(Sign Up) ができないワタクシですよ😭
 ぐーぐる翻訳さんたすけて‼️

 うーん、そのうちがんばる💧

音を鳴らします

 まあ、それはさておき!
 なにしろMML演奏の素晴らしい点は、「ドレミ」表記で記述出来ることです!(もちろん普通にcdeのMMLでも記述できます)
 というわけで、こんな感じで効果音を設定します。
 センスは無いけどゆるして💧

#効果音
正解音「音階7 音符32 音量80 ド64レ#」
ハズレ音「音階3 音符8 ド」
クリア音『音階6 音符16【「ファ"ラド」「ファ"ラド」「ド"ファ"ラ」】「ファ"ラド」ーーーーー』
ゲームオーバー音『調♭(ソラシレミ) テンポ 180
トラック1 音階4 シシ8.シ16シ↑レ8.ド16 ド8.↓シ16シ8.シ16シ
トラック2 音階4 音量 60 ファソファソファソファ』

 あとは、マウス押したときのイベントと、終了判定にMML演奏を追加するだけです!

描画中キャンバスマウス押した時には
    ,マウス位置取得
// ~~~ 中略 ~~~
    もしゲーム中フラグオフならば戻る
    もし拾えるデータ[][]1ならば
        正解音MML演奏
        現在データ[][]0
        進行方向[,]進行方向更新
        拾った履歴[,,進行方向]配列追加
        進行方向[,]から拾えるデータ更新
    違えば
        ハズレ音MML演奏
    ここまで
    盤面描画0.1秒待つ終了判定
ここまで

 再生の反応もよく、効果音として十分に機能していますよ‼️🎶

●終了判定
    現在データ空データ同じ配列か確認
    もしそれはいならば:
        
クリア音MML演奏
        「クリア!」言う
        ゲーム中フラグオフ戻る
    拾えるデータ空データ同じ配列か確認
    もしそれはいならば:
      
ゲームオーバー音MML演奏
        「失敗!」言う
        ゲーム中フラグオフ戻る
ここまで

 ・・・あれ?

ダイアログとMML演奏を同時に使う場合

 注意点としては、言うなどのダイアログを使用すると、先にMML演奏があってもダイアログの方が先に開いてしまいます。そして、ダイアログが閉じてから演奏が始まります。

!『拡張プラグイン:music.js』取り込む
「ドレミファソラシ↑ド」MML演奏
「OK」言う

 演奏後すぐに次の命令が実行されるのはある意味当然で、そうでなければBGMなどとして使うことが出来ないですからね~。
 でも、ダイアログが演奏を止めてしまうので困ったなと言うところ。
 感覚的にはやはり、クリアしたら先に曲が鳴って、それからダイアログじゃないですか?

 ちなみに、オーディオ再生の場合はどうかというと、Firefoxの場合はイイ感じに再生されつつダイアログも開くのですが、chrome系の場合はご同様にダイアログが先に開き、閉じてから再生が始まります💧
 しかし、chrome系も、オーディオ再生言うの間に秒待つでごく短いウェイトを入れてやることで、Firefox同様ダイアログ開きつつ再生させることが出来ますし、オーディオ命令の中にはオーディオ長さ取得があり、取得した秒数だけウェイトを入れてやることで曲が再生し終わった後でダイアログを開くことも出来ます。

 がっ!
 MML演奏はまた動作が異なりました。
 曲より短いウェイトを入れた場合、その秒数分だけ再生されてダイアログが上がり、曲が中断されてしまいます><
 そして、ダイアログを閉じるとFirefoxの場合は続きが演奏され、chromeは演奏されませんでした。
 ダイアログの動作はブラウザごと仕様が違っててめんどくさい~😣
 でも、どちらにしてもダイアログを開きつつ演奏もさせるというのは難しそうです。

 ならばやはり、曲を再生してからダイアログとしたい。
 でも、音楽命令の中に曲の長さを取得する命令はありません。
 しょうがない、ちょっと自分で計算してみよう。

曲の長さを計算

 特に指定をしていなければ、テンポのデフォルトは120、音符は四分音符です。
 テンポとは1分間に四分音符が何個入るかなので、テンポ120なら1分間に四分音符が120入る速さです。
60÷120で、0.5が四分音符一個の長さとなり、ドレミファソラシドの8音なら4秒という計算になるはずです。

!『拡張プラグイン:music.js』取り込む
「ドレミファソラシ↑ド」MML演奏
4秒待つ
「OK」言う

 あれー?
 良いかと思いきや、ダイアログ閉じた後にちょっと鳴る~💧
 残響というか余韻というかの分を考慮しなきゃなようです。
 とりあえず1秒くらいプラスしておく。

●終了判定
    現在データ空データ同じ配列か確認
    もしそれはいならば:
        
ゲーム中フラグオフ
        クリア音MML演奏
        60/120*3+1秒待つ
        「クリア!」言う
        戻る
    拾えるデータ空データ同じ配列か確認
    もしそれはいならば:
        
ゲーム中フラグオフ
        ゲームオーバー音MML演奏
        60/180*7+1秒待つ
        「失敗!」言う
        戻る
ここまで

 だいたい良い感じ?
 完全に残響が消えるまでとしてしまうとダイアログ開くのがのろくさい印象になるので、こんなものかと思います。

おわります

 できました‼️ 完成です✨
 ムダに引っ張りましたが、なでしこの新機能のダイアログキャンセル値の紹介や、MML演奏を効果音として使えるか試したり、自作のプラグインも実際に使ってみたりと頑張りました。

 長くなったので、コードはこちらから確認して下さい~。
 遊んでみて下さいね☆

 その後、効果音をオンオフするチェックを加えたり、問題作成や問題データ取り込みのUIを開閉出来るようにしたりしなどしています。

2
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?