์‚ฌ์šฉ์ž ๋„๊ตฌ

์‚ฌ์ดํŠธ ๋„๊ตฌ


wiki:it:dream_of_enc:metaverse:phaser

์ฐจ์ด

๋ฌธ์„œ์˜ ์„ ํƒํ•œ ๋‘ ํŒ ์‚ฌ์ด์˜ ์ฐจ์ด๋ฅผ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

์ฐจ์ด ๋ณด๊ธฐ๋กœ ๋งํฌ

๋‹ค์Œ ํŒ
์ด์ „ ํŒ
wiki:it:dream_of_enc:metaverse:phaser [2025/07/28 05:57] โ€“ ๋งŒ๋“ฆ - ๋ฐ”๊นฅ ํŽธ์ง‘ 127.0.0.1wiki:it:dream_of_enc:metaverse:phaser [2025/07/30 06:43] (ํ˜„์žฌ) โ€“ ๋ฐ”๊นฅ ํŽธ์ง‘ 127.0.0.1
์ค„ 1: ์ค„ 1:
 ====== ๐ŸŽฎ Phaser.js ๊ฒŒ์ž„ ์—”์ง„ ====== ====== ๐ŸŽฎ Phaser.js ๊ฒŒ์ž„ ์—”์ง„ ======
  
-Phaser Baduk Metaverse ํ”„๋กœ์ ํŠธ์˜ Phaser.js ๊ฒŒ์ž„ ์—”์ง„ ๊ตฌํ˜„์— ๋Œ€ํ•ด ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค.+Phaser Baduk Metaverse ํ”„๋กœ์ ํŠธ์—์„œ ์‚ฌ์šฉ๋˜๋Š” Phaser.js ๊ฒŒ์ž„ ์—”์ง„์˜ ๊ตฌํ˜„ ๋‚ด์šฉ์— ๋Œ€ํ•ด ์ž์„ธํžˆ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค.
  
 +----
 ===== ๐Ÿ“‹ ๊ฐœ์š” ===== ===== ๐Ÿ“‹ ๊ฐœ์š” =====
  
-Phaser.js๋Š” HTML5 ๊ฒŒ์ž„ ๊ฐœ๋ฐœ์„ ์œ„ํ•œ JavaScript ํ”„๋ ˆ์ž„์›Œํฌ๋กœ, ๋ฐ”๋‘‘ ๊ฒŒ์ž„์˜ ์‹œ๊ฐ์  ์š”์†Œ์™€ ์ธํ„ฐ๋ž™์…˜์„ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค.+Phaser.js๋Š” HTML5 ๊ฒŒ์ž„ ๊ฐœ๋ฐœ์— ํŠนํ™”๋œ ๊ฐ•๋ ฅํ•œ JavaScript ํ”„๋ ˆ์ž„์›Œํฌ์ž…๋‹ˆ๋‹ค. ์ด ํ”„๋ ˆ์ž„์›Œํฌ๋Š” ๋ฐ”๋‘‘ ๊ฒŒ์ž„์˜ ์‹œ๊ฐ์  ์š”์†Œ๋ฅผ ๊ตฌํ˜„ํ•˜๊ณ , ์‚ฌ์šฉ์ž ์ธํ„ฐ๋ž™์…˜ ๋ฐ ์‹ค์‹œ๊ฐ„ ํ†ต์‹  ๊ธฐ๋Šฅ์„ ํ†ตํ•ฉํ•˜์—ฌ ๋ชฐ์ž…๊ฐ ์žˆ๋Š” ๊ฒŒ์ž„ ๊ฒฝํ—˜์„ ์ œ๊ณตํ•˜๋Š” ๋ฐ ํ•ต์‹ฌ์ ์ธ ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.
  
-===== ๐Ÿ—๏ธ ๊ธฐ๋ณธ ๊ตฌ์กฐ =====+  * ''HTML5 ๊ธฐ๋ฐ˜'': ์›น ๋ธŒ๋ผ์šฐ์ €์—์„œ ์ง์ ‘ ์‹คํ–‰๋˜์–ด ๋ณ„๋„์˜ ์„ค์น˜ ์—†์ด ์ ‘๊ทผ์„ฑ์ด ๋†’์Šต๋‹ˆ๋‹ค.ย 
 +  * ''๊ฒŒ์ž„ ๊ฐœ๋ฐœ ํŠนํ™”'': ์Šคํ”„๋ผ์ดํŠธ, ์• ๋‹ˆ๋ฉ”์ด์…˜, ๋ฌผ๋ฆฌ ์—”์ง„ ๋“ฑ ๊ฒŒ์ž„ ๊ฐœ๋ฐœ์— ํ•„์š”ํ•œ ๋‹ค์–‘ํ•œ ๊ธฐ๋Šฅ์„ ๋‚ด์žฅํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.ย 
 +  * ''์œ ์—ฐํ•œ ๊ตฌ์กฐ'': ์”ฌ(Scene) ๊ธฐ๋ฐ˜์˜ ์•„ํ‚คํ…์ฒ˜๋ฅผ ํ†ตํ•ด ๊ฒŒ์ž„์˜ ๊ฐ ๋ถ€๋ถ„์„ ๋ชจ๋“ˆํ™”ํ•˜์—ฌ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  
-**๋ฉ”์ธ ๊ฒŒ์ž„ ํŒŒ์ผ (game.js):**ย +----ย 
-<code javascript>+==== 1. ๊ฒŒ์ž„ ์—”์ง„ ๊ธฐ๋ณธ ๊ตฌ์กฐ ๋ฐ ์„ค์ • ====ย 
 +ย 
 +Phaser.js ๊ฒŒ์ž„ ์—”์ง„์˜ ํ•ต์‹ฌ ์ง„์ž…์ ์ธ ''game.js'' ํŒŒ์ผ์€ ๊ฒŒ์ž„์˜ ์ „๋ฐ˜์ ์ธ ์„ค์ •๊ณผ ์ดˆ๊ธฐํ™”๋ฅผ ๋‹ด๋‹นํ•ฉ๋‹ˆ๋‹ค. ์ด ํŒŒ์ผ์€ ๊ฒŒ์ž„์˜ ์บ”๋ฒ„์Šค ํฌ๊ธฐ, ๋ฐฐ๊ฒฝ์ƒ‰, ์‚ฌ์šฉํ•  ์”ฌ ๋ชฉ๋ก ๋“ฑ ํ•„์ˆ˜์ ์ธ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.ย 
 +ย 
 +=== 1) ๋ฉ”์ธ ๊ฒŒ์ž„ ํŒŒ์ผ (game.js) ===ย 
 +ย 
 +''game.js''๋Š” Phaser ๊ฒŒ์ž„ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•˜๊ณ , ๊ฒŒ์ž„์˜ ์ „์—ญ ์„ค์ •์„ ์ •์˜ํ•˜๋Š” ํŒŒ์ผ์ž…๋‹ˆ๋‹ค. ์ด๊ณณ์—์„œ ๊ฒŒ์ž„์˜ ํ•ด์ƒ๋„, ๋ Œ๋”๋ง ๋ฐฉ์‹, ํฌํ•จ๋  ์”ฌ ๋ชฉ๋ก ๋“ฑ์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.ย 
 +ย 
 +<file javascript>
 import Phaser from 'phaser'; import Phaser from 'phaser';
 import BadukScene from './scenes/BadukScene'; import BadukScene from './scenes/BadukScene';
 import MenuScene from './scenes/MenuScene'; import MenuScene from './scenes/MenuScene';
  
 +// 1. ๊ฒŒ์ž„ ์„ค์ • ๊ฐ์ฒด ์ •์˜
 const config = { const config = {
-    type: Phaser.AUTO,ย +    type: Phaser.AUTO, // ๋ Œ๋”๋ง ๋ฐฉ์‹ (WebGL ๋˜๋Š” Canvas ์ž๋™ ์„ ํƒ)ย 
-    width: 1200,ย +    width: 1200,      // ๊ฒŒ์ž„ ํ™”๋ฉด ๋„ˆ๋น„ (ํ”ฝ์…€)ย 
-    height: 800,ย +    height: 800,       // ๊ฒŒ์ž„ ํ™”๋ฉด ๋†’์ด (ํ”ฝ์…€)ย 
-    parent: 'game-container',ย +    parent: 'game-container', // ๊ฒŒ์ž„ ์บ”๋ฒ„์Šค๊ฐ€ ์‚ฝ์ž…๋  HTML ์š”์†Œ์˜ IDย 
-    backgroundColor: '#2c3e50',ย +    backgroundColor: '#2c3e50', // ๊ฒŒ์ž„ ๋ฐฐ๊ฒฝ์ƒ‰ย 
-    scene: [MenuScene, BadukScene],ย +    scene: [MenuScene, BadukScene], // ๊ฒŒ์ž„์— ํฌํ•จ๋  ์”ฌ ๋ชฉ๋ก (์ˆœ์„œ ์ค‘์š”)ย 
-    physics: {ย +    physics: {         // ๋ฌผ๋ฆฌ ์—”์ง„ ์„ค์ •ย 
-        default: 'arcade',+        default: 'arcade', // ๊ธฐ๋ณธ ๋ฌผ๋ฆฌ ์—”์ง„์œผ๋กœ Arcade ๋ฌผ๋ฆฌ ์—”์ง„ ์‚ฌ์šฉ
         arcade: {         arcade: {
-            gravity: { y: 0 },ย +            gravity: { y: 0 }, // y์ถ• ์ค‘๋ ฅ ์—†์Œย 
-            debug: false+            debug: false       // ๋ฌผ๋ฆฌ ๊ฐ์ฒด ๋””๋ฒ„๊ทธ ์ •๋ณด ๋น„ํ™œ์„ฑํ™”
         }         }
     },     },
-    scale: {ย +    scale: {           // ์Šค์ผ€์ผ๋ง ์„ค์ •ย 
-        mode: Phaser.Scale.FIT,ย +        mode: Phaser.Scale.FIT, // ํ™”๋ฉด์— ๋งž๊ฒŒ ๊ฒŒ์ž„ ํฌ๊ธฐ ์กฐ์ ˆย 
-        autoCenter: Phaser.Scale.CENTER_BOTH+        autoCenter: Phaser.Scale.CENTER_BOTH // ๊ฐ€๋กœ/์„ธ๋กœ ์ค‘์•™ ์ •๋ ฌ
     }     }
 }; };
  
 +// 2. Phaser ๊ฒŒ์ž„ ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ
 const game = new Phaser.Game(config); const game = new Phaser.Game(config);
 +
 +// 3. ๊ฒŒ์ž„ ์ธ์Šคํ„ด์Šค ๋‚ด๋ณด๋‚ด๊ธฐ (๋‹ค๋ฅธ ํŒŒ์ผ์—์„œ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๋„๋ก)
 export default game; export default game;
