suchen

Heim  >  Fragen und Antworten  >  Hauptteil

Gibt es eine andere Möglichkeit, den Fortschritt beim Löschen von Pixeln in Phaser zu verfolgen?

<p>Ich versuche also, ein Rubbelkartenspiel zu entwickeln, bei dem der Benutzer die Karte freirubbeln muss, um freizulegen, was sich darunter befindet. Ich möchte überprüfen, ob der Benutzer 70 % der Leinwand zerkratzt hat, um alles freizulegen. Ich versuche, Phaser zu verwenden, um diese Funktionalität zu implementieren, aber es funktioniert nicht. </p> <p>Ich habe versucht, Bilddaten zu berechnen, um ein Array von Pixeln zu erhalten, aber es wird ein Array mit ausschließlich Nullen zurückgegeben. Ich verwende die Funktion „calcuteScratchRatio“ im folgenden Code.</p> <pre class="brush:php;toolbar:false;">BaseScene aus "./BaseScene" importieren; const SKY_IMAGE = "Himmel"; const SKY_IMAGE_BLACK = "skyblack"; const BOARD = "Board"; const HEADER_ACT = "header_act"; const KEY_BRUSH = "Pinsel"; const BGGAME = "bg-game"; Standardklasse exportieren Scratch erweitert BaseScene { Konstruktor(config) { super("Scratch", { ...config }); this.config = config; this.isDown = false; this.renderTexture = null; this.brush = null; this.erasedPixels = 0; this.screenCenter = [config.width / 2, config.height / 2]; } erstellen() { super.create(); this.cover = this.make.image({ Schlüssel: SKY_IMAGE_BLACK, hinzufügen: falsch, }); this.board = this.make.image({ Tastatur, hinzufügen: falsch, }); 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); let helloWorld = this.add .text(0, 0, „Hallo Welt“) .setFont("20px Arial") .setColor("#ffffff"); const container = this.add.container(headerinfo.x, headerinfo.y); container.add(helloWorld); } Abkratzen() { this.add .image(this.screenCenter[0] - 160, this.screenCenter[1], SKY_IMAGE) .setScale(0.7); this.cover.setOrigin(0, 0); const width = this.cover.width; const height = this.cover.height; console.log(width, height); const rt = this.add.renderTexture( this.screenCenter[0] – 160, this.screenCenter[1], Breite * 0,7, Höhe * 0,71 ); this.isRenderTextureErased = false; this.erasureThreshold = 0,99; rt.setOrigin(0.5, 0.5); rt.draw(this.cover); //, Breite * 0,5, Höhe * 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({ Schlüssel: KEY_BRUSH, hinzufügen: falsch, }); this.renderTexture = rt; } handlePointerDown(pointer) { this.isDown = true; this.handlePointerMove(pointer); } handlePointerMove(pointer) { if (!this.isDown) { zurückkehren; } const x = pointer.x - this.renderTexture.x + this.renderTexture.width * 0,5; const y = pointer.y - this.renderTexture.y + this.renderTexture.height * 0,5; this.renderTexture.erase(this.brush, x, y); const result = this.calculateScratchRatio(x, y); console.log("result", result); }berechneScratchRatio(x, y) { const Textur = this.textures.get(SKY_IMAGE_BLACK); console.log(texture); if (!texture) { console.error(`Textur mit Schlüssel '${SKY_IMAGE_BLACK}' nicht gefunden.`); 0 zurückgeben; } console.log(texture); const canvas = document.createElement("canvas"); canvas.width = textur.source[0].width; console.log("canvas.width", canvas.width); canvas.height = textur.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); const pixel = imageData.data; console.log(imageData, pixel); let erasedCount = 0; for (let i = 3; i < pixels.length; i += 4) { const alpha = pixels[i + 3]; if (alpha < 128) { erasedCount++; } } const totalPixels = canvas.width * canvas.height; const scratchRatio = (erasedCount / totalPixels) * 100; return Math.round(scratchRatio); } }</pre> <p><br /></p>
P粉928591383P粉928591383456 Tage vor671

Antworte allen(1)Ich werde antworten

  • 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>

    Antwort
    0
  • StornierenAntwort