Maison  >  Article  >  interface Web  >  Utiliser JavaScript pour réaliser la version Web Idées de conception Pongo et compétences en partage de code source_javascript

Utiliser JavaScript pour réaliser la version Web Idées de conception Pongo et compétences en partage de code source_javascript

WBOY
WBOYoriginal
2016-05-16 16:44:221256parcourir

1. Introduction au contexte du jeu (non-sens écrit devant) :

Un jour début mai, j'ai vu un site Web recommandant ce jeu, Pongo. Il avait l'air plutôt bien, alors je l'ai téléchargé et essayé sur mon iPad. Après avoir joué à deux jeux, j'ai trouvé que c'était plutôt agréable parce que c'était. Tout le monde connaît les jeux portables.

Mais au bout d'un moment, j'ai découvert que le jeu semblait avoir des bugs sur l'iPad. Après avoir joué pendant un moment, il restait bloqué et je devais forcer à quitter. C'était vraiment inquiétant, et le disque attendait toujours. être brisé.

Que faire ? La pensée perverse selon laquelle jouer à des jeux n'est pas aussi bon que jouer à ses propres jeux est revenue, puis j'ai jeté le pad à mon ami. J'ai eu le cœur brisé, je suis retourné silencieusement à l'ordinateur et j'ai commencé à écrire mon propre jeu qui ne se figerait pas. .

Il m'a fallu environ deux heures pour écrire le framework de base, puis je l'ai essayé dans l'application Sina et l'effet était pratiquement jouable, puis je me suis endormi.

Au réveil le lendemain, j'ai passé du temps à concevoir l'interface car je n'avais rien à faire le week-end. Malheureusement, j'ai détecté de sérieux bugs, et j'ai finalement passé du temps à les corriger.

Au final, le jeu s'est nommé "Pongo" (cliquez sur votre téléphone portable pour jouer). La version ordinateur n'est pas supportée pour le moment, j'ai donc téléchargé le code source sur Github et supprimé le module de soumission de score.

2. Site d'essai du jeu :

Pongo (version mobile uniquement) : http://mypongo.sinaapp.com/

Github open source (bienvenue sur fork pour améliorer le jeu) : https://github.com/ChenReason/pongo/blob/gh-pages/index.html

3. Règles du jeu et gameplay :

Cliquer sur l'écran changera la direction du mouvement de la lunette. Cliquer une fois changera la direction de la lunette. Le but est simplement de bloquer la bille qui roule et de l'empêcher de sortir du grand cercle. Plus c'est long, mieux c'est ! Enfin, vous pouvez soumettre vos propres résultats pour le classement !

4. Technologie utilisée dans le jeu :

HTML, CSS, JavaScript, Canvas, PHP

5. Idées de conception de jeux :

a) Utilisez Canvas pour dessiner l'interface principale du jeu. Le bas est un rectangle monochrome avec un grand cercle le recouvrant. Un petit cercle et un déflecteur sont dessinés sur le grand cercle. cercle d'une taille de 1px au milieu du déflecteur (Pour implémenter la détection de collision).

b) Il existe 8 directions de déplacement du petit cercle, à savoir haut, bas, gauche, droite, haut gauche, bas gauche, haut droit et bas droit.

c) Il n'y a que deux sens de déplacement du déflecteur, dans le sens horaire et antihoraire.

d) La détection de collision n'implique pas l'utilisation du moteur, mais détermine la distance entre le petit cercle et le super petit cercle au milieu du déflecteur, réalisant ainsi une détection de collision simple.

e) Déterminez la direction du rebond de la balle après une collision. Faites preuve de bon sens pour énumérer 8 situations au total.

6. Difficultés de mise en œuvre du jeu :

a) Détection de collision.

b) Le moment de l'effacement du timer setInterval et s'il est clair et complet.

c) La relation entre la durée de la période de minuterie et l'expérience de jeu.

d) Problèmes de fluidité du jeu causés par des performances différentes entre les appareils Android et IOS.

7. Problèmes actuels dans le jeu :

