JS 实战 贪吃蛇游戏

news2024/11/19 6:26:58

一、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 = true
        break  //没必要重复了,直接跳出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 = true
  return 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 = true
    return 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 = null

const 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 = true
        break  //没必要重复了,直接跳出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:""
    }
      // 再次调用initGame
      initGame()

   }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 = true
  return 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 = true
    return collideCheckInfo
  }
}
//   3. 检测是否吃到食物
if(newHead.x === food.x && newHead.y === food.y){
  collideCheckInfo.isEat = true
  score++  //分数自增
}
 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.coloradmin.cn/o/1683506.html

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

相关文章

vue表格中上传按钮样式

问题&#xff1a;写了样式但是遇到问题如下图&#xff1a; 解决方法&#xff1a; ::v-deep .el-upload {display: flex;justify-content: center;align-items: center; } 因为上传的图标被包含在el-upload中&#xff0c;而删除按钮并没有被包含在el-upload中。 所以整体的样式…

存储+调优:存储-IP-SAN

存储调优&#xff1a;存储-IP-SAN 数据一致性问题 硬盘&#xff08;本地&#xff0c;远程同步rsync&#xff09; 存储设备&#xff08;网络&#xff09; 网络存储 不同接口的磁盘 1.速率 2.支持连接更多设备 3.支持热拔插 存储设备什么互联 千…

ACM实训

【碎碎念】继续搞习题学习&#xff0c;今天完成第四套的ABCD&#xff0c;为下一周挤出时间复习&#xff0c;加油 Digit Counting 问题 法希姆喜欢解决数学问题。但有时解决所有的数学问题对他来说是一个挑战。所以有时候他会为了解决数学难题而生气。他拿起一支粉笔&#xff…

岛屿问题刷题

200. 岛屿数量 - 力扣&#xff08;LeetCode&#xff09; class Solution {public int numIslands(char[][] grid) {int n grid.length;//grid行数int m grid[0].length;//grid列数int res 0;for(int r 0;r<n;r){for(int c0;c<m;c){if(grid[r][c]1){dfs(grid,r,c);res…

HCIP-VLAN综合实验

一、实验拓扑 二、实验要求 1、pc1和pc3所在接口为access;属于vlan 2; PC2/PC4/PC5/PC6处于同一网段’其中PC2可以访问PC4/PC5/PC6; PC4可以访问PC6&#xff1b;PC5不能访问PC6&#xff1b; 2、PC1/PC3与PC2/PC4/PC5/PC6不在同一个网段&#xff1b; 3、所有PC通过DHCP获取IP…

Multi-Attention Transformer for Naturalistic Driving Action Recognition

标题&#xff1a;用于自然驾驶行为识别的多注意力Transformer 源文链接&#xff1a;https://openaccess.thecvf.com/content/CVPR2023W/AICity/papers/Dong_Multi-Attention_Transformer_for_Naturalistic_Driving_Action_Recognition_CVPRW_2023_paper.pdfhttps://openaccess…

安装ollama并部署大模型并测试

Ollama介绍 项目地址&#xff1a;ollama 官网地址&#xff1a; https://ollama.com 模型仓库&#xff1a;https://ollama.com/library API接口&#xff1a;api接口 Ollama 是一个基于 Go 语言开发的简单易用的本地大语言模型运行框架。可以将其类比为 docker&#xff08;同基…

鸿蒙ArkUI-X跨平台技术:【SDK结构介绍】

ArkUI-X SDK目录结构介绍 简介 本文档配套ArkUI-X&#xff0c;将OpenHarmony ArkUI开发框架扩展到不同的OS平台&#xff0c;比如Android和iOS平台&#xff0c;让开发者基于ArkUI&#xff0c;可复用大部分的应用代码&#xff08;UI以及主要应用逻辑&#xff09;并可以部署到相…

深度学习之人脸性别年龄检测系统

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 一、项目背景与意义 随着计算机视觉和深度学习技术的飞速发展&#xff0c;人脸性别年龄检测系统在多个领域展现出广…

简易Docker磁盘使用面板Doku

