{"id":115,"date":"2026-04-26T09:14:49","date_gmt":"2026-04-26T00:14:49","guid":{"rendered":"https:\/\/tate.stars.ne.jp\/wpa\/?p=115"},"modified":"2026-04-26T12:04:32","modified_gmt":"2026-04-26T03:04:32","slug":"mainscene","status":"publish","type":"post","link":"https:\/\/tate.stars.ne.jp\/wpa\/mainscene.html","title":{"rendered":"MainScene"},"content":{"rendered":"<pre><code class=\"swift\">\nimport { Scene } from 'phaser';\nimport Player from '.\/Player';\nimport ScoreText from \".\/ScoreText\";\n\nexport default class MainScene extends Scene {\nprivate player!: Phaser.Physics.Arcade.Sprite;\nprivate platforms!: Phaser.Physics.Arcade.StaticGroup;\nprivate joystick: any;\nprivate rexVirtualJoystick: any;\nprivate stars!: Phaser.Physics.Arcade.Group;\nprivate hitSound!: Phaser.Sound.BaseSound;\nprivate score: number = 0;\nprivate timeLeft: number =30; \/\/ \u5236\u9650\u6642\u9593\uff0830\u79d2\uff09\nprivate scoreText!: Phaser.GameObjects.Text;\nprivate timerText!: Phaser.GameObjects.Text;\nprivate timerEvent!: Phaser.Time.TimerEvent;\n\n constructor() {\n     super('MainScene');\n }\n preload() {\n  this.load.image('sky', 'assets\/sky.png');\n  this.load.image('ground', 'assets\/platform.png');\n  this.load.spritesheet('player', 'assets\/player3.png', {\n    frameWidth: 116, frameHeight: 168\n });\n  this.load.image('star', 'assets\/star.png');\n  this.load.image('bomb', 'assets\/bomb.png');\n  this.load.audio('coinSound', 'assets\/coin.mp3');\n}\n\ncreate() {\n  this.add.image(950 \/ 2, 550 \/ 2, 'sky').setScale(1.5).setAlpha(0.9);\n this.scoreText = this.add.text(16, 16, 'Stars: 0 \/ 10',\n  { fontSize: '32px', color: '#fff' });\n  this.timerText = this.add.text(16, 50, `Time: ${this.timeLeft}`,\n   { fontSize: '32px', color: '#ff0000' });\nthis.hitSound = this.sound.add('coinSound', {volume: 0.7, delay: 0});\n\n this.platforms = this.physics.add.staticGroup();\n this.platforms.create(400, 548, 'ground').setScale(2).refreshBody();\n  this.platforms.create(640, 350, 'ground');\n  this.platforms.create(50, 200, 'ground');\n  this.platforms.create(750, 180, 'ground');\n this.stars = this.physics.add.group({\n key: 'star',\n  repeat: 11,\n  setXY: {x: 12, y: 0, stepX: 70},\n });\n this.physics.add.collider(this.stars, this.platforms);\n(this.stars.getChildren() as Phaser.Physics.Arcade.Sprite[]).forEach(star => {\n  star.setBounceY(Phaser.Math.FloatBetween(0.4, 0.8));\n  });\n\n  this.player = new Player(this, 400, 360, 'player');\n  this.player.setBounce(0.2).setScale(0.5);\n  this.physics.add.existing(this.player);\n  this.player.setCollideWorldBounds(true);\n  this.physics.add.collider(this.player, this.platforms);\n\n   this.joystick = this.rexVirtualJoystick.add(this, {\n    x: 100,\n    y: 400,\n     radius: 100,\n     base: this.add.circle(0, 0, 100, 0x888888),\n    thumb: this.add.circle(0, 0, 50, 0xcccccc),\n      dir: '8dir',   \/\/ 8\u65b9\u5411\u5165\u529b\n      forceMin: 16,\n      fixed: false,  \/\/ \u3053\u3053\u3092false\u306b\u8a2d\u5b9a\n      enable: true\n     }).setVisible(false); \/\/ \u6700\u521d\u306f\u975e\u8868\u793a\u306b\u3057\u3066\u304a\u304f\n\n  this.input.on('pointerdown', (pointer: Phaser.Input.Pointer) => {\n    this.joystick.x = pointer.x;\n    this.joystick.y = pointer.y;\n    this.joystick.setVisible(true); \/\/ \u30bf\u30c3\u30c1\u3057\u305f\u5834\u6240\u3067\u8868\u793a\n    this.joystick.base.depth = 100; \/\/ \u5fc5\u8981\u306b\u5fdc\u3058\u3066\u91cd\u306a\u308a\u9806\u3092\u8abf\u6574\n    this.joystick.thumb.depth = 101;\n  });\n\/\/ \u6307\u3092\u96e2\u3057\u305f\u6642\u306b\u975e\u8868\u793a\u306b\u3059\u308b\u5834\u5408\n  this.input.on('pointerup', () => {\n   this.joystick.setVisible(false);\n });\n\nthis.physics.add.collider( this.player, this.stars, (player,star, ) =>\n  {\n   \/\/(star as Phaser.Physics.Arcade.Sprite).disableBody(true, true);\n   const en = star as Phaser.Physics.Arcade.Sprite;\n   en.disableBody(true, true);\n  \/\/this.scoreText.addScore(5);\n   this.score += 1;\n   this.scoreText.setText(`Stars: ${this.score} \/ 10`);\n   \/\/ 10\u500b\u96c6\u3081\u305f\u3089\u30af\u30ea\u30a2\u51e6\u7406\u3078\n    if (this.score >= 10) {\n    this.winGame();\n     this.input.once('pointerdown', () => {\n   \/\/this.updateEnemyBehavior();\n   this.score = 0;\n    this.timerEvent.destroy();\n    this.timeLeft = 30;\n    this.scene.restart();\n   });\n }\n  this.hitSound.play();\n  if (this.stars.countActive(true) === 0) {\n  this.spawnNewStars(5);\n  }\n  });\n\nthis.timerEvent = this.time.addEvent({\n delay: 1000,\n callback: this.updateTimer,\n callbackScope: this,\n loop: true\n });\n}\n\/\/ \u661f\u3092\u751f\u6210\u3059\u308b\u95a2\u6570\n spawnStars() {\n for (let i = 0; i < 12; i++) {\n   const star = this.stars.create(i * 70, 0, 'star');\n   star.setBounceY(Phaser.Math.FloatBetween(0.4, 0.8));\n }\n}\n private updateTimer() {\n this.timeLeft -= 1;\n this.timerText.setText(`Time: ${this.timeLeft}`);\n\/\/ \u6642\u9593\u5207\u308c\u306b\u306a\u3063\u305f\u3089\u30b2\u30fc\u30e0\u30aa\u30fc\u30d0\u30fc\n if (this.timeLeft <= 0) {\n  this.gameOver();\n  this.input.once('pointerdown', () => {\n  \/\/ this.updateEnemyBehavior();\n  this.score = 0;\n  this.timerEvent.destroy();\n  this.timeLeft = 30;\n this.scene.restart();\n });\n  }\n }\n\nprivate gameOver() {\n this.timerEvent.remove(); \/\/ \u30bf\u30a4\u30de\u30fc\u505c\u6b62\n \/\/this.timerEvent.destroy(); \/\/ \u30bf\u30a4\u30de\u30fc\u505c\u6b62\n this.physics.pause(); \/\/ \u7269\u7406\u6f14\u7b97\u505c\u6b62\n this.add.text(400, 300, 'GAME OVER',\n { fontSize: '64px', color: '#f00' }).setOrigin(0.5);\n}\n private winGame() {\n   this.timerEvent.remove();\n   this.add.text(400, 300, 'YOU WIN!',\n   { fontSize: '64px', color: '#0f0' }).setOrigin(0.5);\n }\n\nprivate spawnNewStars(count: number) {\n\/\/count\u5206\u3060\u3051\u661f\u3092\u518d\u6d3b\u6027\u5316\u3001\u307e\u305f\u306f\u65b0\u898f\u4f5c\u6210\nfor (let i = 0; i < count; i++) {\n \/\/ \u753b\u9762\u5185\u306e\u30e9\u30f3\u30c0\u30e0\u306a\u4f4d\u7f6e\u306b\u914d\u7f6e\n const x = Phaser.Math.Between(20, 900);\nconst y = Phaser.Math.Between(10, 0);\n\n\/\/ \u65e2\u5b58\u306e\u975e\u30a2\u30af\u30c6\u30a3\u30d6\u306a\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u3092\u518d\u5229\u7528\n const star = this.stars.get(x, y, 'star');\n if (star) {\n  star.setActive(true);\n  star.setVisible(true);\n  star.body.enable = true;\n  \/\/ \u5fc5\u8981\u306b\u5fdc\u3058\u3066\u30d0\u30a6\u30f3\u30c9\u8a2d\u5b9a\u306a\u3069\u3092\u518d\u9069\u7528\n   star.setBounceY(Phaser.Math.FloatBetween(0.4, 0.8));\n }\n  }\n }\n\n update() {\n \/\/ 3. \u6bce\u30d5\u30ec\u30fc\u30e0\u3001\u30b8\u30e7\u30a4\u30b9\u30c6\u30a3\u30c3\u30af\u306e\u72b6\u614b\u3092\u30d7\u30ec\u30a4\u30e4\u30fc\u306b\u6e21\u3059\n if (this.player) {\nthis.player.update(this.joystick);\n   }\n }\n}\n<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>import { Scene } from &#8216;phaser&#8217;&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-115","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\/115","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=115"}],"version-history":[{"count":1,"href":"https:\/\/tate.stars.ne.jp\/wpa\/wp-json\/wp\/v2\/posts\/115\/revisions"}],"predecessor-version":[{"id":116,"href":"https:\/\/tate.stars.ne.jp\/wpa\/wp-json\/wp\/v2\/posts\/115\/revisions\/116"}],"wp:attachment":[{"href":"https:\/\/tate.stars.ne.jp\/wpa\/wp-json\/wp\/v2\/media?parent=115"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/tate.stars.ne.jp\/wpa\/wp-json\/wp\/v2\/categories?post=115"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/tate.stars.ne.jp\/wpa\/wp-json\/wp\/v2\/tags?post=115"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}