首页  >  问答  >  正文

有没有其他办法来跟踪Phaser中擦除像素的进度?

<p>所以我正在尝试创建一个刮刮卡游戏,用户需要刮开卡片来揭示下面的内容。我想要检查用户是否刮开了画布的70%来全部揭示。我正在尝试使用phaser来实现这个功能,但是它不起作用。</p> <p>我尝试计算imagedata以获取像素数组,但是它返回一个全为零的数组。我在下面的代码中使用了calculateScratchRatio函数。</p>
从“./BaseScene”导入BaseScene;

const SKY_IMAGE = "天空";
const SKY_IMAGE_BLACK = "天黑";
const BOARD =“板”;
const HEADER_ACT = "header_act";
const KEY_BRUSH = "画笔";
const BGGAME = "bg 游戏";

导出默认类 Scratch 扩展 BaseScene {
  构造函数(配置){
    超级(“划痕”,{...配置});
    this.config = 配置;
    this.isDown = false;
    this.renderTexture = null;
    this.brush = null;
    this.erasedPixels = 0;
    this.screenCenter = [config.width / 2, config.height / 2];
  }

  创造() {
    超级.create();
    this.cover = this.make.image({
      键:SKY_IMAGE_BLACK,
      添加:假,
    });
    this.board = this.make.image({
      键盘,
      添加:假,
    });
    this.ScratchOff();
    this.add.image(...this.screenCenter, BOARD).setScale(0.7);
    console.log(this.board.getBounds());
    const headerinfo = this.add
      .image(this.screenCenter[0] - 160, 130, "header_act")
      .setScale(0.7);
    让 helloWorld = this.add
      .text(0, 0, "你好世界")

      .setFont("20px 宋体")
      .setColor("#ffffff");

    const 容器 = this.add.container(headerinfo.x, headerinfo.y);
    容器.add(helloWorld);
  }

  刮掉(){
    这个.add
      .image(this.screenCenter[0] - 160, this.screenCenter[1], SKY_IMAGE)
      .setScale(0.7);

    this.cover.setOrigin(0, 0);

    const 宽度 = this.cover.width;
    const height = this.cover.height;
    控制台.log(宽度,高度);

    const rt = this.add.renderTexture(
      this.screenCenter[0] - 160,
      这个.screenCenter[1],
      宽度*0.7,
      高度*0.71
    );
    this.isRenderTextureErased = false;
    this.erasureThreshold = 0.99;
    rt.setOrigin(0.5, 0.5);
    rt.draw(this.cover); //,宽度*0.5,高度*0.5)

    rt.setInteractive();
    rt.on(Phaser.Input.Events.POINTER_DOWN, this.handlePointerDown, this);
    rt.on(Phaser.Input.Events.POINTER_MOVE, this.handlePointerMove, this);
    rt.on(Phaser.Input.Events.POINTER_UP, () => (this.isDown = false));

    this.brush = this.make.image({
      键:KEY_BRUSH,
      添加:假,
    });

    this.renderTexture = rt;
  }

  处理指针向下(指针){
    this.isDown = true;
    this.handlePointerMove(指针);
  }

  处理指针移动(指针){
    if (!this.isDown) {
      返回;
    }
    const x = 指针.x - this.renderTexture.x + this.renderTexture.width * 0.5;
    常量 y =
      指针.y - this.renderTexture.y + this.renderTexture.height * 0.5;
    this.renderTexture.erase(this.brush, x, y);
    const 结果 = this.calculateScratchRatio(x, y);
    console.log(“结果”, 结果);
  }计算划痕比(x,y){
    const 纹理 = this.textures.get(SKY_IMAGE_BLACK);
    控制台.log(纹理);
    如果(!纹理){
      console.error(`未找到带有键“${SKY_IMAGE_BLACK}”的纹理。`);
      返回0;
    }

    控制台.log(纹理);
    const canvas = document.createElement("canvas");
    canvas.width =texture.source[0].width;
    console.log("canvas.width", canvas.width);
    canvas.height =texture.source[0].height;
    const context = canvas.getContext("2d");
    context.drawImage(texture.source[0].image, 0, 0);

    const imageData = context.getImageData(0, 0, canvas.width, canvas.height);

    常量像素 = imageData.data;
    console.log(imageData, 像素);
    让擦除计数 = 0;

    for (令 i = 3; i ></p>
P粉928591383P粉928591383403 天前624

全部回复(1)我来回复

  • P粉207483087

    P粉2074830872023-08-15 19:19:20

    你的代码中有很多内容,很难让它正常工作。
    最好的做法是发布一个迷你可运行代码,就像这里提到的这里

    不过,一个简单快速的解决方案是使用canvasTexture来创建封面纹理,这样你就可以直接从这个对象访问上下文。

    这是一个我会这样做的简短演示:
    (基于这个答案的概念)

    document.body.style = 'margin:0;';
     
    class ScratchScene extends Phaser.Scene {
      constructor() {
        super('ScratchScene')
      }
      
      create(){
    
        let helperGraphics = this.make.graphics({x:0, y: 0, add: false});
        helperGraphics.fillStyle(0xff0000);
        helperGraphics.fillRect(0, 0, 200, 50 );
        helperGraphics.generateTexture('cover', 200, 50);
        
        let coverImage = this.textures.get('cover').getSourceImage()
        this.coverHelperCanvas = this.textures.createCanvas('coverTexture', 200, 50)
        this.coverHelperCanvas.draw(0, 0, coverImage)
        this.coverHelperCanvas.context.globalCompositeOperation = 'destination-out'
          
        this.precent = this.add.text(10 , 10, '' );
    
        this.add.text( config.width/2, config.height / 2, 'YOU WON')
          .setOrigin(.5)
          .setFontSize(20);
        
        let cover = this.add.image(config.width/2, config.height / 2, 'coverTexture')
            .setInteractive();
          
        cover.on('pointermove', this.clearCover, this);
        
        this.checkPercent();
      }
      
      checkPercent(){
          let full = 200 * 50;
          let { data } =  this.coverHelperCanvas.context.getImageData(0, 0,200, 50);
          let current = data.filter((v,i) => ((i + 1) % 4 == 0) && v > 0).length;
          this.precent.setText(`Cover Percent: ${ (current  / full * 100).toFixed(2) }%` );
      }
      
      clearCover(e, x, y){
        let radius = 10;
        this.coverHelperCanvas.context.beginPath()
        this.coverHelperCanvas.context.arc(x, y, radius, 0, Math.PI * 2, false)
        this.coverHelperCanvas.context.fill();
        this.coverHelperCanvas.update();
        this.checkPercent();
      }
    }
    
    var config = {
        type: Phaser.AUTO,
        width: 536,
        height: 163,
        scene: [ScratchScene]
    }; 
    
    new Phaser.Game(config);
    console.clear();
    <script src="https://cdn.jsdelivr.net/npm/phaser/dist/phaser.min.js"></script>

    回复
    0
  • 取消回复