首頁 > web前端 > H5教程 > 主體

Html5斗地主棋牌架設Canvas實現斗地主遊戲程式碼解析

php爱好者
發布: 2017-10-30 16:42:26
原創
4930 人瀏覽過

現在我看了h5.zhengtuwl.comhtml5以及canvas相關知識和斗地主的demo後,自己用demo上的素材試著寫了個斗地主,代碼沒重構好,歡迎賜教。

話不多說,以下就一步一步解釋下吧

只有一個common.js 檔案

1、資源類別

var Resource = Class.create();
$.extend(Resource.prototype, {
   初始化: function () { },
   圖片: [
       { 路徑: 'img/ bg1.png', x: 0, y: 0, w: 800, h: 480, data: null, type: 61,visible: true },
       { path: 'img/BeiMian.jpg', x: 320, y: 5, w: 100, h: 121, 資料: null, 類型: 62, 可見: true },
       { 路徑: 'img/btn.jpg', x: 300, y: 281, wimg/btn.jpg', x: 300, y: 281, w :140,h:50,資料:null,類型:63,可見:true,文字:'開始',textX:366,textY:310},
       { x:0,y:0,類型:66, isText: true, 可見: false },
       { 路徑: 'img/1.jpg', 資料: null, 類型: 16, 可見: false },
       { 路徑: 'img/2.jpg'資料: null, 類型: 17, 可見: false },
       { 路徑: 'img/3.jpg', 資料: null, 類型: 3, 可見: false, se: 1 },
   'img/4.jpg', 資料: null, 類型: 4, 可見: false, se: 1 },
       { 路徑: 'img/5.jpg', 資料: null, 類型: 5, 可見: false , se: 1 },
       { 路徑: 'img/6.jpg', 資料: null, 類型: 6, 可見: false, se: 1 },
      { 路徑: 'img/7.jpg' , 資料: null, 類型: 7, 可見: false, se: 1 },
       { 路徑: 'img/8.jpg', 資料: null, 類型: 8, 可見: false, se: 1 },
       { 路徑:'img/9.jpg',資料:null,類型:9,可見:false,se:1 },
       { 路徑:'img/10.jpg',資料:null,類型: 10, 可見: false, se: 1 },
       { 路徑: 'img/11.jpg', 資料: null, 類型: 11, 可見: false, se: 1 },
 /12.jpg', 資料: null, 類型: 12, 可見: false, se: 1 },
       { 路徑: 'img/13.jpg', 資料: null, 類型: 13, 可見: false, se : 1 },
       { 路徑: 'img/14.jpg', 資料: null, 類型: 14, 可見: false, se: 1 },
       { 路徑: 'img/15 路徑: 'img/15.jpg', : null, 類型: 15, 可見: false, se: 1 },
       { 路徑: 'img/16.jpg', 資料: null, 類型: 3, 可見: false, se: 4 },
{ 路徑: 'img/17.jpg', 資料: null, 類型: 4, 可見: false, se: 4 },
       { 路徑: 'img/18.jpg', 資料: null, 類型: 5,可見: false, se: 4 },
       { 路徑: 'img/19.jpg', 資料: null, 類型: 6, 可見: false, se: 4 },
  類型     { 路徑  .jpg', 資料: null, 類型: 7, 可見: false, se: 4 },
       { 路徑: 'img/21.jpg', 資料: null, 類型: 8, 可見: false, se: 4 },
       { 路徑: 'img/22.jpg', 資料: null, 類型: 9, 可見: false, se: 4 },
       { 路徑: 'img/23.jpg', 資料: { 路徑: 'img/23.jpg', 資料: { null null , 類型: 10, 可見: false, se: 4 },
       { 路徑: 'img/24.jpg', 資料: null, 類型: 11, 可見: false, se: 4 },##   路徑  : 'img/25.jpg', 資料: null, 類型: 12, 可見: false, se: 4 },
       { 路徑: 'img/26.jpg', 資料: null, 類型: 13, 可見: 'img/26.jpg', 資料: null, 類型: 13, 可見: false, se: 4 },
       { 路徑: 'img/27.jpg', 資料: null, 類型: 14, 可見: false, se: 4 },
      { 路徑: 'gimg/28 ', 資料: null, 類型: 15, 可見: false, se: 4 },
       { 路徑: 'img/29.jpg', 資料: null, 類型: 3, 可見: false, se: 3 },
       { 路徑:'img/30.jpg',資料:null,類型:4,可見:false,se:3 },
       { 路徑:'img/31.jpg',資料:null,類型: 5, 可見: false, se: 3 },
       { 路徑: 'img/32.jpg', 資料: null, 類型: 6, 可見: false, se: 3 },
  類型: 6, 可見: false, ' img/33.jpg', 資料: null, 類型: 7, 可見: false, se: 3 },
       { 路徑: 'img/34.jpg', 資料: null, 類型: 8, 可見: false, se: 3 },
       { 路徑: 'img/35.jpg', 資料: null, 型態: 9, 可見: false, se: 3 },
  jp     { 路徑: 'img/36.
  jp     { 路徑: 'img/36.資料:空,類型:10,可見:假,se:3 },
       { 路徑:'img/37.jpg',資料:空,類型:11,可見:假,se:3 },
       { 路徑: 'img/38.jpg', 資料: null, 類型: 12, 可見: false, se: 3 },
       { 路徑: 'img/39.jpg', 資料: null, , 可見: false, se: 3 },
       { 路徑: 'img/40.jpg', 資料: null, 類型: 14, 可見: false, se: 3 },
       { 路徑: 'img/41.jpg', 資料: null, 類型: 15, 可見: false, se: 3 },
       { 路徑: 'img/42.jpg', 資料: null, 類型: 3,可見: false, se: 2 },
       { 路徑: 'img/43.jpg', 資料: null, 類型: 4, 可見: false, se: 2 },
  類型     { 路徑  .jpg', 資料: null, 類型: 5, 可見: false, se: 2 },
       { 路徑: 'img/45.jpg', 資料: null, 類型: 6, 可見: false, se: 2 },
       { 路徑: 'img/46.jpg', 資料: null, 類型: 7, 可見: false, se: 2 },
      : { 路徑: 'img/47.jpg', 資料     : { 路徑: 'img/47.jpg', 資料: { null null , 類型: 8, 可見: false, se: 2 },
       { 路徑: 'img/48.jpg', 資料: null, 類型: 9, 可見: false, se: 2 },## : 'img/49.jpg', 資料: null, 類型: 10, 可見: false, se: 2 },
       { 路徑: 'img/50.jpg', 資料: null, 類型: 11, 路徑: 'img/50.jpg', 資料: null, 類型: 11, 可見: false, se: 2 },
       { 路徑: 'img/51.jpg', 資料: null, 類型: 12, 可見: false, se: 2 },
     可見: false, se: 2 },
      { 路徑: 'gimg/52. ', 資料: null, 類型: 13, 可見: false, se: 2 },
       { 路徑: 'img/53.jpg', 資料: null, 類型: 14, 可見: false, se: 2 },
       { 路徑: 'img/54.jpg', 資料: null, 類型: 15, 可見: false, se: 2 }
   ]
});

資源 }

#」資源]

});


資源.Images是素材整理(幾個按鈕,文本,54張牌,背景圖片等),大家可以下載demo看看
2、Lables類,在Canvas上查看上畫文本的,比如按鈕文字,相關知識請看canvas教學

var Labels = Class.create();
$.extend(Labels.prototype, {
   初始化: function (cxt) {
       this.cxt = cxt;
   },
   setText: 函數(文字、位置){
       this.cxt.font = '粗體20px 襯線';

       .cxt.#00.cxt. #        this. cxt.textAlign = 'center';

       this.cxt.fillText(text, postion.x, postion.y);

   }

});

#});

#這個類別的方法setText主要是根據設定的字體,字體大小,字體顏色,在Canvas上畫文字的,this.cxt這個是canvas上下文(每個教學的叫法不一樣),首先this.cxt.font = 'bold 20px serif';這個是設定字體大小,樣式等,this.cxt.fillStyle = '#000000';這個

###是設定字體顏色,this.cxt.textAlign = 'center';這個是設定字體對齊方式,this.cxt.fillText(text, postion.x, postion.y);這是開始在canvas上畫文字,postion.x, postion.y分別是x座標和y座標。 ##3 、DdZGame遊戲類,主要功能就是初始化斗地主,發牌,搶地主等,出牌未待完續,後續更新###

var DdZGame = Class.create();
DdZGame.Statics = { DealedNums: 0, isLeftFirstDeal: true };
$.extend(DdZGame.prototype, {

       DdZGame.Statics.IsGetLander = false;
       DdZGame.Statics.DealTime = 66;
       .left.DealTime = 66;
       .left.     this.myPokers = [ ];
       this.LastPokers = [];//最後3張牌

       this.leftPlays = [];
      ;

       this.myBtnPostion = { y: 245, x: 162 };

       this.isStart = false;

       this.isStart = false;


#          this.allPokers = new Array();

       this.Lander = 0;//地主,1右邊,2My,3左邊## .GmCanvas = document.getElementById('gmCanvas');


#         this.cxt = this.GmCanvas.getContext('2d');##  ) ;
       this.init();
       this.initEvt();
   },
   initEvt: function () {   },
   initEvt: function () { #procob. ) {
           var box = this.GmCanvas.getBoundingClientRect();

           DdZGame.Statics.Mouse.Postbox - : e.page
           this.onControlClick();
       }, this);
   },
  (var i = 0;我            var c = this.Controls[i];
           var postion = DdZGame.Statics.MousePostion;##        if (position.x >= c.x && postion.x = c.y && postion.y                   c.onClick();##   true;
                 休息;
}
           }
       }
       if (!isClick) {
               var c = this.myPokers[i ];
               var postion = DdZGame.Statics.MousePostion;
              if (c.onClicklick) {# 1  x >= c.x && postion.x = c.y && postion.y                        c.onClick();##                     break;
                   }
       }
   },
   loadImages: 函數(回調){
       var loadNums = 0;
       var totalNums = this.Res.##        var totalNums = this.Res.## .length -this Control. #        $.each(this.Res.Images, $.proxy(function (i, o) {
           if (!o.path 
           o.data = new Image();
           o.data.src = o.path;
           o.data.onload = $.proxy(f. #                   this.allPokers.push(o);
               }
               else
              loadedNums++;
             if (loadedNums >=totalNums ) {
                   callback.call(this);
               }# #    },
   drawImage: function (callback, isUnVisibleLast) { / /isVisibleLast 令是否底牌看不見
       $.each(this.Controls, $.proxy(function (i, o) {
           if (!o.visible))                   if ( o.type == 62) {
               var x = 0;
               for (var i = 0; i                    this.cxt.drawImage(o.data, o.x, o.y, o.w, o.h);##          }
              o.x = x;
           }
else if (!o.isText) {
               this.cxt.drawImage(o.data, o.x, o.y, o.w, o.h); 63) {
               this.Lbl.setText(o.text, { x: o.textX, y: o.textY });



      #  


## onClick = $.proxy(function () {
                       o.onClick = null;
                        this.drawImage();
                    this.De           , this);
           }

            if (o.type == 66) {
     . #            }
       }, this));


#        /*克隆*/
 
       /*克隆*/
 
copyRightPokers = this.rightPokers . slice();
       var copyMyPokers = this.myPokers.slice();
       var copyLastPokers = this.LastPokers.slice();##o.. copyLastPokers = this.LastPokers。 var isDealEndRight = false ;
       var isDealEndMy = false;
       var isDealEndLast = false;

       var beiMain = $.gregre(this.Re.I. type == 62; }, this))[0];
       var DrawPokers = function (arry, 方向, isBeiMian, identiy, axis) {
           if (arry & arryvar.lem >  = arry [ 0];
               var x = 0, y = 0;


              DdZGame.Statics[方向] = this[方向] ;
               }

               if (!o.x) {
                  y = DdZGame.Statics[方向].y ;

                   o.x = 這個[方向].x;
                   o.y = 這個[方向].y;
#                        x = o.x;
                  y = o.y;
      

#                if (!o.visible) {
                             o.w = 18;
               o .h = 129;
               if (arry.length == 1) {
                    ;
               }







               var img = o.data;
               if (isBeiMian) {##o/ I              }
              el se if (direction == 'myPannel') {
o. onClick = $.proxy(function () {
                       if (!this.isStart)
                      if (!o.isPlay) {
                       o.y - = 30;
                       }
                       else {
                         o.isPlay = false;
                          o.y += 30;
                       }

                       DdZGame.Statics.DealTime = 0;
this.drawImage();
                   }, this);
           , y);
               DdZGame.Statics[方向][軸]身分;

               arry.splice(0, 1);
#                if (DdZGame.Statics.DealTime > 0)
                   DdZGame.Statics[direction + 'handle'] = setTimeout($.proxy(function () {#¡ 方向, isBeiMian, identiy, axis);
                  } , this), DdZGame.Statics.DealTime);
               else
                      }
           else if (D dZGame.Statics[方向+ 'handle'] || DdZGame.Statics.DealTime == 0) {
               clearTimeout(DdZGame.Statics[指示  leftPannel ' && copyLeftPokers.length == 0) {
                   isDealEndLeft = true;
   #                if (direction == 'rightPannel' && copyRightPokers.length == 0) {
                   isDealEndRight = true;##       if (direction == 'myPannel' && copyMyPokers.length == 0 ){
                   isDealEndMy = true;
               }
 0) {
                   isDealEndLast = true;
               }## End alEndMy && isDealEndLast) {
                   /*發牌完成者*/
             if (callback)
                       callback ();
         


       DrawPokers.call(this, copyLeftPokers, 'leftPannel', true, 26, 'y');
       DrawPokers.call(, copyrightRights,     , DrawPokers.call(, copyright”Pokers, true' y');
       DrawPokers.call(this, copyMyPokers, 'myPannel', false, 19, 'x');

       DrawPokers.call(this, copy2,300,03,30,00, 'x');
   },
#    init: function () {
       this.loadImages(this.drawImage);
   },
  unction
       this.leftPannel = { x: 5, y: 18 };
       this.rightPannel = { x: 691, y: 18 };
:1 ;
       this.lastPannel = { x: 243, y: 5 };


       if (DdZGame.Statics.DealedNums >= 51) { //發牌完畢




1發牌
#. $.each(this.allPokers, $.proxy(function (i, o) {
               o.visible = true;
          this));


           this.myPokers.sort(function (a, b) {
               if (a.type != b.type)) 勾選.type;
return b.se - a.se;
           });
           $.grep(this.Res.Images, $.proxy(function (o, i) { return o.type == 62; }, this))[0].visible = false;
           this.drawImage($.proxy(function () { this.GetLander(); }, this), true);

 ##        else {
           else {
           else {
           中中之後上 {
           /*1、左上*/
           var index = Math.floor(Math.random()中 *#this.Po kers p var c = this .allPokers.splice(index, 1);
           c[0].visible = true;
           this.leftPokers.push(c[0]);#pics 

           /*2、右*/
         /*2、右*/
           index = Math.floor(Math.random() * (this.allPokers.length - 1) + 0);Math.random() * (this.allPokers.length - 1) + 0);#m./o&o. 1);
           c[0].visible = true;
           this.rightPokers.push(c[0]);#        index = Math.floor (Math.random() * (this.allPokers.length - 1) + 0);
            c = this.allPokers.splice(index, 1);
    #           this.myPokers.push(c[0]);
           DdZGame.Statics.DealedNums++;

           this.

#        etLander: 函數 (firstGet , minScore, curScore) {
       /*隨機出誰先稱呼地主*/

       //if (curScore && !this.isGetLander[1] &this&this  //if (curScore && !this.isGetLander[1] &this ! isGetLander[3]) {
       //    //**遊戲結束!
       //    alert('無人搶地主');
       //    return;
       //}


       var 位置= { 1: { y: 100, x: 640 }, 3: { y: 100, x: 126 }, 2: { x: 216, y: 297 } } }  (!curScore) {
           if (!minScore)
               minScore = 1;
  firstGet = Math.floor(Math.random() * (3 - 1 + 1) + 1);
           if (firstGet == 1 || firstGet == 3) {  //電腦搶地主
           || ||pet . ) {
                   $.each(this.Controls, $.proxy(function (i, o) {
         .                 o.visible = false;
                      }# #   , this));

                   var max = 0;
                 this.isGetLander[2]) {
                       max = this.isGetLander[1];
   .                }
              }
                  else {
       
                       this.Lander = 2;
           與   etLander[3]) {
                       max = this.isGetLander[3];
     ##                    }
                   if (max == 0 ;
                       return;
                 
                   var t = {};
                   var tObj = $.gre .extend(t, tObj);//複製物件
                   if (this.CurScore == 4) {
                 }
                  t.text = txt;
                   t.x = 位置[this.Lander].x;
                 1.y = 位置[this.L   t.visible = true;
                 this.Controls.push(t);



#                   //this.drawImage($.proxy(function () {

                   //    this.FanDiPai(this );##                    this.FanDiPai(this .FanDiPai(this) .lander);
                   return;
                            this.CurScore = Math.floor(Math.random() * ( 4 -最低分數+ 1 ) + minScore);

               this.isGetLander[firstGet] = this.CurScore == 4 ? -1 : this.CurScore;

               var txt = this.CurScore + '分數';
        = $.grep(this.Res.Images, function (o, i) { return o.type == 66; })[0];
               $.extend(t, tObj);//複製物件
 ##                  txt = '不搶';
               }

     t.x = postion[firstGet].x;
              t.y = 位置[firstGet].y;
               t.visible = true;

               this.Controls.push(t);
                    this.Lander = firstGet;
                   //DdZGame.Statics.IsGetLander = true;
                      var dz = {};
                  $.extend(dz, tObj);//複製對象
                   dz.text = '地主';
                 dz.y = t.y;
                  dz.visible = true;

#              
##        Controls.push(dz);

                   //this.drawImage($.proxy(function () { this.Play(this.Lander, '電腦地主'); }, this));//電腦搶到地主優先出牌
                   this.FanDiPai(this.Lander);
       }
               else {
                  if (this.CurScore = = 4) {
                       var test = 'abcdefg';
#           nextGet = firstGet == 1 ? 2 : 1;
                   minScore = this.CurScore == 4 ? minScore : this.CurScore + 1;
                   this.CurScore = this.CurScore == 4 ? 0 : this.CurScore;


#                    DdZGame.Statics.DealTime = 0;
   this.m GetLander(nextGet, minScore); }, this ), true);//電腦搶到地主優先出牌
                   return;
#            1# )
#                 if (curScore) {
           /*碼寫的很垃圾,外表沒用物件*/
/*My已經叫過地主,按鈕需要隱藏*/
           $.each(this.Controls, $.proxy(function (i, o) {
             o. visible = false;
               }
           }, this));

  txt = this.CurScore + '分';
           var t = { };
           var tObj = $.grep(this.Res.Images, function (o, i) { return o.type == 66; })[0];
  1    ;//複製物件
           if (this.CurScore == 4) {
               ;
           t.x = postion[2] .x;
           t.y = postion[2].y;
           t.visible = true;
   # Control this.isGetLander[2] = curScore == 4 ? -1 : curScore;

           if (this.CurScore == 3 || (this.isGetLander[1] && this.isGetLander[3] && this.CurScore!= 4)& this.isGetLander[3] && this.CurScore #= 4)) {
               this.Lander = 2;
               //DdZGame.Statics.IsGetLander = true     /” 0;

               var dz = {};
               $ .extend(dz, tObj);//複製物件
               dz.text = '地主';
          z.y = t.y;
               dz.visible = true;

               this.Controls.push(dz);

               //this.drawImage($.proxyImage($.proxy  ); }, this), false);//電腦搶到地主優先出牌
               this.FanDiPai(this.Lander);
     c 1 c 1          else {
               minScore = this.CurScore == 4 ? minScore : this.CurScore + 1;
               this.CurScore = this.CurScore == ander[3]) {
                   DdZGame.Statics.DealTime = 0;
                   );
                   return;
               }
               else {  //已經轉了一圈,則比較搶地主的分數大小
               this.isGetLander[1] > this.isGetLander[2]) {
                       max = this.isGetLander[1];
                 }
                   else {
                         this.Lander = 2;
                   }
                   if (max <  max = this.isGetLander[3];
                       this.Lander = 3;
                   }
                   alert('遊戲結束!');
                      return;
           txt = '地主';
                   var t = {};
                   var tObj = $.grep(this.Res.Images, function (o, i) { return o.type == 66; })[0] ;
                   $.extend(t, tObj);//複製物件                
                  t.x = postion[this.Lander] .x;
                  t.y = 位置[this.Lander ].y;
                   if (this.Lander != 2) {
                       }
                   else {
                 }
                   t .visible = true;
                   this.Controls.push(t);


#                        //this.drawImage($.proxy( function) () { this.Play(this.Lander, '搶地主啊'); }, this), false);
                   this.FanDiPai(this.Lander);
       ##            }
       }
     否則 if (this.isGetLander[2] = = -1 || this.isGetLander[2]) {
           $.each(this.Controls, $.proxy(function (i, o) {
       1      o.可見= false;
               }
#            }, this));

  Lander[1] > this.isGetLander[2]) {
               max = this.isGetLander[1];
               this.Lander) ##                max = this.isGetLander[2];
              this.Lander = 2 ;
          }
           if (max          this.Lander = 3;
           }
        如果 ( max == 0) {
               alert('遊戲結束!');
               return;
 txt = max + '分';
           var t = {} ;
           var tObj = $.grep(this.Res.Images, function (o, i) { return o.type == 66; })[0];
           $.extend(t, tObj);//複製物件
           if (this.CurS       }
           t.text = txt;
           t.x = 位置[this.Lander].x;
           t.y = 位置[   this.Controls. Push(t);


           //DdZGame.Statics.DealTime = 0;
           //地主ander) {
       //    return;
       //}
       //DdZGame.Statics.IsGetLander = true;///是否在搶地主##     var btnObj = $.grep(this.Res.Images, $.proxy(function (o, i) {
           return o.type == 63;
      }, this))[0];
      !this.CurScore) {
           this.CurScore = 0;
       }
       var.       if ( i > this.CurScore) {
               var btn = {};
               $ ';
               btn.x = this. myBtnPostion.x;
               btn.y = this.myBtnPostion.y;
           63;
               btn. textX = this.myBtnPostion.x + 30;
             btn.textY = 286;
               btn.h = 50;##        btn.Lander = true;
            btn.onClick = (函數(i, obj) { return function () { obj.GetLander(3, i + 1, i); }; })(i, this)
               DdZGame.Statics.DealTime = 0;
              this.Controls.push(btnmy)  .x += btn.w + 10;
          }
       }
       if (DdZGame.Statics.DealTime == 0) {
           var          btn.text = '不搶';
           btn.x = this.myBtnPostion.x;
           btn.y = this.myB    btn.type = 63;
         按鈕.textX = this.myBtnPostion.x + 30;
           btn.textY = 286;
           btn。       btn.Lander = true;
btn.onClick = $.proxy(function () { this.GetLander(3, minScore, 4); }, this);
           this.Controls.push(btn );
       }
   },
#    粉絲底牌: 函數(登陸器){//翻底牌
       DdZGame.Statics.DealTime = 0;#  #        if ( lander == 1) {
           p = 'rightPokers';
       }
 kers';
       }


