2011-12-23 4 views
1

Я пытаюсь визуализировать усиливающий агент, перемещающийся по 2-й сетке. Я закодировал визуализацию с использованием холста, и каждый раз, когда мой агент делает ход, я пытаюсь обновить сетку. Я надеялся увидеть анимацию, но вместо этого я ничего не вижу, пока агент не завершил все эти шаги, и я вижу конечное состояние. Если я перейду с помощью инструментов Google Chromes Developer, я увижу отдельные шаги. Я не думаю, что проблема в том, что мой код работает быстро, потому что каждый шаг занимает пару секунд.Элемент холста не обновляется

Моя реализация такова, что функция gridWorld() вызывала один раз, чтобы создать новый объект, и executeAction вызывается каждый раз, когда хочу рисовать. Как показано, я использовал ctx.save() и ctx.restore(), но это только попытка решить эту проблему, и, похоже, это не имеет никакого значения.

Благодаря

var execute gridWorld = function(action) { 
    var canvas = document.getElementById("grid"); 
    this.ctx = canvas.getContext("2d"); 

    this.executeAction = function(action) { 
     this.ctx.save() 
     // ... Do reinforcement learning stuff 
     // For every cell in grid, do: 
     this.ctx.fillStyle = "rgb(244,0,0)" 
     this.ctx.fillRect(positionX, poisitonY, 10,10) 

     this.ctx.restore(); 
    } 
} 

ответ

0

Даже если код занимает много времени, чтобы выполнить, браузер не будет обновляться на дисплее до тех пор, пока фактический разрыв в коде. Используйте setTimeout(), чтобы вызвать прерывание выполнения кода всякий раз, когда вы хотите обновить холст.

+0

Спасибо, но я не уверен, как с этим работать. В моей функции выполнения выполнения я заменил код чертежа на setTimeout (draw, 15). Но кажется, что функция draw не вызывается после 15 миллисекунд, но вместо этого все они вызываются после завершения основного кода (т. Е. Той же проблемы, что и раньше). Также код чертежа зависит от состояния агента, как я могу быть уверенным, что это состояние будет, если оно вызвано из последовательности? – zenna

+0

'[выполнить код для рисования первого кадра] [wait] [выполнить код для рисования второго кадра] [wait]' и т. Д. Предыдущий кадр должен использовать 'setTimeout' для функции, которая рисует следующий кадр. Если ваш код не настроен по кадру, вам необходимо изменить его так, как есть. –

1

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

Live Demo

Если я сделал что-то вроде этого, например

for(x = 0; x < 256; x++){ 
    player.x = x; 
    ctx.fillStyle = "#000"; 
    ctx.fillRect(0,0,256,256); 
    ctx.fillStyle = "#fff"; 
    ctx.fillRect(player.x,player.y,4,4); 
} 

Вы бы только когда-либо видеть игрока в конце правления каждый раз, когда эта функция вызывается, и вы Wouldn» t видеть любую из анимаций между ними, потому что цикл работает слишком быстро. Вот почему в моей живой демонстрации я делаю это небольшими приращениями и вызываю ничью каждые 15 миллисекунд, чтобы у вас была возможность увидеть, что накладывается на холст.

+0

Спасибо, но, как я уже сказал в своем вопросе, я не думаю, что мой код должен быть быстрым (так как их значительное вычисление происходит в каждом цикле). Вместо этого я думаю, что основной цикл каким-то образом блокирует обновление экрана. Я попытался использовать setTimeout, чтобы обойти это без успеха, как описано в моем комментарии к ответу выше. Спасибо – zenna

+0

@zenna, чтобы кто-то мог помочь вам увидеть больше кода или примера. Просто так, чтобы вы знали, что в цикле вы никогда не увидите обновление к холсту, если не выйдете из него, в цикле for вы никогда не увидите обновления, которые происходят в цикле for fyi. – Loktar

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