実現したいこと
- 音楽の再生時間に応じて、キーボードが押された時点の判定枠を実装したい
- 音声ファイルが読み込まれた時点で再生したいが、ユーザーアクションがないと再生できない問題を解決したい
- 画像読み込み時の設計案が思い浮かばない
前提
JavaScriptでFNFの音ゲーを実装したいです。
画像描画とメモリ管理は後回しで、今現在時点では、「音声ファイルの読み込み・判定秒数の計算方法・画像読み込みの方法と描画」がわかればよしとします。
発生している問題・エラーメッセージ
・keydown時のミリ秒が5桁のミリ秒(53467.93791など)になっているのに、クラスでPERFECT~BADの範囲から外れているにも関わらずなぜかPERFECTのみしか出力しないです。 ・今はEnterキーを押したら音楽が再生されるようにしていますが、再びEnterキーを押すと二重三重にも再生されてしまうため その対策をしたいです。 ・画像読み込みはcanvasで描画しようと思っています。背景→判定枠は初期段階で読み込むというのはわかります。 問題なのは、いざ曲が開始した際に上から降ってくるノーツの秒数と個数をどうやって管理しつつ描画し続けるのかがよくわかっておりません。
該当のソースコード
JavaScript(fnf.js)
1class Notes{ 2 constructor(x,y,VelX,VelY,width,height,time){ 3 this.x = x; 4 this.y = y; 5 this.VelX = VelX; 6 this.VelY = VelY; 7 this.width = width; 8 this.height = height; 9 this.time = time; 10 } 11 notesdisplay(){ 12 13 } 14} 15class notes_key extends Notes{ 16 constructor(x,y,VelX,VelY,width,height,time){ 17 super(x,y,VelX,VelY,width,height,time); 18 } 19 display(){ 20 21 } 22} 23/*ノーツと判定枠は座標・加速度・画像サイズ・到達時間の値を受け取る。*/ 24 25//下記はFNFの 26class Notes_Elements{ 27 constructor(){ 28 this.normal = 'normal'; 29 this.invisible = 'invisible'; 30 this.reverse = 'reverse'; 31 this.death = 'death'; 32 } 33} 34 35class Notes_Display extends Notes_Elements{ 36 constructor(normal,invisible,reverse,death){ 37 super(normal,invisible,reverse,death); 38 } 39} 40 41class Notes_Judge{ 42 constructor(){ 43 this.Perfect=32; 44 this.GOOD=70; 45 this.BAD=110; 46 this.MISS=150; 47 } 48 //単位はミリ秒に統一 49} 50class Pushing{ 51 constructor(up_push,down_push,left_push,right_push){ 52 this.up_push = false; 53 this,down_push = false; 54 this.left_push = false; 55 this.right_push = false; 56 } 57} 58class Pushing_continue extends Pushing{ 59 constructor(up_pushing,down_pushing,left_pushing,right_pushing){ 60 super(up_pushing,down_pushing,left_pushing,right_pushing); 61 } 62} 63 64class passed_time{ 65 constructor(s_time,e_time){ 66 this.s_time = s_time; 67 this.e_time = e_time; 68 } 69 progress(){ 70 if(this.e_time < this.s_time){ 71 return (this.s_time - this.e_time); 72 } else { 73 return (this.e_time - this.s_time); 74 } 75 76 } 77} 78let totaltime = new passed_time(); 79 80function move(key_send){ 81 if(key_send.up_push){ 82 const judgetime = totaltime.progress(); //経過時間を計算 83 const judgeup = new Notes_Judge(); 84 85 switch(true){ 86 case judgetime <= judgeup.Perfect: 87 case judgetime >=0: 88 console.log("Perfect: " + judgetime + "ms"); 89 break; 90 91 case judgetime <= judgeup.GOOD: 92 case judgetime > judgeup.Perfect: 93 console.log("GOOD: "+ judgetime + "ms"); 94 break; 95 96 case judgetime <= judgeup.BAD: 97 case judgetime > judgeup.GOOD: 98 console.log("BAD: " + judgetime + "ms"); 99 break; 100 101 102 } 103 } 104 105 if(key_send.down_push){ 106 const judgetime = totaltime.progress(); 107 const judgeup = new Notes_Judge(); 108 109 switch(true){ 110 case judgetime <= judgeup.Perfect: 111 case judgetime >= judgeup.GOOD: 112 console.log("Perfect: " + judgetime + "ms"); 113 break; 114 115 case judgetime <= judgeup.BAD: 116 case judgetime >= judgeup.GOOD: 117 console.log("GOOD: "+ judgetime + "ms"); 118 break; 119 120 case judgetime <= judgeup.MISS: 121 case judgetime >= judgeup.BAD: 122 console.log("BAD: " + judgetime + "ms"); 123 break; 124 125 126 } 127 } 128 129 if(key_send.left_push){ 130 const judgetime = Math.abs(totaltime.progress()); 131 const judgeup = new Notes_Judge(); 132 } 133 134 if(key_send.right_push){ 135 const judgetime = Math.abs(totaltime.progress()); 136 const judgeup = new Notes_Judge(); 137 } 138} 139 140document.addEventListener('keydown',(event)=>{ 141 const check = new Pushing(); 142 switch (event.key){ 143 case 'ArrowUp': 144 totaltime.s_time = performance.now(); 145 check.up_push = true; 146 break; 147 case 'ArrowDown': 148 totaltime.s_time = performance.now(); 149 check.down_push = true; 150 break; 151 case 'ArrowLeft': 152 totaltime.s_time = performance.now(); 153 check.left_push = true; 154 break; 155 case 'ArrowRight': 156 totaltime.s_time = performance.now(); 157 check.right_push = true; 158 break; 159 } 160 161 move(check); 162}); 163 164 165document.addEventListener('keyup', (event) => { 166 const check = new Pushing(); 167 switch (event.key){ 168 case 'ArrowUp': 169 totaltime.e_time = performance.now(); 170 check.up_push = false; 171 break; 172 case 'ArrowDown': 173 totaltime.e_time = performance.now(); 174 check.down_push = false; 175 break; 176 case 'ArrowLeft': 177 totaltime.e_time = performance.now(); 178 check.left_push = false; 179 break; 180 case 'ArrowRight': 181 totaltime.e_time = performance.now(); 182 check.right_push = false; 183 break; 184 } 185});
JavaScript(include_music.js)
1const start = document.addEventListener('keypress',(event)=>{ 2 if(event.key === 'Enter'){ 3 const music = new Audio('test.mp3'); 4 music.load(); 5 music.pause(); 6 //const time = music.src; 7 //console.log(time); 8 music.volume = 0.05; 9 music.autoplay = true; 10 } 11}); 12
HTML(index.html)
1<html> 2<head> 3<title>FNFもどき</title> 4<script src="fnf.js" defer></script> 5<script src="include_music.js" defer></script> 6</head> 7<body> 8</body> 9 10</html>
試したこと
・performance.now()を使い、keydownとkeyupで、キーが押されたタイミングで変数に保存し、その差を計算した。
・Event.timeStampでも同様に試したが、結果は同じだった。
・警視庁のポリズム内のソースコードを参考にしてみたが、クラスの定義についてはおおよそ分かった。しかし、肝心の画像描画の処理とノーツの管理などがどのようになっているのかわからなかった。
https://www.keishicho.metro.tokyo.lg.jp/play/rhythm/
補足情報(FW/ツールのバージョンなど)
ブラウザ:Chrome Ver.114.0.5735.134
PCのスペック: CPU: i7-12700 2.10 GHz
メモリ: 32GB
Windows11 Home 22H2
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2023/06/25 10:22
2023/06/25 11:53
2023/06/26 12:20