You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Phaser + Vite项目中图像与字体画质过低、放大模糊的解决方法求助

Phaser + Vite项目中图像与字体画质过低、放大模糊的解决方法求助

我正在学Phaser,用Vite搭了个原生JS项目,现在遇到个头疼的问题——项目里的图片和字体画质特别差,放大之后模糊得没法看。想问问大家怎么才能让文本和图片都保持高清质感呀?


我的代码如下:

mainScene.js 脚本:

import { Scene } from "phaser";

class MainScene extends Scene {
  constructor() {
    super("MainScene");
  }
  preload() {
    console.log("preload");
    
    this.load.image("gameBG", "/Sprites/gameBG.png");
    this.load.image("mineDefaultLight", "/Sprites/mineDefaultLight.png");
    this.load.image("gameNameBG", "/Sprites/gameNameBG.png");
    this.load.image("arrow", "/Sprites/arrow.png");
    this.load.image("howToPlayBtn", "/Sprites/howToPlayBtn.png");
    this.load.image("menuBtn", "/Sprites/menuBtn.png");
    this.load.image("minesSelectionBG", "/Sprites/minesSelectionBG.png");
    this.load.image("nextBG", "/Sprites/nextBG.png");
    this.load.image("randomBG", "/Sprites/randomBG.png");
    this.load.image("autoGameBG", "/Sprites/autoGameBG.png");
    this.load.image("refreshImg", "/Sprites/refresh.png");
    this.load.image("autoToggleOffImg", "/Sprites/autoToggleOff.png");
    this.load.image("betPanelBGImg", "/Sprites/betPanelBG.png");
    this.load.image("customBetFieldImg", "/Sprites/customBetFieldImg.png");
    this.load.image("minusBtnImg", "/Sprites/minus.png");
    this.load.image("betAmountsBtn", "/Sprites/betAmountsBtn.png");
    this.load.image("plusBtnImg", "/Sprites/plus.png");
    this.load.image("autoPlayBtn", "/Sprites/autoPlayBtn.png");
    this.load.image("betBtn", "/Sprites/betBtn.png");
    this.load.image("betBtnArrow", "/Sprites/betBtnArrow.png");
    this.load.image("minesSVG", "/Sprites/MinusSVG.svg"); // Preload the MinesSVG.svg image
    this.load.image("refreshSVG", "/Sprites/refreshSVG.svg");

    this.load.spritesheet("demo", "/Sprites/refresh.png", {frameWidth: 22, frameHeight: 18});
  }
  create() {
    console.log("create");

    let gameBG = this.add.image(0, 0, "gameBG").setOrigin(0, 0);
    gameBG.setDisplaySize(950, 520);
    gameBG.setPosition(5, 5);

    function preserveAspect(image, targetWidth, targetHeight) {
      const scale = Math.min(targetWidth / image.width, targetHeight / image.height);
      image.setScale(scale);
    }

    //Header
    let gameHeaderContainer = this.add.container(7, 7);
    let gameHeader = this.add.graphics();
    gameHeader.fillStyle(0x000000, .3);
    gameHeader.fillRoundedRect(0, 0, 946, 30, 12);
    gameHeaderContainer.add(gameHeader);

    let gameNameBG = this.add.image(3, 3, "gameNameBG").setOrigin(0, 0);
    gameNameBG.setDisplaySize(130, 24);
    gameHeaderContainer.add(gameNameBG);

    let arrow = this.add.image(110, 12, "arrow").setOrigin(0, 0);
    preserveAspect(arrow, 10, 10);
    gameHeaderContainer.add(arrow);

    let gameNameTxt = this.add.text(47.428, 7, "MINES", {
      fontSize: "12px",
      fontFamily: "Roboto",
      color: "#ffffff",
    });
    gameHeaderContainer.add(gameNameTxt);

    let howToPlayBtn = this.add.image(148, 4, "howToPlayBtn").setOrigin(0, 0);
    preserveAspect(howToPlayBtn, 150, 22);
    gameHeaderContainer.add(howToPlayBtn);

    let menuBtn = this.add.image(919, 4, "menuBtn").setOrigin(0, 0);
    preserveAspect(menuBtn, 24, 24);
    gameHeaderContainer.add(menuBtn);

    let totalBalanceTxt = this.add.text(890, 8, "3,000.00  ", {
      fontSize: "12px",
      fontFamily: "Roboto",
      color: "#ffffff",
    }).setOrigin(1, 0);
    let inrText = this.add.text(totalBalanceTxt.x, totalBalanceTxt.y, "INR", {
      fontSize: "12px",
      fontFamily: "Roboto",
      color: "#6C9FC7",
    }).setOrigin(0, 0);
    totalBalanceTxt.setText(totalBalanceTxt.text);
    gameHeaderContainer.add(inrText);
    gameHeaderContainer.add(totalBalanceTxt);
    totalBalanceTxt.setOrigin(1, 0);

    //Middle
    let subHeaderLine = this.add.graphics();
    subHeaderLine.fillStyle(0x000000, .3);
    subHeaderLine.fillRoundedRect(268.955, 71, 422.09, 4, 2);

    const group = this.add.group();
    const rows = 5, columns = 5;
    const cellWidth = 78.9, cellHeight = 59.46;
    const spacingX = 5, spacingY = 6;
    const offsetX = 272.75, offsetY = 84;

    for (let i = 0; i < rows * columns; i++) {
      const col = i % columns;
      const row = Math.floor(i / columns);
      const x = offsetX + col * (cellWidth + spacingX) + cellWidth / 2;
      const y = offsetY + row * (cellHeight + spacingY) + cellHeight / 2;

      const box = this.add.image(x, y, 'mineDefaultLight');
      preserveAspect(box, cellWidth, cellHeight);
      group.add(box);
    }

    //SubFooter
    let subFooterContainer = this.add.container(273, 415);
    let randomBG = this.add.image(0, 0, "randomBG").setOrigin(0, 0);
    randomBG.setDisplaySize(205.27, 30.05);
    subFooterContainer.add(randomBG);

    let randomTxt = this.add.text(70, 7, "RANDOM", {
      fontSize: "14px",
      fontFamily: "Roboto",
      color: "#ffffff",
    });
    subFooterContainer.add(randomTxt);

    let autoGameBG = this.add.image(210, 2, "autoGameBG").setOrigin(0, 0);
    autoGameBG.setDisplaySize(205.23, 26);
    subFooterContainer.add(autoGameBG);

    // let refreshImg = this.add.image(214, 6, "refreshImg").setOrigin(0, 0);
    // preserveAspect(refreshImg, 22, 18);
    // subFooterContainer.add(refreshImg);

    // let refreshSVG = this.add.image(214, 6, "refreshSVG").setOrigin(0, 0);
    // preserveAspect(refreshSVG, 22, 18);
    // subFooterContainer.add(refreshSVG);

    let demoSprite = this.add.sprite(214, 6, "refreshImg");
    demoSprite.setOrigin(0, 0);
    demoSprite.setDisplaySize(22, 18);
    subFooterContainer.add(demoSprite);

    let autoToggleOffImg = this.add.image(264, 7, "autoToggleOffImg").setOrigin(0, 0);
    autoToggleOffImg.setDisplaySize(28, 16);
    subFooterContainer.add(autoToggleOffImg);

    let autoGameTxt = this.add.text(300, 7, "Auto Game", {
      fontSize: "12px",
      fontFamily: "Roboto",
      color: "#ffffff",
    });
    subFooterContainer.add(autoGameTxt);

    //Footer
    let footerContainer = this.add.container(7, 455);

    let gameFooter = this.add.graphics();
    gameFooter.fillStyle(0x000000, .3);
    gameFooter.fillRoundedRect(0, 0, 946, 68, 12);
    footerContainer.add(gameFooter);

    let betPanelBGImg = this.add.image(170, 9, "betPanelBGImg").setOrigin(0, 0);
    betPanelBGImg.setDisplaySize(298, 50);
    footerContainer.add(betPanelBGImg);

    let betINRTxt = this.add.text(232, 16, "Bet INR", {
      fontSize: "12px",
      fontFamily: "Roboto",
      color: "#ffffff",
    });
    footerContainer.add(betINRTxt);

    let customBetFieldImg = this.add.image(184, 30, "customBetFieldImg").setOrigin(0, 0);
    customBetFieldImg.setDisplaySize(142, 22);
    footerContainer.add(customBetFieldImg);

    let betAmountInputField = this.add.text(240, 32, "0.00", {
      fontSize: "14px",
      fontFamily: "Roboto",
      fontStyle: "bold",
      color: "#ffffff",
    }).setOrigin(0, 0);
    footerContainer.add(betAmountInputField);

    let minusBtnImg = this.add.image(340, 20, "minusBtnImg").setOrigin(0, 0);
    preserveAspect(minusBtnImg, 33, 33);
    footerContainer.add(minusBtnImg);

    /* // Add the MinesSVG.svg image at the first position
    let minesSVG = this.add.image(340, 20, "minesSVG").setOrigin(0, 0).setToTop();
    // minesSVG.setDisplaySize(950, 520);
    preserveAspect(minesSVG, 33, 33);
    footerContainer.add(minesSVG); */

    let betAmountsBtn = this.add.image(380, 18, "betAmountsBtn").setOrigin(0, 0);
    preserveAspect(betAmountsBtn, 33, 33);
    footerContainer.add(betAmountsBtn);

    let plusBtnImg = this.add.image(420, 21, "plusBtnImg").setOrigin(0, 0);
    preserveAspect(plusBtnImg, 33, 33);
    footerContainer.add(plusBtnImg);

    let autoPlayBtn = this.add.image(480, 9, "autoPlayBtn").setOrigin(0, 0);
    preserveAspect(autoPlayBtn, 240, 50);
    footerContainer.add(autoPlayBtn);

    let betBtn = this.add.image(535, 10, "betBtn").setOrigin(0, 0);
    betBtn.setDisplaySize(242, 52);
    footerContainer.add(betBtn);

    let betBtnArrow = this.add.image(554, 22.5, "betBtnArrow").setOrigin(0, 0);
    preserveAspect(betBtnArrow, 19, 21);
    footerContainer.add(betBtnArrow);

    let betBtnTxt = this.add.text(645, 26, "BET", {
      fontSize: "14px",
      fontFamily: "Roboto",
      color: "#ffffff",
    });
    footerContainer.add(betBtnTxt);

    //SubHeader
    let subHeaderContainer = this.add.container(268.955, 44);
    let subHeader = this.add.graphics();
    subHeader.fillStyle(0x000000, .3);
    subHeader.fillRoundedRect(0, 0, 422.09, 22, 10);
    subHeaderContainer.add(subHeader);

    let minesSelectionBG = this.add.image(1, 1.5, "minesSelectionBG").setOrigin(0, 0);
    preserveAspect(minesSelectionBG, 138, 20);
    subHeaderContainer.add(minesSelectionBG);
  }
}

export default MainScene;

备注:内容来源于stack exchange,提问作者Vinit Kumawat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.15 03:24:32