mango / index.html
kimhyunwoo's picture
Update index.html
75f3231 verified
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>๋ง๊ณ  ํ•ฉ์น˜๊ธฐ ๊ฒŒ์ž„</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/matter-js/0.19.0/matter.min.js"></script>
<style>
body {
margin: 0;
padding: 0;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100vh;
background-color: #FFF3E0; /* ์—ฐํ•œ ๋ง๊ณ ์ƒ‰ ๋ฐฐ๊ฒฝ */
font-family: 'Arial', sans-serif;
overflow: hidden; /* ์Šคํฌ๋กค ๋ฐฉ์ง€ */
touch-action: none; /* ๋ชจ๋ฐ”์ผ์—์„œ ๋ถˆํ•„์š”ํ•œ ์Šคํฌ๋กค/์คŒ ๋ฐฉ์ง€ */
}
#game-container {
position: relative;
border: 2px solid #FFA000; /* ์ง„ํ•œ ๋ง๊ณ ์ƒ‰ ํ…Œ๋‘๋ฆฌ */
background-color: #FFECB3; /* ๊ฒŒ์ž„ ์˜์—ญ ๋ฐฐ๊ฒฝ */
box-shadow: 0 0 10px rgba(0,0,0,0.2);
border-radius: 10px;
overflow: hidden; /* ๋‚ด๋ถ€ ์š”์†Œ๊ฐ€ ๋„˜์น˜์ง€ ์•Š๋„๋ก */
}
canvas {
display: block;
background-color: transparent; /* ์บ”๋ฒ„์Šค ์ž์ฒด ๋ฐฐ๊ฒฝ์€ ํˆฌ๋ช…ํ•˜๊ฒŒ */
}
#ui-container {
display: flex;
justify-content: space-around;
align-items: center;
width: 100%;
max-width: 400px; /* ๊ฒŒ์ž„ ์ปจํ…Œ์ด๋„ˆ ๋„ˆ๋น„์— ๋งž์ถค */
padding: 10px 0;
color: #E65100; /* UI ํ…์ŠคํŠธ ์ƒ‰์ƒ */
}
#score-board, #next-mango-preview {
font-size: 1.2em;
font-weight: bold;
}
#game-over-message {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: rgba(0, 0, 0, 0.7);
color: white;
padding: 20px;
border-radius: 10px;
text-align: center;
font-size: 1.5em;
display: none; /* ์ดˆ๊ธฐ์—๋Š” ์ˆจ๊น€ */
z-index: 100;
}
#game-over-message button {
padding: 10px 20px;
font-size: 0.8em;
margin-top: 15px;
background-color: #FFA000;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
}
</style>
</head>
<body>
<div id="ui-container">
<div id="score-board">์ ์ˆ˜: 0</div>
<div id="next-mango-preview">๋‹ค์Œ ๋ง๊ณ : ?</div>
</div>
<div id="game-container">
<canvas id="game-canvas"></canvas>
<div id="game-over-message">
๊ฒŒ์ž„ ์˜ค๋ฒ„!<br>
์ตœ์ข… ์ ์ˆ˜: <span id="final-score">0</span>
<button onclick="restartGame()">๋‹ค์‹œ ์‹œ์ž‘</button>
</div>
</div>
<script>
// Matter.js ๋ชจ๋“ˆ
const { Engine, Render, Runner, Bodies, Composite, Events, Mouse, MouseConstraint, Body } = Matter;
// ๊ฒŒ์ž„ ์„ค์ •
const gameContainer = document.getElementById('game-container');
const canvas = document.getElementById('game-canvas');
const scoreBoard = document.getElementById('score-board');
const nextMangoPreview = document.getElementById('next-mango-preview');
const gameOverMessage = document.getElementById('game-over-message');
const finalScoreDisplay = document.getElementById('final-score');
// ํ™”๋ฉด ํฌ๊ธฐ์— ๋งž๊ฒŒ ์บ”๋ฒ„์Šค ํฌ๊ธฐ ๋™์  ์กฐ์ ˆ
let canvasWidth = Math.min(window.innerWidth * 0.95, 400); // ํ™”๋ฉด ๋„ˆ๋น„์˜ 95% ๋˜๋Š” ์ตœ๋Œ€ 400px
let canvasHeight = Math.min(window.innerHeight * 0.7, 600); // ํ™”๋ฉด ๋†’์ด์˜ 70% ๋˜๋Š” ์ตœ๋Œ€ 600px
gameContainer.style.width = `${canvasWidth}px`;
gameContainer.style.height = `${canvasHeight}px`;
canvas.width = canvasWidth;
canvas.height = canvasHeight;
// ๋ง๊ณ  ์ข…๋ฅ˜ ์ •์˜ (ํฌ๊ธฐ, ์ƒ‰์ƒ, ์ ์ˆ˜)
const MANGO_TYPES = [
{ radius: canvasWidth * 0.035, color: '#FFF9C4', score: 10, label: '์• ํ”Œ๋ง๊ณ  ์”จ์•—' }, // ๋งค์šฐ ์ž‘์Œ
{ radius: canvasWidth * 0.045, color: '#FFF176', score: 20, label: '๋ฏธ๋‹ˆ ๋ง๊ณ ' },
{ radius: canvasWidth * 0.06, color: '#FFEE58', score: 40, label: '์ž‘์€ ๋ง๊ณ ' },
{ radius: canvasWidth * 0.075, color: '#FFD54F', score: 80, label: '๋ง๊ณ ' },
{ radius: canvasWidth * 0.09, color: '#FFC107', score: 160, label: '์ž˜์ต์€ ๋ง๊ณ ' },
{ radius: canvasWidth * 0.11, color: '#FFA000', score: 320, label: 'ํŠน๋Œ€ ๋ง๊ณ ' },
{ radius: canvasWidth * 0.13, color: '#FF8F00', score: 640, label: '์ ๋ณด ๋ง๊ณ ' },
{ radius: canvasWidth * 0.15, color: '#FF6F00', score: 1280, label: 'ํ‚น ๋ง๊ณ ' },
{ radius: canvasWidth * 0.18, color: '#E65100', score: 2560, label: '๊ณจ๋“  ํ‚น๋ง๊ณ ' } // ๊ฐ€์žฅ ํฐ ๋ง๊ณ 
];
let engine, render, runner;
let currentDroppingMango = null;
let nextMangoTypeIndex = 0;
let score = 0;
let gameOver = false;
let canDrop = true; // ๋“œ๋ž ์ฟจํƒ€์ž„
const DROP_COOLDOWN = 300; // ms
const gameOverLineY = canvasHeight * 0.15; // ์ด ์„  ์œ„๋กœ ๋ง๊ณ ๊ฐ€ ์Œ“์ด๋ฉด ๊ฒŒ์ž„ ์˜ค๋ฒ„
function initGame() {
gameOver = false;
score = 0;
updateScoreDisplay();
gameOverMessage.style.display = 'none';
canDrop = true;
// Matter.js ์—”์ง„ ์ƒ์„ฑ
engine = Engine.create();
engine.world.gravity.y = 0.9; // ์ค‘๋ ฅ ์„ค์ •
// Matter.js ๋ Œ๋”๋Ÿฌ ์ƒ์„ฑ
render = Render.create({
canvas: canvas,
engine: engine,
options: {
width: canvasWidth,
height: canvasHeight,
wireframes: false, // ์ƒ‰์ƒ ์ฑ„์šฐ๊ธฐ
background: 'transparent' // game-container ๋ฐฐ๊ฒฝ์ƒ‰์„ ์‚ฌ์šฉ
}
});
// ๋ฒฝ๊ณผ ๋ฐ”๋‹ฅ ์ƒ์„ฑ
const wallOptions = { isStatic: true, render: { fillStyle: '#BCAAA4' } }; // ์—ฐ๊ฐˆ์ƒ‰ ๋ฒฝ
Composite.add(engine.world, [
Bodies.rectangle(canvasWidth / 2, canvasHeight + 25, canvasWidth, 50, wallOptions), // ๋ฐ”๋‹ฅ (๋„‰๋„‰ํ•˜๊ฒŒ ์•„๋ž˜๋กœ)
Bodies.rectangle(-25, canvasHeight / 2, 50, canvasHeight, wallOptions), // ์™ผ์ชฝ ๋ฒฝ
Bodies.rectangle(canvasWidth + 25, canvasHeight / 2, 50, canvasHeight, wallOptions) // ์˜ค๋ฅธ์ชฝ ๋ฒฝ
]);
// ๊ฒŒ์ž„ ์˜ค๋ฒ„ ๋ผ์ธ (์‹œ๊ฐ์  ํ‘œ์‹œ๋Š” ์•ˆํ•จ, ํŒ์ •์šฉ)
// Bodies.rectangle(canvasWidth / 2, gameOverLineY, canvasWidth, 2, { isStatic: true, isSensor: true, render: {fillStyle: 'red' }})
// ๋‹ค์Œ ๋ง๊ณ  ์ค€๋น„
prepareNextMango();
updateNextMangoPreview();
// ์—”์ง„ ์‹คํ–‰
runner = Runner.create();
Runner.run(runner, engine);
Render.run(render);
// ์ถฉ๋Œ ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ
Events.on(engine, 'collisionStart', handleCollision);
// ๋งˆ์šฐ์Šค/ํ„ฐ์น˜ ์ด๋ฒคํŠธ
gameContainer.addEventListener('click', handleDropInput);
gameContainer.addEventListener('mousemove', handleMouseMove);
gameContainer.addEventListener('touchmove', handleTouchMove, { passive: false }); // passive false๋กœ ์Šคํฌ๋กค ๋ฐฉ์ง€
gameContainer.addEventListener('touchend', handleDropInput);
// ๊ฒŒ์ž„ ๋ฃจํ”„ (๊ฒŒ์ž„์˜ค๋ฒ„ ์ฒดํฌ ๋“ฑ)
Events.on(engine, 'afterUpdate', checkGameOver);
// ํ˜„์žฌ ๋–จ์–ด๋œจ๋ฆด ๋ง๊ณ  ์ƒ์„ฑ
spawnDroppingMango();
}
function spawnDroppingMango() {
if (gameOver || !canDrop) return;
const mangoType = MANGO_TYPES[nextMangoTypeIndex];
const x = Math.max(mangoType.radius, Math.min(canvasWidth - mangoType.radius, canvasWidth / 2)); // ์ค‘์•™์—์„œ ์‹œ์ž‘
currentDroppingMango = Bodies.circle(x, mangoType.radius * 1.5, mangoType.radius, {
isStatic: true, // ๋–จ์–ด์ง€๊ธฐ ์ „์—๋Š” ๊ณ ์ •
restitution: 0.2,
friction: 0.5,
label: 'droppingMango',
mangoIndex: nextMangoTypeIndex,
render: {
fillStyle: mangoType.color,
strokeStyle: '#5D4037', // ๋ง๊ณ  ํ…Œ๋‘๋ฆฌ
lineWidth: 2
}
});
Composite.add(engine.world, currentDroppingMango);
prepareNextMango();
updateNextMangoPreview();
}
function prepareNextMango() {
// ์ฒ˜์Œ ๋ช‡ ๊ฐœ๋Š” ์ž‘์€ ๋ง๊ณ  ์œ„์ฃผ๋กœ
if (Composite.allBodies(engine.world).filter(b => b.label === 'mango').length < 5) {
nextMangoTypeIndex = Math.floor(Math.random() * 3); // 0, 1, 2 ์ค‘ ํ•˜๋‚˜
} else {
nextMangoTypeIndex = Math.floor(Math.random() * 5); // 0, 1, 2, 3, 4 ์ค‘ ํ•˜๋‚˜
}
}
function updateNextMangoPreview() {
if (gameOver) {
nextMangoPreview.textContent = "๋‹ค์Œ ๋ง๊ณ : -";
return;
}
const nextType = MANGO_TYPES[nextMangoTypeIndex];
// ์ด๋ชจ์ง€๋กœ ํ‘œํ˜„ํ•˜๊ฑฐ๋‚˜, ์ƒ‰์ƒ ์›์œผ๋กœ ํ‘œํ˜„ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
nextMangoPreview.innerHTML = `๋‹ค์Œ: <span style="color:${nextType.color}; font-size:1.2em;">โ—</span> ${nextType.label.split(' ')[0]}`;
}
function handleMouseMove(event) {
if (gameOver || !currentDroppingMango || !currentDroppingMango.isStatic) return;
const rect = canvas.getBoundingClientRect();
let x = event.clientX - rect.left;
const radius = MANGO_TYPES[currentDroppingMango.mangoIndex].radius;
x = Math.max(radius, Math.min(canvasWidth - radius, x)); // ์บ”๋ฒ„์Šค ๊ฒฝ๊ณ„ ์•ˆ์œผ๋กœ ์ œํ•œ
Body.setPosition(currentDroppingMango, { x: x, y: currentDroppingMango.position.y });
}
function handleTouchMove(event) {
if (gameOver || !currentDroppingMango || !currentDroppingMango.isStatic) return;
event.preventDefault(); // ์Šคํฌ๋กค ๋ฐฉ์ง€
const rect = canvas.getBoundingClientRect();
let x = event.touches[0].clientX - rect.left;
const radius = MANGO_TYPES[currentDroppingMango.mangoIndex].radius;
x = Math.max(radius, Math.min(canvasWidth - radius, x));
Body.setPosition(currentDroppingMango, { x: x, y: currentDroppingMango.position.y });
}
function handleDropInput(event) {
if (gameOver || !currentDroppingMango || !canDrop || !currentDroppingMango.isStatic) return;
Body.setStatic(currentDroppingMango, false); // ๋ง๊ณ ๋ฅผ ๋–จ์–ด๋œจ๋ฆผ
currentDroppingMango.label = 'mango'; // ์ผ๋ฐ˜ ๋ง๊ณ ๋กœ ๋ ˆ์ด๋ธ” ๋ณ€๊ฒฝ
currentDroppingMango = null;
canDrop = false;
// ๋‹ค์Œ ๋ง๊ณ  ์Šคํฐ ์ฟจ๋‹ค์šด
setTimeout(() => {
canDrop = true;
if (!gameOver) {
spawnDroppingMango();
}
}, DROP_COOLDOWN);
}
function handleCollision({ pairs }) {
if (gameOver) return;
pairs.forEach(pair => {
const bodyA = pair.bodyA;
const bodyB = pair.bodyB;
if (bodyA.label === 'mango' && bodyB.label === 'mango' &&
bodyA.mangoIndex !== undefined && bodyB.mangoIndex !== undefined &&
bodyA.mangoIndex === bodyB.mangoIndex) {
// ๊ฐ™์€ ์ข…๋ฅ˜์˜ ๋ง๊ณ ๊ฐ€ ์ถฉ๋Œํ•˜๋ฉด
const currentTypeIndex = bodyA.mangoIndex;
if (currentTypeIndex < MANGO_TYPES.length - 1) {
// ํ•ฉ์ณ์งˆ ์œ„์น˜ (๋‘ ๋ง๊ณ ์˜ ์ค‘๊ฐ„)
const newPosition = {
x: (bodyA.position.x + bodyB.position.x) / 2,
y: (bodyA.position.y + bodyB.position.y) / 2
};
// ๊ธฐ์กด ๋ง๊ณ  ์ œ๊ฑฐ
Composite.remove(engine.world, [bodyA, bodyB]);
// ์ƒˆ ๋ง๊ณ  ์ƒ์„ฑ
const nextTypeIndex = currentTypeIndex + 1;
const newMangoType = MANGO_TYPES[nextTypeIndex];
const newMango = Bodies.circle(newPosition.x, newPosition.y, newMangoType.radius, {
restitution: 0.2,
friction: 0.5,
label: 'mango',
mangoIndex: nextTypeIndex,
render: {
fillStyle: newMangoType.color,
strokeStyle: '#5D4037',
lineWidth: 2
}
});
Composite.add(engine.world, newMango);
// ์ ์ˆ˜ ์ถ”๊ฐ€
score += newMangoType.score;
updateScoreDisplay();
// ํ•ฉ์ณ์งˆ ๋•Œ ์ž‘์€ ํšจ๊ณผ (์„ ํƒ ์‚ฌํ•ญ)
Body.scale(newMango, 1.1, 1.1); // ์‚ด์ง ์ปค์กŒ๋‹ค๊ฐ€
setTimeout(() => Body.scale(newMango, 1/1.1, 1/1.1), 50); // ์›๋ž˜ ํฌ๊ธฐ๋กœ
} else {
// ๊ฐ€์žฅ ํฐ ๋ง๊ณ ๋ผ๋ฆฌ ํ•ฉ์ณ์ง€๋ฉด ํŠน๋ณ„ํ•œ ์ฒ˜๋ฆฌ (์˜ˆ: ๋ณด๋„ˆ์Šค ์ ์ˆ˜)
score += MANGO_TYPES[currentTypeIndex].score * 2; // ๋งˆ์ง€๋ง‰ ๋ง๊ณ  ํ•ฉ์ฒด ์‹œ ๋ณด๋„ˆ์Šค
updateScoreDisplay();
// ์—ฌ๊ธฐ์„œ๋Š” ๊ทธ๋ƒฅ ๋‘์ง€๋งŒ, ์›ํ•œ๋‹ค๋ฉด ๋‘ ๊ฐœ๋ฅผ ์ œ๊ฑฐํ•  ์ˆ˜๋„ ์žˆ์Œ
}
}
});
}
function updateScoreDisplay() {
scoreBoard.textContent = `์ ์ˆ˜: ${score}`;
}
let gameOverCheckTimeout = null;
function checkGameOver() {
if (gameOver) return;
const bodies = Composite.allBodies(engine.world);
for (let body of bodies) {
// 'droppingMango'๋Š” ์•„์ง ๋–จ์–ด์ง€๋Š” ์ค‘์ด๋ฏ€๋กœ ์ œ์™ธ, isStatic๋„ ์ œ์™ธ (๋ฒฝ ๋“ฑ)
if (body.label === 'mango' && !body.isStatic) {
// ๋ง๊ณ ์˜ ์ตœ์ƒ๋‹จ์ด ๊ฒŒ์ž„ ์˜ค๋ฒ„ ๋ผ์ธ๋ณด๋‹ค ์œ„์— ์žˆ๊ณ , ์†๋„๊ฐ€ ๊ฑฐ์˜ ๋ฉˆ์ท„์„ ๋•Œ
if (body.position.y - MANGO_TYPES[body.mangoIndex].radius < gameOverLineY && Math.abs(body.velocity.y) < 0.1) {
// ๋ฐ”๋กœ ๊ฒŒ์ž„์˜ค๋ฒ„ ์‹œํ‚ค์ง€ ์•Š๊ณ , ์ž ๊น ์œ ์˜ˆ ์‹œ๊ฐ„์„ ๋‘  (์•„์Šฌ์•„์Šฌํ•˜๊ฒŒ ๊ฑธ์น˜๋Š” ๊ฒฝ์šฐ)
if (!gameOverCheckTimeout) {
gameOverCheckTimeout = setTimeout(() => {
// ์œ ์˜ˆ ์‹œ๊ฐ„ ํ›„์—๋„ ์—ฌ์ „ํžˆ ์กฐ๊ฑด ๋งŒ์กฑ ์‹œ ๊ฒŒ์ž„ ์˜ค๋ฒ„
if (body.position.y - MANGO_TYPES[body.mangoIndex].radius < gameOverLineY) {
triggerGameOver();
}
gameOverCheckTimeout = null;
}, 1500); // 1.5์ดˆ ์œ ์˜ˆ
}
return; // ํ•˜๋‚˜๋ผ๋„ ๊ฑธ๋ฆฌ๋ฉด ์ผ๋‹จ ๋Œ€๊ธฐ
}
}
}
// ๊ฒŒ์ž„์˜ค๋ฒ„ ๋ผ์ธ์— ๊ฑธ๋ฆฐ ๋ง๊ณ ๊ฐ€ ์—†์œผ๋ฉด ์œ ์˜ˆ ํƒ€์ด๋จธ ์ทจ์†Œ
if (gameOverCheckTimeout) {
clearTimeout(gameOverCheckTimeout);
gameOverCheckTimeout = null;
}
}
function triggerGameOver() {
if (gameOver) return; // ์ค‘๋ณต ํ˜ธ์ถœ ๋ฐฉ์ง€
gameOver = true;
canDrop = false; // ๋” ์ด์ƒ ๋“œ๋ž ๋ถˆ๊ฐ€
finalScoreDisplay.textContent = score;
gameOverMessage.style.display = 'block';
// ํ˜„์žฌ ์›€์ง์ด๋Š” ๋ง๊ณ ๊ฐ€ ์žˆ๋‹ค๋ฉด ์ œ๊ฑฐ
if(currentDroppingMango) {
Composite.remove(engine.world, currentDroppingMango);
currentDroppingMango = null;
}
updateNextMangoPreview(); // ๋‹ค์Œ ๋ง๊ณ  ํ‘œ์‹œ ์—†์• ๊ธฐ
// Runner.stop(runner); // ๋ฌผ๋ฆฌ์—”์ง„ ๋ฉˆ์ถ”๊ธฐ (์„ ํƒ)
// Render.stop(render); // ๋ Œ๋”๋ง ๋ฉˆ์ถ”๊ธฐ (์„ ํƒ)
console.log("๊ฒŒ์ž„ ์˜ค๋ฒ„! ์ตœ์ข… ์ ์ˆ˜:", score);
}
function restartGame() {
// ๊ธฐ์กด Matter.js ๊ฐ์ฒด๋“ค ์ •๋ฆฌ
if (runner) Runner.stop(runner);
if (render) Render.stop(render);
if (engine) {
Composite.clear(engine.world, false); // false๋Š” ๋ฒฝ ๋“ฑ static body๋Š” ๋‚จ๊ธฐ์ง€ ์•Š์Œ
Engine.clear(engine);
}
// ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ๋„ ์ œ๊ฑฐํ•ด์•ผ ํ•  ์ˆ˜ ์žˆ์œผ๋‚˜, ์—ฌ๊ธฐ์„œ๋Š” gameContainer๋ฅผ ํ†ต์งธ๋กœ ์“ฐ๋ฏ€๋กœ ๊ดœ์ฐฎ์„ ์ˆ˜ ์žˆ์Œ
// gameContainer.removeEventListener('click', handleDropInput);
// ... (๋‹ค๋ฅธ ๋ฆฌ์Šค๋„ˆ๋“ค๋„)
// ๊ฒŒ์ž„ ์žฌ์‹œ์ž‘
initGame();
}
// ์ฐฝ ํฌ๊ธฐ ๋ณ€๊ฒฝ ์‹œ ๊ฒŒ์ž„ ๋‹ค์‹œ ๋กœ๋“œ (๊ฐ„๋‹จํ•œ ์ฒ˜๋ฆฌ)
// ์ข€ ๋” ๋ถ€๋“œ๋Ÿฌ์šด ๋ฆฌ์‚ฌ์ด์ง•์„ ์›ํ•˜๋ฉด, Matter.js์˜ Render.setPixelRatio, Body.scale ๋“ฑ์„ ์‚ฌ์šฉํ•ด์•ผ ํ•จ
window.addEventListener('resize', () => {
// ๊ฒŒ์ž„์ด ์ง„ํ–‰ ์ค‘์ด์—ˆ๋‹ค๋ฉด, ์‚ฌ์šฉ์ž์—๊ฒŒ ์•Œ๋ฆฌ๊ณ  ์žฌ์‹œ์ž‘ ์œ ๋„ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Œ
// ์—ฌ๊ธฐ์„œ๋Š” ๊ฐ„๋‹จํ•˜๊ฒŒ ์ƒˆ๋กœ๊ณ ์นจ ๋ฐฉ์‹์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๊ฑฐ๋‚˜, restartGame() ํ˜ธ์ถœ
// alert("ํ™”๋ฉด ํฌ๊ธฐ๊ฐ€ ๋ณ€๊ฒฝ๋˜์–ด ๊ฒŒ์ž„์„ ์žฌ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค.");
// location.reload(); // ๊ฐ€์žฅ ๊ฐ„๋‹จํ•œ ๋ฐฉ๋ฒ•
// ํ˜น์€ ๋™์ ์œผ๋กœ ์บ”๋ฒ„์Šค ํฌ๊ธฐ๋งŒ ์กฐ์ ˆ (๋” ๋ณต์žกํ•จ)
canvasWidth = Math.min(window.innerWidth * 0.95, 400);
canvasHeight = Math.min(window.innerHeight * 0.7, 600);
gameContainer.style.width = `${canvasWidth}px`;
gameContainer.style.height = `${canvasHeight}px`;
if (render) {
render.canvas.width = canvasWidth;
render.canvas.height = canvasHeight;
render.options.width = canvasWidth;
render.options.height = canvasHeight;
// ๋ฒฝ ์œ„์น˜ ์—…๋ฐ์ดํŠธ
const bodies = Composite.allBodies(engine.world);
const ground = bodies.find(b => b.label === 'Rectangle Body' && b.position.y > canvasHeight - 50); // ๋Œ€๋žต์  ๋ฐ”๋‹ฅ ์ฐพ๊ธฐ
const leftWall = bodies.find(b => b.label === 'Rectangle Body' && b.position.x < 0);
const rightWall = bodies.find(b => b.label === 'Rectangle Body' && b.position.x > canvasWidth - 50);
if(ground) Body.setPosition(ground, { x: canvasWidth / 2, y: canvasHeight + 25 });
if(leftWall) Body.setPosition(leftWall, { x: -25, y: canvasHeight / 2 });
if(rightWall) Body.setPosition(rightWall, { x: canvasWidth + 25, y: canvasHeight / 2 });
// ๊ณผ์ผ ํฌ๊ธฐ๋„ ๋น„์œจ์— ๋งž๊ฒŒ ์žฌ์กฐ์ • ํ•„์š”
// MANGO_TYPES์˜ radius๋ฅผ canvasWidth ๊ธฐ์ค€์œผ๋กœ ๋‹ค์‹œ ๊ณ„์‚ฐํ•˜๊ณ ,
// ํ˜„์žฌ ํ™”๋ฉด์˜ ๋ชจ๋“  ๋ง๊ณ ๋“ค์˜ ํฌ๊ธฐ๋ฅผ Body.scale๋กœ ์กฐ์ ˆํ•ด์•ผ ํ•จ. (์ด ๋ถ€๋ถ„์€ ์ƒ๋žตํ•จ, ๋ณต์žก๋„ ์ฆ๊ฐ€)
// ๊ฐ„๋‹จํžˆ restartGame()์„ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ์ด ๋” ๋‚˜์„ ์ˆ˜ ์žˆ์Œ.
}
// ์‹ค์ œ๋กœ๋Š” ๋” ๋ณต์žกํ•œ ๋ฆฌ์‚ฌ์ด์ฆˆ ์ฒ˜๋ฆฌ๊ฐ€ ํ•„์š”. ์—ฌ๊ธฐ์„œ๋Š” ๊ฐ„๋‹จํžˆ UI๋งŒ ๋งž์ถค.
// ๊ฒŒ์ž„์„ ์ฒ˜์Œ๋ถ€ํ„ฐ ๋‹ค์‹œ ์‹œ์ž‘ํ•˜๋Š”๊ฒŒ ๊ฐ€์žฅ ์•ˆ์ •์ ์ผ ์ˆ˜ ์žˆ์Œ.
});
// ๊ฒŒ์ž„ ์‹œ์ž‘
initGame();
</script>
</body>
</html>