国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

物理世界的互動之旅:Matter.js入門指南

這篇具有很好參考價值的文章主要介紹了物理世界的互動之旅:Matter.js入門指南。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

本文簡介

戴尬猴,我是德育處主任


歡迎來到《物理世界的互動之旅:Matter.js入門指南》。

本文將帶您探索 Matter.js,一個強大而易于使用的 JavaScript 物理引擎庫。

我將介紹 Matter.js 的基本概念,包括引擎、世界、物體和約束等。

本文還提供豐富的代碼示例,幫助各位工友更好地理解如何使用 Matter.js 創(chuàng)建令人驚嘆的物理場景(先畫個餅吧~)。


本文是我的學(xué)習(xí)筆記和個人理解,在翻譯和部分概念的理解上可能存在一點偏差,如果發(fā)現(xiàn)本文有什么錯漏的地方,請自行調(diào)節(jié)呼吸頻率。我懶得改~

本文前1000字都在講一些基礎(chǔ)概念,你覺得無聊可以先看后面的內(nèi)容,看完再回來過一遍基礎(chǔ)概念就行了。


Matter.js是什么?

在現(xiàn)實世界中,物理是無處不在的。從行星和恒星的運動到電子的運動,物理定律描述了我們周圍幾乎所有事物的運動和相互作用。

在計算機科學(xué)中,物理引擎是一種模擬物理現(xiàn)象的軟件程序。它們通常用于創(chuàng)建物理游戲、虛擬現(xiàn)實和仿真等應(yīng)用程序。物理引擎可以模擬各種現(xiàn)象,例如重力、碰撞和摩擦等。物理引擎通常是非常復(fù)雜的,因為它必須模擬現(xiàn)實世界中的各種效果。

在Web瀏覽器想模擬真實世界的物理現(xiàn)象其實也有很多庫,2D方面有 Matter.js、P2.js 等,3D方面有 Cannon.jsammo.js 等。

而本文是將 Matter.js 的,所以我在這只會說 Matter.js 的好話。

Matter.js 是一個非常強大的 JavaScript 2D物理引擎,它能夠幫助你在Web應(yīng)用程序中實現(xiàn)逼真的物理效果。

Matter.js 提供了可定制的碰撞檢測、重力、力學(xué)效應(yīng)和運動控制等功能,讓你可以快速、簡單地構(gòu)建交互式的物理模擬。無論是模擬游戲、建筑模型還是實驗室實驗,Matter.js 都可以滿足你的需求。

Matter.js官網(wǎng) ??


基礎(chǔ)概念

在學(xué)習(xí) Matter.js 前,我們需要了解一些基礎(chǔ)概念。由于本文是入門篇,所以我只介紹常用的基礎(chǔ)概念。

模塊名稱 說明
引擎(Engine) 引擎 EngineMatter.js 的核心組件,用于管理物理世界中的所有對象、計算物體的運動和相互作用。用來模擬真實環(huán)境的。
渲染器(Render) 渲染器 Render 用于將物理世界中的對象可視化。意思就是它能將物體渲染到屏幕上。
復(fù)合體(Composite) 是包含多個剛體和約束的容器,它們可以作為單個物理對象進行操作。
剛體(Body) 表示具有物理屬性的實體,如形狀、質(zhì)量和速度等。剛體可以是各種形狀,例如矩形、圓形、多邊形等。
約束(Constraint) 用于約束剛體的相對運動,例如讓兩個剛體之間的距離保持不變、限制旋轉(zhuǎn)等。
循環(huán)模塊 (Runner) Runner 用于管理和控制物理引擎的主循環(huán)。

我用自己的話粗略總結(jié)一下(但我感覺我總結(jié)得不太正確,工友們有更好的理解可以到評論區(qū)留句話,沒什么好說的也可以寫句“到此一游”)。

引擎 Engine 可以模擬我們真實世界的一些物理法則。

剛體 Body 可以粗略理解為現(xiàn)實世界中的物體,比如一個球、一張凳子。

復(fù)合體 Composite 是一個容器,可以將多個物體整合起來,讓它們產(chǎn)生聯(lián)系。比如創(chuàng)建了一個球(剛體),然后用 Composite 將球和引擎連接起來,這樣球就會收到物理規(guī)則的影響了。

渲染器 Render 就是個眼睛的作用,它能幫助我們看到 Matter.js 創(chuàng)建出來的世界。

約束 Constraint 就是約束,比如一個蹺蹺板由一根很長的模板和一個底座組成,底座固定在地面,木板的中間鎖定在底座上面,這個鎖定動作就是約束。正因為有這個約束,所以蹺蹺板才能成為蹺蹺板。

循環(huán)模塊 Runner 可以粗略的理解為現(xiàn)實世界中的時間。如果沒有循環(huán)模塊,頁面的所有元素都是定格的。你可以理解為現(xiàn)實世界沒有時間的話,整個世界都會靜止。


以上就是我覺得 Matter.js 入門階段需要了解的一些基礎(chǔ)概念。

除此之外其實還需要掌握一些基礎(chǔ)物理概念,比如知道什么是碰撞,什么事摩擦力、阻力、重力等。這類概念會在接下來的案例中講解。


安裝Matter.js

在開始使用 Matter.js 之前,需要確保在項目中安裝了它。

可以通過 npm 在命令行中安裝,也可以通過 cdn 的方式引入。

CDN

github 上下載并引入到你的項目即可 github地址???。

你也可以 在這找到指定版本??。

如果你不想把 Matter.js 下載到本地,也可以在 bootcdn 搜索 Matter.js 并引入。

<script src="https://cdn.bootcdn.net/ajax/libs/matter-js/0.19.0/matter.js"></script>

NPM

Matter.js 的 npm 地址??

npm install matter-js


起步,第一個 Matter.js 應(yīng)用

