用js代码实现贪吃蛇小游戏

news2024/9/23 0:34:35

js已经学了大部分了,现在就利用我所学的js知识试试做贪吃蛇小游戏吧

以下部分相关图片以及思路笔记均出自渡一陈老师的视频

首先制作简单的静态页面,添加贪吃蛇移动的背景和相关图片,比如开始游戏等等

将各个功能均封装在函数中,利用主函数调用分函数会使结构更清晰

初始化游戏

初始化地图

地图坐标

 

  //1.初始化地图
  for(let i=0;i<tr;i++){
    for(let j=0;j<td;j++){
      gridData.push({
        x:j,
        y:i
      })
    }
  }

绘制蛇

  • 在游戏相关配置文件(js文件)中定义蛇的身体大小,以及蛇的相关位置信息(位置坐标,对应身体还是头部标志,身体元素相关元素标签)
  • 在index.js文件中遍历snake的位置信息,若domContent(身体元素相关元素标签)为空,就添加元素标签,给标签设置定位,并设置每个元素的left和top为身体大小*x或者*y,并且判断身体元素是蛇头还是身体,是蛇头就添加蛇头的背景,是身体就添加背景颜色并设置圆角边框
  • 判断是否第一次创建蛇后,在容器中append创建的元素
// 蛇的身体大小
let snakeBody=20
// 蛇相关的配置信息
let snake={
  // 蛇的初始位置
  snakePos:[//domContent为蛇的相应dom元素 flag根据身体还是蛇头分别渲染
    {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'}
  ]
}
/**
 *绘制蛇的方法
 *  @param {*} snake
 * */
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("../images/snake.png") center/contain no-repeat`
      }else{
        // 说明是蛇身
        snake.snakePos[i].domContent.style.background="#9ddbb1"
        snake.snakePos[i].domContent.style.borderRadius='50%'
      }
    }
    // 需要将创建的DOM元素添加到container 容器上面
    document.querySelector(".container").append(snake.snakePos[i].domContent)
  }
}

添加几个蛇身后效果如图所示:

绘制食物

  • 其过程和绘制蛇过程基本类似,先在配置文件中声明食物的相关配置信息,食物对象中不需要标志元素
  • 要求食物不可出现在蛇头蛇身以及container外面区域,生成随机数在while中循环无限循环,直到坐标符合条件退出循环,利用一个变量判断是否需要退出循环
  • 生成正确的坐标后,就创建一个新的变量,设置绝对定位,宽高,背景,最后append到container中,当然,要先判断food.domContent是否为空,为空才可创建,创建之后只是改变食物的位置,不会再继续创建元素,故设置食物的elft和top要在判断条件外执行
// 整个网格的行与列
const tr=30
const td=30// 食物相关的配置信息
let food={
  x:0,y:0,domContent:""
}function drawFood(){
  // 食物的坐标是随机的 但食物不可生成在蛇头 蛇身 以及container之外的区域
  while(true){
    // 构成一个死循环,直到生成符合要求的坐标才能退出该循环
    let isRepeat=false //默认生成的坐标符合要求
    // 随机生成一个坐标
    food.x=Math.floor(Math.random()*tr)
    food.y=Math.floor(Math.random()*td)
    // 查看坐标是否符合要求(遍历蛇)
    for(let i=0;i<snake.snakePos.length;i++){
      if(snake.snakePos[i].x===food.x&&snake.snakePos[i].y===food.y){
        // 进入此if 说明当前生成的食物坐标和蛇的位置冲突
        isRepeat=true
        break
      }
     
    }
    if(!isRepeat){
      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.background=`url("../images/food.png") 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"
}

绑定事件

  • 按下键盘的上下左右时,蛇会上下左右移动,此时要添加相关配置信息,明确新蛇头和旧蛇头之间的位置关系,在确定新的蛇头坐标时,会用一个对象和旧蛇头进行计算
  • 绑定事件keydown
  • 同时在蛇的相关配置信息中添加方向
