通过第一阶段所学的知识实现贪吃蛇游戏
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="../lib/index.js"></script>
<style>
* {
margin: 0;
padding: 0;
}
canvas{
margin: 50px auto 0;
display: block;
background: yellow;
}
</style>
</head>
<body>
<canvas id="canvas" width="400" height="400">
此浏览器不支持canvas
</canvas>
</body>
</html>
<script>
const ctx = document.getElementById('canvas')
const gl = ctx.getContext('webgl')
// 创建着色器源码
const VERTEX_SHADER_SOURCE = `
// 只传递顶点数据
attribute vec4 aPosition;
void main() {
gl_Position = aPosition; // vec4(0.0,0.0,0.0,1.0)
gl_PointSize = 15.0;
}
`; // 顶点着色器
const FRAGMENT_SHADER_SOURCE = `
void main() {
gl_FragColor = vec4(1.0,0.0,0.0,1.0);
}
`; // 片元着色器
const program = initShader(gl, VERTEX_SHADER_SOURCE, FRAGMENT_SHADER_SOURCE)
const aPosition = gl.getAttribLocation(program, 'aPosition');
// 蛇身的长度
let points = [
{x: 0, y: 0},
]
// 食物的坐标
const random = {
isConnect: true
}
// 移动的速度
let originSpeed = 0.02;
// 行动的速度
let speed = originSpeed;
// 移动的方向
let direction = 'x';
// 允许吃掉食物的误差范围
let base = 1.5;
document.onkeydown = (event) => {
switch (event.keyCode) {
case 37:
direction = 'x';
speed = -originSpeed
break;
case 38:
direction = 'y';
speed = originSpeed;
break;
case 39:
direction = 'x';
speed = originSpeed;
break;
case 40:
direction = 'y';
speed = -originSpeed;
break;
}
}
function createRandom() {
if (random.isConnect) {
random.x = Math.random() * 2 - 1;
random.y = Math.random() * 2 - 1;
random.isConnect = false;
}
}
function draw() {
gl.vertexAttrib3f(aPosition, random.x, random.y, 0.0);
gl.drawArrays(gl.POINTS, 0, 1);
let prex = 0;
let prey = 0;
for (let i = 0; i < points.length; i++) {
if (i === 0) {
prex = points[0].x
prey = points[0].y
points[0][direction] += speed;
} else {
let {x, y} = points[i]
points[i].x = prex
points[i].y = prey
prex = x;
prey = y;
}
gl.vertexAttrib3f(aPosition, points[i].x, points[i].y, 0.0);
gl.drawArrays(gl.POINTS, 0, 1);
}
}
let timer = null
function start() {
timer = setInterval(() => {
// 边界判断
if (
points[0].x > 1.0 ||
points[0].x < -1.0 ||
points[0].y < -1.0 ||
points[0].y > 1.0
) {
alert('游戏结束');
restart();
}
if (
points[0].x > random.x - base * originSpeed &&
points[0].x < random.x + base * originSpeed &&
points[0].y < random.y + base * originSpeed &&
points[0].y > random.y - base * originSpeed
) {
points.push({ x: random.x, y: random.y })
random.isConnect = true;
}
createRandom();
draw();
}, 100)
}
start();
function restart() {
clearInterval(timer)
points = [
{x: 0, y: 0}
]
direction = 'x'
speed = originSpeed
start();
}
</script>
效果图
代码中的initShader方法是自己封装好的方法
请参考https://blog.csdn.net/qq_45013951/article/details/134637108
下面是WebGL+Three.js入门与实战的总体链接
1.1 绘制一个点
1.2 webgl坐标系
1.3 学习使用attribute变量-绘制一个水平移动的点
1.4 通过鼠标控制绘制
1.5 修改点的颜色
1.6 实现贪吃蛇游戏
2.1 使用缓冲区对象-绘制多个点