・はじめに
※この記事は身内のアドベントカレンダー向けの記事です。最初の方はどうでもいいことをつらつら書き述べているので、読み飛ばしてください。
・誰おま
PMOBの隅っこのあいつ。あいつだよあいつ。
・この記事何
デスクトップマスコットを、プログラミング言語「なでしこ」を用いて書くという記事です。
この記事を書いた動機は、PMOBのアドベントカレンダーへの参加です。
PMOBアドベントカレンダーの埋まり具合を見てたら、「自分も参加しなくては」という使命感に駆られました。
ただ、書きたい記事というものがなかなか思い浮かばなかったのですが、前々から作りたいなぁと思っていたデスクトップマスコットのプログラミングをちょうどやっている最中でしたので、これを記事にしようという事になりました。
・デスクトップマスコットis何(ここいらない)
ロックマンエグゼシリーズをご存知でしょうか?
作中では、一般普及している携帯端末の中にナビと呼ばれるキャラクターが色々やってます(適当)
それをイメージできる方ならすぐ理解できるかと思いますが、名前の通り、デスクトップ上で色々な動きを見せたり、何かしたり、何もしなかったりするプログラムです(機能があるものだとアプリケーションのランチャーだったりとかする)
代表的なものでは、「伺か(うかがか)」や「しめじ」などがあります。
機能は様々で、辞書を元に喋ったり(文章を表示)、飛んだりはねたりウィンドウをよじ登ったりします。
・なでしこis何
日本語でプログラミングが行えるという、一風変わったプログラミング言語です。
命令も日本語、変数にも日本語が扱えるなどの特徴があります。
この言語の利点は、プログラミングに馴染みが無くても、日本語さえ分かれば、簡単なプログラムを作成できる点でしょうか。
ですが、複雑なプログラムを作ろうとすると、日本語であるのもあいまって、非常に読みにくいソースコードになりがちです。また、処理も重めです。
なでしこの利点は日本語であることであり、欠点も日本語であることだといえます。
・じゃあなんでなでしこ使うん
なでしこの利点と欠点を述べましたが、それを上回るだけの利点がなでしこにはあると思います。
それは、「各種ライブラリの存在」です。
なでしこは有志の手によって作成されたライブラリがいくつか存在しています。
例として、Nakotter(TwitterAPIを叩くライブラリ)、aquestalk(所謂ゆっくりボイスで文章を読み上げるライブラリ)などが挙げられます。
他の言語ではいろいろと面倒な手続きを踏まなくてはならない部分が、「日本語が使える」だけで扱えてしまうのです!(ただちょっと色々と中途半端なんだよね...)
そのため、小物を作るのにはかなりうってつけの言語だと思います。
・プログラムを書く
・ソースコード
母艦の画像は「もぶぴー.gif」
母艦を画像通り変形
母艦をダブルクリックした時は~終わる
母艦速度は0
//ふきだしフォームの作成//
ふきだしとはフォーム
そのWは300
そのHは200
ふきだしを吹き出し変形
//せりふラベルの作成//
台詞とはラベル
台詞について
親部品はふきだし
Xは70
Yは70
Wは200
Hは100
文字位置は「中央」
//せりふ読み込み処理//
台詞集とは配列
「dict.txt」を毎行読んで反復
台詞集¥(回数-1)はそれ
台詞数は回数
//せりふ読み込み処理はここまで//
//ふきだしの処理//
ふきだしタイマーとはタイマー
その間隔は3
その時満ちた時は
ふきだしのXは(母艦の左-ふきだしのW)
ふきだしのYは(母艦の上-ふきだしのH)
ふきだしの可視はオン
台詞のテキストは台詞集¥(台詞数の乱数)
1秒待つ
ふきだしの可視はオフ
表示クリア
//ふきだしの処理はここまで//
//定期イベント設定//
定期間隔=0.01
//定期イベント設定ここまで//
//定期イベント1:重力で落下//
天井位置=0
地面位置=600
●落ちろ
重力は9.8*定期間隔
母艦速度は母艦速度+重力
母艦のYは母艦のY+母艦速度
もし母艦のY>地面位置なら、
母艦のY=地面位置
もし母艦速度の絶対値>3.5なら母艦速度 = -(母艦速度/2)
違えば 母艦速度=0
もし母艦のY<天井位置なら、
母艦のY=天井位置
母艦速度 = -(母艦速度/2)
//重力落下ここまで//
//定期的なイベントの処理用タイマー//
定期タイマーとはタイマー
その間隔は定期間隔
その時満ちた時は
落ちろ
//定期的なイベントの処理ここまで//
ふきだしタイマーを開始
定期タイマーを開始
シンタックスハイライトは手動で付けたのでガバってるかもしれないです(半ギレ)
なでしこのシンタックスハイライト実装しろ(無茶振り)
しかもぶっつけ本番テストしながら書いてるやつだから汚い(確信)
おじさん許しちくり~(挑発)
・解説
上の方から適当に解説します
1.母艦の変形
母艦の画像は「もぶぴー.gif」
母艦を画像通り変形
母艦をダブルクリックした時は~終わる
母艦の画像は「{画像パス}」 でウィンドウを変形させるための画像を読み込みます。
母艦を画像通り変形 でウィンドウを変形します。
母艦を画像通りに変形してしまうと、閉じるボタンがなくなってしまうので、母艦をダブルクリックした時に終了させるようにします。(この部分は公式ページでも書いてあります)
2.ふきだしの作成
とりあえず、デスクトップマスコットに何か喋らせるような機能を付けたいと思います。
なでしこにはウィンドウを変形させる命令がいくつかあります。先ほどの画像通り変形もその一つです。
吹き出しの形に変形する命令もあります。
//ふきだしフォームの作成//
ふきだしとはフォーム
そのWは300
そのHは200
ふきだしを吹き出し変形
{フォーム名}とはフォーム で別窓を作ることができます。
そ(れ)のWは などの部分は、フォームについての情報を変更しています。
そ(れ)についての説明は面倒なので省きますが、近いものだとthisかと思います(ぜんぜん違うと思うけど)
なので、ここの "そのWは300" は "ふきだし.W = 300" のようなものです。
ふきだしを吹き出し変形 で 生成した別窓を吹き出しの形にします。
3.せりふの作成
先ほどは台詞を表示する領域として、吹き出しを作りました。今度は表示させる台詞を読み込んでいきます。
//せりふ読み込み処理//
台詞集とは配列
「dict.txt」を毎行読んで反復
台詞集¥(回数-1)はそれ
台詞数は回数
//せりふ読み込み処理はここまで//
台詞集とは配列 で "台詞集" という名前の配列を生成します。この時点では文字列が入るのか数値が入るのかなどは決まっていません。
「dict.txt」を毎行読んで反復 から以下ではdict.txtの中身を一行ずつ配列に格納し、台詞の数を台詞数に代入しています。
説明が面倒なのでかなり省きます(ぉぃ)
毎行読んで反復 ではファイル終端まで一行ずつ読んでいきます。
その時、 それ の中身は読んだ一行を指しています。
配列に格納したり取り出す時は、 {配列名}[{番号}] や {配列名}\{番号} と書きます。
回数 はループした回数です。
配列の中の回数-1の場所に それ を格納していくわけです。
4.ふきだしの処理
吹き出しの別窓と吹き出しに表示する台詞が完成したので、吹き出しの処理を作ります。
//せりふラベルの作成//
台詞とはラベル
台詞について
親部品はふきだし
Xは70
Yは70
Wは200
Hは100
文字位置は「中央」
台詞とはラベル では、文字を表示するためのGUI部品を生成しています。
台詞について は、それ以下のインデントがある行で、 そ{れ} を省略できます。
親部品はふきだし では、ラベルを吹き出し用の別窓、 ふきだし に配置しています。
X,Y,W,Hは察してください(ぇ)
文字位置は「中央」 とすることで、ラベルに表示される文字は中央揃えになります。
//ふきだしの処理//
ふきだしタイマーとはタイマー
その間隔は3
その時満ちた時は
ふきだしのXは(母艦の左-ふきだしのW)
ふきだしのYは(母艦の上-ふきだしのH)
ふきだしの可視はオン
台詞のテキストは台詞集¥(台詞数の乱数)
1秒待つ
ふきだしの可視はオフ
表示クリア
//ふきだしの処理はここまで//
ふきだしタイマーとはタイマー では、吹き出しを処理するための ふきだしタイマー というタイマーを生成しています(ややこしい)
その間隔は3 とすることで、3秒ずつのタイマーに設定しています。
ちなみにミリ秒単位にしたい場合は、 その値は{設定したい時間} とすることで可能です。
ふきだしのXは(以下略) では、吹き出しの出る座標が母艦にくっつくように調整しています。
ふきだしの可視はオン では、ふきだしの別窓を見える状態にします。
台詞のテキストは台詞集\(台詞数の乱数) では、台詞数 が最大値になる乱数で 台詞集からランダムに文字列を取り出して、ラベルのテキストに代入します。
1秒待つ で1秒待ってからふきだしの可視をオフにしています。が、待つ 命令はあまり使うのは好ましくないと思います(処理がとまってしまうため)
タイマー間隔ごとに、ふきだしの可視がオンかオフかで処理を分岐させるなどした方がいいかもしれません。
ふきだしタイマーを開始
定期タイマーを開始
あと、タイマーは {タイマー名}を開始 を書かないとタイマーが動きませんのでご注意。
5.跳ねろもぶぴー
ぶっちゃけおまけです。
あとバグを仕様と言い張る勇気(そうじゃない)
//定期イベント設定//
定期間隔=0.01
//定期イベント設定ここまで//
//定期イベント1:重力で落下//
天井位置=0
地面位置=600
●落ちろ
重力は9.8*定期間隔
母艦速度は母艦速度+重力
母艦のYは母艦のY+母艦速度
もし母艦のY>地面位置なら、
母艦のY=地面位置
もし母艦速度の絶対値>3.5なら母艦速度 = -(母艦速度/2)
違えば 母艦速度=0
もし母艦のY<天井位置なら、
母艦のY=天井位置
母艦速度 = -(母艦速度/2)
//重力落下ここまで//
//定期的なイベントの処理用タイマー//
定期タイマーとはタイマー
その間隔は定期間隔
その時満ちた時は
落ちろ
正直この部分は解説するのも正直面倒なので、適当に説明します。
なでしこで関数を宣言する場合は、 ●{関数名} もしくは *{関数名} と書きます。
●落ちろ(無慈悲) 関数の中身は大体察しが付くとは思いますが、もぶぴー、もとい母艦が跳ねるための関数です。
0.01秒ごとに重力加速度を下方向の速度に足して、速度の分だけ母艦のY座標を移動させています。
どうでもいいですが、この処理の仕方だと母艦をつかんでいる状態のときにも常に下方向の速度を溜め込みますので、つかんだままにしているともぶぴーがガクガク震えだします(笑)
もちろん母艦を離すと溜め込んだ分の速度で移動し、天井位置を設定していない場合は虚空の彼方へと旅立っていきます(戻ってはきますが)
解決策はいろいろと考え付きますが、それについては面倒なので書きません(当たり前だよなぁ?)
・あとがきするんだよあくしろよ
最後の方になるにつれてだんだんと適当になりました。お詫び申し上げません。
ぶっちゃけて言えば、なでしこはプログラミングに疎くても簡単にプログラミングができる・・・と思わせておいて、リファレンス等のドキュメント類があんまり充実してないです。
初心者向け・・・かと言われると非常に微妙な言語であります。
文法についても、美しいなでしこ語を要求されるので(接続詞関連は特にうるさい)プログラミング初心者が中々踏み込んだことをやろうとするとしっぺ返しを受けることになるかと思います。
ですが、プログラミングを日本語で行えることの利点は非常に大きく、ごくごく簡単なプログラムであ
れば楽にかけますので、「あぁ!プログラムってこうやって動いているんだ!」などの実感を得るには非常にうってつけかと思います。
また、多少のプログラミングに心得のある方であれば、GUIのツールを作るのは興味があるけど大変そう・・・難しそう・・・という人でも他の言語と比べて、簡単に、直感的にツールを製作することができると思います。
日本語で書けること、そしてGUI関連についてそれなりに強いところがなでしこの魅力だといえます。
あと日本語だから惜しみなく淫夢語録が使えるのも利点だゾ。あぁ^~たまらねえぜ。
(アドベントカレンダー記事投稿)やったぜ。