a) Étant donné que la détection de collision compare la distance entre les centres de deux cercles et implique l'utilisation d'une minuterie, en raison de l'intervalle de minuterie extrêmement court, des dizaines de collisions se sont effectivement produites derrière une collision vue à l'œil nu. fait que la direction de rebond réelle finale de la balle est différente du théorème physique réel. Après optimisation, la probabilité d'apparition a été réduite, mais cela est toujours inévitable, par conséquent, certains joueurs constateront que si la balle ne touche pas la barrière. avec précision, le centre du plateau peut faire échouer le jeu.

b) Parce que la fonction est trop verbeuse, l'efficacité de fonctionnement est faible et la minuterie est utilisée, l'expérience de jeu sur Andorid est différente de celle sur iOS ou d'autres terminaux mobiles (dans l'ensemble, iOS est meilleur qu'Android) .

c) Les classements ne sont pas automatiquement mis à jour en temps réel. (Je ne sais pas encore comment utiliser la base de données)

8. Aperçu de l'interface du jeu :

(L'image 1 est la première version, l'image 2 a supprimé le bouton, l'image 3 est la version finale, l'image 4 est le classement)

Utiliser JavaScript pour réaliser la version Web Idées de conception Pongo et compétences en partage de code source_javascript

Photo 1

Utiliser JavaScript pour réaliser la version Web Idées de conception Pongo et compétences en partage de code source_javascript

Photo 2

Utiliser JavaScript pour réaliser la version Web Idées de conception Pongo et compétences en partage de code source_javascript

Photo 3

Utiliser JavaScript pour réaliser la version Web Idées de conception Pongo et compétences en partage de code source_javascript

9. Une partie du code source JavaScript du jeu :

Copier le code Le code est le suivant :

var ifingame=0;
var maxgrade=0,grade=0;
var grade1,grade2;
var pseudo;
var gamespeed=1.4;//小球速度
var linespeed=Math.PI/95; //跟踪线速度
var crashdistancefaild=-7;//碰撞检测参数
var crashdistancesucc=15
var fantanjuli=7;   
var themaxgradeline=12.1;    
function getCookie1(nickname)
{
 if (document.cookie.length>0)
 {
  c_start=document.cookie.indexOf(nickname "=")
  if ( c_start!=-1)
  {
   c_start=c_start pseudo.length 1;
   c_end=document.cookie.indexOf(",",c_start);
   if (c_end==-1)
               c_end=document.cookie.length;
   return unescape(document.cookie.substring(c_start,c_end));
  }
 } 
 return ""
}
function getCookie2(mymaxgrade)
{
 if (document.cookie.length>0)
 {
  c_start=document.cookie.indexOf(mymaxgrade "=")
  if (c_start!= -1)
  {
   c_start=c_start mymaxgrade.length 1;
   c_end=document.cookie.indexOf(";",c_start);
   if (c_end==-1)
c_end=document.cookie.length;
   return unescape(document.cookie.substring(c_start,c_end));
  }
 } 
 return ""
}   
function setCookie( pseudo, valeur, mymaxgrade, maxgrade, expiredays)
{
 var exdate=new Date()
 exdate.setDate(exdate.getDate() expiredays)
 document.cookie=nickname "=" évasion (value) "," mymaxgrade "=" escape(maxgrade) ((expiredays==null) ? "" : "; expires=" exdate.toGMTString());
}
function checkCookie()
{
 nickname=getCookie1('nickname');
    maxgrade=parseInt(getCookie2 ('mymaxgrade'));
       if(isNaN(maxgrade)==true)
       {
       maxgrade=0;
      }
 if (nickname!=null && pseudo!="" )
   {
        alert('欢迎' pseudo '回来!' 'n' "如果喜欢请分享一下哈~");
    }
 else
   {
  pseudo = invite ('请输入你的昵称:(名字太长上榜可是会显示不完整的哦)',"")
    si (pseudo!=null && pseudo!="")
     {
var maxgradestring=maxgrade.toString();
      setCookie('nickname',nickname,'mymaxgrade',maxgradestring,365);
     }
   }
}   

var objpane= document.getElementById("pane");
var ctxpane=objpane.getContext("2d");
ctxpane.translate(150,150);//必备 画布中心点平移 
function sendmail()
     {
            if(grade2>themaxgradeline)
            var max_grade=grade2;
            window.location.href='index.php?max_grade=' max_grade '&nick_name=' pseudo;
         /*    {
              ?   $grade=$_GET['max_grade'];
   $nickname=$_GET['nick_name'];
   $mail = new SaeMail();
   $ ret = $mail->quickSend( 'reasonpongo@163.com' , $grade , $nickname ,'reasonpongo@163.com' , 'mypongo' );
   $mail->clean();
   ?>
           }*/
            alerte(surnom "你的成绩为:" grade2 "提交成功~");
        }  

   
