//////////////////////////////////////////////////////////////////////////////// // tt.hsp // // 打つ >>> 黄昏 // // // 「何やるの?」なコメントはありますが、 // 「何をしたいの?」なコメントがほとんど無いです。 // すいません。 //////////////////////////////////////////////////////////////////////////////// // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // 定数 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - FONT_FACE = "MS ゴシック" // バッファ #enum MAIN_BUFFER_ID = 0 #enum BACKGROUND_BUFFER_ID #enum CARD_BUFFER_ID #enum TASK_CACHE_BUFFER_ID // メインバッファ #const MAIN_BUFFER_WIDTH 640 #const MAIN_BUFFER_HEIGHT 480 // エフェクト #const EFFECT_CAPACITY 32 #enum global _e_x_=0 // x #enum global _e_y_ // Y #enum global _e_count_ // #enum global _e_type_ // #enum global _e_size_ // // タスク数 #const NUM_TASKS 100 // phase #enum ON_TITLE = 0 #enum ON_TYPING #module // timeGetTime #uselib "winmm" #cfunc global timeGetTime "timeGetTime" // hsptv #ifdef __NO_HSPTV if 0 { # deffunc hsptv_send var dummy1, int dummy2 return } #else // hsptv # runtime "hsptv" # regcmd 18 # cmd hsptv_send 0 #endif // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // 太ライン // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #deffunc w_line int x1, int y1, int x2, int y2, int w repeat w, w / 2 line x1, y1 + cnt, x2, y2 + cnt loop return // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // メイン // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #global // いつもの randomize // スコアとる hsptv_send buf, -1 notesel buf // 初期化 gosub*initialize // 背景作る buffer BACKGROUND_BUFFER_ID boxf // 線を描く color 16, 16, 16 // 下の線、まっすぐ w_line 0, 400, MAIN_BUFFER_WIDTH, 400, 4 // 下にカクッとなる方 w_line 400, 400, 440, 440, 5 w_line 440, 440, MAIN_BUFFER_WIDTH, 440, 4 // 上にカクッとなる方 w_line 360, 400, 400, 360, 5 w_line 400, 360, MAIN_BUFFER_WIDTH, 360, 4 // まる circle -40, 310, 160, 510 circle 500, -60, 700, 140 // まるの中抜き color circle -36, 314, 156, 506 circle 504, -54, 696, 136 // グラデーション // 加算コピーで repeat 80 color 176 - cnt, 240 - cnt, limit(300 - cnt, 0, 0xff) // (横に線引く、加算で) gmode 5, 640, 6, 192 grect 320, cnt * 6 + 3 loop // バッファ作る buffer CARD_BUFFER_ID gosub*drawCardBuffer repeat // いつもの redraw : await 16 : redraw 0 // 背景初期化 pos 0, 0 gmode 0, MAIN_BUFFER_WIDTH, MAIN_BUFFER_HEIGHT gcopy BACKGROUND_BUFFER_ID if( phase ) : else { // タイトル pos 240, 64 hsvcolor 108, 80, 255 font FONT_FACE, 32, 17 mes "TYPE >>> TWILIGHT" // タイトル背景(背景明るく) pget 3200 gmode 5, 640, 60, 16 grect 320, 80 // 横のランキング背景 gmode 6, 220, 480, 32 grect 110, 240 // ランキング font FONT_FACE, 13, 17 pos 4, 160 range = "[1 - 15]", "[16 - 30]" pget 3200 mes "%Top" + range( selectedRank / 15 ) repeat 15, selectedRank / 15 * 15 hsvcolor 108, 64, 200 if( selectedRank == cnt ) { hsvcolor 108, 32, 255 } pos 4, 176 + ( cnt \ 15 ) * 17 noteget name, cnt * 3 + 1 mes "No." + ( cnt + 1 ) + " " + name loop cardAnimationCount++ // カード描く // 出現時点滅 if( cardAnimationCount & 0xffffff2 ) { // ノイズ t = ( rnd(cnt\96+1) < 2 ) // 上から一ラインずつカードバッファの内容をコピー repeat 120 gmode 5, 320, 1, 128 // たまに雑音( 10 - rnd(21) ) * t pos limit( cardAnimationCount * cardAnimationCount * 3, 0, 260 ) + ( 10 - rnd(21) ) * t, ( selectedRank \ 15 ) * 17 + 116 + cnt + ( 1 - rnd(3) ) * t gcopy CARD_BUFFER_ID, 0, cnt loop } // 上キー if( key == 38 ) { selectedRank += 29 selectedRank \= 30 gosub*drawCardBuffer } // 下キー if( key == 40 ) { selectedRank++ selectedRank \= 30 gosub*drawCardBuffer } // エンター if( key == 13 ) { gosub*initialize phase++ } dim key } else { // 経過時間取得 passed = timeGetTime() - startTime s = passed / 1000 ms = passed \ 1000 // 問題文 pos 28, 256 + carretPosY gmode 2, MAIN_BUFFER_WIDTH, 158 gcopy TASK_CACHE_BUFFER_ID, 0, ( ( typeIndex / 36 ) - 2 ) * 32 + 1 carretPosY /= 3 // 打った font FONT_FACE, 32 hsvcolor 108, 160, 240 pos 28, 319 mes strmid( task, ( typeIndex / 36 ) * 36, typeIndex \ 36 ) // 枠上下の線 hsvcolor 108, 64, 216 line 0, 320, MAIN_BUFFER_WIDTH, 320 line 0, 350, MAIN_BUFFER_WIDTH, 350 // ライン枠 pget 3200 gmode 5, 640, 32, 32 grect 320, 336 // カウントダウン if( countDownCounter < 3 ) { pos 320, 240 mes 3 - countDownCounter gmode 6, 640, 480, 64 pget 3200 grect 320, 240 redraw wait 100 countDownCounter += key countDownCounter++ startTime = timeGetTime() continue } // キャレット pget 3200 if( lastType ) : else { color 0xff } // gmode 5, 16, 32, 32 grect 28 + ( typeIndex \ 36 ) * 16 + 8 - bbx, 336 // エフェクト repeat EFFECT_CAPACITY dup effect, effects.0.cnt if( effect._e_count_ > 0 ) { dup effect_e_count_, effect._e_count_ dup effect_e_type_, effect._e_type_ rc = 0.1 rr = 1 if( effect_e_type_ == 1 ) { // player : correct color 0x99, 0x99, 0xff } else : if( effect_e_type_ == 0 ) { // player : wrong color 0xff rc = 0.0 rr = 1.5707963267949 } else { // enemy color 0x33, 0x33, 0x66 } // 描く repeat 6 rad = rc * effect_e_count_ + cnt t = effect_e_count_ - 12 t *= t / 2 x = effect._e_x_ + cos(rad) * t y = effect._e_y_ + sin(rad) * t gmode 5, 2, effect_e_count_ * 2, 96 if( abs( y - 336 ) < 96 ) { grect x, y, rad - rr } loop effect_e_count_-- } loop // キー判定 repPosX = 28 + ( typeIndex \ 36 ) * 16 + 8 if( key == peek( task, typeIndex ) - ( 'a' - 'A' ) ) { // あってる // リプレイエフェクト登録 effects.0.effectIndex = repPosX, 336, 18, 1 effectIndex++ effectIndex \= EFFECT_CAPACITY // typeIndex++ score++ bbx = 32 if( typeIndex \ 36 == 0 ) { carretPosY += 32 } // スペース if( peek( task, typeIndex ) == 32 ) { bbx = 32 typeIndex++ if( typeIndex \ 36 == 0 ) { carretPosY += 32 } } lastType++ } else : if( key ) { // まちがてる effects.0.effectIndex = repPosX, 336, 18, 0 effectIndex++ effectIndex \= EFFECT_CAPACITY dim lastType score -= 3 } // リプレイ if( repBaseNorma + ( peek(vs_rep,s) - 0x20 ) * ms / 1000 > repTypeIndex ) { repTypeIndex++ effects.0.effectIndex = 28 + ( repTypeIndex \ 36 ) * 16 + 8, ( ( -( typeIndex / 36 ) + ( repTypeIndex / 36 ) ) * 32 ) + 336, 18, 2 effectIndex++ effectIndex \= EFFECT_CAPACITY } bbx /= 2 // カウント // しかく hsvcolor 108, 80, 255 repeat 60 w = 8 if( s >= cnt ) { w = 4 } if( s + 1 == cnt ) { w = 10 - ms / 200 } gmode 5, w, w, 32 grect 10 * cnt + 20, 26 grect 10 * cnt + 20, 98 loop // 字 pos 308, 52 font FONT_FACE, 24, 17 mes 60 - s // 時間変わった瞬間 if( s != _s ) { rawReplay._s = typeIndex - preTypeIndex preTypeIndex = typeIndex repBaseNorma += peek(vs_rep, _s) - 0x20 } _s = s // 時間切れ if( s >= 60 ) { // リプレイデータ作成 sdim replay, 62 repeat 60 poke replay, cnt, rawReplay.cnt + 0x20 loop // フェードアウト redraw repeat 20 await 33 color 0x99, 0x99, 0x99 gmode 6, 640, 480, 4 grect 320, 240 loop // タイムアップ gmode 6, 640, 32, 48 pget 3200 grect 320, 240 font FONT_FACE, 32, 16 pget 3200 pos 24, 224 mes "Time is up... Retry(Y/N)? [Score:" + strf( "%4d]", Score ) // スコア hsptv_send buf, score, replay // まち repeat wait 10 if( key == 'Y' ) { break } if( key == 'N') { dim phase gosub*drawCardBuffer break } loop gosub*initialize } dim key } loop // 初期化 *initialize // 問題 raw_task="comevdisp,delcom,button,chkbox,combox,input,objsize,cnt,pos,err,ginfo,hspstat,hspver,hwnd,lparam,refstr,stat,strsize,wparam,bcopy,bsave,chdir,chdpm,delete,dirlist,memfile,mkdir,await,break,continue,exgoto,gosub,goto,if,loop,oncmd,onerror,repeat,return,stop,wait,mci,mmstop,lpeek,comres,dimtype,newmod,sdim,wpoke,bgscr,bmpsave,boxf,buffer,chgdisp,circle,cls,color,dialog,gmode,groll,gsel,gzoom,hsvcolor,line,mes,picload,pset,redraw,screen,sendmsg,syscolor,sysfont,title,width,abs,atan,cos,dirinfo,expf,int,length,libptr,limit,logf,objinfo,sin,sysinfo,vartype,varuse,mcall,mouse,randomize,stick,dupptr,xor,getpath,instr,noteinfo,strf,cnvstow" // ばらす dim idx repeat NUM_TASKS getstr tasks.cnt, raw_task, idx, ',' idx += strsize loop // 問題文組み立て // 量としては、世界最速wpm=200ちょっと + α sdim task repeat 250 task += tasks(rnd(100)) + " " loop // 問題文のフォントの描画が遅いので描画済みの奴をキャッシュしとく buffer TASK_CACHE_BUFFER_ID, MAIN_BUFFER_WIDTH, 1600 font FONT_FACE, 32 boxf hsvcolor 108, 64, 216 repeat 40 pos 0, cnt * 32 mes strmid( task, 36 * cnt, 36 ) loop gsel // 初期化 dim rawReplay, 60 dim type_pool dim preTypeIndex onkey gosub*lbl_onkey dim repBaseNorma dim repTypeIndex dim effects, _e_size_, EFFECT_CAPACITY dim countDownCounter dim typeIndex dim preTypeIndex lastType++ dim score dim _s return *lbl_onkey key = wparam return *drawCardBuffer // スコアファイル foo = selectedRank * 3 noteget rep_score, foo noteget name, foo + 1 noteget vs_rep, foo + 2 dim cardAnimationCount if( rep_score == "" ) { sdim vs_rep, 65 memset vs_rep, ' ', 64 } // gsel CARD_BUFFER_ID color boxf // 背景描く repeat 120 c = 0x33 if( cnt & 2 ) { c = 0x11 } color c, c, c line 16 - cnt, cnt, 320, cnt loop // VS pos 20, 50 color font FONT_FACE, 96, 18 mes "VS" // 下線 boxf 16, 30, 240, 32 boxf 60, 106, 300, 108 // ランク color 0x99, 0x99, 0x99 font FONT_FACE, 16, 17 pos 24, 12 mes "No." + ( selectedRank + 1 ) + " " + name // スコア font FONT_FACE, 24, 18 pos 210, 76 mes strf( "%4dpt", 0 + rep_score ) // 右上● color circle 296, 10, 310, 24 gsel return /* * TODO: * * FIXME: * * NOTE: * */