【愚公系列】2023年12月 WEBGL专题-贪吃蛇游戏
🏆 作者简介,愚公搬代码
🏆《头衔》:华为云特约编辑,华为云云享专家,华为开发者专家,华为产品云测专家,CSDN博客专家,CSDN商业化专家,阿里云专家博主,阿里云签约作者,腾讯云优秀博主,腾讯云内容共创官,掘金优秀博主,51CTO博客专家等。
🏆《近期荣誉》:2023年华为云十佳博主,2022年CSDN博客之星TOP2,2022年华为云十佳博主等。
🏆《博客内容》:.NET、Java、Python、Go、Node、前端、IOS、Android、鸿蒙、Linux、物联网、网络安全、大数据、人工智能、U3D游戏、小程序等相关领域知识。
🏆🎉欢迎 👍点赞✍评论⭐收藏
🚀前言
贪吃蛇游戏是一种经典的电子游戏,玩家需要控制一条蛇去吃各种食物,使之变得越来越长,并避免撞到自己的身体或墙壁。随着吃到的食物越来越多,蛇的速度也会加快,玩家需要不断调整蛇的方向来避免失败。贪吃蛇游戏可以在电脑、手机、游戏机等不同平台上玩,是一款简单而又有趣的休闲游戏。
🚀一、贪吃蛇游戏
好的,以下是一个完整的WebGL贪吃蛇游戏的实现。在这个实现中,我们将使用键盘控制蛇的移动,并让蛇吃到食物时变长。
HTML代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<style>
html,body{
height: 100%;
margin: 0;
text-align: center;
}
canvas{
width: 600px;
height: 600px;
margin-top: 100px;
background-color: aqua;
}
</style>
<body>
<canvas></canvas>
<div>
<button id="start">开始</button>
<button id="stop">暂停</button>
</div>
</body>
</html>
JavaScript代码:
<script>
const canvas = document.querySelector('canvas');
const gl = canvas.getContext('webgl');
// 顶点着色器源码
const vertexShaderSource = `
attribute vec4 aPostion;
void main(){
gl_Position = aPostion;
gl_PointSize = 5.0;
}
`
// 片元着色器源码
const fragmentShaderSource = `
void main(){
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
`
// 初始化着色器
function initShader(gl,vertexShaderSource,fragmentShaderSource){
// 创建顶点着色器
const vertexShader = gl.createShader(gl.VERTEX_SHADER);
// 创建片元着色器
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
// 为着色器添加源码
gl.shaderSource(vertexShader, vertexShaderSource);
gl.shaderSource(fragmentShader, fragmentShaderSource);
// 编译着色器
gl.compileShader(vertexShader);
gl.compileShader(fragmentShader);
// 创建程序
const program = gl.createProgram();
// 为程序添加着色器
gl.attachShader(program,vertexShader);
gl.attachShader(program,fragmentShader);
// 建立联系
gl.linkProgram(program);
// 使用程序
gl.useProgram(program);
return program;
}
const program = initShader(gl,vertexShaderSource,fragmentShaderSource);
// 获取attribute参数
const aPostion = gl.getAttribLocation(program,'aPostion');
// 蛇
const points = [{x:0,y:0}];
// 当前的点
const point = {
isConnect:true
}
const ERROR_SIZE = 0.03;
const BASE_STEP = 0.03;
// 每步走多少
let step = BASE_STEP;
// 方向
let direction = 'x';
let timer = null;
// 生成点
const createPoint = () => {
if(point.isConnect){
point.x = Math.random()*2 - 1;
point.y = Math.random()*2 - 1;
point.isConnect = false;
}
}
document.onkeydown = e => {
switch(e.keyCode){
case 37:
direction = 'x';
step = -1 * BASE_STEP;
break;
case 38:
direction = 'y';
step = BASE_STEP;
break;
case 39:
direction = 'x';
step = BASE_STEP;
break;
case 40:
direction = 'y';
step = -1 * BASE_STEP;
break;
}
}
const draw = () => {
// 绘制食物
gl.vertexAttrib4f(aPostion,point.x,point.y,0.0,1.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] += step;
}else{
const { x, y } = points[i];
points[i].x = prex;
points[i].y = prey;
prex = x;
prey = y;
}
// 画蛇
gl.vertexAttrib4f(aPostion,points[i].x,points[i].y,0.0,1.0);
gl.drawArrays(gl.POINTS,0,1);
}
}
// 开始
const start = () => {
createPoint();
// 需要让蛇动起来
timer = setInterval(()=>{
if(points[0].x > 1.0 ||
points[0].x < -1.0 ||
points[0].y > 1.0 ||
points[0].y < -1.0
){
// 游戏结束
alert('游戏结束')
reast();
return ;
}
// 如果在误差范围内则命中
if(points[0].x < point.x + ERROR_SIZE &&
points[0].x > point.x - ERROR_SIZE &&
points[0].y < point.y + ERROR_SIZE &&
points[0].y > point.y - ERROR_SIZE
){
points.push({x:point.x,y:point.y});
point.isConnect = true;
createPoint();
}
// 需要去绘制
draw()
},100)
}
// 重置
const reast = () => {
timer && clearInterval(timer);
points = [{x:0,y:0}];
point = {
isConnect:true
}
step = BASE_STEP;
direction = 'x';
}
document.querySelector('#start').addEventListener('click',()=>{
start();
})
document.querySelector('#stop').addEventListener('click',()=>{
timer && clearInterval(timer);
})
</script>
在这个实现中,我们添加了一个食物对象,并在每个更新周期检查蛇是否吃到了食物。如果蛇吃到了食物,我们就让蛇变长,并在一个新的位置生成一个新的食物。
我们还添加了一个事件监听器,以便在按下箭头键时改变蛇的方向。
🚀感谢:给读者的一封信
亲爱的读者,
我在这篇文章中投入了大量的心血和时间,希望为您提供有价值的内容。这篇文章包含了深入的研究和个人经验,我相信这些信息对您非常有帮助。
如果您觉得这篇文章对您有所帮助,我诚恳地请求您考虑赞赏1元钱的支持。这个金额不会对您的财务状况造成负担,但它会对我继续创作高质量的内容产生积极的影响。
我之所以写这篇文章,是因为我热爱分享有用的知识和见解。您的支持将帮助我继续这个使命,也鼓励我花更多的时间和精力创作更多有价值的内容。
如果您愿意支持我的创作,请扫描下面二维码,您的支持将不胜感激。同时,如果您有任何反馈或建议,也欢迎与我分享。
再次感谢您的阅读和支持!
最诚挚的问候, “愚公搬代码”
- 点赞
- 收藏
- 关注作者
评论(0)