何だってんだよぉ~!!
目次
概要
JavaScript の練習がてら、テトリスを作ってみようと思いました。
そういえば遥か昔に GitHub Pages を立ち上げたきり、何も出来ていないなぁと思っていたんですが、ふと GitHub Pages では JS が動くじゃん!と思って、とりあえず上げてみた次第です。
↑ここからできます。(現状スマホからでは動かせません)
- key config
- w ... 即落下
- a ... ←
- s ... ↓
- d ... →
- k ... 反時計回り回転
- m ... 時計回り回転
キーコンフィグは上のようになっています。
ユーザー設定できないので、後で設定できるようにしたいとは思っています。
↑ ソースコードはこちら。
場所が分かりにくいですが、
- tetris.html (mypage/tetris.html at master · bakkyalo/mypage · GitHub)
- css/tetris.css (mypage/css/tetris.css at master · bakkyalo/mypage · GitHub)
- js/tetris.js (mypage/js/tetris.js at master · bakkyalo/mypage · GitHub)
がそれです。(git の push の時期によってはリンクは切れるかも)
テトリスを管理するデータ構造とアルゴリズムの設計
実際にテトリスを作る際のデータ構造やアルゴリズムの設計に関しては他のサイトや動画にたくさんあるため、気が向いたら書くくらいのノリでいようかなと思います。
t-kihira さんのこの動画をかなり参考にしています。
www.nicovideo.jp
TODO
自動で落ちるようにする (難しくなるからあんまりやりたくはない)即落ち機能の実装どこに落ちるかの表示- 連鎖数の管理と表示
- key config のユーザー設定実装
ゲーム開始画面や終了時の実装- txt 挿入に詳しくなる。fetch API の習得?
- 毎回全盤面を
drawImage()
してるのでクソ重。画像を挿入する方法を調べて検討する - 中身がほとんど一緒な移動可能判定と実際の移動が分離した実装になっており、無駄がある。
- ミノを操作するたび毎回毎回回転処理を書いているのがなんだかなぁだよね。
JavaScript Tips
以下、私が JS を書いている中で躓いた点の備忘録を残しておきます。
。。。しかし、今回の JS のほとんどは、ChatGPT くんに訊きながら書いたなぁ。Google 先生よりも欲しい情報がダイレクトに来るからなぁ。あんたすげぇよ。もうこんな記事の存在意義なんて無いに等しいじゃん。
二次元配列
一気に宣言する方法がない。ので for
で定義する。
let array = []; for(let i = 0; i < 20; i++) { array[i] = []; }
…と思いきや、あるんだよなぁこれが。
let array = new Array(20).fill().map( () => new Array(10).fill(0) );
値渡しと参照渡し?
普通の数字とかは変数に変数を代入して片方の値を書き換えるともう片方は値が書き変わらないけど、配列の変数に配列の変数を代入して片方を書き換えるともう片方も変わってしまう。
let a = 3; let b = a; b = 99; console.log(a); // 3 -- まぁ分かる。 console.log(b); // 99
let a = [1, 2, 3, 4, 5]; let b = a; b[2] = 99; console.log(a); // [1, 2, 99, 4, 5] -- !!? console.log(b); // [1, 2, 99, 4, 5]
そういう所謂参照を共有する行為をシャロ―コピー (shallow copy) と呼ぶ。
対して、実体をそのまま複製する行為はディープコピー (deep copy) と呼ばれる。
なので、配列を値渡ししたい場合は、Object.assign()
を使用する。
let a = [1, 2, 3, 4, 5]; let b = Object.assign([], a); b[2] = 99; console.log(a); // [1, 2, 3, 4, 5] -- ok! console.log(b); // [1, 2, 99, 4, 5]
じゃあ、2 次元配列を値渡ししたい時は?
concat, slice, Object.assign() は 2 次元目以降の値渡しには使えない。カスがよ
それなりに安全で、それなりに市民権のある方法は、JSON.parse()
と JSON.stringify()
を使う方法らしい。
javascript 多次元配列の複製(値渡し)
let a = [ [1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12] ]; let b = JSON.parse(JSON.stringify(a)); b[1][2] = 99; console.log(a); console.log(b);
最近だと structuredClone()
というものができたらしい。
developer.mozilla.org
let a = [ [1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12] ]; let b = structuredClone(a); b[1][2] = 99; console.log(a); console.log(b);
これが一番簡単そうですね。
ただ、めっちゃ新しい機能らしいので (ブラウザによっては 2022年の夏からとかという噂が...) 、古いブラウザからではちゃんと見えないかもしれない。
innerText, TextContent, value らへんの話
わかんにゃい
タイムフレーム
setTimeout, setInterval, requestAnimationFrame
txt の中身を相対パスで開いてそのまま表示する
XMLHttpRequest()
を使う。(ただ、今これ非推奨らしいね)
let request = new XMLHttpRequest(); request.open('GET', "./akari.txt"); // html からの相対パス request.onload = () => { let htmlStr = "<pre>" + request.responseText + "</pre>"; document.getElementById("akari").innerHTML = htmlStr; // html の方で id="akari" と振っておきます } request.send();