Images are not being displayed, but they are clearly being loaded (Javascript Game being hosted on Wordpress)

So here's the deal. I created this Sonic themed "Brick Breaker" style game that I wanted to host on a Wordpress site. Originally the game had 8 JS files, a CSS file and an HTML file but for the purposes of wordpress I threw everything into one file.

My first issue was that the JavaScript wasn't loading, but the images were being displayed as static in the corner of the page. After some rearranging (basically my scripts had to load in a certain order) I was able to get the JavaScript working.

Now I am having the most bizarre issue --- the PNG images (Sonic and the Rings) are not being displayed to the user, but they are CLEARLY being loaded when the game boots. How do I know this? I know this because the UI in lower right hand corner of the screen counts DOWN lives when I move the paddle to the left and let it run and the game eventually ends.

Basically, the images just aren't showing up on the canvas --- it's like they are invisible?

And yes, I have already tried changing the display type from "none" (they are supposed to be drawn onto the canvas using the draw function anyway, so that's not the solution).

Here's my code:

 <!DOCTYPE html>
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <title>Sonic's Ring Grabber (Still In Dev)</title>
        <meta name="description" content="">
        <meta name="viewport" content="width=device-width, initial-scale=1">
    </head>
    <body>
        <style>
 #gameScreen {
   border: 1px double black;

}

img {
  display: none;
}

</style>
   <canvas id="gameScreen" width=800 height=600></canvas>
   <img href='sftp://[email protected]/clickandbuilds/BehaviorsSpace/sonicballgame/assets/SpinballSonicJP.png' width="10%" id="sonicBall"/>
   <img href='sftp://[email protected]/clickandbuilds/BehaviorsSpace/sonicballgame/assets/sonicring2.png' id="rings"/>
  <script>

class Ring {
    constructor(game, position) {

        this.image = document.getElementById('rings');
        this.markedForDeletion = false;
        this.game = game;
        this.position = position;
        this.width = 40;
        this.height = 40;


    }
    update() {
        if (detectCollision(this.game.ball, this)) {
            this.markedForDeletion = true;
        }

    }
    draw(ctx) {
        ctx.drawImage(this.image, this.position.x, this.position.y, this.width, this.height);

    }
}
  class Ball {
    constructor(game) {
        this.image = document.getElementById('sonicBall');

        this.gameWidth = game.gameWidth;
        this.gameHeight = game.gameHeight;
        this.size = 60;
        this.reset();
        this.game = game;
    }

    reset() {
        this.speed = {
            x: 2,
            y: 2
        };
        this.position = {
            x: 250,
            y: 400,
        };
    }
    draw(ctx) {
        ctx.drawImage(this.image, this.position.x, this.position.y, this.size, this.size);

    }
    update(deltaTime) {

        this.position.x += this.speed.x;
        this.position.y += this.speed.y;

        //wall on left and right
        if (this.position.x + this.size > this.gameWidth || this.position.x < 0) {
            this.speed.x = -this.speed.x;
        }

        // wall on top and bottom
        if (this.position.y < 0) {
            this.speed.y = -this.speed.y;
        }
        if (this.position.y + this.size > this.gameHeight) {
            this.game.tries--;
            this.reset();
        }


        //check collision with paddle

        if (detectCollision(this, this.game.paddle)) {

            this.speed.y = -this.speed.y;
            this.position.y = this.game.paddle.position.y - this.size;
        }
    }
}
class Paddle {
    constructor(game) {
        this.width = 150;
        this.height = 20;
        this.maxSpeed = 5;
        this.speed = 0;
        this.position = {
            x: game.gameWidth / 2 - this.width / 2,
            y: game.gameHeight - this.height - 10,
        };
    }

    moveLeft() {
        this.speed = -this.maxSpeed;
    }
    moveRight() {
        this.speed = +this.maxSpeed;
    }

    stop() {
        this.speed = 0;
    }
    draw(ctx) {
        ctx.fillStyle = "green";
        ctx.fillRect(this.position.x, this.position.y, this.width, this.height);
    }

    update(deltaTime) {

        this.position.x += this.speed;

        if (this.position.x < 0) this.position.x = 0;
        if (this.position.x > 650) this.position.x = 650;

    }
}
class InputHandler {
    constructor(paddle, game) {
        document.addEventListener('keydown', event => {
            switch (event.keyCode) {
                case 37:
                    paddle.moveLeft();
                    break;
                case 39:
                    paddle.moveRight();
                    break;
                case 13:
                    game.togglePause();
                    break;
                case 32:
                    game.toggleStart();
                    break;
                case 89:
                game.toggleRestart();
                break;
            }
        });
        document.addEventListener('keyup', event => {
            switch (event.keyCode) {
                case 37:
                    if (paddle.speed < 0)
                        paddle.stop();
                    break;
                case 39:
                    if (paddle.speed > 0)
                        paddle.stop();
                    break;
            }
        });
    }
}
function buildLevel(game, level) {
    let rings = [];

    level.forEach((row, rowIndex) => {
        row.forEach((ring, ringIndex) => {
            if (ring === 1) {
                let position = {
                    x: 82 * ringIndex,
                    y: 40 + 35 * rowIndex
                }
                rings.push(new Ring(game, position));
            }
        });
    });

    return rings;
}


