在请求不带文件扩展名的文件的 Apache Web 服务器上加载资源失败

问题描述 投票:0回答:1

我正在尝试将我在 github 上找到的一个小型俄罗斯方块基础游戏实现到我的网络服务器中,但图块的图像未加载到游戏中,并且在控制台中显示无法加载资源 404 未找到,它描述了它所在的文件寻找我在以下代码中的数组中列出的颜色,但缺少 .png 扩展名,即使数组明确应该请求图像源来自具有 .png 扩展名的资源文件夹中

此外,它正在加载一种颜色,蓝色,但是当我刷新页面以尝试获取另一种颜色时,它说例如找不到文件“橙色”

文件结构位于apache的htdocs内,其服务在本地主机上运行,如下所示,

  1. 文档
  • index.html(带有 tetris.html 的链接)
  • 俄罗斯方块.html
  • 俄罗斯方块.js
  • 俄罗斯方块.css
  • 资源文件夹(这包括 .png 形式的所有颜色,例如 blue.png)
window.onload = () => {
    const
        background = document.getElementById("background"),
        scoreLbl = document.getElementById("score"),
        linesLbl = document.getElementById("lines"),
        canvas = document.getElementById("game-canvas"),
        ctx = canvas.getContext("2d");

    let audio = new Audio("resources/music.mp3");

    class Tetromino {
        static COLORS = [".resources/blue.png", ".resources/green.png", ".resources/yellow.png", ".resources/red.png", ".resources/orange.png", ".resources/light-blue.png", ".resources/purple.png"];
        static BLOCK_SIZE = 28;
        static DELAY = 400;
        static DELAY_INCREASED = 5;

        constructor(xs, ys, color = null) {
            this.x = xs;
            this.y = ys;
            this.length = xs.length;
            this.color = color;
            this.img = new Image();
            
    
            // Set up a promise to track image loading
            this.imgLoaded = new Promise((resolve, reject) => {
                this.img.onload = resolve;
                this.img.onerror = reject;
            });
    
            if (color !== null) {
                this.img.src = Tetromino.COLORS[color];
                console.log(this.img.src);
                console.log((TETROMINOES.COLORS[color]));
            }
        }

        update(updFunc) {
            for (let i = 0; i < this.length; ++i) {
                ctx.clearRect(
                    this.x[i] * Tetromino.BLOCK_SIZE,
                    this.y[i] * Tetromino.BLOCK_SIZE,
                    Tetromino.BLOCK_SIZE,
                    Tetromino.BLOCK_SIZE
                );

                updFunc(i);
            }

            this.draw();
        }

        draw() {
            if (!this.img.complete) {
                this.img.onload = () => this.draw();
                return;
            }
            // Print the current tetromine
            for (let i = 0; i < this.length; ++i) {
                ctx.drawImage(
                    this.img,
                    this.x[i] * Tetromino.BLOCK_SIZE,
                    this.y[i] * Tetromino.BLOCK_SIZE,
                    Tetromino.BLOCK_SIZE,
                    Tetromino.BLOCK_SIZE
                );
            }
        }

        collides(checkFunc) {
            for (let i = 0; i < this.length; ++i) {
                const { x, y } = checkFunc(i);
                if (x < 0 || x >= FIELD_WIDTH || y < 0 || y >= FIELD_HEIGHT || FIELD[y][x] !== false)
                    return true;
            }
            return false;
        }

        merge() {
            for (let i = 0; i < this.length; ++i) {
                FIELD[this.y[i]][this.x[i]] = this.color;
            }
        }

        rotate() {
            const
                maxX = Math.max(...this.x),
                minX = Math.min(...this.x),
                minY = Math.min(...this.y),
                nx = [],
                ny = [];

            if (!this.collides(i => {
                    nx.push(maxX + minY - tetromino.y[i]);
                    ny.push(tetromino.x[i] - minX + minY);
                    return { x: nx[i], y: ny[i] };
                })) {
                this.update(i => {
                    this.x[i] = nx[i];
                    this.y[i] = ny[i];
                });
            }
        }
    }

    const
        FIELD_WIDTH = 10,
        FIELD_HEIGHT = 20,
        FIELD = Array.from({ length: FIELD_HEIGHT }),
        MIN_VALID_ROW = 4,
        TETROMINOES = [
            new Tetromino([0, 0, 0, 0], [0, 1, 2, 3]),
            new Tetromino([0, 0, 1, 1], [0, 1, 0, 1]),
            new Tetromino([0, 1, 1, 1], [0, 0, 1, 2]),
            new Tetromino([0, 0, 0, 1], [0, 1, 2, 0]),
            new Tetromino([0, 1, 1, 2], [0, 0, 1, 1]),
            new Tetromino([0, 1, 1, 2], [1, 1, 0, 1]),
            new Tetromino([0, 1, 1, 2], [1, 1, 0, 0])
        ];

    let tetromino = null,
        delay,
        score,
        lines;



    (function setup() {

        canvas.style.top = Tetromino.BLOCK_SIZE;
        canvas.style.left = Tetromino.BLOCK_SIZE;

        ctx.canvas.width = FIELD_WIDTH * Tetromino.BLOCK_SIZE;
        ctx.canvas.height = FIELD_HEIGHT * Tetromino.BLOCK_SIZE;

        // Scale background
        const scale = Tetromino.BLOCK_SIZE / 13.83333333333;
        background.style.width = scale * 166;
        background.style.height = scale * 304;

        // Offset each block to the middle of the table width
        const middle = Math.floor(FIELD_WIDTH / 2);
        for (const t of TETROMINOES) t.x = t.x.map(x => x + middle);

        reset();
        draw();
    })();

    function reset() {
        // Make false all blocks
        FIELD.forEach((_, y) => FIELD[y] = Array.from({ length: FIELD_WIDTH }).map(_ => false));

        ctx.clearRect(0, 0, canvas.width, canvas.height);

        delay = Tetromino.DELAY;
        score = 0;
        lines = 0;
    }
    
    function playMusic() {
        audio.play();
        
        
    }

    function draw() {
        if (tetromino) {

            // Collision?
            if (tetromino.collides(i => ({ x: tetromino.x[i], y: tetromino.y[i] + 1 }))) {
                tetromino.merge();
                // Prepare for new tetromino
                tetromino = null;

                // Check for completed rows
                let completedRows = 0;
                for (let y = FIELD_HEIGHT - 1; y >= MIN_VALID_ROW; --y)
                    if (FIELD[y].every(e => e !== false)) {
                        for (let ay = y; ay >= MIN_VALID_ROW; --ay)
                            FIELD[ay] = [...FIELD[ay - 1]];

                        ++completedRows;
                        // Keep the same row
                        ++y;
                    }

                if (completedRows) {
                    // Print againt the table
                    ctx.clearRect(0, 0, canvas.width, canvas.height);
                    for (let y = MIN_VALID_ROW; y < FIELD_HEIGHT; ++y) {
                        for (let x = 0; x < FIELD_WIDTH; ++x) {
                            if (FIELD[y][x] !== false) new Tetromino([x], [y], FIELD[y][x]).draw();
                        }
                    }

                    score += [40, 100, 300, 1200][completedRows - 1];
                    lines += completedRows;
                } else {
                    // Check if player has lost
                    if (FIELD[MIN_VALID_ROW - 1].some(block => block !== false)) {
                        alert("Game Over! \n \nScore: "+ score + "\nLines Cleared: " + lines);
                        reset();
                    }
                }


            } else
                tetromino.update(i => ++tetromino.y[i]);
        }
        // No tetromino failing
        else {

            scoreLbl.innerText = score;
            linesLbl.innerText = lines;

            // Create random tetromino
            tetromino = (({ x, y }, color) =>
                new Tetromino([...x], [...y], color)
            )(
                TETROMINOES[Math.floor(Math.random() * (TETROMINOES.length - 1))],
                Math.floor(Math.random() * (Tetromino.COLORS.length - 1))
            );

            tetromino.draw();
        }

        setTimeout(draw, delay);
    }

    // Move
    window.onkeydown = event => {
        playMusic();
        switch (event.key) {
            
            case "ArrowLeft":
                if (!tetromino.collides(i => ({ x: tetromino.x[i] - 1, y: tetromino.y[i] })))
                    tetromino.update(i => --tetromino.x[i]);
                
                break;
            case "ArrowRight":
                if (!tetromino.collides(i => ({ x: tetromino.x[i] + 1, y: tetromino.y[i] })))
                    tetromino.update(i => ++tetromino.x[i]);
                break;
            case "ArrowDown":
                delay = Tetromino.DELAY / Tetromino.DELAY_INCREASED;
                break;
            case " ":
                tetromino.rotate();
                break;
            case "ArrowUp":
                tetromino.rotate();
                break;
        }
    }
    window.onkeyup = event => {
        if (event.key === "ArrowDown")
            delay = Tetromino.DELAY;
    }

}

我尝试加载俄罗斯方块文件并期望游戏可以玩(它以前可以运行,但不是在 apache 上,而是在我发布文件的 esp32 网络服务器上),但经过大量故障排除后,加载的唯一颜色是蓝色

javascript html apache webserver tetris
1个回答
0
投票

尝试将静态变量 COLORS 更改为:

static COLORS = ["./resources/blue.png", "./resources/green.png", "./resources/yellow.png", "./resources/red.png", "./resources/orange.png", "./resources/light-blue.png", "./resources/purple.png"];
© www.soinside.com 2019 - 2024. All rights reserved.