## else if (登陸器== 3) {
           p = 'leftPokers';
       }
       /*誰搶地主,底牌誰*/
         $.each(this.LastPokers, $.proxy(function (i, o) {
          var c = {};## .    o);
           c.x = null;
           c.y = null;
         =       }, this));
if(lander == 2){
this.mypokers.sort(function(a,b){
a.x = null;
a.y = a.y = null;
b.x = null;
               b.y = null;
               if (a.type != b.type)#            return b.se - a.se;
          });
           this.myPannel = { x: 198, y: 330 };
           DdZGame.Statics['myPanage'] = null;#thisfm. .proxy(function () { this .isStart = true; this.Play(lander, '是地主啊'); //出牌
//alert('');
   }
});





#看程式碼

initialize:這個函數被建構函數,初始化一些起始變數。不像svg那樣,因為canvas是一幀一幀畫上去的,html dom裡是看不到裡面的每個元素,javascript自然也無法取得到canvas裡的某些元素,那canvas元素點擊事件是怎麼處理的了?座標判斷這個座標是否在某個元素內。 :這裡不是真正的元素事件,只是物件的一個函數屬性),然後呼叫onclick函數,執行對應的程式碼。 canvas上畫初始的元素。是發牌,每方的牌都是隨機的,if(DdZGame.Statics.DealedNums >= 51)發了51張牌之後,就剩下3張底牌,然後再把這51張牌和3張底牌畫在畫布上

GetLander :這個是搶地主,誰先搶地主是隨機的,如果是先隨機的到電腦搶地主,那搶地主的分數也是隨機的。



#

以上是Html5斗地主棋牌架設Canvas實現斗地主遊戲程式碼解析的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!