2012-04-06 2 views
1

Я изучаю HTML5 (и OO Javascript), и я пытаюсь сделать простой игровой движок, но рендеринг на холст работает в очень странных условиях. Here является ссылка на страницу и вот мой index.html:

HTML5 рендеринг холста странно

<html> 
<head> 
    <script type="text/javascript"> 
     function load() 
     { 
      var game = new Game(); 
      game.start(); 
     } 
    </script> 
    <title>Game</title> 
    <style> 
     canvas 
     { 
      outline:0; 
      border:1px solid #000; 
      margin-left: auto; 
      margin-right: auto; 
     } 
    </style> 
</head> 
<body onload="load()"> 
    <canvas id='c'></canvas> 

    <script src="classes/Tuple.js"></script> 
    <script src="classes/Rect.js"></script> 
    <script src="classes/Sprite.js"></script> 
    <script src="classes/Game.js"></script> 
</body> 
</html> 



При первой загрузке, это даст NS_ERROR_DOM_TYPE_MISMATCH_ERR Exception в Firefox 11.0 и TypeError Исключение в Chrome 18.0. Для того, чтобы сделать его работу:

Firefox 11,0

  • выберите URL в адресной строке и вручную нажмите клавишу ВВОД ИЛИ
  • нажмите кнопку обновления ИЛИ
  • нажмите F5.

Chrome 18,0

  • выберите URL в адресной строке и вручную нажмите клавишу ВВОД ИЛИ
  • нажмите кнопку обновления ИЛИ
  • нажать клавишу F5 или
  • нажмите Shift/Ctrl + F5.

То, что я подозреваю, - только предположение, но мне кажется, как один или несколько файлов .js не доступен/готов к тому времени, это называется во время первой загрузки страницы. Пройдя несколько раз в Firebug, кажется, что спрайты не загружаются в первый запрос страницы.

Возможно, некоторые из файлов .js по-прежнему загружаются при создании, затем кешировании экземпляра в Game(), и все они доступны только при загрузке второй страницы?

Любые идеи? Я был бы благодарен за ваше взятие, спасибо!

+0

Хм, я сделал Game.js первый из четырех включений, но я, похоже, получаю такое же поведение (я обновляю силу, чтобы я не уходил из кешированной копии) –

ответ

3

Я скопировал ваши файлы локально и провел некоторые проверки. Мне кажется, что это не ваши файлы JavaScript, которые недоступны, но ваш спрайт.

Вы не загружаете PNG, пока не позвоните Game.start. Когда вы это сделаете:

roadSpritesheetImage.src = "assets/sprites/player/playerSpriteSheet.png"; 

Это начинает асинхронную загрузку изображения. Остальная часть кода выполняется до того, как изображение полностью загрузится, поэтому, когда вы нарезаете изображение, вы отрезаете его так, как если бы атрибут src был нулевым.

Вот почему вы можете поразить обновление, и все работает так, как ожидалось ... изображение кэшируется.

Вы можете сортировать выгрузить загрузку вашего спрайта, добавив тег изображения непосредственно перед холстом:

<img src="assets/sprites/player/playerSpriteSheet.png" style="display:none;" /> 

Это будет работать, так как событие нагрузки тела не уволено до содержания (включая изображение) является полностью загружен (я считаю, мне пришлось бы это посмотреть). Затем, если вы присвоите это изображение img.src, вы будете ссылаться на кешированное изображение.

В качестве альтернативы вы можете связать остальную функциональность игры с номером img.onload. Например:

self.loadSprites = function() 
{ 
    var roadSpritesheetImage = new Image();  
    roadSpritesheetImage.onload = function() { 
     self.entities.push(new Sprite("testTile", 
      roadSpritesheetImage, 
      new Tuple(16, 16), 
      new Rect(0, 0, 32, 16))); 
     self.run(); 
    }; 

    roadSpritesheetImage.src = "assets/sprites/player/playerSpriteSheet.png"; 
}; 

self.run = function() { 
    var drawSuccessful = false; 
    drawSuccessful = self.entities[0].draw(self.context); 
    self.entities[0].nextFrame(); 

    //if we managed to draw the Sprite successfully without any raised exceptions 
    if(drawSuccessful) { 
     setTimeout(self.run, 300); 
    } else { alert("stopping execution of the game."); } 
}; 

self.start = function() 
{ 
    self.loadSprites(); 
}; 

Выполнение этой операции является более чистым, и это гарантирует, что у вас нет каких-либо условий гонки с вашими ресурсами.

У меня была аналогичная проблема с плагином jQuery, который я создал, чтобы нарисовать N-головоломку из исходного изображения. Я нашел this MDN documentation чрезвычайно полезным в то время, хотя в итоге я использовал нарезанные divs вместо холста.

+0

Это замечательно! Посмотрев на процесс загрузки в Chrome Timeline, я начал подозревать то же самое. Однако я просто предположил, что когда вы объявляете новый объект Image(), он просто ждет, пока изображение не будет загружено до продолжения. Теперь я вижу, что это не так. Это новая учетная запись, поэтому у меня недостаточно репутации, чтобы повысить свой пост, но когда я это сделаю. Еще раз спасибо, вы избавили меня от путаницы! –

+1

@AlexAlksne, вы можете отметить это как ответ. Теперь вам нужно учитывать при загрузке 2+ спрайтов, 'self.run()' не следует вызывать, пока все они не будут загружены. – Alexander

+0

@AlexAlksne без проблем. В таком случае может быть трудно поймать время загрузки ... особенно когда ваш спрайт составляет всего 4 КБ. –

Смежные вопросы