2016-01-01 12 views
6

otrzymałem następujący błąd:Nie udało się wykonać „drawImage” na „CanvasRenderingContext2D”

Uncaught TypeError: Failed to execute 'drawImage' on 'CanvasRenderingContext2D': The provided value is not of type '(HTMLImageElement or HTMLVideoElement or HTMLCanvasElement or ImageBitmap)'

Widziałem odniesienie do tego samego błędu tutaj, ale realizacja różnił się od kopalni. To jest gra, która renderuje niektóre obrazy, ale nadal daje ten błąd. Tu jest mój kodu:

Jest to linia, gdzie stany chrom błąd jest:

for (row = 0; row < numRows; row++) { 
    for (col = 0; col < numCols; col++) { 
     /* The drawImage function of the canvas' context element 
     * requires 3 parameters: the image to draw, the x coordinate 
     * to start drawing and the y coordinate to start drawing. 
     * We're using our Resources helpers to refer to our images 
     * so that we get the benefits of caching these images, since 
     * we're using them over and over. 
     */ 
     ctx.drawImage(resources.get(rowImages[row]), col * 101, row * 83); 
     } 
} 

To ctx.drawImage(resources.get(rowImages[row]), col * 101, row * 83). Jest to pełna funkcja render(). Obrazy są zawarte w poniższej tablicy:

function render() { 
     /* This array holds the relative URL to the image used 
     * for that particular row of the game level. 
     */ 
     var rowImages = [ 
       'images/water-block.png', // Top row is water 
       'images/stone-block.png', // Row 1 of 3 of stone 
       'images/stone-block.png', // Row 2 of 3 of stone 
       'images/stone-block.png', // Row 3 of 3 of stone 
       'images/grass-block.png', // Row 1 of 2 of grass 
       'images/grass-block.png' // Row 2 of 2 of grass 
      ], 
      numRows = 6, 
      numCols = 5, 
      row, col; 

     /* Loop through the number of rows and columns we've defined above 
     * and, using the rowImages array, draw the correct image for that 
     * portion of the "grid" 
     */ 
     for (row = 0; row < numRows; row++) { 
      for (col = 0; col < numCols; col++) { 
       /* The drawImage function of the canvas' context element 
       * requires 3 parameters: the image to draw, the x coordinate 
       * to start drawing and the y coordinate to start drawing. 
       * We're using our Resources helpers to refer to our images 
       * so that we get the benefits of caching these images, since 
       * we're using them over and over. 
       */ 
       ctx.drawImage(resources.get(rowImages[row]), col * 101, row * 83); 
      } 
      } 


     renderEntities(); 
    } //END RENDER 

zasobów jest osobny plik resources.js że tworzy pamięć podręczną dla obrazów kod następuje w przypadku, to pomaga:

