Download as txt, pdf, or txt
Download as txt, pdf, or txt
You are on page 1of 3

<!

DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Interactive Box2D Demo</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/box2dweb/2.1.a.3/Box2dWeb-
2.1.a.3.min.js"></script>
<style>
body { font-family: Arial, sans-serif; }
#controls { margin-bottom: 10px; }
label { margin-right: 10px; }
input { width: 50px; }
</style>
</head>
<body>
<div id="controls">
<label>중력: <input type="number" id="gravity" value="-9.81"
step="0.1"></label>
<label>마찰력: <input type="number" id="friction" value="0.3" step="0.1"
min="0" max="1"></label>
<label>반발 계수: <input type="number" id="restitution" value="0.5"
step="0.1" min="0" max="1"></label>
<label>밀도: <input type="number" id="density" value="1.0" step="0.1"
min="0.1"></label>
<button id="reset">초기화</button>
</div>
<canvas id="canvas" width="800" height="600" style="border:1px solid
#000;"></canvas>
<script>
function initBox2D() {
if (typeof Box2D === 'undefined') {
console.error('Box2D library is not loaded');
alert('Box2D 라이브러리를 불러오는 데 실패했습니다. 인터넷 연결을 확인해주세요.');
return false;
}
return true;
}

document.addEventListener('DOMContentLoaded', function () {
if (!initBox2D()) return;

const SCALE = 30; // 픽셀 대 미터 비율

// Box2D 네임스페이스 설정
const b2Vec2 = Box2D.Common.Math.b2Vec2;
const b2World = Box2D.Dynamics.b2World;
const b2BodyDef = Box2D.Dynamics.b2BodyDef;
const b2Body = Box2D.Dynamics.b2Body;
const b2FixtureDef = Box2D.Dynamics.b2FixtureDef;
const b2PolygonShape = Box2D.Collision.Shapes.b2PolygonShape;
const b2CircleShape = Box2D.Collision.Shapes.b2CircleShape;

const canvas = document.getElementById("canvas");


const context = canvas.getContext("2d");
const canvasWidth = canvas.width / SCALE;
const canvasHeight = canvas.height / SCALE;
let world, circleBody, circleFixture;

function createWorld() {
// 월드 생성
world = new b2World(new b2Vec2(0,
parseFloat(document.getElementById('gravity').value)), true);

// 그라운드 생성
const groundBodyDef = new b2BodyDef();
groundBodyDef.position.Set(canvasWidth / 2, 0.5);
const groundBody = world.CreateBody(groundBodyDef);
const groundBox = new b2PolygonShape();
groundBox.SetAsBox(canvasWidth / 2, 0.5);
groundBody.CreateFixture(groundBox, 0);

// 원 생성
const circleBodyDef = new b2BodyDef();
circleBodyDef.type = b2Body.b2_dynamicBody;
circleBodyDef.position.Set(canvasWidth / 2, canvasHeight - 1);
circleBody = world.CreateBody(circleBodyDef);
const circleShape = new b2CircleShape();
circleShape.SetRadius(1);
const circleFixtureDef = new b2FixtureDef();
circleFixtureDef.shape = circleShape;
circleFixtureDef.density =
parseFloat(document.getElementById('density').value);
circleFixtureDef.friction =
parseFloat(document.getElementById('friction').value);
circleFixtureDef.restitution =
parseFloat(document.getElementById('restitution').value);
circleFixture = circleBody.CreateFixture(circleFixtureDef);
}

function updatePhysics() {
world.SetGravity(new b2Vec2(0,
parseFloat(document.getElementById('gravity').value)));

circleFixture.SetDensity(parseFloat(document.getElementById('density').value));

circleFixture.SetFriction(parseFloat(document.getElementById('friction').value));

circleFixture.SetRestitution(parseFloat(document.getElementById('restitution').valu
e));
circleBody.ResetMassData();
}

function draw() {
world.Step(1 / 60, 8, 3);
world.ClearForces();

context.clearRect(0, 0, canvas.width, canvas.height);

// 그라운드 그리기
context.fillStyle = "brown";
context.fillRect(0, canvas.height - 0.5 * SCALE, canvas.width, 0.5
* SCALE);

// 원 그리기
const position = circleBody.GetPosition();
context.save();
context.translate(position.x * SCALE, canvas.height - position.y *
SCALE);
context.fillStyle = "red";
context.beginPath();
context.arc(0, 0, SCALE, 0, Math.PI * 2, true);
context.fill();
context.restore();

requestAnimationFrame(draw);
}

createWorld();
draw();

// 컨트롤 이벤트 리스너


document.getElementById('gravity').addEventListener('input',
updatePhysics);
document.getElementById('friction').addEventListener('input',
updatePhysics);
document.getElementById('restitution').addEventListener('input',
updatePhysics);
document.getElementById('density').addEventListener('input',
updatePhysics);
document.getElementById('reset').addEventListener('click', function() {
world.DestroyBody(circleBody);
createWorld();
});
});
</script>
</body>
</html>

You might also like