JS 实战 贪吃蛇游戏

一、css 部分

1. 居中

想要开始和暂停两个按钮居中,可以将盒子设置为弹性盒

也可以使用其他方法

【代码】

2.  将父元素设置为相对定位,偏于之后贪吃蛇长长的身子,是以父元素为基点的绝对定位,通过 left 和 top 来控制位置

二、 JS 部分

(一) 初始化地图

用一个数组,来储存地图上的每一个点

注意:上图红框位置是(0,0)

1. 设置标签

标签不一样,到时候渲染的东西也就不一样

2. 用绝对定位设置初始位置

3. 【代码】

// 蛇相关的配置let snake = {// 蛇的初始位置snakePos:[{ x:0,y:0,domContent:"",flag:'body'},{ x:1,y:0,domContent:"",flag:'body'},{ x:2,y:0,domContent:"",flag:'body'},{ x:3,y:0,domContent:"",flag:'head'}]
}// 初始化游戏方法function initGame(){// 1. 初始化地图for(let i = 0;i < tr; i++){for(let j = 0 ; j < td ; j++){gridData.push({// 给数组里面加对象x:i,y:j})}}

(二)绘制蛇

1. 设置蛇头蛇身

注意:CSS中样式转变到JS中 - 短横线删除变为大写字母

2. 用 append 将创建的元素加到容器上

3. 【代码】

// 绘制蛇的方法
function drawSnake(snake){for(let i = 0;i < snake.snakePos.length;i++){// 判断内容是不是为空,是不是第一次开始if(!snake.snakePos[i].domContent){//如果进入此if,说明是第一次创建蛇snake.snakePos[i].domContent = document.createElement("div")snake.snakePos[i].domContent.style.position = "absolute"snake.snakePos[i].domContent.style.width = snakeBody + "px"snake.snakePos[i].domContent.style.height = snakeBody + "px"snake.snakePos[i].domContent.style.left = snake.snakePos[i].x * snakeBody + "px"snake.snakePos[i].domContent.style.top = snake.snakePos[i].y * snakeBody + "px"if(snake.snakePos[i].flag === 'head'){// 说明当前是蛇头snake.snakePos[i].domContent.style.background = 'url(/img/snake.jpg) center/contain no-repeat'snake.snakePos[i].domContent.style.borderRadius = '50%'snake.snakePos[i].domContent.style.width = snakeBody +5 + "px"snake.snakePos[i].domContent.style.height = snakeBody +5 + "px"}else{//说明是蛇身snake.snakePos[i].domContent.style.background = "rgb(249, 203, 210)";snake.snakePos[i].domContent.style.borderRadius = '50%'snake.snakePos[i].domContent.style.top = snake.snakePos[i].y * snakeBody +3 + "px"}} // 需要将添加的元素加到 container 容器上去document.querySelector(".container").append(snake.snakePos[i].domContent)}
}

(三)绘制食物

1. 随机生成一个坐标

2.【代码】

// 绘制食物function drawFood(){// 1. 食物的坐标是随机的// 2. 食物不能生成在蛇头或者蛇身上while(true){//构成一个死循环,直到生成符合要求的实物坐标才能退出该循环let isRepeat = false  //默认生成的坐标是符合要求的// 随机生成一个坐标(几格)food.x = Math.floor(Math.random() * tr )food.y = Math.floor(Math.random() * tr )// 查看坐标是否符合要求(遍历蛇)for(let i = 0;i<snake.snakePos.length;i++){if(snake.snakePos[i].x === food.x && snake.snakePos[i].y === food.y){// 进入此if,说明当前生成的食物坐标和蛇的坐标冲突了isRepeat = truebreak  //没必要重复了,直接跳出for循环}}if(!isRepeat){//跳出 while 循环break}}// 若跳出了整个 while 循环,那么食物坐标一定是 OK 的// 给他添加食物if(!food.domContent){food.domContent = document.createElement("div")food.domContent.style.width = snakeBody + "px"food.domContent.style.height = snakeBody + "px"food.domContent.style.position = "absolute"food.domContent.style.borderRadius = '50%'food.domContent.style.background = 'url(/img/食物.jpg) center/contain no-repeat'//添加到容器中document.querySelector(".container").append(food.domContent)}//食物的位置food.domContent.style.left = food.x * snakeBody + "px" food.domContent.style.top = food.y * snakeBody + "px" 
}

(四)绑定事件

1. 用户按键盘上的上下左右,对应的字符串

