実現したいこと
- 音楽の再生時間に応じて、キーボードが押された時点の判定枠を実装したい
- 音声ファイルが読み込まれた時点で再生したいが、ユーザーアクションがないと再生できない問題を解決したい
- 画像読み込み時、requestAnimationFrameを使ってノーツを実際に動かしたい
前提
発生している問題・エラーメッセージ
・今はEnterキーを押したら音楽が再生されるようにしていますが、再びEnterキーを押すと二重三重にも再生されてしまうため その対策をしたい。 ・試しにクラスノーツで、描画と移動をrequestAnimationFrameで動かそうとしたが、描画されはするが微動だにしない。 コンソールログでposyを確認してみたが、posy = 2で変化がない。
該当のソースコード
JavaScript
1let canvas = document.querySelector(".fnfcanvas"); 2let ctx = canvas.getContext("2d"); 3let width = canvas.width = 1080; 4let height = canvas.height = 640; 5//ノーツそのものの制御(座標・加速度・画像の大きさ・各秒数) 6class Notes{ 7 constructor(x,y,VelX,VelY,width,height,time){ 8 this.x = x; 9 this.y = y; 10 this.VelX = VelX; 11 this.VelY = VelY; 12 this.width = width; 13 this.height = height; 14 this.time = time; 15 } 16 notesmoving(){ 17 //ここにVelYの挙動およびVelXなどの挙動を書く。 18 if((this.y + this.height) >= height ){ 19 this.VelY = -(this.VelY); 20 } 21 if((this.y - this.height) <= 0){ 22 this.VelY = -(this.velY); 23 } 24 this.y += this.VelY; 25 26 } 27 notesdrawing(){ 28 //ここに描画処理を書く。 29 ctx.fillRect(0,0,width,height); 30 ctx.translate(width/2,height/2); 31 const note_sprite = new Image(); 32 note_sprite.src = "arrow_down_empty.png"; 33 34 let sprite = 0; 35 let posy = 0; 36 37 note_sprite.addEventListener("load",(event)=>{ 38 ctx.drawImage(note_sprite,(sprite * 158),0,158,157,0,0+posy,74,73.5); 39 }); 40 ctx.fillRect(-(width/2), -(height/2), width, height); 41 if (posy > height/2) { 42 let newStartPos = -((height/2) + 157); 43 posX = Math.ceil(newStartPos); 44 console.log(posy); 45 } else { 46 posy += 2; 47 } 48 } 49} 50const notes_LEGENDALY = []; 51const notes_LASO = []; 52const notes_SLASO = []; 53 54 55function loop(){ 56 const test = new Notes(0,0,1,1,158,157,34.5); 57 test.notesdrawing(); 58 test.notesmoving(); 59} 60 61window.requestAnimationFrame(loop); 62 63 64 65//判定枠 66class notes_lane extends Notes{ 67 constructor(x,y,VelX,VelY,width,height,time){ 68 super(x,y,VelX,VelY,width,height,time); 69 } 70 laneupdate(){ 71 72 } 73 74 lanedisplay(){ 75 76 } 77 lanedraw(){ 78 laneupdate(); 79 lanedisplay(); 80 } 81} 82//ノーツの種類(上から通常・半透明・ダメージノーツ・即死ノーツ) 83class Notes_Elements{ 84 constructor(){ 85 this.normal = 'normal'; 86 this.invisible = 'invisible'; 87 this.reverse = 'damage'; 88 this.death = 'death'; 89 } 90} 91 92 93 94 95 96//グローバル定数を作れるらしいので、やってみる。 97function define(name,value){ 98 Object.defineProperty(window,name,{ 99 get: function(){return value;}, 100 set: function(){throw(name+ "は既に定義済みです!");}, 101 }); 102} 103define("PERFECT",32); 104define("GOOD",70); 105define("BAD",110); 106define("MISS",150); 107 108 109class Pushing{ 110 constructor(up_push,down_push,left_push,right_push){ 111 this.up_push = false; 112 this,down_push = false; 113 this.left_push = false; 114 this.right_push = false; 115 } 116} 117class Pushing_continue extends Pushing{ 118 constructor(up_pushing,down_pushing,left_pushing,right_pushing){ 119 super(up_pushing,down_pushing,left_pushing,right_pushing); 120 } 121 122} 123//押した経過時間の計算 124class passed_time{ 125 constructor(s_time,e_time){ 126 this.s_time = s_time; 127 this.e_time = e_time; 128 } 129 progress(){ 130 if(this.e_time < this.s_time){ 131 return (this.s_time - this.e_time); 132 } else { 133 return (this.e_time - this.s_time); 134 } 135 } 136} 137let totaltime = new passed_time(); 138 139//判定枠 140const move=(key_send)=>{ 141 if(key_send.up_push){ 142 const judgetime = totaltime.progress(); 143 144 145 if((judgetime <= PERFECT) && (judgetime >= 0)){ 146 console.log(`Perfect: ${judgetime}ms`); 147 } 148 149 if(judgetime <= GOOD && judgetime > PERFECT){ 150 console.log(`GOOD: ${judgetime}ms`); 151 } 152 153 if(judgetime <= BAD && judgetime > GOOD){ 154 console.log(`BAD: ${judgetime}ms`); 155 } 156 157 } 158 159 if(key_send.down_push){ 160 const judgetime = totaltime.progress(); 161 162 163 if((judgetime <= PERFECT) && (judgetime >= 0)){ 164 console.log(`Perfect: ${judgetime}ms`); 165 } 166 167 if(judgetime <= GOOD && judgetime > PERFECT){ 168 console.log(`GOOD: ${judgetime}ms`); 169 } 170 171 if(judgetime <= BAD && judgetime > GOOD){ 172 console.log(`BAD: ${judgetime}ms`); 173 } 174 } 175 176 if(key_send.left_push){ 177 const judgetime = totaltime.progress(); 178 179 180 if((judgetime <= PERFECT) && (judgetime >= 0)){ 181 console.log(`Perfect: ${judgetime}ms`); 182 } 183 184 if(judgetime <= GOOD && judgetime > PERFECT){ 185 console.log(`GOOD: ${judgetime}ms`); 186 } 187 188 if(judgetime <= BAD && judgetime > GOOD){ 189 console.log(`BAD: ${judgetime}ms`); 190 } 191 } 192 193 if(key_send.right_push){ 194 const judgetime = totaltime.progress(); 195 196 197 if((judgetime <= PERFECT) && (judgetime >= 0)){ 198 console.log(`Perfect: ${judgetime}ms`); 199 } 200 201 if(judgetime <= GOOD && judgetime > PERFECT){ 202 console.log(`GOOD: ${judgetime}ms`); 203 } 204 205 if(judgetime <= BAD && judgetime > GOOD){ 206 console.log(`BAD: ${judgetime}ms`); 207 } 208 } 209}; 210 211document.addEventListener('keydown',(event)=>{ 212 const check = new Pushing(); 213 switch (event.key){ 214 case 'ArrowUp': 215 totaltime.s_time = performance.now(); 216 check.up_push = true; 217 break; 218 case 'ArrowDown': 219 totaltime.s_time = performance.now(); 220 check.down_push = true; 221 break; 222 case 'ArrowLeft': 223 totaltime.s_time = performance.now(); 224 check.left_push = true; 225 break; 226 case 'ArrowRight': 227 totaltime.s_time = performance.now(); 228 check.right_push = true; 229 break; 230 } 231 console.log(`keydown: ${totaltime.s_time}ms`); 232 move(check); 233}); 234 235 236document.addEventListener('keyup', (event) => { 237 const check = new Pushing(); 238 switch (event.key){ 239 case 'ArrowUp': 240 totaltime.e_time = performance.now(); 241 check.up_push = false; 242 break; 243 case 'ArrowDown': 244 totaltime.e_time = performance.now(); 245 check.down_push = false; 246 break; 247 case 'ArrowLeft': 248 totaltime.e_time = performance.now(); 249 check.left_push = false; 250 break; 251 case 'ArrowRight': 252 totaltime.e_time = performance.now(); 253 check.right_push = false; 254 break; 255 } 256 console.log(`keyup: ${totaltime.s_time}ms`); 257}); 258
試したこと
・performance.now()を使い、keydownとkeyupで、キーが押されたタイミングで変数に保存し、その差を計算した。
・ノーツクラスにnotesdrawingとnotesmovingメソッドを追加して、requestAnimationFrameで描画しながら移動するように試みた。
補足情報(FW/ツールのバージョンなど)
ブラウザ:Chrome 114.0.5735.134
PCのスペック: CPU: i7-12700 2.10 GHz
メモリ: 32GB
Windows11 Home 22H2
回答3件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。