// 要明确新的蛇头和旧的蛇头之间的位置关系
// 我们在确定新的蛇头坐标的时候,会那下面的对象和旧蛇头做一个计算

const 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:[//domContent为蛇的相应dom元素 flag根据身体还是蛇头分别渲染
    {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 bindEvent(){
  document.addEventListener('keydown',function(e){
    // console.log(e.key)
    if(e.key==='ArrowUp'||e.key.toLocaleLowerCase()==='w'){
      // 用户按的是上
      snake.direction=directionNum.top
    }
    if(e.key==='ArrowDown'||e.key.toLocaleLowerCase()==='s'){
      // 用户按的是下
      snake.direction=directionNum.bottom

    }
    if(e.key==='ArrowLeft'||e.key.toLocaleLowerCase()==='a'){
      // 用户按的是左
      snake.direction=directionNum.left

    }
    if(e.key==='ArrowRight'||e.key.toLocaleLowerCase()==='d'){
      // 用户按的是右
      snake.direction=directionNum.right

    }
    snakeMove()
  })
}

移动蛇

  • 声明一个新蛇头,新蛇头对象中包含snakePos中的所有,移动时要将新蛇头添加至snake.snakePos中,将旧蛇头变为蛇身,即把flag变为body,并将其相关属性变为身体的属性,最后重新绘制蛇即可
  • 注意,蛇头会随着方向的变化而变化,在drawSnack中添加switch,若方向为上,蛇头逆时针旋转90deg,其余以此类推
  • 碰撞检测:声明一个判断对象,里面包含两个判断,一个为是否吃到食物,一个判断是否碰撞墙壁或者碰到蛇身
  • 碰到墙壁即为新蛇头的位置坐标越界,碰到蛇身即为判断新蛇头是否和蛇身位置坐标冲突,冲突就说明碰到自己,吃到东西则为新蛇头的坐标和食物的坐标一致,吃到食物之后就重新生成食物的位置坐标
  • 蛇整体移动的过程为:每次触发键盘事件,蛇头改变,旧蛇头变为蛇身,若吃到苹果,不删除最后一个蛇身,若没有吃到苹果,则删除最后一个蛇身,即为snake.snakePos[0].domContent。
/***
 * 碰撞检测
 */
function isCollide(newHead){
  let collideCheckInfo={
    isCollide:false,//是否碰撞墙壁 蛇身
    isEat:false//是否吃到食物
  }
  // 1.检测是否碰到墙壁
  if(newHead.x<0||newHead.x>=td||newHead.y<0||newHead.y>=tr){
    collideCheckInfo.isCollide=true
    return collideCheckInfo
  }
  // 检测是是否碰到自己
  for(let i=0;i<snake.snakePos.length;i++){
    if(snake.snakePos[i].x===newHead.x&&snake.snakePos[i].y===newHead.y){
      collideCheckInfo.isCollide=true
      return collideCheckInfo
    }
  }
  // 检测是否吃到东西
  if(newHead.x===food.x&&newHead.y===food.y){
    collideCheckInfo.isEat=true
    score++
  }
  return collideCheckInfo
}

/**
 * 蛇的移动方法
 */
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 说明撞墙了
    window.confirm(`游戏结束,您当前的得分为${score}分,是否要重新开始游戏`)
    alert("撞墙了")
  }
  // 将旧的头修改为身体
  oldHead.flag='body'
  oldHead.domContent.style.background="#9ddbb1"
  oldHead.domContent.style.borderRadius="50%"
  snake.snakePos.push(newHead)
  // 判断是否吃到东西
  if(collideCheckResult.isEat){
    // 1.重新生成新的食物
    drawFood()
  }
  else{
    // 说明没有吃到食物
    // 移除最后一个元素
    document.querySelector(".container").removeChild(snake.snakePos[0].domContent)
    snake.snakePos.shift();//删除第一个元素
  }
  drawSnake(snake)
}
  • 当游戏开始时,要让蛇自动沿着当前方向移动,使用间歇函数定时器来决定蛇移动的速度
  • 给用户选择当游戏结束时,是继续游戏还是结束游戏,继续游戏就初始化游戏,结束游戏就取消键盘事件,并停止计时器
  • 游戏进行中若点击container区域就先暂停游戏,暂停游戏时,要用到事件委托,因为当用户点击确定重新开始游戏时,会将container里的内容重置,此时的绑定事件已经不存在了,通过父亲找到儿子进行相关操作可避免直接给儿子添加绑定事件的缺点,暂停游戏时记得清除定时器,开始时再打开

