[英]Typescript: Moving an image to the left and then back to the right
第一个免责声明:我对Typescript / javascript /前端开发仍然非常陌生
背景:我有一组图像(代表一副纸牌)。 当轮到AI玩纸牌时,我试图显示一种“思维”的模拟,而不是立即玩纸牌。 我的模拟是遍历卡片的手并“选择”每张卡片(通过“选择”,我的意思是将图像稍微向左移动,然后再向右移动)。
我正在使用Visual Studio Code,并且正在Chrome中调试。 我当前的代码如下。 前提是进行API调用(实际上是执行AI逻辑的地方)。 然后,演示文稿反复遍历卡片的手,每等待一秒,将等待1/4秒,将卡片向左移动,再等待1/4秒,然后将卡片向右移动。 在“选择”所有卡之后,将播放实际的卡。 我目前在回调函数中拥有所有功能,以使其保持同步,但是我不确定我是否需要这样做。
// Call in to the API, which will perform the AI logic
// The API will return a slot that was played, which contains the card placed into that slot
opponentTurn(callback)
{
this.boardService.opponentTurn()
.subscribe(
cardPlayed =>
{
// Set the card played
let cardData = [];
cardData = JSON.parse(cardPlayed.toString());
// To add a slight hint of "thinking", let's "select" (slightly move the card to the left) each card down, up, and back down to the card that the API selected
this.selectCard(function(_thisagain) {
// Done
// Now simulate the move
_thisagain.dragService.simulateDragDrop(cardData);
});
callback(this);
}
);
}
// Call this to "select" a card; used by the AI "thinking" simulation
selectCard(callback)
{
for (var i = 0; i < this.players[1].cardHand.length; i++)
{
let imgObj = document.getElementById(this.players[1].name + i);
if (imgObj != null)
{
this.moveCard(imgObj, '400px', function(_thisagain) {
_thisagain.moveCard(imgObj, '350px', function() {
// Done
});
});
}
}
callback(this);
}
moveCard(imgObj, position, callback)
{
this.wait(250, function() {
imgObj.style.right = position;
});
callback(this);
}
wait(ms, callback)
{
var start = new Date().getTime();
var end = start;
while(end < start + ms)
{
end = new Date().getTime();
}
callback(this);
}
因此,我一直在挣扎的是代码可以正常工作,但是只有当我在上面设置一个断点时才可以。 例如,如果我在“ _thisagain.moveCard(imgObj,'350px',function(){”每次我“继续”时,如果我删除断点,则这些卡根本不会移动(但是我仍然需要等待才能在板上玩该卡)。
仍然是Typescript / javascript的新手,我不太确定发生了什么。 似乎当我设置了断点时,会发生重画以显示卡偏移。 没有断点,似乎没有重绘发生。 不过,我不确定如何纠正这个问题,因此也不确定为什么要在这里。
因此,经过更多的研究和大量的反复试验后,我开始进行研究。 真正使我步入正轨的帖子是: DOM在长期运行的功能上刷新
在该问题中,有一个回答说:“网页是基于单个线程控制器更新的,并且一半的浏览器不会更新DOM或样式,直到您的JS执行停止,才将计算控制权交给浏览器。”
原来那是我所缺少的关键。 我在单个语句中处理了太多内容,并且js没有释放回浏览器,因此DOM / html未被更新以显示“动画”。
然后,我用一个也张贴在答案中的jsfiddle示例将“工作”线程拼凑在一起,该线程根据过程“状态”将进程分解为多个块,并使用setTimeout()将控件返回给浏览器。 每个工作线程仍设置为回调函数,以确保每个块中的处理在继续之前完成。 对于我最初的问题,一切正常。 我仍在进行重构,并且我相信可能有更好的方法来实现结果,但是现在我很满意。
为了将来帮助某个可能偶然遇到我问题的人,这就是我的工作线程所拥有的。 当然,我对术语的选择可能不正确,但是要点是。 当我要开始流程时,可以设置“状态”文本并调用工作程序。 然后,工人根据需要处理流程。
doHeavyWork() {
if (this.status == 'finish')
{
// All steps done
}
else
{
let _this = this;
switch (_this.status)
{
case 'start':
_this.status = 'working';
_this.opSelectCard = 0;
this.opponentTurn(function(response) {
_this.opCardData = response;
_this.status = 'selectCard';
});
break;
case 'selectCard':
_this.status = 'working';
this.selectCard(_this.opSelectCard, function(response) {
_this.opImgObj = response;
_this.status = 'moveCardLeft';
});
break;
case 'moveCardLeft':
_this.status = 'working';
this.moveCardLeft(_this.opImgObj, '-25px', function(root) {
_this.status = 'moveCardRight';
});
break;
case 'moveCardRight':
_this.status = 'working';
this.moveCardRight(_this.opImgObj, '1px', function(root) {
_this.opSelectCard++;
if (_this.opSelectCard < _this.players[1].cardHand.length)
{
_this.status = 'selectCard';
}
else
{
_this.status = 'simulateDragDrop';
}
});
break;
case 'simulateDragDrop':
_this.status = 'working';
this.dragService.simulateDragDrop(_this.opCardData, function(root) {
_this.status = 'refreshDisplay';
});
break;
case 'refreshDisplay':
_this.status = 'working';
this.refreshCardDisplay(function(root) {
_this.status = 'refreshDisplay';
});
break;
case 'refreshBoard':
_this.status = 'working';
this.refreshBoard(_this.boardCards, function(root) {
_this.status = 'updateScore';
});
break;
case 'updateScore':
_this.status = 'working';
this.updateScore(_this.boardCards, function(_this) {
_this.status = 'switchTurns';
});
break;
case 'switchTurns':
_this.status = 'working';
this.switchTurns(function(_this) {
if (_this.turn == 1)
{
_this.status = 'finish';
}
else
{
_this.status = 'start';
}
});
break;
}
setTimeout(function() {
_this.doHeavyWork();
}, 0);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.