这个项目似乎有 1 年多没更新了&#xff0c;最后发布版本的问题也没人修复&#xff0c;所以看看就行&#xff0c;不建议安装 什么是 Doku &#xff1f; Doku 是一个简单、轻量级的基于 Web 的应用程序&#xff0c;允许您以用户友好的方式监控 Docker 磁盘使用情况。Doku 显示 D…

【30天精通Prometheus:一站式监控实战指南】第6天:mysqld_exporter从入门到实战:安装、配置详解与生产环境搭建指南,超详细

亲爱的读者们&#x1f44b;   欢迎加入【30天精通Prometheus】专栏&#xff01;&#x1f4da; 在这里&#xff0c;我们将探索Prometheus的强大功能&#xff0c;并将其应用于实际监控中。这个专栏都将为你提供宝贵的实战经验。&#x1f680;   Prometheus是云原生和DevOps的…

JavaEE-网络初识

文章目录 一、网络背景1.1 起源1.2 国内网络的发展 二、关键概念2.1 网络2.2 设备2.3 ip地址与端口号 三、协议3.1 协议分层3.2 OSI七层模型3.3 TCP/IP五层模型3.4 数据传输过程的简单叙述 一、网络背景 1.1 起源 在国外大概时上世纪70年代左右&#xff0c;网络就出现了&…

鸿蒙OS开发:【一次开发,多端部署】(典型布局场景)

典型布局场景 虽然不同应用的页面千变万化&#xff0c;但对其进行拆分和分析&#xff0c;页面中的很多布局场景是相似的。本小节将介绍如何借助自适应布局、响应式布局以及常见的容器类组件&#xff0c;实现应用中的典型布局场景。 布局场景实现方案 开发前请熟悉鸿蒙开发指导…

与MySQL DDL 对比分析OceanBase DDL的实现

本文将简要介绍OceanBase的DDL实现方式&#xff0c;并通过与MySQL DDL实现的对比&#xff0c;帮助大家更加容易理解。 MySQL DDL 的算法 MySQL 的DDL实现算法主要有 copy、inplace和instant。 copy copy算法的实现相对简单&#xff0c;MySQL首先会创建一个临时表&#xff0…

服务器c盘爆满了,这几种方法可以帮助C盘“瘦身”

我们在使用服务器的时候基本不会在C盘安装软件&#xff0c;那么用久了发现C盘满了&#xff0c;提示空间不足&#xff1f;那么这是怎么回事&#xff0c;为什么空间会占用这么快呢&#xff1f; 原因一&#xff1a; C盘满了&#xff0c;很可能是因为电脑里的垃圾文件过多。操作系…

Servlet的request对象

request对象的继承关系 1.HttpServletRequest接口继承了ServletRequest接口&#xff0c;对其父接口进行了扩展&#xff0c;可以处理满足所有http协议的请求 2.HttpServletRequest和ServletRequest都是接口&#xff0c;不能创建对象&#xff0c;因此在tomcat底层定义实现类并创…

Google Find My Device:科技守护,安心无忧

在数字化的时代&#xff0c;我们的生活与各种智能设备紧密相连。而 Google Find My Device 便是一款为我们提供安心保障的实用工具。 一、Find My Decice Netword的定义 谷歌的Find My Device Netword旨在通过利用Android设备的众包网络的力量&#xff0c;帮助用户安全的定位所…

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

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

【oracle004】oracle内置函数手册总结(已更新)

1.熟悉、梳理、总结下oracle相关知识体系。 2.日常研发过程中使用较少&#xff0c;随着时间的推移&#xff0c;很快就忘得一干二净&#xff0c;所以梳理总结下&#xff0c;以备日常使用参考 3.欢迎批评指正&#xff0c;跪谢一键三连&#xff01; 总结源文件资源下载地址&#x…

Google发布的CAT3D,在1分钟内,能够从任意数量的真实或生成的图像创建3D场景。

给定任意数量的输入图像&#xff0c;使用以这些图像为条件的多视图扩散模型来生成场景的新视图。生成的视图被输入到强大的 3D 重建管道&#xff0c;生成可以交互渲染的 3D 表示。总处理时间&#xff08;包括视图生成和 3D 重建&#xff09;仅需一分钟。 相关链接 论文&#x…