Phaser에서 픽셀 삭제 진행 상황을 추적하는 다른 방법이 있습니까?
P粉928591383
2023-08-14 20:29:20
<p>그래서 저는 사용자가 카드를 긁어 밑에 무엇이 있는지 알아내야 하는 스크래치 카드 게임을 만들려고 합니다. 사용자가 캔버스의 70%를 긁어 모두 공개했는지 확인하고 싶습니다. 이 기능을 구현하기 위해 Phaser를 사용하려고 하는데 작동하지 않습니다. </p>
<p>픽셀 배열을 얻기 위해 이미지 데이터를 계산해 보았으나 모두 0으로 구성된 배열이 반환되었습니다. 아래 코드에서는 계산ScratchRatio 함수를 사용하고 있습니다.</p>
<pre class="brush:php;toolbar:false;">"./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);
}
}</pre>
<p><br /></p>
코드가 너무 많아서 작동시키기가 어렵습니다.
가장 좋은 방법은 여기 여기에 언급된 것과 같은 미니 실행 가능 코드를 게시하는 것입니다.
그러나 간단하고 빠른 해결책은
canvasTexture
을 사용하여 Cover Texture을 만들어 이 개체에서 직접 컨텍스트에 액세스할 수 있도록 하는 것입니다.여기에 제가 어떻게 할 것인지에 대한 간단한 데모가 있습니다:
(이 답변 컨셉을 토대로)