相关效果如下所示:

代码:

index.html

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

index.css

*{
  /* 去除内外边距 */
  margin: 0;
  padding: 0;
}
/* 整体游戏容器样式 */
.container {
  position: relative;
  display: flex;
  justify-content: center;
  align-items: center;
  width: 600px;
  height: 600px;
  background-color: #225675;
  border: 20px solid #7dd9ff;
  margin: 20px auto;
}
.container button {
  border: none;
  outline: none;
}
/* 开始按钮 */
.startBtn {
  width: 200px;
  height: 80px;
  background: url(../images/startGame.png) center/contain no-repeat;
  display: block;
}
/* 暂停按钮 */
.pauseBtn {
  width: 70px;
  height: 70px;
  background: url(../images/start.png) center/contain no-repeat;
  display: none;
}

index.js

/**
 *绘制蛇的方法
 *  @param {*} snake
 * */
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("../images/snake.png") center/contain no-repeat`
        // 根据方向进行一个旋转
        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="#9ddbb1"
        snake.snakePos[i].domContent.style.borderRadius='50%'
      }
    }
    // 需要将创建的DOM元素添加到container 容器上面
    document.querySelector(".container").append(snake.snakePos[i].domContent)
  }
}
function drawFood(){
  // 食物的坐标是随机的 但食物不可生成在蛇头 蛇身 以及container之外的区域
  while(true){
    // 构成一个死循环,直到生成符合要求的坐标才能退出该循环
    let isRepeat=false //默认生成的坐标符合要求
    // 随机生成一个坐标
    food.x=Math.floor(Math.random()*tr)
    food.y=Math.floor(Math.random()*td)
    // 查看坐标是否符合要求(遍历蛇)
    for(let i=0;i<snake.snakePos.length;i++){
      if(snake.snakePos[i].x===food.x&&snake.snakePos[i].y===food.y){
        // 进入此if 说明当前生成的食物坐标和蛇的位置冲突
        isRepeat=true
        break
      }
     
    }
    if(!isRepeat){
      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.background=`url("../images/food.png") 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"
}
/***
 * 碰撞检测
 * @param {*} newHead 新计算出来的蛇头坐标
 */
