1

I am trying to use class on drawImage function.

But it seems that drawImage function couldn't get the attribute img of variable monster.

I have no idea what would caused this error.

Not quite understand why browser give me the below error code ... please help me.

Uncaught TypeError: Cannot read property 'img' of undefined.

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Tower Defense</title>
    <style>
        canvas {
            padding: 0;
            margin: auto;
            display: block;
        }
    </style>
</head>

<body>
    <script>
        var canvas = document.createElement("canvas");
        var ctx = canvas.getContext("2d");
        canvas.width = 500;
        canvas.height = 500;
        document.body.appendChild(canvas);

        function Monster(img, x = 0, y = 0, w,h) {
            this.img = img;
            this.x = x;
            this.y = y;
            this.w = w;
            this.h = h;
        }

        var monster;

        var DrawMonster = function(mons) {
            ctx.drawImage(mons.img, mons.x, mons.y, mons.w, mons.h);
        }

        var PreLoadImages = function() {
            var img = new Image();
            img.addEventListener("load", function() {     // or img.onload = function() { ...
                monster = new Monster(this, 0, 0, 100, 100);            
            });
            img.src = "res/Mons_Pirate.jpg";
        }

        PreLoadImages();
        DrawMonster(monster);

    </script>
</body>

</html>

Please change the link (res/Mons_Pirate.jpg) of image while testing.

j08691
  • 204,283
  • 31
  • 260
  • 272
  • 1
    DrawMonster should be inside the on load function – Krishjs Dec 20 '17 at 04:21
  • `monster` will only be defined after the image is loaded. – Sebastian Simon Dec 20 '17 at 04:21
  • @Xufox I have already declared monster outside the PreLoadImages function. And monster has been defined when I called the PreLoadImages function. Still not quite understand why I can't use drawImage on monster outside the load function...? – Chanber Liou Dec 20 '17 at 05:27
  • @ChanberLiou No, you have not defined `monster` when you called `PreLoadImages`. – Sebastian Simon Dec 20 '17 at 08:04
  • Possible duplicate of [Why are these variables "undefined"?](https://stackoverflow.com/questions/17830523/why-are-these-variables-undefined), and of course [Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference](https://stackoverflow.com/q/23667086/4642212). – Sebastian Simon Dec 20 '17 at 08:06

1 Answers1

0

DrawImage should be inside the image load function.Instance of Monster is created only inside the Image load function.Image will be loaded in async.

   <!DOCTYPE html>
    <html lang="en">

     <head>
      <meta charset="UTF-8">
      <title>Tower Defense</title>
      <style>
        canvas {
            padding: 0;
            margin: auto;
            display: block;
        }
       </style>
     </head>

   <body>
       <script>
           var canvas = document.createElement("canvas");
           var ctx = canvas.getContext("2d");
           canvas.width = 500;
           canvas.height = 500;
           document.body.appendChild(canvas);

        function Monster(img, x = 0, y = 0, w,h) {
            this.img = img;
            this.x = x;
            this.y = y;
            this.w = w;
            this.h = h;
        }

        var monster;

        var DrawMonster = function(mons) {
            ctx.drawImage(mons.img, mons.x, mons.y, mons.w, mons.h);
        }

        var PreLoadImages = function() {
            var img = new Image();
            img.addEventListener("load", function() {     // or img.onload = 
            function() { 
                monster = new Monster(this, 0, 0, 100, 100);            
                DrawMonster(monster);
            });
            img.src = "res/Mons_Pirate.jpg";
        }

        PreLoadImages();

    </script>
</body>

</html>
Krishjs
  • 358
  • 2
  • 17
  • Any suggestion if I want to use DrawMonster function outside the load function of img? I thought I have declared the monster outside the load function. Then, I change its value in the load function. But It is still a global variable. I should be able to use it anywhere after changing value in he load function. Is there anything wrong? – Chanber Liou Dec 20 '17 at 05:19
  • Image will take sometime to load If you call DrawImages next to the PreLoadImages the method will be called immediately but at that time the image is not yet loaded so the monster object will be undefined – Krishjs Dec 20 '17 at 07:28
  • Oh~ I thought JavaScript will finish executing PreLoadImages function, then DrawMonster function. Sounds like javascript can do multi-threading task??! Anyway, thank you for the answer! – Chanber Liou Dec 21 '17 at 10:28