Wonder Typing
かっこいいタイピングゲームを作りたい
LIVE CODING 2010/07/16
ルール
何かキーを押すとスタート
Level40になったらタイピング終了
音楽が完全に流れるより前にミスタイプをするとGame Overになります。
Level24になったらミスタイプをしてもGame Overにはなりません。
使用したコード
タイピングゲームをつくろう! http://wonderfl.net/c/8Al5
うにょうにょ http://wonderfl.net/c/rrle
はじけ飛ぶ何か http://wonderfl.net/c/g4Yr
SiON TETRISizer http://wonderfl.net/c/f5eX
/**
* Copyright shohei909 ( http://wonderfl.net/user/shohei909 )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/5vKk
*/
// forked from shohei909's タイピングゲームをつくろう!Let's make typing game
// forked from shohei909's LIVE CODING 一日でタイピングゲーム作る on 2010-3-29
//かっこいいタイピングゲームを作りたい
//LIVE CODING 2010/07/16
//ルール
//何かキーを押すとスタート
//Level40になったらタイピング終了
//音楽が完全に流れるより前にミスタイプをするとGame Overになります。
//Level24になったらミスタイプをしてもGame Overにはなりません。
//使用したコード
//タイピングゲームをつくろう! http://wonderfl.net/c/8Al5
//うにょうにょ http://wonderfl.net/c/rrle
//はじけ飛ぶ何か http://wonderfl.net/c/g4Yr
//SiON TETRISizer http://wonderfl.net/c/f5eX
package{
import flash.display.AVM1Movie;
import flash.geom.Rectangle;
import flash.geom.Matrix;
import flash.display.BitmapData;
import flash.display.Bitmap;
import flash.display.BlendMode;
import flash.display.Sprite;
import flash.text.*;
import flash.events.*;
import org.si.sound.events.*;
import org.si.sion.events.*;
import org.si.sion.*;
import com.bit101.components.*;
public class Game extends Sprite{
public static const W:int = 465;
public static const H:int = 465;
//Typingクラスのオブジェクトを作成します。
public var typing:Typing = new Typing();
//レベル
private var level:int = 0;
//背景のエフェクト
public var erectMap:ErectBitmap = new ErectBitmap();
public var smokeMap:SmokeMap = new SmokeMap(W,H);
//枠の表示
public var flame:Sprite = new Sprite();
//結果表示用の変数
public var textField:TextField = new TextField();
public var title:Label;
public var subtitle:Label;
public var baseData:String = "";
public var typeData:String = "";
public var wordData:String = "";
private var windowX:int;
private var windowY:int;
private var sion:SiON;
private var wait:int = 10;
private var stop:Boolean = true;
private var lineBrghtness:Number = 1;
private var whiteOut:Boolean = false;
private var whiteLevel:int = 0;
private var clear:Boolean = false;
private var sounds:Vector.<int> = new Vector.<int>();;
private var sound:int=-1;
private var d:Array=[62,65,69,72];
public function Game() {
//好きな単語をリストに登録します
var list:Array=[
{ word : "" , kana : "wonderful" },
{ word : "" , kana : "flash" },
{ word : "" , kana : "target" },
{ word : "" , kana : "hit" },
{ word : "" , kana : "text" },
{ word : "" , kana : "count" },
{ word : "" , kana : "black" },
{ word : "" , kana : "field" },
{ word : "" , kana : "down" },
{ word : "" , kana : "mail" },
{ word : "" , kana : "true" },
{ word : "" , kana : "clear" },
{ word : "" , kana : "build" },
{ word : "" , kana : "make" },
{ word : "" , kana : "loop" },
{ word : "" , kana : "frame" },
{ word : "" , kana : "matrix" },
{ word : "" , kana : "logic" },
{ word : "" , kana : "fire" },
{ word : "" , kana : "stage" },
{ word : "" , kana : "parent" },
{ word : "" , kana : "window" },
{ word : "" , kana : "white" },
{ word : "" , kana : "fiber" },
{ word : "" , kana : "second" },
{ word : "" , kana : "visible" },
{ word : "" , kana : "license" },
{ word : "" , kana : "magic" },
{ word : "" , kana : "check" },
{ word : "" , kana : "sound" },
{ word : "" , kana : "step" },
{ word : "" , kana : "test" },
{ word : "" , kana : "data" },
{ word : "" , kana : "try" },
{ word : "" , kana : "trick" },
{ word : "" , kana : "escape" },
{ word : "" , kana : "delete" },
{ word : "" , kana : "print" },
{ word : "" , kana : "shift" },
{ word : "" , kana : "end" },
{ word : "" , kana : "copy" },
{ word : "" , kana : "event" },
{ word : "" , kana : "child" },
{ word : "" , kana : "rectangle" },
{ word : "" , kana : "scale" },
{ word : "" , kana : "height" },
{ word : "" , kana : "width" },
{ word : "" , kana : "display" },
{ word : "" , kana : "add" },
{ word : "" , kana : "center" },
{ word : "" , kana : "next" },
{ word : "" , kana : "object" },
{ word : "" , kana : "number" },
{ word : "" , kana : "color" },
{ word : "" , kana : "dark" },
{ word : "" , kana : "line" },
{ word : "" , kana : "cool" },
{ word : "" , kana : "effect" },
{ word : "" , kana : "sphere" },
{ word : "" , kana : "puzzle" },
{ word : "" , kana : "time" },
{ word : "" , kana : "memory" },
{ word : "" , kana : "movie" },
{ word : "" , kana : "action" },
{ word : "" , kana : "air" },
{ word : "" , kana : "work" },
{ word : "" , kana : "skin" },
{ word : "" , kana : "private" },
{ word : "" , kana : "application" },
{ word : "" , kana : "answer" },
{ word : "" , kana : "style" },
{ word : "" , kana : "void" },
{ word : "" , kana : "set" },
{ word : "" , kana : "project" },
{ word : "" , kana : "package" },
{ word : "" , kana : "world" },
{ word : "" , kana : "noise" }
];
//個人的に単語の最後にスペースを打つ形式が好きなので、
//単語リストにスペースを追加していきます。
for(var i:uint=0;i<list.length;i++){list[i].kana+=" ";}
//typingクラスに単語リストを設定します。
typing.setWordList(list);
//表示
addChild(erectMap);
erectMap.scaleX = 5;
erectMap.scaleY = 5;
addChild(smokeMap);
addChild(typing);
addChild(flame);
new FPSMeter(this);
title = new Label(this,10,360,"Wonder Typing");
title.scaleX = title.scaleY = 4;
subtitle = new Label(this,20,420,"Press any key to start");
subtitle.scaleX = subtitle.scaleY = 1.5;
//音
sion = new SiON(_onBeat, _onNoteOn);
//TypingEventのリスナーを追加します。
typing.addEventListener(TypingEvent.TYPE_WORD,onWordType); //単語入力完了を監視するリスナー
typing.addEventListener(TypingEvent.TYPE,onType); //文字のタイプを監視するリスナー
addEventListener(Event.ENTER_FRAME,onEnterFrame);
//音楽開始
sion.start();
//textFieldでタイピングの結果など表示します
addChild(textField);
textField.autoSize = TextFieldAutoSize.LEFT;
textField.blendMode = BlendMode.INVERT;
textField.scaleX=1.4;
textField.scaleY=1.4;
textField.y=370;
textField.x=320;
//Escキーを感知するためのリスナー
stage.addEventListener("keyDown", restart);
}
private function start():void{
sounds = new Vector.<int>();
erectMap.reset();
sion.start();
//タイピングを開始します。
typing.reset();
typing.start();
//ターゲットとなる単語を設定します
setTarget();
stop = false;
level = 0;
title.text = "Wonder Typing";
subtitle.text = "";
}
private function end():void{
clear = false;
typing.stop();
sion.end();
smokeMap.clear();
wait = 30;
_blackOut();
}
//ターゲットを設定します
private function setTarget():void{
//単語表からタイプする単語を追加します。
typing.addTargetRandom(1); //ランダムに単語を追加します。
//ウィンドウの表示場所を設定します。
var x:int = 300*Math.random()+70;
var y:int = 250*Math.random()+20;
var l:int = typing.target[0].kana.length;
typing.typingWindows[0].x = x-70;
typing.typingWindows[0].y = y;
smokeMap.create(x-5*l,y,l,10,8);
}
private function drowFlame():void{
flame.graphics.clear();
lineBrghtness -= 0.03;
var blue:uint = 0x0000FF*lineBrghtness;
var green:uint = 0x0000FF*lineBrghtness;
var red:uint = 0x000033*lineBrghtness;
flame.graphics.lineStyle(5,0x01*blue + 0x0100*green + 0x010000*red ,0.7);
flame.graphics.beginFill(0x000000,0.8);
flame.graphics.drawRect(5,360,455,100);
}
//タイプした時に呼び出されるイベント
private function onType(e:TypingEvent):void{
if(e.miss==0){
var l:int = Math.ceil(level/4)+1;
for(var i:int=0;i<l;i++){
erectMap.addPoint();
}
if("qwert".indexOf(e.typed)>=0){sion.se(2);}
if("asdfg".indexOf(e.typed)>=0){sion.se(4);}
if("zxcvb".indexOf(e.typed)>=0){sion.se(6);}
if("yuiop".indexOf(e.typed)>=0){sion.se(3);}
if("hjkl;".indexOf(e.typed)>=0){sion.se(5);}
if("nm,./".indexOf(e.typed)>=0){sion.se(7);}
smokeMap.del();
}else{
smokeMap.bitmapData.fillRect(smokeMap.bitmapData.rect, 0x44993311);
if(level<24){
title.text="Game Over";
erectMap.reset();
end();
}else{
}
}
}
//単語が入力完了した時に呼び出されるイベント
private function onWordType(e:TypingEvent):void{
sion.se(0);
level++;
sion.measure = level;
smokeMap.bitmapData.fillRect(smokeMap.bitmapData.rect, 0x88777777);
//40単語タイプしたらタイピング終了
if(level==40){
if(typing.play){
finish();
typing.stop();
}
}else{
//ターゲットがなくなったのに合わせて、次のターゲットを表示します。
if(typing.target.length == 0){
setTarget();
}
}
}
private function finish():void{
end();
clear = true;
}
//毎フレーム呼び出されるイベント
private function onEnterFrame(e:Event):void{
if(wait == 0){
//好きなようにタイピングの結果を表示します。
baseData = " Time: " + typing.time.toFixed(3);
baseData += "\n Level: " + level + "/" + 40;
baseData += "\n Touch: " + typing.touch;
var speed:Number = typing.touch/(typing.time+0.01);
baseData += "\n Speed: " + speed.toFixed(1) + "key/s";
textField.text = baseData + "\n\n" + typeData + "\n\n" + wordData;
if(typing.play == false){
//終了処理
stop = true;
subtitle.text = "Press any key to start";
if(clear){setRank();}
}
}else{
wait--;
}
drowFlame();
if(whiteLevel > -1 && whiteLevel < 0xD0){
smokeMap.transMap.fillRect(smokeMap.transMap.rect,0x01000000*whiteLevel + 0xFFFFFF);
if(whiteOut){
whiteLevel++;
}else{
whiteLevel--;
}
}
}
private function _whiteOut():void{
whiteLevel = 1;
whiteOut = true;
}
private function _blackOut():void{
whiteLevel--;
whiteOut = false;
}
private function restart(e:KeyboardEvent = null):void{
if(stop && e.keyCode!=229){
start();
}
}
private function setRank():void{
var r:String = "Rank O";
var t:Number = typing.time;
if(t<35){ r = "Rank !!!"; }
else if(t<45){ r = "Rank !!"; }
else if(t<55){ r = "Rank !"; }
else if(t<65){ r = "Rank S"; }
else if(t<75){ r = "Rank AAA"; }
else if(t<90){ r = "Rank AA"; }
else if(t<110){ r = "Rank A"; }
else if(t<130){ r = "Rank B"; }
else if(t<160){ r = "Rank C"; }
else if(t<200){ r = "Rank D"; }
else if(t<240){ r = "Rank E"; }
else if(t<290){ r = "Rank F"; }
else if(t<350){ r = "Rank G"; }
else if(t<410){ r = "Rank H"; }
else if(t<470){ r = "Rank I"; }
else if(t<530){ r = "Rank J"; }
else if(t<600){ r = "Rank K"; }
title.text = typing.time.toFixed(3)+"_"+r;
}
//---------------------------------------- SiON events
private function _onBeat(e:SiONTrackEvent) : void {
lineBrghtness = 1;
}
private function _onNoteOn(e:SiONTrackEvent) : void {
if (e.eventTriggerID == 1) {
_whiteOut();
}
}
}
}
import flash.text.*;
import flash.events.*;
import flash.utils.*;
import flash.geom.*;
import flash.display.*;
import flash.filters.BlurFilter;
import mx.utils.ColorUtil;
import org.si.sion.*;
import org.si.sion.events.*;
import org.si.sion.effector.*;
import org.si.sion.sequencer.*;
import org.si.sound.*;
import org.si.sound.synthesizers.*;
//音
class SiON extends SiONDriver {
private var bs:BassSequencer = new BassSequencer("o3C", 15);
public var dm:DrumMachine = new DrumMachine(0,0,0,2,2,2);
private var back:SiONData, fill:SiONData, fill2:SiONData;
private var analogSynth:AnalogSynth = new AnalogSynth();
function SiON(onBeat:Function, onNoteOn:Function) : void {
super();
setVoice(0, new SiONVoice(5,2,63,63,-10,0,2,20));
back = compile("#EFFECT1{delay312,30,1};%5@0,40@v64,32q1s24$o6b-r2.;");
fill = compile("#A=o7[crgrfrcrgrfcrgfr];r1^1%6@0l16@v32,16q8$A(7)A(5);%2@f0,2,16q8s20@0,10%t1,1,0c1^1^8;%2q0s32l16v4[cc(]16;@v128%5@5q0s32,-128o3$c;");//)
fill2= compile("#A=o7[drargrdrargaragr];%6@0l16@v16,8q8$AA");
bpm = 132;
setSamplerData(0, render("%2@v128q0s32o4g16"));
setSamplerData(2, render("%6@0o8q8l64cb-f"));
setSamplerData(3, render("%6@0o8q8l64gcd"));
setSamplerData(4, render("%6@0o7q8l64cb-f"));
setSamplerData(5, render("%6@0o7q8l64gcd"));
setSamplerData(6, render("%6@0o6q8l64cb-f"));
setSamplerData(7, render("%6@0o6q8l64gcd"));
addEventListener(SiONTrackEvent.BEAT, onBeat);
addEventListener(SiONTrackEvent.NOTE_ON_FRAME, onNoteOn);
addEventListener(SiONEvent.STREAM_STOP, _onStreamStop);
dm.volume = 0.6;
bs.synthesizer = analogSynth;
bs.volume = 0.4;
analogSynth.setVCAEnvelop(0, 0.3, 0.7, 0.2);
analogSynth.setVCFEnvelop(0.4, 0.3, 0.1, 0.6, 0.7);
}
public function set measure(m:int) : void {
switch (m) {
case 1: dm.bass.mute = false; break;
case 4: dm.hihat.mute = false; break;
case 8: bs.mute = false; bs.fadeIn(16); break;
case 10: bpm = 105; break;
case 12: bpm = 110; analogSynth.setVCFEnvelop(0.45, 0.3, 0.1, 0.6, 0.75); break;
case 14: bpm = 115; analogSynth.setVCFEnvelop(0.5, 0.3, 0.1, 0.6, 0.8); break;
case 16: bpm = 120; analogSynth.setVCFEnvelop(0.55, 0.3, 0.1, 0.6, 0.85); break;
case 18: bpm = 125; analogSynth.setVCFEnvelop(0.6, 0.3, 0.1, 0.6, 0.85); break;
case 20: bpm = 132; dm.snare.mute = false; dm.hihatPatternNumber = 2; break;
case 24: sequenceOn(fill, null, 0, 0, 16); break;
case 28: sequenceOn(fill2, null, 0, 0, 16); break;
}
}
public function start() : void {
bpm = 100;
fadeIn(4);
play(back);
dm.snarePatternNumber = 0;
dm.hihatPatternNumber = 13;
dm.snare.mute = true;
dm.hihat.mute = true;
dm.bass.mute = true;
bs.mute = true;
dm.play();
bs.play();
}
public function end() : void {
fadeOut(4);
}
public function se(i:int, pan:int=0, len:int=0, qnt:int=1) : void {
var t:SiMMLTrack = playSound(i, len, 0, qnt);
t.effectSend1 = 32;
t.pan = pan;
}
private function _onStreamStop(e:SiONEvent) : void {
bs.stop();
dm.stop();
}
}
//はじけ飛ぶEffect==========================
class SmokeMap extends Bitmap{
public var color:uint = 0xFF000000;
private var cores:Vector.<Object> = new Vector.<Object>();
private var points:Vector.<Object> = new Vector.<Object>();
public var transMap:BitmapData;
private var rate:Number = 60;
private var filter:BlurFilter = new BlurFilter(4,4,1);
private var aliveRect:Rectangle;
public function SmokeMap(w:int,h:int){
aliveRect = new Rectangle(-100,-100,w+200,h+200);
transMap = new BitmapData(w,h,true,0x00000000);
super(new BitmapData(w,h,true));
this.addEventListener( "enterFrame", onFrame );
}
public function create(x:int,y:int,n:int,w:int=10,r:int = 10):void{
for(var i:int=0;i<n;i++){
var core:Object = { x:x+i*w,y:y };
cores.push( core );
for(var j:int=0;j<5;j++){
var randX:Number = (Math.random()*2-1);
var randY:Number = (Math.random()*2-1);
points.push( {
x: core.x+randX*r,
y: core.y+randY*r,
dy: randX*r,
dx: randY*r,
target: core,
chase: true,
life: 40
} );
}
}
}
private function onFrame(e:Event):void{
move();
drow();
}
private function drow():void{
var b:BitmapData = bitmapData;
b.lock();
b.merge(transMap,b.rect,new Point(),50,50,50,50);
var l:int = points.length;
for(var i:int=l-1;i>-1;i--){
var p:Object = points[i];
b.fillRect(new Rectangle(p.x,p.y,15,15),color*p.life/10);
}
b.applyFilter(b,b.rect,new Point(),filter);
b.unlock();
}
private function move():void{
var l:int = points.length;
for(var i:int=0;i<l;i++){
var p:Object = points[i];
p.x += p.dx;
p.y += p.dy;
if(p.chase){
var core:Object = p.target;
var rx:Number = core.x-p.x;
var ry:Number = core.y-p.y;
var deg:Number = Math.atan2( rx , ry );
var r:Number = (rx*rx+ry*ry)/100;
p.dx += Math.sin(deg)*r;
p.dy += Math.cos(deg)*r;
}else{
p.life--;
if(p.life<0 || bitmapData.rect.contains(p.x,p.y)==false){
points.splice(i,1);
l--;i--;
}
}
}
}
public function del(n:int = 0):Boolean{
var l:int = points.length;
if(n < cores.length){
var c:Object = cores[n];
cores.splice(n,1);
for(var i:int=0;i<l;i++){
var p:Object = points[i];
if(p.target == c){
p.chase = false;
p.dx *= 5;
p.dy *= 5;
}
}
return true;
}
return false;
}
public function clear():void{
while(del()){}
}
}
//=============================
//背景用Effect=============================
class ErectBitmap extends Bitmap{
public static const WIDTH:int = 93;
public static const HEIGHT:int = 93;
public static const DIR:Array = [[1,0],[0,1],[-1,0],[0,-1]];
public var baseBitmap:BitmapData;
public var points:Vector.<Object>=new Vector.<Object>();
private var count:int=0;
private var stock:int=0;
public function ErectBitmap():void{
baseBitmap = new BitmapData(WIDTH,HEIGHT,false,0x222222)
super(baseBitmap.clone());
baseBitmap.lock();
for(var i:int=1;i<WIDTH;i+=2){
for(var j:int=1;j<HEIGHT;j+=2){
baseBitmap.setPixel(i,j,0x000000);
}
}
baseBitmap.unlock();
addEventListener(Event.ENTER_FRAME,onFrame);
}
public function onFrame(e:Event):void{
count++;
bitmapData.lock();
bitmapData.merge(baseBitmap,baseBitmap.rect,new Point(),50,100,80,100);
var size:int = points.length;
for(var i:int;i<size;i++){
var point:Object = points[i];
drow(point); move(point);
if(bitmapData.rect.contains(point.x,point.y)==false){
points.splice(i,1);
size--;i--;
}
if(count%2==0){
var pDir:int = Math.random()*5;
if(pDir<4){ point.dir=DIR[pDir] }
}
}
if(count%2==0){
while(stock > 0){stock--;add();}
}
bitmapData.unlock();
}
private function drow(point:Object):void{
bitmapData.setPixel(point.x,point.y,point.color);
}
private function move(point:Object):void{
point.x += point.dir[0];
point.y += point.dir[1];
}
private function add():void{
var px:int = Math.ceil((WIDTH/2+0.5) * Math.random()) ;
var py:int = Math.ceil((HEIGHT/2+0.5) * Math.random()) ;
px =px*2; py=py*2;
var pDir:int = Math.random()*4;
var red:uint = Math.random()*0xCC+0x44;
var green:uint = Math.random()*0xCC+0x44;
var blue:uint = Math.random()*0xFF;
var pColor:uint = red*0x010000 + green*0x0100 + blue*0x01;
points.push({x:px,y:py,dir:DIR[pDir],color:pColor});
}
public function addPoint():void{
stock++;
}
public function reset():void{
stock=0;
points=new Vector.<Object>();
}
}
//=============================
//単語を表示する。ウィンドウの表示。
class TypingWindow extends Sprite{
public var typedFormat:TextFormat = new TextFormat();
public var kanaFormat:TextFormat = new TextFormat();
public var wordFormat:TextFormat = new TextFormat();
public var romanFormat:TextFormat = new TextFormat();
public var kanaField:TextField = new TextField();
public var wordField:TextField = new TextField();
public var romanField:TextField = new TextField();
public var blinde:Sprite = new Sprite();
public var messageFormat:TextFormat = new TextFormat();
public var messageField:TextField = new TextField();
public function TypingWindow(){
//addChild(kanaField);
//addChild(wordField);
addChild(romanField);
layout();
}
//ウィンドウのレイアウトです。好きに改変してください*******************************************
public function layout():void{
var w :int = 140; //幅
var h :int = 30; //高さ
var r :int = 20; //丸み
//背景、枠の設定
//graphics.lineStyle (4, 0x000000, 1); // 線のスタイル指定
//graphics.beginFill (0xAAAACC, 1); // 面のスタイル設定
//graphics.drawRoundRect(0, 0, w, h , r , r);
/*
//かなの設定
with(kanaFormat){
size = 15; //サイズの設定
bold = false //太文字にするか
font = "MS ゴシック" //フォント
align = "center"; //文字の揃え方
}
with(kanaField){
width = 200;
y = 10;
alpha = 1; //透明度
selectable = false;
defaultTextFormat = kanaFormat;
}*/
/*
//メインの単語の設定
with(wordFormat){
size = 24; //サイズの設定
bold = true; //太文字にするか
font = "メイリオ" //フォント
align = "center"; //文字の揃え方
}
with(wordField){
width = 200;
y = 25;
alpha = 1; //透明度
selectable = false;
defaultTextFormat = wordFormat;
}
*/
//ローマ字の設定
with(romanFormat){
size = 15; //サイズの設定
bold = false; //太文字にするか
font = "メイリオ" //フォント
align = "center"; //文字の揃え方
color = 0xDDDDDD; //色
}
with(romanField){
width = w;
x="0"
y = 0;
alpha = 1; //透明度
selectable = false;
defaultTextFormat = romanFormat;
}
//タイプ済みの文字の設定
with(typedFormat){
size = 15; //サイズの設定
bold = false; //太文字にするか
font = "メイリオ" //フォント
color = 0x666666; //色
align = "center"; //文字の揃え方
}
//ウィンドウがオフのときの設定
blinde.graphics.lineStyle (4, 0x444444, 0.3); // 線のスタイル指定
blinde.graphics.beginFill (0x000000, 0.7); // 面のスタイル設定
blinde.graphics.drawRoundRect(0, 0, w, h , r , r);
//メッセージの設定
with(messageFormat){
size = 25; //サイズの設定
bold = true; //太文字にするか
color = 0xFFFFFF;
font = "メイリオ" //フォント
align = "center"; //文字の揃え方
}
with(messageField){
width = w;
y = -5;
alpha = 1; //透明度
selectable = false;
defaultTextFormat = messageFormat;
}
}
//****************************************************************
public function off():void{
if(contains(blinde)==false){addChild(blinde);}
}
public function on():void{
if(contains(blinde)){removeChild(blinde);}
if(contains(messageField)){removeChild(messageField);}
}
public function setMessage(m:String):void{
messageField.text = m;
off();
addChild(messageField);
}
public var _typed:String;
public function set typed(t:String):void{
_typed = t;
var length:int = _typed.length;
if(length > romanField.text.length){
length = romanField.text.length;
}else if(length+1 == romanField.text.length){
if(romanField.text.substring(length)==" "){
setMessage("SPACE");
}
}
romanField.setTextFormat(typedFormat,-1,length);
}
}
//ここから下は編集せずにタイピングゲームを作ることができます
class Typing extends Sprite{
public var typed:String;
public var play:Boolean;
public var time:Number;
private var lastTime:Number;
public var touch:int;
public var missTouch:int;
public var finWord:int;
public var typingWindows:Vector.<TypingWindow>;
public var romanList:Vector.<Array>;
public var wordList:Array = new Array(); //単語表
public var target:Vector.<Object>; //現在ターゲットとなっている単語
public var hint:Vector.<Object>; //次以降の単語
//Objectの変数は基本的に二つ word:単語 kana:かな index:単語リスト中での番号
public var unused:Vector.<int>; //未使用の単語のリスト
private var lastWord:Object;
private var lastType:Object;
private var currentWord:Object;
private var currentType:Object;
//文字をタイプします。 t は length=1 の文字列にしてください。
//このメソッドを呼び出すと指定された文字列をタイプしたのと同じ操作をします
public function type(t:String):void{
var s:String = typed + t;
var miss:Boolean=true;
var clear:int = -1;
for(var i:int=target.length-1;i>=0;i--){
if(match(target[i].kana,s) == s.length){
typed = s;
typingWindows[i].on();
var preffered:String = preferredRoman(target[i].kana,s);
typingWindows[i].romanField.text = preffered;
typingWindows[i].typed = typed;
miss = false;
if(typed==preffered){
clear = i;
}
}else{
typingWindows[i].off();
typingWindows[i].romanField.text = firstRoman(target[i].kana);
}
}
if(miss){
currentType.miss = 1;
currentWord.miss++;
missTouch++;
back();
}else{
touch++;
currentType.miss=0;
}
currentType.typed = t;
currentType.time = time;
dispatchEvent(new TypingEvent(TypingEvent.TYPE,false,false,
currentType.time - lastType.time,currentType.typed,currentType.miss));
lastType = currentType;
currentType = {typed:"", miss:0, time:0};
if(clear>=0){
finWord++;
currentWord.index = target[clear].index;
currentWord.word = target[clear].word;
currentWord.kana = target[clear].kana;
currentWord.typed = typed;
clearWord(clear);
}
}
//単語リストの設定
//start()するより前に設定してください.
//またtargetが設定されているときに単語リストを変更しないでください。
public function setWordList(list:Array):void{
wordList = list;
unused = new Vector.<int>();
for(var i:int=0;i<wordList.length;i++){
unused[i] = i;
wordList[i].index = i;
}
}
//単語リスト hint の中から順番にnコの単語をtargetに追加
public function addTargetFirst(n:int):void{
if(wordList.length < 1){return;}
for(var i:int=0;i<n;i++){
var k:int;
if(hint.length == 0){
if(unused.length==0){
for(var j:int=0;j<wordList.length;j++){
unused[j] = j;
}
}
k = unused[0];
unused.splice(0,1);
addTarget(wordList[k]);
}else{
addTarget(hint[0]);
hint.splice(0,1);
}
}
}
//単語リストまたは hint の中からランダムにnコの単語をtargetに追加
public function addTargetRandom(n:int):void{
if(wordList.length < 1){return;}
for(var i:int=0;i<n;i++){
var rand:int;
var k:int;
if(hint.length == 0){
if(unused.length==0){
for(var j:int=0;j<wordList.length;j++){
unused[j] = j;
}
}
rand = Math.random() * unused.length;
k = unused[rand];
unused.splice(rand,1);
addTarget(wordList[k]);
}else{
rand = Math.random() * hint.length;
hint.splice(rand,1);
addTarget(hint[rand]);
}
}
}
//単語リストの中から順番にnコの単語をhintに追加
//hintに設定された単語は優先的にtargetに追加されるので,
//hintを用いることで次の単語、その次の単語をあらかじめ決めることができます。
public function addHintFirst(n:int):void{
if(wordList.length < 1){return;}
for(var i:int=0;i<n;i++){
var k:int;
if(unused.length==0){
for(var j:int=0;j<wordList.length;j++){
unused[j] = j;
}
}
k = unused[0];
unused.splice(0,1);
addHint(wordList[k]);
}
}
//単語リストの中からランダムにnコの単語をhintに追加
public function addHintRandom(n:int):void{
if(wordList.length < 1){return;}
for(var i:int=0;i<n;i++){
var rand:int;
var k:int;
if(unused.length==0){
for(var j:int=0;j<wordList.length;j++){
unused[j] = j;
}
}
rand = Math.random() * unused.length;
k = unused[rand];
unused.splice(rand,1);
addHint(wordList[k]);
}
}
/*
addTargetRandom(),addTargetFirst(),
addHintRandom(),addHintFirst()メソッドは
既に使用されている単語を避けて、単語を追加します。
つまり,addTargetRandom(),addTargetFirst()メソッドでは、
1, hintに指定されている単語
2, まだ使用されていない単語
3, 既に使用された単語
の順に、単語の追加が行われます。
*/
//Objectを指定してtargetに追加
public function addTarget(o:Object):void{
target.push(o);
typingWindows.push(new TypingWindow());
typingWindows[typingWindows.length-1].kanaField.text = o.kana;
typingWindows[typingWindows.length-1].wordField.text = o.word;
typingWindows[typingWindows.length-1].romanField.text = firstRoman(o.kana);
addChildAt(typingWindows[typingWindows.length-1],0);
}
//Objectを指定してhintに追加
public function addHint(o:Object):void{
hint.push(o);
}
//targetを消去。removeTarget(消去する最初のターゲット,消去する個数)
public function removeTarget(s:int, count:int = -1):void{
var c:int = 0;
while(c != count && target.length > s){
removeChild(typingWindows[s]);
typingWindows.splice(s,1);
target.splice(s,1);
c++;
}
return;
}
//単語入力完了処理
public function clearWord(n:int):void{
removeTarget(n,1);
typed="";
back();
currentWord.time = time;
dispatchEvent(new TypingEvent(TypingEvent.TYPE_WORD,false,false,
currentWord.time - lastWord.time,currentWord.typed,currentWord.miss,
currentWord.word,currentWord.kana,currentWord.index
));
lastWord = currentWord;
currentWord = {typed:"",word:"", kana:"", index:0, miss:0, time:0};
}
//与えられたかなの先頭にromanが最大何文字マッチするか返す
public function match(kana:String,roman:String):int{
var matchLength:int = 0;
var longest:int = 0;
var unreaded:String = kana;
var unreadedRoman:String = roman;
while(unreaded.length != 0 && unreadedRoman.length != 0){
loop1:for(var n:int=4;n>0;n--){//文字数
for(var m:int=0;m<3;m++){//候補番号
if(romanList[m][unreaded.substring(0,n)] != undefined){
var term:String = romanList[m][unreaded.substring(0,n)]
if(term == unreadedRoman.substring(0,term.length)){
unreaded = unreaded.substring(n);
unreadedRoman = unreadedRoman.substring(term.length);
matchLength += term.length;
longest = matchLength;
break loop1;
}else{
while(term.length > 1){
term = term.substring(0,term.length - 1);
if(term == unreadedRoman.substring(0,term.length)){
if(longest < matchLength + term.length){longest = matchLength + term.length;}
break;
}
}
}
}
}
}
if(n==0){break;}
}
return longest;
}
public function preferredRoman(kana:String,roman:String):String{
//romanがタイプされているときの最適なローマ字の振り方を返す
var matchLength:int = 0;
var longest:int = 0;
var preferred:String = "";
var unreaded:String = kana;
var unreadedRoman:String = roman;
while(unreaded.length != 0 && unreadedRoman.length != 0){
loop1:for(var n:int=4;n>0;n--){//文字数
for(var m:int=0;m<4;m++){//候補番号
if(romanList[m][unreaded.substring(0,n)] != undefined){
var term:String = romanList[m][unreaded.substring(0,n)]
if(term == unreadedRoman.substring(0,term.length)){
preferred += term;
unreaded = unreaded.substring(n);
unreadedRoman = unreadedRoman.substring(term.length);
matchLength += term.length;
longest = matchLength;
if(roman.length==longest){return preferred + firstRoman(unreaded);}
break loop1;
}else{
var bterm:String = term;
while(term.length > 1){
term = term.substring(0,term.length - 1);
if(term == unreadedRoman.substring(0,term.length)){
longest = matchLength+term.length;
if(roman.length==longest){
preferred += bterm;
unreaded = unreaded.substring(n);
unreadedRoman = unreadedRoman.substring(term.length);
matchLength += term.length;
longest = matchLength;
return preferred + firstRoman(unreaded);
}
break;
}
}
}
}
}
}
if(n==0){
break;
}
}
preferred += firstRoman(unreaded);
return preferred;
}
//kanaのもっとも簡単なローマ字の振り方を返す
public function firstRoman(kana:String):String{
var unreaded:String = kana;
var preferred:String = "";
while(unreaded.length != 0){
loop1:for(var n:int=4;n>0;n--){//文字数
for(var m:int=0;m<4;m++){//候補番号
if(romanList[m][unreaded.substring(0,n)] != undefined){
preferred += romanList[m][unreaded.substring(0,n)];
unreaded = unreaded.substring(n);
break loop1;
}
}
}
if(n==0){
break;
}
}
return preferred;
}
//単語リストとウインドウスタイル以外を初期化します
public function reset():void{
time = 0;
missTouch = 0;
touch = 0;
finWord = 0;
typed = "";
currentWord = {typed:"",word:"", kana:"", index:0, miss:0, time:0};
currentType = {typed:"", miss:0, time:0};
lastWord = {typed:"",word:"", kana:"", index:0, miss:0, time:0};
lastType = {typed:"", miss:0, time:0};
typingWindows = new Vector.<TypingWindow>();
target = new Vector.<Object>();
hint = new Vector.<Object>();
while(numChildren>0){removeChildAt(0);}
setWordList(wordList);
play = false;
}
//タイピングを一時停止します
public function stop():void{
play = false;
removeEventListener(Event.ENTER_FRAME,onEnterFrame);
stage.removeEventListener("keyDown", onKeyDown);
}
//タイピングを開始します
public function start():void{
play = true;
lastTime = getTimer()/1000;
addEventListener(Event.ENTER_FRAME,onEnterFrame);
stage.addEventListener("keyDown", onKeyDown);
}
public function onKeyDown(e:KeyboardEvent):void{
if(e.keyCode < 16 || e.keyCode > 18){
type(String.fromCharCode(e.charCode));
}
}
private function back():void{
for(var i:int=0;i<target.length;i++){
if(match(target[i].kana,typed) == typed.length){
var preffered:String = preferredRoman(target[i].kana,typed);
typingWindows[i].romanField.text = preffered;
typingWindows[i].on();
if(typed != ""){typingWindows[i].typed = typed;}
}else{
typingWindows[i].romanField.text = firstRoman(target[i].kana);
}
}
}
public function onEnterFrame(e:Event):void{
var t:Number = getTimer()/1000;
time += t - lastTime;
lastTime = t;
}
public function Typing(){
reset();
romanList = new Vector.<Array>(4); //かなとローマ字の変換表
//候補1------------------------------------------------------------
romanList[0] = new Array();
romanList[0]["ー"] = "-";
romanList[0]["。"] = ".";
romanList[0]["、"] = ",";
romanList[0]["?"] = "?";
romanList[0]["!"] = "!";
romanList[0][" "] = " ";
romanList[0]["あ"] = "a";
romanList[0]["い"] = "i";
romanList[0]["う"] = "u";
romanList[0]["え"] = "e";
romanList[0]["お"] = "o";
romanList[0]["か"] = "ka";
romanList[0]["き"] = "ki";
romanList[0]["く"] = "ku";
romanList[0]["け"] = "ke";
romanList[0]["こ"] = "ko";
romanList[0]["さ"] = "sa";
romanList[0]["し"] = "si";
romanList[0]["す"] = "su";
romanList[0]["せ"] = "se";
romanList[0]["そ"] = "so";
romanList[0]["な"] = "na";
romanList[0]["に"] = "ni";
romanList[0]["ぬ"] = "nu";
romanList[0]["ね"] = "ne";
romanList[0]["の"] = "no";
romanList[0]["た"] = "ta";
romanList[0]["ち"] = "ti";
romanList[0]["つ"] = "tu";
romanList[0]["て"] = "te";
romanList[0]["と"] = "to";
romanList[0]["は"] = "ha";
romanList[0]["ひ"] = "hi";
romanList[0]["ふ"] = "fu";
romanList[0]["へ"] = "he";
romanList[0]["ほ"] = "ho";
romanList[0]["ま"] = "ma";
romanList[0]["み"] = "mi";
romanList[0]["む"] = "mu";
romanList[0]["め"] = "me";
romanList[0]["も"] = "mo";
romanList[0]["や"] = "ya";
romanList[0]["ゆ"] = "yu";
romanList[0]["いぇ"] = "ye";
romanList[0]["よ"] = "yo";
romanList[0]["ら"] = "ra";
romanList[0]["り"] = "ri";
romanList[0]["る"] = "ru";
romanList[0]["れ"] = "re";
romanList[0]["ろ"] = "ro";
romanList[0]["わ"] = "wa";
romanList[0]["ゐ"] = "wi";
romanList[0]["ゑ"] = "we";
romanList[0]["を"] = "wo";
romanList[0]["が"] = "ga";
romanList[0]["ぎ"] = "gi";
romanList[0]["ぐ"] = "gu";
romanList[0]["げ"] = "ge";
romanList[0]["ご"] = "go";
romanList[0]["ざ"] = "za";
romanList[0]["じ"] = "ji";
romanList[0]["ず"] = "zu";
romanList[0]["ぜ"] = "ze";
romanList[0]["ぞ"] = "zo";
romanList[0]["だ"] = "da";
romanList[0]["ぢ"] = "di";
romanList[0]["づ"] = "du";
romanList[0]["で"] = "de";
romanList[0]["ど"] = "do";
romanList[0]["ば"] = "ba";
romanList[0]["び"] = "bi";
romanList[0]["ぶ"] = "bu";
romanList[0]["べ"] = "be";
romanList[0]["ぼ"] = "bo";
romanList[0]["ぱ"] = "pa";
romanList[0]["ぴ"] = "pi";
romanList[0]["ぷ"] = "pu";
romanList[0]["ぺ"] = "pe";
romanList[0]["ぽ"] = "po";
romanList[0]["ぁ"] = "la";
romanList[0]["ぃ"] = "li";
romanList[0]["ぅ"] = "lu";
romanList[0]["ぇ"] = "le";
romanList[0]["ぉ"] = "lo";
romanList[0]["ゃ"] = "lya";
romanList[0]["ゅ"] = "lyu";
romanList[0]["ょ"] = "lyo";
romanList[0]["ゎ"] = "lwa";
romanList[0]["っ"] = "ltu";
romanList[0]["ヵ"] = "lka";
romanList[0]["ヶ"] = "lke";
romanList[0]["きゃ"] = "kya";
romanList[0]["きぃ"] = "kyi";
romanList[0]["きゅ"] = "kyu";
romanList[0]["きぇ"] = "kye";
romanList[0]["きょ"] = "kyo";
romanList[0]["しゃ"] = "sya";
romanList[0]["しぃ"] = "syi";
romanList[0]["しゅ"] = "syu";
romanList[0]["しぇ"] = "sye";
romanList[0]["しょ"] = "syo";
romanList[0]["ちゃ"] = "tya";
romanList[0]["ちぃ"] = "tyi";
romanList[0]["ちゅ"] = "tyu";
romanList[0]["ちぇ"] = "tye";
romanList[0]["ちょ"] = "tyo";
romanList[0]["にゃ"] = "nya";
romanList[0]["にぃ"] = "nyi";
romanList[0]["にゅ"] = "nyu";
romanList[0]["にぇ"] = "nye";
romanList[0]["にょ"] = "nyo";
romanList[0]["ひゃ"] = "hya";
romanList[0]["ひぃ"] = "hyi";
romanList[0]["ひゅ"] = "hyu";
romanList[0]["ひぇ"] = "hye";
romanList[0]["ひょ"] = "hyo";
romanList[0]["みゃ"] = "mya";
romanList[0]["みぃ"] = "myi";
romanList[0]["みゅ"] = "myu";
romanList[0]["みぇ"] = "mye";
romanList[0]["みょ"] = "myo";
romanList[0]["りゃ"] = "rya";
romanList[0]["りぃ"] = "ryi";
romanList[0]["りゅ"] = "ryu";
romanList[0]["りぇ"] = "rye";
romanList[0]["りょ"] = "ryo";
romanList[0]["ぎゃ"] = "gya";
romanList[0]["ぎぃ"] = "gyi";
romanList[0]["ぎゅ"] = "gyu";
romanList[0]["ぎぇ"] = "gye";
romanList[0]["ぎょ"] = "gyo";
romanList[0]["じゃ"] = "ja";
romanList[0]["じぃ"] = "zyi";
romanList[0]["じゅ"] = "ju";
romanList[0]["じぇ"] = "je";
romanList[0]["じょ"] = "jo";
romanList[0]["ぢゃ"] = "dya";
romanList[0]["ぢぃ"] = "dyi";
romanList[0]["ぢゅ"] = "dyu";
romanList[0]["ぢぇ"] = "dye";
romanList[0]["ぢょ"] = "dyo";
romanList[0]["びゃ"] = "bya";
romanList[0]["びぃ"] = "byi";
romanList[0]["びゅ"] = "byu";
romanList[0]["びぇ"] = "bye";
romanList[0]["びょ"] = "byo";
romanList[0]["ぴゃ"] = "pya";
romanList[0]["ぴぃ"] = "pyi";
romanList[0]["ぴゅ"] = "pyu";
romanList[0]["ぴぇ"] = "pye";
romanList[0]["ぴょ"] = "pyo";
romanList[0]["うぁ"] = "wa";
romanList[0]["うぃ"] = "wi";
romanList[0]["うぇ"] = "we";
romanList[0]["うぉ"] = "wo";
romanList[0]["ヴぁ"] = "va";
romanList[0]["ヴぃ"] = "vi";
romanList[0]["ヴ"] = "vu";
romanList[0]["ヴぇ"] = "ve";
romanList[0]["ヴぉ"] = "vo";
romanList[0]["ヴゃ"] = "vya";
romanList[0]["ヴゅ"] = "vyu";
romanList[0]["ヴょ"] = "vyo";
romanList[0]["てゃ"] = "tha";
romanList[0]["てぃ"] = "thi";
romanList[0]["てゅ"] = "thu";
romanList[0]["てぇ"] = "the";
romanList[0]["てょ"] = "tho";
romanList[0]["ふぁ"] = "fa";
romanList[0]["ふぃ"] = "fi";
romanList[0]["ふぅ"] = "fwu";
romanList[0]["ふぇ"] = "fe";
romanList[0]["ふぉ"] = "fo";
romanList[0]["ふゃ"] = "fya";
romanList[0]["ふゅ"] = "fyu";
romanList[0]["ふょ"] = "fyo";
romanList[0]["でゃ"] = "dha";
romanList[0]["でぃ"] = "dhi";
romanList[0]["でゅ"] = "dhu";
romanList[0]["でぇ"] = "dhe";
romanList[0]["でょ"] = "dho";
romanList[0]["くぁ"] = "qa";
romanList[0]["くぃ"] = "qi";
romanList[0]["くぅ"] = "qwu";
romanList[0]["くぇ"] = "qe";
romanList[0]["くぉ"] = "qo";
romanList[0]["くゃ"] = "qya";//何て読むんだ,これ。
romanList[0]["くゅ"] = "qyu";
romanList[0]["くょ"] = "qyo";
romanList[0]["すぁ"] = "swa";
romanList[0]["すぃ"] = "swi";
romanList[0]["すぅ"] = "swu";
romanList[0]["すぇ"] = "swe";
romanList[0]["すぉ"] = "swo";
romanList[0]["ぐぁ"] = "gwa";
romanList[0]["ぐぃ"] = "gwi";
romanList[0]["ぐぅ"] = "gwu";
romanList[0]["ぐぇ"] = "gwe";
romanList[0]["ぐぉ"] = "gwo";
romanList[0]["どぁ"] = "dwa";
romanList[0]["どぃ"] = "dwi";
romanList[0]["どぅ"] = "dwu";
romanList[0]["どぇ"] = "dwe";
romanList[0]["どぉ"] = "dwo";
romanList[0]["とぁ"] = "twa";
romanList[0]["とぃ"] = "twi";
romanList[0]["とぅ"] = "twu";
romanList[0]["とぇ"] = "twe";
romanList[0]["とぉ"] = "two";
romanList[0]["つぁ"] = "tsa";
romanList[0]["つぃ"] = "tsi";
romanList[0]["つぇ"] = "tse";
romanList[0]["つぉ"] = "tso";
romanList[0]["ん"] = "nn";
//候補2------------------------------------------------------------
romanList[1] = new Array();
romanList[1]["い"] = "yi";
romanList[1]["う"] = "wu";
romanList[1]["うぁ"] = "wha";
romanList[1]["うぃ"] = "whi";
romanList[1]["うぇ"] = "whe";
romanList[1]["うぉ"] = "who";
romanList[1]["う"] = "wu";
romanList[1]["か"] = "ca";
romanList[1]["く"] = "cu";
romanList[1]["こ"] = "co";
romanList[1]["くぃ"] = "qwi";
romanList[1]["くぅ"] = "qwu";
romanList[1]["くぇ"] = "qwe";
romanList[1]["くぉ"] = "qwo";
romanList[1]["くぁ"] = "kwa";
romanList[1]["くぃ"] = "qwi";
romanList[1]["くぅ"] = "qwu";
romanList[1]["くぇ"] = "qwe";
romanList[1]["くぉ"] = "qwo";
romanList[1]["しゃ"] = "sha";
romanList[1]["し"] = "shi";
romanList[1]["しゅ"] = "shu";
romanList[1]["しぇ"] = "she";
romanList[1]["しょ"] = "sho";
romanList[1]["せ"] = "ce";
romanList[1]["じ"] = "zi";
romanList[1]["じゃ"] = "zya";
romanList[1]["じぃ"] = "jyi";
romanList[1]["じゅ"] = "zyu";
romanList[1]["じぇ"] = "zye";
romanList[1]["じょ"] = "zyo";
romanList[1]["ちゃ"] = "cha";
romanList[1]["ち"] = "chi";
romanList[1]["ちぃ"] = "cyi";
romanList[1]["ちゅ"] = "chu";
romanList[1]["ちぇ"] = "che";
romanList[1]["ちょ"] = "cho";
romanList[1]["つ"] = "tsu";
romanList[1]["ふ"] = "hu";
romanList[1]["ふぁ"] = "fwa";
romanList[1]["ふぃ"] = "fwi";
romanList[1]["ふぇ"] = "fwe";
romanList[1]["ふぉ"] = "fwo";
romanList[1]["ぁ"] = "xa";
romanList[1]["ぃ"] = "xi";
romanList[1]["ぅ"] = "xu";
romanList[1]["ぇ"] = "xe";
romanList[1]["ぉ"] = "xo";
romanList[1]["ゃ"] = "xya";
romanList[1]["ゅ"] = "xyi";
romanList[1]["ょ"] = "xyu";
romanList[1]["ゎ"] = "xwa";
romanList[1]["っ"] = "ltsu";
romanList[0]["ヵ"] = "xka";
romanList[0]["ヶ"] = "xke";
//候補3------------------------------------------------------------
romanList[2] = new Array();
romanList[2]["う"] = "whu";
romanList[2]["し"] = "ci";
romanList[2]["くぁ"] = "qwa";
romanList[2]["くぃ"] = "qyi";
romanList[2]["くぇ"] = "qye";
romanList[2]["じゃ"] = "jya";
romanList[2]["じゅ"] = "jyu";
romanList[2]["じぇ"] = "jye";
romanList[2]["じょ"] = "jyo";
romanList[2]["ちゃ"] = "cya";
romanList[2]["ちゅ"] = "cyu";
romanList[2]["ちぇ"] = "cye";
romanList[2]["ちょ"] = "cyo";
romanList[2]["ふぃ"] = "fyi";
romanList[2]["ふぇ"] = "fye";
romanList[2]["ふぉ"] = "fwo";
romanList[2]["ぃ"] = "lyi";
romanList[2]["ぇ"] = "lye";
//候補4------------------------------------------------------------
romanList[3] = new Array();
romanList[3]["ぃ"] = "xyi";
romanList[3]["ぇ"] = "xye";
//一文字目になるひらがな表
var beforetse1:Array = [
"あ","い","う","え","お",
"か","き","く","け","こ",
"さ","し","す","せ","そ",
"た","ち","つ","て","と",
"は","ひ","ふ","へ","ほ",
"ま","み","む","め","も",
"や","ゆ","よ",
"わ","ゐ","う","ヱ","を","ん",
"ら","り","る","れ","ろ",
"が","ぎ","ぐ","げ","ご",
"ざ","じ","ず","ぜ","ぞ",
"だ","ぢ","づ","で","ど",
"ば","び","ぶ","べ","ぼ",
"ぱ","ぴ","ぷ","ぺ","ぽ","ヴ",
"ゃ","ゅ","ょ","ゎ",
"ぁ","ぃ","ぅ","ぇ","ぉ",
"!","?","。","、"," "
];
var beforetse2:Array = ["","ゃ","ゅ","ょ",
"ぁ","ぃ","ぅ","ぇ","ぉ"
];
//連続すると「っ」になるアルファベット
var tse:Array =["q","w","r","t","y","p","s","d","f","g","h","j","k","l","z","x","c","v","b","m"];
//直前にn 1つで「ん」になるアルファベット
var nn:Array =["q","w","r","t","p","s","d","f","g","h","j","k","l","z","x","c","v","b","m","!","?",".",","," "];
//「っ」の付く候補作成
for(var i:int = 0;i < beforetse1.length;i++){
for(var j:int = 0;j < beforetse2.length;j++){
for(var k:int = 0;k < 4;k++){
var ok1:Boolean = false;
if( romanList[k][ beforetse1[i]+beforetse2[j] ] !=undefined){
for(var n:int=0;n<tse.length;n++){
if(romanList[k][ beforetse1[i]+beforetse2[j] ].substring(0,1) == tse[n]){ok1 = true;}
}
}
if( ok1 ){
romanList[k][ "っ"+beforetse1[i]+beforetse2[j] ] = romanList[k][ beforetse1[i]+beforetse2[j] ].substr(0,1) + romanList[k][ beforetse1[i]+beforetse2[j] ];
}
var ok2:Boolean = false;
if( romanList[k][ beforetse1[i]+beforetse2[j] ] !=undefined){
for(n=0;n<tse.length;n++){
if(romanList[k][ beforetse1[i]+beforetse2[j] ].substring(0,1) == nn[n]){ok2 = true;}
}
}
if( ok2 ){
romanList[k][ "ん"+beforetse1[i]+beforetse2[j] ] = "n" + romanList[k][ beforetse1[i]+beforetse2[j] ];
}
if( ok1 && ok2 ){
romanList[k][ "ん"+"っ"+beforetse1[i]+beforetse2[j] ] = "n" + romanList[k][ beforetse1[i]+beforetse2[j] ].substr(0,1) + romanList[k][ beforetse1[i]+beforetse2[j] ];
}
}
}
}
//半角文字
for(i=32;i<127;i++){
romanList[0][String.fromCharCode(i)] = String.fromCharCode(i);
}
}
}
class TypingEvent extends Event{
public var time :Number; //タイプにかかった時間
public var typed:String; //タイプされた文字列
public var miss :int; //ミスタイプの数
public var word :String; //タイプされた単語
public var kana :String; //タイプされたかな
public var index :String; //タイプされた単語の番号
static public var TYPE_WORD :String = "typeWord"; //タイプされたかな
static public var TYPE :String = "type"; //タイプされた単語の番号
public function TypingEvent(type:String, bubbles:Boolean = false, cancelable:Boolean = false,
timeValue:Number = 0, typedValue:String = "", missValue:int = 0,
wordValue:String="", kanaValue:String = "", indexValue:String = ""
):void{
super( type , bubbles , cancelable);
time = timeValue;
typed = typedValue;
miss = missValue;
word = wordValue;
kana = kanaValue;
index = indexValue;
}
}