使用Matter.js时画布无内容显示,请求技术协助
Matter.js画布无内容显示问题排查与解决
问题描述
跟随Matter.js教程开发时,画布仅显示白色区域,无任何物理体内容,尝试过其他解决方案无效,以下是使用VS Code编写的HTML和JS代码:
HTML代码
<!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>square.</title> <script src="https://cdnjs.cloudflare.com/ajax/libs/matter-js/0.17.1/matter.min.js"></script> <script src="scripts.js"></script> <style> canvas { position: relative; width: 800px; height: 600px; background-color: white; } </style> </head> <body onload='init()'> <div id="areaToRender"> </div> </body> </html>
JS代码(原代码)
let Engine = Matter.Engine Render = Matter.Render Runner = Matter.Runner Bodies = Matter.Bodies Composite = Matter.Composite Composties = Matter. Composites Constraint = Matter.Constraint Mouse = Matter.Mouse let MouseConstraint = Matter.MouseConstraint Events = Matter.Events let engine; let render; let runner; function init() { engine = Engine.create(); } render = Render.create({ element: document.getElementById("areaToRender"), engine: engine, options: { width: 800, height: 600, pixelRatio: 1, background : '#fafafa', wireframes: false } }); Render.run(render); runner = Runner.create(); Runner.run(runner, engine); let lastClear = "(not given)" function clearWorld(exampleName) { if (lastClear != exampleName) { lastClear = exampleName Matter.Composite.clear(engine.world, false) } } function StartBoxes() { clearWorld("Boxes") let boxA = Bodies.rectangle(400, 200, 80, 80); let boxB = Bodies.rectangle(400, 200, 80, 80, { render: { fillStyle: 'red', strokeStyle: 'blue', lineWidth: 3 } }); let ground = Bodies.rectangle(400, 610, 810, 60, { isStatic: true}); Composite.add(engine.world, [boxA, boxB, ground]); Engine.update(engine); }
问题根源与修复方案
核心问题:
StartBoxes函数未被调用
所有物理体的创建和添加逻辑都在StartBoxes函数中,但代码中没有任何触发该函数的逻辑,导致物理世界为空,画布自然无内容。变量声明语法错误
原代码中Composties = Matter. Composites和Mouse = Matter.Mouse存在多余空格,会导致变量未正确绑定到Matter.js的对应模块,修正后:let Engine = Matter.Engine, Render = Matter.Render, Runner = Matter.Runner, Bodies = Matter.Bodies, Composite = Matter.Composite, Composites = Matter.Composites, Constraint = Matter.Constraint, Mouse = Matter.Mouse, MouseConstraint = Matter.MouseConstraint, Events = Matter.Events;渲染代码执行时机错误
原代码中Render.create、Render.run等逻辑在init函数外部执行,而engine是在body onload触发的init中才创建的,这会导致渲染器初始化时engine可能尚未完成创建,需将这些逻辑移到init函数内部。画布尺寸配置冲突
原HTML的CSS中设置canvas宽500px高400px,但Render选项中设置的是800x600,会导致画布缩放变形,已统一为800x600。
修正后的完整JS代码
let Engine = Matter.Engine, Render = Matter.Render, Runner = Matter.Runner, Bodies = Matter.Bodies, Composite = Matter.Composite, Composites = Matter.Composites, Constraint = Matter.Constraint, Mouse = Matter.Mouse, MouseConstraint = Matter.MouseConstraint, Events = Matter.Events; let engine; let render; let runner; let lastClear = "(not given)" function init() { // 创建引擎 engine = Engine.create(); // 创建渲染器并绑定到指定元素 render = Render.create({ element: document.getElementById("areaToRender"), engine: engine, options: { width: 800, height: 600, pixelRatio: 1, background: '#fafafa', wireframes: false } }); // 启动渲染器和运行器 Render.run(render); runner = Runner.create(); Runner.run(runner, engine); // 调用创建物理体的函数 StartBoxes(); } function clearWorld(exampleName) { if (lastClear !== exampleName) { lastClear = exampleName; Matter.Composite.clear(engine.world, false); } } function StartBoxes() { clearWorld("Boxes"); let boxA = Bodies.rectangle(400, 200, 80, 80); let boxB = Bodies.rectangle(400, 200, 80, 80, { render: { fillStyle: 'red', strokeStyle: 'blue', lineWidth: 3 } }); let ground = Bodies.rectangle(400, 610, 810, 60, { isStatic: true}); Composite.add(engine.world, [boxA, boxB, ground]); }
验证效果
修正后,页面加载时init函数会自动执行,创建引擎、渲染器,并调用StartBoxes生成物理体,画布上会显示两个重叠的矩形(一个默认样式,一个红色填充蓝色边框)和底部的静态地面,物理体也会正常下落并与地面发生碰撞。
内容的提问来源于stack exchange,提问作者OverTheMoonAgain
相关产品推荐
相关产品推荐

