Recently, the gameplay of Rubik's cube suddenly wanted to write a Miku's model with HMTL5. Since the Rubik's Cube is a 3D cube, this time I tried to write a simple 3D model with HTML5.
The following is a preview screen. Production processFirst you need to download html5 open source library LUFYLEGEND -.4.0
The Rubik's cube is divided into 6 planes, each of which is composed of 9 small rectangles. Now I encapsulate each small rectangle as a class.
Because now it is a 3D Rubik's Cube, to draw each small rectangle, you need to know the 4 fixed points of the small rectangle, and these 4 fixed points will be transformed according to the rotation angle of the space. You need to know the angle of the Rubik's cube around the X and Z axis.
Therefore, the establishment of the rectangular class is as follows
Function RECT (Pointa, Pointb, Pointc, Pointd, ANGLEX, ANGLEZ, Color) {base (this, lsprite, []); this.pointz = [(Pointa [0]+pointb [0]+PO PO intD [0])/4, (pointa [1]+pointb [1]+pointc [1]+pointd [1]/4, (pointa [2]+pointb [2]+pointc [2]+pointd [2 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; [2] ;};
Pointa, pointb, pointc, pointd is the four vertices of small rectangles. Anglex, anglez are the angle of the X -axis and Z axis, respectively. Color is the color of small rectangles.
The Rubik's cube is divided into 6 planes, first look at the front side. If the center of the cube is used as the center of the 3D coordinate system, the coordinates corresponding to each fixed point of the nine small rectangles are shown in the figure below.
Therefore, the nine small rectangles on the previous side can be established by the following code
For (var x = 0; x <3; x ++) {for (var y 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);}}}
Among them, BACKLAYER is a LSprite class. STEP is half a small rectangle. The same reason can get five other faces.
Six noodles have been established. Before drawing these 6 planes, you must first calculate the coordinates of each fixed point from the perspective of rotation. Look at the picture below
According to the above figure, you can get the fixed -point coordinates after transforming the following formula
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];};
Finally, draw this rectangle according to the four fixed -point coordinates of the small rectangle,
Rect.prototype.Draw = Function (layer) {this.graphics.clear (); This.graphics.drawvertices ETPOINT (this.pointb), this .getpoint (this.pointc), this.getpoint (this.pointd), true, this.color);};};};
DrawVertices is a method of the LGRAPHICS class in the LUFYLEGEND.JS library. It can draw a polygon based on the fixed -point coordinate array that is introduced.
Finally, the complete code is given, and the code is very small. The JS code has a total of 91 lines.
First, index.html<! Doctype html> <html> <gead> <meta charset = UTF-8> <Title> 3D Rubik's Cube </Title> </Head> <body> <DIV ID = MyLegend> Loading ... </div> Type = Text/JavaScript SRC = ../Lufylegend -.4.0.min.js> </Script> <Script Type = Text/JavaScript SRC =./Main.js> </script> XT/JavaScript src =./Rect.js> </Script> </Body> </html>Second, RECT class
Function RECT (Pointa, Pointb, Pointc, Pointd, ANGLEX, ANGLEZ, Color) {base (this, lsprite, []); this.pointz = [(Pointa [0]+pointb [0]+PO PO intD [0])/4, (pointa [1]+pointb [1]+pointc [1]+pointd [1]/4, (pointa [2]+pointb [2]+pointc [2]+pointd [2 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 .getpoint (this.pointa),, This.getpoint (this.pointb), this.getpoint (this.pointc), this.getpoint (this.pointd)], true, this.Color);}; tion (a, b) {{ this.anglex = a; this.anglez = b; this.z = this.getpoint (this.pointz) [2]; radiprototype.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; u2; , v2, w2];};Third, main.js
Init (50, mylegend, 400,400, main); VAR A = 0, B = 0, BackLayer, Step = 20, key = null; function main () {backlayer = new lsprite (); ; backlayer.x = 120, backlayer.y = 120; // After (var x = 0; x <3; x ++) {for (var y = 0; y <3; y ++) {z = 0; var revging = 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);} / /Previous for (var x = 0; x <3; x ++) {for (var y y = 0; y <3; y ++) {z = 3; var recle = new RECT ([-3*Step+x*2*2*2*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);} // above 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*2* step, -Step+Z*2*Step], 0,0,#FFFFFF); Backlayer.addchild (RECT);} // For (var x = 0; x <3; x ++) {for (var z ZAR 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);}} // left 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);}} // Right for (var y 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 tion (a, b) {return az -bz;}) ; For (key in backlayer.childlist) {backlayer.childlist [key] .setangle (a, b); backlayer.childlist [key] .draw (backlayer);}}
This is just a very simple 3D model. I hope it will be helpful to everyone's learning. I also hope that everyone will support VEVB Wulin.com.