var gamedirection={
 shang : 1,
 xia  : 5,
 zuo  : 7,
 vous  : 3,
 zuoshang : 8,
 zuoxia : 6,
 youshang : 2,
 youxia  : 4,
 horloge : 0,
 anticlock : 9,
 };//方向
var canvas={
 largeur : 300,
 hauteur : 300,
 };//Canvas

var bigcircle = {//Paramètres du grand cercle
x : 0, //valeur de coordonnée sur l'axe x du centre du cercle
y : 0, //y- valeur de coordonnée de l'axe du centre du cercle
      r : 150, //Le rayon du cercle
c: 'rgb(255,255,255)',
};//Grand cercle
var smallcircle = {//Paramètre du petit cercle
x : 0, / /La valeur de coordonnée sur l'axe x du centre du cercle
y : 0, //La valeur de coordonnée sur l'axe y du centre du cercle
r: 12, //Le rayon du cercle
c: 'rgb(204,105,106)',
direction : gamedirection.xia,
};//Petit cercle

ligne var = {//Les paramètres de la ligne de déflecteur
x : 0, //La valeur de coordonnée sur l'axe x du centre du cercle
y : 0, //La valeur de coordonnée sur l'axe y du centre de le cercle
r : 150, //Le rayon de l'arc
début :(Math.PI/2-Math.PI/16),
fin : (Math .PI/2 Math.PI/ 16),
c : 'rgb(55,55,55)',
direction : gamedirection.anticlock,
};//Ligne de traçage
var dot = {//Paramètres du point de suivi
x: (bigcircle.r*Math.cos(line.start Math.PI/16)),//Prendre le grand cercle comme origine
y: (bigcircle.r*Math. sin(line.start Math.PI/16)),
r : 1,
}//Point de suivi
fonction changelinedirection()
{
if(line.direction==gamedirection .clock)
{
line.direction=gamedirection.anticlock;
}
else
{
line.direction=gamedirection.clock;
}
}

function getdistance(){
var distance=Math.sqrt((smallcircle.x)*(smallcircle.x ) (smallcircle.y )*(smallcircle.y ));
distance de retour
}/ /Renvoyer la distance carrée entre la petite balle et le centre du grand cercle getdistance()

function ifgameover(){//Juge si elle est hors limites
if((getdistance() - bigcircle .r)>5 )
return true;
else
return false;
} //Déterminer si le jeu est terminé ifgameover()
function ifcrash(){ //Détection de collision
var dx = dot. x-smallcircle.x;
var dy = dot.y-smallcircle.y;
var dd=Math.sqrt(dx*dx dy*dy);
if (dd< crashdistancesucc)
return true;
else
return false;
}//Détection de collision ifcrash()

