繁体   English   中英

打字稿:将图片向左移动,然后向右移动

[英]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.

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