{"id":123,"date":"2026-04-26T15:49:05","date_gmt":"2026-04-26T06:49:05","guid":{"rendered":"https:\/\/tate.stars.ne.jp\/wpa\/?p=123"},"modified":"2026-04-26T15:49:41","modified_gmt":"2026-04-26T06:49:41","slug":"breakout","status":"publish","type":"post","link":"https:\/\/tate.stars.ne.jp\/wpa\/breakout.html","title":{"rendered":"Breakout"},"content":{"rendered":"<pre><code class=\"swift\">\nMainScene\nimport { Scene } from 'phaser';\nimport ScoreText from \".\/ScoreText\";\nexport default class MainScene extends Scene {\n private paddle!: Phaser.Types.Physics.Arcade.ImageWithDynamicBody;\n private ball!: Phaser.Types.Physics.Arcade.ImageWithDynamicBody;\n private bricks!: Phaser.Physics.Arcade.StaticGroup;\n private scoreText!: ScoreText;\n private hitSound!: Phaser.Sound.BaseSound;\n constructor() {\n     super('GameScene');\n   }\n preload() {\n this.load.image('paddle', 'assets\/paddle.png');\n this.load.image('ball', 'assets\/ball2.png');\n this.load.image('brick', 'assets\/brick.png');\n this.load.spritesheet('explosion', 'assets\/explosion.png', {\n   frameWidth: 64,\n   frameHeight: 64,\n   endFrame: 23\n  });\n this.load.audio('coinSound', 'assets\/se.mp3');\n }\ncreate() {\n        \/\/ \u7269\u7406\u30a8\u30f3\u30b8\u30f3\u306e\u8a2d\u5b9a\n this.physics.world.checkCollision.down = false;\n const style: Phaser.Types.GameObjects.Text.TextStyle = {\n  fontSize: '22px',\n  color: '#fff',\n  fontFamily: 'Courier'\n };\n this.scoreText = new ScoreText(this, 14, 14, style);\n \/\/ \u30d1\u30c9\u30eb\u306e\u4f5c\u6210\n this.paddle = this.physics.add.image(400, 550, 'paddle').setImmovable();\n this.paddle.body.setCollideWorldBounds(true);\n this.hitSound = this.sound.add('coinSound', {volume: 0.7, delay: 0});\n \/\/ \u30dc\u30fc\u30eb\u306e\u4f5c\u6210\n this.ball = this.physics.add.image(400, 500, 'ball');\n this.ball.body.setCollideWorldBounds(true);\n this.ball.body.setBounce(1);\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\u975e\u8868\u793a\u306b\u3059\u308b\n});\n\/\/ \u30d6\u30ed\u30c3\u30af\u306e\u751f\u6210\n  this.bricks = this.physics.add.staticGroup();\n  for (let y = 0; y < 5; y++) {\n   for (let x = 0; x < 12; x++) {\n   this.bricks.create(70 + x * 60, 50 + y * 30, 'brick');\n  }\n }\nthis.physics.add.collider(this.ball, this.paddle);\n this.physics.add.collider( this.ball, this.bricks, (ball,brick, ) =>\n  {\n\/\/  (star as Phaser.Physics.Arcade.Sprite).disableBody(true, true);\nconst en = brick as Phaser.Physics.Arcade.Sprite;\nen.disableBody(true, true);\nthis.scoreText.addScore(5);\n this.hitSound.play();\n this.createExplosion(en.x-5, en.y+2);\n\/\/   this.createExplosion(5,5);\n if (this.bricks.countActive(true) === 0) {\n  \/\/   this.gameClearText.setText('YOU WIN!\\nClick to Restart');\n   this.gameWin();\n   }\n });\nthis.input.once('pointerdown', () => {\n this.startBall();\n });\n}\nprivate 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 }\nstartBall() {\n  this.ball.body.setVelocity(250, -230);\n}\nprivate gameWin() {\n  this.physics.pause();\n  this.add.text(400, 300, 'YOU WIN!\\nClick to Restart',\n  { fontSize: '54px', color: '#009dff' }).setOrigin(0.5).setAlign('center');\n  this.input.once('pointerdown', () => {\n   this.scene.restart();\n  });\n }\n\nupdate() {\n const pointer = this.input.activePointer;\n this.paddle.x = Phaser.Math.Clamp(pointer.x, 50, 750);\n \/\/ \u30b2\u30fc\u30e0\u30aa\u30fc\u30d0\u30fc\u5224\u5b9a\n if (this.ball.y > 600) {\n \/\/  this.scene.restart();\n this.gameOver();\n   }\n}\n\nprivate gameOver() {\n this.physics.pause(); \/\/ \u7269\u7406\u6f14\u7b97\u3092\u505c\u6b62\n this.ball.setTint(0xff0000); \/\/ \u30dc\u30fc\u30eb\u3092\u8d64\u304f\u3059\u308b\n const gameOverText = this.add.text(400, 300, 'GAME OVER', {\n   fontSize: '64px',\n   color: '#ff0000'\n }).setOrigin(0.5);\n \/\/ \u753b\u9762\u30af\u30ea\u30c3\u30af\u3067\u518d\u958b\n this.input.once('pointerdown', () => {\n   this.scene.restart();\n   });\n }\n}\n<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>MainScene import { Scene } fro&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-123","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\/123","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=123"}],"version-history":[{"count":1,"href":"https:\/\/tate.stars.ne.jp\/wpa\/wp-json\/wp\/v2\/posts\/123\/revisions"}],"predecessor-version":[{"id":124,"href":"https:\/\/tate.stars.ne.jp\/wpa\/wp-json\/wp\/v2\/posts\/123\/revisions\/124"}],"wp:attachment":[{"href":"https:\/\/tate.stars.ne.jp\/wpa\/wp-json\/wp\/v2\/media?parent=123"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/tate.stars.ne.jp\/wpa\/wp-json\/wp\/v2\/categories?post=123"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/tate.stars.ne.jp\/wpa\/wp-json\/wp\/v2\/tags?post=123"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}