php开发h5游戏教程,HTML5实现魔方游戏的代码

这篇文章详细介绍了如何使用HTML5、WebGL技术创建一款3D魔方游戏,包括顶点着色器和片段着色器的代码实现,以及光影效果和鼠标交互操作的处理。通过实例代码,读者可以了解到WebGL在游戏开发中的应用和3D图形编程的基本原理。
摘要由CSDN通过智能技术生成

这篇文章给大家分享的内容是关于HTML5实现魔方游戏的代码,有一定的参考价值,有需要的朋友可以从参考一下,希望对你有所帮助。

WebGL魔方小游戏 - www.web-tinker.com

attribute vec3 position;

attribute vec3 normal;

attribute vec3 color;

uniform mat4 mMatrix;

uniform mat4 mvpMatrix;

uniform mat4 mvpShadowerMatrix;

uniform vec3 lVector;

varying float diffuse;

varying vec4 vPosition;

varying vec3 vColor;

void main(){

vec4 v4Position=vec4(position,1.0);

vPosition=mvpShadowerMatrix*v4Position;

gl_Position=mvpMatrix*v4Position;

vec3 tNormal=(mMatrix*vec4(normalize(normal),0.0)).xyz;

diffuse=max(-dot(tNormal,normalize(lVector)),0.4);

vColor=color;

}

precision lowp float;

varying float diffuse;

uniform sampler2D depthData;

uniform vec2 size;

varying vec4 vPosition;

varying vec3 vColor;

vec2 depthMap;

float f(float i,float j){

float z=texture2D(depthData,depthMap+vec2(i,j)*2.0/size).z;

return abs(z-vPosition.z)<0.01?diffuse:0.4;

}

void main(){

depthMap=(vPosition.xy/vPosition.w*0.5+0.5)/512.0*size;

float vDiffuse=0.0;

for(float i=-2.0;i<=2.0;i++)for(float j=-2.0;j<=2.0;j++)vDiffuse+=f(i,j);

vDiffuse/=25.0;

gl_FragColor=vec4(vec3(vDiffuse*vColor),1.0);

}

attribute vec3 position;

attribute vec3 normal;

attribute vec3 color;

uniform mat4 mvpMatrix;

varying float xx;

void main(){

gl_Position=mvpMatrix*vec4(position,1.0);

normal;color;

}

precision lowp float;

uniform float index;

void main(){

gl_FragColor=vec4(vec3(index),1.0);

}

attribute vec3 position;

uniform mat4 mvpShadowerMatrix;

varying float depth;

void main(){

gl_Position=mvpShadowerMatrix*vec4(position,1.0);

depth=gl_Position.z;

}

varying lowp float depth;

void main(){

gl_FragColor=vec4(vec3(depth),1.0);

}

