{"id":144,"date":"2026-06-15T15:50:27","date_gmt":"2026-06-15T06:50:27","guid":{"rendered":"https:\/\/tate.stars.ne.jp\/wpa\/?p=144"},"modified":"2026-06-15T15:54:08","modified_gmt":"2026-06-15T06:54:08","slug":"rexplugin2","status":"publish","type":"post","link":"https:\/\/tate.stars.ne.jp\/wpa\/rexplugin2.html","title":{"rendered":"Rexplugin2"},"content":{"rendered":"<p>Bullet<\/p>\n<pre><code class=\"swift\">\nimport * as Phaser from 'phaser';\nexport class Bullet extends Phaser.Physics.Arcade.Sprite\n{\n    private player: any;\n    constructor(scene: Phaser.Scene, x: number, y: number) {\n        \/\/ \u30b3\u30f3\u30b9\u30c8\u30e9\u30af\u30bf\u3067\u89aa\u30af\u30e9\u30b9 (Phaser.Physics.Arcade.Sprite) \u3092\u547c\u3073\u51fa\u3059\n        super(scene, x, y, \"playbullet\");\n        scene.physics.add.existing(this);\n        this.setActive(false);\n        this.setVisible(false);\n        scene.time.delayedCall(3000, this.destroyBullet, [], this);\n    }\n    private destroyBullet(): void {\n        this.destroy();\n        this.setVisible(false);\/\/bullet\u3092\u30b7\u30fc\u30f3\u304b\u3089\u524a\u9664\u3057\u3001\u30e1\u30e2\u30ea\u3092\u89e3\u653e\u3059\u308b\n    }\n\n    \/\/ \u30b7\u30fc\u30f3\u306b\u8ffd\u52a0\u3055\u308c\u305f\u3068\u304d\u306b\u547c\u3073\u51fa\u3055\u308c\u308b\u521d\u671f\u5316\u30e1\u30bd\u30c3\u30c9\n    fire(x: number, y: number, speed: number) {\n        const body = this.body as Phaser.Physics.Arcade.Body;\n        body.reset(this.x, this.y); \/\/ \u5f3e\u4e38\u306e\u4f4d\u7f6e\u3092\u30ea\u30bb\u30c3\u30c8\n        this.setPosition(x, y);\n        this.setActive(true);  \/\/ \u30a2\u30af\u30c6\u30a3\u30d6\u306b\u3059\u308b\n        this.setVisible(true); \/\/ \u8868\u793a\u3059\u308b\n        this.setVelocityX(-speed); \/\/ \u4e0a\u65b9\u5411\u306b\u79fb\u52d5\uff08\u901f\u5ea6\u306f\u9069\u5b9c\u8abf\u6574\uff09\n    }\n\n\n    \/\/ \u66f4\u65b0\u51e6\u7406 (\u30b7\u30fc\u30f3\u306eupdate\u304b\u3089\u547c\u3070\u308c\u308b)\n    update(time: number, delta: number) {\n        if ( this.x < -50 || this.x > 950*3 + 50) {\n            this.setActive(false);\n            this.setVisible(false);\n        }\n    }\n}\n<\/code><\/pre>\n<p>\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/<br \/>\nEnemy<\/p>\n<pre><code class=\"swift\">\n\nimport * as Phaser from 'phaser';\nexport class Enemy extends Phaser.Physics.Arcade.Sprite {\n    constructor(scene: Phaser.Scene, x: number, y: number) {\n        super(scene, x, y, 'enemy'); \/\/ 'enemy'\u306f\u4e8b\u524d\u306b\u30ed\u30fc\u30c9\u3055\u308c\u305f\u753b\u50cf\u306e\u30ad\u30fc\n\n        scene.add.existing(this);\n        scene.physics.add.existing(this);\n        this.setCollideWorldBounds(true).setDepth(2);\n        this.setBounce(0.1).setScale(1.8);\n        this.createAnimations(scene);\n    }\n\n    createAnimations(scene: Phaser.Scene) {\n        scene.anims.create({\n            key: \"left2\", frameRate: 2, repeat: -1,\n            frames: this.anims.generateFrameNumbers('enemy', {start: 4, end: 5}),\n        });\n        scene.anims.create({\n            key: \"right2\", frameRate: 2, repeat: -1,\n            frames: this.anims.generateFrameNumbers('enemy', {start: 6, end: 7}),\n        });\n\n    }\n\n\n    update() {\n\n    }\n\n}\n\n<\/code><\/pre>\n<p>\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/<br \/>\nMyPlayer<\/p>\n<pre><code class=\"swift\">\nimport * as Phaser from 'phaser';\nexport class MyPlayer extends Phaser.Physics.Arcade.Sprite {\n    private speed: number = 200;\n    private readonly animKeyRun: string = 'run';\n    private readonly animKeyLeft: string = 'left';\n    private readonly animKeyIdle: string = 'idle';\n    private readonly animKeyRight: string = 'right';\n    private joystick: any;\n\n    constructor(scene: Phaser.Scene, x: number, y: number, texture: string) {\n        super(scene, x, y, texture);\n\n        \/\/ \u30b7\u30fc\u30f3\u306b\u8ffd\u52a0\n        scene.add.existing(this);\n        scene.physics.add.existing(this);\n        this.setBounce(0.2).setScale(0.5).setDepth(2);\n\n        \/\/ \u885d\u7a81\u8a2d\u5b9a\uff08\u5fc5\u8981\u306b\u5fdc\u3058\u3066\uff09\n        this.setCollideWorldBounds(true);\n        this.createAnimations(scene);\n        this.setFlipX(false);\n    }\n\n    createAnimations(scene: Phaser.Scene) {\n        this.anims.create({\n            key: this.animKeyRun,\n            frames: this.anims.generateFrameNumbers('player', {\n                start: 5,\n                end: 8\n            }),\n            frameRate: 10,\n            repeat: -1\n        });\n\n        this.anims.create({\n            key: this.animKeyRight,\n            frames: [{key: 'player', frame: 5}],\n            frameRate: 20\n        });\n\n        this.anims.create({\n            key: this.animKeyLeft,\n            frames: [{key: 'player', frame: 2}],\n            frameRate: 20\n        });\n\n    }\n\n    \/\/ \u30b8\u30e7\u30a4\u30b9\u30c6\u30a3\u30c3\u30af\u306e\u72b6\u614b\u3092\u53d7\u3051\u53d6\u3063\u3066\u66f4\u65b0\n    update(joystick: any): void {\n\n        const cursorKeys = joystick.createCursorKeys();\n\n        \/\/ \u901f\u5ea6\u306e\u521d\u671f\u5316\n        this.setVelocityX(0);\n\n        \/\/ \u5de6\u53f3\u79fb\u52d5\u306e\u5224\u5b9a\n        if (cursorKeys.left.isDown) {\n            this.setVelocityX(-this.speed);\n            this.setFlipX(true); \/\/ \u5de6\u3092\u5411\u304f\n            this.anims.play(this.animKeyRun, true);\/\/ \u30a2\u30cb\u30e1\u30fc\u30b7\u30e7\u30f3\u304c\u3042\u308b\u5834\u5408\n        } else if (cursorKeys.right.isDown) {\n            this.setVelocityX(this.speed);\n            this.setFlipX(false); \/\/ \u53f3\u3092\u5411\u304f\n            this.anims.play(this.animKeyRun, true);\n        } else {\n            this.anims.play(this.animKeyRight, true); \/\/ \u505c\u6b62\u6642\n        }\n        if ( cursorKeys.up.isDown) {\n            this.setVelocityY(-200);\n            if (this.y < 70) {\n                this.setVelocityY(0);\n            }\n\n        }\n\n    }\n\n\n}\n\n<\/code><\/pre>\n<p>\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/<br \/>\nScoreText<\/p>\n<pre><code class=\"swift\">\nimport * as Phaser from 'phaser';\nexport class ScoreText extends Phaser.GameObjects.Text {\n    private score: number = 0;\n\n    constructor(scene: Phaser.Scene, x: number, y: number,\n                style: Phaser.Types.GameObjects.Text.TextStyle) {\n        \/\/ \u89aa\u30af\u30e9\u30b9 (Phaser.GameObjects.Text) \u306e\u30b3\u30f3\u30b9\u30c8\u30e9\u30af\u30bf\u3092\u547c\u3073\u51fa\u3059\n        super(scene, x, y, 'Score:0', style);\n\n        \/\/ \u3053\u306e\u30c6\u30ad\u30b9\u30c8\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u3092\u30b7\u30fc\u30f3\u306e\u8868\u793a\u30ea\u30b9\u30c8\u306b\u8ffd\u52a0\u3059\u308b\n        scene.add.existing(this);\n    }\n\n    \/\/ \u30b9\u30b3\u30a2\u3092\u52a0\u7b97\u3057\u3066\u8868\u793a\u3092\u66f4\u65b0\u3059\u308b\u30e1\u30bd\u30c3\u30c9\n    public addScore(points: number): void {\n        this.score += points;\n        this.setText('Score:'+ this.score);\n        \/\/  this.setText(`Score:${this.score}`);\n    }\n    \/\/ \u30b9\u30b3\u30a2\u3092\u30ea\u30bb\u30c3\u30c8\u3059\u308b\u30e1\u30bd\u30c3\u30c9\n    public resetScore(): void {\n        this.score = 0;\n        this.updateScoreText();\n    }\n\n    \/\/ \u73fe\u5728\u306e\u30b9\u30b3\u30a2\u3092\u53d6\u5f97\u3059\u308b\u30e1\u30bd\u30c3\u30c9\n    public getScore(): number {\n        return this.score;\n    }\n    private updateScoreText(): void {\n        this.setText(`Score: ${this.score}`);\n    }\n}\n\n<\/code><\/pre>\n<p>\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/<\/p>\n<p>GameScene<\/p>\n<pre><code class=\"swift\">\nimport * as Phaser from 'phaser';\nimport {MyPlayer} from \".\/MyPlayer\";\nimport {Bullet} from \".\/Bullet\";\nimport {ScoreText} from \".\/ScoreText\";\nimport {Enemy} from \".\/Enemy\";\n\nexport class GameScene extends Phaser.Scene {\n\n    private joystick: any;\n    private player!: MyPlayer;\n    private rexVirtualJoystick: any;\n    private yuka?: Phaser.GameObjects.Rectangle;\n    private bullets!: Phaser.Physics.Arcade.Group;\n    private bullet: any;\n    private coins!: any;\n    private scoreText!: ScoreText;\n    private coin?: Phaser.GameObjects.GameObject;\n    private platforms!: Phaser.Physics.Arcade.StaticGroup;\n    private hitSound!: Phaser.Sound.BaseSound;\n    private enemy!: Enemy;\n    private enemies!: Phaser.GameObjects.Group;\n    private isEnemyActive: boolean = false;\n    private playerbullets!: Phaser.Physics.Arcade.Group;\n    private shootEvent!: Phaser.Time.TimerEvent;\n    private hearts: Phaser.GameObjects.Image[] = [];\n    private initialHealth: number = 10;\n    private currentHealth = 10;\n    private maxHealth = 10;\n\n    constructor() {\n        super({key: 'GameScene'});\n    }\n\n    preload() {\n        this.load.image('myblock', 'assets\/block.png');\n        this.load.spritesheet('player', 'assets\/mplayer.png', {\n            frameWidth: 127, frameHeight: 168\n        });\n        this.load.image(\"ground\", \"assets\/platform.png\");\n        this.load.image(\"bullet\", \"assets\/laser.png\");\n        this.load.image('shoot', 'assets\/shoot.png');\n        this.load.spritesheet('explosion', 'assets\/explosion.png', {\n            frameWidth: 64,\n            frameHeight: 64,\n            endFrame: 23\n        });\n        this.load.spritesheet('enemy', 'assets\/enemy.png', {frameWidth: 32, frameHeight: 32});\n        this.load.image('playbullet', 'assets\/bullet.png');\n        this.load.spritesheet('coin', 'assets\/coin.png',\n            {frameWidth: 32, frameHeight: 32});\n        this.load.audio('coinSound', 'assets\/coin.mp3');\n        this.load.image('heart', 'assets\/heart.png');\n    }\n\n    create(): void {\n        this.add.image(700, 150, 'myblock').setScale(1.5).setOrigin(0);\n        this.add.image(700 * 2, 200, 'myblock').setScale(1.5).setOrigin(0);\n        this.add.image(700 * 3, 250, 'myblock').setScale(1.5).setOrigin(0);\n\n\n        \/\/ \u30cf\u30fc\u30c8\u753b\u50cf\u3092\u914d\u7f6e\n        for (let i = 0; i < this.maxHealth; i++) {\n            const heart = this.add.image(30 + i * 29, 19, 'heart').setScale(0.1).setScrollFactor(0);\n            this.hearts.push(heart);\n        }\n\n        this.cameras.main.setBounds(0, 0, 950 * 3, 550);\n        this.physics.world.setBounds(0, 0, 950 * 3, 550);\n\n        this.platforms = this.physics.add.staticGroup();\n        for (let i = 0; i < 3; i++) {\n            const x = Phaser.Math.Between(200, 30);\n            const y = Phaser.Math.Between(20, -20);\n            \/\/   const platform = this.physics.add.sprite(x, y, 'ground');\n            const platform = this.physics.add.sprite(0, 0, 'ground');\n            platform.setX(400 + (i * 750) + x);\n            platform.setY(150 + (i * 23) + y),\n                platform.setImmovable(true);\n            this.platforms.add(platform);\n        }\n\n        this.tweens.add({\n            targets: this.platforms.getChildren(),  \/\/ \u30b0\u30eb\u30fc\u30d7\u5185\u306e\u5168\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u3092\u5bfe\u8c61\u306b\u3059\u308b\n            x: '+=100',           \/\/ \u73fe\u5728\u306ey\u5ea7\u6a19\u304b\u3089100\u30d4\u30af\u30bb\u30eb\u4e0b\u306b\u79fb\u52d5\n            duration: 1000,       \/\/ 1\u79d2\u304b\u3051\u3066\u79fb\u52d5\n            ease: 'Sine.easeInOut',\n            yoyo: true,           \/\/ \u5143\u306b\u623b\u308b\n            repeat: -1,           \/\/ \u7121\u9650\u30eb\u30fc\u30d7\n            delay: 0,             \/\/ \u5fc5\u8981\u3067\u3042\u308c\u3070\u9045\u5ef6\u3092\u8a2d\u5b9a\n            stagger: 500 \/\/ \u9806\u756a\u306b\u52d5\u304b\u3057\u305f\u3044\u5834\u5408\u306f100ms\u306e\u9045\u5ef6\u3092\u8a2d\u5b9a\n        });\n\n        this.yuka = this.add.rectangle(0, 350, 950 * 3, 200, 0x00FFFF).setOrigin(0);\n        this.physics.add.existing(this.yuka, true);\n        \/\/  this.physics.add.staticGroup(this.yuka);\n        this.player = new MyPlayer(this, 300, 280, 'player');\n        this.cameras.main.startFollow(this.player);\n        this.player.setCollideWorldBounds(true);\n\n        this.cameras.main.startFollow(this.player);\n        \/\/ \u30aa\u30d7\u30b7\u30e7\u30f3: \u8ffd\u5f93\u6642\u306e\u30aa\u30d5\u30bb\u30c3\u30c8\u3084\u6163\u6027\u3092\u8a2d\u5b9a\u3059\u308b\u3053\u3068\u3082\u53ef\u80fd\n        this.cameras.main.setFollowOffset(-10, 5);\n        \/\/  this.cameras.main.setLerp(0.005, 0.005);\n        this.physics.add.existing(this.player);\n\n\n        this.physics.add.collider(this.player, this.yuka);\n\n        \/\/ \u30b3\u30a4\u30f3\u3092\u7ba1\u7406\u3059\u308b\u7269\u7406\u30b0\u30eb\u30fc\u30d7\u306e\u4f5c\u6210\n        this.coins = this.physics.add.group();\n        this.physics.add.existing(this.coins);\n\n        this.physics.add.collider(this.coins, this.yuka);\n        this.physics.add.collider(this.player, this.platforms);\n\n        \/\/ \u30b9\u30b3\u30a2\u30c6\u30ad\u30b9\u30c8\u306e\u30b9\u30bf\u30a4\u30eb\u8a2d\u5b9a\n        const style: Phaser.Types.GameObjects.Text.TextStyle = {\n            fontSize: '32px',\n            color: '#fff',\n            \/\/  fontStyle: 'bold',\n            fontFamily: 'Courier'\n        };\n        this.scoreText = new ScoreText(this, 16, 36, style);\n        this.scoreText.setScrollFactor(0);\n\n\n        this.hitSound = this.sound.add('coinSound', {volume: 0.7, delay: 0});\n\n        this.anims.create({\n            key: 'explode', \/\/ \u30a2\u30cb\u30e1\u30fc\u30b7\u30e7\u30f3\u306e\u8b58\u5225\u30ad\u30fc\n            frames: this.anims.generateFrameNumbers('explosion', {\n                start: 0, \/\/ \u958b\u59cb\u30d5\u30ec\u30fc\u30e0\u756a\u53f7\n                end: 23   \/\/ \u7d42\u4e86\u30d5\u30ec\u30fc\u30e0\u756a\u53f7\n            }),\n            frameRate: 20, \/\/ 1\u79d2\u3042\u305f\u308a\u306e\u30d5\u30ec\u30fc\u30e0\u6570\n            repeat: 0,     \/\/ \u7e70\u308a\u8fd4\u3057\u56de\u6570 (0\u30671\u56de\u306e\u307f\u518d\u751f\u3001-1\u3067\u7121\u9650\u30eb\u30fc\u30d7)\n            hideOnComplete: true \/\/ \u30a2\u30cb\u30e1\u30fc\u30b7\u30e7\u30f3\u5b8c\u4e86\u6642\u306b\u30b9\u30d7\u30e9\u30a4\u30c8\u3092\u975e\u8868\u793a\u306b\u3059\u308b\n        });\n\n        this.playerbullets = this.physics.add.group({\n            classType: Bullet,\n            allowGravity: false,\/\/ \u4f7f\u7528\u3059\u308b\u30ab\u30b9\u30bf\u30e0\u30af\u30e9\u30b9\u3092\u6307\u5b9a\n            maxSize: 50,       \/\/ \u30d7\u30fc\u30eb\u3067\u304d\u308b\u6700\u5927\u6570\n            runChildUpdate: true \/\/ update\u30e1\u30bd\u30c3\u30c9\u3092\u81ea\u52d5\u7684\u306b\u5b9f\u884c\u3055\u305b\u308b\n        }) as Phaser.Physics.Arcade.Group;\n\n        this.shootEvent = this.time.addEvent({\n            delay: 1500,\n            callback: this.enemyShoot,\n            callbackScope: this,\n            loop: true\n        });\n        this.bullets = this.physics.add.group({\n            defaultKey: 'bullet',\n            maxSize: 70,\n            runChildUpdate: true\n        });\n\n\n        this.anims.create({\n            key: 'rotate',\n            frames: this.anims.generateFrameNumbers('coin', {start: 0, end: 7}),\n            frameRate: 10,\n            repeat: -1\n        });\n\n        for (let i = 1; i < 15; i++) {\n            const randomX = Phaser.Math.Between(0, 945 * 3);\n            this.coin = this.physics.add.sprite(randomX, 0, 'coin').setOrigin(1).setScale(2.2).anims.play('rotate');\n            \/\/   this.coin.setOffset(0, -10);\n            (this.coin.body as Phaser.Physics.Arcade.Body).setOffset(0, -5);\n            this.physics.add.collider(this.coin, this.yuka);\n            this.physics.add.existing(this.coin);\n            this.physics.add.collider(this.coin, this.platforms);\n\n            this.physics.add.collider(this.playerbullets, this.coin, (bullet, coin) => {\n                (coin as Phaser.Physics.Arcade.Sprite).disableBody(true, true);\n                const pos = coin as Phaser.Physics.Arcade.Sprite;\n                if (this.player.flipX) {\n                    this.createExplosion(pos.x - 50, pos.y);\n                } else {\n                    this.createExplosion(pos.x + 50, pos.y);\n                }\n                this.hitSound.play();\n\n                this.scoreText.addScore(10);\n                \/\/  this.score += 10;\n                \/\/    this.scoreText.setText('Score: ' + this.score);\n                bullet.destroy();\n            });\n\n        }\n\n\n        this.joystick = (this.plugins.get('rexVirtualJoystick') as any).add(this, {\n            x: 150,\n            y: 470,\n            radius: 100,\n            base: this.add.circle(0, 0, 100, 0x0000FF).setAlpha(0.1),\n            thumb: this.add.circle(0, 0, 50, 0xFFA500).setAlpha(0.5),\n        })\n            .on('update', this.update, this);\n\n        this.enemies = this.physics.add.group({runChildUpdate: true});\n\n        const x = Phaser.Math.Between(800, 900);\n        \/\/    const y = Phaser.Math.Between(310, 316);\n        this.enemy = new Enemy(this, x, 320);\n        this.enemies.add(this.enemy);\n\n        this.enemy.setCollideWorldBounds(true);\n        this.physics.add.collider(this.enemy, this.yuka);\n        this.enemy.anims.play('left2', true);\n        this.enemy.setVelocityX(-150); \/\/ \u6700\u521d\u306f\u53f3\u3078\n        this.isEnemyActive = false;\n        this.enemy.setVisible(false);\n        (this.enemy.body as Phaser.Physics.Arcade.Body).setEnable(false);\n\n\n        this.input.addPointer(2);\n        const jumpButton = this.add.image(850, 480, 'shoot').setScale(0.4).setAlpha(0.5);\n        jumpButton.setInteractive().setScrollFactor(0);\n        jumpButton.on(\"pointerdown\", () => {\n            this.shoot();\n\n        });\n        jumpButton.on(\"pointerup\", () => {\n            \/\/   this.shoot();\n        });\n        this.physics.add.collider(this.playerbullets, [this.enemies, this.bullets], (bullet, enemy) => {\n            (enemy as Phaser.Physics.Arcade.Sprite).disableBody(true, true);\n            const star = bullet as Phaser.Physics.Arcade.Sprite;\n            star.disableBody(true, true);\n            if (this.enemies.countActive(true) === 0) {\n                \/\/  this.spawnNewStars(3);\n            }\n            \/\/ 1\u79d2\u5f8c\u306b\u65b0\u3057\u3044\u4f4d\u7f6e\u306b\u518d\u51fa\u73fe\n            this.time.delayedCall(2000, () => {\n                \/\/   this.spawnEnemy(16);\n                this.spawnEnemy(6);\n            });\n        });\n\n\n        this.physics.add.collider(this.player, this.bullets, (myplayer, myenemy) => {\n            \/\/  this.hp =100;\n            const tar = myplayer as Phaser.Physics.Arcade.Sprite;\n            const myeny = myenemy as Phaser.Physics.Arcade.Sprite;\n            myeny.disableBody(true, true);\n\n            tar.setTint(0xff0000);\n            this.time.addEvent({\n                delay: 200,\n                callback: () => {\n                    tar.setTint(0xffffff);\n                }\n            });\n            this.damage();\n        });\n    }\n\n    damage() {\n        if (this.currentHealth > 0) {\n            this.currentHealth -= 1;\n\n            \/\/ \u914d\u5217\u306e\u6700\u5f8c\u306e\u30cf\u30fc\u30c8\u3092\u7a7a\u306e\u30cf\u30fc\u30c8\u306b\u5207\u308a\u66ff\u3048\u308b\u304b\u3001\u7834\u68c4\u3059\u308b\n            const heartToRemove = this.hearts.pop();\n            if (heartToRemove) {\n                heartToRemove.destroy(); \/\/ \u753b\u50cf\u3092\u7834\u68c4\n            }\n            if (this.currentHealth === 0) {\n                this.add.text(460, 140, 'GAME OVER',\n                    {fontSize: '84px', color: '#ff0000'}).setOrigin(0.5).setScrollFactor(0);\n                this.physics.pause();\n                this.player.setVisible(false);\n                this.time.delayedCall(3000, () => {\n                    this.initialHealth = 10;\n                    this.scene.start('GameScene');\n\n                });\n                \/\/   this.player.setVisible(false);\n            }\n        }\n    }\n\n    private showGameOverText() {\n        this.add.text(950 \/ 2, 550 \/ 2 - 100, 'Game over!\\nClick to Restart',\n            {fontSize: '64px', color: '#ff0000'}).setOrigin(0.5).setAlign('center');\n        this.input.once('pointerdown', () => {\n            \/\/   this.updateEnemyBehavior();\n            this.scene.restart();\n        });\n\n    }\n\n    private createExplosion(x: number, y: number) {\n        const explosion = this.add.sprite(x, y, 'explosion');\n        explosion.play('explode');\n        explosion.on('animationcomplete', () => {\n            explosion.destroy(); \/\/ \u30a2\u30cb\u30e1\u304c\u7d42\u308f\u3063\u305f\u3089\u6d88\u3059\n        });\n    }\n\n    private spawnEnemy(count: number) {\n        for (let i = 0; i < count; i++) {\n            const newX = Phaser.Math.Between(800, 1800);\n            const newY = Phaser.Math.Between(314, 313);\n            if (!this.enemy) {\n                \/\/    this.enemy = this.physics.add.sprite(newX, newY, 'enemy');\n                this.enemy = new Enemy(this, newX, newY);\n            } else {\n                this.enemy.enableBody(true, newX, newY, true, true);\n            }\n        }\n    }\n\n\n    shoot() {\n        \/\/ \u30d7\u30fc\u30eb\u304b\u3089\u5229\u7528\u53ef\u80fd\u306a\u5f3e\u4e38\u3092\u53d6\u5f97\u3059\u308b\n        \/\/   const bulletY = this.player.y - (this.player.height \/ 2) + 10;\n        const bullet = this.playerbullets.get(this.player.x, this.player.y).setScale(0.1) as Bullet | null;\n\n        if (bullet) {\n            if (this.player.flipX) {\n                bullet.fire(this.player.x + 9, this.player.y + 11, 800);\n            } else {\n                bullet.fire(this.player.x + 9, this.player.y + 11, -800);\n            }\n        }\n    }\n\n    private enemyShoot() {\n        if (!this.isEnemyActive || !(this.enemy.body as Phaser.Physics.Arcade.Body).enable) return;\n        const bullet = this.bullets.get(this.enemy.x, this.enemy.y);\n        if (bullet) {\n            bullet.setActive(true).setVisible(true);\n            bullet.body.allowGravity = false;\n            bullet.enableBody = true;\n            bullet.setScale(0.6);\n            this.time.delayedCall(2200, () => {\n                bullet.destroy();\n                bullet.setVisible(false);\n            });\n            \/\/ \u30d7\u30ec\u30a4\u30e4\u30fc\u3078\u306e\u89d2\u5ea6\u3092\u8a08\u7b97\n            const angle = Phaser.Math.Angle.Between(this.enemy.x, this.enemy.y, this.player.x, this.player.y);\n            if (this.player.x < this.enemy.x) {\n                this.enemy.setFlipX(false);\n            } else {\n                this.enemy.setFlipX(true);\n            }\n            this.physics.velocityFromRotation(angle, 500, bullet.body.velocity);\n        }\n    }\n\n    fireShot() {\n        const bulletCount = 5; \/\/ \u767a\u5c04\u3059\u308b\u6570\n        const spreadAngle = Phaser.Math.DegToRad(15); \/\/ \u5e83\u304c\u308b\u7bc4\u56f2\u306e\u5408\u8a08\uff0830\u5ea6\uff09\n        const startAngle = this.player.rotation - spreadAngle \/ 2; \/\/ \u958b\u59cb\u89d2\u5ea6\n        const angleStep = spreadAngle \/ (bulletCount - 1); \/\/ \u5f3e\u3054\u3068\u306e\u89d2\u5ea6\u306e\u5dee\n        let bulletSpeed = 400; \/\/ \u5f3e\u306e\u901f\u5ea6\n\n        for (let i = 0; i < bulletCount; i++) {\n            \/\/ 1. \u5404\u5f3e\u306e\u89d2\u5ea6\u3092\u8a08\u7b97\n            const angle = startAngle + (angleStep * i);\n            \/\/ 2. \u5f3e\uff08Sprite\uff09\u3092\u751f\u6210\n            const bullet = this.playerbullets.get(this.player.x, this.player.y).setScale(0.1);\n            if (bullet) {\n                bullet.setActive(true);\n                bullet.setVisible(true);\n                if (bullet) {\n                    if (this.player.flipX) {\n                        \/\/   bullet.fire(this.player.x, this.player.y + 5, 800);\n                        this.physics.velocityFromRotation(angle, -bulletSpeed, bullet.body.velocity);\n                    } else {\n                        this.physics.velocityFromRotation(angle, bulletSpeed, bullet.body.velocity);\n                        \/\/  bullet.fire(this.player.x, this.player.y + 5, -800);\n                    }\n                }\n            }\n        }\n    }\n\n    private updateEnemyBehavior() {\n        const distance = Phaser.Math.Distance.Between(\n            this.player.x, this.player.y,\n            this.enemy.x, this.enemy.y\n        );\n        \/\/ 1. \u51fa\u73fe\u8ddd\u96e2\u30c1\u30a7\u30c3\u30af\n        if (!this.isEnemyActive &#038;&#038; distance < 300) {\n            this.isEnemyActive = true;\n            this.enemy.setVisible(true);\n            (this.enemy.body as Phaser.Physics.Arcade.Body).setEnable(true);\n        }\n        if (!this.isEnemyActive) return;\n\n        \/\/ 2. \u505c\u6b62\u8ddd\u96e2\u30c1\u30a7\u30c3\u30af\uff06\u79fb\u52d5\n        if (distance > 300) {\n            \/\/ \u30d7\u30ec\u30a4\u30e4\u30fc\u306b\u5411\u304b\u3063\u3066\u79fb\u52d5\n            this.physics.moveToObject(this.enemy, this.player, 190);\n            if (this.player.y < this.enemy.y) {\n                this.enemy.setVelocityY(0);\n            }\n        } else {\n            this.enemy.setVelocity(0);\n        }\n    }\n\n    update() {\n        this.updateEnemyBehavior();\n        if (this.player) {\n            this.player.update(this.joystick);\n        }\n\n    }\n\n}\n\n<\/code><\/pre>\n<p>\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/<\/p>\n<p>main.ts<\/p>\n<pre><code class=\"swift\">\nimport * as Phaser from 'phaser';\nimport VirtualJoystickPlugin from 'phaser4-rex-plugins\/plugins\/virtualjoystick-plugin.js';\n\nimport { GameScene } from '.\/scenes\/GameScene';\n\nconst config: Phaser.Types.Core.GameConfig = {\n    type: Phaser.AUTO,\n    width: 950,\n    height: 550,\n    backgroundColor: '#cccccc',\n    \/\/ antialias: false,\n    disableContextMenu: true,\n    banner: false,\n    scale: {\n        mode: Phaser.Scale.FIT,\n        autoCenter: Phaser.Scale.CENTER_BOTH },\n    parent: 'app',\n\n    physics: {\n        default: 'arcade',\n        arcade: {\n            gravity: { x: 0, y: 400 },\n            debug: false,\n        },\n    },\n    plugins: {\n        global: [{\n            key: 'rexVirtualJoystick',\n            plugin: VirtualJoystickPlugin,\n            start: true\n        },\n        ]\n    },\n    scene: [GameScene],\n};\nwindow.addEventListener('load', () => {\n    new Phaser.Game(config);\n});\n\n<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Bullet import * as Phaser from&hellip;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2,3],"tags":[],"class_list":["post-144","post","type-post","status-publish","format-standard","hentry","category-phaser4","category-typescript"],"_links":{"self":[{"href":"https:\/\/tate.stars.ne.jp\/wpa\/wp-json\/wp\/v2\/posts\/144","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/tate.stars.ne.jp\/wpa\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/tate.stars.ne.jp\/wpa\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/tate.stars.ne.jp\/wpa\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/tate.stars.ne.jp\/wpa\/wp-json\/wp\/v2\/comments?post=144"}],"version-history":[{"count":2,"href":"https:\/\/tate.stars.ne.jp\/wpa\/wp-json\/wp\/v2\/posts\/144\/revisions"}],"predecessor-version":[{"id":146,"href":"https:\/\/tate.stars.ne.jp\/wpa\/wp-json\/wp\/v2\/posts\/144\/revisions\/146"}],"wp:attachment":[{"href":"https:\/\/tate.stars.ne.jp\/wpa\/wp-json\/wp\/v2\/media?parent=144"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/tate.stars.ne.jp\/wpa\/wp-json\/wp\/v2\/categories?post=144"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/tate.stars.ne.jp\/wpa\/wp-json\/wp\/v2\/tags?post=144"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}