You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 17:19:55