【问题标题】:Sliding puzzle (javascript & HTML5) - need to animate moving elements滑动拼图 (javascript & HTML5) - 需要动画移动元素
【发布时间】:2015-05-23 12:10:03
【问题描述】:

我有一个滑动拼图,其中图像被分割成一个网格,您可以将正方形移动到空白空间。我想让这个动画,所以实际上滑入空白空间,而不仅仅是出现在那里。这是我正在使用的代码笔:http://codepen.io/akshivictor/pen/jPPypW 和下面的 javascript。

var context = document.getElementById('puzzle').getContext('2d');

var img = new Image();
img.src = 'http://i.imgur.com/H1la3ZG.png?1';
img.addEventListener('load', drawTiles, false);

var boardSize = document.getElementById('puzzle').width;
var tileCount =3;

var tileSize = boardSize / tileCount;

var clickLoc = new Object;
clickLoc.x = 0;
clickLoc.y = 0;

var emptyLoc = new Object;
emptyLoc.x = 0;
emptyLoc.y = 0;

var solved = false;

var boardParts;
setBoard();

document.getElementById('scale').onchange = function() {
  tileCount = this.value;
  tileSize = boardSize / tileCount;
  setBoard();
  drawTiles();
};

document.getElementById('puzzle').onclick = function(e) {
  clickLoc.x = Math.floor((e.pageX - this.offsetLeft) / tileSize);
  clickLoc.y = Math.floor((e.pageY - this.offsetTop) / tileSize);
  if (distance(clickLoc.x, clickLoc.y, emptyLoc.x, emptyLoc.y) == 1) {
    slideTile(emptyLoc, clickLoc);
    drawTiles();
  }
};

function setBoard() {
  boardParts = new Array(tileCount);
  for (var i = 0; i < tileCount; ++i) {
    boardParts[i] = new Array(tileCount);
    for (var j = 0; j < tileCount; ++j) {
      boardParts[i][j] = new Object;
      boardParts[i][j].x = (tileCount - 1) - i;
      boardParts[i][j].y = (tileCount - 1) - j;
    }
  }
  emptyLoc.x = boardParts[tileCount - 1][tileCount - 1].x;
  emptyLoc.y = boardParts[tileCount - 1][tileCount - 1].y;
  solved = false;
}

function drawTiles() {
  context.clearRect(0, 0, boardSize, boardSize);
  for (var i = 0; i < tileCount; ++i) {
    for (var j = 0; j < tileCount; ++j) {
      var x = boardParts[i][j].x;
      var y = boardParts[i][j].y;
      if (i != emptyLoc.x || j != emptyLoc.y || solved == true) {
        context.drawImage(img, x * tileSize, y * tileSize, tileSize, tileSize,
          i * tileSize, j * tileSize, tileSize, tileSize);
      }
    }
  }
}

function distance(x1, y1, x2, y2) {
  return Math.abs(x1 - x2) + Math.abs(y1 - y2);
}

function slideTile(toLoc, fromLoc) {
  if (!solved) {
    boardParts[toLoc.x][toLoc.y].x = boardParts[fromLoc.x][fromLoc.y].x;
    boardParts[toLoc.x][toLoc.y].y = boardParts[fromLoc.x][fromLoc.y].y;
    boardParts[fromLoc.x][fromLoc.y].x = tileCount - 1;
    boardParts[fromLoc.x][fromLoc.y].y = tileCount - 1;
    toLoc.x = fromLoc.x;
    toLoc.y = fromLoc.y;
    checkSolved();
  }
}

function checkSolved() {
  var flag = true;
  for (var i = 0; i < tileCount; ++i) {
    for (var j = 0; j < tileCount; ++j) {
      if (boardParts[i][j].x != i || boardParts[i][j].y != j) {
        flag = false;
      }
    }
  }
  solved = flag;
}

我对本文http://www.sitepoint.com/image-manipulation-with-html5-canvas-a-sliding-puzzle-2/中的滑动拼图进行了改编

【问题讨论】:

    标签: javascript html animation sliding


    【解决方案1】:

    做平移动画的一般方法是:

    animate(object):
        while(object.not_in_place())
            object.move(small_amount)
            sleep(some_time)
            draw(object)
        repeat
    

    因此,将图像向正确的方向移动少量(几个像素)并以足够快的速度重复该移动(尽管中间有睡眠)以获得滑动动画。

    如果您需要缓入或缓出动画,您的翻译量将随时长而变化。

    对于固定间隔后的重复调用,请在 JavaScript 中使用 setTimeout

    更多详情

    假设您正在从(a, b) 移动到(c, b)(这是二维笛卡尔平面中的坐标),那么在 x 方向上移动的距离是 (c - b) 和 y 方向是 0。 所以,将(c - b) 的距离除以x

    让动画的总持续时间为T,然后将其划分为相同数量的间隔,例如t。 因此,您的算法变为:

    while(object.x != c)
        object.x += x
        sleep(t)
        object.draw()
    repeat 
    

    同样,您可以针对 y 方向的情况进行操作。请注意,在您的游戏中,您无需沿任意方向移动,只需水平或垂直移动即可。

    虽然 JavaScript 没有等效的 sleep() 例程,但您可以像这样使用 setTimeout

    function x() { 
        id = setTimeout(x, 1000); // x will be called every 1 seconds ( = 1000 ms)
    }
    
    clearTimeout(id); // this removes the timeout and stops the repeated function calls
    

    【讨论】:

      猜你喜欢
      • 2014-03-17
      • 2021-11-27
      • 2018-09-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多