Column > 【C#,VB】trr風の長文タイピングソフトの作成
2016/8/7 【C#,VB】trr風の長文タイピングソフトの作成

皆さんはtrrというソフトをご存じでしょうか?

trrというのはEmacs上で動くタイピングソフトです。
特徴としては、単語ではなく文章を打つタイプのソフトだということや、
速度やミス率、独自の評価値などを教えてくれるという点が挙げられます。

本家trrには及ばずとも、何かそれっぽいタイピングソフトを作ってみたいな!と思ったので
作ってみました。


実際に動かしている様子はこんな感じです。
作り方を以下に書いていきます。







1. 仕様決め、コントロールの配置


上の動画を見てもらえばわかりますが、
今回作ったプログラムは、本家trrにある
難易度選択、テキスト選択、ハイスコアの記録などの機能は一切省いて
タイピングに最低限必要な機能だけをそろえた感じになっています。

ですが、本家に唯一勝っている(?)部分として
スコアやミス率などがリアルタイムで表示されています。

また、表示する文章はtxtファイルを読み込んで表示しているのですが、
改行の場所は指定せず、自動で改行を行うようにしています。



コントロールの配置は下のようになっています。


リアルタイムでスコアなどを出すためにtimerを1つ置いていて、
それ以外のコントロールは全てlabelです。

guideText, typingPoint, missPointはそれぞれ
打ち込む文章、自分が打った文章、自分が間違えた場所を表示します。
noticeは得点やミス率などを表示します。
showMenuはただの飾りです。
Textに空白をたくさん入れることで画面いっぱいに枠を広げています。

一番重要なこととして、各コントロールのフォントは
デフォルトではMS UI Gothicが設定されていますが、
このフォントだと文字ごとに大きさが違っているので
MS ゴシックに変更しておきます。

こうすることで、どの文字も同じ大きさを使用するようになるので
見た目が綺麗になります。


2. プログラム
2-1. 初期化処理


まずは初期化処理のプログラムを組みます。




guideText, typingPoint, missPointの3つに親子関係を持たせて位置を揃えます。
また、BackColorにTransparentを指定することで親のTextを透けて見えるようにしています。

注意点としては、1つの親に2つの子を持たせないようにしなければいけません。
1つの親に2つの子を持たせると、子供のTextが他の子の所では透けないからです。
今回はguideTextの子がtypingPoint、typingPointの子がmissPointという風にしています。


3つのコントロールが同じ位置にいるため、右図のようなやり方だと
どちらかの子がもう一つの子に隠れてしまうことになります。
そのため、親子関係をしっかりさせて孫を一番前に持ってくることが重要です。

readFile()関数は次の章で作ります!


2-2. ファイル読み込み


次はファイルの読み込みを行います。
読み込むtxtファイルは下のような形式になっています。


\から始まっている行がタイトルで、その一行下からタイピングの文章が入っています。
タイピングの文章は何行改行しても構わず、改行はスペース1つ分として扱うことにしました。
また、ファイルの終端には]を置いてあります。



プログラムは上のような感じです。
txtファイルを読み込んでguideTextにコピーしています。

表示させる文章の選び方は、最初にファイルのランダムな位置にアクセスして
後ろの方向に一文字ずつ見ていき、\が見つかったらその文章を
タイピングに使うことにしています。


本文にスペースか改行があったときは、spaceOrNewline()関数で
タイピング中でスペースと改行のどちらを入れるかを決定しています。

タイピングの文章は5行あることを想定していますが、
5行に届かない時も対応できるようになっています。

windowsで作成したので、改行周りの処理は全てCr+Lfになっている前提で作っています。




2-3. スペースと改行の選択


次は、タイピングの文章をコピーするときに空白と改行を適切に入れるための関数を作ります。

プログラムは下のような感じです。



流れとしては、colsCount変数で今の行に何文字書かれているかを記録して、
それが一定値を超えたときは改行を入れて、そうでないときはスペースを入れています。




2-4. キーが押された時の処理


ここまでで、プログラムを起動してからタイピングの文章を読み込んで
表示するまでが出来たので、次はキーが押された時の処理を作ります。
プログラムは下のようになりました。



キーが押された時のイベントはKeyPressの他にKeyDownやPreviewKeyDownがありますが、
KeyDownやPreviewKeyDownは大文字小文字の区別ができなかったり、
Shiftキーなどにも反応してしまうのでKeyPressイベントを使いました。

初めてキーが押されたとき(startedTypingがfalseのとき)は
timer1をスタートさせて得点などの計測を始めます。

押されたキーが正しいかどうかの判定は、
e.KeyCharとguideTextの文字が同じかどうかで見ています。

押されたキーが正しいか違っているかによって、
押したキーの回数や間違えた回数などをカウントしていますが、
正しくEnterを押した場合は終了の判定も行います。


2-5. 得点の計測


最後にtimer1のtickイベントに得点などを計算して表示するプログラムを作ります。



timerのIntervalの単位はミリ秒が使われているので、1000で割ることで単位を秒にしています。

ミス率と字数/分は単純に計算して出しています。

評価の値は、本家trrのデフォルトの評価関数である
(打文字数-(誤打数×10))×60÷(経過した秒数)
という式を用いています。


2-6. ソースコード


上の方で書いてきたプログラムを繋ぎ合わせると、
最終的なソースコードは下のようになりました。




3. あとがき


こんな感じでプログラムは完成です。

今回は最低限タイピングソフトと言えるものにしただけなので、
タイピング部分の前後にメニューを入れたり、ハイスコアなどを記録するようにしたりすれば
より本格的なタイピングソフトになるかなあと思います。

    Please
    Share!
  • feedly
  • facebook
  • twitter
  • hatena bookmark
  • pocket
  • Google plus

inserted by FC2 system