forked from: IME Typing
Microsoft IMEのローマ字入力に対応したタイピングゲームです。
日本語入力モードをオフにしてプレイします。
/**
* Copyright yamat1011 ( http://wonderfl.net/user/yamat1011 )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/93fN
*/
// forked from shohei909's IME Typing
/*
Microsoft IMEのローマ字入力に対応したタイピングゲームです。
日本語入力モードをオフにしてプレイします。
*/
package {
import flash.display.Sprite;
[SWF(backgroundColor="0x113399")]
public class FlashTest extends Sprite {
private var words:Array = [
{ word : "今日から夏の大バーゲンセール!" , kana : "きょうからなつのだいばーげんせーる!" },
{ word : "くわばらくわばら。" , kana : "くわばらくわばら。" },
{ word : "蟻が鯛なら芋虫ゃクジラ" , kana : "ありがたいならいもむしゃくじら" },
{ word : "赤信号みんなで渡れば怖くない。" , kana : "あかしんごうみんなでわたればこわくない。" },
{ word : "どうってことないさ。" , kana : "どうってことないさ" },
{ word : "何か用かの九日十日" , kana : "なにかようかのここのかとおか" },
{ word : "悪事に手を染める。" , kana : "あくじにてをそめる。" },
{ word : "その手は桑名の焼き蛤" , kana : "そのてはくはなのやきはまぐり" },
{ word : "黄金虫は金持ちだ。" , kana : "こがねむしはかねもちだ。" },
{ word : "全米ナンバーワン大ヒット映画が日本上陸!" , kana : "ぜんべいなんばーわんだいひっとえいががにほんじょうりく!" },
{ word : "驚き桃の木山椒の木" , kana : "おどろきもものきさんしょのき" },
{ word : "犯罪から足を洗う。" , kana : "はんざいからあしをあらう。" },
{ word : "このぬれせんべい、湿気ってる。" , kana : "このぬれせんべいしけってる。" },
{ word : "やーい、お前んち、おっばけやーしきー。" , kana : "やーい、おまえんち、おっばけやーしきー。" },
{ word : "明後日からがんばる。" , kana : "明後日からがんばる。" },
{ word : "聞き流すだけで、驚くほど英語が話せるようになる!" , kana : "ききながすだけでおどろくほどえいごがはなせるようになる!" },
{ word : "竹垣に丈高い竹立てかけた。" , kana : "たけがきにたけたかいたけたてかけた。" },
{ word : "掘ったイモいじるな。" , kana : "ほったいもいじるな。" },
{ word : "割っちゃいねぇ。" , kana : "わっちゃいねぇ。" },
{ word : "今なら五個セットでサンキュッパです。" , kana : "いまならごこせっとでさんきゅっぱです。" },
{ word : "あら安い。" , kana : "あらやすい。" },
{ word : "目の上のこぶた" , kana : "めのうえのこぶた" },
{ word : "濡れ手で泡々" , kana : "ぬれてであわあわ" },
{ word : "だから小さいすずらにしとけって言ったのに。" , kana : "だからちいさいすずらにしとけっていったのに。" },
{ word : "まずい!ずらかるぞ!" , kana : "まずい!ずらかるぞ!" },
{ word : "あながち間違ってなかったね。" , kana : "あながちまちがってなかったね。" },
{ word : "そこはかとなくすばらしい。" , kana : "そこはかとなくすばらしい。" },
{ word : "どっこいどっこい" , kana : "どっこいどっこい" },
{ word : "竹垣に竹立てかけたら怒られた。" , kana : "たけがきにたけたてかけたらおこられた。" },
{ word : "すきやき焼きすぎた。" , kana : "すきやきやきすぎた。" },
{ word : "富士山麓、オウム鳴く。" , kana : "ふじさんろくおうむなく。" },
{ word : "これは鉛筆ですか?いいえ、机です。" , kana : "これはえんぴつですか?いいえ、つくえです。" },
{ word : "ややこしい。" , kana : "ややこしい。" },
{ word : "しめしめ" , kana : "しめしめ" },
{ word : "明日できることは明日やる。" , kana : "あしたできることはあしたやる。" },
{ word : "電球「おれ切れるとマジ周りとか見えなくなるからな」" , kana : "でんきゅう「おれきれるとまじまわりとかみえなくなるからな」" },
{ word : "ここぞとばかり" , kana : "ここぞとばかり" },
{ word : "ナウなヤングにバカウケ" , kana : "なうなやんぐにばかうけ" },
{ word : "あばらバラバラ", kana : "あばらばらばら" },
{ word : "ガダルカナル" , kana : "がだるかなる" },
{ word : "ヤンバルクイナ" , kana : "やんばるくいな" },
{ word : "プノンペン" , kana : "ぷのんぺん" },
{ word : "ワイナイナ" , kana : "わいないな" },
{ word : "肉きゅう" , kana : "にくきゅう" },
{ word : "痛しかゆし" , kana : "いたしかゆし" },
{ word : "へなちょこ" , kana : "へなちょこ" },
{ word : "小腹" , kana : "こばら" },
{ word : "遮二無二" , kana : "しゃにむに" },
{ word : "マカロン" , kana : "まかろん" },
{ word : "老若男女" , kana : "ろうにゃくなんにょ" },
{ word : "すこぶる" , kana : "すこぶる" },
{ word : "キャッサバ粉" , kana : "きゃっさばこ" },
{ word : "似たり寄ったり" , kana : "にたりよったり" },
{ word : "ぬらりひょん" , kana : "ぬらりひょん" },
{ word : "あっけらかん" , kana : "あっけらかん" },
{ word : "叙情詩" , kana : "じょじょうし" },
{ word : "からきし" , kana : "からきし" },
{ word : "オコジョ" , kana : "おこじょ" },
{ word : "こちょこちょ" , kana : "こちょこちょ" },
{ word : "あんぽんたん" , kana : "あんぽんたん" },
{ word : "カッパドキア" , kana : "かっぱどきあ" },
{ word : "ちちんぷいぷい" , kana : "ちちんぷいぷい" },
{ word : "アブラカタブラ" , kana : "あぶらかたぶら" },
{ word : "情状酌量" , kana : "じょうじょうしゃくりょう" },
{ word : "金屏風" , kana : "きんびょうぶ" },
{ word : "ニイニイゼミ" , kana : "にいにいぜみ" },
{ word : "ブッポウソウ" , kana : "ぶっぽうそう" },
{ word : "ツクツクボウシ" , kana : "つくつくぼうし" },
{ word : "マチュピチュ" , kana : "まちゅぴちゅ" },
{ word : "高速増殖炉もんじゅ" , kana : "こうそくぞうしょくろもんじゅ" },
{ word : "貨客船マンギョンボン号" , kana : "かきゃくせんまんぎょんぼんごう" },
{ word : "じゃばら" , kana : "じゃばら" },
{ word : "鎖骨" , kana : "さこつ" },
{ word : "タクラマカン砂漠" , kana : "たくらまかんさばく" },
{ word : "アルファルファ" , kana : "あるふぁるふぁ" },
{ word : "すっとこどっこい" , kana : "すっとこどっこい" },
{ word : "御意" , kana : "ぎょい" },
{ word : "支笏湖" , kana : "しこつこ" },
{ word : "すたこらさっさ" , kana : "すたこらさっさ" },
{ word : "ざっくばらん" , kana : "ざっくばらん" },
{ word : "腕っぷし" , kana : "うでっぷし" },
{ word : "行き当たりばったり" , kana : "いきあたりばったり" },
{ word : "アルパカ" , kana : "あるぱか" },
{ word : "笑止" , kana : "しょうし" },
{ word : "ちょんまげ" , kana : "ちょんまげ" },
{ word : "ブギウギ" , kana : "ぶぎうぎ" },
{ word : "お得意様" , kana : "おとくいさま" },
{ word : "猫だまし" , kana : "ねこだまし" },
{ word : "イグノーベル賞" , kana : "いぐのーべるしょう" },
{ word : "ハラペーニョ" , kana : "はらぺーにょ" },
{ word : "なれの果て" , kana : "なれのはて" },
{ word : "抗う" , kana : "あらがう" },
{ word : "デイダラボッチ" , kana : "でいだらぼっち" },
{ word : "なしくずし" , kana : "なしくずし" },
{ word : "チョベリバ" , kana : "ちょべりば" },
{ word : "ダブルラリアット" , kana : "だぶるらりあっと" },
{ word : "がらくた" , kana : "がらくた" },
{ word : "わたがし" , kana : "わたがし" },
{ word : "チャンチャラおかしい" , kana : "ちゃんちゃらおかしい" },
{ word : "プルコギ" , kana : "ぷるこぎ" },
{ word : "ちりとてちん" , kana : "ちりとてちん" },
{ word : "つまようじ" , kana : "つまようじ" },
{ word : "ンジャメナ" , kana : "んじゃめな" },
{ word : "きかんぼう" , kana : "きかんぼう" },
{ word : "度肝を抜く" , kana : "どぎもをぬく" },
{ word : "やっつけ仕事" , kana : "やっつけしごと" },
{ word : "そこそこ" , kana : "そこそこ" },
{ word : "キッパリ" , kana : "きっぱり" },
{ word : "へっぽこ" , kana : "へっぽこ" },
{ word : "エルニーニョ" , kana : "えるにーにょ" },
{ word : "えげつない" , kana : "えげつない" },
{ word : "嘘八百" , kana : "うそはっぴゃく" },
{ word : "夕焼け小焼け" , kana : "ゆうやけこやけ" },
{ word : "八方塞がり" , kana : "はっぽうふさがり" },
{ word : "アンドロイド" , kana : "あんどろいど" },
{ word : "もやしキムチ" , kana : "もやしきむち" },
{ word : "チャンバラごっこ" , kana : "ちゃんばらごっこ" },
{ word : "チョコレート" , kana : "ちょこれーと" },
{ word : "おっちょこちょい" , kana : "おっちょこちょい" },
{ word : "しゃらくさい" , kana : "しゃらくさい" },
{ word : "小ざかしい" , kana : "こざかしい" },
{ word : "トムソンガゼル" , kana : "とむそんがぜる" },
{ word : "しくじる" , kana : "しくじる" },
{ word : "くじける" , kana : "くじける" },
{ word : "癇癪玉" , kana : "かんしゃくだま" },
{ word : "ひっけらかす" , kana : "ひっけらかす" },
{ word : "かまいたち" , kana : "かまいたち" },
{ word : "いたちごっこ" , kana : "いたちごっこ" },
{ word : "大目玉を食らう" , kana : "おおめだまをくらう" },
{ word : "てんてこまい" , kana : "てんてこまい" },
{ word : "じゃじゃ馬" , kana : "じゃじゃうま" },
{ word : "サモトラケのニケ" , kana : "さもとらけのにけ" },
{ word : "とんずら" , kana : "とんずら" },
{ word : "カヤック" , kana : "かやっく" },
{ word : "岡持ち" , kana : "おかもち" },
{ word : "イソギンチャク" , kana : "いそぎんちゃく" },
{ word : "オリゴ糖" , kana : "おりごとう" },
{ word : "原っぱ" , kana : "はらっぱ" },
{ word : "枝豆" , kana : "えだまめ" },
{ word : "ジャングルジム" , kana : "じゃんぐるじむ" },
{ word : "フラメンコ" , kana : "ふらめんこ" },
{ word : "水族館" , kana : "すいぞくかん" },
{ word : "かっぱらう" , kana : "かっぱらう" },
{ word : "にんまり" , kana : "にんまり" },
{ word : "タイピングなう" , kana : "たいぴんぐなう" },
{ word : "ガビーン" , kana : "がびーん" }
];
function FlashTest() {{
var typing:Typing = new Typing( stage );
TypeStyle.setStyle( TypeStyle.DARK );
//accessary
var keyboard:TypeKeyboard = new TypeKeyboard( typing );
addChild( keyboard );
keyboard.scaleX = keyboard.scaleY = 0.7;
keyboard.x = 20;
keyboard.y = 300;
//panel
var panel:TypePanel = new TypePanel( typing, 464, 55, 0.25, 0.45, 0.30 );
panel.y = 200;
addChild( panel );
//monitor
var monitor:TypeMonitor = new TypeMonitor( typing, 445, 100, 0.25, 0.45, 0.30 );
monitor.x = 10;
monitor.y = 10;
//addChild( monitor );
//manager
new TypeManager( typing, words );
//start
typing.start();
}
}
}
}
import flash.utils.Timer;
import flash.display.Shape;
import flash.text.TextFormat;
import flash.text.TextField;
import flash.display.Graphics;
import flash.display.Sprite;
import flash.events.KeyboardEvent;
import flash.events.EventDispatcher;
import flash.events.Event;
import flash.utils.getTimer;
import flash.display.Stage;
class TypeData {
/** 半角文字のリスト */
static public const HANKAKU:String = "1234567890-^\\qwertyuiop@[asdfghjkl;:]zxcvbnm,./!\"#$%&'()=~|QWERTYUIOP`{ASDFGHJKL+*}ZXCVBNM<>?_ ";
/** HANKAKUに対応する全角文字のリスト */
static public const ZENKAKU:String = "1234567890ー^¥qwertyuiop@[asdfghjkl;:]zxcvbnm,./!”#$%&’()=~|QWERTYUIOP‘{ASDFGHJKL+*}ZXCVBNM<>?_ ";
/** かなからローマ字への変換表*/
static public const ROMANS:Object = {
"あ":["a"], "う":["u", "wu", "whu"], "い":["i", "yi"], "え":["e"], "お":["o"],
"か":["ka", "ca"], "き":["ki"], "く":["ku", "cu"], "け":["ke"], "こ":["ko", "co"],
"さ":["sa"], "し":["si", "shi", "ci"], "す":["su"], "せ":["se", "ce"], "そ":["so"],
"た":["ta"], "ち":["ti", "chi"], "つ":["tu", "tsu"], "て":["te"], "と":["to"],
"な":["na"], "に":["ni"], "ぬ":["nu"], "ね":["ne"], "の":["no"],
"は":["ha"], "ひ":["hi"], "ふ":["fu", "hu"], "へ":["he"], "ほ":["ho"],
"ま":["ma"], "み":["mi"], "む":["mu"], "め":["me"],"も":["mo"],
"や":["ya"], "ゆ":["yu"], "よ":["yo"],
"ら":["ra"], "り":["ri"], "る":["ru"], "れ":["re"],"ろ":["ro"],
"わ":["wa"], "を":["wo"], "ん":["nn"],
"が":["ga"], "ぎ":["gi"], "ぐ":["gu"], "げ":["ge"],"ご":["go"],
"ざ":["za"], "じ":["ji", "zi"], "ず":["zu"], "ぜ":["ze"], "ぞ":["zo"],
"だ":["da"], "ぢ":["di"], "づ":["du"], "で":["de"], "ど":["do"],
"ば":["ba"], "び":["bi"], "ぶ":["bu"], "べ":["be"], "ぼ":["bo"],
"ぱ":["pa"], "ぴ":["pi"], "ぷ":["pu"], "ぺ":["pe"], "ぽ":["po"],
"しゃ":["sya", "sha"], "しゅ":["syu", "shu"], "しょ":["syo", "sho"], "しぃ":["syi"], "しぇ":["sye", "she"],
"きぃ":["kyi"], "きゃ":["kya"], "きゅ":["kyu"], "きぇ":["kye"], "きょ":["kyo"],
"にゃ":["nya"], "にぃ":["nyi"], "にゅ":["nyu"], "にぇ":["nye"], "にょ":["nyo"],
"ちゃ":["tya", "cha", "cya"], "ちぃ":["tyi", "cyi"], "ちゅ":["tyu", "chu", "cyu"], "ちぇ":["tye", "che", "cye"], "ちょ":["tyo", "cho", "cyo"],
"とぁ":["twa"], "とぃ":["twi"], "とぅ":["twu"], "とぇ":["twe"], "とぉ":["two"],
"てゃ":["tha"], "てぃ":["thi"], "てゅ":["thu"], "てぇ":["the"], "てょ":["tho"],
"ひゃ":["hya"], "ひぃ":["hyi"], "ひょ":["hyo"], "ひぇ":["hye"], "ひゅ":["hyu"],
"りゃ":["rya"], "りぃ":["ryi"], "りゅ":["ryu"], "りぇ":["rye"], "りょ":["ryo"],
"うぁ":["wa", "wha"], "うぃ":["wi", "whi"], "うぇ":["we", "whe"], "うぉ":["wo", "who"],
"ヴぁ":["va"], "ヴぃ":["vi"], "ヴ":["vu"], "ヴぇ":["ve"], "ヴぉ":["vo"], "ヴゃ":["vya"], "ヴゅ":["vyu"], "ヴょ":["vyo"],
"くぁ":["qa", "kwa", "qwa"], "くぃ":["qi", "qwi", "qyi"], "くぅ":["qwu", "qwu"], "くぇ":["qe", "qwe", "qye"], "くぉ":["qo", "qwo"], "くゃ":["qya"], "くゅ":["qyu"], "くょ":["qyo"],
"すぁ":["swa"], "すぃ":["swi"], "すぅ":["swu"], "すぇ":["swe"], "すぉ":["swo"],
"ふぁ":["fa", "fwa"], "ふぃ":["fi", "fwi", "fyi"], "ふぅ":["fwu"], "ふぇ":["fe", "fwe", "fye"], "ふぉ":["fo", "fwo", "fwo"], "ふゃ":["fya"], "ふゅ":["fyu"], "ふょ":["fyo"],
"ぎゃ":["gya"], "ぎぃ":["gyi"], "ぎゅ":["gyu"], "ぎぇ":["gye"], "ぎょ":["gyo"],
"じゃ":["ja", "zya", "jya"], "じぃ":["zyi", "jyi"], "じゅ":["ju", "zyu", "jyu"], "じぇ":["je", "zye", "jye"], "じょ":["jo", "zyo", "jyo"],
"ぐぁ":["gwa"], "ぐぃ":["gwi"], "ぐぅ":["gwu"], "ぐぇ":["gwe"], "ぐぉ":["gwo"],
"ぢゃ":["dya"], "ぢぃ":["dyi"], "ぢゅ":["dyu"], "ぢぇ":["dye"], "ぢょ":["dyo"],
"どぁ":["dwa"], "どぃ":["dwi"], "どぅ":["dwu"], "どぇ":["dwe"], "どぉ":["dwo"],
"でゃ":["dha"], "でぃ":["dhi"], "でゅ":["dhu"], "でぇ":["dhe"], "でょ":["dho"],
"びゃ":["bya"], "びぃ":["byi"], "びゅ":["byu"], "びぇ":["bye"], "びょ":["byo"],
"ぴゃ":["pya"], "ぴぃ":["pyi"], "ぴょ":["pyo"], "ぴぇ":["pye"], "ぴゅ":["pyu"],
"つぁ":["tsa"], "つぃ":["tsi"], "つぇ":["tse"], "つぉ":["tso"],
"いぇ":["ye"],
"ぁ":["la", "xa"], "ぃ":["li", "xi", "lyi", "xyi"], "ぅ":["lu", "xu"], "ぇ":["le","xe","lye","xye"], "ぉ":["lo","xo"],
"ゃ":["lya","xya"],"ゅ":["lyu","xyi"],"ょ":["lyo","xyu"],"ゎ":["lwa","xwa"],
"っ":["ltu","ltsu"],"ヶ":["lke","xke"],"ヵ":["lka","xka"],
"「":["["], "」":["]"], "。":["."], "、":[","]
}
/** ローマ字からかなへの変換表 */
static public const KANA:Object = {
qwa:"くぁ", qa:"くぁ", bye:"びぇ", kwa:"くぁ", sho:"しょ", syu:"しゅ", byo:"びょ", byu:"びゅ", syi:"しぃ", pya:"ぴゃ",
sye:"しぇ", qi:"くぃ", shu:"しゅ", ti:"ち", qwi:"くぃ", qe:"くぇ", qyi:"くぃ", pyo:"ぴょ", cu:"く", tu:"つ", qwu:"くぅ",
kya:"きゃ", pyi:"ぴぃ", qo:"くぉ", chi:"ち", pyu:"ぴゅ", kyi:"きぃ", she:"しぇ", qye:"くぇ", tsa:"つぁ", pye:"ぴぇ",
qwe:"くぇ", qya:"くゃ", kyu:"きゅ", tsu:"つ", tsi:"つぃ", kye:"きぇ", te:"て", nu:"ぬ", qyu:"くゅ", to:"と", qwo:"くぉ",
ne:"ね", tse:"つぇ", kyo:"きょ", "]":"」", no:"の", tso:"つぉ", "[":"「", qyo:"くょ", xa:"ぁ", na:"な", ha:"は", ye:"いぇ",
swa:"すぁ", li:"ぃ", nya:"にゃ", swo:"すぉ", la:"ぁ", swi:"すぃ", lyi:"ぃ", nyi:"にぃ", xyi:"ゅ", swe:"すぇ", ku:"く",
swu:"すぅ", ke:"け", nyu:"にゅ", fa:"ふぁ", myi:"みぃ", nyo:"にょ", xu:"ぅ", nye:"にぇ", ni:"に", lu:"ぅ", mya:"みゃ",
e:"え", hi:"ひ", fyi:"ふぃ", fwa:"ふぁ", i:"い", fwi:"ふぃ", myo:"みょ", fu:"ふ", le:"ぇ", fi:"ふぃ", xi:"ぃ", hu:"ふ",
xe:"ぇ", mye:"みぇ", o:"お", lye:"ぇ", ho:"ほ", he:"へ", u:"う", myu:"みゅ", sa:"さ", cha:"ちゃ", fwu:"ふぅ", cya:"ちゃ",
xye:"ぇ", co:"こ", fe:"ふぇ", ma:"ま", tyi:"ちぃ", fwe:"ふぇ", tya:"ちゃ", cyi:"ちぃ", fye:"ふぇ", mi:"み", xya:"ゃ",
lo:"ぉ", tyu:"ちゅ", lya:"ゃ", xo:"ぉ", lyu:"ゅ", fwo:"ふぉ", cyu:"ちゅ", mo:"も", fo:"ふぉ", lyo:"ょ", chu:"ちゅ",
mu:"む", xyu:"ょ", ya:"や", che:"ちぇ", fyu:"ふゅ", me:"め", fya:"ふゃ", cye:"ちぇ", tye:"ちぇ", shi:"し", a:"あ",
xwa:"ゎ", fyo:"ふょ", ri:"り", lwa:"ゎ", yu:"ゆ", cho:"ちょ", gya:"ぎゃ", ru:"る", tyo:"ちょ", yo:"よ", ci:"し",
ltu:"っ", twi:"とぃ", cyo:"ちょ", ra:"ら", lka:"ヵ", gyu:"ぎゅ", gyi:"ぎぃ", xka:"ヵ", lke:"ヶ", ltsu:"っ", ja:"じゃ",
xke:"ヶ", ko:"こ", re:"れ", twa:"とぁ", zya:"じゃ", gyo:"ぎょ", gye:"ぎぇ", jya:"じゃ", twu:"とぅ", jyi:"じぃ", su:"す",
zyi:"じぃ", twe:"とぇ", ro:"ろ", ju:"じゅ", si:"し", two:"とぉ", wa:"うぁ", jyu:"じゅ", zyu:"じゅ", tha:"てゃ", wo:"うぉ",
je:"じぇ", thu:"てゅ", thi:"てぃ", nn:"ん", jye:"じぇ", tho:"てょ", gi:"ぎ", ga:"が", jo:"じょ", zyo:"じょ", zye:"じぇ",
jyo:"じょ", hyi:"ひぃ", ge:"げ", the:"てぇ", gwa:"ぐぁ", hyo:"ひょ", hya:"ひゃ", zi:"じ", gu:"ぐ", hye:"ひぇ", za:"ざ",
go:"ご", gwu:"ぐぅ", hyu:"ひゅ", ji:"じ", gwe:"ぐぇ", ce:"せ", rya:"りゃ", gwo:"ぐぉ", zu:"ず", gwi:"ぐぃ", ryi:"りぃ",
dya:"ぢゃ", ze:"ぜ", se:"せ", dyi:"ぢぃ", zo:"ぞ", ".":"。", so:"そ", dyu:"ぢゅ", da:"だ", rye:"りぇ", ",":"、", dye:"ぢぇ",
di:"ぢ", ryo:"りょ", ryu:"りゅ", dyo:"ぢょ", du:"づ", wha:"うぁ", ta:"た", whi:"うぃ", de:"で", wi:"うぃ", dwa:"どぁ",
"do":"ど", whe:"うぇ", dwi:"どぃ", ba:"ば", who:"うぉ", ki:"き", dwu:"どぅ", we:"うぇ", va:"ヴぁ", dwe:"どぇ", bu:"ぶ",
bi:"び", vi:"ヴぃ", dwo:"どぉ", be:"べ", ka:"か", ca:"か", dha:"でゃ", bo:"ぼ", vu:"ヴ", dhi:"でぃ", pa:"ぱ", ve:"ヴぇ",
dhu:"でゅ", pi:"ぴ", vo:"ヴぉ", dhe:"でぇ", pu:"ぷ", vya:"ヴゃ", dho:"でょ", pe:"ぺ", wu:"う", yi:"い", bya:"びゃ",
po:"ぽ",vyo:"ヴょ",vyu:"ヴゅ",byi:"びぃ",sya:"しゃ",whu:"う",sha:"しゃ",syo:"しょ"
}
/** nのうしろに来てもnが「ん」にならない文字 */
static public const NN:String = "euioany";
/** 二つ続くと「っ」になる文字 */
static public const LTU:String = "qwrtypsdfghjklzxcvbm";
static public const CODE48:String = "0123456789";
static public const CODE65:String = "abcdefghijklmnopqrstuvwxyz";
static public const CODE186:String = ":;,-./@";
static public const CODE219:String = "[¥]^";
static public const CODE226:String = "\\";
static public const QWERTY_KEY:Array = [ "1234567890-^¥", "qwertyuiop@[", "asdfghjkl;:]", "zxcvbnm,./\\" ];
static public const QWERTY_SHIFT:Array = [ "!\"#$%&'() =~|", "QWERTYUIOP`{", "ASDFGHJKL+*}", "ZXCVBNM<>?_" ];
static public const DVORAK_KEY:Array = [ "1234567890[]¥", ":,.pyfgcrl/@", "aoeuidhtns-^", ";qjkxbmwvz\\" ];
static public const DVORAK_SHIFT:Array = [ "!\"#$%&'() {}|", "*<>PYFGCRL?`", "AOEUIDHTNS=~", "+QJKXBMWVZ_" ]
static public const BOARD_INDENT:Array = [ 1, 1.5, 1.8, 2.3, 5 ]
}
class TypeUtil
{
// romanのかなに変換可能な部分をかなに変換して返します
static public function kana( roman:String, option:TypeOption = null ):String {
if( roman == "" ){ return "" }
var kana:String;
for( var i:uint = 3; i > 0; i-- ){
var subroman:String = roman.substr( 0, i );
if( option ){ kana = option.kana( subroman ); }
if( !kana ){ kana = TypeData.KANA[subroman]; }
if( !kana && i == 1 ){
var next:String = roman.substr( i, 1 );
var hankaku:int = TypeData.HANKAKU.indexOf( subroman );
if( subroman == next && TypeData.LTU.indexOf(subroman) != -1 ){ kana = "っ" }
else if( subroman == "n" && TypeData.NN.indexOf(next) == -1 ){ kana = "ん" }
else if( hankaku != -1 ){ kana = TypeData.ZENKAKU.substr( hankaku,1 ) }
}
if( kana ){ return kana + TypeUtil.kana( roman.substr(i), option ) }
}
return "";
}
//kanaに対してromanが入力されているときに、次にタイプできるキーの候補を返します。
static public function next( kana:String, roman:String = "", option:TypeOption = null ):Array{
var next:Array = [];
if( kana == "" ){ return [] }
for( var i:uint = 2; i > 0; i-- ){
var roman2:String = roman;
var subkana:String = kana.substr( 0, i );
var nextKana:String = kana.substr( i );
var subromans:Array = [];
if ( option ) { ArrayUtil.blend( subromans, option.romans( subkana ) ); }
if ( i == 1 ) {
var zenkaku:int = TypeData.ZENKAKU.indexOf( subkana );
var hankaku:int = TypeData.HANKAKU.indexOf( subkana );
if( subkana == "っ" ){ ArrayUtil.blend( subromans, _preLtu( nextKana, option ) ) }
else if ( subkana == "ん" ) { ArrayUtil.blend( subromans, _preN( nextKana, option )) }
else if ( zenkaku != -1 ) { subromans.push( TypeData.HANKAKU.substr( zenkaku,1 ) ); }
else if ( hankaku != -1 ) { subromans.push( TypeData.HANKAKU.substr( hankaku,1 ) ); }
}
ArrayUtil.blend( subromans, TypeData.ROMANS[subkana] );
var l:uint = subromans.length;
var flag:Boolean = false;
while( l > 0 ){
if( roman2.length == 0 ){ ArrayUtil.blend( next, _firsts(subromans) ); break; }
var first:String = roman2.substr(0, 1);
for( var j:uint = 0; j < l; j++ ){
if( subromans[j].substr( 0, 1 ) == first ){
subromans[j] = subromans[j].substr( 1 );
if ( subromans[j] == "" ) {
ArrayUtil.blend( next, TypeUtil.next( nextKana, roman2.substr(1), option ) );
subromans.splice(j,1); l--; j--;
}
}else{
subromans.splice(j,1); l--; j--;
}
}
roman2 = roman2.substr(1);
}
}
return next;
}
//かなを渡すとそのかなの手前に来ることで「っ」になりうるローマ字を返します。
static private function _preLtu( kana:String, option:TypeOption ):Array{
var next:Array = next( kana, "", option );
var pre:Array = [];
var l:uint = next.length;
const LTU:String = TypeData.LTU;
for( var i:uint = 0; i<l; i++ ){
var n:String = next[i];
if( LTU.indexOf(n) != -1 ){ pre.push(n); }
}
return pre;
}
//かなを渡すとそのかなの手前にn来ることで「ん」になる場合[n]を返します。
static private function _preN( kana:String, option:TypeOption ):Array{
var next:Array = next( kana, "", option );
var l:uint = next.length;
const NN:String = TypeData.NN;
for( var i:uint = 0; i<l; i++ ){
var n:String = next[i];
if( NN.indexOf(n) == -1 ){ return ["n"]; }
}
return [];
}
//arrの一文字目の配列を作ります。
static private function _firsts( arr:Array ):Array {
var l:uint = arr.length;
var firsts:Array = [];
for( var i:uint; i<l; i++ ){
firsts.push( arr[i].substr(0,1) );
}
return firsts;
}
/**
* 入力されているときのかなに対するもっとも簡単なローマ字のふりかたを返します。
* @param kana
* @param roman
* @param option
* @return
*/
static public function simplestRoman( kana:String, roman:String = "", option:TypeOption = null ):String {
if ( roman == "" ) { return _simplestRoman( kana, option); }
for ( var i:uint = 2; i > 0; i-- ) {
var roman2:String = roman;
var subkana:String = kana.substr( 0, i );
var nextKana:String = kana.substr( i );
var subromans:Array = [];
if ( option ) { ArrayUtil.blend( subromans, option.romans( subkana ) ); }
if ( i == 1 ) {
var zenkaku:int = TypeData.ZENKAKU.indexOf( subkana );
var hankaku:int = TypeData.HANKAKU.indexOf( subkana );
if( subkana == "っ" ){ ArrayUtil.blend( subromans, _preLtu( nextKana, option ) ) }
else if ( subkana == "ん" ) { ArrayUtil.blend( subromans, _preN( nextKana, option )) }
else if ( zenkaku != -1 ) { subromans.push( TypeData.HANKAKU.substr( zenkaku,1 ) ); }
else if ( hankaku != -1 ) { subromans.push( TypeData.HANKAKU.substr( hankaku,1 ) ); }
}
ArrayUtil.blend( subromans, TypeData.ROMANS[subkana] );
var l:uint = subromans.length;
for( var j:uint = 0; j < l; j++ ){
var subroman:String = subromans[j];
var rl:uint = subroman.length;
var c:uint = 0;
while ( true ) {
var one:String = roman2.substr( c, 1 );
if( subroman.indexOf( one, c ) == c ){ ;
if ( rl == c + 1 ) {
var next:String = simplestRoman( nextKana, roman2.substr(rl), option );
if ( next != null ) { return subroman + next }
break
}
}else { break; }
c++;
}
}
}
return null;
}
//かなに対するもっとも簡単なローマ字のふりかたを返します。
static private function _simplestRoman( kana:String, option:TypeOption = null ):String {
if ( kana == "" ) { return "" }
var roman:String;
for ( var i:uint = 2; i > 0; i-- ) {
var subkana:String = kana.substr( 0, i );
var nextKana:String = kana.substr( i );
if ( option ) { roman = option.romans( subkana )[0]; }
if ( !roman && i == 1 ) {
var zenkaku:int = TypeData.ZENKAKU.indexOf( subkana );
var hankaku:int = TypeData.HANKAKU.indexOf( subkana );
if( subkana == "っ" ){ roman = _preLtu( nextKana, option )[0] }
else if ( subkana == "ん" ) { roman = _preN( nextKana, option )[0] }
else if ( zenkaku != -1 ) { roman = TypeData.HANKAKU.substr( zenkaku,1 ); }
else if ( hankaku != -1 ) { roman = TypeData.HANKAKU.substr( hankaku,1 ); }
}
if ( !roman ) {
var romans:Array = TypeData.ROMANS[subkana];
if( romans ){ roman = romans[0] }
}
if ( roman ) {
var next:String = _simplestRoman( nextKana, option );
if ( next != null ) { return roman + next }
}
}
return null;
}
}
class ArrayUtil{
/**
* arr2のうち、arr1にまだ含まれないもののみを配列の前方に追加します。
* @param arr1
* @param arr2
* @return
*/
static public function blend( arr1:Array, arr2:Array ):Array {
if ( !arr2 ) { return arr1; }
var l:uint = arr2.length;
for ( var i:uint = 0; i < l; i++ ) {
var e:* = arr2[i];
if ( arr1.indexOf( e ) == -1 ) { arr1.push( e ); }
}
return arr1;
}
}
class TypeConfig{
static public var option:TypeOption;
static public var dovrak:Boolean = false;
static public var space:Boolean = true;
}
class TypeStyle{
/** クリーム系の配色です。 */
static public const CREAM:Object = { fill:0xEEDDCC, activeFill:0xDDAA77, activeFill2:0xDDBB99, disableFill:0x776655, line:0x554433 }
/** 暗いの配色です。 */
static public const DARK:Object = { fill:0x111116, activeFill:0xDD4411, activeFill2:0x1144DD, disableFill:0xCCCCCC, line:0xDDDDEE }
static public const DEFAULT:Object = CREAM;
/** アクセサリーの通常時のfillColorです。 */
static public var fill:uint = DEFAULT.fill;
/** アクセサリーがフォーカスを得た時などに使われるfillColorです。 */
static public var activeFill:uint = DEFAULT.activeFill;
/** fillとactiveFillの中間にあたるfillColorです。 */
static public var activeFill2:uint = DEFAULT.activeFill2;
/** アクセサリーがの時などに使われるfillColorです。 */
static public var disableFill:uint = DEFAULT.disableFill;
/** 枠線に使われる色です。 */
static public var line:uint = DEFAULT.line;
static public var defaultTextFormat:TextFormat = new TextFormat( "メイリオ", 70, 0, true, null, null, null, null, "center", null, null, null, null)
static public var nextFormat:TextFormat = new TextFormat( );
static public var typedFormat:TextFormat = new TextFormat( null, null, 0 );
static public var typingFormat:TextFormat = new TextFormat( null, null, 0x666666);
static public function setStyle( style:Object ):void {
TypeStyle.fill = style.fill;
TypeStyle.activeFill = style.activeFill;
TypeStyle.activeFill2 = style.activeFill2;
TypeStyle.disableFill = style.disableFill;
TypeStyle.line = style.line;
}
}
//===========================================================================================================
dynamic class TypeWord{
public var word:String;
public var kana:String = "";
public var chosen:Boolean;
public var isTarget:Boolean;
public var typable:Boolean;
public var roman:String;
public var defaultRoman:String;
public var next:Array;
function TypeWord( obj:Object ):void {
for ( var str:String in obj ) {
this[str] = obj[str]
}
if( TypeConfig.space ){ kana += " " }
this.defaultRoman = TypeUtil.simplestRoman( kana, "", TypeConfig.option );
}
}
class TypeOption{
/** [[かな,roman],...] */
public var options:Array = [];
static public const IROHA:Array = [["ゑ","we"],["ゐ","wi"]];
static public const CHA:Array = [["ちゃ", "cha"], ["ち", "chi"], ["ちゅ", "tyu"], ["ちぇ", "che"], ["ちょ", "cho"]];
function TypeOption( ...arrays ) {
options = options.concat.apply( null, arrays );
}
public function romans( kana:String ):Array {
var l:uint = options.length;
var romans:Array = [];
for ( var i:uint = 0; i < l; i++ ) {
var option:Array = options[i]
if ( option[0] == kana ) { romans.push( option[1] ); }
}
return romans;
}
public function kana( roman:String ):String {
var l:uint = options.length;
for ( var i:uint = 0; i < l; i++ ) {
var option:Array = options[i]
if ( option[1] == kana ) { return option[0]; }
}
return null;
}
}
class TypeEvent extends Event{
public var lastTyped:String;
public var word:TypeWord;
static public const WORD_REMOVED:String = "wordRemoved";
static public const WORD_ADDED:String = "wordAdded";
static public const MISSED:String = "missed";
static public const INITED:String = "inited";
static public const TYPED:String = "typed";
static public const START:String = "start";
static public const STOP:String = "stop";
function TypeEvent( type:String ) { super( type ); }
}
//===========================================================================================
class Typing extends EventDispatcher {
private var _stage:Stage;
public var target:Vector.<TypeWord>;
public var active:Vector.<TypeWord>;
private var _running:Boolean;
public function get running():Boolean{ return _running; }
private var _typed:String;
public function get typed():String{ return _typed; }
private var _next:Array;
public function get next():Array{ return _next; }
function Typing( stage:Stage ){
this._stage = stage;
init();
}
/** 初期化を行います */
public function init():void {
_next = [];
_typed = "";
_running = false;
target = new Vector.<TypeWord>();
active = new Vector.<TypeWord>();
dispatchEvent( new TypeEvent( TypeEvent.INITED ) );
}
/** targetに新たな単語を登録します。 */
public function addTarget( word:TypeWord ):void{
target.push( word );
word.next = TypeUtil.next( word.kana, typed, TypeConfig.option );
word.typable = ( word.next.length != 0 );
if( word.typable ){ active.push( word ); }
word.roman = TypeUtil.simplestRoman( word.kana, typed, TypeConfig.option );
ArrayUtil.blend( _next, word.next );
var e:TypeEvent = new TypeEvent( TypeEvent.WORD_ADDED );
e.word = word;
dispatchEvent( e );
}
/** キーボードの監視をスタートさせます。 */
public function start():void {
if ( !_running ) {
_running = true;
_stage.addEventListener( "keyDown", onKeyDown );
dispatchEvent( new TypeEvent( TypeEvent.START ) );
}
}
/** キーボードの監視を停止させます。 */
public function stop():void {
if ( _running ) {
_running = false;
_stage.removeEventListener( "keyDown", onKeyDown );
dispatchEvent( new TypeEvent( TypeEvent.STOP ) );
}
}
/** キーをタイプしたときに呼び出されるイベントハンドラです。この関数を呼び出すことでキーをタイプしたときと同じ挙動をさせることが可能になります。 */
public function onKeyDown( evt:KeyboardEvent ):void{
var s:String = String.fromCharCode( evt.charCode );
var nx:int = next.indexOf( s );
var e:TypeEvent;
if ( nx == -1 ) {
e = new TypeEvent( TypeEvent.MISSED );
e.lastTyped = s;
dispatchEvent( e );
}else {
_typed += s;
var flag:Boolean = false;
var l:uint = active.length;
var c:uint = 0;
_next = [];
for( var i:uint = 0; i < l; i++ ) {
var word:TypeWord = active[i];
if( word.typable ){
word.next = TypeUtil.next( word.kana, typed, TypeConfig.option );
word.typable = word.next == null || ( word.next.length != 0 );
ArrayUtil.blend( _next, word.next );
if ( word.roman == typed ) {
target.splice( target.indexOf(word), 1 );
active.splice( i, 1 );
flag = true;
i--; l--;
}
if ( word.typable ) { word.roman = TypeUtil.simplestRoman( word.kana, typed, TypeConfig.option ); }
else{ word.roman = word.defaultRoman; }
}else {
active.splice( i, 1 );
i--; l--;
}
}
e = new TypeEvent( TypeEvent.TYPED );
e.lastTyped = s;
dispatchEvent( e );
if ( flag ) {
wordsInit();
e = new TypeEvent( TypeEvent.WORD_REMOVED );
e.lastTyped = s;
e.word = word;
dispatchEvent( e );
}
}
}
private function wordsInit():void {
var l:uint = target.length;
active = new Vector.<TypeWord>();
_typed = "";
_next = [];
for ( var i:uint = 0; i < l; i++ ) {
var word:TypeWord = target[i];
active.push( word );
word.next = TypeUtil.next( word.kana, typed, TypeConfig.option );
ArrayUtil.blend( _next, word.next );
word.typable = ( word.next.length != 0 );
word.roman = word.defaultRoman;
}
}
}
class TypeManager extends EventDispatcher{
public var typing:Typing;
public var wordList:Vector.<TypeWord>;
public var next:Vector.<TypeWord>;
public var nextMax:int = 20;
public var timeLimit:Number = -1;
public var timeCount:Number = 0;
private var _useTimeLimit:Boolean = false;
public var addLimit:int = -1;
public var addCount:int = 0;
public var removeLimit:int = -1;
public var removeCount:int = 0;
public var cycleLimit:int = -1;
public var cycleCount:int;
public var zeroPost:Boolean = true;
public var timePost:Number = -1;
public var shuffle:Boolean = false;
private var _currentTime:Number = 0;
private var _lastAdd:Number = 0;
function TypeManager( typing:Typing, wordList:Array ):void{
this.wordList = new Vector.<TypeWord>();
for each( var w:Object in wordList ) { this.wordList.push(new TypeWord(w)); }
this.typing = typing;
typing.addEventListener( TypeEvent.INITED, init );
typing.addEventListener( "start", onStart );
init( null )
}
public function add():void{
if ( addLimit != addCount ) {
addCount++;
setNext();
next.reverse();
typing.addTarget( next.pop() );
next.reverse();
setNext();
}
}
public function setNext():void {
var wordList:Vector.<TypeWord> = this.wordList;
var next:Vector.<TypeWord> = this.next;
var l:int = wordList.length;
var c:int = 0;
while ( next.length < nextMax ) {
var w:TypeWord = wordList[ (Math.random() * l) >>> 0 ];
if ( c > 10 || next.indexOf(w) == -1 ) { next.push( w ); c = 0; }
c++;
}
}
public function onStart( e:Event ):void{
this.addEventListener( "enterFrame", onFrame );
typing.addEventListener( "wordAdded", onWordAdded );
typing.addEventListener( "wordRemoved", onWordRemoved );
_currentTime = getTimer() / 1000;
}
public function init( e:Event ):void{
timeCount = 0;
addCount = 0;
removeCount = 0;
cycleCount = 0;
_useTimeLimit = ( timeLimit != -1 );
next = new Vector.<TypeWord>();
setNext();
add();
}
private function onFrame( e:Event ):void{
var time:Number = getTimer() * 0.001;
timeCount += time - _currentTime;
if( _useTimeLimit && timeCount >= timeLimit){ complete() }
if( 0 < timePost && timePost < time - _lastAdd ){ add() }
}
private function onWordAdded( e:Event ):void{
_lastAdd = getTimer() * 0.001;
}
private function onWordRemoved( e:Event ):void{
if( removeLimit == removeCount++ ){ complete(); }
if( typing.target.length == 0 ){
if( addLimit == addCount ){ complete(); }
else if( zeroPost ){ add(); }
}
}
public function complete():void{
this.removeEventListener( "enterFrame", onFrame );
typing.removeEventListener( "wordAdded", onWordAdded );
typing.removeEventListener( "wordRemoved",onWordRemoved)
typing.stop();
this.dispatchEvent( new Event( Event.COMPLETE ) );
}
}
class TypeKeyboard extends Sprite{
private var _typing:Typing;
public function get typing():Typing{ return _typing }
public var keys:Array = TypeData.QWERTY_KEY;
public var shiftKeys:Array = TypeData.QWERTY_SHIFT;
private var _dvorak:Boolean = false;
/**
* Dvorak配列を用いるかどうかのBooleanです。
*/
public function get dvorak():Boolean{ return _dvorak; }
public function set dvorak( b:Boolean ):void{
if( _dvorak != b ){
_dvorak = b;
if( b ){
keys = TypeData.DVORAK_KEY;
shiftKeys = TypeData.DVORAK_SHIFT;
}else{
keys = TypeData.QWERTY_KEY;
shiftKeys = TypeData.QWERTY_SHIFT;
}
init();
}
}
static public var indent:Array = TypeData.BOARD_INDENT;
static private const keySize:Number = 40;
public var typeKeys:Vector.<TypeKey> = new Vector.<TypeKey>;
public var shiftKey1:TypeKey;
public var shiftKey2:TypeKey;
private var _shifted:Boolean = false;
public function get shifted():Boolean{ return _shifted; }
function TypeKeyboard( typing:Typing = null ) {
this._typing = typing;
init();
}
//typingの現状を読み込んで次に打つべきキーのヒントを出力します。
private function read( e:TypeEvent ):void {
var next:Array = _typing.next;
var l:int = next.length;
if( _shifted ){ unshift() }
for each( var key1:TypeKey in typeKeys ){ key1.up(); }
for ( var i:int = 0; i < l; i++ ) {
var str:String = next[i];
for each( var key:TypeKey in typeKeys ){
if( key.key == str ){
if ( i == 0) { key.down(); }
else if( key.state == "up" && shifted == false ){ key.over(); }
}else if ( key.shiftKey == str ) {
if ( i == 0) { key.down(); shiftKey1.down(); shiftKey2.down(); shift() }
else if( key.state == "up" && shifted ){ key.over(); }
}
}
}
}
private function init():void{
if ( typing ) {
typing.addEventListener( TypeEvent.TYPED, read );
typing.addEventListener( TypeEvent.WORD_ADDED, read );
typing.addEventListener( TypeEvent.WORD_REMOVED, read );
if ( typing.running ) { read( null ) }
else{ typing.addEventListener( TypeEvent.START, read ); }
}
while( this.numChildren > 0 ){ this.removeChildAt(0); }
var h:int = keys.length;
var s:Number = keySize;
for( var i:int = 0; i < h; i++ ){
var w:int = keys[i].length
for( var j:int = 0; j < w; j++ ){
var str:String = keys[i].substr(j,1)
var code:int = 48 + TypeData.CODE48.indexOf( str );
if( code == 47 ){ code = 65 + TypeData.CODE65.indexOf( str ) }
if( code == 64 ){ code = 186 + TypeData.CODE186.indexOf( str ) }
if( code == 185 ){ code = 219 + TypeData.CODE219.indexOf( str ) }
if( code == 218 ){ code = 226 + TypeData.CODE226.indexOf( str ) }
var mark:Boolean = i == 2 &&( j == 3 || j == 6 )
var key:TypeKey= new TypeKey( s-1, s-1, str, shiftKeys[i].substr(j,1), code, mark );
key.x = ( j + indent[i] ) * s;
key.y = i * s;
addChild( key );
typeKeys.push( key );
}
}
for( i = 0; i < 3; i++ ){
key = new TypeKey( s*indent[i]-1, s-1, "", null, [229,9,22][i] );
key.y = i * s;
addChild( key );
}
var w0:Number = keys[0].length + indent[0];
var w1:Number = keys[1].length + indent[1];
var w2:Number = keys[2].length + indent[2];
var w3:Number = keys[3].length + indent[3];
//back space
key = new TypeKey( s-1, s-1, "BS", "BS", 8 );
key.x = w0 * s;
addChild( key );
typeKeys.push( key );
//shift
key = new TypeKey( indent[3]*s- 1, s-1, "Shift", "Shift", 16 );
key.y = 3 * s;
addChild( key );
typeKeys.push( key );
shiftKey1 = key;
key = new TypeKey( (w0-w3+1)*s -1, s-1, "Shift", "Shift", 16 );
key.x = w3 * s;
key.y = 3 * s;
addChild( key );
typeKeys.push( key );
shiftKey2 = key;
//enter
key = new TypeEnterKey( (w0-w1+1)*s -1, (w0-w2+1)*s -1, s-1, 2*s-1 );
key.x = w1 * s;
key.y = 1 * s;
addChild( key );
typeKeys.push( key );
//space
key = new TypeKey( 4*s -1, s-1, " ", " ", 32 );
key.x = indent[4] * s;
key.y = 4 * s;
addChild( key );
typeKeys.push( key );
}
public function shift():void {
_shifted = true;
for each( var key:TypeKey in typeKeys ){ key.shift() }
}
public function unshift():void {
_shifted = false;
for each( var key:TypeKey in typeKeys ){ key.unshift() }
}
}
class TypeKey extends Sprite{
public var upFill:uint = TypeStyle.fill;
public var downFill:uint = TypeStyle.activeFill;
public var overFill:uint = TypeStyle.activeFill2;
public var disableFill:uint = TypeStyle.disableFill;
public var fillColor:uint = upFill;
public var lineColor:uint = TypeStyle.line;
public var state:String = "up";
public var textField:TextField = new TextField();
protected var w:Number;
protected var h:Number;
public var key:String;
public var shiftKey:String;
public var code:int;
public var shifted:Boolean;
public var mark:Boolean;
function TypeKey( width:Number, height:Number, key:String, shiftKey:String, code:Number, mark:Boolean = false ){
w = width; h = height; this.key = key; this.shiftKey = shiftKey; this.code = code; this.mark = mark
var format:TextFormat = new TextFormat( "_monospace", h/2.33, lineColor, true );
textField.defaultTextFormat = format;
textField.x = 6;
textField.y = 1;
textField.selectable = false;
draw();
addChild( textField );
drawText();
}
public function draw():void{
var g:Graphics = this.graphics;
g.clear();
g.beginFill( fillColor, 1 );
g.lineStyle( 2, lineColor );
g.drawRoundRect( 0,0, w, h, 8 );
g.endFill();
if( mark ){
var cw:Number = w/2;
g.lineStyle( 1, lineColor, 0.8 );
g.moveTo( cw + 4, h - 13 );
g.lineTo( cw - 4, h - 13 );
}
g.lineStyle( 1, 0xFFFFFF, 0.5 );
g.moveTo( 5, 1 );
g.lineTo( 5, h-10 );
g.lineTo( w-5 , h-10 );
g.lineTo( w-5 , 1 );
}
public function drawText():void {
if( shifted ){ textField.text = shiftKey; }
else { textField.text = key; }
}
public function down():void{
fillColor = downFill;
state = "down";
draw();
}
public function over():void{
fillColor = overFill;
state = "over";
draw();
}
public function up():void{
fillColor = upFill;
state = "up";
draw();
}
public function disable():void{
fillColor = disableFill;
state = "disable";
draw();
}
public function shift():void{
shifted = true;
drawText();
}
public function unshift():void{
shifted = false;
drawText();
}
}
class TypeEnterKey extends TypeKey{
private var w2:Number;
private var h2:Number;
function TypeEnterKey ( width:Number, width2:Number, height:Number, height2:Number ){
w2 = width2; h2 = height2;
super( width, height, "Enter", "Enter", 13 )
addChild( textField );
drawText();
}
override public function draw():void{
var g:Graphics = this.graphics;
g.clear();
g.beginFill( fillColor, 1 );
g.lineStyle( 2, lineColor );
var l:Function = g.lineTo;
var c:Function = g.curveTo;
var r:Number = 8;
var x0:Number = 0, x1:Number = w - w2, x2:Number = w;
var y0:Number = 0, y1:Number = h, y2:Number = h2;
g.moveTo( x0, y0 + r );
l( x0, y1 - r ); c( x0, y1, x0 + r, y1 );
l( x1 , y1 );
l( x1, y2 - r ); c( x1, y2, x1 + r, y2 );
l( x2 - r, y2 ); c( x2, y2, x2, y2 - r );
l( x2, y0 + r ); c( x2, y0, x2 - r, y0 );
l( x0 + r, y0 ); c( x0, y0, x0, y0 + r );
g.endFill();
g.lineStyle( 1, 0xFFFFFF, 0.5 );
x0 = 4, x1 = w - w2 + 4, x2 = w - 4;
y0 = 1, y1 = h - 10, y2 = h2 - 10;
g.moveTo( x0, y0 );
l( x0, y1 ); l( x1, y1 ); l( x1, y2 ); l( x2, y2 ); l( x2, y0 );
}
}
class TypePanel extends Sprite{
public var typing:Typing;
public var kanaField:TextField = new TextField();
public var wordField:TextField = new TextField();
public var romanField:TextField = new TextField();
private var w:Number, h:Number;
private var nextFormat:TextFormat = TypeStyle.nextFormat;
private var typedFormat:TextFormat = TypeStyle.typedFormat;
private var typingFormat:TextFormat = TypeStyle.typingFormat;
function TypePanel( typing:Typing, width:Number, height:Number, kanaWeight:Number = 0.2, wordWeight:Number = 0.5, romanWeight:Number = 0.3 ){
this.typing = typing;
w = width; h = height;
var y:Number = 0;
var th:Number;
var format:TextFormat;
var weights:Array = [ kanaWeight, wordWeight, romanWeight ];
var fields:Array = [ kanaField, wordField, romanField ];
for( var i:int = 0; i < 3; i++ ){
var weight:Number = weights[i];
var field:TextField = fields[i];
if( weight > 0 ){
th = h * weight;
format = TypeStyle.defaultTextFormat;
field.scaleX = field.scaleY = th * 0.01;
field.width = w / field.scaleX;
field.height = th / field.scaleY;
field.y = y;
field.selectable = false;
field.defaultTextFormat = format;
addChild( field );
y += th;
}
}
update(null);
typing.addEventListener( "wordAdded", update );
typing.addEventListener( "wordRemoved", update );
typing.addEventListener( "typed", update );
}
private function update( e:Event ):void {
if( typing.active.length == 1 ){
var word:TypeWord = typing.active[0];
var wordNum:Number = 0;
kanaField.text = word.kana;
wordField.text = word.word;
romanField.text = word.roman;
romanField.setTextFormat( typingFormat, -1, -1 );
var tl:int = typing.typed.length;
if ( tl > 0 ) {
if( tl < word.roman.length ){ romanField.setTextFormat( typedFormat, -1, tl); }
if( tl + 1 < word.roman.length){ romanField.setTextFormat( nextFormat, tl, tl + 1 ); }
}
}
}
}
class TypeMonitor extends Sprite{
public var typing:Typing;
public var maxText:TextField = new TextField();
public var minText:TextField = new TextField();
public var text:TextField = new TextField();
private var w:Number, h:Number;
private var graph:Shape = new Shape;
private var gw:Number, gh:Number;
public var time:int;
public var typeCount:int;
public var speed:Number;
public var miss:Number;
private var currentTime:int;
private var typeHistory: Vector.<int>;
private var missHistory: Vector.<int>;
private var timer:Timer = new Timer( 100 );
private var type3Graph:Vector.<Number>;
private var miss3Graph:Vector.<Number>;
private var graphMax:Number = 0.05;
private var graphLen:int = 0;
function TypeMonitor( typing:Typing, width:Number, height:Number, kanaWeight:Number = 0.2, wordWeight:Number = 0.5, romanWeight:Number = 0.3 ){
this.typing = typing;
w = width; h = height;
var g:Graphics = this.graphics;
g.beginFill( 0x222222, 1 );
g.lineStyle( 1, 0x444444, 1 );
g.drawRect( 0,0, w, h );
g.endFill();
var m:Number = 8;
gh = h - 2 * m - 10; gw = w - 2 * m - 60;
this.addChild( graph );
graph.x = 60 + m; graph.y = m;
g.beginFill( 0, 1 );
g.lineStyle( 1, 0x444444, 1 );
g.drawRect( graph.x, graph.y, gw, gh );
text = new TextField();
text.width = w - m;
text.y = gh + m;
text.defaultTextFormat = new TextFormat( null, 10, 0xAAAAAA, null, null, null, null, null, "right" )
addChild( text );
maxText = new TextField();
maxText.width = 60;
maxText.x = m;
maxText.defaultTextFormat = new TextFormat( null, 10, 0xAAAAAA, null, null, null, null, null, "right" )
addChild( maxText );
minText = new TextField();
minText.width = 60;
minText.x = m;
minText.y = gh;
minText.defaultTextFormat = new TextFormat( null, 10, 0xAAAAAA, null, null, null, null, null, "right" )
minText.text = "0key/s";
addChild( minText );
timer.addEventListener( "timer", update );
typing.addEventListener( "inited", onInited );
typing.addEventListener( "start", onStart );
typing.addEventListener( "stop", onStop );
typing.addEventListener( "typed", onTyped );
typing.addEventListener( "missed", onMissed );
onInited(null);
}
private function onInited( e:Event ):void{
time = 0;
typeCount = 0;
miss = 0;
speed = 0;
typeHistory = new Vector.<int>();
missHistory = new Vector.<int>();
type3Graph = new Vector.<Number>();
miss3Graph = new Vector.<Number>();
graphMax = 0.01;
graphLen = 0;
draw();
}
private function onStart( e:Event ):void{
currentTime = getTimer();
timer.start();
}
private function onStop( e:Event ):void{
timer.stop();
}
private function onTyped( e:Event ):void{
time += getTimer() - currentTime;
currentTime = getTimer();
typeHistory.push( time );
typeCount++;
}
private function onMissed( e:Event ):void{
time += getTimer() - currentTime;
currentTime = getTimer();
missHistory.push( time );
}
private function update( e:Event ):void{
time += getTimer() - currentTime;
currentTime = getTimer();
var t:Number = time / 1000;
text.text = " Time:"+ t.toFixed(1)+"sec" + " Miss:" + miss.toFixed(2) + "key/s"+ " CurrentSpeed:" + speed.toFixed(2) + "key/s" +" AverageSpeed:" + (typeCount/t).toFixed(2) + "key/s";
maxText.text = "" + ( graphMax * 10 ).toFixed(2) + "key/s";
while( t > ( graphLen + 3 ) / 10 ){
tgPush();
mgPush();
graphLen += 3;
}
draw();
}
private function tgPush():void{
var t:int = currentTime;
var start:int = (graphLen - 30) * 100;
var end:int = graphLen * 100;
var c:int = 0;
for( var i:int = typeHistory.length - 1; i >= 0; i--){
t = typeHistory[i]
if( end > t ){
if( t > start ){ c++ }
else{ typeHistory.splice( 0, i+1 ); i = -1; }
}
}
var s:Number;
if( graphLen > 30 ){
s = c / 30;
if( graphMax < s ){ graphMax = s; }
type3Graph.push( s );
speed = s*10;
if( type3Graph.length > gw ){
type3Graph.reverse();
type3Graph.pop();
type3Graph.reverse();
}
}
}
private function mgPush():void{
var t:int = currentTime;
var start:int = (graphLen - 30) * 100;
var end:int = graphLen * 100;
var c:int = 0;
for( var i:int = missHistory.length - 1; i >= 0; i--){
t = missHistory[i]
if( end > t ){
if( t > start ){ c++; }
else{ missHistory.splice( 0, i+1 ); i = -1; }
}
}
var s:Number;
if( graphLen > 30 ){
s = c / 30;
if( graphMax < s ){ graphMax = s; }
miss3Graph.push( s );
miss = s*10;
if( miss3Graph.length > gw ){
miss3Graph.reverse();
miss3Graph.pop();
miss3Graph.reverse();
}
}
}
private function draw():void{
var g:Graphics = graph.graphics;
g.clear();
g.lineStyle( 1, 0xAAAAAA, 0.8 );
var l:int; var i:int;
l = miss3Graph.length;
g.lineStyle( 0.5, 0xFF0000, 0.8 );
for( i = 0; i < l; i++ ){
if( i == 0 ){ g.moveTo( l-i, gh * ( graphMax - miss3Graph[i] ) / graphMax ) }
else{ g.lineTo( l-i, gh * ( graphMax - miss3Graph[i] ) / graphMax ) }
}
l = type3Graph.length;
g.lineStyle( 0.5, 0xFF00, 0.8 );
for( i = 0; i < l; i++ ){
if( i == 0 ){ g.moveTo( l-i, gh * ( graphMax - type3Graph[i] ) / graphMax ) }
else{ g.lineTo( l-i, gh * ( graphMax - type3Graph[i] ) / graphMax ) }
}
}
}