方块幻域 手机版
by NeonRanger53111 lines3.0 KB
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>方块幻域 手机版</title>
<style>
*{margin:0;padding:0}
body{overflow:hidden;background:#87CEFA}
canvas{display:block}
#tip{position:absolute;color:#fff;top:10px;left:10px;font-size:18px;text-shadow:1px 1px 2px #000}
</style>
</head>
<body>
<div id="tip">触屏操控:滑动转动视角,点击方块挖掘 / 放置方块</div>
<script>
// 简易3D方块世界,webgl,手机浏览器直接打开
const canvas = document.createElement('canvas');
document.body.appendChild(canvas);
const gl = canvas.getContext('webgl');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
// 方块颜色
const GRASS = [0.37,0.62,0.21];
// 简单顶点着色器、片元着色器
const vsSource = `
attribute vec3 aPosition;
attribute vec3 aColor;
uniform mat4 uMvp;
varying vec3 vColor;
void main(){
gl_Position = uMvp * vec4(aPosition,1.0);
vColor = aColor;
}`;
const fsSource = `
precision mediump float;
varying vec3 vColor;
void main(){
gl_FragColor = vec4(vColor,1.0);
}`;
function createShader(gl,type,src){
const shader = gl.createShader(type);
gl.shaderSource(shader,src);
gl.compileShader(shader);
return shader;
}
const vs = createShader(gl,gl.VERTEX_SHADER,vsSource);
const fs = createShader(gl,gl.FRAGMENT_SHADER,fsSource);
const program = gl.createProgram();
gl.attachShader(program,vs);
gl.attachShader(program,fs);
gl.linkProgram(program);
gl.useProgram(program);
// 生成地面方块顶点(简化版本)
const vertices = [];
function addCube(x,y,z,color){
const s = 0.5;
// 简化只画顶面
vertices.push(x-s,y+s,z+s, ...color);
vertices.push(x+s,y+s,z+s, ...color);
vertices.push(x+s,y+s,z-s, ...color);
vertices.push(x-s,y+s,z+s, ...color);
vertices.push(x+s,y+s,z-s, ...color);
vertices.push(x-s,y+s,z-s, ...color);
}
// 生成一片平地
for(let x = -8;x<=8;x++){
for(let z = -8;z<=8;z++){
addCube(x,0,z,GRASS);
}
}
const buf = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER,buf);
gl.bufferData(gl.ARRAY_BUFFER,new Float32Array(vertices),gl.STATIC_DRAW);
const aPos = gl.getAttribLocation(program,'aPosition');
const aCol = gl.getAttribLocation(program,'aColor');
gl.enableVertexAttribArray(aPos);
gl.enableVertexAttribArray(aCol);
gl.vertexAttribPointer(aPos,3,gl.FLOAT,false,24,0);
gl.vertexAttribPointer(aCol,3,gl.FLOAT,false,24,12);
// 透视矩阵(简化)
function mat4Perspective(fov,aspect,near,far){
const f = 1/Math.tan(fov/2);
const nf = 1/(near-far);
return new Float32Array([
f/aspect,0,0,0,
0,f,0,0,
0,0,(far+near)*nf,-1,
0,0,2*far*near*nf,0
]);
}
const mvp = mat4Perspective(Math.PI/3,canvas.width/canvas.height,0.1,100);
const uMvpLoc = gl.getUniformLocation(program,"uMvp");
gl.uniformMatrix4fv(uMvpLoc,false,mvp);
gl.clearColor(0.53,0.81,0.98,1);
function render(){
gl.clear(gl.COLOR_BUFFER_BIT);
gl.drawArrays(gl.TRIANGLES,0,vertices.length/6);
requestAnimationFrame(render);
}
render();
</script>
</body>
</html>
Game Source: 方块幻域 手机版
Creator: NeonRanger53
Libraries: none
Complexity: moderate (111 lines, 3.0 KB)
The full source code is displayed above on this page.
Remix Instructions
To remix this game, copy the source code above and modify it. Add a ARCADELAB header at the top with "remix_of: game-neonranger53" to link back to the original. Then publish at arcadelab.ai/publish.