這個例子是 Matter.js 官方的起步案例,通過這個例子你可以快速理解到前面講的 Matter.js 基礎(chǔ)概念。

先看效果。

物理世界的互動之旅:Matter.js入門指南

從這個動圖我們可以看出:

  1. 這個世界有2個正方形和一個地面(底部的長方形)。
  2. 正方形出現(xiàn)在空中,然后做自由落體運動。
  3. 左邊的正方形碰到地面后出現(xiàn)了一點回彈。
  4. 右邊的正方形落地前砸到左邊的正方形,阻止了左邊正方形的回彈,并且自己往右滾動了一下。

要使用 Matter.js 實現(xiàn)上面的效果,需要做以下幾步:

  1. 創(chuàng)建容器。
  2. 引入 Matter.js。
  3. 創(chuàng)建引擎。
  4. 創(chuàng)建渲染器,綁定畫布上。
  5. 創(chuàng)建正方形和地面,并且讓地面元素保持靜止。
  6. 將創(chuàng)建好的元素添加到“世界”里(沒錯,你就是創(chuàng)世神~)。
  7. 最后,為這個世界添加“時間”屬性,讓它可以運轉(zhuǎn)起來(Matter.Runner)。

上面所說的步驟還需要對應(yīng)基礎(chǔ)概念的表格配合理解。

轉(zhuǎn)換成代碼

<!-- 1. 創(chuàng)建容器 -->
<div id="c"></div>

<!-- 2. 引入 matter -->
<script src="../js/matter.js"></script>
<script>

  const Engine = Matter.Engine
  const Render = Matter.Render
  const Bodies = Matter.Bodies
  const Composite = Matter.Composite
  const Runner = Matter.Runner

  // 3. 創(chuàng)建引擎
  let engine = Engine.create()

  // 4. 創(chuàng)建渲染器,并將引擎連接到畫布上
  let render = Render.create({
    element: document.getElementById('c'), // 綁定頁面元素
    engine: engine, // 綁定引擎
  })

  // 5-1. 創(chuàng)建兩個正方形
  let boxA = Bodies.rectangle(400, 200, 80, 80)
  let boxB = Bodies.rectangle(450, 50, 80, 80)

  // 5-2. 創(chuàng)建地面,將isStatic設(shè)為true,表示物體靜止
  let ground = Bodies.rectangle(400, 610, 810, 60, { isStatic: true })

  // 6. 將所有物體添加到世界中
  Composite.add(engine.world, [boxA, boxB, ground])

  // 7. 執(zhí)行渲染操作
  Render.run(render)

  // 8. 創(chuàng)建運行方法
  var runner = Runner.create()

  // 9. 運行渲染器
  Runner.run(runner, engine)
</script>

我們使用 Engine 創(chuàng)建引擎,Matter.js 的這個引擎默認(rèn)幫我們定義好這個世界的基本運行規(guī)律。

然后我們使用 Render 創(chuàng)建渲染器,這個渲染器可以將引擎和頁面綁定在一起。

Bodies 是剛體的意思,用它來創(chuàng)建物體的,本例就創(chuàng)建了2個正方形和1個地面。

Composite 就是前面講到的復(fù)合體,它可以讓世界和物體產(chǎn)生關(guān)聯(lián),也就是說可以將物體添加到世界中。

最后通過 Render 讓這個世界有了“時間”的概念,物體也會根據(jù)世界的規(guī)則在時間的運行下產(chǎn)生運動。

上面的代碼也許你還不理解每個方法的具體使用方式,但結(jié)合我前面的分析,我相信你已經(jīng)大概了解 Matter.js “創(chuàng)造世界”的基本流程(也許聽完我的解析后更懵了)。


渲染器

在前面的例子中,我們使用 Matter.Render.create 將畫布和頁面元素綁定在一起。此時默認(rèn)的畫布尺寸是 800px * 600px。

// 省略部分代碼

let render = Matter.Render.create({
  element: document.getElementById('c'), // 綁定頁面元素
  engine: engine, // 綁定引擎
})

其實它還支持其他屬性配置,可以設(shè)置畫布寬高等信息。


設(shè)置畫布寬高

使用 Matter.Render.create 時還能傳入 options 參數(shù)。

// 省略部分代碼

let render = Matter.Render.create({
  element: document.getElementById('c'), // 綁定頁面元素
  engine: engine, // 綁定引擎
  options: {
    width: 400,
    height: 400
  }
})

關(guān)閉線框模式

Matter.js 創(chuàng)建的形狀默認(rèn)是線框模式的,你可以手動關(guān)閉這個模式,Matter.js 就會自動幫你填充一些顏色到基礎(chǔ)圖形上。

關(guān)閉線框模式的方式是將 wireframes 設(shè)置為 false。

物理世界的互動之旅:Matter.js入門指南

// 省略部分代碼

let render = Matter.Render.create({
  element: document.getElementById('c'), // 綁定頁面元素
  engine: engine, // 綁定引擎
  options: {
    wireframes: false
  }
})

其他代碼,包括創(chuàng)建圖形的代碼都和“起步,第一個 Matter.js 應(yīng)用”一樣。

options 還支持其他的配置,有興趣的工友可以看看 文檔??。


圖形元素

Matter.js 支持多種基礎(chǔ)圖形,包括矩形、圓形、三角形、梯形、多邊形等。這些圖形還支持配置顏色、摩擦力等屬性。


基礎(chǔ)圖形

先說說基礎(chǔ)。

Matter.js 文檔中你會留意到創(chuàng)建物體使用的是 Body 或者 Bodies,翻譯成中文就是“剛體”。

在物理世界中,剛體是指在運動中和受力作用后,形狀和大小不變,而且內(nèi)部各點的相對位置不變的物體。

