const {PI} = Math;
const TAU = PI * 2;
const canvas = document.createElement("canvas");
document.body.appendChild(canvas);
const ctx = canvas.getContext("2d");
canvas.height = 180;
canvas.width = 400;
const engine = Matter.Engine.create();
engine.gravity.y = 0;
const ship = {
body: Matter.Bodies.rectangle(
canvas.width / 2,
canvas.height / 2,
20,
20,
{
frictionAir: 0.03,
density: 0.3,
friction: 0.8,
}
),
size: 20,
destX: canvas.width / 2,
destY: canvas.height / 2,
color: "#eaf",
setDestination(x, y) {
this.destX = x;
this.destY = y;
},
draw(ctx) {
ctx.save();
ctx.translate(this.body.position.x, this.body.position.y);
ctx.rotate(this.body.angle);
ctx.lineWidth = 3;
ctx.beginPath();
ctx.moveTo(0, 0);
ctx.lineTo(this.size / 1.2, 0);
ctx.stroke();
ctx.fillStyle = this.color;
ctx.fillRect(
this.size / -2,
this.size / -2,
this.size,
this.size
);
ctx.strokeRect(
this.size / -2,
this.size / -2,
this.size,
this.size
);
ctx.restore();
},
};
Matter.Composite.add(engine.world, [ship.body]);
canvas.addEventListener("click", (e) => {
ship.setDestination(e.offsetX, e.offsetY);
});
(function update() {
requestAnimationFrame(update);
ctx.clearRect(0, 0, canvas.width, canvas.height);
const {x, y} = ship.body.position;
const dist = Math.sqrt(
(ship.destX - x) ** 2 + (ship.destY - y) ** 2
);
if (dist > 10) {
const dx = ship.destX - ship.body.position.x;
const dy = ship.destY - ship.body.position.y;
let theta = Math.atan2(dy, dx);
const a =
ship.body.angle > 0
? ((ship.body.angle + TAU) % TAU) - TAU
: -(((-ship.body.angle + TAU) % TAU) - TAU);
let diff = a - theta;
diff = diff > PI ? diff - TAU : diff;
diff = diff < -PI ? diff + TAU : diff;
const f = dist < 70 ? Math.min(0.02, dist / 10000) : 0.03;
Matter.Body.applyForce(
ship.body,
{x, y},
{
x: Math.cos(theta) * f,
y: Math.sin(theta) * f,
}
);
if (dist > 15) {
Matter.Body.setAngularVelocity(ship.body, diff / -8);
} else {
Matter.Body.setAngularVelocity(ship.body, 0);
}
}
ship.draw(ctx);
Matter.Engine.update(engine);
})();
body {
margin: 0;
font-family: monospace;
display: flex;
align-items: center;
}
html, body {
height: 100%;
}
canvas {
background: #eee;
margin: 1em;
border: 4px solid #222;
}
#instructions {
transform: rotate(-90deg);
background: #222;
color: #fff;
padding: 2px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/matter-js/0.19.0/matter.min.js"></script>
<div id="instructions">click to move</div>
translate
并开始覆盖MJS的物理引擎时,就好像买一辆自行车只是为了搬运它一样。 - undefined