function randomback()
{
var x=Math.floor(Math. random()*3);
switch (smallcircle.direction){
case gamedirection.shang :
{
switch (x)
{
cas 0 :
smallcircle .direction=gamedirection.xia;
smallcircle.y=smallcircle.y fantanjuli;
break;
cas 1 :
smallcircle.direction=gamedirection.zuoxia;
                                                          smallcircle.x=smallcircle x-fantanjuli;
smallcircle.y=smallcircle.y fantanjuli;
break;
cas 2; :
smallcircle.direction=gamedirection.youxia;
smallcirc le.x=smallcircle.x fantanjuli;
smallcircle.y=smallcircle.y fantanjuli;
break;
par défaut:
break;
} break;
}
    case gamedirection.xia :
    {
     switch (x)
     {
      case 0 :
      smallcircle.direction=gamedirection.shang;
      smallcircle.y=smallcircle.y -fantanjuli;
      pause;
      cas 1 :
      smallcircle.direction=gamedirection.zuoshang;
      smallcircle.x=smallcircle.x-fantanjuli;
      smallcircle.y=smallcircle.y-fantanjuli ;
      pause;
      cas 2 :
      smallcircle.direction=gamedirection.youshang;
      smallcircle.x=smallcircle.x fantanjuli;
      smallcircle.y=smallcircle.y-fantanjuli;
      pause ;
      par défaut :
      pause ;     
     } break;
    }
       case gamedirection.zuo:
    {
     switch (x)
     {
      case 0:
      smallcircle.direction=gamedirection.you;
      smallcircle.x=smallcircle.x fantanjuli;
      pause;
      cas 1 :
      smallcircle.direction=gamedirection.youshang;
      smallcircle.x=smallcircle.x;
      petit cercle .y=smallcircle.y-fantanjuli;
      break;
      cas 2 :
      smallcircle.direction=gamedirection.youxia;
      smallcircle.x=smallcircle.x fantanjuli;
      smallcircle.y= smallcircle.y fantanjuli;
      break;
      default:
      break;
     } break;
    }
    case gamedirection.you:
    {
     switch (x)
     {
      cas 0 :
      smallcircle.direction=gamedirection.zuo;
      smallcircle.x=smallcircle.x-fantanjuli;
      break;
      cas 1 :
      petitcercle.direction =gamedirection.zuoxia;
      smallcircle.x=smallcircle.x-fantanjuli;
      smallcircle.y=smallcircle.y fantanjuli;
      break;
      cas 2 :
      smallcircle.direction=gamedirection. zuoshang;
      smallcircle.x=smallcircle.x-fantanjuli;
      smallcircle.y=smallcircle.y-fantanjuli;
      break;
      par défaut :
      break;
     } break;

    }
    case gamedirection.zuoshang :
    {
     switch (x)
     {
      case 0 :
      smallcircle.direction=gamedirection.youxia;
      petit cercle .x=smallcircle.x fantanjuli;
      smallcircle.y=smallcircle.y fantanjuli;
      break;
      cas 1 :
      smallcircle.direction=gamedirection.xia;
      smallcircle.y=smallcircle .y fantanjuli;
      break;
      cas 2 :
      smallcircle.direction=gamedirection.you;
      smallcircle.x=smallcircle.x fantanjuli;
      break;
      default:
      pause;
     } pause;

    }
    case gamedirection.zuoxia :
    {
     switch (x)
     {
      case 0 :
      smallcircle.direction=gamedirection.youshang;
      smallcircle.x=smallcircle.x fantanjuli;
     smallcircle.y=smallcircle.y-fantanjuli;
      break;
      cas 1 :
      smallcircle.direction=gamedirection.shang;
      smallcircle.y=smallcircle.y-fantanjuli;
      pause;
      cas 2 :
      smallcircle.direction=gamedirection.you;
      smallcircle.x=smallcircle.x fantanjuli;
      pause ;
      par défaut :
      pause ;
} Break;

}
case Gamedirection.youshang:
{
switch (x)
{
case 0:
smallriccle.derection = gamedirection. zuoxia;
      smallcircle.x=smallcircle.x-fantanjuli;
      smallcircle.y=smallcircle.y fantanjuli;
      break;
      cas 1 :
      smallcircle.direction=gamedirection.zuo;
smallcircle.x = smallcircle.x-FantanJuli;
Break;
cas 2:
smallcircle.direction = gamedirection.xia;
smallcircle.y = smallriccle.y Fantanjuli;
Break ;
      par défaut :
      break;
     } break;

    }
    case gamedirection.youxia:
    {
     switch (x)
     {
cas 0 :
      smallcircle.direction=gamedirection.zuoshang;
      smallcircle.x=smallcircle.x-fantanjuli;
      smallcircle.y=smallcircle.y-fantanjuli;
      break;
      cas 1 :
      smallcircle.direction=gamedirection.zuo;
      smallcircle.x=smallcircle.x-fantanjuli;
      break;
      cas 2 :
     smallcircle.direction=gamedirection.shang;
smallcircle.y=smallcircle.y-fantanjuli;
      break;
      par défaut :
      break;
     } break;

    }
    par défaut :
    {
casser;  
    }
   } 
}//小球随机反向 randomback()
function smallcircledirection()
{
 switch (smallcircle.direction){    //根据小球方向做移动
    case gamedirection.shang:
    {
     smallcircle.y=smallcircle.y-gamespeed;
     grade ;
     if(grade>maxgrade)
     {
                        maxgrade=grade ;
                      newrecoder();
                    }
     addone();
     break;
    }
    case gamedirection.xia:
    {
     smallcircle.y=smallcircle.y gamespeed;
     grade ;
     if(grade>maxgrade)
     {
                       maxgrade=grade;
                      newrecoder();
                    }
     addone();
     break;
    }
    case gamedirection.zuo:
    {
     smallcircle.x=smallcircle.x-gamespeed ;
     grade ;
     if(grade>maxgrade)
     {
                       maxgrade=grade;
                      newrecoder();
                    }
     addone();
     break;
    }
    case gamedirection.you :
    {
     smallcircle.x=smallcircle.x gamespeed;
     grade ;
     if(grade>maxgrade)
     {
                        maxgrade= grade;
                      newrecoder();
                    }
     addone();
     break;
    }
    case gamedirection.zuoshang:
    {
     smallcircle.x=smallcircle. x-gamespeed*0.8;
     smallcircle.y=smallcircle.y-gamespeed*0.8;
     grade ;
     if(grade>maxgrade)
     {
                         maxgrade=grade;
                      nouvelenregistreur ();
                    }
     addone();
     break;
    }
    case gamedirection.zuoxia:
    {
     smallcircle.x=smallcircle.x-gamespeed*0 .8 ;
     smallcircle.y=smallcircle.y gamespeed*0.8;
     grade ;
     if(grade>maxgrade)
     {
                        maxgrade=grade;
                      newrecoder();
                    }
     addone();
     break;
    }
    case gamedirection.youshang :
    {
     smallcircle.x=smallcircle.x gamespeed*0.8;
     smallcircle.y=smallcircle.y-gamespeed*0.8;
     grade ;
     if (grade>maxgrade)
     {
                       maxgrade=grade;
                     newrecoder();
                   }
     addone();
     break;
    }
    case gamedirection.youxia :
    {
     smallcircle.x=smallcircle.x gamespeed*0.8;
     smallcircle.y=smallcircle.y gamespeed*0.8;
     grade ;
     if(grade>maxgrade)
{
                        maxgrade=grade;
                      newrecoder();
                    }
     addone();
     break ;
    }
    par défaut :
    {
     pause ;  
    }
   } 
}//小球移动 smallcircledirection()
/*画出底部圆*/
ctxpane.beginPath(); //大圆
ctxpane.arc(bigcircle.x,bigcircle.y,bigcircle.r,0,Math.PI*2,true);
ctxpane.fillStyle = bigcircle.c;
ctxpane.fill ();
ctxpane.closePath();
/*画出底部追踪线条*/
ctxpane.beginPath();
ctxpane.lineWidth=6;
ctxpane.strokeStyle = line .c;
ctxpane.arc(line.x, line.y, line.r, line.start, line.end,false);
ctxpane.Stroke();
ctxpane.closePath();
function tapme()//tapme
{
 ctxpane.beginPath();
 ctxpane.strokeStyle="rgb(255,222,195)";
 ctxpane .font = "Papyrus 80px";
 ctxpane.StrokeText('TAP',-95,30);
 ctxpane.fillStyle="rgb(255,205,105)";
 ctxpane.font = "Papyrus 35px" ;
 ctxpane.fillText('me',70,30);
 ctxpane.closePath();
 }
