Maison > Article > interface Web > Cadre de jeu HTML5 Développement cnGameJS Principes d'animation réalisant des enregistrements
Dans le jeu, l'effet animation du personnage du jeu est une partie essentielle du jeu. Dans cette section, nous prenons comme exemple la construction des personnages de Super Mario pour expliquer l'implémentation de l'animation dans cnGameJS.
1. Principe :
Si une animation veut mettre en œuvre une série d'actions, on peut garder un instantané de chaque action et la mettre dans un grand photo Ci-dessus, à chaque fois que le cadre est mis à jour, les instantanés de chaque action sont cyclés pour être affichés, et enfin une animation est obtenue. Nous devons donc d'abord préparer une image comme celle-ci :
Vous la voyez ? Placez chaque action dans une position différente de l'image, et vous pourrez ensuite obtenir des effets d'animation en modifiant la position d'affichage.
Lorsque cnGameJS appelle la méthode start pour démarrer le jeu, il appellera la méthode initialize du gameObj entrant pour initialiser et générer une boucle de jeu. À chaque fois dans la boucle, la update. et méthode de dessin. Par conséquent, nous pouvons mettre l'initialisation de l'animation dans l'initialisation de gameObj, et placer respectivement la mise à jour et le dessin dans la mise à jour et le dessin de gameObj pour réaliser la lecture de l'animation.
Effet :
Code :
<body> <canvas id="gameCanvas">请使用支持canvas的浏览器查看</canvas> </body> <script src="http://files.cnblogs.com/Cson/cnGame_v1.0.js"></script> <script> var Src="http://pic002.cnblogs.com/images/2012/273330/2012021312050269.png"; /* 初始化 */ cnGame.init('gameCanvas',{width:50,height:60}); var gameObj={ initialize:function(){ this.marie=cnGame.SpriteSheet("marie",Src,{frameSize:[50,60],width:150,height:60,loop:true}); }, update:function(){ this.marie.update(); }, draw:function(){ this.marie.draw(); } } cnGame.loader.start([Src],gameObj); </script>
2 .Implement
Comme vu ci-dessus, nous n'avons besoin d'utiliser qu'une petite quantité de code pour réaliser la lecture d'une animation d'image. Ensuite, nous présenterons comment l'animation d'image dans cnGameJS est encapsulée.
Vous pouvez facilement constater que cnGameJS suit un modèle spécifique divise l' objet phases en trois : initialiser (initialisation), mettre à jour (mise à jour du cadre) et dessiner (dessiner) . De cette façon, nous pouvons facilement écrire des codes pour différentes fonctions dans les étapes correspondantes. L'animation du cadre spriteSheet ne fait pas exception et est également écrite selon ce modèle.
Initialisation : L'utilisateur définit certaines informations nécessaires.
spriteSheet.prototype={ /** *初始化 **/ init:function(id,src,options){ /** *默认对象 **/ var defaultObj={ x:0, y:0, width:120, height:40, frameSize:[40,40], frameDuration:100, direction:"right", //从左到右 beginX:0, beginY:0, loop:false, bounce:false }; options=options||{}; options=cg.core.extend(defaultObj,options); this.id=id; //spriteSheet的id this.src=src; //图片地址 this.x=options.x; //动画X位置 this.y=options.y; //动画Y位置 this.width=options.width; //图片的宽度 this.height=options.height; //图片的高度 this.image=cg.loader.loadedImgs[this.src]; //图片对象 this.frameSize=options.frameSize; //每帧尺寸 this.frameDuration=options.frameDuration; //每帧持续时间 this.direction=options.direction; //读取帧的方向(从做到右或从上到下) this.currentIndex=0; //目前帧索引 this.beginX=options.beginX; //截取图片的起始位置X this.beginY=options.beginY; //截图图片的起始位置Y this.loop=options.loop; //是否循环播放 this.bounce=options.bounce; //是否往返播放 this.onFinsh=options.onFinsh; //播放完毕后的回调函数 this.frames=caculateFrames(options); //帧信息集合 this.now=new Date().getTime(); //当前时间 this.last=new Date().getTime(); //上一帧开始时间 },
Il existe de nombreux paramètres ci-dessus, qui sont tous des préréglages pour les propriétés d'animation d'image. Il convient de noter que nous avons appelé la méthode privée caculateFrames pour calculer les informations de chaque image et les enregistrer dans des images afin de préparer le dessin de l'image.
Mise à jour du cadre :
Pendant le processus de mise à jour de chaque cadre, nous obtenons d'abord l'heure actuelle comme heure de début du cadre, et la comparons avec l'heure de début de l'image précédente Soustrayez pour obtenir le temps pris pour la dernière image. Si le temps pris dépasse le temps par image précédemment défini, une mise à jour de l'image peut être effectuée. Déterminez ensuite s'il faut boucler ou lire l'animation d'avant en arrière, et mettez à jour l'index d'image correspondant, le cas échéant. Une fois l'index de trame définitivement déterminé, les informations de trame peuvent être obtenues à partir du tableau de trames et renvoyées.
/** *更新帧 **/ update:function(){ this.now=new Date().getTime(); var frames=this.frames; if((this.now-this.last)>this.frameDuration){//如果间隔大于帧间间隔,则update var currentIndex=this.currentIndex; var length=this.frames.length; this.last=this.now; if(currentIndex>=length-1){ if(this.loop){ //循环 return frames[this.currentIndex=0]; } else if(!this.bounce){//没有循环并且没有往返滚动,则停止在最后一帧 this.onFinsh&&this.onFinsh(); this.onFinsh=undefined; return frames[currentIndex]; } } if((this.bounce)&&((currentIndex>=length-1&&path>0)||(currentIndex<=0&&path<0))){ //往返 path*=(-1); } this.currentIndex+=path; } return frames[this.currentIndex]; },
Dessin du cadre :
Une fois le cadre mis à jour, l'index du cadre actuel a été obtenu, la méthode de tirage peut donc l'obtenir à partir des cadres qui enregistrent toutes les informations de l'image. dans les informations de l'image actuelle (y compris la position de départ de l'interception de l'image, etc.), interceptant ainsi une grande image à la position spécifiée et dessinant l'image de la zone d'image :
/** *在特定位置绘制该帧 **/ draw:function(){ var currentFrame=this.getCurrentFrame(); var width=this.frameSize[0]; var height=this.frameSize[1]; cg.context.drawImage(this.image,currentFrame.x,currentFrame.y,width,height,this.x,this.y,width,height); }
Enfin, il offre également la possibilité de passer à un cadre spécifique et à d'autres méthodes.
Tous les codes sources du module d'animation :
/** *包含多帧图像的大图片 **/ spriteSheet=function(id,src,options){ if(!(this instanceof arguments.callee)){ return new arguments.callee(id,src,options); } this.init(id,src,options); } spriteSheet.prototype={ /** *初始化 **/ init:function(id,src,options){ /** *默认对象 **/ var defaultObj={ x:0, y:0, width:120, height:40, frameSize:[40,40], frameDuration:100, direction:"right", //从左到右 beginX:0, beginY:0, loop:false, bounce:false }; options=options||{}; options=cg.core.extend(defaultObj,options); this.id=id; //spriteSheet的id this.src=src; //图片地址 this.x=options.x; //动画X位置 this.y=options.y; //动画Y位置 this.width=options.width; //图片的宽度 this.height=options.height; //图片的高度 this.image=cg.loader.loadedImgs[this.src]; //图片对象 this.frameSize=options.frameSize; //每帧尺寸 this.frameDuration=options.frameDuration; //每帧持续时间 this.direction=options.direction; //读取帧的方向(从做到右或从上到下) this.currentIndex=0; //目前帧索引 this.beginX=options.beginX; //截取图片的起始位置X this.beginY=options.beginY; //截图图片的起始位置Y this.loop=options.loop; //是否循环播放 this.bounce=options.bounce; //是否往返播放 this.onFinsh=options.onFinsh; //播放完毕后的回调函数 this.frames=caculateFrames(options); //帧信息集合 this.now=new Date().getTime(); //当前时间 this.last=new Date().getTime(); //上一帧开始时间 }, /** *更新帧 **/ update:function(){ this.now=new Date().getTime(); var frames=this.frames; if((this.now-this.last)>this.frameDuration){//如果间隔大于帧间间隔,则update var currentIndex=this.currentIndex; var length=this.frames.length; this.last=this.now; if(currentIndex>=length-1){ if(this.loop){ //循环 return frames[this.currentIndex=0]; } else if(!this.bounce){//没有循环并且没有往返滚动,则停止在最后一帧 this.onFinsh&&this.onFinsh(); this.onFinsh=undefined; return frames[currentIndex]; } } if((this.bounce)&&((currentIndex>=length-1&&path>0)||(currentIndex<=0&&path<0))){ //往返 path*=(-1); } this.currentIndex+=path; } return frames[this.currentIndex]; }, /** *跳到特定帧 **/ index:function(index){ this.currentIndex=index; return this.frames[this.currentIndex]; }, /** *获取现时帧 **/ getCurrentFrame:function(){ return this.frames[this.currentIndex]; }, /** *在特定位置绘制该帧 **/ draw:function(){ var currentFrame=this.getCurrentFrame(); var width=this.frameSize[0]; var height=this.frameSize[1]; cg.context.drawImage(this.image,currentFrame.x,currentFrame.y,width,height,this.x,this.y,width,height); } } this.SpriteSheet=spriteSheet; });
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!