-</code>+</file>ย 
 +ย 
 +''์ฝ”๋“œ ์„ค๋ช…'':ย 
 +  * ''์ž„ํฌํŠธ (Import)'': Phaser ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€ ๊ฒŒ์ž„์—์„œ ์‚ฌ์šฉํ•  ''MenuScene'', ''BadukScene'' ์”ฌ๋“ค์„ ๋ถˆ๋Ÿฌ์˜ต๋‹ˆ๋‹ค.ย 
 +  * ''config ๊ฐ์ฒด'': ๊ฒŒ์ž„์˜ ์ „๋ฐ˜์ ์ธ ์„ค์ •์„ ๋‹ด๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ฃผ์š” ์†์„ฑ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.ย 
 +    *   ''type'': ๊ฒŒ์ž„ ๋ Œ๋”๋ง ๋ฐฉ์‹์„ ๊ฒฐ์ •ํ•ฉ๋‹ˆ๋‹ค. ''Phaser.AUTO''๋Š” ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์ง€์›ํ•˜๋Š” ์ตœ์ ์˜ ๋ Œ๋”๋ง ๋ฐฉ์‹(WebGL ๋˜๋Š” Canvas)์„ ์ž๋™์œผ๋กœ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.ย 
 +    *   ''width'', ''height'': ๊ฒŒ์ž„ ํ™”๋ฉด์˜ ํ•ด์ƒ๋„๋ฅผ ํ”ฝ์…€ ๋‹จ์œ„๋กœ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.ย 
 +    *   ''parent'': ๊ฒŒ์ž„ ์บ”๋ฒ„์Šค๊ฐ€ ์‚ฝ์ž…๋  HTML ๋ฌธ์„œ ๋‚ด์˜ ํŠน์ • DOM ์š”์†Œ ID๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ, ''id="game-container"''๋ฅผ ๊ฐ€์ง„ ์š”์†Œ์— ๊ฒŒ์ž„์ด ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.ย 
 +    *   ''backgroundColor'': ๊ฒŒ์ž„์˜ ๊ธฐ๋ณธ ๋ฐฐ๊ฒฝ์ƒ‰์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.ย 
 +    *   ''scene'': ๊ฒŒ์ž„์—์„œ ์‚ฌ์šฉํ•  ๋ชจ๋“  ์”ฌ(Scene)๋“ค์˜ ๋ฐฐ์—ด์ž…๋‹ˆ๋‹ค. ๋ฐฐ์—ด์˜ ์ˆœ์„œ์— ๋”ฐ๋ผ ์”ฌ๋“ค์ด ๋กœ๋“œ๋˜์ง€๋งŒ, ๊ฒŒ์ž„ ์‹œ์ž‘ ์‹œ์—๋Š” ์ฒซ ๋ฒˆ์งธ ์”ฌ์ด ๊ธฐ๋ณธ์œผ๋กœ ์‹œ์ž‘๋ฉ๋‹ˆ๋‹ค.ย 
 +    *   ''physics'': ๋ฌผ๋ฆฌ ์—”์ง„ ์„ค์ •์„ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ๋Š” ๋ฐ”๋‘‘ ๊ฒŒ์ž„์— ํ•„์š”ํ•˜์ง€ ์•Š์€ ์ค‘๋ ฅ์„ ๋น„ํ™œ์„ฑํ™”ํ•˜๊ณ  ๋””๋ฒ„๊ทธ ๋ชจ๋“œ๋ฅผ ๊บผ๋‘์—ˆ์Šต๋‹ˆ๋‹ค.ย 
 +    *   ''scale'': ๊ฒŒ์ž„์ด ๋‹ค์–‘ํ•œ ํ™”๋ฉด ํฌ๊ธฐ์— ๋งž์ถฐ ์–ด๋–ป๊ฒŒ ์กฐ์ ˆ๋ ์ง€ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. ''FIT'' ๋ชจ๋“œ๋Š” ํ™”๋ฉด ๋น„์œจ์„ ์œ ์ง€ํ•˜๋ฉฐ ๊ฐ€๋Šฅํ•œ ํ•œ ํฌ๊ฒŒ ํ‘œ์‹œํ•˜๊ณ , ''CENTER_BOTH''๋Š” ๊ฒŒ์ž„์„ ํ™”๋ฉด ์ค‘์•™์— ๋ฐฐ์น˜ํ•ฉ๋‹ˆ๋‹ค.ย 
 +  * ''Phaser.Game ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ'': ์œ„์—์„œ ์ •์˜ํ•œ ''config'' ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ƒˆ๋กœ์šด Phaser ๊ฒŒ์ž„ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ์ด ์ธ์Šคํ„ด์Šค๊ฐ€ ์‹ค์ œ ๊ฒŒ์ž„์„ ์‹คํ–‰ํ•˜๋Š” ์ฃผ์ฒด์ž…๋‹ˆ๋‹ค.ย 
 +  * ''export default game'': ์ด ๊ฒŒ์ž„ ์ธ์Šคํ„ด์Šค๋ฅผ ๋‹ค๋ฅธ JavaScript ํŒŒ์ผ์—์„œ ๋ถˆ๋Ÿฌ์™€ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๋‚ด๋ณด๋ƒ…๋‹ˆ๋‹ค.ย 
 +ย 
 +----ย 
 +==== 2. ์”ฌ(Scene) ๊ด€๋ฆฌ ๋ฐ ์ „ํ™˜ ====
  
-===== ๐ŸŽฏ ์”ฌ(Scene) ๊ด€๋ฆฌ =====+Phaser.js์—์„œ ''์”ฌ(Scene)''์€ ๊ฒŒ์ž„์˜ ํŠน์ • ์ƒํƒœ๋‚˜ ํ™”๋ฉด์„ ๋‚˜ํƒ€๋‚ด๋Š” ๋…๋ฆฝ์ ์ธ ๋‹จ์œ„์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ๊ฒŒ์ž„์˜ ๋ฉ”๋‰ด ํ™”๋ฉด, ์‹ค์ œ ๊ฒŒ์ž„ ํ”Œ๋ ˆ์ด ํ™”๋ฉด, ๊ฒŒ์ž„ ์˜ค๋ฒ„ ํ™”๋ฉด ๋“ฑ์ด ๊ฐ๊ฐ์˜ ์”ฌ์œผ๋กœ ๊ตฌํ˜„๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์”ฌ์€ ๊ฒŒ์ž„์˜ ๋กœ๋“œ, ์ƒ์„ฑ, ์—…๋ฐ์ดํŠธ, ์ข…๋ฃŒ ๋“ฑ ์ƒ๋ช…์ฃผ๊ธฐ๋ฅผ ๊ฐ€์ง‘๋‹ˆ๋‹ค.
  