function newrecoder()
{
 ctxpane.beginPath();
 ctxpane.fillStyle="rgb(255,0,0)";
 ctxpane.font = "18px Papyrus";
 ctxpane.fillText("Nouveau!",58,80);
ctxpane.closePath();
 }
function addone()
{
 grade1=(grade/150).toFixed(1);
 grade2=(maxgrade/150).toFixed( 1);
 var say1="now";
 var say2="best"
 ctxpane.beginPath();
 ctxpane.StrokeStyle="rgb(250,222,185)";
 ctxpane. font = "60px Papyrus";
 ctxpane.StrokeText(grade1,-45,-60);
 ctxpane.StrokeText(grade2,-45,100);

 ctxpane.fillStyle="rgb(255 ,0,100)";
 ctxpane.font = "15px Papyrus";
 ctxpane.fillText(say1,58,-60);

 ctxpane.fillStyle="rgb(255,0,100)" ;
 ctxpane.font = "15px Papyrus";
 ctxpane.fillText(say2,58,100);
 ctxpane.closePath();
}
function movetest(){

 if(ifgameover())
 {
        ifingame=0;
        if(maxgrade>parseInt(getCookie2('mymaxgrade')))
  {
   setCookie('nickname',nickname ,'mymaxgrade',maxgrade.toString(),365);  
  }
  clearInterval(timer);
  tapme();
 }
 else
 {
  if(ifcrash())
   {
    randomback() ;
   } 
ctxpane.clearRect(-150,-150,300,300); //清屏

ctxpane.beginPath(); //大圆
ctxpane.arc(bigcircle.x,bigcircle.y,bigcircle.r,0,Math.PI*2,true);
ctxpane.fillStyle = bigcircle.c;
ctxpane.fill ();
ctxpane.closePath();
if(line.direction==gamedirection.clock)   //跟踪线顺时针
{
 line.start=line.start linespeed; 
 line.end=line.end linespeed;
 ctxpane.beginPath();
 ctxpane.lineWidth=4;
 ctxpane.StrokeStyle = line.c;
 ctxpane.arc(line. x, line.y, line.r, line.start, line.end,false);
 ctxpane.Stroke();
 ctxpane.closePath(); 
}
if(line.direction==gamedirection.anticlock)         //跟踪逆顺时针
{
 line.start=line.start - linespeed; 
 line.end=line.end -linespeed;
 ctxpane.beginPath();
 ctxpane.lineWidth=4;
 ctxpane.StrokeStyle = line.c;
 ctxpane.arc(line .x, line.y, line.r, line.start, line.end,false);
 ctxpane.Stroke();
 ctxpane.closePath();  
}

dot.x=bigcircle.r*Math.cos(line.start Math.PI/32) //跟踪点
dot.y=bigcircle.r*Math.sin( line.start Math.PI/32)
ctxpane.beginPath();//线上跟踪点
ctxpane.arc(dot.x,dot.y,dot.r,0,Math.PI*2 ,true);
ctxpane.fillStyle = smallcircle.c;
ctxpane.fill();
ctxpane.closePath(); 
smallcircledirection();//小圆
ctxpane.save();
ctxpane.beginPath();
ctxpane.arc(smallcircle.x,smallcircle.y,smallcircle.r,0, Math.PI*2,true);
ctxpane.fillStyle = smallcircle.c;
ctxpane.fill();
ctxpane.closePath();
ctxpane.restore();
>
}//主函数

    /////////////////////////////////////////
tapme ();
var timer;
function startgame(){//开始游戏

    if(ifingame==0)
    {
        ifingame=1;
        grade=0;
        var xx=Math.floor(Math.random()*8);
/*      switch(xx)
        {
            cas 0 :
   smallcircle.direction=gamedirection.shang;
   break;
   cas 1 :
   smallcircle.direction=gamedirection.xia;
   break;
   cas 2 :
   smallcircle.direction=gamedirection.zuo;
   break;
   cas 3 :
   smallcircle.direction=gamedirection.you;
   break;
   cas 4 :
   smallcircle.direction=gamedirection.zuoshang;
   break;
   cas 5 :
   smallcircle.direction=gamedirection.zuoxia;
   break;
   cas 6 :
   smallcircle.direction=gamedirection.youshang;
   break;
   cas 7 :
   smallcircle.direction=gamedirection.youxia;
   break;
   par défaut :
   break;
        } */
    smallcircle.direction=gamedirection.xia;
 smallcircle.x=smallcircle.y=0;
 line.start=Math.PI/2-Math.PI/26;
 line. end=Math.PI/2 Math.PI/26;
 line.direction=gamedirection.anticlock;

 clearInterval(timer);
 timer=setInterval(movetest,10);
}
 }//开始游戏 startgame()  
    function opentop()
    {
        window.location="http://pongotop.sinaapp.com";
    }

10.写在最后

这纯属又是一个自娱自乐,写完后的第三天因为开始忙着投简历找实习就没空再管,扔到朋友圈让朋友玩去了。这一个月过去了再重新看这游戏,感觉它不该就这样死掉,本人没什么技术,做得很拙略,因此发出这篇文字希望能帮到一些对pongo感兴趣的朋友,再者就是希望如果有这方面的高手看到了能够给予赐教,一切疑惑和赐教都欢迎给我留言,谢谢!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn