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

Phaser切割物体后,如何给fromVertices生成的新形状填充红色?

问题描述

我正在制作一个可将物体切成两半的小型游戏,需要让切割后生成的新形状填充为红色,但当前设置无效。第94-99行是新形状的创建代码,目前正在调试第99行。我曾尝试使用.render.fillStyle来设置红色填充,但没有效果,恳请各位提供帮助!

切割后形状未正确填充红色


游戏逻辑代码(level1.js)

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: false,
            }
        }
    }
    level1 = new Phaser.Game(gameConfig);
    window.focus();

}
//document.body.style = 'margin:0;';

class scene1 extends Phaser.Scene{
    constructor(){
        super("PlayGame");
    }
create(){

    
    let path = [{x:0, y:0}, {x:level1.config.width, y:0}, {x:level1.config.width, y:50},{x: 0, y:50} ];
        this.polygon = this.matter.add.fromVertices(level1.config.width/2, 70, path, { isStatic: true });
        this.polygon.gameObject = this.add.polygon(level1.config.width/2, 70 , path, 0xff0000);
        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(pointer){
        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){ 
              body.gameObject.destroy();
              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: true });
            let topleft = this.matter.bodyBounds.getTopLeft(slicedBody); 
            slicedBody.gameObject = this.add.polygon(topleft.x, topleft.y, polyObject, 0xff0000);



            }.bind(this));
        }
    };

HTML页面代码

<!DOCTYPE html>
<html>
    <head>
        <script src = "phaser.min.js"></script>
        <script src = "polyk.js"></script>
        <script src = "level1.js"></script>
        <script src="//cdn.jsdelivr.net/npm/phaser/dist/phaser.min.js"></script>
        <script src="http://polyk.ivank.net/polyk.js"></script>

        <style type = "text/css">
            body{
                background-image:url("gamebackground.jpg");
                height: 100%;
                background-position: center;
                background-repeat: no-repeat;
                background-size: cover;
                padding: 0px;
                margin: 0px;
            }

    </head>
    <body>
        <div id = "thegame"></div>
        <script>
    </body>
</html>

入口文件代码

import Phaser from 'phaser'

import { scene1 } from 'Desktop/diss/level1.js'
import { scene2 } from 'Desktop/diss/level2.js'
import { scene3 } from 'Desktop/diss/level3.js'
import { scene4 } from 'Desktop/diss/level4.js'
import { scene5 } from 'Desktop/diss/level5.js'
import { scene5 } from 'Desktop/diss/level6.js'

const gameConfig = {
  type: Phaser.AUTO,
  width: 400,
  height: 400,
  backgroundColor: '#000088',
  parent: 'phaser-example',
  scene: [scene1, scene2, scene3, scene4, scene5, scene6]
};

const game = new Phaser.Game(gameConfig)

game()

解决方案

问题出在切割后多边形的坐标设置上:你用物理体的左上角坐标作为add.polygon的位置,但该方法的前两个参数是多边形的原点坐标,而非左上角坐标。这导致多边形位置偏移,填充色无法正常显示。

修改第98-99行代码:

// 原代码
let topleft = this.matter.bodyBounds.getTopLeft(slicedBody); 
slicedBody.gameObject = this.add.polygon(topleft.x, topleft.y, polyObject, 0xff0000);

// 修改后
slicedBody.gameObject = this.add.polygon(sliceCentre.x, sliceCentre.y, polyObject, 0xff0000);

另外,HTML中重复引入了Phaser和polyk.js,建议只保留一套引入避免冲突:

<script src="//cdn.jsdelivr.net/npm/phaser/dist/phaser.min.js"></script>
<script src="http://polyk.ivank.net/polyk.js"></script>
<script src = "level1.js"></script>

内容的提问来源于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:58:05