Récemment, en étudiant comment jouer au Rubik's Cube, j'ai soudainement eu envie d'utiliser HMTL5 pour écrire un modèle de Rubik's Cube. Puisque le Rubik's Cube est un cube 3D, j'ai essayé d'écrire un modèle 3D simple en utilisant HTML5 cette fois.
Ce qui suit est l'écran d'aperçu.
Processus de production
Vous devez d'abord télécharger la bibliothèque open source Html5 lufylegend-1.4.0
Le Rubik's Cube est divisé en 6 faces, chaque face est composée de 9 petits rectangles. Maintenant, j'encapsule chaque petit rectangle comme une classe
Parce que ce que je construis maintenant est un Rubik's Cube 3D, je le fais. il faut le dessiner Pour chaque petit rectangle, il faut connaître les 4 points fixes du petit rectangle, et ces 4 points fixes se transformeront en fonction de l'angle de rotation de l'espace donc, afin de calculer les coordonnées de ces 4 fixes. points, vous devez connaître l'angle de rotation du Rubik's Cube autour de l'axe x et de l'axe z.
Alors, créez une classe de rectangle comme suit
function Rect(pointA,pointB,pointC,pointD,angleX,angleZ,color){ base(this,LSprite,[]); this.pointZ=[(pointA[0]+pointB[0]+pointC[0]+pointD[0])/4,(pointA[1]+pointB[1]+pointC[1]+pointD[1])/4,(pointA[2]+pointB[2]+pointC[2]+pointD[2])/4]; this.z = this.pointZ[2]; this.pointA=pointA,this.pointB=pointB,this.pointC=pointC,this.pointD=pointD,this.angleX=angleX,this.angleZ=angleZ,this.color=color; } Rect.prototype.setAngle = function(a,b){ this.angleX = a; this.angleZ = b; this.z=this.getPoint(this.pointZ)[2]; };
pointA, pointB, pointC, pointD sont les quatre sommets du petit rectangle , angleX, angleZ sont respectivement l'angle de rotation des axes x et z, et color est la couleur du petit rectangle.
Le Rubik's Cube est divisé en 6 faces. Regardons d'abord la face avant Si le centre du cube est utilisé comme centre du système de coordonnées 3D, alors les coordonnées correspondant à chaque point fixe. des 9 petits rectangles sont comme indiqué dans la figure ci-dessous
Ainsi, les 9 petits rectangles sur la surface avant peuvent être créés par le code suivant
for(var x=0;x<3;x++){ for(var y=0;y<3;y++){ z = 3; var rect = new Rect([-3*step + x*2*step,-3*step + y*2*step,-3*step + z*2*step],[-step + x*2*step,-3*step + y*2*step,-3*step + z*2*step], [-step + x*2*step,-step + y*2*step,-3*step + z*2*step],[-3*step + x*2*step,-step + y*2*step,-3*step + z*2*step],0,0,"#FF0000"); backLayer.addChild(rect); } }
Parmi eux, backLayer est une classe LSprite, et step a la longueur d'un demi petit rectangle. De la même manière, les cinq autres faces peuvent également être obtenues.
Six faces ont été établies. Avant de dessiner ces six faces, il faut d'abord calculer les coordonnées de chaque point fixe en fonction de l'angle de rotation
<🎜. >
D'après l'image ci-dessus, utilisez la formule suivante pour obtenir les coordonnées du point fixe transformé
Rect.prototype.getPoint = function(p){ var u2,v2,w2,u=p[0],v=p[1],w=p[2]; u2 = u * Math.cos(this.angleX) - v * Math.sin(this.angleX); v2 = u * Math.sin(this.angleX) + v * Math.cos(this.angleX); w2 = w; u = u2; v = v2; w = w2; u2 = u; v2 = v * Math.cos(this.angleZ) - w * Math.sin(this.angleZ); w2 = v * Math.sin(this.angleZ) + w * Math.cos(this.angleZ); u = u2; v = v2; w = w2; return [u2,v2,w2]; };
Enfin, selon les quatre points fixes coordonnées du petit rectangle , pour dessiner ce rectangle,
Rect.prototype.draw = function(layer){ this.graphics.clear(); this.graphics.drawVertices(1,"#000000",[this.getPoint(this.pointA),this.getPoint(this.pointB), this.getPoint(this.pointC),this.getPoint(this.pointD)],true,this.color); };
où drawVertices est une méthode de la classe LGraphics de la bibliothèque lufylegend.js, qui peut être basé sur les coordonnées à virgule fixe entrantes. Tableau pour dessiner un polygone.
Enfin, le code complet est donné. Il y a très peu de code et un total de 91 lignes de code JS.
1. index.html
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>3D魔方</title> </head> <body> <p id="mylegend">loading……</p> <script type="text/javascript" src="../lufylegend-1.4.0.min.js"></script> <script type="text/javascript" src="./Main.js"></script> <script type="text/javascript" src="./Rect.js"></script> </body> </html>
2. >
function Rect(pointA,pointB,pointC,pointD,angleX,angleZ,color){ base(this,LSprite,[]); this.pointZ=[(pointA[0]+pointB[0]+pointC[0]+pointD[0])/4,(pointA[1]+pointB[1]+pointC[1]+pointD[1])/4,(pointA[2]+pointB[2]+pointC[2]+pointD[2])/4]; this.z = this.pointZ[2]; this.pointA=pointA,this.pointB=pointB,this.pointC=pointC,this.pointD=pointD,this.angleX=angleX,this.angleZ=angleZ,this.color=color; } Rect.prototype.draw = function(layer){ this.graphics.clear(); this.graphics.drawVertices(1,"#000000",[this.getPoint(this.pointA),this.getPoint(this.pointB), this.getPoint(this.pointC),this.getPoint(this.pointD)],true,this.color); };Rect.prototype.setAngle = function(a,b){ this.angleX = a; this.angleZ = b; this.z=this.getPoint(this.pointZ)[2]; }; Rect.prototype.getPoint = function(p){ var u2,v2,w2,u=p[0],v=p[1],w=p[2]; u2 = u * Math.cos(this.angleX) - v * Math.sin(this.angleX); v2 = u * Math.sin(this.angleX) + v * Math.cos(this.angleX); w2 = w; u = u2; v = v2; w = w2; u2 = u; v2 = v * Math.cos(this.angleZ) - w * Math.sin(this.angleZ); w2 = v * Math.sin(this.angleZ) + w * Math.cos(this.angleZ); u = u2; v = v2; w = w2; return [u2,v2,w2]; };
Trois, Main.js
init(50,"mylegend",400,400,main); var a = 0,b=0,backLayer,step = 20,key = null; function main(){ backLayer = new LSprite(); addChild(backLayer); backLayer.x = 120,backLayer.y = 120; //后 for(var x=0;x<3;x++){ for(var y=0;y<3;y++){ z = 0; var rect = new Rect([-3*step + x*2*step,-3*step + y*2*step,-3*step + z*2*step],[-step + x*2*step,-3*step + y*2*step,-3*step + z*2*step], [-step + x*2*step,-step + y*2*step,-3*step + z*2*step],[-3*step + x*2*step,-step + y*2*step,-3*step + z*2*step],0,0,"#FF4500"); backLayer.addChild(rect); } } //前 for(var x=0;x<3;x++){ for(var y=0;y<3;y++){ z = 3; var rect = new Rect([-3*step + x*2*step,-3*step + y*2*step,-3*step + z*2*step],[-step + x*2*step,-3*step + y*2*step,-3*step + z*2*step], [-step + x*2*step,-step + y*2*step,-3*step + z*2*step],[-3*step + x*2*step,-step + y*2*step,-3*step + z*2*step],0,0,"#FF0000"); backLayer.addChild(rect); } } //上 for(var x=0;x<3;x++){ for(var z=0;z<3;z++){ y = 0; var rect = new Rect([-3*step + x*2*step,-3*step + y*2*step,-3*step + z*2*step],[-step + x*2*step,-3*step + y*2*step,-3*step + z*2*step], [-step + x*2*step,-3*step + y*2*step,-step + z*2*step],[-3*step + x*2*step,-3*step + y*2*step,-step + z*2*step],0,0,"#FFFFFF"); backLayer.addChild(rect); } } //下 for(var x=0;x<3;x++){ for(var z=0;z<3;z++){ y = 3; var rect = new Rect([-3*step + x*2*step,-3*step + y*2*step,-3*step + z*2*step],[-step + x*2*step,-3*step + y*2*step,-3*step + z*2*step], [-step + x*2*step,-3*step + y*2*step,-step + z*2*step],[-3*step + x*2*step,-3*step + y*2*step,-step + z*2*step],0,0,"#FFFF00"); backLayer.addChild(rect); } } //左 for(var y=0;y<3;y++){ for(var z=0;z<3;z++){ x = 0; var rect = new Rect([-3*step + x*2*step,-3*step + y*2*step,-3*step + z*2*step],[-3*step + x*2*step,-3*step + y*2*step,-step + z*2*step], [-3*step + x*2*step,-step + y*2*step,-step + z*2*step],[-3*step + x*2*step,-step + y*2*step,-3*step + z*2*step],0,0,"#008000"); backLayer.addChild(rect); } } //右 for(var y=0;y<3;y++){ for(var z=0;z<3;z++){ x = 3; var rect = new Rect([-3*step + x*2*step,-3*step + y*2*step,-3*step + z*2*step],[-3*step + x*2*step,-3*step + y*2*step,-step + z*2*step], [-3*step + x*2*step,-step + y*2*step,-step + z*2*step],[-3*step + x*2*step,-step + y*2*step,-3*step + z*2*step],0,0,"#0000FF"); backLayer.addChild(rect); } } backLayer.addEventListener(LEvent.ENTER_FRAME,onframe); } function onframe(){ a += 0.1 , b += 0.1; backLayer.childList = backLayer.childList.sort(function(a,b){return a.z - b.z;}); for(key in backLayer.childList){ backLayer.childList[key].setAngle(a,b); backLayer.childList[key].draw(backLayer); } }
Ce qui précède est le contenu du modèle 3D [HTML5] - une centaine de lignes de code pour implémenter un exemple de Rubik's cube rotatif en trois dimensions. Pour plus de contenu connexe, veuillez faire attention au site Web chinois PHP (www. .php.cn) !
-->