<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      【CSON原創】HTML5游戲框架cnGameJS開發實錄(精靈對象篇)

      返回目錄

      1.什么是精靈對象(sprite)?

        所謂的精靈對象,就是游戲中的一個具有行為的元素,以超級瑪麗為例,瑪麗,敵人都算是一個精靈對象。在cnGameJS框架中,精靈對象如下幾個特點:

        1.添加動畫:在之前的動畫篇中,我們介紹過cnGameJS如何實現幀動畫。而作為精靈對象,就是動畫的使用者。例如我們控制瑪麗向不同方向的行走,瑪麗會產生行走的動畫。

        2.包含圖像:對于另外一些精靈對象,它可能不需要運動動畫,這時我們就可以只讓它使用圖像。

        3.能進行不同類型的運動:可以讓精靈對象向不同方向,以不同加速度進行移動。

      2.demo展現

        這里以一個簡單的demo進行展現,我們通過鼠標控制瑪麗的行動(勻加速運動),當瑪麗停止時,使用圖片。當瑪麗移動時,使用動畫,鍵盤左右方向鍵控制瑪麗的移動

        效果:

       

        代碼:

      <body>
      <div><canvas id="gameCanvas">請使用支持canvas的瀏覽器查看</canvas></div>
      </body>
      <script src="https://files.cnblogs.com/Cson/cnGame_v1.0.js"></script>
      <script>
      var Src="http://images.cnblogs.com/cnblogs_com/Cson/290336/o_player.png";

      /* 初始化 */
      cnGame.init(
      'gameCanvas',{width:300,height:150});
      var floorY=cnGame.height-40;
      var gameObj=(function(){
      /* 玩家對象 */
      var player=function(options){
      this.init(options);
      this.speedX=0;
      this.moveDir;
      this.isJump=false;
      }
      cnGame.core.inherit(player,cnGame.Sprite);
      player.prototype.initialize
      =function(){
      this.addAnimation(new cnGame.SpriteSheet("playerRight",Src,{frameSize:[50,60],loop:true,width:150,height:60}));
      this.addAnimation(new cnGame.SpriteSheet("playerLeft",Src,{frameSize:[50,60],loop:true,width:150,height:120,beginY:60}));
      }
      player.prototype.moveRight
      =function(){
      if(cnGame.core.isUndefined(this.moveDir)||this.moveDir!="right"){
      this.moveDir="right";
      this.speedX<0&&(this.speedX=0);
      this.setMovement({aX:10,maxSpeedX:15});
      this.setCurrentAnimation("playerRight");
      }
      }
      player.prototype.moveLeft
      =function(){
      if(cnGame.core.isUndefined(this.moveDir)||this.moveDir!="left"){
      this.moveDir="left";
      this.speedX>0&&(this.speedX=0);
      this.setMovement({aX:-10,maxSpeedX:15});
      this.setCurrentAnimation("playerLeft");
      }
      }
      player.prototype.stopMove
      =function(){

      if(this.speedX<0){
      this.setCurrentImage(Src,0,60);
      }
      else if(this.speedX>0){
      this.setCurrentImage(Src);
      }
      this.moveDir=undefined;
      this.resetMovement();

      }
      player.prototype.update
      =function(){
      player.prototype.parent.prototype.update.call(
      this);//調用父類update
      if(cnGame.input.isPressed("right")){
      this.moveRight();
      }
      else if(cnGame.input.isPressed("left")){
      this.moveLeft();
      }
      else{
      this.stopMove();
      }


      }

      return {
      initialize:
      function(){
      cnGame.input.preventDefault([
      "left","right","up","down"]);
      this.player=new player({src:Src,width:50,height:60,x:0,y:floorY-60});
      this.player.initialize();
      },
      update:
      function(){
      this.player.update();
      },
      draw:
      function(){
      this.player.draw();
      }

      };
      })();
      cnGame.loader.start([Src],gameObj);
      </script>


      3.實現

        和動畫篇spriteSheet對象一樣,sprite對象同樣劃分三個階段:初始化,更新,繪制

        首先看sprite的初始化函數:

              /**
      *初始化
      *
      */
      init:function(options){

      /**
      *默認對象
      *
      */
      var defaultObj={
      x:0,
      y:0,
      imgX:0,
      imgY:0,
      width:32,
      height:32,
      angle:0,
      speedX:0,
      speedY:0,
      aX:0,
      aY:0,
      maxSpeedX:postive_infinity,
      maxSpeedY:postive_infinity,
      maxX:postive_infinity,
      maxY:postive_infinity,
      minX:-postive_infinity,
      minY:-postive_infinity
      };
      options=options||{};
      options=cg.core.extend(defaultObj,options);
      this.x=options.x;
      this.y=options.y;
      this.angle=options.angle;
      this.width=options.width;
      this.height=options.height;
      this.angle=options.angle;
      this.speedX=options.speedX;
      this.speedY=options.speedY;
      this.aX=options.aX;
      this.aY=options.aY;
      this.maxSpeedX=options.maxSpeedX;
      this.maxSpeedY=options.maxSpeedY;
      this.maxX=options.maxX;
      this.maxY=options.maxY;
      this.minX=options.minX;
      this.minY=options.minY;


      this.spriteSheetList={};
      if(options.src){ //傳入圖片路徑
      this.setCurrentImage(options.src,options.imgX,options.imgY);
      }
      else if(options.spriteSheet){//傳入spriteSheet對象
      this.addAnimation(options.spriteSheet);
      setCurrentAnimation(options.spriteSheet);
      }

      }

        參數很多,主要包括:對象位置,旋轉角度,尺寸,xy方向的速度,xy方向的加速度,xy方向的最大速度。另外如果用戶傳入圖片地址,則設置當前sprite對象使用圖片,否則使用spriteSheet動畫。

        先看看sprite對象如何使用圖像:

              /**
      *設置當前顯示圖像
      *
      */
      setCurrentImage:function(src,imgX,imgY){
      if(!this.isCurrentImage(src,imgX,imgY)){
      imgX=imgX||0;
      imgY=imgY||0;
      this.image=cg.loader.loadedImgs[src];
      this.imgX=imgX;
      this.imgY=imgY;
      this.spriteSheet=undefined;
      }
      },

        首先檢測現在是否正在使用該圖像,如果不是,則從loader里獲取下載好的image對象(所有圖像資源在游戲開始時已下載好,詳情請看:HTML5游戲框架cnGameJS開發實錄(資源加載模塊篇)),并且設置spriteSheet為undefined(表示不使用spriteSheet動畫),這樣sprite對象就可以使用圖像了。

        再看看如何使用動畫:

              /**
      *設置當前顯示動畫
      *
      */
      setCurrentAnimation:function(id){//可傳入id或spriteSheet
      if(!this.isCurrentAnimation(id)){
      if(cg.core.isString(id)){
      this.spriteSheet=this.spriteSheetList[id];
      this.image=this.imgX=this.imgY=undefined;
      }
      else if(cg.core.isObject(id)){
      this.spriteSheet=id;
      this.addAnimation(id);
      this.image=this.imgX=this.imgY=undefined;
      }
      }

      },

        首先根據傳入的spriteSheet或spriteSheet的id判斷是否正在使用該動畫,如果不是,則設置sprite使用spriteSheet動畫。

        設置好sprite對象使用動畫后,核心函數update就負責調用spriteSheet的update,更新sprite使用的動畫,需要注意的是使spriteSheet的xy為sprite的xy:

                  
      if(this.spriteSheet){//更新spriteSheet動畫
      this.spriteSheet.x=this.x
      this.spriteSheet.y=this.y;
      this.spriteSheet.update();
      }

        這樣就完成的sprite對象動畫的展示。

        最后看看如何實現最后一個特點:使sprite能進行變速的運動。

        要進行變速運動,我們需要確立如下幾個變量:初始速度,經過的時間,以及加速度。現在看cnGameJS負責變速運動的部分:

              /**
      *設置移動參數
      *
      */
      setMovement:function(options){
      isUndefined=cg.core.isUndefined;
      isUndefined(options.speedX)?this.speedX=this.speedX:this.speedX=options.speedX;
      isUndefined(options.speedY)?this.speedY=this.speedY:this.speedY=options.speedY;

      isUndefined(options.aX)?this.aX=this.aX:this.aX=options.aX;
      isUndefined(options.aY)?this.aY=this.aY:this.aY=options.aY;
      isUndefined(options.maxX)?this.maxX=this.maxX:this.maxX=options.maxX;
      isUndefined(options.maxY)?this.maxY=this.maxY:this.maxY=options.maxY;
      isUndefined(options.minX)?this.minX=this.minX:this.minX=options.minX;
      isUndefined(options.minY)?this.minY=this.minY:this.minY=options.minY;


      if(this.aX!=0){
      this.startTimeX=new Date().getTime();
      this.oriSpeedX=this.speedX;
      isUndefined(options.maxSpeedX)?this.maxSpeedX=this.maxSpeedX:this.maxSpeedX=options.maxSpeedX;
      }
      if(this.aY!=0){
      this.startTimeY=new Date().getTime();
      this.oriSpeedY=this.speedY;
      isUndefined(options.maxSpeedY)?this.maxSpeedY=this.maxSpeedY:this.maxSpeedY=options.maxSpeedY;
      }

      }

        每次用戶調用setMovement,就保留sprite的初速度,和運動開始的時間。這樣在每次update的時候,就可以根據前面兩個變量,獲取到sprite現時的速度,并計算現時的XY方向上的位移:

       

                  if(this.aX!=0){
      var now=new Date().getTime();
      var durationX=now-this.startTimeX;
      var speedX=this.oriSpeedX+this.aX*durationX/1000;
      if(this.maxSpeedX<0){
      this.maxSpeedX*=-1;
      }
      if(speedX<0){
      this.speedX=Math.max(speedX,this.maxSpeedX*-1) ;
      }
      else{
      this.speedX=Math.min(speedX,this.maxSpeedX);
      }
      }
      if(this.aY!=0){
      var now=new Date().getTime();
      var durationY=now-this.startTimeY;
      this.speedY=this.oriSpeedY+this.aY*durationY/1000;
      }
      this.move(this.speedX,this.speedY);

        當update更新了sprite的位移,就可以通過第三個階段draw方法,把sprite繪制出來。

              /**
      *繪制出sprite
      *
      */
      draw:function(){
      var context=cg.context;
      if(this.spriteSheet){
      this.spriteSheet.x=this.x
      this.spriteSheet.y=this.y;
      this.spriteSheet.draw();
      }
      else if(this.image){
      context.save()
      context.translate(this.x, this.y);
      context.rotate(this.angle * Math.PI / 180);
      context.drawImage(this.image,this.imgX,this.imgY,this.width,this.height,0,0,this.width,this.height);
      context.restore();
      }

      },

        注意sprite在使用spriteSheet動畫或在使用圖像,draw方法執行都不相同。當使用sprieSheet動畫時,draw方法實質上是調用了spriteSheet的draw方法繪制幀圖像,而當sprite使用圖像,我們還可以讓圖像旋轉之后再繪制。

        sprite對象還提供一個getRect方法,返回包含該sprite對象的矩形。該方法為檢測sprite對象和其他對象的碰撞帶來方便。有關碰撞檢測請看:HTML5游戲框架cnGameJS開發實錄(碰撞檢測篇)

        另外sprite對象同樣具有move,moveTo,resize,resizeTo等功能,方便對該對象的位置和尺寸進行操控。

       

        sprite對象所有源碼:

      /**
      *
      *sprite對象
      *
      *
      */
      cnGame.register("cnGame",function(cg){

      var postive_infinity=Number.POSITIVE_INFINITY;

      var sprite=function(id,options){
      if(!(this instanceof arguments.callee)){
      return new arguments.callee(id,options);
      }
      this.init(id,options);
      }
      sprite.prototype={
      /**
      *初始化
      *
      */
      init:function(options){

      /**
      *默認對象
      *
      */
      var defaultObj={
      x:0,
      y:0,
      imgX:0,
      imgY:0,
      width:32,
      height:32,
      angle:0,
      speedX:0,
      speedY:0,
      aX:0,
      aY:0,
      maxSpeedX:postive_infinity,
      maxSpeedY:postive_infinity,
      maxX:postive_infinity,
      maxY:postive_infinity,
      minX:-postive_infinity,
      minY:-postive_infinity
      };
      options=options||{};
      options=cg.core.extend(defaultObj,options);
      this.x=options.x;
      this.y=options.y;
      this.angle=options.angle;
      this.width=options.width;
      this.height=options.height;
      this.angle=options.angle;
      this.speedX=options.speedX;
      this.speedY=options.speedY;
      this.aX=options.aX;
      this.aY=options.aY;
      this.maxSpeedX=options.maxSpeedX;
      this.maxSpeedY=options.maxSpeedY;
      this.maxX=options.maxX;
      this.maxY=options.maxY;
      this.minX=options.minX;
      this.minY=options.minY;

      this.spriteSheetList={};
      if(options.src){ //傳入圖片路徑
      this.setCurrentImage(options.src,options.imgX,options.imgY);
      }
      else if(options.spriteSheet){//傳入spriteSheet對象
      this.addAnimation(options.spriteSheet);
      setCurrentAnimation(options.spriteSheet);
      }

      },
      /**
      *返回包含該sprite的矩形對象
      *
      */
      getRect:function(){
      return new cg.shape.Rect({x:this.x,y:this.y,width:this.width,height:this.height});

      },
      /**
      *添加動畫
      *
      */
      addAnimation:function(spriteSheet){
      this.spriteSheetList[spriteSheet.id]=spriteSheet;
      },
      /**
      *設置當前顯示動畫
      *
      */
      setCurrentAnimation:function(id){//可傳入id或spriteSheet
      if(!this.isCurrentAnimation(id)){
      if(cg.core.isString(id)){
      this.spriteSheet=this.spriteSheetList[id];
      this.image=this.imgX=this.imgY=undefined;
      }
      else if(cg.core.isObject(id)){
      this.spriteSheet=id;
      this.addAnimation(id);
      this.image=this.imgX=this.imgY=undefined;
      }
      }

      },
      /**
      *判斷當前動畫是否為該id的動畫
      *
      */
      isCurrentAnimation:function(id){
      if(cg.core.isString(id)){
      return (this.spriteSheet&&this.spriteSheet.id===id);
      }
      else if(cg.core.isObject(id)){
      return this.spriteSheet===id;
      }
      },
      /**
      *設置當前顯示圖像
      *
      */
      setCurrentImage:function(src,imgX,imgY){
      if(!this.isCurrentImage(src,imgX,imgY)){
      imgX=imgX||0;
      imgY=imgY||0;
      this.image=cg.loader.loadedImgs[src];
      this.imgX=imgX;
      this.imgY=imgY;
      this.spriteSheet=undefined;
      }
      },
      /**
      *判斷當前圖像是否為該src的圖像
      *
      */
      isCurrentImage:function(src,imgX,imgY){
      imgX=imgX||0;
      imgY=imgY||0;
      var image=this.image;
      if(cg.core.isString(src)){
      return (image&&image.srcPath===src&&this.imgX===imgX&&this.imgY===imgY);
      }
      },
      /**
      *設置移動參數
      *
      */
      setMovement:function(options){
      isUndefined=cg.core.isUndefined;
      isUndefined(options.speedX)?this.speedX=this.speedX:this.speedX=options.speedX;
      isUndefined(options.speedY)?this.speedY=this.speedY:this.speedY=options.speedY;

      isUndefined(options.aX)?this.aX=this.aX:this.aX=options.aX;
      isUndefined(options.aY)?this.aY=this.aY:this.aY=options.aY;
      isUndefined(options.maxX)?this.maxX=this.maxX:this.maxX=options.maxX;
      isUndefined(options.maxY)?this.maxY=this.maxY:this.maxY=options.maxY;
      isUndefined(options.minX)?this.minX=this.minX:this.minX=options.minX;
      isUndefined(options.minY)?this.minY=this.minY:this.minY=options.minY;


      if(this.aX!=0){
      this.startTimeX=new Date().getTime();
      this.oriSpeedX=this.speedX;
      isUndefined(options.maxSpeedX)?this.maxSpeedX=this.maxSpeedX:this.maxSpeedX=options.maxSpeedX;
      }
      if(this.aY!=0){
      this.startTimeY=new Date().getTime();
      this.oriSpeedY=this.speedY;
      isUndefined(options.maxSpeedY)?this.maxSpeedY=this.maxSpeedY:this.maxSpeedY=options.maxSpeedY;
      }

      },
      /**
      *重置移動參數回到初始值
      *
      */
      resetMovement:function(){
      this.speedX=0;
      this.speedY=0;
      this.aX=0;
      this.aY=0;
      this.maxSpeedX=postive_infinity;
      this.maxSpeedY=postive_infinity;
      this.maxX=postive_infinity;
      this.minX=-postive_infinity;
      this.maxY=postive_infinity;
      this.minY=-postive_infinity;
      },
      /**
      *更新位置和幀動畫
      *
      */
      update:function(){
      if(this.aX!=0){
      var now=new Date().getTime();
      var durationX=now-this.startTimeX;
      var speedX=this.oriSpeedX+this.aX*durationX/1000;
      if(this.maxSpeedX<0){
      this.maxSpeedX*=-1;
      }
      if(speedX<0){
      this.speedX=Math.max(speedX,this.maxSpeedX*-1) ;
      }
      else{
      this.speedX=Math.min(speedX,this.maxSpeedX);
      }
      }
      if(this.aY!=0){
      var now=new Date().getTime();
      var durationY=now-this.startTimeY;
      this.speedY=this.oriSpeedY+this.aY*durationY/1000;
      }
      this.move(this.speedX,this.speedY);


      if(this.spriteSheet){//更新spriteSheet動畫
      this.spriteSheet.x=this.x
      this.spriteSheet.y=this.y;
      this.spriteSheet.update();
      }
      },
      /**
      *繪制出sprite
      *
      */
      draw:function(){
      var context=cg.context;
      if(this.spriteSheet){
      this.spriteSheet.x=this.x
      this.spriteSheet.y=this.y;
      this.spriteSheet.draw();
      }
      else if(this.image){
      context.save()
      context.translate(this.x, this.y);
      context.rotate(this.angle * Math.PI / 180);
      context.drawImage(this.image,this.imgX,this.imgY,this.width,this.height,0,0,this.width,this.height);
      context.restore();
      }

      },
      /**
      *移動一定距離
      *
      */
      move:function(dx,dy){
      dx=dx||0;
      dy=dy||0;
      var x=this.x+dx;
      var y=this.y+dy;
      this.x=Math.min(Math.max(this.minX,x),this.maxX);
      this.y=Math.min(Math.max(this.minY,y),this.maxY);
      return this;

      },
      /**
      *移動到某處
      *
      */
      moveTo:function(x,y){
      this.x=Math.min(Math.max(this.minX,x),this.maxX);
      this.y=Math.min(Math.max(this.minY,y),this.maxY);
      return this;
      },
      /**
      *旋轉一定角度
      *
      */
      rotate:function(da){
      this.angle+=da;
      return this;
      },
      /**
      *旋轉到一定角度
      *
      */
      rotateTo:function(){
      this.angle=da;
      return this;

      },
      /**
      *改變一定尺寸
      *
      */
      resize:function(dw,dh){
      this.width+=dw;
      this.height+=dh;
      return this;
      },
      /**
      *改變到一定尺寸
      *
      */
      resizeTo:function(width,height){
      this.width=width;
      this.height=height;
      return this;
      }

      }
      this.Sprite=sprite;

      });
      posted @ 2012-02-14 12:43  Cson  閱讀(2165)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 熟妇人妻不卡中文字幕| 无码人妻丰满熟妇啪啪| 亚洲男人天堂2018| 国产精品白嫩极品在线看| 中国CHINA体内裑精亚洲日本| 视频一区视频二区亚洲视频| 边添小泬边狠狠躁视频| 2020国产成人精品视频| 国产成人免费高清激情视频| 人妻丝袜无码专区视频网站| 亚洲色av天天天天天天| 少妇办公室好紧好爽再浪一点| 长治市| 成人久久精品国产亚洲av| 男人扒女人添高潮视频| 亚洲 欧美 清纯 校园 另类| 人妻中文字幕av资源站| 亚洲欧美日韩综合久久久| 祥云县| 欧美z0zo人禽交另类视频| 国偷自产一区二区三区在线视频| 免费看的日韩精品黄色片| 亚洲AV高清一区二区三区尤物| 动漫精品中文无码卡通动漫| 国产国拍亚洲精品永久软件| 欧美高清一区三区在线专区| 久天啪天天久久99久孕妇| 亚洲熟妇精品一区二区| 日韩一区二区三区精品区| 国产午夜福利短视频| 久久久无码精品亚洲日韩蜜桃| 亚洲AV成人无码精品电影在线| 老师扒下内裤让我爽了一夜| 我要看亚洲黄色太黄一级黄| 自拍偷自拍亚洲一区二区| 成人资源网亚洲精品在线| 国产视频最新| 亚洲av综合久久成人网| 制服丝袜美腿一区二区| 日本高清中文字幕免费一区二区| 五月国产综合视频在线观看|