function isCollide(newHead){
  let collideCheckInfo={
    isCollide:false,//是否碰撞墙壁 蛇身
    isEat:false//是否吃到食物
  }
  // 1.检测是否碰到墙壁
  if(newHead.x<0||newHead.x>=td||newHead.y<0||newHead.y>=tr){
    collideCheckInfo.isCollide=true
    return collideCheckInfo
  }
  // 检测是是否碰到自己
  for(let i=0;i<snake.snakePos.length;i++){
    if(snake.snakePos[i].x===newHead.x&&snake.snakePos[i].y===newHead.y){
      collideCheckInfo.isCollide=true
      return collideCheckInfo
    }
  }
  // 检测是否吃到东西
  if(newHead.x===food.x&&newHead.y===food.y){
    collideCheckInfo.isEat=true
    score++
  }
  return collideCheckInfo
}
function move(e){
  console.log(e.key)
  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

  }
  snakeMove()
}
/**
 * 蛇的移动方法
 */
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(`游戏结束,您当前的得分为${score}分,是否要重新开始游戏`)){
      // 重新开始游戏
      document.querySelector('.container').innerHTML=`
      <!-- 开始按钮 -->
      <button class="startBtn" style="display:none"></button>
      <!-- 暂停按钮 -->
      <button class="pauseBtn" style="display:none"></button>
      `
      score=0
      console.log(score)
      // gridData=[]
      snake={
        // 蛇一开始移动的方向
        direction:directionNum.right,//一开始向右边移动
        // 蛇的初始位置
        snakePos:[//domContent为蛇的相应dom元素 flag根据身体还是蛇头分别渲染
          {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:""
      }
      console.log("已初始化")
      initGame()
      return
      // drawSnake(snake)
    }else {
      // 结束游戏
      document.removeEventListener('keydown',move)
      // console.log("取消")
      clearInterval(timerStop)
      return

    }
    // alert("撞墙了")
  }
  // 将旧的头修改为身体
  oldHead.flag='body'
  oldHead.domContent.style.background="#9ddbb1"
  oldHead.domContent.style.borderRadius="50%"
  snake.snakePos.push(newHead)
  // 判断是否吃到东西
  if(collideCheckResult.isEat){
    // 1.重新生成新的食物
    drawFood()
  }
  else{
    // 说明没有吃到食物
    // 移除最后一个元素
    document.querySelector(".container").removeChild(snake.snakePos[0].domContent)
    snake.snakePos.shift();//删除第一个元素
  }
  drawSnake(snake)
}


/**
 * 初始化游戏方法
 */
function initGame(){
  //1.初始化地图
  for(let i=0;i<tr;i++){
    for(let j=0;j<td;j++){
      gridData.push({
        x:j,
        y:i
      })
    }
  }
  // 2.绘制蛇
  drawSnake(snake)
  // 3.绘制食物
  drawFood()
}
function startGame(){
  timerStop=setInterval(function(){
    snakeMove()
  },time)
}
/**
 * 绑定事件
 */

function bindEvent(){
  // 1.键盘事件
  document.addEventListener('keydown',move)
  // 2.计时器自动调用蛇移动的方法
  startGame();
  // 3.点击整个容器的时候,可以暂停和重新开始游戏
  document.querySelector('.container').addEventListener('click',function(e){
    // 通过事件委托的形式,判断用户点击的是container还是暂停按钮
    if(e.target.className ==="container"){
    document.querySelector('.pauseBtn').style.display='block'
    clearInterval(timerStop)

    }else {
      document.querySelector('.pauseBtn').style.display='none'
      startGame()
    }
  })
  // 4.给暂停按钮绑定事件
  // 点击子元素事件,冒泡后也会触发父元素点击事件
//   document.querySelector('.pauseBtn').addEventListener('click',function(e){
//     e.stopPropagation()
    
//   })
}
/**
 * 游戏的主方法
 */
function main(){
  // 用户点击了开始游戏之后,再做后续工作
  document.querySelector('.startBtn').addEventListener('click',function(e){
    e.stopPropagation()
    document.querySelector('.startBtn').style.display="none"
    // 1.首先初始化游戏
    initGame()
    // 2.绑定事件
    bindEvent()
  })
}

main()

config.js

// 游戏相关配置文件
let gridData=[]//存储地图对象
// 整个网格的行与列
const tr=30
const td=30
// 蛇的身体大小
let snakeBody=20

// 要明确新的蛇头和旧的蛇头之间的位置关系
// 我们在确定新的蛇头坐标的时候,会那下面的对象和旧蛇头做一个计算

