2016-01-01 16 views
6

ho ricevuto il seguente errore:Impossibile eseguire 'drawImage' on 'CanvasRenderingContext2D'

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

vidi riferimento lo stesso errore qui, ma l'esecuzione è stata diversa dalle miniere. Questo è un gioco e rende alcune immagini, ma dà ancora questo errore. Qui è il mio codice:

Questa è la linea dove cromati stati l'errore è:

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); 
     } 
} 

E 'il ctx.drawImage(resources.get(rowImages[row]), col * 101, row * 83).

Questa è la funzione completa render(). Le immagini sono contenute nella seguente matrice:

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 

risorse è un file separato resources.js che crea una cache per le immagini, il codice segue nel caso in cui questo aiuta:

(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 anche indicato altri due sezioni sotto lo stesso errore:

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); 
} 

L'errore è nella chiamata di rendering render();

e sull'ultima riga del mio file che chiama main() come segue:

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

non si caricano mai le immagini, quindi 'resources.get (rowImages [row])' non può restituire nulla, quindi 'drawImage' si lamenta. – Kaiido

+0

Sposto un po 'di codice e ho caricato le immagini per primo, quindi ho aiutato. Grazie – Janice

risposta

2

Hai un carico, onReady, meccanismo di richiamata assomiglia.

così vorrei fare come una funzione principale di ricominciare tutto:

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

anche se resources.get() sarebbe portare avanti il ​​caricamento delle immagini, che è asincrona per natura, si avrebbe l'errore comunque perché DrawImage aspettiamo che il risorsa per essere lì, non essere caricato e quindi disegnato.

+0

ok sai di una risorsa che mostra la sintassi per farlo in modo asincrono? Grazie – Janice

+0

hai provato ad adattare il mio pseudo codice? l'ho scritto leggendo le "risorse" della biblioteca che hai pubblicato. – AndreaBogazzi

+0

sì AndreaBogazzi Ora ho un'implementazione simile, non esattamente in quest'ordine ma la cosa strana è che posso vedere tutte le mie immagini in Internet Explorer ma in Chrome vedo solo le immagini di sfondo strane. Ho sempre pensato che Chrome sia il browser superiore. L'errore che sto ottenendo ora è: Uncaught ReferenceError: il nemico non è definito Ecco uno snippet di codice dall'area in cui ho definito il nemico. – Janice