6.4_精灵动画制作器
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>精灵动画制作器</title>
<style>
body{
background: #ddd;
}
#canvas{
position: absolute;
top: 30px;
left: 10px;
background: #FFFFFF;
cursor: crosshair;
margin-left: 10px;
margin-top: 10px;
box-shadow: 4px 4px 8px rgba(0,0,0,0.5);
-webkit-box-shadow: 4px 4px 8px rgba(0,0,0,0.5);
-moz-box-shadow: 4px 4px 8px rgba(0,0,0,0.5);
}
input{
margin-left: 15px;
}
</style>
</head>
<body>
<input id="explosionButton" type="button" value="bomb" />
<canvas id="canvas" width="462" height="500"></canvas>
</body>
<script>
var Sprite = function(name,painter,behaviors){
if(name !== undefined){ this.name = name; }
if(painter !== undefined){ this.painter = painter; }
this.top = 0;
this.left = 0;
this.width = 10;
this.height = 10;
this.velocityX = 0;
this.velocityY = 0;
this.visible = true;
this.animating = false;
this.behaviors = behaviors || [];
}
Sprite.prototype = {
paint:function(context){
if(this.painter !== undefined && this.visible){
this.painter.paint(this,context);
}
},
update:function(context,time){
for(var i=0;i<this.behaviors.length;i++){
this.behaviors[i].execute(this,context,time);
}
}
}
</script>
<script>
var ImagePainter = function (imageUrl){
this.image = new Image();
this.image.src = imageUrl;
}
ImagePainter.prototype ={
paint:function(sprite,context){
if(this.image.complete){
context.drawImage(this.image,sprite.left,sprite.top,sprite.width,sprite.height);
}
}
}
</script>
<script>
var SpriteAnimator = function(painters, elapsedCallback){
this.painters = painters || [];
this.elapsedCallback = elapsedCallback;
this.duration = 1000;
this.startTime = 0;
this.index = 0;
};
SpriteAnimator.prototype = {
start:function(sprite,duration){
var endTime = +new Date() + duration;
var period = duration/this.painters.length;
var animator = this;
var originalPainter = sprite.painter;
var lastUpdate = +new Date();
this.index = 0;
sprite.animating = true;
sprite.painter = this.painters[this.index];
requestAnimationFrame(function spriteAnimatorAnimate(time){
time = +new Date();
if(time<endTime){
if(time - lastUpdate >period){
sprite.painter = animator.painters[++animator.index];
lastUpdate = time;
}
requestAnimationFrame(spriteAnimatorAnimate);
}else{
animator.end(sprite,originalPainter);
}
});
},
end:function(sprite,originalPainter){
if(this.painters == explosionPainters){
sprite.animating = false;
console.log('结束了');
}
if(this.elapsedCallback){
this.elapsedCallback(sprite);
}else{
sprite.painter = originalPainter;
}
}
}
</script>
<script>
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
var explosionButton = document.getElementById('explosionButton');
var bomb_left = 100;
var bomb_top = 80;
var bomb_width = 180;
var bomb_height = 130;
var num_explosion_painters = 9;
var num_fuse_painters = 9;
var bombPainter = new ImagePainter('img/bomb.jpg');
var bombNoFusePainter = new ImagePainter('img/bomb-no-fuse.jpg');
var fuseBurningPainters =[];
var explosionPainters = [];
var fuseBurningAnimator = new SpriteAnimator(fuseBurningPainters,function(){
bomb.painter = bombNoFusePainter;
});
var explosionAnimator = new SpriteAnimator(explosionPainters,function(){
bomb.painter = bombPainter;
});
var bomb = new Sprite('bomb',bombPainter);
bomb.left = bomb_left;
bomb.top = bomb_top;
bomb.width = bomb_width;
bomb.height = bomb_height;
for(var i =1; i<=num_fuse_painters;i++){
fuseBurningPainters.push(
new ImagePainter('img/fuse-0'+ i +'.jpg'));
}
for(var i =1; i<=num_explosion_painters;i++){
explosionPainters.push(
new ImagePainter('img/explosion-0'+ i +'.jpg'));
}
window.requestAnimationFrame(animate);
function animate(now){
console.log('动画持续绘制中');
now = +new Date();
context.clearRect(0,0,canvas.width,canvas.height);
bomb.paint(context);
window.requestAnimationFrame(animate);
}
explosionButton.onclick = function(){
if(bomb.animating){
console.log('不执行点击操作');
return;
};
fuseBurningAnimator.start(bomb,2000);
setTimeout(function(){
explosionAnimator.start(bomb,1000);
setTimeout(function(){
bomb.painter = bombPainter;
},2000)
},3000);
}
</script>
</html>