1980年にカシオ計算機が発売した初代ゲーム電卓のデジタルインベーダーをJavaScriptで再現したものです。
2018年には復刻版も発売されて、ちょっと話題になっていました。
今回作成したものはこちらからプレイできます
スクリプト自体は数年前(2016年頃)に作成したものですが、リプレイ対応や難易度設定の追加など今回少し手直ししました。
作成した当時は表示する敵数字を決定するのに普通にMath.random()
を使用していましたが、リプレイ機能を追加するにあたって同じ乱数列を出す必要があったので、今回Xorshift
を使ってシード値を指定することで同じ乱数列を出せるようにしています。
class XorShift {
constructor(seed = Math.random() * 0x7fffffff) {
this.x = 123456789;
this.y = 362436069;
this.z = 521288629;
this.w = seed;
}
next() {
const t = this.x ^ (this.x << 11);
this.x = this.y;
this.y = this.z;
this.z = this.w;
this.w = (this.w ^ (this.w >>> 19)) ^ (t ^ (t >>> 8));
return this.w;
}
random() {
return (this.next() + 0x80000000) / 0x100000000;
}
rand(min, max) {
if(min > max) [min, max] = [max, min];
return min + Math.floor(this.random() * (1 + max - min));
}
}
// example
console.log('SEED無指定');
const x0 = new XorShift(); // SEED無指定(Math.random()でSEED決定)
for(let i = 0; i < 10; ++i) console.log(x0.next());
console.log('SEED指定');
const x1 = new XorShift(12345678); // SEED指定
for(let i = 0; i < 10; ++i) console.log(x1.next());
// 速度と出現する値のばらつき具合確認
const arr = {};
console.time();
const x = new XorShift();
for(let i = 0; i < 1e7; ++i) {
const r = x.rand(1, 10);
if(arr[r] === undefined) arr[r] = 1;
else ++arr[r];
}
console.log(arr);
console.timeEnd();
Xorshiftのおかげでリプレイについては概ね正確に再現できていますが、まだ稀になにかのタイミングでずれることがあるようで(ずれる原因はXorshift
とは無関係の部分です)、最後まで再現できていたらラッキー、程度に捉えてもらえると助かります。
最近のiOS、iPadOSでは、touchstart
/touchend
イベントの連打が最低でも0.5秒程度開けないと効かない(それより早い連打は無視される)不具合があったようでプレイに支障をきたしていたのですが、ともにバージョン13.6で元に戻ったようです。