그래서 저는 사용자가 카드를 긁어 밑에 무엇이 있는지 알아내야 하는 스크래치 카드 게임을 만들려고 합니다. 사용자가 캔버스의 70%를 긁어 모두 공개했는지 확인하고 싶습니다. 이 기능을 구현하기 위해 Phaser를 사용하려고 하는데 작동하지 않습니다.
픽셀 배열을 얻기 위해 이미지 데이터를 계산해 보았으나 모두 0으로 구성된 배열이 반환되었습니다. 아래 코드에서는 계산ScratchRatio 함수를 사용하고 있습니다.
"./BaseScene"에서 BaseScene 가져오기; const SKY_IMAGE = "하늘"; const SKY_IMAGE_BLACK = "하늘색"; const 보드 = "보드"; const HEADER_ACT = "header_act"; const KEY_BRUSH = "브러쉬"; const BGGAME = "bg-게임"; 기본 클래스 내보내기 Scratch는 BaseScene을 확장합니다. 생성자(구성) { super("스크래치", { ...config }); this.config = 구성; this.isDown = 거짓; this.renderTexture = null; this.brush = null; this.erasedPixels = 0; this.screenCenter = [config.width / 2, config.height / 2]; } 만들다() { super.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 헤더정보 = this.add .image(this.screenCenter[0] - 160, 130, "header_act") .setScale(0.7); helloWorld = this.add를 허용하세요. .text(0, 0, "안녕하세요 세계") .setFont("20px Arial") .setColor("#ffffff"); const 컨테이너 = this.add.container(headerinfo.x, headerinfo.y); 컨테이너.추가(helloWorld); } 스크래치오프() { this.add .image(this.screenCenter[0] - 160, this.screenCenter[1], SKY_IMAGE) .setScale(0.7); this.cover.setOrigin(0, 0); const 너비 = this.cover.width; const 높이 = this.cover.height; console.log(너비, 높이); const rt = this.add.renderTexture( this.screenCenter[0] - 160, this.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; } handlerPointerDown(포인터) { this.isDown = 사실; this.handlePointerMove(포인터); } handlerPointerMove(포인터) { if (!this.isDown) { 반품; } const x = 포인터.x - this.renderTexture.x + this.renderTexture.width * 0.5; const y = 포인터.y - this.renderTexture.y + this.renderTexture.height * 0.5; this.renderTexture.erase(this.brush, x, y); const 결과 = this.calculateScratchRatio(x, y); console.log("결과", 결과); }계산ScratchRatio(x, y) { const 텍스처 = this.textures.get(SKY_IMAGE_BLACK); console.log(텍스처); if (!texture) { console.error(`'${SKY_IMAGE_BLACK}' 키를 포함한 텍스처를 찾을 수 없습니다.`); 0을 반환합니다. } console.log(텍스처); const 캔버스 = document.createElement("캔버스"); canvas.width = 텍스처.소스[0].width; console.log("canvas.width", canvas.width); 캔버스.높이 = 텍스처.소스[0].높이; const context = canvas.getContext("2d"); context.drawImage(texture.source[0].image, 0, 0); const imageData = context.getImageData(0, 0, canvas.width, canvas.height); const 픽셀 = imageData.data; console.log(imageData, 픽셀); 지워진카운트 = 0으로 놔두세요; for (let i = 3; i < pixel.length; i += 4) { const 알파 = 픽셀[i + 3]; if (알파 < 128) { 지워진카운트++; } } const totalPixels = canvas.width * canvas.height; const scrapRatio = (erasedCount / totalPixels) * 100; return Math.round(scratchRatio); } }
코드가 너무 많아서 작동시키기가 어렵습니다.
가장 좋은 방법은 여기여기에 언급된 것과 같은 미니 실행 가능 코드를 게시하는 것입니다.
그러나 간단하고 빠른 해결책은
canvasTexture
을 사용하여Cover Texture을 만들어 이 개체에서 직접 컨텍스트에 액세스할 수 있도록 하는 것입니다.여기에 제가 어떻게 할 것인지에 대한 간단한 데모가 있습니다:
(이답변컨셉을 토대로)