-**๋ฉ”๋‰ด ์”ฌ (MenuScene.js):**ย +=== 2) ๋ฉ”๋‰ด ์”ฌ (MenuScene.js) ===ย 
-<code javascript>+ย 
 +''MenuScene.js''๋Š” ๊ฒŒ์ž„์ด ์‹œ์ž‘๋  ๋•Œ ๊ฐ€์žฅ ๋จผ์ € ์‚ฌ์šฉ์ž์—๊ฒŒ ๋ณด์—ฌ์ง€๋Š” ๋ฉ”๋‰ด ํ™”๋ฉด์„ ๋‹ด๋‹นํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ๋Š” ๊ฒŒ์ž„ ์‹œ์ž‘ ๋ฒ„ํŠผ, ์„ค์ • ๋ฒ„ํŠผ ๋“ฑ์„ ๋ฐฐ์น˜ํ•˜๊ณ , ์‚ฌ์šฉ์ž์˜ ์ž…๋ ฅ์— ๋”ฐ๋ผ ๋‹ค๋ฅธ ์”ฌ์œผ๋กœ ์ „ํ™˜ํ•˜๋Š” ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค.ย 
 +ย 
 +<file javascript>
 import Phaser from 'phaser'; import Phaser from 'phaser';
  
 export default class MenuScene extends Phaser.Scene { export default class MenuScene extends Phaser.Scene {
     constructor() {     constructor() {
-        super({ key: 'MenuScene' });+        super({ key: 'MenuScene' }); // ์”ฌ์˜ ๊ณ ์œ  ํ‚ค ์ •์˜
     }     }
  
     preload() {     preload() {
-        // ๋ฉ”๋‰ด ๋ฐฐ๊ฒฝ ๋ฐ ๋ฒ„ํŠผ ์ด๋ฏธ์ง€ ๋กœ๋“œ+        // 1. ํ•„์š”ํ•œ ์ด๋ฏธ์ง€ ์—์…‹ ๋กœ๋“œ
         this.load.image('menu-bg', 'assets/menu-background.png');         this.load.image('menu-bg', 'assets/menu-background.png');
         this.load.image('play-button', 'assets/play-button.png');         this.load.image('play-button', 'assets/play-button.png');
์ค„ 58: ์ค„ 92:
  
     create() {     create() {
-        // ๋ฐฐ๊ฒฝ ์„ค์ •+        // 2. ๋ฐฐ๊ฒฝ ์ด๋ฏธ์ง€ ์ถ”๊ฐ€ (ํ™”๋ฉด ์ค‘์•™์— ๋ฐฐ์น˜)
         this.add.image(600, 400, 'menu-bg');         this.add.image(600, 400, 'menu-bg');
                  
-        // ์ œ๋ชฉ ํ…์ŠคํŠธย +        // 3. ๊ฒŒ์ž„ ์ œ๋ชฉ ํ…์ŠคํŠธ ์ถ”๊ฐ€ย 
-        this.add.text(600, 200, '๋ฐ”๋‘‘ ๋ฉ”ํƒ€๋ฒ„์Šค', {+        this.add.text(600, 200, '๋ฐ”๋‘‘ ๋ฉ”ํƒ€๋ฒ„์Šค',// x, y, ํ…์ŠคํŠธ, ์Šคํƒ€์ผ
             fontSize: '48px',             fontSize: '48px',
-            fill: '#ffffff',+            fill: '#ffffff', // ํฐ์ƒ‰ ๊ธ€์ž
             fontFamily: 'Arial'             fontFamily: 'Arial'
-        }).setOrigin(0.5);ย +        }).setOrigin(0.5); // ํ…์ŠคํŠธ์˜ ๊ธฐ์ค€์ ์„ ์ค‘์•™์œผ๋กœ ์„ค์ •ย 
-        ย +ย 
-        // ํ”Œ๋ ˆ์ด ๋ฒ„ํŠผ+        // 4. ํ”Œ๋ ˆ์ด ๋ฒ„ํŠผ ์ƒ์„ฑ ๋ฐ ์ƒํ˜ธ์ž‘์šฉ ์„ค์ •
         const playButton = this.add.image(600, 350, 'play-button')         const playButton = this.add.image(600, 350, 'play-button')
-            .setInteractive();+            .setInteractive(); // ํด๋ฆญ ๊ฐ€๋Šฅํ•˜๋„๋ก ์„ค์ •
                  
-        playButton.on('pointerdown', () => {ย +        playButton.on('pointerdown', () => { // ๋ฒ„ํŠผ ํด๋ฆญ ์‹œ ์ด๋ฒคํŠธย 
-            this.scene.start('BadukScene');+            this.scene.start('BadukScene'); // 'BadukScene'์œผ๋กœ ์ „ํ™˜
         });         });
                  
-        // ์„ค์ • ๋ฒ„ํŠผ+        // 5. ์„ค์ • ๋ฒ„ํŠผ ์ƒ์„ฑ ๋ฐ ์ƒํ˜ธ์ž‘์šฉ ์„ค์ •
         const settingsButton = this.add.image(600, 450, 'settings-button')         const settingsButton = this.add.image(600, 450, 'settings-button')
             .setInteractive();             .setInteractive();
                  
         settingsButton.on('pointerdown', () => {         settingsButton.on('pointerdown', () => {
-            // ์„ค์ • ์”ฌ์œผ๋กœ ์ด๋™ย +            console.log('์„ค์ • ๋ฉ”๋‰ด ์—ด๊ธฐ'); // ์„ค์ • ๊ธฐ๋Šฅ์€ ์ฝ˜์†” ๋กœ๊ทธ๋กœ ๋Œ€์ฒด
-            console.log('์„ค์ • ๋ฉ”๋‰ด ์—ด๊ธฐ');+
         });         });
     }     }
 } }
-</code>+</file>ย 
 +ย 
 +''์ฝ”๋“œ ์„ค๋ช…'':ย 
 +  * ''constructor'': ์”ฌ์˜ ๊ณ ์œ ํ•œ ํ‚ค(์—ฌ๊ธฐ์„œ๋Š” 'MenuScene')๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ๋‹ค๋ฅธ ์”ฌ์—์„œ ์ด ์”ฌ์„ ์ฐธ์กฐํ•  ๋•Œ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.ย 
 +  * ''preload()'': ์ด ์”ฌ์ด ์‹œ์ž‘๋˜๊ธฐ ์ „์— ํ•„์š”ํ•œ ๋ชจ๋“  ์ด๋ฏธ์ง€, ์˜ค๋””์˜ค ๋“ฑ์˜ ์—์…‹์„ ๋ฏธ๋ฆฌ ๋กœ๋“œํ•˜๋Š” ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค. ๊ฒŒ์ž„ ๋กœ๋”ฉ ์‹œ๊ฐ„์„ ๋‹จ์ถ•ํ•˜๊ณ , ์”ฌ์ด ์ค€๋น„๋˜์—ˆ์„ ๋•Œ ์ฆ‰์‹œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.ย 
 +  * ''create()'': ์”ฌ์˜ ์—์…‹ ๋กœ๋”ฉ์ด ์™„๋ฃŒ๋œ ํ›„, ๊ฒŒ์ž„ ์˜ค๋ธŒ์ ํŠธ(๋ฐฐ๊ฒฝ, ๋ฒ„ํŠผ, ํ…์ŠคํŠธ ๋“ฑ)๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ๋ฐฐ์น˜ํ•˜๋Š” ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค.ย 
 +    *   ''this.add.image()'': ๋ฐฐ๊ฒฝ ์ด๋ฏธ์ง€์™€ ๋ฒ„ํŠผ ์ด๋ฏธ์ง€๋ฅผ ํ™”๋ฉด์— ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.ย 
 +    *   ''this.add.text()'': ๊ฒŒ์ž„ ์ œ๋ชฉ ํ…์ŠคํŠธ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  ์Šคํƒ€์ผ์„ ์ ์šฉํ•ฉ๋‹ˆ๋‹ค. ''setOrigin(0.5)''๋Š” ํ…์ŠคํŠธ์˜ ์ค‘์•™์„ ๊ธฐ์ค€์œผ๋กœ ์œ„์น˜๋ฅผ ์žก๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.ย 
 +    *   ''setInteractive()'': ๋ฒ„ํŠผ ์ด๋ฏธ์ง€๋ฅผ ํด๋ฆญ ๊ฐ€๋Šฅํ•œ ์ƒํ˜ธ์ž‘์šฉ ๊ฐ์ฒด๋กœ ๋งŒ๋“ญ๋‹ˆ๋‹ค.ย 
 +    *   ''on('pointerdown', ...)'': ๋ฒ„ํŠผ์ด ํด๋ฆญ(๋˜๋Š” ํ„ฐ์น˜)๋˜์—ˆ์„ ๋•Œ ์‹คํ–‰๋  ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. ''this.scene.start('BadukScene')''์„ ํ†ตํ•ด ์‹ค์ œ ๋ฐ”๋‘‘ ๊ฒŒ์ž„ ์”ฌ์œผ๋กœ ์ „ํ™˜ํ•ฉ๋‹ˆ๋‹ค.ย 
 +ย 
 +----ย 
 +=== 2) ๋ฐ”๋‘‘ ๊ฒŒ์ž„ ์”ฌ (BadukScene.js) ===ย 
 +ย 
 +''BadukScene.js''๋Š” ๋ฐ”๋‘‘ ๊ฒŒ์ž„์˜ ํ•ต์‹ฌ ๋กœ์ง๊ณผ ์‚ฌ์šฉ์ž ์ธํ„ฐ๋ž™์…˜์ด ๊ตฌํ˜„๋˜๋Š” ์”ฌ์ž…๋‹ˆ๋‹ค. ๋ฐ”๋‘‘ํŒ, ๋ฐ”๋‘‘๋Œ์˜ ๋ฐฐ์น˜, ํด๋ฆญ ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ, ํ„ด ๊ด€๋ฆฌ, ๊ทธ๋ฆฌ๊ณ  ์„œ๋ฒ„์™€์˜ ํ†ต์‹  ๋“ฑ์„ ๋‹ด๋‹นํ•ฉ๋‹ˆ๋‹ค.
  
-**๋ฐ”๋‘‘ ๊ฒŒ์ž„ ์”ฌ (BadukScene.js):**ย +<file javascript>
-<code javascript>+
 import Phaser from 'phaser'; import Phaser from 'phaser';
