我正在参加「码上掘金挑战赛」详情请看:码上掘金挑战赛来了!
前言
这几天我闲着无聊,在看上网的时候发现了一个好玩的东西——matter.js
matter.js 介绍
matter.js 是一个用 JavaScript 编写的 2D 刚体物理引擎。该库可以帮助您轻松地在浏览器中模拟 2D 物理。它提供了许多功能,例如创建刚体并为它们分配物理属性(如质量、面积或密度)的能力。您还可以模拟不同类型的碰撞和力,例如重力和摩擦力。
matter.js 体验
我这里展示的效果只是这个引擎的一小部分
下面是官方的在线演示
matter.js在线演示: brm.io/matter-js/d…
matter.js 的使用
引入 matter.js
我们先要去将matter.js下载下来,然后再引入。
如果不想要下载,可以引入在线链接
<script src="https://cdnjs.cloudflare.com/ajax/libs/matter-js/0.18.0/matter.min.js"></script>
使用 matter.js
HTML
HTML里面只需要引入matter.js
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!-- 这里引入matter.js的在线地址 -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/matter-js/0.18.0/matter.min.js"></script>
</head>
<body>
</body>
</html>
css
css里面其实里面可以什么都不用写,但是最好清除掉外边距和内边距,不然canavs与边框之间的空隙看着有些难受
* {
margin: 0;
padding: 0;
}
写两行代码的时候可以写成 m0+p0 可以直接打出这两行代码
JavaScript
JavaScript就比较的复杂了
Engine 是引擎,引擎模块包含创建和操作引擎的方法
Render 是渲染器,基于HTML5画布的渲染器
Runner 是表演环境,演出舞台. Matter.js 中任何的物体都需要一个舞台/容器,而存放这些物体的地方,则称之为World(世界)
Bodies 可以用来创建各种形状的物体,用于创建各种形状的物体,物体必须添加到Wolrd中,然后由引擎运行世界
let Engine = Matter.Engine; // 创建引擎
let Render = Matter.Render; // 创建画布
let World = Matter.World; // 创建世界
let Bodies = Matter.Bodies; // 用于创建各种的物体
let engine = Engine.create();
//render(渲染器)将要渲染的物理引擎是上面的engine,而渲染的对象是html网页的body
let render = Render.create({ element: document.body, engine: engine ,
options: {
pixelRatio: 1, // 设置像素比 这个关系到性能
background: '#76BAFE', // 设置全局背景颜色
// 要设置背景颜色需要将线框模式为关
wireframes: false, // 线框模
// wireframeBackground: '#222' 线框模式时背景色
// 要设置线框颜色需要打开线框模式
// 但是打开之后就不能设置全局背景颜色了
}
});
Bodies创建的方法
语法:
Bodies.rectangle = function(x, y, width, height, options)
// x,y 分别表示矩形中心点的坐标,坐标的原点(0,0)在 Canvas(画布)的左上角
// width,height 分别表示矩形的宽和高
// options:描述矩形的参数,是一个 json 对象
// rect = Bodies.rectangle(200, 100, 50, 50), // 矩形
// circle = Bodies.circle(300, 100, 25), // 圆
// polygon = Bodies.polygon(450, 100, 5, 25), // 多边形
// trapezoid = Bodies.trapezoid(590, 100, 50, 50, 3); // 梯形
我们创建两个物体
// 创建圆形
let round = Bodies.circle(100, 100, 50{
density: .68, // 设置密度
restitution: 1.5, // 设置物体的弹跳力
render: {
sprite: {
// 设置贴图
texture: '月饼.png'
}
}
})
// 创建矩形
let box = Bodies.rectangle(100, 150, 200, 200,{
density: 1,
restitution: 1.5,
render: {
sprite: {
texture: 'https://momozi2006.github.io/qq%E5%A4%B4%E5%83%8F.png'
}
}
})
// 创建固定的物体
let ground = Bodies.rectangle(innerWidth / 2, innerHeight / 2, innerWidth * 2, 50, {
// isStatic设为true,表示物体静止
isStatic: true
})
创建物体之后将它添加进入世界
然后运行引擎和渲染器
World.add(engine.world, [round, box, ground]);// 将所有物体添加到世界中
Engine.run(engine);//运行引擎
Render.run(render);//运行渲染器
让我们来看一下现在的效果
它这里面还有一个鼠标控制的事件
我们可以添加该事件
// Composites 模块包含用于创建具有常用配置(例如,堆栈和链)的复合实体的工厂方法
let Composite = Matter.Composite;
// MouseConstraint 用于创建鼠标约束的方法。鼠标约束用于允许用户交互,提供通过鼠标或触摸移动身体的能力。
let MouseConstraint = Matter.MouseConstraint;
// Mouse 模块包含用于创建和操作鼠标输入的方法
let Mouse = Matter.Mouse;
// 添加鼠标控制事件
let mouse = Mouse.create(render.canvas);
let mouseConstraint = MouseConstraint.create(engine, {
mouse: mouse,
constraint: {
stiffness: 0.2,
render: {
visible: false
}
}
})
// 将世界添加进入鼠标事件
Composite.add(engine.world, mouseConstraint);
// 保持鼠标与渲染同步
render.mouse = mouse;
添加完事件之后就可以使用鼠标去拖拽这些物体
看到这里你应该就学会简单的使用mater.js了
如果想要了解更多的使用方法,可以去看看官方的教程或者别的文章
总结
将引擎、渲染器、世界这些东西设置好,再创建一些想要的物体,最后再运行引擎和渲染器就大功告成了。其实这个东西还是挺简单的
以下是所有的代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./matter.min.js"></script>
<style>
* {
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<script>
window.onload = function () {
let Engine = Matter.Engine;
let Render = Matter.Render;
let World = Matter.World;
let Bodies = Matter.Bodies;
let engine = Engine.create();
let render = Render.create({
element: document.body,
engine: engine,
options: {
pixelRatio: 1, // 设置像素比 这个关系到性能
background: '#76BAFE', // 设置全局背景颜色
// 要设置背景颜色需要将线框模式为关
wireframes: false, // 线框模式
// wireframeBackground: '#222' 线框模式时背景色
// 要设置线框颜色需要打开线框模式
// 但是打开之后就不能设置全局背景颜色了
}
})
let Composite = Matter.Composite;
let MouseConstraint = Matter.MouseConstraint;
let Mouse = Matter.Mouse;
let canvas = document.querySelector('canvas');
canvas.width = innerWidth;
canvas.height = innerHeight;
let roundA = Bodies.circle(100, 100, 50, {
density: .68, // 设置密度
restitution: 1.5, // 设置弹力
render: {
sprite: {
texture: '月饼.png'
}
}
})
let boxA = Bodies.rectangle(100, 150, 200, 200, {
density: 1,
restitution: 1.5,
render: {
sprite: {
texture: 'qq头像.png'
}
}
})
World.add(engine.world, [roundA, boxA]);
let ground = Bodies.rectangle(innerWidth / 2, innerHeight - 30, innerWidth * 2, 50, { isStatic: true });
World.add(engine.world, [ground]);
Engine.run(engine);
Render.run(render);
let mouse = Mouse.create(render.canvas);
let mouseConstraint = MouseConstraint.create(engine, {
mouse: mouse,
constraint: {
stiffness: 0.2,
render: {
visible: false
}
}
})
Composite.add(engine.world, mouseConstraint);
render.mouse = mouse;
}
</script>
</body>
</html>
拓展
这是一个有关 render 的 options 对象:
width: 800,
height: 600,
pixelRatio: 1, 设置像素比
background: '#fafafa', 全局渲染模式时背景色
wireframeBackground: '#222', 线框模式时背景色
hasBounds: false,
enabled: true,
wireframes: true, 线框模式
showSleeping: true, 刚体睡眠状态
showDebug: false, Debug 信息
showBroadphase: false, 粗测阶段
showBounds: false, 刚体的界限
showVelocity: false, 移动刚体时速度
showCollisions: false, 刚体碰撞点
showSeparations: false, 刚体分离
showAxes: false, 刚体轴线
showPositions: false, 刚体位置
showAngleIndicator: false, 刚体转角指示
showIds: false, 显示每个刚体的 ID
showVertexNumbers: false, 刚体顶点数
showConvexHulls: false, 刚体凸包点
showInternalEdges: false, 刚体内部边界
showMousePosition: false 鼠标约束线