2. 通过计算得到新蛇头的坐标

新的蛇头坐标

注意:把所有snake 都改为 oldHead

按上下左右可以实现移动

     ————>

根据方向转蛇头

是否吃到食物


// 碰撞检测
function isCollide(newHead){let collideCheckInfo = {isCollide : false,  //是否碰到身体或者墙壁isEat : false  // 是否吃到食物}
//   1. 检测是否碰到墙壁
// td 是列,tr 是行
if(newHead.x < 0 || newHead.x >= td || newHead.y < 0 || newHead.y >= tr ){collideCheckInfo.isCollide = truereturn collideCheckInfo
}
//   2. 检测是否碰到身体
// 遍历整个蛇身,检查有没有碰到身体
for(let i = 0; i < snake.snakePos.length; i++){if(snake.snakePos[i].x === newHead.x && snake.snakePos[i].y === newHead.y){collideCheckInfo.isCollide = truereturn collideCheckInfo}
}
//   3. 检测是否吃到食物
if(newHead.x === food.x && newHead.y === food.y){collideCheckInfo.isEat = true
}return collideCheckInfo}

控制用户不能左移动的时候按右,上移动的时候按下

添加定时器,让蛇自己动

(五)bug 修复

点击重新开始之后,暂停键不起作用

可以将两个按钮添加上去

但是,点击按钮不会有相应的反应(它上面没有绑定事件)

可以通过事件委托,将之前添加的事件给到后面的新 dom 元素中

三、总代码

1. HTML

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><link rel="stylesheet" href="/css/index.css"></head>
<body><!-- 整个游戏容器 --><div class="container"><!-- 开始游戏按钮 --><button class="startBtn"></button><!-- 暂停游戏按钮 --><button class="pauseBtn"></button><script src="/js/index.js"></script><script src="/js/config.js"></script></div>
</body>
</html>

2. CSS

*{margin: 0;padding: 0;
}.container{width: 600px;height: 600px;background-color: lightblue;margin: 20px auto;border: 20px solid lightskyblue;/* 想要开始和暂停两个按钮居中,可以将盒子设置为弹性盒 */display: flex;justify-content: center;align-items: center;position: relative;
}/* 按钮公共样式 */
.container button{border: none;outline: none;
}/* 开始按钮 */
/* contain 是铺满整个 */
.startBtn{width: 200px;height: 80px;background: url(/img/开始.png) center/contain no-repeat;display: block;
}/* 暂停按钮 */
.pauseBtn{width: 70px;height: 70px;background: url(/img/暂停.png) center/contain no-repeat;display: none;
}
/* 食物 */
/* snake */

3. JS

// 游戏的相关配置const gridData = []; //储存地图数组// 整个网格的行与列const tr = 30  //行const td = 30  //列// 蛇的身体大小
// 大盒子宽高600 30行 30列 所以每一小格就是 20 ,所以蛇的身体就是 20
const snakeBody = 20// 要明确 
// 我们在确定新的蛇头坐标的时候,会拿下面的对象和旧蛇头做一个计算
// 从而得到新蛇头的坐标
let directionNum = {left:{ x:-1, y: 0 , flag: 'left'},right:{ x:1, y: 0 , flag: 'right'},top:{ x:0, y: -1 , flag: 'top'},bottom:{ x:0, y: 1, flag: 'bottom'}
}// 蛇相关的配置
let snake = {// 蛇一开始移动的方向direction : directionNum.right,   // 一开始向右边移动// 蛇的初始位置snakePos:[{ x:0,y:0,domContent:"",flag:'body'},{ x:1,y:0,domContent:"",flag:'body'},{ x:2,y:0,domContent:"",flag:'body'},{ x:3,y:0,domContent:"",flag:'head'}]
}// 游戏分数
let score = 0// 停止计时器
let timerStop = nullconst time = 200// 食物相关的配置信息
let food= {x:0, y:0, domContent:""  //domContent刚开始是空
}// 配置信息结束// 绘制蛇的方法
function drawSnake(snake){for(let i = 0;i < snake.snakePos.length;i++){// 判断内容是不是为空,是不是第一次开始if(!snake.snakePos[i].domContent){//如果进入此if,说明是第一次创建蛇snake.snakePos[i].domContent = document.createElement("div")snake.snakePos[i].domContent.style.position = "absolute"snake.snakePos[i].domContent.style.width = snakeBody + "px"snake.snakePos[i].domContent.style.height = snakeBody + "px"snake.snakePos[i].domContent.style.left = snake.snakePos[i].x * snakeBody + "px"snake.snakePos[i].domContent.style.top = snake.snakePos[i].y * snakeBody + "px"if(snake.snakePos[i].flag === 'head'){// 说明当前是蛇头snake.snakePos[i].domContent.style.background = 'url(/img/snake.jpg) center/contain no-repeat'snake.snakePos[i].domContent.style.borderRadius = '50%'snake.snakePos[i].domContent.style.width = snakeBody +5 + "px"snake.snakePos[i].domContent.style.height = snakeBody +5 + "px"// 根据方向旋转蛇头switch(snake.direction.flag){case 'top':{snake.snakePos[i].domContent.style.transform = 'rotate(-90deg)'break}case 'bottom':{snake.snakePos[i].domContent.style.transform = 'rotate(90deg)'break}case 'left':{snake.snakePos[i].domContent.style.transform = 'rotate(180deg)'break}case 'right':{snake.snakePos[i].domContent.style.transform = 'rotate(0deg)'break}}}else{//说明是蛇身snake.snakePos[i].domContent.style.background = "rgb(249, 203, 210)";snake.snakePos[i].domContent.style.borderRadius = '50%'snake.snakePos[i].domContent.style.top = snake.snakePos[i].y * snakeBody +3 + "px"}} // 需要将添加的元素加到 container 容器上去document.querySelector(".container").append(snake.snakePos[i].domContent)}
}// 绘制食物function drawFood(){// 1. 食物的坐标是随机的// 2. 食物不能生成在蛇头或者蛇身上while(true){//构成一个死循环,直到生成符合要求的实物坐标才能退出该循环let isRepeat = false  //默认生成的坐标是符合要求的// 随机生成一个坐标(几格)food.x = Math.floor(Math.random() * tr )food.y = Math.floor(Math.random() * tr )// 查看坐标是否符合要求(遍历蛇)for(let i = 0;i<snake.snakePos.length;i++){if(snake.snakePos[i].x === food.x && snake.snakePos[i].y === food.y){// 进入此if,说明当前生成的食物坐标和蛇的坐标冲突了isRepeat = truebreak  //没必要重复了,直接跳出for循环}}if(!isRepeat){//跳出 while 循环break}}// 若跳出了整个 while 循环,那么食物坐标一定是 OK 的// 给他添加食物if(!food.domContent){food.domContent = document.createElement("div")food.domContent.style.width = snakeBody +5 + "px"food.domContent.style.height = snakeBody +5 + "px"food.domContent.style.position = "absolute"food.domContent.style.borderRadius = '50%'food.domContent.style.background = 'url(/img/食物.jpg) center/contain no-repeat'//添加到容器中document.querySelector(".container").append(food.domContent)}//食物的位置food.domContent.style.left = food.x * snakeBody + "px" food.domContent.style.top = food.y * snakeBody + "px" 
}// 初始化游戏方法function initGame(){// 1. 初始化地图for(let i = 0;i < tr; i++){for(let j = 0 ; j < td ; j++){gridData.push({// 给数组里面加对象x:i,y:j})}}// 2. 绘制蛇drawSnake(snake);  //将snake传进去,调用 drawSnake函数// 3. 绘制食物drawFood(snake);}// 绑定事件
function bindEvent(){//  1. 首先键盘事件,用户按上下左右,蛇能移动document.onkeydown = function(e){if((e.key === "ArrowUp" || e.key.toLocaleLowerCase() === "w") && snake.direction.flag !== "bottom"){// 用户按的是上snake.direction = directionNum.top}if((e.key === "ArrowDown" || e.key.toLocaleLowerCase() === "s") && snake.direction.flag !== "top"){// 用户按的是下snake.direction = directionNum.bottom}if((e.key === "ArrowLeft" || e.key.toLocaleLowerCase() === "a") && snake.direction.flag !== "right"){// 用户按的是左snake.direction = directionNum.left}if((e.key === "ArrowRight" || e.key.toLocaleLowerCase() === "d") && snake.direction.flag !== "left"){// 用户按的是右snake.direction = directionNum.right}}// 2. 计时器自动调用,蛇移动的方法startGame() // 3. 点击整个容器的时候,可以暂停游戏和重新开始游戏document.querySelector('.container').onclick = function(e){// 这边通过事件委托的形式,判断用户酒精点击的是 container 容器,还是暂停按钮或者开始按钮// 从而做出不同的处理// 用一个类名判断,点击的是暂停按钮,还是重新开始按钮if(e.target.className === 'container'){// 那么要做的是暂停操作document.querySelector('.pauseBtn').style.display = 'block'clearInterval(timerStop)}else{// 那么要做的是恢复游戏操作document.querySelector('.pauseBtn').style.display = 'none'startGame()}}}// 自动调用蛇移动
function startGame(){timerStop = setInterval(function(){snakeMove()},time)
}// 蛇的移动方法
function snakeMove(){let oldHead = snake.snakePos[snake.snakePos.length - 1]//  根据方向计算出新的蛇头坐标let newHead = {domContent:"",x : oldHead.x + snake.direction.x,y : oldHead.y + snake.direction.y,flag : 'head'}// 接下来我们首先要做碰撞检测// 看计算出来的新的蛇头有没有碰上食物,蛇的身体,墙壁let collideCheckResult = isCollide(newHead)if(collideCheckResult.isCollide){// 进入这个 if 说明碰撞了if( window.confirm(`哦呦~ gameover~ 笨蛋凯凯当前的分数是${score}分,啵我一口,允许你再来一次~ 嘿嘿`)){// 重新开始游戏//重置内容document.querySelector(".container").innerHTML = `<!-- 开始游戏按钮 --><button class="startBtn" style="display:none"></button><!-- 暂停游戏按钮 --><button class="pauseBtn" style="display:none"></button>`score = 0 // 蛇的初始位置snake = {// 蛇一开始移动的方向direction : directionNum.right,   // 一开始向右边移动// 蛇的初始位置snakePos:[{ x:0,y:0,domContent:"",flag:'body'},{ x:1,y:0,domContent:"",flag:'body'},{ x:2,y:0,domContent:"",flag:'body'},{ x:3,y:0,domContent:"",flag:'head'}]}food = {x:0,y:0,domContent:""}// 再次调用initGameinitGame()}else{// 结束游戏// 把绑定的事件删除document.onkeydown = null;// 关闭定时器clearInterval(timerStop)}return  //结束 snakeMove 函数}// 将旧的头修改为身体oldHead.flag = 'body'oldHead.domContent.style.background = "rgb(249, 203, 210)" oldHead.domContent.style.borderRadius = '50%'// 将蛇头大小改为蛇身大小,并且垂直居中oldHead.domContent.style.width = snakeBody + "px"oldHead.domContent.style.height = snakeBody + "px"oldHead.domContent.style.top = oldHead.y * snakeBody +3 + "px"// 判断是否吃到食物
if(collideCheckResult.isEat){// 吃到食物了,重新生成新食物drawFood()
}else{// 进入这里,说明没有吃到食物// 那么移除最后一个元素document.querySelector(".container").removeChild(snake.snakePos[0].domContent)// 把最后一个元素从数组中删除,即删除第一个数组snake.snakePos.shift()
}//  把新蛇头加进去snake.snakePos.push(newHead)// 重新绘制蛇drawSnake(snake)
}// 碰撞检测
function isCollide(newHead){let collideCheckInfo = {isCollide : false,  //是否碰到身体或者墙壁isEat : false  // 是否吃到食物}
//   1. 检测是否碰到墙壁
// td 是列,tr 是行
if(newHead.x < 0 || newHead.x >= td || newHead.y < 0 || newHead.y >= tr ){collideCheckInfo.isCollide = truereturn collideCheckInfo
}
//   2. 检测是否碰到身体
// 遍历整个蛇身,检查有没有碰到身体
for(let i = 0; i < snake.snakePos.length; i++){if(snake.snakePos[i].x === newHead.x && snake.snakePos[i].y === newHead.y){collideCheckInfo.isCollide = truereturn collideCheckInfo}
}
//   3. 检测是否吃到食物
if(newHead.x === food.x && newHead.y === food.y){collideCheckInfo.isEat = truescore++  //分数自增
}return collideCheckInfo}// 游戏的主方法
function main() {// 用户点击了开始游戏之后,再做后续的工作document.querySelector('.startBtn').onclick = function(e){// 取消冒泡e.stopPropagation()document.querySelector('.startBtn').style.display = 'none'// 1. 第一步 初始化游戏initGame(); //调用初始化游戏方法// 2. 绑定事件bindEvent();
}
}
main(); //调用游戏的主方法

好啦!本次的分享到这里就结束啦!大家快去练练这个小游戏吧~

我们下次不见不散哦 !!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/13841.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

富甲美国---沃尔玛创始人山姆·沃尔顿

富甲美国---沃尔玛创始人山姆沃尔顿_山姆沃尔顿是犹太人吗?-CSDN博客文章浏览阅读786次。​1.不断地检讨回顾我们做得好不好或需要改进的&#xff0c;我们从没有对现况满足过。我们会短暂地大肆庆祝成功&#xff0c;然后认真地检讨下次如何能做得更好---不断改进与创新。2我们…

数据挖掘导致直接路径读(direct path read)耗尽了IO

一大早就有喊业务卡的&#xff0c;检查等待事件源头&#xff0c;均为oracle写等待 查看IO负载持续维持在100%繁忙 后台有两个并行rman备份在&#xff0c;停止备份io繁忙没有好转&#xff0c;检查最近ash报告&#xff0c;发现DDTEK ODBC Oracle程序模块占用最高 检查该模块&…

阿里云、百度云和移动云的对象存储横向性能对比

文章目录 前言一、对比测试的方法和标准A. 测试环境的设置 二、对比测试的结果A、阿里云OSS测试结果2.B. 百度云结果C. 移动云结果分析与结论 总结 前言 在企业的数字化转型进程中&#xff0c;我们观察到越来越多的公司将其IT基础设施迁移到云端。随着企业业务的持续运营&…

音视频安卓主板记录仪手持终端定制开发_基于MT6762平台解决方案

音视频安卓主板采用了基于MT6762高性能处理器芯片的设计&#xff0c;其中包括4个主频高达2.0GHz的Cortex-A53核心和4个主频1.5GHz的Cortex-A53高效聚焦核心&#xff0c;可提供无比流畅的体验。搭载Android 12操作系统&#xff0c;系统版本进行了全新的优化&#xff0c;进一步确…

linux 错误记录(三)

这里的内核源码路径&#xff1a; cd /usr/src/linux-headers-5.4.0-150-generic/ 内核版本&#xff1a; $ uname -r 5.4.0-150-generic 错误现象 ./include/uapi/asm-generic/int-ll64.h:12:10: fatal error: asm/bitsperlong.h: No such file or directory 搜索后是有的 …

向上调整建堆与向下调整建堆的时间复杂度 AND TopK问题

目录 前言建堆的时间复杂度TOPK问题总结 前言 本篇旨在介绍使用向上调整建堆与向下调整建堆的时间复杂度. 以及topk问题 博客主页: 酷酷学!!! 感谢关注~ 建堆的时间复杂度 堆排序是一种优于冒泡排序的算法, 那么在进行堆排序之前, 我们需要先创建堆, 为什么说堆排序的是优于…

Backend - postgresSQL DB 存储过程(数据库存储过程)

目录 一、存储过程的特性 &#xff08;一&#xff09;作用 &#xff08;二&#xff09;特点 &#xff08;三&#xff09;编码结构的区别 二、定时执行存储过程 三、2种编码结构 &#xff08;一&#xff09;函数结构 1. SQL代码 2. 举例 &#xff08;1&#xff09;例1-循…

考场作弊行为自动抓拍分析系统

考场作弊行为自动抓拍分析系统采用了AI神经网络和深度学习算法&#xff0c;考场作弊行为自动抓拍分析系统通过人形检测和骨架勾勒等技术&#xff0c;实时计算判断考生的异常动作行为。通过肢体动作识别技术&#xff0c;系统可以详细分析考生的头部和手部肢体动作&#xff0c;进…

如何提高学习思考能力

目录 前言第一章、学习能力1.1)学习能力介绍1.1.1 感知能力与提升1.1.2 想象能力与提升1.1.3 理解能力与提升1.1.4 逻辑能力与提升1.1.5 记忆能力与提升1.1.6 专注能力与提升1.1.7 自控能力与提升1.2)学习能力提升总结1.3.1 走出舒适区1.3.2 积极的环境1.3.3 情绪影响1.3.4 身…

