Heim > Artikel > Web-Frontend > Das HTML5-Spielframework cnGameJS entwickelt rekordverdächtige Animationsprinzipien
Im Spiel ist der Animationseffekt der Spielfigur ein wesentlicher Bestandteil des Spiels. In diesem Abschnitt nehmen wir die Konstruktion von Super Mario-Charakteren als Beispiel, um die Implementierung von Animationen in cnGameJS zu erläutern.
1. Prinzip:
Wenn eine Animation eine Reihe von Aktionen implementieren möchte, können wir von jeder Aktion einen Schnappschuss machen und ihn in einer großen Datei zusammenfassen Bild oben: Jedes Mal, wenn der Frame aktualisiert wird, werden die Schnappschüsse jeder Aktion zyklisch angezeigt, und schließlich wird eine Animation erhalten. Daher müssen wir zunächst ein Bild wie das folgende vorbereiten:
Siehst du es? Platzieren Sie jede Aktion an einer anderen Position im Bild. Anschließend können Sie durch Ändern der Anzeigeposition Animationseffekte erzielen.
Wenn cnGameJS die Startmethode aufruft, um das Spiel zu starten, ruft es die Initialisierungsmethode des eingehenden gameObj zur Initialisierung auf und generiert jedes Mal in der Schleife das UpDatum und Zeichenmethode. Daher können wir die Initialisierung der Animation in die Initialisierung von gameObj einfügen und die Aktualisierung und den Draw in die Aktualisierung und den Draw von gameObj einfügen, um die Animationswiedergabe zu realisieren.
Wirkung:
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 .Implementieren
Wie oben gezeigt, müssen wir nur eine kleine Menge Code verwenden, um die Wiedergabe einer Frame-Animation zu realisieren. Als nächstes stellen wir vor, wie die Frame-Animation in cnGameJS gekapselt wird.
Sie können leicht feststellen, dass cnGameJS einem bestimmten Muster folgt, das die Objektphasen in drei Phasen unterteilt: Initialisieren (Initialisierung), Aktualisieren (Frame-Update) und Zeichnen (Zeichnen) . Auf diese Weise können wir in entsprechenden Phasen problemlos Codes für verschiedene Funktionen schreiben. Die SpriteSheet-Frame-Animation ist keine Ausnahme und wird ebenfalls nach diesem Muster geschrieben.
Initialisierung: Der Benutzer legt einige notwendige Informationen fest.
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(); //上一帧开始时间 },
Oben gibt es viele Parameter, die alle Voreinstellungen für Frame-Animationsattribute sind. Es ist zu beachten, dass wir die private Methode caculateFrames aufgerufen haben, um die Informationen jedes Frames zu berechnen und sie in Frames zu speichern, um das Zeichnen des Frames vorzubereiten.
Frame-Update:
Während des Aktualisierungsprozesses jedes Frames ermitteln wir zunächst die aktuelle Zeit als Startzeit des Frames und vergleichen sie mit der Startzeit des vorherigen Frames Subtrahieren Sie, um die für den letzten Frame benötigte Zeit zu erhalten. Wenn die benötigte Zeit die zuvor eingestellte Zeit pro Frame überschreitet, kann ein Frame-Update durchgeführt werden. Bestimmen Sie dann, ob die Animation in einer Schleife oder vor und zurück abgespielt werden soll, und aktualisieren Sie den entsprechenden Frame-Index entsprechend. Nachdem der Frame-Index endgültig bestimmt wurde, können die Frame-Informationen aus dem Frame-Array abgerufen und zurückgegeben werden.
/** *更新帧 **/ 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]; },
Rahmenzeichnung:
Nachdem der Rahmen aktualisiert wurde, wurde der Index des aktuellen Rahmens abgerufen, sodass die Zeichenmethode ihn aus den Rahmen abrufen kann Dadurch werden alle Bildinformationen in den Informationen des aktuellen Bildes gespeichert (einschließlich der Startposition des Bildabfangs usw.), wodurch ein großes Bild an der angegebenen Position abgefangen und das Bild des Bildbereichs gezeichnet wird:
/** *在特定位置绘制该帧 **/ 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); }
Schließlich bietet es auch die Möglichkeit, zu einem bestimmten Frame zu springen und andere Methoden anzuwenden.
Alle Quellcodes des Animationsmoduls:
/** *包含多帧图像的大图片 **/ 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; });
Das obige ist der detaillierte Inhalt vonDas HTML5-Spielframework cnGameJS entwickelt rekordverdächtige Animationsprinzipien. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!