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.
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.
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); } }
你的代码中有很多内容,很难让它正常工作。
最好的做法是发布一个迷你可运行代码,就像这里提到的这里。
不过,一个简单快速的解决方案是使用
canvasTexture
来创建封面纹理,这样你就可以直接从这个对象访问上下文。这是一个我会这样做的简短演示:
(基于这个答案的概念)