简体   繁体   中英

HTML5 Canvas drawImage() inside object literal

I'm trying to make a snake game with HTML5 using the object literal pattern, but I can't seem to draw an image on the canvas. I've researched a lot and found for instance that I can't set the image src while the object is being created (so I've put that in a function). The image seems to be available as it shows up in the console and can be appended to the body. What am I missing please?

 (function ($) { $.fn.preload = function() { // http://stackoverflow.com/a/476681 this.each(function(){ $('<img/>')[0].src = this; }); } })(jQuery); $(document).ready(function() { $(['./images/grass-500x500.png']).preload(); // I've tried with and without this function (defined elsewhere) // Object literal pattern var game = { // Background image background: new Image(), setBGSource: function() { this.background.src = 'images/grass-500x500.png'; }, // Canvas details canvas: $("#canvas")[0], ctx: canvas.getContext("2d"), WIDTH: $("#canvas").width(), HEIGHT: $("#canvas").height(), // Game details CELL_WIDTH: 10, direction: null, food: null, score: null, snakeArray: [], init: function() { this.direction = "right"; this.createSnake(); this.setBGSource(); this.draw(); }, createSnake: function() { var length = 5; // Initial length of snake for (var i = length - 1; i >= 0; i--) { this.snakeArray.push({ x: i, y: 1 // y : 0 - initial position of snake in cell units }); } }, // Create food item createFood: function() { this.food = { x: Math.round(Math.random() * (WIDTH - CELL_WIDTH) / CELL_WIDTH), y: Math.round(Math.random() * (HEIGHT - CELL_WIDTH) / CELL_WIDTH) } // Position of food with x and and y between 0 and eg 44 }, // Drawing function draw: function() { // Repaint the background on each frame console.log(this.background); // displays <img src="images/grass-500x500.png"> this.ctx.drawImage(this.background, 0, 0); // WHY DOESN'T THIS WORK PLEASE? $('body').append(this.background); // appends image, no problem } }; game.init(); }) 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <canvas id="canvas"></canvas> 

The problem here is that the image is being preloaded asynchronously while at the same time you call game.init() and thus game.draw() , which expects the image being loaded already.

Thus, unless the image is in your browser's cache, the asynchronous preloading might not have finished at the time of game.draw() .

You need to wait until preloading has finished before calling game.init() . JavaScript offers some good tools in dealing with asynchronous execution, eg callbacks, promises etc.

Have a look here: https://gamedev.stackexchange.com/questions/24102/resource-loader-for-an-html5-and-javascript-game

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM