====== ๐ŸŽฎ Phaser.js ====== Phaser.js๋Š” HTML5 ๊ฒŒ์ž„ ๊ฐœ๋ฐœ์„ ์œ„ํ•œ JavaScript ํ”„๋ ˆ์ž„์›Œํฌ๋กœ, ์›น ๋ธŒ๋ผ์šฐ์ €์—์„œ ๊ฒŒ์ž„์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค. ===== ๐Ÿ“‹ ์ •์˜ ===== **Phaser.js**๋Š” HTML5 Canvas์™€ WebGL์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•œ ์˜คํ”ˆ์†Œ์Šค ๊ฒŒ์ž„ ํ”„๋ ˆ์ž„์›Œํฌ์ž…๋‹ˆ๋‹ค. ์Šคํ”„๋ผ์ดํŠธ, ์• ๋‹ˆ๋ฉ”์ด์…˜, ์‚ฌ์šด๋“œ, ๋ฌผ๋ฆฌ ์—”์ง„ ๋“ฑ ๊ฒŒ์ž„ ๊ฐœ๋ฐœ์— ํ•„์š”ํ•œ ๋ชจ๋“  ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ===== ๐ŸŽฏ ์ฃผ์š” ํŠน์ง• ===== **1. ํฌ๋กœ์Šค ํ”Œ๋žซํผ ์ง€์›** - ์›น ๋ธŒ๋ผ์šฐ์ €์—์„œ ์‹คํ–‰๋˜๋Š” HTML5 ๊ฒŒ์ž„์„ ๊ฐœ๋ฐœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. - ๋ชจ๋ฐ”์ผ, ๋ฐ์Šคํฌํ†ฑ, ํƒœ๋ธ”๋ฆฟ ๋“ฑ ๋‹ค์–‘ํ•œ ๊ธฐ๊ธฐ์—์„œ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. **2. ํ’๋ถ€ํ•œ ๊ฒŒ์ž„ ๊ธฐ๋Šฅ** - ์Šคํ”„๋ผ์ดํŠธ ๊ด€๋ฆฌ ๋ฐ ์• ๋‹ˆ๋ฉ”์ด์…˜ - ์‚ฌ์šด๋“œ ๋ฐ ์Œ์•… ์žฌ์ƒ - ๋ฌผ๋ฆฌ ์—”์ง„ (Arcade Physics, Matter.js) - ์ž…๋ ฅ ์ฒ˜๋ฆฌ (ํ‚ค๋ณด๋“œ, ๋งˆ์šฐ์Šค, ํ„ฐ์น˜) - ์นด๋ฉ”๋ผ ๋ฐ ์‹œ๊ฐ ํšจ๊ณผ **3. ์ง๊ด€์ ์ธ API** - ๊ฒŒ์ž„ ๊ฐœ๋ฐœ์— ํŠนํ™”๋œ API๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. - ์”ฌ(Scene) ๊ธฐ๋ฐ˜ ๊ตฌ์กฐ๋กœ ๊ฒŒ์ž„ ์ƒํƒœ๋ฅผ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ===== ๐Ÿ—๏ธ ๊ธฐ๋ณธ ๊ตฌ์กฐ ===== **Phaser ๊ฒŒ์ž„ ์„ค์ •:** import Phaser from 'phaser'; const config = { type: Phaser.AUTO, width: 800, height: 600, parent: 'game-container', backgroundColor: '#2c3e50', scene: { preload: preload, create: create, update: update }, physics: { default: 'arcade', arcade: { gravity: { y: 300 }, debug: false } } }; const game = new Phaser.Game(config); **๊ธฐ๋ณธ ๊ฒŒ์ž„ ์”ฌ:** function preload() { // ์—์…‹ ๋กœ๋“œ this.load.image('player', 'assets/player.png'); this.load.image('background', 'assets/background.png'); this.load.audio('jump', 'assets/jump.wav'); } function create() { // ๊ฒŒ์ž„ ๊ฐ์ฒด ์ƒ์„ฑ this.add.image(400, 300, 'background'); this.player = this.physics.add.sprite(100, 450, 'player'); // ์ž…๋ ฅ ์„ค์ • this.cursors = this.input.keyboard.createCursorKeys(); // ์‚ฌ์šด๋“œ ์„ค์ • this.jumpSound = this.sound.add('jump'); } function update() { // ๊ฒŒ์ž„ ๋กœ์ง ์—…๋ฐ์ดํŠธ if (this.cursors.left.isDown) { this.player.setVelocityX(-160); } else if (this.cursors.right.isDown) { this.player.setVelocityX(160); } else { this.player.setVelocityX(0); } if (this.cursors.up.isDown && this.player.body.touching.down) { this.player.setVelocityY(-330); this.jumpSound.play(); } } ===== ๐ŸŽจ ์Šคํ”„๋ผ์ดํŠธ ๊ด€๋ฆฌ ===== ์Šคํ”„๋ผ์ดํŠธ๋Š” ๋น„๋””์˜ค ๊ฒŒ์ž„์ด๋‚˜ ์ปดํ“จํ„ฐ ๊ทธ๋ž˜ํ”ฝ์—์„œ ์‚ฌ์šฉ๋˜๋Š” 2D ๋น„ํŠธ๋งต ์ด๋ฏธ์ง€ ๋˜๋Š” ์• ๋‹ˆ๋ฉ”์ด์…˜์˜ ๊ตฌ์„ฑ ์š”์†Œ์ž…๋‹ˆ๋‹ค. ํ™”๋ฉด์— ํ‘œ์‹œ๋˜๋Š” ์บ๋ฆญํ„ฐ, ์˜ค๋ธŒ์ ํŠธ ๋˜๋Š” ๋ฐฐ๊ฒฝ ์š”์†Œ๊ฐ€ ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. **์Šคํ”„๋ผ์ดํŠธ ์ƒ์„ฑ:** // ์ด๋ฏธ์ง€ ์Šคํ”„๋ผ์ดํŠธ const sprite = this.add.sprite(x, y, 'spriteKey'); // ๋ฌผ๋ฆฌ ๋ฐ”๋”” ์ถ”๊ฐ€ const physicsSprite = this.physics.add.sprite(x, y, 'spriteKey'); // ๊ทธ๋ฃน ์ƒ์„ฑ const group = this.add.group(); group.add(sprite1); group.add(sprite2); **์• ๋‹ˆ๋ฉ”์ด์…˜ ์„ค์ •:** // ์Šคํ”„๋ผ์ดํŠธ ์‹œํŠธ์—์„œ ์• ๋‹ˆ๋ฉ”์ด์…˜ ์ƒ์„ฑ this.anims.create({ key: 'walk', frames: this.anims.generateFrameNumbers('player', { start: 0, end: 3 }), frameRate: 10, repeat: -1 }); // ์• ๋‹ˆ๋ฉ”์ด์…˜ ์žฌ์ƒ sprite.play('walk'); ===== ๐ŸŽต ์‚ฌ์šด๋“œ ์‹œ์Šคํ…œ ===== **์‚ฌ์šด๋“œ ๊ด€๋ฆฌ:** // ์‚ฌ์šด๋“œ ๋กœ๋“œ this.load.audio('bgMusic', 'assets/music.mp3'); this.load.audio('jumpSound', 'assets/jump.wav'); // ์‚ฌ์šด๋“œ ์žฌ์ƒ const bgMusic = this.sound.add('bgMusic', { loop: true, volume: 0.5 }); bgMusic.play(); // ํšจ๊ณผ์Œ ์žฌ์ƒ this.sound.play('jumpSound'); ===== ๐ŸŽฎ ์ž…๋ ฅ ์ฒ˜๋ฆฌ ===== **ํ‚ค๋ณด๋“œ ์ž…๋ ฅ:** // ์ปค์„œ ํ‚ค ์„ค์ • this.cursors = this.input.keyboard.createCursorKeys(); // ํŠน์ • ํ‚ค ์„ค์ • this.spaceKey = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.SPACE); // ํ‚ค ์ด๋ฒคํŠธ this.input.keyboard.on('keydown-A', function() { console.log('A ํ‚ค๊ฐ€ ๋ˆŒ๋ ธ์Šต๋‹ˆ๋‹ค!'); }); **๋งˆ์šฐ์Šค/ํ„ฐ์น˜ ์ž…๋ ฅ:** // ํด๋ฆญ ์ด๋ฒคํŠธ this.input.on('pointerdown', function(pointer) { console.log('ํด๋ฆญ ์œ„์น˜:', pointer.x, pointer.y); }); // ์Šคํ”„๋ผ์ดํŠธ ํด๋ฆญ ์ด๋ฒคํŠธ sprite.setInteractive(); sprite.on('pointerdown', function() { console.log('์Šคํ”„๋ผ์ดํŠธ๊ฐ€ ํด๋ฆญ๋˜์—ˆ์Šต๋‹ˆ๋‹ค!'); }); ===== ๐Ÿƒ ๋ฌผ๋ฆฌ ์—”์ง„ ===== **Arcade Physics:** // ๋ฌผ๋ฆฌ ๋ฐ”๋”” ์ถ”๊ฐ€ this.player = this.physics.add.sprite(100, 450, 'player'); // ์ค‘๋ ฅ ์„ค์ • this.player.body.setGravityY(300); // ์ถฉ๋Œ ๊ฐ์ง€ this.physics.add.collider(this.player, this.platforms); // ์˜ค๋ฒ„๋žฉ ๊ฐ์ง€ this.physics.add.overlap(this.player, this.coins, this.collectCoin, null, this); **์ถฉ๋Œ ์ฒ˜๋ฆฌ:** function collectCoin(player, coin) { coin.disableBody(true, true); this.score += 10; this.scoreText.setText('Score: ' + this.score); } ===== ๐Ÿ“ฑ ๋ชจ๋ฐ”์ผ ์ตœ์ ํ™” ===== **๋ฐ˜์‘ํ˜• ๋””์ž์ธ:** const config = { type: Phaser.AUTO, width: window.innerWidth, height: window.innerHeight, scale: { mode: Phaser.Scale.FIT, autoCenter: Phaser.Scale.CENTER_BOTH } }; **ํ„ฐ์น˜ ์ปจํŠธ๋กค:** // ๊ฐ€์ƒ ์กฐ์ด์Šคํ‹ฑ this.joyStick = this.plugins.get('rexvirtualjoystickplugin').add(this, { x: 100, y: 500, radius: 50, base: this.add.circle(0, 0, 50, 0x888888), thumb: this.add.circle(0, 0, 25, 0xcccccc), // ... ๊ธฐํƒ€ ์„ค์ • }); ===== ๐ŸŽจ ์‹œ๊ฐ ํšจ๊ณผ ===== **ํŒŒํ‹ฐํด ์‹œ์Šคํ…œ:** // ํŒŒํ‹ฐํด ์ƒ์„ฑ const particles = this.add.particles('particle'); const emitter = particles.createEmitter({ speed: 100, scale: { start: 1, end: 0 }, blendMode: 'ADD' }); // ํŒŒํ‹ฐํด ๋ฐœ์‚ฌ emitter.setPosition(400, 300); **์นด๋ฉ”๋ผ ํšจ๊ณผ:** // ์นด๋ฉ”๋ผ ํŒ”๋กœ์šฐ this.cameras.main.startFollow(this.player); // ์นด๋ฉ”๋ผ ํ”๋“ค๊ธฐ this.cameras.main.shake(500, 0.01); // ํŽ˜์ด๋“œ ํšจ๊ณผ this.cameras.main.fade(1000, 0, 0, 0); ===== ๐Ÿ“Š ์„ฑ๋Šฅ ์ตœ์ ํ™” ===== **๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ:** // ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ํ…์Šค์ฒ˜ ์ œ๊ฑฐ this.textures.remove('unusedSprite'); // ์Šคํ”„๋ผ์ดํŠธ ํ’€๋ง const spritePool = this.add.group(); for (let i = 0; i < 10; i++) { const sprite = this.add.sprite(0, 0, 'bullet'); sprite.setActive(false); sprite.setVisible(false); spritePool.add(sprite); } **๋ Œ๋”๋ง ์ตœ์ ํ™”:** // ์ •์  ๊ฐ์ฒด๋Š” ํ•œ ๋ฒˆ๋งŒ ๋ Œ๋”๋ง this.add.staticGroup(); // ๋ฐฐ์น˜ ๋ Œ๋”๋ง ์‚ฌ์šฉ this.add.batch('sprites'); ===== ๐Ÿ“š ๊ด€๋ จ ์šฉ์–ด ===== * [[wiki:glossary:web_technologies:javascript|JavaScript]] - ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด * [[wiki:glossary:web_technologies:css|CSS]] - ์Šคํƒ€์ผ๋ง * [[wiki:glossary:development_tools:git:github|GitHub]] - ์ฝ”๋“œ ์ €์žฅ์†Œ ===== ๐Ÿ”— ๊ด€๋ จ ๋ฌธ์„œ ===== * [[wiki:it:dream_of_enc:metaverse:phaser|Phaser.js ๊ฒŒ์ž„ ์—”์ง„]] * [[wiki:it:dream_of_enc:metaverse:game_logic|๋ฐ”๋‘‘ ๊ฒŒ์ž„ ๋กœ์ง]] * [[wiki:glossary:web_technologies:css|CSS]] - ์Šคํƒ€์ผ๋ง * [[wiki:glossary:development_tools:git:github|GitHub]] - ์ฝ”๋“œ ์ €์žฅ์†Œ --- //์ด ํŽ˜์ด์ง€๋Š” ์ž๋™์œผ๋กœ ์ƒ์„ฑ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.//