2015-05-23 6 views
0

У меня есть раздвижная головоломка, где изображение разбивается на сетку, и вы можете перемещать квадраты в пустое пространство. Я хотел бы, чтобы это оживлялось, поэтому, чтобы фактически скользить в пустое пространство, не просто появляйтесь там. Вот код, из которого я работаю: http://codepen.io/akshivictor/pen/jPPypW и javascript ниже.Раздвижная головоломка (javascript и HTML5) - нужно анимировать движущиеся элементы

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/

ответ

0

Общий способ сделать трансляционной анимации:

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

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

Если вам нужна анимация с облегчением или легкостью, количество переводов изменится с продолжительностью.

Для повторных вызовов после фиксированного интервала используйте JavaScript в формате setTimeout.

Подробнее

Допустим, вы двигаетесь от (a, b) к (c, b) (которые являются координатами в 2-мерном декартовой плоскости), то расстояние перемещения в направлении х является (c - b) и у-направление 0. Итак, разделите расстояние (c - b) в равных количествах, чтобы сказать x.

Пусть общая продолжительность анимации будет T, а затем разделите ее на такое же количество интервалов t. Следовательно, ваши алгоритмы становятся:

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

Кроме того, вы можете сделать для случая у-направления. Обратите внимание: в вашей игре вам не нужно двигаться в произвольном направлении, только горизонтально или вертикально, что упрощает реализацию.

Хотя, JavaScript имеет никакого эквивалента сна() рутина, вы можете использовать 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