乡村振兴的乡村旅游新模式:挖掘乡村旅游资源,创新旅游开发方式,打造乡村旅游新品牌,助力美丽乡村建设

目录 一、引言 二、乡村旅游资源挖掘 1、自然景观资源 2、人文历史资源 3、农业产业资源 三、旅游开发方式创新 1、多元化旅游产品 2、体验式旅游模式 3、智慧旅游建设 四、乡村旅游新品牌打造 1、品牌定位与策划 2、品牌传播与推广 3、品牌维护与提升 五、助力美…

当代家庭教育杂志社《当代家庭教育》杂志社24年第6期目录

家庭教育资讯 《家庭教育蓝皮书2024:中国家庭养育环境报告》出炉 4 2024年4月至7月北京市将开展“双减”专项行动 5 小学生玩“烟卡”到底该不该禁&#xff1f; 5 家庭教育理论探索 新时代家长家庭教育素养&#xff1a;意涵、关键要素及其培育 周起煌; 6-10 …

【游戏】数30必胜玩法

游戏规则 规则&#xff1a;参与人数 2 2 2人&#xff0c;轮流交替数依次递增 1 1 1数数&#xff0c;最少数 1 1 1个数&#xff0c;最多数 n n n个数&#xff0c;数到 30 30 30的人为输家&#xff01; x { N 1 P 1 m ( 30 − 1 ) ( m o d ( n 1 ) ) if m 1 N m P 2 m P…