const 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:[//domContent为蛇的相应dom元素 flag根据身体还是蛇头分别渲染
    {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 food={
  x:0,y:0,domContent:""
}
// 游戏分数
let score=0
// 停止计时器
let timerStop=null
// 计时器事件
let time=300

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

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

相关文章

大数据技术主要学什么,有哪些课程

大数据技术是指在海量数据的环境下&#xff0c;采集、存储、处理、分析和管理数据的一系列技术与方法。随着互联网、物联网以及各种智能设备的普及&#xff0c;数据量呈爆炸性增长&#xff0c;传统数据处理手段已难以应对&#xff0c;因此大数据技术应运而生&#xff0c;旨在从…

包管理工具npm、cnpm、yarn、NVM

[包]英文单词是package,代表了一组特定功能的源码集合 包管理工具&#xff1a; 管理[包]的应用软件,可以对[包]进行下载安装,更新,删除,上传等操作借助包管理工具,可以快速开发项目,提升开发效率 包管理工具是一个通用的概念,很多编程语言都有包管理工具,所以掌握好包管理工具非…

供应链|经典论文解读:(s,S) 策略在动态库存下的最优性

文章考虑了具有订购成本&#xff08;由单位成本加上重新订购成本组成&#xff09;的动态库存问题。具体而言&#xff0c;对于每个时期&#xff0c;系统在中期开始是做出一系列采购决策——这些采购有助于库存的积累&#xff0c;并在随后的周期被需求所消耗。每时期系统会产生各…

开源15T tokens!HuggingFace放出规模最大、质量最高预训练数据集 | 最新快讯

新智元报道 编辑&#xff1a;LRS FineWeb 是一个高质量的预训练数据集&#xff0c;包含 15T 个 tokens&#xff0c;主要包含英语文本&#xff1b;消融实验证明了 FineWeb 数据集的质量要高于其他开源数据集&#xff1b;数据清洗脚本也已开源。 Meta 最近开源的 Llama 3 模型再次…

如何根据IP获取国家省份城市名称PHP免费版

最近项目遇到需要根据IP获取用户国家功能需求&#xff0c;网上找了一下&#xff0c;很多API接口都需要付费&#xff0c;考虑为公司节约成本&#xff0c;就取找找有没有开源的 github 上面那个包含多种语言&#xff0c;下面这个只有php&#xff0c;用法很简单 $ip 114.114.114…

QT7_视频知识点笔记_1_ 基础知识(帮助文档),窗口(内存回收机制),信号槽(传参),Lambda表达式

1.QT基础 QT是一个框架&#xff0c;不用像C语言自己从底层写&#xff0c;需要的功能可以先看是否QT库中有直接可使用的 帮助文档的使用&#xff1a;F1跳入帮助文档&#xff0c; QT中常用的类&#xff1a;比如QPushbutton&#xff0c;查看帮助文档则可知道对应的函数和解决方…

C语言知识点补充——操作符详解

1、计算幂次数和平方根 使用<math.h>数学库 pow()函数计算幂次数&#xff1b;sqrt()函数计算平方根。 注&#xff1a;sqrt()输入同样的数字&#xff0c;计算出来的数值&#xff0c;可能不相等&#xff0c;因为输出double数&#xff0c;小数点后面的数值不一定一致。 2…

制作外贸脚本的流程和代码分享!

在全球化的今天&#xff0c;外贸业务成为了许多企业拓展市场、增加收入的重要途径&#xff0c;而在外贸业务中&#xff0c;一个优秀的脚本往往能够起到事半功倍的效果。 那么&#xff0c;如何制作一个高效、专业的外贸脚本呢?本文将为您详细解析制作外贸脚本的流程&#xff0…

力扣每日一题-拆炸弹-2024.5.5

力扣题目&#xff1a;拆炸弹 题目链接: 1652.拆炸弹 题目描述 代码思路 根据代码实现分为k等于0和k不等于0的情况。k等于0很容易处理&#xff0c;而k不等于0时&#xff0c;需要使用滑动窗口的方式来解决。先根据小于0或大于0确定一个窗口&#xff0c;然后移动&#xff0c;获…

Windows中安装的PostgreSQL 数据库如何重启

1. 使用Windows服务管理器 打开“运行”对话框&#xff08;按WinR键&#xff09;。输入services.msc并按回车&#xff0c;这将打开服务列表。在服务列表中找到PostgreSQL服务。它通常命名为“PostgreSQL”后面跟着版本号和实例名称&#xff0c;例如“PostgreSQL 13 - mydb”。…

MES生产系统与数字孪生双重结合:智慧制造工厂的新引擎

随着数字化浪潮的推动&#xff0c;制造行业正在经历着前所未有的变革。在这个变革的浪潮中&#xff0c;MES生产制造系统与数字孪生技术的深度融合成为了制造工厂未来发展的核心驱动力。这种结合不仅提升了生产效率&#xff0c;优化了资源配置&#xff0c;降低了运营成本&#x…

解决mac出现npm install 卡在“sill idealTree buildDeps“的问题

问题出现场景&#xff1a; 在新建一个项目尝试npm install命令时&#xff0c;一直卡在“sill idealTree buildDeps“ 尝试过的无效解决方案包括&#xff1a; 切换/关闭梯子重启更换网络更换npm源更新删除 package.json 最终解决方案&#xff1a; 引起问题的原因是MacOS设置中…

年轻人刮疯了,刮刮乐断货了

年轻人刮疯了 刮刮乐缺货了。 00后彩票店老板陆诗等得有点着急。她的福彩店开在深圳&#xff0c;今年4月才开门营业&#xff0c;但从开业到今天&#xff0c;刮刮乐总共就来了一回货——开业时发的20本。 那之后&#xff0c;刮刮乐就彻底断供了。原本&#xff0c;陆诗想把刮刮…

重学SpringBoot3-SPI机制

更多SpringBoot3内容请关注我的专栏&#xff1a;《SpringBoot3》 期待您的点赞&#x1f44d;收藏⭐评论✍ 重学SpringBoot3-SPI机制 什么是 SPI&#xff1f;Spring Boot 中的 SPI 机制spring.factories 文件自动配置的实现启动流程中的作用 SPI实际应用步骤 1: 新建模块步骤 2:…

【1小时掌握速通深度学习面试6】图神经网络-下

目录 23. GraphSage 24.简述图神经网络的推理机制在其他领域中的应用 与传统NN的区别&#xff08;GNN优点&#xff09; 23. GraphSage GraphSage出现之前的图网络方法需要图中所有的顶点在训练embedding的时候都出现&#xff0c;这些的方法本质上是transductive&#xff0c…

我独自升级:崛起怎么下载 我独自升级游戏下载教程分享

定于5月8日全球揭幕的《我独自升级崛起》——一款扣人心弦的动作RPG巨制&#xff0c;灵感采撷于同名动画及网络漫画的热潮&#xff0c;誓将引领满怀热忱的玩家步入一场交织着深邃探索和宏大规模的奇妙冒险。该游戏立足于一个独树一帜的网络武侠宇宙&#xff0c;细腻刻画了一个凡…

基于Springboot的民航网上订票系统(有报告)。Javaee项目,springboot项目。

演示视频&#xff1a; 基于Springboot的民航网上订票系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构…

【Osek网络管理测试】[TG3_TC1]Limphome复位_NM报文

&#x1f64b;‍♂️ 【Osek网络管理测试】系列&#x1f481;‍♂️点击跳转 文章目录 1.环境搭建2.测试目的3.测试步骤4.预期结果5.测试结果 1.环境搭建 硬件&#xff1a;VN1630 软件&#xff1a;CANoe 2.测试目的 验证DUT从LimpHome状态转换到Reset状态是否满足NM标准的…

【电商-虾皮】

电商-虾皮 ■ 人口分布■ 市场■ 欧美市场■ 东南亚市场 ■ ■ 人口分布 ■ 市场 ■ 欧美市场 亚马逊 ■ 东南亚市场 shopee ■

推荐网站(4)以图片找动漫,二次元福利!!!

有的时候只有图片不知道&#xff0c;这是什么动漫&#xff0c;在多少集出现过那么&#xff0c;这个网站觉得是你的福音 我们去b站随便找一个动漫试试看&#xff0c;截图保存 然后进入网站&#xff0c;点击文件按钮上传照片 可以看到精准搜出来了动漫&#xff0c;更为重要的是连…