いろいろな弾

シューティングゲームの弾幕って素敵ですよね。
画面いっぱいに広がる弾。
どこに行けば避けられるのか、はたまた無理ゲーなのか。
デモはこちらです。

記事はデモの抜粋なので、コピペだけでは動きません。
弾の移動には、デルタタイムを掛けると滑らかに動いて見えます。
今回はやっていません(ゴメンネ)。

処理の流れ

main.js

// メインループ
const id = setInterval(() => {
    try {
        // 弾管理クラスのメインループ
        shotClass.forEach(e => e.roop(Canvas.getCanvasSize()));
        // キャンバスのメインループ
        Canvas.roop(Bullets);
    } catch(error) {
        console.error(error);
        clearInterval(id);
    }
}, 30 / 1000);

弾を管理するクラスのメインループで弾の生成・移動処理をし、キャンバスのループ内で描画処理をしています。
フロント画面の弾のオプション値を参照し、押下されたボタンの弾を生成するようにしています。

Line.js

createBullet(canvasSize) {
    const directions = this.getDirection(this.directionValue);
    directions.forEach(direction => {
        // 弾の生成
        const Bullet = new BulletClass();
        // キャンバスの中心から生成する
        Bullet.setPos({x: canvasSize / 2, y: canvasSize / 2});
        Bullet.setSize(canvasSize / 20);
        Bullet.setDirection(direction);
        Bullet.setSpeed(this.speedValue);
        this.Bullets.push(Bullet); 
    });
}

弾を直線的に飛ばすクラスです。
フロント画面のオプション値(弾の方向)から得られた値によって方向を変えています。
弾の生成位置、大きさ、進行方向、進行速度を決め、配列に追加しています。

Swirl.js

createBullet(canvasSize) {
    const directions = this.getDirection(this.directionValue);
    directions.forEach((direction, i) => {
        // 弾の生成
        const Bullet = new BulletClass();
        // キャンバスの中心から生成する
        Bullet.setPos({x: canvasSize / 2, y: canvasSize / 2});
        Bullet.setSize(canvasSize / 20);
        // 進行方向を1度づつずらす
        this.rad += 1;
        if(360 <= this.rad) this.rad = 0;
        // 射出方向の数だけずらす
        const r = this.rad + 360 / directions.length * i;
        const radian = r * Math.PI / 180;
        direction.x = Math.cos(radian);
        direction.y = Math.sin(radian);
        Bullet.setDirection(direction);
        Bullet.setSpeed(this.speedValue);
        this.Bullets.push(Bullet);
    });
}

弾を渦巻き状に飛ばすクラスです。
弾の進行方向を少しづつ変えることで渦巻き状にいます。
自機狙い弾で似たようなことをしています。
実際は、弾は直線的に飛んでいる・・・・・・・・・ので、Line.js 内の処理も Swirl.js でできます。
進行方向をずらす際(10行目)、角度に足していくと右回りになり、角度から引いていくと左回りになります。(JavaScript の場合)

Canvas.js

// キャンバスの初期化
this.ctx.fillStyle = '#ffffffff';
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
this.ctx.fillStyle = '#22ee22ff';
this.ctx.strokeStyle = '#000000ff';
ShotBullet.forEach(Bullet => {
    // 弾の描画
    this.ctx.beginPath();
    this.ctx.arc(Bullet.getPos().x, Bullet.getPos().y, Bullet.getSize(), 0, Math.PI * 2, true);
    this.ctx.fill();
    this.ctx.stroke();
});

弾クラスを描画する処理です。
弾クラスから位置や大きさを取得して描画しています。

Bullet.js

class BulletClass {
    constructor() {
        // 大きさ
        this.size = 10;
        // 位置
        this.pos = { x: 0, y: 0 };
        // 速さ
        this.speed = { x:0, y: 0 };
        // 方向
        this.direction = { x: 0, y: 0 };
    }

    getSize() {
        return this.size;
    }

    setSize(s) {
        this.size;
    }

    getPos() {
        return this.pos;
    }
    
    setPos(p) {
        this.pos = p;
    }

    getSpeed() {
        return this.speed;
    }

    setSpeed(s) {
        if(s.hasOwnProperty('x') && s.hasOwnProperty('y')) this.speed = s;
        else this.speed = {x: s, y: s};
    }

    getDirection() {
        return this.direction;
    }

    setDirection(d) {
        this.direction = d;
    }

    move(p = {x: 1, y: 1}) {
        this.pos.x += this.speed.x * this.direction.x * p.x;
        this.pos.y += this.speed.y * this.direction.y * p.y;
    }
}

弾のクラスです。
弾の大きさや位置情報、飛んでいく速さや飛んでいく方向などを持っています。
情報を利用して、Canvas.js で描画します。
弾の移動は、【速さ * 向き】を利用しています。

Direction.js

class DirectionClass {    
    getDirection(d) {
        switch(d) {
            case 0:
                return [{ x:0, y:1 }];
            case 1:
                return [{ x:0, y:1 }, { x:0, y:-1 }];
            case 2:
                return [{ x:1, y:0 }, { x: -1, y:0 }];
            case 3:
                return [{ x:0, y:1 }, { x:0, y:-1 }, { x:1, y:0 }, { x:-1, y:0 }];
            case 4:
                return [
                            { x:0, y:1 }, { x:0, y:-1 }, { x:1, y:0 }, { x:-1, y:0 },
                            { x:1, y:1 }, { x:-1, y:-1 }, { x:1, y:-1 }, { x:-1, y:1 }
                        ];
            default:
                console.log('定義されていない方向です。とりあえず下方向に飛ばします。');
                return [{ x:0, y: 1}];
        }
    }
}

弾の移動する向きを決めるクラスです。
canvas は通常左上を原点なので、右・下に向かうと+方向となります。