头歌03- 01背包

""" 题目&#xff1a;有n个重量分别为w{w_1,w_2,…,w_n}的物品&#xff0c;他们的价值分别为v{v_1,v_2,…,v_n}&#xff0c;给定一个容量为V的背包。 设计从这些物品中选取一部分物品放入该背包的方案&#xff0c;每个物品要么选中要么不选中&#xff0c;要求选…

轻松上手ClickHouse:ClickHouse入门

引言 在数字化时代&#xff0c;大数据处理和分析已经成为了各行各业不可或缺的一环。而ClickHouse&#xff0c;作为一款高性能的列式数据库管理系统&#xff0c;以其卓越的查询性能和灵活的扩展性&#xff0c;赢得了众多企业和开发者的青睐。本文将带领大家走进ClickHouse的世…

CCF-GESP 等级考试 2023年12月认证C++一级真题

2023年12月真题 一、单选题&#xff08;每题2分&#xff0c;共30分&#xff09; 第 1 题 以下C不可以作为变量的名称的是( )。 A. CCF GESPB. ccfGESPC. CCFgespD. CCF_GESP 第 2 题 C表达式10 - 3 * (2 1) % 10的值是( )。 A. 0B. 1C. 2D. 3 第 3 题 假设现在是上午⼗点&…

Python基础学习笔记(四)——运算符

目录 算术运算符1. 四则运算2. 整除3. 取模4. 求幂 赋值运算符1. 链式赋值2. 参数赋值3. 系列解包赋值 关系运算符身份运算符成员运算符逻辑运算符位运算符1. 按位运算2. 移位运算 优先级 算术运算符 1. 四则运算 # 加减乘除:除法结果为浮点数 print(12, 1-2, 1*2, 2/1)3 -1 …

Kubernetes常用命令

目录 一.资源管理办法 1.陈述式资源管理方法 &#xff08;1&#xff09;kubernetes 集群管理集群资源的唯一入口是通过相应的方法调用 apiserver 的接口 &#xff08;2&#xff09;kubectl 是官方的CLI命令行工具&#xff0c;用于与 apiserver 进行通信&#xff0c;将用户在…

VC++学习(3)——认识MFC框架,新建项目,添加按钮

目录 引出第三讲 MFC框架新建项目Windows搜索【包含内容的搜索】如何加按钮添加成员变量添加成功 添加按钮2杂项 总结 引出 VC学习&#xff08;3&#xff09;——认识MFC框架&#xff0c;新建项目&#xff0c;添加按钮 MFC(Microsoft Foundation Classes)&#xff0c;是微软公…

零基础小白撸空投攻略:空投流程是什么样的? 如何操作?

在Web3的世界中&#xff0c;空投&#xff08;Airdrop&#xff09;是一种常见的营销和推广策略&#xff0c;通过向特定用户群体免费分发代币&#xff0c;项目方希望能够吸引更多的用户和关注。对于许多刚刚接触加密货币和区块链的新手来说&#xff0c;都会疑惑空投的流程究竟是什…

AI - GPT-4o是什么?

一、定义&#xff1a; GPT-4o是OpenAI推出的最新旗舰级人工智能模型&#xff0c;它是GPT系列的一个重要升级&#xff0c;其中的"o"代表"Omni"&#xff0c;中文意思是“全能”&#xff0c;凸显了其多功能特性。该模型被设计为能够实时对音频、视觉和文本进…