[英]How can I create a running animation on an HTML5 canvas?
我正在構建一個簡單的2D游戲,以嘗試學習畫布。 角色可以在虛擬環境中運行,並且一個名為yOffset的變量控制其與屏幕頂部的偏移量。 我還有一個名為running的全局變量,它根據字符是否正在運行而將自身設置為true或false(此處未顯示)。 我的目標是使角色在運行時上下擺動,以下所有代碼都產生了許多setInterval()
。 這是使角色運行的正確方法,還是應該以其他方式進行? 如果是這樣,怎么辦?
$(document).keydown(function(e) {
if(e.which == 97) {
running = true;
run();
} else if(e.which == 100) {
running = true;
run();
} else if(e.which == 119) {
running = true;
run();
} else if(e.which == 115) {
running = true;
run();
}
});
(是的,如果角色停止運行,則運行變量確實變為false [此處未顯示]-我已經確保了運行變量運行良好)
runTimer = 0;
function run() {
if(runTimer == 0 && running) {
runTimer = 1;
yOffset = 80;
setTimeout(function() {
yOffset = 120;
}, 150);
setTimeout(function() { if (running) { runTimer = 0;run(); } }, 300);
}
}
如果您需要更多信息,請在此處獲得我當前正在使用的版本。
我認為你可以簡化你的代碼,而事實上,你必須在很可能的情況下,你想添加一些其它字符。
為了重新使用動畫,最好將動畫(==角色將經歷的不同步驟)和動畫狀態(==角色現在位於哪一步)分開。
我在這里寫了動畫系統的一些元素。
因此,我定義了什么是動畫步驟,整個動畫(到目前為止,這只是動畫步驟的一個數組)和一個動畫器(保存狀態,有人可能會將其視為動畫的“讀取器”)。
一旦定義了動畫和動畫師,並啟動了動畫師,您只需要調用tick(time)以使動畫繼續前進,並調用offset()來讀取偏移量,這比與一堆setIntervals戰斗要簡單得多。
// --------------------
function AnimationStep(duration, offset) {
this.duration = duration;
this.offset = offset;
// you might add : image index, rotation, ....
}
// --------------------
function Animation(animationSteps) {
this.steps = animationSteps; // Array of AnimationStep
}
// define a read-only length property
Object.defineProperty(Animation.prototype, 'length', {
get: function () {
return this.steps.length
}
});
// --------------------
function Animator() {
this.currentAnimation = null;
this.step = -1;
this.running = false;
this.remainingTime = 0; // remaining time in current step;
}
Animator.prototype.startAnim = function (newAnim, firstStep) {
this.currentAnimation = newAnim;
this.step = firstStep || 0;
this.remainingTime = newAnim.steps[this.step].duration;
this.running = true;
}
Animator.prototype.tick = function (dt) {
// do nothing if no animation ongoing.
if (!this.running) return;
this.remainingTime -= dt;
// 'eat' as many frames as required to have a >0 remaining time
while (this.remainingTime <= 0) {
this.step++;
if (this.step == this.currentAnimation.length) this.step = 0;
this.remainingTime += this.currentAnimation.steps[this.step].duration;
}
};
Animator.prototype.offset = function () {
return this.currentAnimation.steps[this.step].offset;
}
// ______________________________
// example
var bounceAnim = [];
bounceAnim.push(new AnimationStep(200, 10));
bounceAnim.push(new AnimationStep(180, 20));
bounceAnim.push(new AnimationStep(150, 30));
bounceAnim.push(new AnimationStep(300, 40));
bounceAnim.push(new AnimationStep(320, 45));
bounceAnim.push(new AnimationStep(200, 40));
bounceAnim.push(new AnimationStep(120, 30));
bounceAnim.push(new AnimationStep(100, 20));
var anim1 = new Animation(bounceAnim);
var animator1 = new Animator();
var animator2 = new Animator();
animator1.startAnim(anim1);
animator2.startAnim(anim1, 3);
// in action :
var ctx = document.getElementById('cv').getContext('2d');
function drawScene() {
ctx.fillStyle = 'hsl(200,60%, 65%)';
ctx.fillRect(0, 0, 600, 200);
ctx.fillStyle = 'hsl(90,60%,75%)';
ctx.fillRect(0, 200, 600, 200);
ctx.fillStyle = 'hsl(10,60%,75%)';
ctx.fillRect(200, 200 + animator1.offset(), 22, 22);
ctx.fillStyle = 'hsl(40,60%,75%)';
ctx.fillRect(400, 200 + animator2.offset(), 22, 22);
animator1.tick(20);
animator2.tick(20);
}
setInterval(drawScene, 20);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.