Matter.js 中,剛體(Body) 是一種物理對象,它具有質(zhì)量、位置、速度、加速度和形狀等屬性,可以被添加到物理世界中并受到物理引擎的模擬。例如矩形和圓形。


在入門階段,我們可以使用 Bodies 創(chuàng)建基礎(chǔ)圖形。


矩形 rectangle

前面我們已經(jīng)使用過矩形了。在這小節(jié)粗略講解一下創(chuàng)建矩形的一些必傳參數(shù)。

創(chuàng)建矩形使用的是 Matter.Bodies.rectangle(x, y, width, height) 方法。

參數(shù) xy 是矩形中心點的坐標(biāo),widthheight 是矩形的寬高。

如果創(chuàng)建一個 80*80 的矩形,希望它的左上角在 (0, 0) 的位置,那 xy 分別設(shè)置成 widthheight 的一半。

物理世界的互動之旅:Matter.js入門指南

// 省略部分代碼

// 創(chuàng)建矩形
let rect = Matter.Bodies.rectangle(40, 40, 80, 80)

// 將矩形添加到世界里
Matter.Composite.add(engine.world, rect)

圓形 circle

創(chuàng)建圓形的方法是 Matter.Bodies.circle(x, y, radius)

xy 是圓心坐標(biāo), radius 是半徑。

物理世界的互動之旅:Matter.js入門指南

// 省略部分代碼

// 創(chuàng)建圓形
let circle = Matter.Bodies.circle(40, 40, 40)

// 將矩形添加到世界里
Matter.Composite.add(engine.world, circle)

梯形 trapezoid

創(chuàng)建梯形的方法是 Matter.Bodies.trapezoid(x, y, width, height, slope)

xy 定義了梯形的中心點坐標(biāo),widthheight 是梯形的寬高,slope 是斜率。

  • 當(dāng)斜率 slope 大于0小于1時,梯形的上邊小于下邊。
  • 當(dāng)斜率 slope 等于0時,梯形的上邊和下邊相等,看起來就是一個矩形。
  • 當(dāng)斜率 slope 小于0時,上邊大于下邊。
  • 當(dāng)斜率 slope 大于等于1時,就會呈現(xiàn)出三角形的樣子。

物理世界的互動之旅:Matter.js入門指南

// 省略部分代碼

let trapezoid = Matter.Bodies.trapezoid(200, 200, 80, 80, 0.5)

三角形 trapezoid

創(chuàng)建三角形的方法和梯形一樣,只需將斜率 slope 設(shè)置成大于等于1的值即可。

物理世界的互動之旅:Matter.js入門指南

// 省略部分代碼

let triangle = Matter.Bodies.trapezoid(200, 200, 80, 80, 1)

物理世界的互動之旅:Matter.js入門指南

// 省略部分代碼

let triangle = Matter.Bodies.trapezoid(200, 200, 80, 80, 2)

正多邊形 polygon

Matter.js 使用 Matter.Bodies.polygon(x, y, sides, radius) 創(chuàng)建正多邊形。

注意,是正多邊形!

參數(shù) xy 是多邊形中心點的坐標(biāo),sides 可以設(shè)置多邊形的邊的數(shù)量,radius 設(shè)置多邊形的半徑。

物理世界的互動之旅:Matter.js入門指南

// 省略部分代碼

let polygon = Matter.Bodies.polygon(200, 200, 7, 40)

自定義多邊形

使用Matter.js創(chuàng)建自定義多邊形,可以使用 Matter.Bodies.fromVertices(x, y, vertexSets) 方法。

xy 定義多變西女中心的坐標(biāo),vertexSets 定義多邊形頂點集合。

// 省略部分代碼

// 定義頂點
const vertices = [
  { x: 0, y: 0 },
  { x: 50, y: 0 },
  { x: 50, y: 50 },
  { x: 25, y: 75 },
  { x: 0, y: 50 }
]

// 自定義多邊形
const trapezoid = Matter.Bodies.fromVertices(100, 100, vertices)

// 將自定義多邊形添加到世界里
Matter.Composite.add(engine.world, trapezoid)

圖形狀態(tài)和屬性配置

前面使用 Matter.bodies 創(chuàng)建的圖形時,可以在最后加多一個對象參數(shù),這個參數(shù)可以配置圖形的狀態(tài)和屬性。

填充色 render.fillStyle

如果您想為Matter.js中的形狀添加填充色,可以在 render 屬性中配置 fillStyle 屬性的值。例如,要將圓形的填充色設(shè)置為橙色,可以使用以下代碼:

物理世界的互動之旅:Matter.js入門指南

// 省略部分代碼

// 創(chuàng)建渲染器
let render = Matter.Render.create({
  element: document.getElementById('c'), // 綁定頁面元素
  engine: engine, // 綁定引擎
  options: {
    width: 400,
    height: 400,
    wireframes: false, // 關(guān)閉線框模式
  }
})

// 省略部分代碼

// 創(chuàng)建矩形
let rect = Matter.Bodies.rectangle(200, 200, 80, 80, {
  render: {
    fillStyle: 'orange'
  }
})

需要注意的是,使用填充色功能時,要關(guān)掉渲染器的線框模式。


邊框顏色和線寬 render.strokeStyle & render.lineWidth

使用 render.strokeStyle 可以設(shè)置邊框顏色,使用 render.lineWidth 可以設(shè)置邊框的寬度。

物理世界的互動之旅:Matter.js入門指南

// 省略部分代碼

// 創(chuàng)建渲染器
let render = Matter.Render.create({
  element: document.getElementById('c'), // 綁定頁面元素
  engine: engine, // 綁定引擎
  options: {
    width: 400,
    height: 400,
    wireframes: false, // 關(guān)閉線框模式
  }
})

// 省略部分代碼

