>  기사  >  웹 프론트엔드  >  [HTML5] 3D 모델--100줄의 코드로 회전하는 3차원 루빅스 큐브를 구현하는 예

[HTML5] 3D 모델--100줄의 코드로 회전하는 3차원 루빅스 큐브를 구현하는 예

黄舟
黄舟원래의
2017-02-22 14:11:503677검색

최근 루빅스 큐브 게임 방법을 공부하다가 갑자기 HMTL5를 사용하여 루빅스 큐브 모델을 작성하고 싶었습니다. 루빅스 큐브는 3D 큐브이기 때문에 이번에는 HTML5를 사용하여 간단한 3D 모델을 작성해 보았습니다.

다음은 미리보기 화면입니다.

[HTML5] 3D 모델--100줄의 코드로 회전하는 3차원 루빅스 큐브를 구현하는 예

제작 과정

먼저 Html5 오픈 소스 라이브러리 lufylegend-1.4.0을 다운로드해야 합니다

루빅큐브는 6개의 면으로 나누어져 있으며 각 면은 9개의 작은 직사각형으로 구성되어 있습니다.

지금 만들고 있는 것은 3D 루빅스 큐브이기 때문입니다. 각각의 작은 직사각형에 대해 작은 직사각형의 4개의 고정점을 알아야 하며, 이 4개의 고정점은 공간의 회전 각도에 따라 변환되므로 이 4개의 고정점의 좌표를 계산합니다. 포인트를 얻으려면 x축과 z축을 중심으로 한 루빅스 큐브의 회전 각도를 알아야 합니다.

그래서 다음과 같이 직사각형 클래스를 만듭니다

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는 작은 직사각형 angleX의 네 꼭짓점입니다. , angleZ는 각각 x축과 z축 사이의 회전 각도이고, color는 작은 직사각형의 색상입니다.

루빅큐브는 6개의 면으로 나누어져 있는데 먼저 앞면을 살펴보겠습니다. 큐브의 중심을 3차원 좌표계의 중심으로 사용하면 각 고정점에 해당하는 좌표가 나옵니다. 9개의 작은 직사각형 중 아래 그림과 같습니다

[HTML5] 3D 모델--100줄의 코드로 회전하는 3차원 루빅스 큐브를 구현하는 예

그래서 이전 표면의 9개의 작은 직사각형은 다음 코드로 생성할 수 있습니다

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);  
    }  
}



그 중 backLayer는 LSprite 클래스이고, step은 작은 직사각형의 절반 길이를 같은 방식으로 얻을 수 있습니다.

6개의 면이 설정되었습니다. 이 6개의 면을 그리기 전에 먼저 회전 각도를 기준으로 각 고정점의 좌표를 계산해야 합니다.

[HTML5] 3D 모델--100줄의 코드로 회전하는 3차원 루빅스 큐브를 구현하는 예

위 그림에 따르면 다음 공식을 사용하여 변환된 고정 소수점 좌표를 얻습니다

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];  
};



마지막으로 작은 직사각형, Draw this 직사각형,

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);  
};



여기서 drawVertices는 lufylegend.js 라이브러리에 있는 LGraphics 클래스의 메소드로, 이를 기반으로 직사각형을 그릴 수 있습니다. 들어오는 고정 소수점 좌표 배열 다각형.

마지막으로 코드가 매우 적고 총 91줄의 JS 코드가 제공됩니다.

One, 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>



Two, Rect 클래스

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];  
};



Three, 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);  
   }  
}



위 내용은 [HTML5] 3D 모델의 내용입니다 - 회전하는 3차원 루빅스 큐브 예제를 구현하기 위한 100줄의 코드입니다. 더 많은 관련 내용은 PHP 중국어 웹사이트(www.php.cn)를 참고하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.