new SimpleWebGL(canvas).namespace(function(

Program,VertexShader,FragmentShader,ArrayBuffer,

Framebuffer,Renderbuffer,Texture2D,Matrix

){

//基本函数

var π=Math.PI,sin=Math.sin,cos=Math.cos,acos=Math.acos,pow=Math.pow,abs=Math.abs,

round=Math.round,random=Math.random,updateMvpMatrix=function(){

this.data.mvpMatrix=new Matrix(this.data.mMatrix).multiply(vpMatrix);

this.data.mvpShadowerMatrix=new Matrix(this.data.mMatrix).multiply(vpShadowerMatrix);

};

//定义方块

var Cube;

(function(){

var i,j,k,p,n,position=[],normal=[],color=[],push=Array.prototype.push,a=1,b=0.9,

ctab=[[1,1,0],[0,0,1],[1,0,0],[1,1,1],[0,1,0],[1,0.5,0]];

for(i=0;i<2;i++)for(j=0;j<3;j++){ //面

for(k=0;k<4;k++)

p=[k>>1?b:-b,k&1?b:-b],p.splice(j,0,i?a:-a),push.apply(position,p),

n=[0,0],n.splice(j,0,i?a:-a),push.apply(normal,n),

push.apply(color,ctab[i*3+j]);

push.apply(position,position.slice(-9,-3));

push.apply(normal,normal.slice(-9,-3));

push.apply(color,color.slice(-9,-3));

};

for(i=0;i<3;i++)for(j=0;j<4;j++){ //棱

for(k=0;k<4;k++)

p=k<2?[a,b]:[b,a],p[0]*=j&2?1:-1,p[1]*=j&1?1:-1,

p.splice(i,0,(k&1?1:-1)*b),push.apply(position,p),

n=[a*(j&2?1:-1),a*(j&1?1:-1)],n.splice(i,0,0),push.apply(normal,n);

push.apply(position,position.slice(-9,-3));

push.apply(normal,normal.slice(-9,-3));

for(k=0;k<6;k++)color.push(0.5,0.5,0.5);

};

for(i=0;i<8;i++)for(j=0;j<3;j++){ //角

for(k=0;k<3;k++)

position.push((k==j?a:b)*(i&1<

normal.push(a*(i&1<

color.push(0.5,0.5,0.5);

};

var count=position.length/3,buffers={

position:new ArrayBuffer(position),

normal:new ArrayBuffer(normal),

color:new ArrayBuffer(color)

};

Cube=function(){this.data=Object.create(buffers);};

Cube.prototype={update:updateMvpMatrix,valueOf:function(){return count;}};

})();

//生成操作对象

var cubes=[],ground;

cubes.dimension=3,

cubes.translation=Matrix.model([0,2,0]);

cubes.rotation=Matrix.model([]).pitch(60).yaw(40).pitch(10);

cubes.wMatrix=new Matrix(cubes.rotation).multiply(cubes.translation);

(function(d){

var i,j,k,o,e=(cubes.dimension-1)/2;

for(i=0;i

cubes.push(o=new Cube()),

o.location=[i,j,k],o.rotation=new Matrix(4),

o.translation=[i*2-d+1,j*2-d+1,k*2-d+1],

o.m=Matrix.model(o.translation),

o.data.mMatrix=new Matrix(o.m).multiply(cubes.wMatrix),

o.rotate=function(m,r){

this.location=Matrix.model(this.location).move(-e,-e,-e)[m](r*90).move(e,e,e).slice(-4,-1).map(round);

this.m=Matrix.model(this.translation).multiply(this.rotation[m](r*90));

};

})(cubes.dimension);

(function(i,j,k){

ground={update:updateMvpMatrix,data:{

position:new ArrayBuffer([-i,0,-j, -i,0,j, i,0,-j, i,0,j, -i,0,j, i,0,-j]),

normal:new ArrayBuffer([0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0]),

color:new ArrayBuffer([].concat(k,k,k,k,k,k)),mMatrix:Matrix.model([0,-7,-9])

},valueOf:function(){return 6;}};

})(7,12,[0.5,0.5,0.5]);

//打乱

(function shuffle(c){

var d=cubes.dimension,dir=random()*d|0,m=["pitch","yaw","roll"][dir],

r=random()*3+1|0,cur=random()*d|0,offset=(d-1)/2,group=[],i,o;

for(i=0;o=cubes[i];i++)if(o.location[dir]==cur)group.push(o);

for(i=0;o=group[i];i++)o.rotate(m,r),o.data.mMatrix=new Matrix(o.m).multiply(cubes.wMatrix);

if(c-->0)shuffle(c);

})(30);

//定义矩阵

var vpMatrix=Matrix.view([0,0,32]).multiply(

Matrix.projection(30,canvas.width/canvas.height,0.01,200)

),lVector=[-0,-8,-8],vpShadowerMatrix=Matrix.view( //光

[-lVector[0],-lVector[1],-lVector[2]],

acos(-lVector[2]/pow(pow(lVector[0],2)+pow(lVector[2],2),0.5))/π*180,

-acos(-lVector[2]/pow(pow(lVector[1],2)+pow(lVector[2],2),0.5))/π*180

).multiply(new Matrix(4).data(2,2,-1/32).data(3,3,9).data(3,1,-1.2));

//初始化着色器

var picker=new Program(new VertexShader(pvShader),new FragmentShader(pfShader)).link(),

shadower=new Program(new VertexShader(bvShader),new FragmentShader(bfShader)).link(),

stage=new Program(new VertexShader(svShader),new FragmentShader(sfShader)).link();

stage.use().data({size:[canvas.width,canvas.height],lVector:lVector});

//初始化缓冲区

var frameTexture=new Texture2D(null,"RGBA",512,512).bind(0),

framebuffer=new Framebuffer(new Renderbuffer("DEPTH_COMPONENT16",512,512),frameTexture).unbind();

//播放帧

var active;

this.play(function(){

var i,o,l=cubes.length;

for(i=0;i

ground.update();

if(MBUTTON==null){

framebuffer.bind(),this.clear("COLOR","DEPTH"),picker.use();

for(i=0;o=cubes[i];i++)picker.data(o.data).data({index:(i+1)/l}).draw(o);

active=round(frameTexture.readPixels(MX,512-MY)[0]/0xFF*l-1);

};

framebuffer.bind(),this.clear("COLOR","DEPTH"),shadower.use();

for(i=0;o=cubes[i];i++)shadower.data(o.data).draw(o);

shadower.data(ground.data).draw(ground);

framebuffer.unbind(),this.clear("COLOR","DEPTH"),stage.use();

for(i=0;o=cubes[i];i++)stage.data(o.data).draw(o);

stage.data(ground.data).draw(ground);

}).setting({DEPTH_TEST:"LESS"}).color(0,0,0,1);

//鼠标操作

var MX,MY,MBUTTON;

(function(){

addEventListener("contextmenu",function(e){e.preventDefault();});

addEventListener("mousedown",function(e){MBUTTON=e.button;});

addEventListener("mouseup",function(e){MBUTTON=null;});

addEventListener("mousemove",function(e){MX=e.layerX,MY=e.layerY;});

//元素拖拽

var queue=[],offset=(cubes.dimension-1)/2;

addEventListener("mousedown",function(e){

if(e.button!=0||active<0)return;

var i,j,o,dir,mx=e.clientX,my=e.clientY,mousemove,mouseup,

groups=[[],[],[]],methods=["pitch","yaw","roll"],mpos;

for(i=0;o=cubes[i];i++)for(j=0;j<3;j++)

if(o.location[j]==cubes[active].location[j])groups[j].push(o);

addEventListener("mousemove",mousemove=function(e){

var ndir,group,i,j,o;

mpos=Matrix.model([(e.clientY-my)/2,(e.clientX-mx)/2,0]).multiply(new Matrix(cubes.wMatrix).inverse()).slice(-4,-1);

group=groups[o=mpos.map(abs),ndir=o.indexOf(Math.max.apply(Math,o))];

if(dir!=ndir)for(i=0;i

if(queue[i].indexOf(group[j])>-1)ndir=dir,j=group.length,i=queue.length;

if(dir!=void 0&&dir!=ndir)

for(i=0;o=groups[dir][i];i++)o.data.mMatrix=new Matrix(o.m).multiply(cubes.wMatrix);

if(group=groups[dir=ndir])for(i=0;o=group[i];i++)

o.data.mMatrix=new Matrix(o.m)[methods[dir]](mpos[dir]).multiply(cubes.wMatrix);

}),addEventListener("mouseup",mouseup=function(){

removeEventListener("mousemove",mousemove),removeEventListener("mouseup",mouseup);

var m=methods[dir],r=round(mpos[dir]/90)%4,group=groups[dir],i,o,r;

if(!group)return;

queue.push(group);

for(i=0;o=group[i];i++)o.rotate(m,r);

if(r=mpos[dir]%=90)if(abs(r)>45)r=r<0?90-abs(r):abs(r)-90;

(function callee(){

if(abs(r*=0.7)<0.5)r=0;

for(i=0;o=group[i];i++)o.data.mMatrix=new Matrix(o.m)[m](r).multiply(cubes.wMatrix);

if(r)setTimeout(callee,16);

else queue.splice(queue.indexOf(group),1);

})()

});

});

//控制方向

addEventListener("mousedown",function(e){

if(e.button!=2)return;

var x=e.clientX,y=e.clientY,mousemove,mouseup;

addEventListener("mousemove",mousemove=function(e){

cubes.rotation.yaw((e.clientX-x)/2).pitch((e.clientY-y)/2);

cubes.wMatrix=new Matrix(cubes.rotation).multiply(cubes.translation);

for(var i=0,o;o=cubes[i];i++)o.data.mMatrix=new Matrix(o.m).multiply(cubes.wMatrix);

x=e.clientX,y=e.clientY;

}),addEventListener("mouseup",mouseup=function(e){

removeEventListener("mousemove",mousemove),removeEventListener("mouseup",mouseup);

});

});

})();

});

相关推荐:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值