// 創(chuàng)建矩形
let rect = Matter.Bodies.rectangle(200, 200, 80, 80, {
  render: {
    strokeStyle: '#3490de', // 設(shè)置邊框顏色
    lineWidth: 20 // 設(shè)置邊框?qū)挾?  }
})

render.fillStylerender.strokeStyle 都支持 顏色關(guān)鍵字、#開頭的十六進制、rgb、rgba等 顏色值。

但不支持 0x 開頭的十六進制顏色。


貼圖 render.sprite

一個優(yōu)秀的前端必須懂得貼圖,Matter.js 也提供了貼圖功能。

只需要配置一下 render.sprite 即可。

我用矩形舉例。

物理世界的互動之旅:Matter.js入門指南

// 省略部分代碼

// 創(chuàng)建矩形
let rect = Matter.Bodies.rectangle(200, 200, 200,  200, {
  render: {
    sprite: { // 使用精靈
      texture: './monkey.jpg' // 圖片紋理位置
    }
  }
})

// 將所有物體添加到世界中
Matter.Composite.add(engine.world, rect)

縮放貼圖 scale

如果需要設(shè)置貼圖的寬高,還可以修改 xScaleyScale 屬性。

但這兩個屬性只會影響貼圖的尺寸,圖形的真實尺寸并不會受到影響。

物理世界的互動之旅:Matter.js入門指南

// 省略部分代碼

let rect = Matter.Bodies.rectangle(200, 200, 200,  200, {
  render: {
    sprite: {
      texture: './monkey.jpg',
      xScale: 0.5,
      yScale: 1.5
    }
  }
})

貼圖偏移 offset

可以設(shè)置精靈圖的 xOffsetyOffset。

// 省略部分代碼

let rect = Matter.Bodies.rectangle(200, 200, 200,  200, {
  render: {
    sprite: {
      texture: './monkey.jpg',
      xOffset: 0.5,
      yOffset: 1
    }
  }
})

不透明度 render.opacity

opacity 的取值范圍是 0 ~ 1

// 省略部分代碼

let rect = Matter.Bodies.rectangle(80, 100, 80, 80, {
  render: {
    opacity: 0.5
  }
})

元素可見性 render.visible

當(dāng) render.visiblefalse 時,元素會隱藏;反之元素就顯示。render.visible 的默認(rèn)值是 true。

// 省略部分代碼

let rect = Matter.Bodies.rectangle(80, 100, 80, 80, {
  render: {
    visible: false // 隱藏元素
  }
})

旋轉(zhuǎn) angle

angle 屬性可以設(shè)置元素的旋轉(zhuǎn)弧度。

為了方便理解,我還是更習(xí)慣用“角度”這個單位。

弧度轉(zhuǎn)角度可以用這個公式:

Math.PI / 180 * 角度

物理世界的互動之旅:Matter.js入門指南

// 省略部分代碼

// 矩形
let rect = Matter.Bodies.rectangle(80, 100, 80, 80, {
  angle: Math.PI / 180 * 45
})

上面這段代碼創(chuàng)建了一個矩形,并且讓他旋轉(zhuǎn)45度。結(jié)合上面的公式應(yīng)該比較容易理解。


空氣阻力 frictionAir

前面簡單的介紹了一下基礎(chǔ)圖形怎么填充顏色、怎么使用貼圖,這些都前菜。

Matter.js 真正的亮點是物理引擎。

在前面有講到,要讓物理引擎動起來,需要用到下面這段代碼

// 省略部分代碼

// 創(chuàng)建運行方法
let runner = Runner.create()

// 運行渲染器
Runner.run(runner, engine)

如果忘了,可以看看前面的 “起步,第一個 Matter.js 應(yīng)用” 這章節(jié)。


先介紹一下空氣阻力。

我們知道,在地球上,當(dāng)一個物體做自由落體運動時,會受到空氣阻力的影響。

Matter.js 提供了 frictionAir 這個屬性可以讓我們給指定物體配置具體的空氣阻力。

物理世界的互動之旅:Matter.js入門指南

// 省略部分代碼

let rectA = Matter.Bodies.rectangle(80, 100, 80, 80, {
  frictionAir: 0.1 // 設(shè)置空氣阻力
})

let rectB = Matter.Bodies.rectangle(200, 100, 80, 80, {
  frictionAir: 0.5 // 設(shè)置空氣阻力
})

let rectC = Matter.Bodies.rectangle(320, 100, 80, 80, {
  frictionAir: 1 // 設(shè)置空氣阻力
})

// 地面
let ground = Matter.Bodies.rectangle(200, 390, 400, 20, {
  isStatic: true,
  render: {
    fillStyle: '#cccccc'
  }
})

// 6. 將所有物體添加到世界中
Matter.Composite.add(engine.world, [rectA, rectB, rectC, ground])

從左往右的立方體中,我分別給它們配置的空氣阻力時 0.10.51 ,數(shù)值越大,空氣阻力就越大,自由落體的速度也就越慢。


回彈力 restitution

前面的例子中創(chuàng)建的物體都是沒有彈力的,它們掉到地面時不會回彈。

如果希望物體有彈性,可以配置它的 restitution 。

物理世界的互動之旅:Matter.js入門指南

// 省略部分代碼

let rectA = Matter.Bodies.rectangle(80, 100, 80, 80, {
  restitution: 0 // 設(shè)置彈力
})

let rectB = Matter.Bodies.rectangle(200, 100, 80, 80, {
  restitution: 1 // 設(shè)置彈力
})

let rectC = Matter.Bodies.rectangle(320, 100, 80, 80, {
  restitution: 1.2 // 設(shè)置彈力
})

// 地面
let ground = Matter.Bodies.rectangle(200, 390, 400, 20, {
  isStatic: true,
  render: {
    fillStyle: '#cccccc'
  }
})

// 6. 將所有物體添加到世界中
Matter.Composite.add(engine.world, [rectA, rectB, rectC, ground])

Matter.js 中,物體的回彈力正常取值范圍是 0 ~ 1。其中0表示碰撞后不反彈,1表示碰撞后完全反彈。

如果反彈系數(shù)大于1,就意味著碰撞后物體的能量增加,這是不符合物理規(guī)律的。

但如果你在做游戲,在處理游戲角色的某些技能時也可以讓回彈力超出1。畢竟這是你的世界。


質(zhì)量 mass

在初中物理課上我們知道,質(zhì)量越大,慣性越大。也就是說物體更難改變它的狀態(tài)(靜止或運動狀態(tài))。當(dāng)施加力或者撞擊物體時,質(zhì)量越大的物體會更難加速或者減速,需要更長的時間來達(dá)到相同的速度或者停止。而質(zhì)量越小的物體則更容易改變它的狀態(tài),可以更快地加速或減速。

Matter.js 中,碰撞響應(yīng)的計算是基于物體的質(zhì)量和速度等參數(shù)的。比如,當(dāng)兩個物體相撞時,質(zhì)量越大的物體會對速度的改變產(chǎn)生更小的影響,而質(zhì)量越小的物體會對速度的改變產(chǎn)生更大的影響。

舉個例子,我在畫布中創(chuàng)建3個質(zhì)量不同的矩形,左邊的矩形的質(zhì)量最小,右邊的最大。在回彈力相同的情況下,質(zhì)量越小,回彈的程度就越大。

物理世界的互動之旅:Matter.js入門指南

// 省略部分代碼

// 矩形A
let rectA = Matter.Bodies.rectangle(80, 100, 80, 80, {
  restitution: 1,
  mass: 0.1
})

// 矩形B
let rectB = Matter.Bodies.rectangle(200, 100, 80, 80, {
  restitution: 1,
  mass: 5
})

// 矩形C
let rectC = Matter.Bodies.rectangle(320, 100, 80, 80, {
  restitution: 1,
  mass: 10
})

// 地面
let ground = Matter.Bodies.rectangle(200, 390, 400, 20, {
  isStatic: true,
  render: {
    fillStyle: '#cccccc'
  }
})

Matter.Composite.add(engine.world, [rectA, rectB, rectC, ground])

靜止 isStatic

前面幾個例子中,空中的幾個矩形都會往下掉,但地面卻不會。

這是因為地面元素將 isStatic 設(shè)置為 true 了,所以元素就不會動了。

// 省略部分代碼

let ground = Matter.Bodies.rectangle(200, 390, 400, 20, {
  isStatic: true,
  render: {
    fillStyle: '#cccccc'
  }
})

關(guān)于基礎(chǔ)元素的其他屬性配置,可以看看 『Matter.js官方文檔的 Body 內(nèi)容』。



堆 stack

Matter.js 中允許你將多個物體組合在一起,以便更方便地管理和操作它們。這個方法叫做“堆 stack”。

你可以將多個矩形放在一個 stack 中,然后一起移動它們,或者一起旋轉(zhuǎn)它們,而不需要分別操作每個矩形。這可以大大簡化代碼,并提高代碼的可維護性。

要創(chuàng)建一個 stack,可以使用 Matter.Composites.stack 方法。

用法:Matter.Composites.stack(xx, yy, columns, rows, columnGap, rowGap, callback)

其中的參數(shù)作用:

  • xxyy: stack 的起始位置。
  • columnsrows: stack 的列數(shù)和行數(shù)。
  • columnGap: 相鄰兩個物體之間的列間隔。
  • rowGap: 相鄰兩個物體之間的行間隔。
  • callback: 回調(diào)函數(shù),通常用于生成 stack 中的每個物體。

舉個完整例子

物理世界的互動之旅:Matter.js入門指南

<div id="c"></div>

<script src="../js/matter.js"></script>
<script>
  let engine = Matter.Engine.create()
  
  let render = Matter.Render.create({
    element: document.getElementById('c'), // 綁定頁面元素
    engine: engine, // 綁定引擎
    options: {
      width: 400,
      height: 400,
      wireframes: false,
    }
  })
  
  // 堆
  // 起始位置是 (20, 20),一共6列3行,列間距10,行間距20
  let stack = Matter.Composites.stack(20, 20, 6, 3, 10, 20, function (x, y) {
    return Matter.Bodies.rectangle(x, y, 30, 30)
  })
  
  // 地面
  let ground = Matter.Bodies.rectangle(200, 390, 400, 20, {
    isStatic: true,
    render: {
      fillStyle: '#cccccc'
    }
  })
  
  // 將堆和地面添加到世界里
  Matter.Composite.add(engine.world, [stack, ground])
  
  Matter.Render.run(render)
  
  let runner = Matter.Runner.create()
  Matter.Runner.run(runner, engine)
</script>

這個例子我只給堆和地面添加了注釋,方便工友們尋找這段主要的代碼。

在使用 stack 時,最后的用來創(chuàng)建物體的回調(diào)函數(shù)有 xy 參數(shù),這兩個參數(shù)是 Matter.js 提供的,它會根據(jù)前面幾個參數(shù) (xx, yy, columns, rows, columnGap, rowGap) 來計算每次 xy 的值是多少,而這個 xy 通常用來定義圖形元素的位置。


stack 更大的意義是方便我們集中管理堆中的元素,比如在上面這個例子中,要讓所有立方體自身旋轉(zhuǎn)30度,可以直接在回調(diào)函數(shù)里寫上。

物理世界的互動之旅:Matter.js入門指南

// 省略部分代碼

let stack = Matter.Composites.stack(20, 20, 6, 3, 10, 20, function (x, y) {
  return Matter.Bodies.rectangle(x, y, 30, 30, {
    angle: Math.PI / 180 * 30, // 旋轉(zhuǎn)30度
    restitution: 0.5 // 添加一點回彈力
  })
})

在這個例子中,我還給每個矩形增加了一點回彈力,讓矩形在落地散開后的動畫看上去更符合真實世界的邏輯。


除了能夠方便地給每個矩形都添加屬性外,你還可以給整個堆進行調(diào)整。

比如整體旋轉(zhuǎn)30度(這個效果和上面的例子不一樣?。?/p>

物理世界的互動之旅:Matter.js入門指南

// 省略部分代碼

let stack = Matter.Composites.stack(20, 20, 6, 3, 10, 20, function (x, y) {
  return Matter.Bodies.rectangle(x, y, 30, 30, {
    restitution: 0.5 // 添加一點回彈力
  })
})

// 整個堆旋轉(zhuǎn)30度
Matter.Composite.rotate(stack, Math.PI / 180 * 30, { x: 0, y: 200 })


約束 Constraint

Matter.js 里,約束 Constraint 可以理解為將2個物體綁在一起。

生活中常見的例子蹺蹺板。

物理世界的互動之旅:Matter.js入門指南

不好意思,放錯圖了,下面這張才對

物理世界的互動之旅:Matter.js入門指南

一個簡單的蹺蹺板分為2部分:橫著的板和底座。

把這兩部分綁定在一起就形成蹺蹺板。

Matter.js 中要實現(xiàn)這個功能,用到的就是約束 Constraint。

先簡單體驗一下再說用法。

物理世界的互動之旅:Matter.js入門指南

<div id="c"></div>

<script src="../js/matter.js"></script>
<script>
  let engine = Matter.Engine.create()
  
  let render = Matter.Render.create({
    element: document.getElementById('c'), // 綁定頁面元素
    engine: engine, // 綁定引擎
    options: {
      width: 400,
      height: 400,
      wireframes: false,
    }
  })
  
  // 板子A(紅色)
  let rectA = Matter.Bodies.rectangle(200, 330, 20, 100, {
    isStatic: true,
    render: {
      fillStyle: '#f00'
    },
    collisionFilter: {
      group: -1
    }
  })

  // 板子B(藍(lán)色)
  let rectB = Matter.Bodies.rectangle(200, 330, 200, 20, {
    render: {
      fillStyle: '#00f'
    },
    collisionFilter: {
      group: -1
    }
  })
  
  // 創(chuàng)建旋轉(zhuǎn)約束
  let rotateConstraint = Matter.Constraint.create({
    bodyA: rectA,
    bodyB: rectB,
    length: 0
  })
  
  // 矩形的堆
  let stack = Matter.Composites.stack(20, 30, 4, 3, 10, 20, function (x, y) {
    return Matter.Bodies.rectangle(x, y, 40, 20)
  })
  
  // 圓形的堆
  let stack_circle = Matter.Composites.stack(220, 60, 3, 4, 10, 20, function (x, y) {
    return Matter.Bodies.circle(x, y, 16)
  })
  
  // 地面
  let ground = Matter.Bodies.rectangle(200, 390, 400, 20, {
    isStatic: true,
    render: {
      fillStyle: '#cccccc'
    }
  })
  
  // 將 藍(lán)色和紅色矩形、約束、矩形堆、圓形堆、地面 都添加到世界里
  Matter.Composite.add(engine.world, [rectA, rectB, rotateConstraint, stack, stack_circle, ground])


  Matter.Render.run(render)

  let runner = Matter.Runner.create()
  Matter.Runner.run(runner, engine)
</script>

在上面的例子中,我創(chuàng)建了1個蹺蹺板(由紅色和藍(lán)色矩形組合而成),1堆小矩形,1堆小圓形,1個地面。

小矩形堆和小圓形堆都做自由落體。

蹺蹺板使用了 Matter.Constraint.create 做約束處理,其中的參數(shù) bodyAbodyB 用來指定要約束的兩個物體。length 表示約束的長度,設(shè)置為0的話,他們之間的約束點就沒有任何挪動的空間,這就和蹺蹺板的原理一樣了。


Matter.Constraint.create(options) 的配置對象包含以下屬性:

  • options:約束的選項。
  • options.bodyA:類型為 Matter.Body,約束連接的第一個物體。
  • options.pointA:類型為 Matter.Vector,約束連接的第一個物體上的點。
  • options.bodyB:類型為 Matter.Body,約束連接的第二個物體。
  • options.pointB:類型為 Matter.Vector,約束連接的第二個物體上的點。
  • options.length:類型為 number,約束的初始長度。
  • options.stiffness:類型為 number,約束的剛度系數(shù)。
  • options.damping:類型為 number,約束的阻尼系數(shù)。
  • options.render:約束的渲染選項。
  • options.render.visible:類型為 boolean,表示約束是否可見,默認(rèn)為 true
  • options.render.lineWidth:類型為 number,表示約束線條的寬度。
  • options.render.strokeStyle:類型為 string,表示約束線條的顏色。


鼠標(biāo)約束

這里所指的耗子約束是指給鼠標(biāo)添加操作物體的功能。

要實現(xiàn)拖拽物體的功能,需要以下幾個步驟:

  1. 創(chuàng)建鼠標(biāo)實例 Matter.Mouse.create
  2. 給鼠標(biāo)添加約束 Matter.MouseConstraint.create。
  3. 將鼠標(biāo)約束添加到物理引擎中。

物理世界的互動之旅:Matter.js入門指南

<div id="c"></div>

<script src="../js/matter.js"></script>
<script>
  let engine = Matter.Engine.create()
  
  let render = Matter.Render.create({
    element: document.getElementById('c'), // 綁定頁面元素
    engine: engine, // 綁定引擎
    options: {
      width: 400,
      height: 400,
      wireframes: false,
    }
  })
  
  let box = Matter.Bodies.rectangle(80, 100, 80, 80, {
    restitution: 0.3,
    mass: 0.1
  })

  let ground = Matter.Bodies.rectangle(200, 390, 400, 20, {
    isStatic: true,
    render: {
      fillStyle: '#cccccc'
    }
  })

  // 創(chuàng)建鼠標(biāo)實例
  let mouse = Matter.Mouse.create(render.canvas)
  
  // 給鼠標(biāo)添加約束
  let mouseConstraint = Matter.MouseConstraint.create(engine, {
    mouse: mouse,
    constraint: {
      stiffness: 0.2,
      render: {
        visible: false // 默認(rèn)為 true,會顯示鼠標(biāo)拖拽軌跡
      }
    }
  })

  // 將鼠標(biāo)約束添加到物理引擎中
  Matter.Composite.add(engine.world, [box, ground, mouseConstraint]);

  Matter.Render.run(render)

  let runner = Matter.Runner.create()

  Matter.Runner.run(runner, engine)
</script>


事件監(jiān)聽

Matter.js 中,可以使用 Events.on 方法來監(jiān)聽各種事件,包括鼠標(biāo)事件、碰撞事件等等。


常用鼠標(biāo)事件

例如這樣監(jiān)聽鼠標(biāo)的各種事件(隨便舉點例子)

// 省略部分代碼


// 創(chuàng)建一個 Mouse 實例
let mouse = Matter.Mouse.create(render.canvas)

let mouseConstraint = Matter.MouseConstraint.create(engine, {
  mouse: mouse
})

// 監(jiān)聽鼠標(biāo)事件

// 監(jiān)聽鼠標(biāo)按下事件
Matter.Events.on(mouseConstraint, 'mousedown', function(event) {
  console.log('按下')
})

// 監(jiān)聽鼠標(biāo)移動事件
Matter.Events.on(mouseConstraint, "mousemove", function(event) {
  console.log('移動')
})

// 監(jiān)聽鼠標(biāo)抬起事件
Matter.Events.on(mouseConstraint, "mouseup", function(event) {
  console.log('抬起')
})

// 監(jiān)聽鼠標(biāo)拖拽剛體 - 開始拖拽
Matter.Events.on(mouseConstraint, 'startdrag', function(event) {
  console.log('開始拖拽')
})

// 監(jiān)聽鼠標(biāo)拖拽剛體 - 結(jié)束拖拽
Matter.Events.on(mouseConstraint, 'enddrag', function(event) {
  console.log('結(jié)束拖拽')
})

Matter.Composite.add(engine.world, mouseConstraint)

監(jiān)聽碰撞

Matter.js 中,用 Matter.Events.on 去監(jiān)聽 collisionStart 事件就能知道物體的碰撞。

除了 collisionStart 外,還有其他監(jiān)聽周期。

  • collisionStart:當(dāng)兩個物體開始碰撞時觸發(fā)。
  • collisionActive:當(dāng)兩個物體持續(xù)碰撞時觸發(fā)。
  • collisionEnd:當(dāng)兩個物體停止碰撞時觸發(fā)。

我用 collisionStart 舉例:

物理世界的互動之旅:Matter.js入門指南

// 省略部分代碼

// 創(chuàng)建一個矩形
var box = Matter.Bodies.rectangle(200, 100, 80, 80, {
  restitution: 1
})

// 地面
let ground = Matter.Bodies.rectangle(200, 390, 400, 20, {
  isStatic: true,
  render: {
    fillStyle: '#cccccc'
  }
})

// 添加剛體到引擎中
Matter.Composite.add(engine.world, [box, ground]);

// 監(jiān)聽碰撞事件
Matter.Events.on(engine, 'collisionStart', function(event) {
  const pairs = event.pairs
  pairs.forEach(pair => {
    console.log(pair)
  })
})

上面這個例子中,我給 box 設(shè)置了回彈力,它首次落地后回彈了2次,首次落地加2次回彈一共就觸發(fā)了3次碰撞,所以在控制臺輸出了3次碰撞的結(jié)果。

其中,pairs 是指一對正在碰撞的物體。當(dāng)兩個物體相互碰撞時,它們就被組成為一個 pair 對象。

我們可以通過 event.pairs 屬性來訪問有關(guān)碰撞的更多信息。



代碼倉庫

點擊下面的鏈接可以獲取到本文所有完整demo,倉庫的代碼還會不定期更新~

? Matter.js 案例倉庫



推薦閱讀

??《眨個眼就學(xué)會了Pixi.js》

??《P5.js 光速入門》

??《Fabric.js從入門到膨脹》


點贊 + 關(guān)注 + 收藏 = 學(xué)會了
代碼倉庫文章來源地址http://www.zghlxwxcb.cn/news/detail-711123.html

到了這里,關(guān)于物理世界的互動之旅:Matter.js入門指南的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 關(guān)于 Python 爬蟲 JS 逆向的入門指南

    請注意,這篇指南只是一個概述,為了深入理解和實踐,你可能需要額外的學(xué)習(xí)和實踐。 ? ? ? ? Python 爬蟲經(jīng)常遇到需要逆向 JavaScript 生成的網(wǎng)站內(nèi)容和邏輯的情況。這種技能對于爬取動態(tài)網(wǎng)站,尤其是那些使用了復(fù)雜 JS 邏輯和反爬蟲技術(shù)的網(wǎng)站,尤其重要。 Python 爬蟲概

    2024年01月16日
    瀏覽(64)
  • TypeScript入門指南:從JS到TS的轉(zhuǎn)變

    上一篇文章中我提到了會設(shè)立專欄去專門跟大家分享一下我在 TypeScript 學(xué)習(xí)中的收獲和筆記,以及一些經(jīng)驗分享,專欄已經(jīng)創(chuàng)建,從這篇開始,每天都會更新一篇文章跟大家分享,想要學(xué)習(xí)探討的小伙伴可以持續(xù)關(guān)注一下。 在 Web 前端開發(fā)中,JavaScript(JS)一直是主流的編程

    2024年02月09日
    瀏覽(15)
  • 【C++入門:C++世界的奇幻之旅】

    【C++入門:C++世界的奇幻之旅】

    1. 什么是C++ 2. C++發(fā)展史 3. C++的重要性 4. C++ 5. 命名空間 6. C++輸入輸出 7. 缺省參數(shù) 8. 函數(shù)重載 9. 引用 10. 內(nèi)聯(lián)函數(shù) 11. auto(C++11) 12. 基于范圍的for循環(huán)(C++11) 13. 指針空值---nullptr(C++11)05.? ????????C語言是結(jié)構(gòu)化和模塊化的語言,適合處理較小規(guī)模的程序。對于

    2024年02月08日
    瀏覽(23)
  • rabbitMQ入門指南:管理頁面全面指南及實戰(zhàn)操作

    rabbitMQ入門指南:管理頁面全面指南及實戰(zhàn)操作

    ??在前一篇文章在centos stream 9環(huán)境中部署和使用rabbitMQ,我們已經(jīng)詳細(xì)介紹了如何在CentOS下安裝和配置RabbitMQ,我們不僅啟動了RabbitMQ服務(wù),還通過插件安裝了管理后臺,并且登陸到管理頁面。 ??RabbitMQ管理后臺提供了一個直觀的用戶界面,允許我們查看和管理RabbitMQ服務(wù)器

    2024年02月12日
    瀏覽(29)
  • 數(shù)據(jù)結(jié)構(gòu)入門指南:鏈表(新手避坑指南)

    數(shù)據(jù)結(jié)構(gòu)入門指南:鏈表(新手避坑指南)

    目錄 前言 1.鏈表 1.1鏈表的概念 ?1.2鏈表的分類 1.2.1單向或雙向 1.2.2.帶頭或者不帶頭 1.2.33. 循環(huán)或者非循環(huán) 1.3鏈表的實現(xiàn) ?定義鏈表 總結(jié) ????????前邊我們學(xué)習(xí)了順序表,順序表是數(shù)據(jù)結(jié)構(gòu)中最簡單的一種線性數(shù)據(jù)結(jié)構(gòu),今天我們來學(xué)習(xí)鏈表,難度相較于順序表會大幅增

    2024年02月15日
    瀏覽(30)
  • HarmonyOS云開發(fā)基礎(chǔ)認(rèn)證題目記錄——包括第一期:Serverless基礎(chǔ)、第二期:快速構(gòu)建用戶認(rèn)證系統(tǒng)、第三期:云函數(shù)入門指南、第四期:云數(shù)據(jù)庫入門指南、第五期:云存儲入門指南。

    1. 【判斷題】? 應(yīng)用架構(gòu)的演進依次經(jīng)歷了微服務(wù)架構(gòu)、單體架構(gòu)、Serverless架構(gòu)等階段。 錯誤 2. 【判斷題】? 認(rèn)證服務(wù)手機號碼登錄需要填寫國家碼。 正確 3. 【判斷題】? 認(rèn)證服務(wù)在綁定微信賬號后就不能再綁定QQ賬號了。 錯誤 4. 【判斷題】? 云函數(shù)可以根據(jù)函數(shù)的實際

    2024年02月05日
    瀏覽(133)
  • (入門向)面向萌新的算法比賽入門指南

    (入門向)面向萌新的算法比賽入門指南

    算法是指解決問題或完成特定任務(wù)的一系列明確指令或步驟集合。它是一個定義良好、逐步執(zhí)行的操作序列,用于將輸入轉(zhuǎn)換為輸出。算法可用于計算、數(shù)據(jù)處理、自動化控制、問題解決等各個領(lǐng)域。 算法通常由一系列簡單的操作組成,這些操作可以是基本的數(shù)學(xué)運算、邏輯

    2024年02月07日
    瀏覽(25)
  • HTML 入門指南

    HTML 入門指南

    參考:HTML 教程- (HTML5 標(biāo)準(zhǔn)) HTML:超級文本標(biāo)記語言(HyperText Markup Language) “超文本” 就是指頁面內(nèi)可以包含圖片、鏈接等非文字內(nèi)容。 “標(biāo)記” 就是使用標(biāo)簽的方法將需要的內(nèi)容包括起來。例如: a herf=\\\"sfdsfsd\\\"www.itcast.cn/a img/ HTML 用于 編寫網(wǎng)頁 。平時上網(wǎng)通過瀏覽器看到

    2024年02月20日
    瀏覽(23)
  • 程序員入門指南

    程序員入門指南

    本文作者:futz12 ,szx0427 雖然本人由于多方面原因沒有選擇計科/軟工(對AI和圖形算法的熱愛),但是根據(jù)多年研究經(jīng)驗(業(yè)余的),打算給各位推薦基本相關(guān)的書和軟件(主要是學(xué)習(xí)思路)。 注意:學(xué)習(xí)編程不一定是搞那些絢麗的界面,開發(fā)有趣的游戲。很多有用且享譽世

    2024年02月14日
    瀏覽(23)
  • IOS小白入門指南

    ????????加入ios 項目已經(jīng)一個多月了,本篇文章主要介紹IOS開發(fā)入門的一些基礎(chǔ)知識,幫助想學(xué)習(xí)iOS開發(fā)的人更有效率地學(xué)習(xí)。 目錄 需要的計算機基礎(chǔ)??? 開發(fā)語言選擇 IOS兩種開發(fā)語言的異同 Objective-C和swift的相同點: 二者的不同點: 開發(fā)環(huán)境---XCode介紹 基本信息 S

    2024年02月01日
    瀏覽(22)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包