(function() { 
    var resourceCache = {}; 
    var loading = []; 
    var readyCallbacks = []; 

    /* This is the publicly accessible image loading function. It accepts 
    * an array of strings pointing to image files or a string for a single 
    * image. It will then call our private image loading function accordingly. 
    */ 
    function load(urlOrArr) { 
     if(urlOrArr instanceof Array) { 
      /* If the developer passed in an array of images 
      * loop through each value and call our image 
      * loader on that image file 
      */ 
      urlOrArr.forEach(function(url) { 
       _load(url); 
      }); 
     } else { 
      /* The developer did not pass an array to this function, 
      * assume the value is a string and call our image loader 
      * directly. 
      */ 
      _load(urlOrArr); 
     } 
    } 

    /* This is our private image loader function, it is 
    * called by the public image loader function. 
    */ 
    function _load(url) { 
     if(resourceCache[url]) { 
      /* If this URL has been previously loaded it will exist within 
      * our resourceCache array. Just return that image rather than 
      * re-loading the image. 
      */ 
      return resourceCache[url]; 
     } else { 
      /* This URL has not been previously loaded and is not present 
      * within our cache; we'll need to load this image. 
      */ 
      var img = new Image(); 
      img.src = url; 
      img.onload = function() { 
       /* Once our image has properly loaded, add it to our cache 
       * so that we can simply return this image if the developer 
       * attempts to load this file in the future. 
       */ 
       resourceCache[url] = img; 

       /* Once the image is actually loaded and properly cached, 
       * call all of the onReady() callbacks we have defined. 
       */ 
       if(isReady()) { 
        readyCallbacks.forEach(function(func) { func(); }); 
       } 
      }; 

      /* Set the initial cache value to false, this will change when 
      * the image's onload event handler is called. Finally, point 
      * the images src attribute to the passed in URL. 
      */ 
      resourceCache[url] = false; 

     } 
    } 

     function get(url) { 
     return resourceCache[url]; 
    } 

    /* This function determines if all of the images that have been requested 
    * for loading have in fact been completly loaded. 
    */ 
    function isReady() { 
     var ready = true; 
     for(var k in resourceCache) { 
      if(resourceCache.hasOwnProperty(k) && 
       !resourceCache[k]) { 
       ready = false; 
      } 
     } 
     return ready; 
    } 

    /* This function will add a function to the callback stack that is called 
    * when all requested images are properly loaded. 
    */ 
    function onReady(func) { 
     readyCallbacks.push(func); 
    } 

    /* This object defines the publicly accessible functions available to 
    * developers by creating a global Resources object. 
    */ 
    window.resources = { 
     load: load, 
     get: get, 
     onReady: onReady, 
     isReady: isReady 
    }; 
})(); 

Chrome wymieniono również dwa inne sekcje z tym samym błędem:

var main = function() { 
    var now = Date.now(); 
    var delta = now - then; 

    update(delta/1000); 
    render(); 

    then = now; 

    //Request to do this again ASAP 
    requestAnimationFrame(main); 
} 

Błąd dotyczy renderowania wywołania render();

i na ostatniej linii mojego pliku, który wzywa main() w następujący sposób:

// Let's play this game! 
var then = Date.now(); 
reset(); 
main(); 
+1

Nigdy nie ładujesz swoich obrazów, stąd 'resources.get (rowImages [row])' nie może niczego zwrócić, stąd 'drawImage' narzeka. – Kaiido

+0

Przesuwam trochę kodu i ładuję obrazy, co pomogło. Dzięki – Janice

Odpowiedz

2

Masz ładunek, onReady, mechanizm callback wygląda.

więc chciałbym zrobić jako głównej funkcji, aby zacząć wszystko:

assets = ['images/water-block.png', 
      'images/stone-block.png', 
      'images/grass-block.png' 
     ]; 
var then = Date.now(); 
reset(); 
resources.onReady(main); 
resources.load(assets); 

nawet jeśli resources.get() wiązałoby na załadowanie obrazu, który jest Asyncronous przez naturę, to masz błąd w każdym razie, bo drawImage oczekują od zasób, który ma tam być, nie być załadowany, a następnie narysowany.

+0

dobrze znasz zasób, który pokazuje składnię do robienia tego asynchronicznie? Dzięki – Janice

+0

próbowałeś dostosować mój pseudo kod? napisałem go czytając "zasoby" biblioteki, które opublikowałeś. – AndreaBogazzi

+0

tak AndreaBogazzi Mam podobną implementację teraz, niezupełnie w tej kolejności, ale dziwne jest to, że widzę wszystkie moje obrazy w eksploratorze internetowym, ale w chrome widzę tylko dziwne obrazy tła. Zawsze uważałem, że Chrome to najlepsza przeglądarka. Błąd, który otrzymuję teraz to: Uncaught ReferenceError: nieprzyjaciel nie jest zdefiniowany Oto fragment kodu z obszaru, w którym zdefiniowałem wroga. – Janice

Powiązane problemy