const level1 = [
    [1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
    [1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
    [1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
    [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
];

const level2 = [
    [0, 1, 0, 1, 0, 1, 0, 1, 0, 1],
    [1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
    [1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
    [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
];

const level3 = [
    [1, 1, 1, 1, 0, 0, 0, 0, 0, 0],
    [0, 1, 0, 1, 0, 1, 0, 1, 0, 1],
    [1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
    [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
];

function detectCollision(ball, gameObject) {
  let leftOfBall = ball.position.x;
  let rightOfBall = ball.position.x + ball.size;
  let topOfBall = ball.position.y;
  let bottomOfBall = ball.position.y + ball.size;

  let leftOfObject = gameObject.position.x;
  let rightOfObject = gameObject.position.x + gameObject.width;
  let topOfObject = gameObject.position.y;
  let bottomOfObject = gameObject.position.y + gameObject.height;

  if (leftOfBall < rightOfObject &&
    rightOfBall > leftOfObject &&
    topOfBall < bottomOfObject &&
    bottomOfBall > topOfObject) {
    return true;
  } else {
    return false;
  }
}
const GAMESTATE = {
    PAUSED: 0,
    RUNNING: 1,
    MENU: 2,
    GAMEOVER: 3
}

class Game {
    constructor(gameWidth, gameHeight) {
        this.gameWidth = gameWidth;
        this.gameHeight = gameHeight;
        this.gamestate = GAMESTATE.MENU;
        this.ball = new Ball(this);
        this.paddle = new Paddle(this);
        this.rings = [];
        this.gameObjects = [];
        this.tries = 3;
        this.levels = [level1, level2, level3]
        this.currentLevel = 0;
        new InputHandler(this.paddle, this);
    }

    start() {

        this.rings = buildLevel(this, this.levels[this.currentLevel]);
        this.gameObjects = [this.ball, this.paddle];

    }

    update(deltaTime) {

        if (this.tries === 0) this.gamestate = GAMESTATE.GAMEOVER;
        if (this.gamestate === GAMESTATE.PAUSED || this.gamestate === GAMESTATE.MENU || this.gamestate === GAMESTATE.GAMEOVER) 
        if (this.rings.length === 0) {
           this.currentLevel++;
           this.ball.reset();
           this.start();
        }
        [...this.gameObjects, ...this.rings].forEach(object => object.update(deltaTime));
        this.gameObjects.forEach((object) => object.update(deltaTime));
        this.rings = this.rings.filter(object => !object.markedForDeletion);
    }

    draw(ctx) {

        [...this.gameObjects, ...this.rings].forEach(object => object.draw(ctx));
        this.gameObjects.forEach(object => object.draw(ctx));
        if (this.gamestate == GAMESTATE.PAUSED) {
            ctx.rect(0, 0, this.gameWidth, this.gameHeight);
            ctx.fillStyle = "rgba(0,0,0,0)";
            ctx.fill();

            ctx.font = "30px Arial";
            ctx.fillStyle = "black";
            ctx.textAlign = "center";
            ctx.fillText("GAME PAUSED", this.gameWidth / 2, this.gameHeight / 2);
        }
        if (this.gamestate == GAMESTATE.MENU) {
            ctx.rect(0, 0, this.gameWidth, this.gameHeight);
            ctx.fillStyle = "rgba(0,0,0)";
            ctx.fill();

            ctx.font = "30px Arial";
            ctx.fillStyle = "white";
            ctx.textAlign = "center";
            ctx.fillText("TO START, PRESS SPACEBAR", this.gameWidth / 2, this.gameHeight / 2);
            ctx.fillText("WHILE PLAYING, PRESS ENTER TO PAUSE", this.gameWidth / 2, this.gameHeight / 1.5);
        }
        if (this.gamestate == GAMESTATE.GAMEOVER) {
            ctx.rect(0, 0, this.gameWidth, this.gameHeight);
            ctx.fillStyle = "rgba(0,0,0)";
            ctx.fill();
            ctx.font = "30px Arial";
            ctx.fillStyle = "white";
            ctx.textAlign = "center";
            ctx.fillText("GAME OVER", this.gameWidth / 2, this.gameHeight / 2);
            ctx.fillText("PRESS Y TO TRY AGAIN", this.gameWidth / 2, this.gameHeight / 1.5);
        }
        if (this.gamestate == GAMESTATE.RUNNING) {
            ctx.font = "20px Arial";
            ctx.fillStyle = "black";
            ctx.textAlign = "right";
            ctx.fillText("LIVES: " + this.tries, this.gameWidth, this.gameHeight);
        }
    }

    togglePause() {
        if (this.gamestate == GAMESTATE.PAUSED) {
            this.gamestate = GAMESTATE.RUNNING;
        } else {
            this.gamestate = GAMESTATE.PAUSED;
        }
    }

    toggleStart() {
        if (this.gamestate == GAMESTATE.MENU) {
            this.gamestate = GAMESTATE.RUNNING;
        this.rings = [];
        this.tries = 3;
        this.levels = [level1, level2, level3]
        this.currentLevel = 0;
        new InputHandler(this.paddle, this);
        }
    }
    toggleRestart() {
        if (this.gamestate == GAMESTATE.GAMEOVER) {
        this.gamestate = GAMESTATE.MENU;
        this.ball = new Ball(this);
        this.paddle = new Paddle(this);
        this.rings = [];
        this.gameObjects = [];
        this.tries = 3;
        this.levels = [level1, level2, level3]
        this.currentLevel = 0;
        new InputHandler(this.paddle, this);
        }
    }
}
let canvas = document.getElementById("gameScreen");
let ctx = canvas.getContext('2d');
const GAME_WIDTH = 800;
const GAME_HEIGHT = 600;

let game = new Game(GAME_WIDTH, GAME_HEIGHT);
game.start();


let lastTime = 0;

//images



function gameLoop(timeStamp) {
    let deltaTime = timeStamp - lastTime;
    lastTime = timeStamp;
    ctx.clearRect(0, 0, GAME_WIDTH, GAME_HEIGHT);

    game.update(deltaTime);
    game.draw(ctx);

    requestAnimationFrame(gameLoop);
}
requestAnimationFrame(gameLoop);

</script>
    </body>
</html>

Anyone have any idea what might be happening here?

Solutions

The image tag should use the src attribute not the href attribute.

no

<img href=""/>

yes

<img src=""/>

Also the reference to the image is typically something like

https://hostname.com/images/my-image.png

The protocol is typically https these days or maybe http (discouraged). You have an sftp protocol in your url which won't work.

If you are storing your image in your Wordpress assets area you should be able to go to the detail view for that image and copy/paste a visible url for that asset.

Alternatively you can right-click on the image and 'Open Image in New Tab' to see the individual image's url in the browser address window in a separate browser tab . If you see the image in the browser you know it is a working url so copy/paste that and add it to the src attribute's value.

Similar questions

Embedding JAR Game into Wordpress website
Hello I am a designer not a programmer. My brother programmed a game for me a while ago with eclipse. It has the extension JAR. I want to embed this game into my wordpress website but I dont know how. I only have the .exe and the .jar file of the game but not the code. How this can be possible without going into deep programming?
Leader board for game on homepage
I've built a simple game which is housed on my homepage. I'd like to create a leader board (a small results table) which displays the top three 3 scores. How would i insert/retrieve the score data into and from my DB? The games been coded using JS, is there wordpress php functions that would help me GET / POST this data. thanks in advance, Cam
Use plugin or custom post type for game score functionality
The last couple of days I've been working on a plug-in that adds the functionality of keeping scores from a paintball game. When I manage to finish it I want to present players with a form so they can add in stuff like: hits, deaths, wins, losses, location, role and date. That goes to a custom table in the WP database. They will also get a profile ...
Connecting multiple post types? Or linking "News" posts with "Game" posts how?
I am building gaming news and tutorial website. But i don't know how to link multiple post types with one specific post. For example, i created post types called So the games post type will be basically a list of Games, News will be posts with news, and Tutorials will be tutorials. But i need to somehow link News and Tutorials to the specific post ...
PHP / JS - Leader board for game
I'm creating a leader board (a small results table) for a Javascript game i've created which displays the top three 3 scores, the score will be a string e.g - '100'. How would i insert/retrieve the score data into and from my DB? the game sits in a wordpress site, are there wordpress php functions that would help me insert/query this data. thanks i...
SQL role playing game -- Classes table referencing a skills table
I've been working on a wordpress plugin that is designed to create a character for a wordpress user using MYSQL. I'm new to php and sql. I'm currently struggling with two tables in my DB. A class table and a skill table. The class table is comprised of the different classes a character can be. For example; a Warrior, Paladin or Wizard. The skills t...

Also ask

We use cookies to deliver the best possible experience on our website. By continuing to use this site, accepting or closing this box, you consent to our use of cookies. To learn more, visit our privacy policy .