如何为Phaser中Matter物理矩形及切割后新形状添加颜色?
问题:Phaser中Matter物理引擎下,切割后的形状无法添加颜色
我用this.matter.add.rectangle创建矩形,开发一款切割形状的游戏。移除.matter后能给形状加颜色,但保留物理特性时无法添加,尤其是切割后的两个新形状需要填充为红色。
我的代码如下:
let level1; window.onload = function() { let gameConfig = { type: Phaser.AUTO, scale: { mode: Phaser.Scale.FIT, autoCenter: Phaser.Scale.CENTER_BOTH, parent: "thegame", width: 600, height: 700 }, scene: scene1, physics: { default: "matter", matter: { gravity: { y: 0 }, debug: true, } } } level1 = new Phaser.Game(gameConfig); window.focus(); } class scene1 extends Phaser.Scene{ constructor(){ super("PlayGame"); } create(){ this.matter.world.update30Hz(); this.matter.world.setBounds(10, 10, level1.config.width - 20, level1.config.height - 10); let rect = this.add.rectangle(level1.config.width / 2, level1.config.height / 2, 600, 100, 0xff0000); this.matter.add.gameObject(rect); this.lineGraphics = this.add.graphics(); this.input.on("pointerdown", this.startDrawing, this); this.input.on("pointerup", this.stopDrawing, this); this.input.on("pointermove", this.keepDrawing, this); this.isDrawing = false; this.add.text(13, 11, 'Level 1',{fontFamily: 'Georgia, "Goudy Bookletter 1911", Times, serif'}); } startDrawing(){ this.isDrawing = true; } keepDrawing(pointer){ if(this.isDrawing){ this.lineGraphics.clear(); this.lineGraphics.lineStyle(1, 0xff0000); this.lineGraphics.moveTo(pointer.downX, pointer.downY); this.lineGraphics.lineTo(pointer.x, pointer.y); this.lineGraphics.strokePath(); } } stopDrawing(pointer){ this.lineGraphics.clear(); this.isDrawing = false; let bodies = this.matter.world.localWorld.bodies; let toBeSliced = []; let toBeCreated = []; for(let i = 0; i < bodies.length; i++){ let vertices = bodies[i].parts[0].vertices; let pointsArray = []; vertices.forEach(function(vertex){ pointsArray.push(vertex.x, vertex.y) }); let slicedPolygons = PolyK.Slice(pointsArray, pointer.downX, pointer.downY, pointer.upX, pointer.upY); if(slicedPolygons.length > 1){ toBeSliced.push(bodies[i]); slicedPolygons.forEach(function(points){ toBeCreated.push(points) }) } } toBeSliced.forEach(function(body){ this.matter.world.remove(body) }.bind(this)) toBeCreated.forEach(function(points){ let polyObject = []; for(let i = 0; i < points.length / 2; i ++){ polyObject.push({ x: points[i * 2], y: points[i * 2 + 1] }) } let sliceCentre = Phaser.Physics.Matter.Matter.Vertices.centre(polyObject) let slicedBody = this.matter.add.fromVertices(sliceCentre.x, sliceCentre.y, polyObject, { isStatic: false }); this.add.text(13, 11, 'Level 1 Complete!',{fontFamily: 'Georgia, "Goudy Bookletter 1911", Times, serif'}); }.bind(this)) } };
解决方案
this.matter.add.fromVertices仅创建物理碰撞体,不会自动生成视觉图形。你需要为每个切割后的物理体手动绘制填充图形,并绑定到物理体上同步运动。
修改stopDrawing方法中toBeCreated.forEach的代码,添加图形绘制与绑定逻辑:
toBeCreated.forEach(function(points){ let polyObject = []; for(let i = 0; i < points.length / 2; i ++){ polyObject.push({ x: points[i * 2], y: points[i * 2 + 1] }) } let sliceCentre = Phaser.Physics.Matter.Matter.Vertices.centre(polyObject) // 创建物理体 let slicedBody = this.matter.add.fromVertices(sliceCentre.x, sliceCentre.y, polyObject, { isStatic: false }); // 1. 创建红色填充的多边形图形 let shapeGraphics = this.add.graphics(); shapeGraphics.fillStyle(0xff0000); // 设置填充色为红色 shapeGraphics.beginPath(); // 以物理体中心为原点绘制,避免位置偏移 shapeGraphics.moveTo(polyObject[0].x - sliceCentre.x, polyObject[0].y - sliceCentre.y); for(let j = 1; j < polyObject.length; j++){ shapeGraphics.lineTo(polyObject[j].x - sliceCentre.x, polyObject[j].y - sliceCentre.y); } shapeGraphics.closePath(); shapeGraphics.fillPath(); // 2. 将图形绑定到物理体,自动同步位置与旋转 this.matter.add.gameObject(shapeGraphics, slicedBody); this.add.text(13, 11, 'Level 1 Complete!',{fontFamily: 'Georgia, "Goudy Bookletter 1911", Times, serif'}); }.bind(this))
关键说明:
- 绘制图形时以物理体中心为原点计算顶点偏移,避免图形与物理体错位
- 使用
this.matter.add.gameObject绑定图形与物理体,Phaser会自动同步两者的位置和旋转,无需手动监听更新
内容的提问来源于stack exchange,提问作者engineeringstudent1999
相关产品推荐
相关产品推荐

