/**
* Copyright tepe ( http://wonderfl.net/user/tepe )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/7Yz6
*/
package{
import flash.display.*;
import flash.filters.GlowFilter;
import flash.system.*;
import flash.text.*;
import flash.net.*;
import flash.events.*;
import flash.geom.Matrix;
import org.libspark.betweenas3.BetweenAS3;
public class Main extends Sprite{
//システムカラー
private const color1:uint = 0x223388;//青
private const color2:uint = 0x44aaff;
//動画リクエストサイズ
private const WIDTH:int = 300;
private const HEIGHT:int = 225;
private var par:Number;//再生進捗率
private var t1:Number = -1;//動画の終了時間
private var players:Array;
private var videoState:int = -1;//プレイヤー状態
//youtube動画ID
private var movie:Array = ["kZAIwipsxo8","MGt25mv4-2Q","W58Il5l_D5s","6m2zV8Adhmk"];
private var i:int = 0;
private var seekWidth:Number = WIDTH;//シークバーの幅
private var list:Array = new Array();//タイミングのリスト
private var codeList:Array;
//セーブデータ
private var so:SharedObject;
private var saveData:Object;
private var player:Object;//youtubeプレイヤー
private var seekBar:Sprite = new Sprite();//シークバー
private var line:Sprite = new Sprite();//タイミングライン
private var timeLine:Sprite = new Sprite();//タイムライン
//デバッグテキスト
private var txt:TextField = new TextField();
private var txt2:TextField = new TextField();
private const tl:Number = 300;//タイムラインが流れる速さを調整
private var lx:Number = 100;//タイミングラインの位置
private var score:int =0;//得点
private var charCnt:int=0;//次のタイピング文字
//コンストラクタ
public function Main(){
init();
}
//初期化
private function init():void{
var loader:Loader;
loader = new Loader();
loader.name = i.toString();
loader.contentLoaderInfo.addEventListener(Event.INIT, onLoaderInit);
const req:String = "http://www.youtube.com/apiplayer?enablejsapi=1&version=3";
loader.load(new URLRequest(req));//youtubeプレイヤー読み込み
stage.addEventListener(Event.ENTER_FRAME,onFrame);
//バックグラウンドカラー
with(graphics){
beginFill(0x000000);
drawRect(-400,0,1400,460);
endFill();
}
//シーク操作開始
seekBar.addEventListener(MouseEvent.MOUSE_DOWN,function():void{
seekBar.addEventListener(MouseEvent.MOUSE_MOVE,onSeek);
});
//シーク操作終了
stage.addEventListener(MouseEvent.MOUSE_UP,function():void{
seekBar.removeEventListener(MouseEvent.MOUSE_MOVE,onSeek);
});
//キーボード入力
stage.addEventListener(KeyboardEvent.KEY_DOWN,onKey);
stage.addEventListener(KeyboardEvent.KEY_UP,function():void{
draw2();
textList[charCnt].textColor = color2;
textList[charCnt].alpha = 1;
});
stage.addChild(txt);
//stage.addChild(txt2);
txt2.textColor = color1;
txt.textColor = color2;
txt.selectable = false;
txt2.selectable= false;
txt.width = 300;
txt2.height = 320;
txt2.text = "";
txt2.alpha = 0.6;
txt.alpha = 0.8;
stage.addChild(timeLine);//タイムライン配置
var glow:GlowFilter = new GlowFilter(color1, 0.3, 13, 15, 5, 15, false, true);
var lineGlow:Shape = new Shape();
lineGlow.filters = [glow];
with(lineGlow.graphics){
lineStyle(2,color1);
moveTo(lx,0);
lineTo(lx,50);
}
draw2();//タイミングライン描画
//タイミングライン配置
line.addChild(lineGlow);
stage.addChild(line);
}
//エンターフレーム
private function onFrame(event:Event):void{
txt.text = String.fromCharCode(charList[charCnt]);
var seek:Number = player.getCurrentTime();//先頭からの経過時間
txt.appendText("\n"+seek.toString());
par = (seek / t1);//再生進捗率更新
txt.appendText("\n"+list[charCnt].toString());
txt.appendText("\n\nscore:"+score.toString());
txt.appendText("\n"+(list[charCnt]-player.getCurrentTime()).toString());
draw1();
timeLine.x = -seek*tl+lx-50;//タイムライン移動
if(list[charCnt] < seek){
if(list[list.length-1]<seek && charCnt == 0)return;
textList[charCnt].textColor = 0x000000;
txt2.scrollV = charCnt;
charCnt++;
charCnt%=list.length;
textList[charCnt].textColor = color2;
textList[charCnt].alpha = 1;
}
}
//シークバー描画
private function draw1():void{
with(seekBar.graphics){1
clear();
beginFill(color1,0.7);
drawRect(0,0,seekWidth,10);
endFill();
beginFill(color2,0.8);
drawRect(0,0,seekWidth*par,10);
endFill();
}
}
//タイミングライン描画
private function draw2(type:int = 0):void{
line.graphics.clear();
with(line.graphics){
if(type==0)lineStyle(2,color2);
else lineStyle(2,color1);
moveTo(lx,0);
lineTo(lx,50);
}
}
//データロード
private function load(id:String="state_data"):void{
so = SharedObject.getLocal(id);
if(so){
var obj : Object = so.data;
if(obj.hasOwnProperty("list") == false)obj.list = new Array();
else list = obj.list;
list.sort(Array.NUMERIC);
//list.reverse();
saveData = obj;
for(var i:int=0;i<list.length;i++){
txt2.appendText("["+i.toString()+"]"+list[i].toString()+"\n");
var n3:Number = list[i]*tl;
timeLine.graphics.lineStyle(1,color2);
timeLine.graphics.moveTo(n3,0);
timeLine.graphics.lineTo(n3,50);
}
setKeyCode();
}
}
private var charList:Array;//タイピングコードの配列
private var textList:Array;//表示文字の配列
private function setKeyCode():void{
var len:int = list.length;
charList = new Array();
textList = new Array();
var i:int;
for(i=0;i<len;i++) charList.push(rndChar());
for(i=0;i<len;i++) createStr(String.fromCharCode(charList[i]), list[i]);
}
//表示文字生成
private function createStr(str:String,timestamp:Number,fontSize:int=50):void{
var c:TextField = new TextField();//表示文字
var c2:TextField = new TextField();//グローフィルター用
var base:Sprite = new Sprite();//ベース
//テキスト設定
var tf:TextFormat = new TextFormat();//テキストフォーマット
tf.size = fontSize;//サイズ
tf.bold = true;//太字
c.defaultTextFormat = c2.defaultTextFormat = tf;//フォーマット適用
c.text = c2.text = str;
c.textColor = 0x000000; //フォントカラー
c2.selectable = c.selectable= false;//文字選択無効
//グローフィルター設定
var glow:GlowFilter = new GlowFilter(color1, 0.7, 13, 13, 5, 5, false, true);
c2.filters = [glow];
base.addChild(c);
base.addChild(c2);
base.x = timestamp*tl;//タイムラインの位置
base.y = Math.random()*HEIGHT;
textList.push(c);
timeLine.addChild(base);//タイムラインに配置
}
//キーボード入力
private function onKey(e:KeyboardEvent):void{
draw2(1);
if(list[charCnt]-player.getCurrentTime()<1.5){
var a:Boolean = checkKey(charList[charCnt],e.keyCode,e.charCode,e.shiftKey);
if(a == true){
textList[charCnt].textColor = 0xffffff;
textList[charCnt].alpha = 0.9;
charCnt++;
charCnt%=list.length;
score++;
}
else{
textList[charCnt].textColor = 0xffffff;
textList[charCnt].alpha = 0.7;
}
}
if(e.keyCode == 27){//タイムラインリセット Esc
list = new Array();
saveData.list = list;
timeLine.graphics.clear();
return;
}
else if(e.keyCode == 32){//タイムラインに追加
var n:Number = player.getCurrentTime();
list.push(n);
list.sort();
txt2.text = "";
for(var i:int=0;i<list.length;i++){
txt2.appendText(list[i].toString()+"\n");
}
charCnt++;
txt2.scrollV = charCnt;
timeLine.graphics.lineStyle(1,color2);
timeLine.graphics.moveTo(n*tl,0);
timeLine.graphics.lineTo(n*tl,50);
var code:int = rndChar();
charList.push(code);
createStr(String.fromCharCode(code),n*tl);//文字追加
saveData.list = list;
}
else if(e.keyCode == 46){//Del
//タイミングラインの前方を1つ消す
}
else if(e.keyCode == 8){//BackSpace
//タイミングラインの後方を1つ消す
}
}
//シーク操作
private function onSeek(e:MouseEvent):void{
var n1:Number = seekBar.mouseX/seekWidth;//シーク位置
if(n1<0)n1=0;
if(1<n1)n1=1;
var n2:Number = Math.round(t1*n1);
player.seekTo(n2,false);
}
//ローダー初期化
private function onLoaderInit(event:Event):void{
const scale:Number =1.4;
const w:Number = WIDTH*scale;
const h:Number = HEIGHT*scale;
seekWidth = w;
var loader:Loader = event.currentTarget.loader;
loader.content.addEventListener("onReady", onPlayerReady);
loader.content.addEventListener("onStateChange",function():void{
videoState = player.getPlayerState()
if(videoState == 0){
player.seekTo(0);//先頭に移動
charCnt=0;
txt2.scrollV = charCnt;
textList[charCnt].textColor = color2;
textList[charCnt].alpha = 1;
}
else if(videoState == 1){//再生中
t1 = player.getDuration();
}
else if(videoState == 5){//頭出し済み
t1 = player.getDuration();
load();
seekBar.x=(stage.stageWidth - w)/2;
seekBar.y=h-50;
var seekGlow:Shape = new Shape();
seekBar.addChild(seekGlow);
seekGlow.graphics.beginFill(0x000000);
seekGlow.graphics.drawRect(0,0,seekWidth,10);
seekGlow.graphics.endFill();
var glow:GlowFilter = new GlowFilter(color1, 0.4, 4, 8, 2, 4, false, true);
seekGlow.filters = [glow]
stage.addChild(seekBar);
textList[charCnt].textColor = color2;
textList[charCnt].alpha = 1;
}
});
loader.scaleX = scale;
loader.scaleY = scale;
loader.x = (stage.stageWidth - w)/2;
//loader.y = (stage.stageHeight - h)/2;
addChild(loader);
stage.addEventListener(MouseEvent.MOUSE_DOWN,onPause);
//txt2.x = txt.x = (stage.stageWidth - w)/2;
txt.y = (stage.stageHeight - h)/2+h-50;
//txt2.y = (stage.stageHeight - h)/2;
}
//一時停止
private function onPause(e:MouseEvent):void{
videoState = player.getPlayerState();
if(videoState == 1)player.pauseVideo();
else if(videoState == 2)player.playVideo();
}
//プレイヤー設定
private function onPlayerReady(event:Event):void{
player = event.currentTarget;
player.setSize(WIDTH, HEIGHT);//サイズ
player.cueVideoById(movie[2]);//動画ID
player.playVideo();//再生
players.push(player);//配列に追加
t1 = player.getDuration();
}
//-------------------------------------------------------------------------------------
//文字変更
private function rndChar(level:int=1):int{
var code:int;
//文字設定
var rnd:int =Math.random()*5;
/*if(4<level){//全文字出題
code = Math.random()*(126-33)+33;
}
else*/ if(3<level && Math.random()<0.2){//記号
rnd = Math.floor(Math.random()*4);
if(rnd == 0) code = Math.floor(Math.random()*15) +33;//記号1
else if(rnd == 1)code = Math.floor(Math.random()*7 ) +58;//記号2
else if(rnd == 2)code = Math.floor(Math.random()*6 ) +91;//記号3
else code = Math.floor(Math.random()*4 )+123;//記号4
}///*
else if(2<level && Math.random()<0.5){//数字
code = Math.random()*10+48;
}
else if(1<level && Math.random()<0.3){//大文字
code = Math.random()*26+65;
}
else{
code = Math.random()*26+97;//小文字
}//*/
return code;
}
/*
* CODE:正解コード keyCode:入力キー charCode:入力文字コード shiftKey:シフトキー
*/
private function checkKey(CODE:int,keyCode:int,charCode:int,shiftKey:Boolean):Boolean{
var code:int = 0;//キーコード
if(CODE == charCode){
return true;
}
//記号1
else if(33<=CODE && CODE<=47){
if(CODE == 33 && shiftKey==true)code=49;// !
else if(CODE == 34 && shiftKey==true)code=50;// "
else if(CODE == 35 && shiftKey==true)code=51;// #
else if(CODE == 36 && shiftKey==true)code=52;// $
else if(CODE == 37 && shiftKey==true)code=53;// %
else if(CODE == 38 && shiftKey==true)code=54;// &
else if(CODE == 39 && shiftKey==true)code=55;// '
else if(CODE == 40 && shiftKey==true)code=56;// (
else if(CODE == 41 && shiftKey==true)code=57;// )
else if(CODE == 42 && shiftKey==true)code=186;// *
else if(CODE == 43 && shiftKey==true)code=187;// +
else if(CODE == 44 && shiftKey==false)code=188;// ,
else if(CODE == 45 && shiftKey==false)code=189;// -
else if(CODE == 46 && shiftKey==false)code=190;// .
else if(CODE == 47 && shiftKey==false)code=191;// /
if(code == keyCode)return true;
return false;
}
//記号2
else if(57<CODE && CODE<65){
if(CODE == 58 && shiftKey==false)code=186;// :
else if(CODE == 59 && shiftKey==false)code=187;// ;
else if(CODE == 60 && shiftKey==true)code=188;// <
else if(CODE == 61 && shiftKey==true)code=189;// =
else if(CODE == 62 && shiftKey==true)code=190;// >
else if(CODE == 63 && shiftKey==true)code=191;// ?
else if(CODE == 64 && shiftKey==false)code=192;// @
if(code == keyCode) return true;
return false;
}
//記号3
else if(91<=CODE && CODE<=96){
if(CODE == 91 && shiftKey==false)code=219;// [
else if(CODE == 92 && shiftKey==false)code=226;// \
else if(CODE == 93 && shiftKey==false)code=221;// ]
else if(CODE == 94 && shiftKey==false)code=222;// ^
else if(CODE == 95 && shiftKey == true)code=226;// _
else if(CODE == 96 && shiftKey == true)code=192;// `
else code = 0;
if(keyCode == code) return true;
else if(CODE==92 && shiftKey==false){
if(keyCode == 226 || keyCode == 220) return true;
}
return false;
}
//記号4
else if(122<CODE && CODE<127){
if(CODE == 123 && shiftKey == true)code=219// {
if(CODE == 124 && shiftKey == true)code=220// |
if(CODE == 125 && shiftKey == true)code=221// }
if(CODE == 126 && shiftKey == true)code=222// ~
if(code == keyCode)return true;
return false;
}
return false;
}
}
}