-import BadukBoard from '../sprites/BadukBoard';ย +import BadukBoard from '../sprites/BadukBoard'; // ๋ฐ”๋‘‘ํŒ ์Šคํ”„๋ผ์ดํŠธ ์ž„ํฌํŠธย 
-import BadukStone from '../sprites/BadukStone';+import BadukStone from '../sprites/BadukStone'; // ๋ฐ”๋‘‘๋Œ ์Šคํ”„๋ผ์ดํŠธ ์ž„ํฌํŠธ
  
 export default class BadukScene extends Phaser.Scene { export default class BadukScene extends Phaser.Scene {
     constructor() {     constructor() {
         super({ key: 'BadukScene' });         super({ key: 'BadukScene' });
-        this.board = null;ย +        this.board = null; // ๋ฐ”๋‘‘ํŒ ๊ฐ์ฒดย 
-        this.stones = [];ย +        this.stones = [];  // ๋†“์—ฌ์ง„ ๋ฐ”๋‘‘๋Œ ๋ฐฐ์—ดย 
-        this.currentPlayer = 'black'; // 'black' ๋˜๋Š” 'white'+        this.currentPlayer = 'black'; // ํ˜„์žฌ ํ„ด ํ”Œ๋ ˆ์ด์–ด ('black' ๋˜๋Š” 'white')ย 
 +        this.gameId = null; // ํ˜„์žฌ ๊ฒŒ์ž„ ID
     }     }
  
     preload() {     preload() {
-        // ๋ฐ”๋‘‘ํŒ๊ณผ ๋Œ ์ด๋ฏธ์ง€ ๋กœ๋“œ+        // 1. ๋ฐ”๋‘‘ํŒ ๋ฐ ๋Œ ์ด๋ฏธ์ง€ ๋กœ๋“œ
         this.load.image('board', 'assets/baduk-board.png');         this.load.image('board', 'assets/baduk-board.png');
         this.load.image('black-stone', 'assets/black-stone.png');         this.load.image('black-stone', 'assets/black-stone.png');
         this.load.image('white-stone', 'assets/white-stone.png');         this.load.image('white-stone', 'assets/white-stone.png');
-        this.load.image('grid', 'assets/grid-lines.png');+        this.load.image('grid', 'assets/grid-lines.png'); // ๋ฐ”๋‘‘ํŒ ๊ทธ๋ฆฌ๋“œ ์ด๋ฏธ์ง€
     }     }
  
     create() {     create() {
-        // ๋ฐ”๋‘‘ํŒ ์ƒ์„ฑย +        // 2. ๋ฐ”๋‘‘ํŒ ์ƒ์„ฑ ๋ฐ ๊ทธ๋ฆฌ๋“œ ๋ผ์ธ ์ถ”๊ฐ€ย 
-        this.board = new BadukBoard(this, 600, 400);ย +        this.board = new BadukBoard(this, 600, 400); // BadukBoard ์Šคํ”„๋ผ์ดํŠธ ์ƒ์„ฑย 
-        ย +        this.add.existing(this.board); // ์”ฌ์— ๋ฐ”๋‘‘ํŒ ์ถ”๊ฐ€ย 
-        // ๊ทธ๋ฆฌ๋“œ ๋ผ์ธ ์ถ”๊ฐ€ย +        this.add.image(600, 400, 'grid'); // ๊ทธ๋ฆฌ๋“œ ๋ผ์ธ ์ด๋ฏธ์ง€ ์ถ”๊ฐ€ย 
-        this.add.image(600, 400, 'grid');ย +ย 
-        ย +        // 3. ํด๋ฆญ ์ด๋ฒคํŠธ ์„ค์ •: ๋ฐ”๋‘‘ํŒ ํด๋ฆญ ์‹œ ์ฐฉ์ˆ˜ ์ฒ˜๋ฆฌ
-        // ํด๋ฆญ ์ด๋ฒคํŠธ ์„ค์ •+
         this.input.on('pointerdown', (pointer) => {         this.input.on('pointerdown', (pointer) => {
             this.handleBoardClick(pointer);             this.handleBoardClick(pointer);
         });         });
                  
-        // ํ”Œ๋ ˆ์ด์–ด ํ‘œ์‹œ+        // 4. ํ˜„์žฌ ํ”Œ๋ ˆ์ด์–ด ํ‘œ์‹œ UI ์ƒ์„ฑ
         this.createPlayerIndicator();         this.createPlayerIndicator();
 +
 +        // 5. (์˜ต์…˜) ๊ฒŒ์ž„ ์‹œ์ž‘ ์‹œ ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ๊ฒŒ์ž„ ID ์ˆ˜์‹ 
 +        if (window.socket) {
 +            window.socket.on('game-start', (data) => {
 +                console.log('๊ฒŒ์ž„์ด ์‹œ์ž‘๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๊ฒŒ์ž„ ID:', data.gameId);
 +                this.gameId = data.gameId;
 +                // ๊ฒŒ์ž„ ์ƒํƒœ ๋™๊ธฐํ™” ๋ฐ ์‹œ์ž‘ ๋กœ์ง ์ถ”๊ฐ€ ๊ฐ€๋Šฅ
 +            });
 +            window.socket.on('game-update', (data) => {
 +                // ๋‹ค๋ฅธ ํ”Œ๋ ˆ์ด์–ด์˜ ์ฐฉ์ˆ˜ ์ •๋ณด ์ˆ˜์‹  ๋ฐ ์ฒ˜๋ฆฌ
 +                if (data.player !== this.currentPlayer) { // ์ž์‹ ์˜ ํ„ด์ด ์•„๋‹Œ ๊ฒฝ์šฐ์—๋งŒ ์ฒ˜๋ฆฌ
 +                    this.placeStone(data.x, data.y, data.player);
 +                }
 +            });
 +        }
     }     }
  
 +    // 6. ๋ฐ”๋‘‘ํŒ ํด๋ฆญ ์ฒ˜๋ฆฌ ํ•จ์ˆ˜
     handleBoardClick(pointer) {     handleBoardClick(pointer) {
-        const boardX = pointer.x - 600;ย +        // ํด๋ฆญ๋œ ํ”ฝ์…€ ์ขŒํ‘œ๋ฅผ ๋ฐ”๋‘‘ํŒ์˜ ์ƒ๋Œ€ ์ขŒํ‘œ๋กœ ๋ณ€ํ™˜ย 
-        const boardY = pointer.y - 400;+        const boardX = pointer.x - this.board.x;ย 
 +        const boardY = pointer.y - this.board.y;
                  
-        // ๋ฐ”๋‘‘ํŒ ์ขŒํ‘œ๋กœ ๋ณ€ํ™˜ย +        // ์ƒ๋Œ€ ์ขŒํ‘œ๋ฅผ ๊ทธ๋ฆฌ๋“œ(๋ฐ”๋‘‘ํŒ ์นธ) ์ขŒํ‘œ๋กœ ๋ณ€ํ™˜ย 
-        const gridX = Math.round(boardX / 40);ย +        const gridX = Math.round(boardX / this.board.gridSize+ 9// 0~18 ๋ฒ”์œ„๋กœ ์กฐ์ •ย 
-        const gridY = Math.round(boardY / 40);ย +        const gridY = Math.round(boardY / this.board.gridSize+ 9;ย 
-        ย +ย 
-        // ์œ ํšจํ•œ ์œ„์น˜์ธ์ง€ ํ™•์ธ+        // ์œ ํšจํ•œ ์ฐฉ์ˆ˜ ์œ„์น˜์ธ์ง€ ํ™•์ธ ํ›„ ๋Œ ๋†“๊ธฐ
         if (this.isValidMove(gridX, gridY)) {         if (this.isValidMove(gridX, gridY)) {
-            this.placeStone(gridX, gridY);+            this.placeStone(gridX, gridY, this.currentPlayer);
         }         }
     }     }
  
 +    // 7. ์ฐฉ์ˆ˜ ์œ„์น˜ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ
     isValidMove(x, y) {     isValidMove(x, y) {
-        // ๋ฐ”๋‘‘ํŒ ๋ฒ”์œ„ ๋‚ด์ธ์ง€ ํ™•์ธ+        // ๋ฐ”๋‘‘ํŒ ๋ฒ”์œ„ (0~18) ๋‚ด์ธ์ง€ ํ™•์ธ
         if (x < 0 || x > 18 || y < 0 || y > 18) {         if (x < 0 || x > 18 || y < 0 || y > 18) {
             return false;             return false;
์ค„ 150: ์ค„ 214:
             stone.gridX === x && stone.gridY === y             stone.gridX === x && stone.gridY === y
         );         );
 +        // TODO: ์ž์ถฉ, ์ฝ” ๊ทœ์น™ ๋“ฑ ์ถ”๊ฐ€์ ์ธ ๋ฐ”๋‘‘ ๊ทœ์น™ ๊ฒ€์‚ฌ ํ•„์š”
     }     }
  
-    placeStone(x, y) {ย +    // 8. ๋ฐ”๋‘‘๋Œ ๋†“๊ธฐ (์‹œ๊ฐ์  ์ฒ˜๋ฆฌ ๋ฐ ์ƒํƒœ ์—…๋ฐ์ดํŠธ)ย 
-        const stoneImage = this.currentPlayer === 'black' ? 'black-stone' : 'white-stone';ย +    placeStone(x, y, playerColor) {ย 
-        const stone = new BadukStone(this, x, y, this.currentPlayer);+        // ํ˜„์žฌ ํ„ด ํ”Œ๋ ˆ์ด์–ด์˜ ๋Œ ์ด๋ฏธ์ง€ ์„ ํƒย 
 +        const stoneImage = playerColor === 'black' ? 'black-stone' : 'white-stone';ย 
 +        // BadukStone ์Šคํ”„๋ผ์ดํŠธ ์ƒ์„ฑ (์• ๋‹ˆ๋ฉ”์ด์…˜ ํฌํ•จ)ย 
 +        const stone = new BadukStone(this, x, y, playerColor);
                  
-        this.stones.push(stone);+        this.stones.push(stone); // ๋†“์—ฌ์ง„ ๋Œ ๋ชฉ๋ก์— ์ถ”๊ฐ€
                  
-        // ํ”Œ๋ ˆ์ด์–ด ๋ณ€๊ฒฝ+        // ํ”Œ๋ ˆ์ด์–ด ํ„ด ๋ณ€๊ฒฝ (๋‹ค์Œ ํ„ด)
         this.currentPlayer = this.currentPlayer === 'black' ? 'white' : 'black';         this.currentPlayer = this.currentPlayer === 'black' ? 'white' : 'black';
                  
-        // UI ์—…๋ฐ์ดํŠธ+        // UI ์—…๋ฐ์ดํŠธ (ํ˜„์žฌ ํ”Œ๋ ˆ์ด์–ด ํ‘œ์‹œ)
         this.updatePlayerIndicator();         this.updatePlayerIndicator();
                  
-        // ์„œ๋ฒ„์— ์ด๋™ ์ „์†กย +        // ์„œ๋ฒ„์— ์ฐฉ์ˆ˜ ์ •๋ณด ์ „์†กย 
-        this.sendMoveToServer(x, y, this.currentPlayer);+        this.sendMoveToServer(x, y, playerColor);
     }     }
  
 +    // 9. ํ˜„์žฌ ํ”Œ๋ ˆ์ด์–ด ํ‘œ์‹œ UI ์ƒ์„ฑ
     createPlayerIndicator() {     createPlayerIndicator() {
         this.playerText = this.add.text(50, 50, 'ํ˜„์žฌ ํ”Œ๋ ˆ์ด์–ด: ํ‘๋Œ', {         this.playerText = this.add.text(50, 50, 'ํ˜„์žฌ ํ”Œ๋ ˆ์ด์–ด: ํ‘๋Œ', {
์ค„ 175: ์ค„ 244:
     }     }
  
 +    // 10. ํ˜„์žฌ ํ”Œ๋ ˆ์ด์–ด ํ‘œ์‹œ UI ์—…๋ฐ์ดํŠธ
     updatePlayerIndicator() {     updatePlayerIndicator() {
         const playerName = this.currentPlayer === 'black' ? 'ํ‘๋Œ' : '๋ฐฑ๋Œ';         const playerName = this.currentPlayer === 'black' ? 'ํ‘๋Œ' : '๋ฐฑ๋Œ';
์ค„ 180: ์ค„ 250:
     }     }
  
 +    // 11. ์„œ๋ฒ„์— ์ฐฉ์ˆ˜ ์ •๋ณด ์ „์†ก
     sendMoveToServer(x, y, player) {     sendMoveToServer(x, y, player) {
-        // Socket.IO๋ฅผ ํ†ตํ•ด ์„œ๋ฒ„์— ์ด๋™ ์ „์†กย +        if (window.socket && this.gameId) {ย 
-        if (window.socket) {ย +            window.socket.emit('move',// 'move' ์ด๋ฒคํŠธ๋กœ ์„œ๋ฒ„์— ๋ฐ์ดํ„ฐ ์ „์†ก
-            window.socket.emit('move', {+
                 x: x,                 x: x,
                 y: y,                 y: y,
                 player: player,                 player: player,
-                gameId: this.gameId+                gameId: this.gameId // ํ˜„์žฌ ๊ฒŒ์ž„ ID ํฌํ•จ
             });             });
         }         }
     }     }
 } }
-</code>+</file>
  
-===== ๐ŸŽจ ์Šคํ”„๋ผ์ดํŠธ(Sprite๊ตฌํ˜„ =====+''์ฝ”๋“œ ์„ค๋ช…'':ย 
 +  * ''constructor'': ์”ฌ์˜ ๊ณ ์œ  ํ‚ค๋ฅผ ์ •์˜ํ•˜๊ณ , ๋ฐ”๋‘‘ํŒ ๊ฐ์ฒด, ๋†“์ธ ๋Œ๋“ค์„ ์ €์žฅํ•  ๋ฐฐ์—ด, ํ˜„์žฌ ํ„ด ํ”Œ๋ ˆ์ด์–ด, ๊ฒŒ์ž„ ID์™€ ๊ฐ™์€ ๊ฒŒ์ž„ ์ƒํƒœ ๋ณ€์ˆ˜๋“ค์„ ์ดˆ๊ธฐํ™”ํ•ฉ๋‹ˆ๋‹ค.ย 
 +  * ''preload()'': ๋ฐ”๋‘‘ํŒ, ํ‘๋Œ, ๋ฐฑ๋Œ ์ด๋ฏธ์ง€ ๋“ฑ ๊ฒŒ์ž„ ํ”Œ๋ ˆ์ด์— ํ•„์š”ํ•œ ๋ชจ๋“  ์—์…‹์„ ๋กœ๋“œํ•ฉ๋‹ˆ๋‹ค.ย 
 +  * ''create()'':ย 
 +    *   ''this.board new BadukBoard(...)'': ์ปค์Šคํ…€ ''BadukBoard'' ์Šคํ”„๋ผ์ดํŠธ๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ์‹œ๊ฐ์ ์ธ ๋ฐ”๋‘‘ํŒ์„ ํ™”๋ฉด์— ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.ย 
 +    *   ''this.input.on('pointerdown', ...)'': ๋งˆ์šฐ์Šค ํด๋ฆญ(๋˜๋Š” ํ„ฐ์น˜) ์ด๋ฒคํŠธ๋ฅผ ๊ฐ์ง€ํ•˜์—ฌ ''handleBoardClick'' ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋„๋ก ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.ย 
 +    *   ''createPlayerIndicator()'': ํ˜„์žฌ ํ„ด์„ ํ‘œ์‹œํ•˜๋Š” UI ํ…์ŠคํŠธ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.ย 
 +    *   ''window.socket.on(...)'': Socket.IO๋ฅผ ํ†ตํ•ด ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ๊ฒŒ์ž„ ์‹œ์ž‘ ๋ฐ ๋‹ค๋ฅธ ํ”Œ๋ ˆ์ด์–ด์˜ ์ฐฉ์ˆ˜ ์ •๋ณด๋ฅผ ์‹ค์‹œ๊ฐ„์œผ๋กœ ์ˆ˜์‹ ํ•˜์—ฌ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.ย 
 +  * ''handleBoardClick(pointer)'': ์‚ฌ์šฉ์ž๊ฐ€ ๋ฐ”๋‘‘ํŒ์„ ํด๋ฆญํ–ˆ์„ ๋•Œ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. ํด๋ฆญ๋œ ํ™”๋ฉด ํ”ฝ์…€ ์ขŒํ‘œ๋ฅผ ๋ฐ”๋‘‘ํŒ์˜ ๊ทธ๋ฆฌ๋“œ ์ขŒํ‘œ(์˜ˆ: (0,0)์—์„œ (18,18)๊นŒ์ง€)๋กœ ๋ณ€ํ™˜ํ•˜๊ณ , ''isValidMove''๋ฅผ ํ†ตํ•ด ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ํ›„ ''placeStone''์„ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.ย 
 +  * ''isValidMove(x, y)'': ์ฃผ์–ด์ง„ ๊ทธ๋ฆฌ๋“œ ์ขŒํ‘œ๊ฐ€ ๋ฐ”๋‘‘ํŒ ๋ฒ”์œ„ ๋‚ด์— ์žˆ๋Š”์ง€, ๊ทธ๋ฆฌ๊ณ  ํ•ด๋‹น ์œ„์น˜์— ์ด๋ฏธ ๋Œ์ด ๋†“์—ฌ์žˆ๋Š”์ง€ ํ™•์ธํ•˜์—ฌ ์ฐฉ์ˆ˜ ๊ฐ€๋Šฅ ์—ฌ๋ถ€๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. (''TODO''์— ์–ธ๊ธ‰๋œ ๊ฒƒ์ฒ˜๋Ÿผ ์‹ค์ œ ๋ฐ”๋‘‘ ๊ทœ์น™์€ ๋” ๋ณต์žกํ•ฉ๋‹ˆ๋‹ค.)ย 
 +  * ''placeStone(x, y, playerColor)'':ย 
 +    *   ''new BadukStone(...)'': ''BadukStone'' ์Šคํ”„๋ผ์ดํŠธ๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ํ•ด๋‹น ์œ„์น˜์— ์‹œ๊ฐ์ ์œผ๋กœ ๋Œ์„ ๋†“์Šต๋‹ˆ๋‹ค. ์ด ๊ณผ์ •์—์„œ ๋Œ์ด ๋‚˜ํƒ€๋‚˜๋Š” ์• ๋‹ˆ๋ฉ”์ด์…˜์ด ํฌํ•จ๋ฉ๋‹ˆ๋‹ค.ย 
 +    *   ''this.stones.push(stone)'': ๋†“์—ฌ์ง„ ๋Œ์„ ''stones'' ๋ฐฐ์—ด์— ์ถ”๊ฐ€ํ•˜์—ฌ ๊ฒŒ์ž„ ์ƒํƒœ๋ฅผ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค.ย 
 +    *   ''this.currentPlayer ...'': ํ˜„์žฌ ํ”Œ๋ ˆ์ด์–ด์˜ ํ„ด์„ ํ‘๋Œ์—์„œ ๋ฐฑ๋Œ๋กœ, ๋˜๋Š” ๋ฐฑ๋Œ์—์„œ ํ‘๋Œ๋กœ ์ „ํ™˜ํ•ฉ๋‹ˆ๋‹ค.ย 
 +    *   ''updatePlayerIndicator()'': UI๋ฅผ ์—…๋ฐ์ดํŠธํ•˜์—ฌ ํ˜„์žฌ ํ„ด ํ”Œ๋ ˆ์ด์–ด๋ฅผ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.ย 
 +    *   ''sendMoveToServer()'': ๋†“์ธ ๋Œ์˜ ์ •๋ณด๋ฅผ ์„œ๋ฒ„๋กœ ์ „์†กํ•˜์—ฌ ๋‹ค๋ฅธ ํ”Œ๋ ˆ์ด์–ด์™€ ๊ฒŒ์ž„ ์ƒํƒœ๋ฅผ ๋™๊ธฐํ™”ํ•ฉ๋‹ˆ๋‹ค.ย 
 +  * ''createPlayerIndicator()'', ''updatePlayerIndicator()'': ํ˜„์žฌ ํ„ด ํ”Œ๋ ˆ์ด์–ด๋ฅผ ํ™”๋ฉด์— ํ…์ŠคํŠธ๋กœ ํ‘œ์‹œํ•˜๊ณ  ์—…๋ฐ์ดํŠธํ•˜๋Š” ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค.ย 
 +  * ''sendMoveToServer(x, y, player)'': Socket.IO๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ฐฉ์ˆ˜ ์ •๋ณด๋ฅผ ์„œ๋ฒ„์˜ 'move' ์ด๋ฒคํŠธ๋กœ ์ „์†กํ•ฉ๋‹ˆ๋‹ค. ๊ฒŒ์ž„ ID๋ฅผ ํ•จ๊ป˜ ๋ณด๋‚ด ํŠน์ • ๊ฒŒ์ž„ ์„ธ์…˜์— ๋Œ€ํ•œ ์ด๋™์ž„์„ ์•Œ๋ฆฝ๋‹ˆ๋‹ค.
  
-**๋ฐ”๋‘‘ํŒ ์Šคํ”„๋ผ์ดํŠธ (BadukBoard.js):**ย +----ย 
-<code javascript>+==== 3. ํ•ต์‹ฌ ์Šคํ”„๋ผ์ดํŠธ(Sprite) ๊ตฌํ˜„ ====ย 
 +ย 
 +Phaser.js์—์„œ ''์Šคํ”„๋ผ์ดํŠธ(Sprite)''๋Š” ๊ฒŒ์ž„ ๋‚ด์—์„œ ์›€์ง์ด๊ฑฐ๋‚˜ ์ƒํ˜ธ์ž‘์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์‹œ๊ฐ์ ์ธ ๊ฐ์ฒด๋ฅผ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ๋ฐ”๋‘‘ ๊ฒŒ์ž„์—์„œ๋Š” ๋ฐ”๋‘‘ํŒ๊ณผ ๋ฐ”๋‘‘๋Œ์ด ๊ฐ๊ฐ์˜ ์Šคํ”„๋ผ์ดํŠธ๋กœ ๊ตฌํ˜„๋˜์–ด ๊ฒŒ์ž„ ์„ธ๊ณ„ ๋‚ด์—์„œ ๋…๋ฆฝ์ ์œผ๋กœ ์กด์žฌํ•˜๋ฉฐ ํŠน์ • ๊ธฐ๋Šฅ์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.ย 
 +ย 
 +=== 3) ๋ฐ”๋‘‘ํŒ ์Šคํ”„๋ผ์ดํŠธ (BadukBoard.js) ===ย 
 +ย 
 +''BadukBoard.js''๋Š” ๋ฐ”๋‘‘ํŒ ์ด๋ฏธ์ง€๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ์Šคํ”„๋ผ์ดํŠธ์ž…๋‹ˆ๋‹ค. ๋‹จ์ˆœํžˆ ์ด๋ฏธ์ง€๋ฅผ ํ‘œ์‹œํ•˜๋Š” ๊ฒƒ์„ ๋„˜์–ด, ๋ฐ”๋‘‘ํŒ์˜ ๊ทธ๋ฆฌ๋“œ ์‹œ์Šคํ…œ์„ ๊ด€๋ฆฌํ•˜๊ณ  ํ”ฝ์…€ ์ขŒํ‘œ์™€ ๊ทธ๋ฆฌ๋“œ ์ขŒํ‘œ ๊ฐ„์˜ ๋ณ€ํ™˜์„ ์ฒ˜๋ฆฌํ•˜๋Š” ์ค‘์š”ํ•œ ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.ย 
 +ย 
 +<file javascript>
 import Phaser from 'phaser'; import Phaser from 'phaser';
  
 export default class BadukBoard extends Phaser.GameObjects.Sprite { export default class BadukBoard extends Phaser.GameObjects.Sprite {
     constructor(scene, x, y) {     constructor(scene, x, y) {
-        super(scene, x, y, 'board');+        super(scene, x, y, 'board'); // Phaser.GameObjects.Sprite ์ƒ์„ฑ์ž ํ˜ธ์ถœ
                  
-        this.setOrigin(0.5);ย +        this.setOrigin(0.5); // ์Šคํ”„๋ผ์ดํŠธ์˜ ๊ธฐ์ค€์ ์„ ์ค‘์•™์œผ๋กœ ์„ค์ •ย 
-        this.setInteractive();+        this.setInteractive(); // ์ƒํ˜ธ์ž‘์šฉ ๊ฐ€๋Šฅํ•˜๋„๋ก ์„ค์ • (ํด๋ฆญ ๋“ฑ)
                  
-        // ๋ฐ”๋‘‘ํŒ ํฌ๊ธฐ ์„ค์ •ย +        this.setScale(1.0); // ๋ฐ”๋‘‘ํŒ ํฌ๊ธฐ (์Šค์ผ€์ผ) ์„ค์ •
-        this.setScale(1.0);+
                  
-        // ๊ทธ๋ฆฌ๋“œ ์ขŒํ‘œ ์‹œ์Šคํ…œย +        // ๋ฐ”๋‘‘ํŒ ๊ทธ๋ฆฌ๋“œ ์ขŒํ‘œ ์‹œ์Šคํ…œ ์„ค์ •ย 
-        this.gridSize = 40;+        this.gridSize = 40; // ํ•œ ์นธ์˜ ํ”ฝ์…€ ํฌ๊ธฐ
         this.boardSize = 19; // 19x19 ๋ฐ”๋‘‘ํŒ         this.boardSize = 19; // 19x19 ๋ฐ”๋‘‘ํŒ
     }     }
  
-    // ๊ทธ๋ฆฌ๋“œ ์ขŒํ‘œ๋ฅผ ํ”ฝ์…€ ์ขŒํ‘œ๋กœ ๋ณ€ํ™˜+    // 1. ๊ทธ๋ฆฌ๋“œ ์ขŒํ‘œ(0~18)๋ฅผ ๊ฒŒ์ž„ ํ™”๋ฉด์˜ ํ”ฝ์…€ ์ขŒํ‘œ๋กœ ๋ณ€ํ™˜
     gridToPixel(gridX, gridY) {     gridToPixel(gridX, gridY) {
-        const pixelX = this.x + (gridX - 9) * this.gridSize;ย +        // ๋ฐ”๋‘‘ํŒ์˜ ์ค‘์•™์ด (0,0)์ด๋ผ๊ณ  ๊ฐ€์ •ํ•˜๊ณ , ๊ทธ๋ฆฌ๋“œ ์ขŒํ‘œ๋ฅผ ํ”ฝ์…€๋กœ ๋ณ€ํ™˜ย 
-        const pixelY = this.y + (gridY - 9) * this.gridSize;+        // ์˜ˆ: gridX 9๋Š” ๋ฐ”๋‘‘ํŒ์˜ ์ค‘์•™ x์ถ•์— ํ•ด๋‹นย 
 +        const pixelX = this.x + (gridX - (this.boardSize - 1) / 2) * this.gridSize;ย 
 +        const pixelY = this.y + (gridY - (this.boardSize - 1) / 2) * this.gridSize;
         return { x: pixelX, y: pixelY };         return { x: pixelX, y: pixelY };
     }     }
  
-    // ํ”ฝ์…€ ์ขŒํ‘œ๋ฅผ ๊ทธ๋ฆฌ๋“œ ์ขŒํ‘œ๋กœ ๋ณ€ํ™˜+    // 2. ๊ฒŒ์ž„ ํ™”๋ฉด์˜ ํ”ฝ์…€ ์ขŒํ‘œ๋ฅผ ๊ทธ๋ฆฌ๋“œ ์ขŒํ‘œ(0~18)๋กœ ๋ณ€ํ™˜
     pixelToGrid(pixelX, pixelY) {     pixelToGrid(pixelX, pixelY) {
-        const gridX = Math.round((pixelX - this.x) / this.gridSize) + 9;ย +        // ํ”ฝ์…€ ์ขŒํ‘œ๋ฅผ ๋ฐ”๋‘‘ํŒ ์ค‘์•™์„ ๊ธฐ์ค€์œผ๋กœ ํ•œ ์ƒ๋Œ€ ์ขŒํ‘œ๋กœ ๋ณ€ํ™˜ ํ›„ ๊ทธ๋ฆฌ๋“œ ํฌ๊ธฐ๋กœ ๋‚˜๋ˆ„์–ด ๊ทธ๋ฆฌ๋“œ ์ขŒํ‘œ ์–ป๊ธฐย 
-        const gridY = Math.round((pixelY - this.y) / this.gridSize) + 9;+        const gridX = Math.round((pixelX - this.x) / this.gridSize) + (this.boardSize - 1) / 2;ย 
 +        const gridY = Math.round((pixelY - this.y) / this.gridSize) + (this.boardSize - 1) / 2;
         return { x: gridX, y: gridY };         return { x: gridX, y: gridY };
     }     }
 } }
-</code>+</file>
  
-**๋ฐ”๋‘‘๋Œ ์Šคํ”„๋ผ์ดํŠธ (BadukStone.js):**ย +''์ฝ”๋“œ ์„ค๋ช…'':ย 
-<code javascript>+  ''constructor(scene, x, y)'':ย 
 +      ''super(scene, x, y, 'board')'': ๋ถ€๋ชจ ํด๋ž˜์Šค์ธ ''Phaser.GameObjects.Sprite''์˜ ์ƒ์„ฑ์ž๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ, ์ด ๊ฐ์ฒด๊ฐ€ 'board'๋ผ๋Š” ํ‚ค๋กœ ๋กœ๋“œ๋œ ์ด๋ฏธ์ง€๋ฅผ ์‚ฌ์šฉํ•˜๋„๋ก ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. ''x''์™€ ''y''๋Š” ๋ฐ”๋‘‘ํŒ ์Šคํ”„๋ผ์ดํŠธ์˜ ํ™”๋ฉด์ƒ ์œ„์น˜์ž…๋‹ˆ๋‹ค.ย 
 +    *   ''this.setOrigin(0.5)''์Šคํ”„๋ผ์ดํŠธ์˜ ์›์ (๊ธฐ์ค€์ )์„ ์ค‘์•™์œผ๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ''x'', ''y'' ์ขŒํ‘œ๊ฐ€ ์Šคํ”„๋ผ์ดํŠธ์˜ ์ค‘์•™์„ ๊ฐ€๋ฆฌํ‚ค๊ฒŒ ๋˜์–ด ์œ„์น˜ ๊ณ„์‚ฐ์ด ํŽธ๋ฆฌํ•ด์ง‘๋‹ˆ๋‹ค.ย 
 +      ''this.setInteractive()'': ์ด ์Šคํ”„๋ผ์ดํŠธ๊ฐ€ ๋งˆ์šฐ์Šค ํด๋ฆญ ๊ฐ™์€ ์‚ฌ์šฉ์ž ์ž…๋ ฅ ์ด๋ฒคํŠธ๋ฅผ ๊ฐ์ง€ํ•  ์ˆ˜ ์žˆ๋„๋ก ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.ย 
 +      ''this.gridSize'', ''this.boardSize'': ๋ฐ”๋‘‘ํŒ์˜ ํ•œ ์นธ(์ ๊ณผ ์  ์‚ฌ์ด)์˜ ํ”ฝ์…€ ํฌ๊ธฐ์™€ ๋ฐ”๋‘‘ํŒ์˜ ๊ฐ€๋กœ/์„ธ๋กœ ์นธ ์ˆ˜๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ํ”ฝ์…€ ์ขŒํ‘œ์™€ ๊ทธ๋ฆฌ๋“œ ์ขŒํ‘œ ๊ฐ„ ๋ณ€ํ™˜์— ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.ย 
 +  * ''gridToPixel(gridX, gridY)'': ๋ฐ”๋‘‘ํŒ์˜ ๊ทธ๋ฆฌ๋“œ ์ขŒํ‘œ(์˜ˆ: (0,0)๋ถ€ํ„ฐ (18,18)๊นŒ์ง€)๋ฅผ ๊ฒŒ์ž„ ํ™”๋ฉด ์ƒ์˜ ์‹ค์ œ ํ”ฝ์…€ ์ขŒํ‘œ๋กœ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ๋ฐ”๋‘‘๋Œ์„ ์ •ํ™•ํ•œ ์œ„์น˜์— ๋†“์„ ๋•Œ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.ย 
 +  * ''pixelToGrid(pixelX, pixelY)'': ๊ฒŒ์ž„ ํ™”๋ฉด ์ƒ์˜ ํ”ฝ์…€ ์ขŒํ‘œ๋ฅผ ๋ฐ”๋‘‘ํŒ์˜ ๊ทธ๋ฆฌ๋“œ ์ขŒํ‘œ๋กœ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ๋งˆ์šฐ์Šค๋ฅผ ํด๋ฆญํ–ˆ์„ ๋•Œ ์–ด๋А ์นธ์„ ํด๋ฆญํ–ˆ๋Š”์ง€ ์•Œ์•„๋‚ผ ๋•Œ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.ย 
 +ย 
 +----ย 
 +=== 3) ๋ฐ”๋‘‘๋Œ ์Šคํ”„๋ผ์ดํŠธ (BadukStone.js) ===ย 
 +ย 
 +''BadukStone.js''๋Š” ๊ฒŒ์ž„ ๋‚ด์—์„œ ํ‘๋Œ๊ณผ ๋ฐฑ๋Œ์„ ๋‚˜ํƒ€๋‚ด๋Š” ์Šคํ”„๋ผ์ดํŠธ์ž…๋‹ˆ๋‹ค. ์ด ํด๋ž˜์Šค๋Š” ๋Œ์˜ ์‹œ๊ฐ์ ์ธ ํ‘œํ˜„๋ฟ๋งŒ ์•„๋‹ˆ๋ผ, ์ฐฉ์ˆ˜ ์‹œ ์• ๋‹ˆ๋ฉ”์ด์…˜ ํšจ๊ณผ๋ฅผ ๋ถ€์—ฌํ•˜์—ฌ ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ํ–ฅ์ƒ์‹œํ‚ต๋‹ˆ๋‹ค.ย 
 +ย 
 +<file javascript>
 import Phaser from 'phaser'; import Phaser from 'phaser';
  
 export default class BadukStone extends Phaser.GameObjects.Sprite { export default class BadukStone extends Phaser.GameObjects.Sprite {
     constructor(scene, gridX, gridY, color) {     constructor(scene, gridX, gridY, color) {
 +        // ๋Œ ์ด๋ฏธ์ง€ ํ‚ค ์„ ํƒ ('black-stone' ๋˜๋Š” 'white-stone')
         const imageKey = color === 'black' ? 'black-stone' : 'white-stone';         const imageKey = color === 'black' ? 'black-stone' : 'white-stone';
 +        // ๋ฐ”๋‘‘ํŒ ๊ฐ์ฒด์˜ gridToPixel ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ทธ๋ฆฌ๋“œ ์ขŒํ‘œ๋ฅผ ํ”ฝ์…€ ์ขŒํ‘œ๋กœ ๋ณ€ํ™˜
         const { x, y } = scene.board.gridToPixel(gridX, gridY);         const { x, y } = scene.board.gridToPixel(gridX, gridY);
                  
-        super(scene, x, y, imageKey);+        super(scene, x, y, imageKey); // Phaser.GameObjects.Sprite ์ƒ์„ฑ์ž ํ˜ธ์ถœ
                  
-        this.gridX = gridX;ย +        this.gridX = gridX; // ๋Œ์˜ ๊ทธ๋ฆฌ๋“œ X ์ขŒํ‘œ ์ €์žฅย 
-        this.gridY = gridY;ย +        this.gridY = gridY; // ๋Œ์˜ ๊ทธ๋ฆฌ๋“œ Y ์ขŒํ‘œ ์ €์žฅย 
-        this.color = color;+        this.color = color; // ๋Œ์˜ ์ƒ‰์ƒ ์ €์žฅ
                  
-        this.setOrigin(0.5);ย +        this.setOrigin(0.5); // ๋Œ์˜ ๊ธฐ์ค€์ ์„ ์ค‘์•™์œผ๋กœ ์„ค์ •ย 
-        this.setScale(0.8);+        this.setScale(0.8); // ๋Œ์˜ ํฌ๊ธฐ(์Šค์ผ€์ผ) ์„ค์ •
                  
-        // ์• ๋‹ˆ๋ฉ”์ด์…˜ ํšจ๊ณผย +        // 1. ์ฐฉ์ˆ˜ ์‹œ ๋Œ์ด ์ปค์ง€๋Š” ์• ๋‹ˆ๋ฉ”์ด์…˜ ํšจ๊ณผ (์Šค์ผ€์ผ -> 0.8)ย 
-        this.setScale(0);ย +        this.setScale(0); // ์ฒ˜์Œ์—๋Š” ํฌ๊ธฐ๋ฅผ 0์œผ๋กœ ์„ค์ •ย 
-        scene.tweens.add({ย +        scene.tweens.add({ // ํŠธ์œˆ(์• ๋‹ˆ๋ฉ”์ด์…˜์ถ”๊ฐ€ย 
-            targets: this,ย +            targets: this, // ์• ๋‹ˆ๋ฉ”์ด์…˜ ์ ์šฉ ๋Œ€์ƒย 
-            scaleX: 0.8,ย +            scaleX: 0.8  // X์ถ• ์Šค์ผ€์ผ์„ 0.8๋กœย 
-            scaleY: 0.8,ย +            scaleY: 0.8  // Y์ถ• ์Šค์ผ€์ผ์„ 0.8
-            duration: 200,ย +
-            ease: 'Back.easeOut'ย +
-        });ย +
-        ย +
-        scene.add.existing(this);ย +
-    }ย +
-ย +
-    // ๋Œ ์ œ๊ฑฐ (์ฐฉ์ˆ˜)ย +
-    remove() {ย +
-        this.scene.tweens.add({ย +
-            targets: this,ย +
-            scaleX: 0,ย +
-            scaleY: 0,ย +
-            duration: 150,ย +
-            ease: 'Back.easeIn',ย +
-            onComplete: () => {ย +
-                this.destroy();ย +
-            }ย +
-        });ย +
-    }ย +
-}ย +
-</code>ย +
-ย +
-===== ๐Ÿ”Œ Socket.IO ํ†ต์‹  =====ย +
-ย +
-**์‹ค์‹œ๊ฐ„ ํ†ต์‹  ์„ค์ •:**ย +
-<code javascript>ย +
-// game.js์—์„œ Socket.IO ์—ฐ๊ฒฐย +
-import io from 'socket.io-client';ย +
-ย +
-const socket = io('http://localhost:3000');ย +
-ย +
-socket.on('connect', () => {ย +
-    console.log('์„œ๋ฒ„์— ์—ฐ๊ฒฐ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.');ย +
-});ย +
-ย +
-socket.on('game-update', (data) => {ย +
-    // ๋‹ค๋ฅธ ํ”Œ๋ ˆ์ด์–ด์˜ ์ด๋™ ์ฒ˜๋ฆฌย +
-    if (data.player !== currentPlayer) {ย +
-        scene.placeStoneFromServer(data.x, data.y, data.player);ย +
-    }ย +
-});ย +
-ย +
-socket.on('game-start', (data) => {ย +
-    console.log('๊ฒŒ์ž„์ด ์‹œ์ž‘๋˜์—ˆ์Šต๋‹ˆ๋‹ค.');ย +
-    scene.startGame(data.gameId);ย +
-});ย +
-ย +
-// ์ „์—ญ์—์„œ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•˜๋„๋ก ์„ค์ •ย +
-window.socket = socket;ย +
-</code>ย +
-ย +
-===== ๐ŸŽจ UI/UX ๊ตฌํ˜„ =====ย +
-ย +
-**๊ฒŒ์ž„ UI ์ปดํฌ๋„ŒํŠธ:**ย +
-<code javascript>ย +
-export default class GameUI {ย +
-    constructor(scene) {ย +
-        this.scene = scene;ย +
-        this.createUI();ย +
-    }ย +
-ย +
-    createUI() {ย +
-        // ํŒจ์Šค ๋ฒ„ํŠผย +
-        this.passButton = this.scene.add.text(50, 150, 'ํŒจ์Šค', {ย +
-            fontSize: '20px',ย +
-            fill: '#ffffff',ย +
-            backgroundColor: '#e74c3c',ย +
-            padding: { x: 10, y: 5 }ย +
-        }).setInteractive();ย +
-        ย +
-        this.passButton.on('pointerdown', () => {ย +
-            this.handlePass();ย +
-        });ย +
-        ย +
-        // ํ•ญ๋ณต ๋ฒ„ํŠผย +
-        this.surrenderButton = this.scene.add.text(50, 200, 'ํ•ญ๋ณต', {ย +
-            fontSize: '20px',ย +
-            fill: '#ffffff',ย +
-            backgroundColor: '#c0392b',ย +
-            padding: { x: 10, y: 5 }ย +
-        }).setInteractive();ย +
-        ย +
-        this.surrenderButton.on('pointerdown', () => {ย +
-            this.handleSurrender();ย +
-        });ย +
-        ย +
-        // ์ ์ˆ˜ ํ‘œ์‹œย +
-        this.scoreText = this.scene.add.text(50, 250, '์ ์ˆ˜: 0 - 0', {ย +
-            fontSize: '18px',ย +
-            fill: '#ffffff'ย +
-        });ย +
-    }ย +
-ย +
-    handlePass() {ย +
-        // ํŒจ์Šค ์ฒ˜๋ฆฌย +
-        if (window.socket) {ย +
-            window.socket.emit('pass', {ย +
-                gameId: this.scene.gameId,ย +
-                player: this.scene.currentPlayerย +
-            });ย +
-        }ย +
-    }ย +
-ย +
-    handleSurrender() {ย +
-        // ํ•ญ๋ณต ์ฒ˜๋ฆฌย +
-        if (window.socket) {ย +
-            window.socket.emit('surrender', {ย +
-                gameId: this.scene.gameId,ย +
-                player: this.scene.currentPlayerย +
-            });ย +
-        }ย +
-    }ย +
-ย +
-    updateScore(blackScore, whiteScore) {ย +
-        this.scoreText.setText(`์ ์ˆ˜: ${blackScore} - ${whiteScore}`);ย +
-    }ย +
-}ย +
-</code>ย +
-ย +
-===== ๐ŸŽฎ ๊ฒŒ์ž„ ๋กœ์ง =====ย +
-ย +
-**๋ฐ”๋‘‘ ๊ทœ์น™ ๊ตฌํ˜„:**ย +
-<code javascript>ย +
-export default class BadukRules {ย +
-    constructor() {ย +
-        this.board = Array(19).fill().map(() => Array(19).fill(null));ย +
-        this.capturedStones = { black: 0, white: 0 };ย +
-    }ย +
-ย +
-    // ๋Œ ๋†“๊ธฐย +
-    placeStone(x, y, color) {ย +
-        if (this.isValidMove(xy, color)) {ย +
-            this.board[y][x] = color;ย +
-            ย +
-            // ์ฐฉ์ˆ˜ ํ™•์ธย +
-            const captured = this.checkCapture(x, y, color);ย +
-            this.capturedStones[color] += captured;ย +
-            ย +
-            return true;ย +
-        }ย +
-        return false;ย +
-    }ย +
-ย +
-    // ์œ ํšจํ•œ ์ด๋™์ธ์ง€ ํ™•์ธย +
-    isValidMove(x, y, color) {ย +
-        if (x < || x >= 19 || y < 0 || y >= 19) {ย +
-            return false;ย +
-        }ย +
-        ย +
-        if (this.board[y][x] !== null) {ย +
-            return false;ย +
-        }ย +
-        ย +
-        // ์ž์ถฉ ํ™•์ธย +
-        this.board[y][x] = color;ย +
-        const hasLiberties = this.hasLiberties(x, y);ย +
-        this.board[y][x] = null;ย +
-        ย +
-        return hasLiberties;ย +
-    }ย +
-ย +
-    // ์ž์œ ๋„ ํ™•์ธย +
-    hasLiberties(x, y) {ย +
-        const color = this.board[y][x];ย +
-        const visited = new Set();ย +
-        ย +
-        return this.checkGroupLiberties(x, y, color, visited);ย +
-    }ย +
-ย +
-    checkGroupLiberties(x, y, color, visited) {ย +
-        const key = `${x},${y}`;ย +
-        if (visited.has(key)) return false;ย +
-        visited.add(key);ย +
-        ย +
-        // ์ƒํ•˜์ขŒ์šฐ ํ™•์ธย +
-        const directions = [[0, 1], [0, -1], [1, 0], [-1, 0]];ย +
-        ย +
-        for (const [dx, dy] of directions) {ย +
-            const nx = x + dx;ย +
-            const ny = y + dy;ย +
-            ย +
-            if (nx < 0 || nx >= 19 || ny < 0 || ny >= 19) {ย +
-                continue;ย +
-            }ย +
-            ย +
-            if (this.board[ny][nx] === null) {ย +
-                return true; // ์ž์œ ๋„ ๋ฐœ๊ฒฌย +
-            }ย +
-            ย +
-            if (this.board[ny][nx] === color) {ย +
-                if (this.checkGroupLiberties(nxny, color, visited)) {ย +
-                    return true;ย +
-                }ย +
-            }ย +
-        }ย +
-        ย +
-        return false;ย +
-    }ย +
-ย +
-    // ์ฐฉ์ˆ˜ ํ™•์ธย +
-    checkCapture(x, y, color) {ย +
-        const directions = [[0, 1], [0, -1], [1, 0], [-1, 0]];ย +
-        let captured = 0;ย +
-        ย +
-        for (const [dx, dy] of directions) {ย +
-            const nx = x + dx;ย +
-            const ny = y + dy;ย +
-            ย +
-            if (nx < 0 || nx >= 19 || ny < 0 || ny >= 19) {ย +
-                continue;ย +
-            }ย +
-            ย +
-            const opponentColor = color === 'black' ? 'white' : 'black';ย +
-            ย +
-            if (this.board[ny][nx] === opponentColor) {ย +
-                if (!this.hasLiberties(nx, ny)) {ย +
-                    captured += this.removeGroup(nx, ny);ย +
-                }ย +
-            }ย +
-        }ย +
-        ย +
-        return captured;ย +
-    }ย +
-ย +
-    // ๊ทธ๋ฃน ์ œ๊ฑฐย +
-    removeGroup(x, y) {ย +
-        const color = this.board[y][x];ย +
-        if (!color) return 0;ย +
-        ย +
-        let count = 0;ย +
-        const stack = [[x, y]];ย +
-        ย +
-        while (stack.length > 0) {ย +
-            const [cx, cy] = stack.pop();ย +
-            ย +
-            if (this.board[cy][cx] === color) {ย +
-                this.board[cy][cx] = null;ย +
-                count++;ย +
-                ย +
-                const directions = [[0, 1], [0, -1], [1, 0], [-1, 0]];ย +
-                for (const [dx, dy] of directions) {ย +
-                    const nx = cx + dx;ย +
-                    const ny = cy + dy;ย +
-                    ย +
-                    if (nx >= 0 && nx < 19 && ny >= 0 && ny < 19) {ย +
-                        if (this.board[ny][nx] === color) {ย +
-                            stack.push([nx, ny]);ย +
-                        }ย +
-                    }ย +
-                }ย +
-            }ย +
-        }ย +
-        ย +
-        return count;ย +
-    }ย +
-}ย +
-</code>ย +
-ย +
-===== ๐Ÿ“š ๊ด€๋ จ ๋ฌธ์„œ =====ย +
-ย +
-  * [[wiki:it:dream_of_enc:metaverse:game_logic|๋ฐ”๋‘‘ ๊ฒŒ์ž„ ๋กœ์ง]]ย +
-  * [[wiki:it:dream_of_enc:metaverse:ui|UI/UX ๊ตฌํ˜„]]ย +
-  * [[wiki:it:dream_of_enc:metaverse:socketio|Socket.IO ์‹ค์‹œ๊ฐ„ ํ†ต์‹ ]]+
  
---- 
-//์ด ํŽ˜์ด์ง€๋Š” ์ž๋™์œผ๋กœ ์ƒ์„ฑ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.//  
wiki/it/dream_of_enc/metaverse/phaser.1753682235.txt.gz ยท ๋งˆ์ง€๋ง‰์œผ๋กœ ์ˆ˜์ •๋จ: ์ €์ž 127.0.0.1

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki