2014-10-14 4 views
1

Мне нужно создать анимацию dropping box, которая должна отскочить 10 раз, когда она достигает определенной Y-точки на холсте, каждый раз в два раза ниже предыдущей. Поэтому у меня есть анимация сбрасывающей коробки, но я не могу сделать работу отказов. Вот функции, которые я написал:Создание анимации с расширением окна на холсте

function dropBox(y, width, height) { 
    var img_box = new Image(); 
    img_box.src = 'images/gift_box_small.png'; 

    var box_y_pos = y; 
    if(y==0) 
     box_y_pos = y-img_box.naturalHeight; 


    img_box.onload = function(){ 
     ctx_overlay.save(); 
     ctx_overlay.clearRect(0,0,width,height); 
     ctx_overlay.drawImage(img_box, (width/2)-(img_box.naturalWidth/2), box_y_pos); 
     ctx_overlay.restore(); 
    } 

    box_y_pos += 3; 

    var box_bottom_position = box_y_pos - img_box.naturalHeight; 

    if(box_y_pos+img_box.naturalHeight<height-25) 
     var loopTimer = setTimeout(function() {dropBox(box_y_pos, width, height)},24); 
    else 
     bounceBox(img_box, box_y_pos, box_y_pos, (height/2)-(img_box.naturalHeight/2), "up"); 

} 

function bounceBox(img, img_final_pos, y, midway_pos, direction){ 
    var midway = midway_pos; 
    var direction = direction; 
    var img_y_pos = y; 

    img.onload = function(){ 
     ctx_overlay.save(); 
     ctx_overlay.clearRect(0,0,docWidth,docHeight); 
     ctx_overlay.drawImage(img, (docWidth/2)-(img.naturalWidth/2), img_y_pos); 
     ctx_overlay.restore(); 
    } 

    for(var i = 0; i < 10; i++){ 
     if(direction=="up"){ 
      //going up 
      if(img_y_pos>midway_){ 
       img_y_pos -= 3; 
       var loopTimer = setTimeout(function() {bounceBox(img, img_final_pos, img_y_pos, midway_pos, "up")},24); 
      } else { 
       img_y_pos += 3; 
       midway = Math.floor(midway /= 2); 
       if(midway%2>0) 
        midway += 1; 
       var loopTimer = setTimeout(function() {bounceBox(img, img_final_pos, img_y_pos, midway_pos, "down")},24); 
      } 
     } else { 
      //going down 
      if(img_y_pos < img_final_pos){ 
       img_y_pos += 3; 
       var loopTimer = setTimeout(function() {bounceBox(img, img_final_pos, img_y_pos, midway_pos, "down")},24); 
      } 
     } 
    } 
} 

JSFiddle: http://jsfiddle.net/n2derqgw/3/

Почему это не работает, и как я могу заставить его работать?

+0

Вот некоторый псевдокод, чтобы вы указывали в правильном направлении. 'if (Box_Y + Box_VY> = canvas_height) Box_VY * = - 1;' В принципе, что бы это сделало (не используя ваши переменные), является то, что позиция, в которой будет находиться поле, больше высоты холста, отмените направление коробки. Когда я делаю анимацию, у меня есть один 'setInterval()', который вызывает сингулярную функцию рисования с отдельными вызовами функций внутри функции draw (только для чистоты). При рисовании формы я обычно имею переменную скорости и переменную положения. Например: 'Box_VY'. Если Box_VY - то, что Y идет вниз – Brendan

ответ

1

Чтобы избежать головной боли, лучше обработать анимацию в пределах одной функции, вызванной с помощью setInterval.
И сохраняйте все связанные с анимацией данные в одном объекте.
Так что ниже код не совсем то, что вы хотите, но должен вам начать:

http://jsfiddle.net/n2derqgw/4/

Установка:

var canvas_overlay, ctx_overlay, docWidth, docHeight; 

var img_box = new Image(); 
img_box.src = 'http://corkeynet.com/test/images/gift_box_small.png'; 

var mustBeReadyCount = 2; // must load image and window 

img_box.onload = launchWhenReady; 
window.onload = launchWhenReady; 

var animationStep = ''; 
var boxAnimationData = { 
    animationStep: '', 
    y: 0, 
    maxY: 0, 
    bounceCount: 6, 
    direction: -1, 
    bounceHeight: 0 
}; 

function launchWhenReady() { 
    mustBeReadyCount--; 
    if (mustBeReadyCount) return; 
    docWidth = window.innerWidth; 
    docHeight = window.innerHeight; 
    canvas_overlay = document.getElementById('canvas_overlay'); 
    ctx_overlay = canvas_overlay.getContext('2d'); 
    resizeCanvas(docWidth, docHeight); 
    boxAnimationData.animationStep = 'falling'; 
    boxAnimationData.bounceHeight = docHeight/2 - img_box.height; 
    setInterval(animateBox, 30); 
}; 

Более интересный код здесь:

function animateBox() { 
    if (boxAnimationData.animationStep == 'falling') dropBox(); 
    else if (boxAnimationData.animationStep == 'bouncing') bounceBox(); 
} 

function dropBox() { 
    ctx_overlay.clearRect(0, 0, docWidth, docHeight); 
    boxAnimationData.y += 3; 
    if (boxAnimationData.y + img_box.height > docHeight) { 
     boxAnimationData.animationStep = 'bouncing'; 
    } 
    ctx_overlay.drawImage(img_box, (docWidth/2) - (img_box.width/2), boxAnimationData.y); 
} 


function bounceBox() { 
    ctx_overlay.clearRect(0, 0, docWidth, docHeight); 
    boxAnimationData.y += boxAnimationData.direction * 3; 
    if (boxAnimationData.y + img_box.height > docHeight) { 
     // reached floor ? swap direction 
     boxAnimationData.direction *= -1; 
     // and reduce jump height 
     boxAnimationData.bounceHeight *= 3/2; 
     boxAnimationData.bounceCount--; 
     if (!boxAnimationData.bounceCount) boxAnimationData.animationStep = ''; 

    } else if (boxAnimationData.y < boxAnimationData.bounceHeight) { 
     boxAnimationData.direction *= -1; 
    } 
    ctx_overlay.drawImage(img_box, (docWidth/2) - (img_box.width/2), boxAnimationData.y); 
} 
+0

На самом деле это именно то, что я хотел! Просто изменилось несколько параметров, и все получилось просто отлично. Проблема теперь в том, когда я пытаюсь объединить ее с другой анимацией, которую у меня есть на странице: я вижу другую анимацию, но я не вижу этого поля: http://jsfiddle.net/n2derqgw/6/ Что я делал неправильно ? – Igal

+0

Ну, очень хороший способ сделать вещи - это урегулировать раз и навсегда вопрос загрузки: загрузить * все * нужные вам изображения, а затем запустить приложение. Если вы сделаете это, я посмотрю ваш код. Cheers – GameAlchemist

+0

Ничего, я, наконец, получил его! Большое спасибо за Вашу помощь! :) – Igal

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