【教程】用 HTML JavaScript 制作 2.5D 迷宫游戏地图

news2024/11/30 12:53:46

  我写了一个能够随机生成迷宫的算法,得到了用户很好的反响,对大家有所帮助。我现在想将这个迷宫以2.5D游戏地图的方式呈现出来。最初我考虑使用CSS来实现这个目标,但效果并不太理想,因为我无法只将它渲染成背景,而不对整个网站进行重新排版。因此,虽然我不打算继续使用CSS来达到这个目标,但我想与大家分享如何使用CSS来按比例渲染迷宫的方法。后来,我决定使用HTML5画布功能和地图块的坐标变换来生成2.5D游戏地图。为此,我在JavaScript脚本中添加了坐标变换的脚本,分享出来希望能对大家能有所帮助。在文章的最后将把实现的地图的代码分享出来。
在这里插入图片描述

CSS 生成2.5D

  使用css脚本样式将html中的div元素转换成2.5D效果,主要是通过css中的属性
在这里插入图片描述

<html>
<style>
.wrapper {
  position: fixed;
  width: 100%; height: 100%;
  left: 0; top: 0;
  text-align: center;
}
.wrapper:before {
  content: "";
  display: inline-block; vertical-align: middle;
  width: 0; height: 100%;
}
.wrapper > .grid {
  display: inline-block;
  vertical-align: middle;
}
.grid > .row {
  font-size: 0;
  width: 100px;
  white-space: nowrap;
}
.grid > .row > .cell {
  position: relative;
  display: inline-block;
  width: 10px; height: 10px;
  outline: 1px solid rgba(0, 0, 0, 0.3);
}
.grid > .row > .cell:hover {
  background-color: red;
}
.grid {
  transform: rotateX(40deg) rotateZ(45deg);
}
</style>
<body>
<div class="wrapper">
  <div class="grid">
    <div class="row">
      <div class="cell"></div>
      <div class="cell"></div>
      <div class="cell"></div>
      <div class="cell"></div>
      <div class="cell"></div>
    </div>
    <div class="row">
      <div class="cell"></div>
      <div class="cell"></div>
      <div class="cell"></div>
      <div class="cell"></div>
      <div class="cell"></div>
    </div>
    <div class="row">
      <div class="cell"></div>
      <div class="cell"></div>
      <div class="cell"></div>
      <div class="cell"></div>
      <div class="cell"></div>
    </div>
    <div class="row">
      <div class="cell"></div>
      <div class="cell"></div>
      <div class="cell"></div>
      <div class="cell"></div>
      <div class="cell"></div>
    </div>
    <div class="row">
      <div class="cell"></div>
      <div class="cell"></div>
      <div class="cell"></div>
      <div class="cell"></div>
      <div class="cell"></div>
    </div>
  </div>
</div>
<script>
</script>
</body>
</html>

这段代码中使用了 CSS transform 属性,它在一些较旧的浏览器(如 IE9 及更早版本)中可能不被支持。这意味着在这些浏览器中,等角视图可能无法正常显示。但是CSS又无法处理复杂交互代码中如果需要为你的网格添加更复杂的交互(如拖拽、缩放等),需要使用 JavaScript 或其他技术实现这些功能。而你的地图块的坐标的样式是写在 CSS 中的,如果你需要在运行时动态修改这些样式,可能需要使用 JavaScript 来操作 DOM,这会导致代码的复杂程度太高,最后导致无法增加其他的元素和功能到地图中来。

脚本生成地图迷宫

  本文将介绍如何使用HTML5 Canvas和JavaScript来制作一个2.5D迷宫游戏地图。HTML和CSS准备工作 我们需要在HTML文件中添加一个canvas元素来作为画布,然后使用CSS样式对其进行一些简单的样式设置。因为我们要在画布上绘制2.5D效果的地图,所以需要使用坐标变换函数将等角坐标系转换为屏幕坐标系和迷宫地图的生成算法。

<html>
<head>
</head>
<body>
   <style>
	canvas {
	  display: block;
	  margin: 0 auto;
	}
   </style>
  <div style="text-align: center;" id="maindiv">
     行数<input type="text" id="rowv" value="10"><button onclick="oncreate()" >生成</button>

	 <br>
    <!-- 创建一个画布,宽度为 640 像素,高度为 360 像素 -->
    <canvas width="800" height="500" id="canvas" ></canvas>
    <br>


  </div>
  <script type="text/javascript">

	// 获取画布元素
    var canvas = document.getElementById("canvas");

    // 获取画布宽度和高度
    var width = canvas.width;
    var height = canvas.height;
    // 获取画布上下文
    var context = canvas.getContext("2d");
    // 初始化格子
    var tile = [];
    var cols = 9;
    var rows = cols;

    // 等角变换的变量和辅助函数
    var IsoW = 40; // 格子宽度
    var IsoH = 20; // 格子高度
    var IsoX = width / 2; // 等角网格的中心 x 坐标
    var IsoY = 20; // 等角网格的顶部 y 坐标

    function IsoToScreenX(localX, localY) {
      // 将等角坐标转换为屏幕坐标的 x 坐标
      return IsoX + (localX - localY) * IsoW;
    }
    function IsoToScreenY(localX, localY) {
      // 将等角坐标转换为屏幕坐标的 y 坐标
      return IsoY + (localX + localY) * IsoH;
    }
    function ScreenToIsoX(globalX, globalY) {
      // 将屏幕坐标转换为等角坐标的 x 坐标
      return ((globalX - IsoX) / IsoW + (globalY - IsoY) / IsoH) / 2;
    }
    function ScreenToIsoY(globalX, globalY) {
      // 将屏幕坐标转换为等角坐标的 y 坐标
      return ((globalY - IsoY) / IsoH - (globalX - IsoX) / IsoW) / 2;
    }
	// 在给定的坐标处绘制变形倾斜45度
	function DrawIsoTile(x, y, color) {
	  // 设置填充颜色
	  context.fillStyle = color;
	  // 开始路径
	  context.beginPath();
	  // 绘制倾斜45度矩形
	  context.moveTo(x, y);
	  context.lineTo(x - IsoW, y + IsoH);
	  context.lineTo(x, y + IsoH * 2);
	  context.lineTo(x + IsoW, y + IsoH);
	  context.closePath();
	  // 填充矩形
	  context.fill();
	}

// 绘制事件
function onshow(ary) {
     canvas = document.getElementById("canvas");

    context.clearRect(0,0, canvas.width, canvas.height);
  // 循环遍历每个格子
	  for (var y = 0; y < rows; y++){
		for (var x = 0; x < cols; x++) {
		  // 获取该格子的图块和对象类型
		  var t = ary[y][x];
		  // 将等角坐标转换为屏幕坐标
		  var rx = IsoToScreenX(x, y);
		  var ry = IsoToScreenY(x, y);
		  // 绘制图块(如果有)
		  switch (t) {
		    //方格子上色,与变形倾斜45度
			case 0: DrawIsoTile(rx, ry, "#C59E77"); break;
			case 1: DrawIsoTile(rx, ry, "#94BA57"); break;
			case 2: DrawIsoTile(rx, ry, "#9DD5E2"); break;
		  }
		}
	}
}

function recursiveBacktrackingMaze(rows, cols) {
  let grid = new Array(rows);
  for (let i = 0; i < rows; i++) {
    grid[i] = new Array(cols).fill(1);
  }
  let stack = [{ row: 1, col: 1 }];
  while (stack.length > 0) {
    let current = stack[stack.length - 1];
    let neighbors = [];
    if (current.row > 2 && grid[current.row - 2][current.col] === 1) {
      neighbors.push({ row: current.row - 2, col: current.col });
    }
    if (current.col > 2 && grid[current.row][current.col - 2] === 1) {
      neighbors.push({ row: current.row, col: current.col - 2 });
    }
    if (current.row < rows - 3 && grid[current.row + 2][current.col] === 1) {
      neighbors.push({ row: current.row + 2, col: current.col });
    }
    if (current.col < cols - 3 && grid[current.row][current.col + 2] === 1) {
      neighbors.push({ row: current.row, col: current.col + 2 });
    }
    if (neighbors.length > 0) {
      let next = neighbors[Math.floor(Math.random() * neighbors.length)];
      let wallRow = (current.row + next.row) / 2;
      let wallCol = (current.col + next.col) / 2;
      grid[next.row][next.col] = 0;
      grid[wallRow][wallCol] = 0;
      stack.push(next);
    } else {
      stack.pop();
    }
  }
  // 设置入口和出口
  grid[1][0] = 0; // 入口
  grid[rows - 2][cols - 1] = 0; // 出口
  return grid;
}
function oncreate(){
    canvas = document.getElementById("canvas");
    cols = parseInt(document.getElementById("rowv").value);
	if(cols<=5){
		cols=5;
	}
	if(cols%2==0){
		cols=cols-1;
	}
    rows = cols;
    // 获取画布宽度和高度
	console.log(context);
	if(cols>12){
		canvas.width=740+(cols*45);
		canvas.height=500+(cols*30);
	}else{
		canvas.width=740;
		canvas.height=600
	}
     width = canvas.width;
     height = canvas.height;
	 IsoX = width / 2;
	 var ar=recursiveBacktrackingMaze(rows,cols);
	onshow(ar);
}
</script>
</body>
</html>

地图块坐标变化

  为了将迷宫地图调整为2.5D效果,我们需要定义四个函数,它们用于将等角坐标系(isometric)与笛卡尔坐标系(screen)之间进行转换。等角坐标系常用于制作类似于 2.5D 的视觉效果。以下是各个函数的解释及示例:

// 初始化地图参数
var IsoW = 40; // 格子宽度
var IsoH = 20; // 格子高度
var IsoX = width / 2; // 等角网格的中心 x 坐标
var IsoY = 20; // 等角网格的顶部 y 坐标

function IsoToScreenX(localX, localY) {
    // 将等角坐标转换为屏幕坐标的 x 坐标
    return IsoX + (localX - localY) * IsoW;
}
function IsoToScreenY(localX, localY) {
    // 将等角坐标转换为屏幕坐标的 y 坐标
    return IsoY + (localX + localY) * IsoH;
}
function ScreenToIsoX(globalX, globalY) {
    // 将屏幕坐标转换为等角坐标的 x 坐标
    return ((globalX - IsoX) / IsoW + (globalY - IsoY) / IsoH) / 2;
}
function ScreenToIsoY(globalX, globalY) {
    // 将屏幕坐标转换为等角坐标的 y 坐标
    return ((globalY - IsoY) / IsoH - (globalX - IsoX) / IsoW) / 2;
}
// 在给定的坐标处绘制变形倾斜45度
function DrawIsoTile(x, y, color) {
    // 设置填充颜色
    context.fillStyle = color;
    // 开始路径
    context.beginPath();
	// 绘制倾斜45度矩形
    context.moveTo(x, y);
    context.lineTo(x - IsoW, y + IsoH);
    context.lineTo(x, y + IsoH * 2);
    context.lineTo(x + IsoW, y + IsoH);
    context.closePath();
    // 填充矩形
    context.fill();
}
  1. IsoToScreenX(localX, localY):将等角坐标转换为屏幕坐标的 x 坐标。
    • 输入:等角坐标的 localX 和 localY。
    • 输出:屏幕坐标的 x 坐标。
    • 示例:IsoToScreenX(2, 1) 可能返回 70(具体值取决于 IsoX 和 IsoW)。
  2. IsoToScreenY(localX, localY):将等角坐标转换为屏幕坐标的 y 坐标。
    • 输入:等角坐标的 localX 和 localY。
    • 输出:屏幕坐标的 y 坐标。
    • 示例:IsoToScreenY(2, 1) 可能返回 35(具体值取决于 IsoY 和 IsoH)。
  3. ScreenToIsoX(globalX, globalY):将屏幕坐标转换为等角坐标的 x 坐标。
    • 输入:屏幕坐标的 globalX 和 globalY。
    • 输出:等角坐标的 x 坐标。
    • 示例:ScreenToIsoX(70, 35) 可能返回 2(具体值取决于 IsoX 和 IsoW)。
  4. ScreenToIsoY(globalX, globalY):将屏幕坐标转换为等角坐标的 y 坐标。
    • 输入:屏幕坐标的 globalX 和 globalY。
    • 输出:等角坐标的 y 坐标。
    • 示例:ScreenToIsoY(70, 35) 可能返回 1(具体值取决于 IsoY 和 IsoH)。

最后,DrawIsoTile(x, y, color) 函数用于在给定坐标处绘制倾斜 45 度的矩形。这个函数接受三个参数:x 坐标、y 坐标和填充颜色。示例:DrawIsoTile(70, 35, '#FF0000') 会在屏幕坐标 (70, 35) 处绘制一个红色的等角矩形。

这里有一些关于等角投影和笛卡尔坐标系之间的转换的例子: 假设 IsoX = 0, IsoY = 0, IsoW = 30, IsoH = 15。

  • 将等角坐标 (2, 1) 转换为屏幕坐标:

    • X 坐标:IsoToScreenX(2, 1) = 0 + (2 - 1) * 30 = 30
    • Y 坐标:IsoToScreenY(2, 1) = 0 + (2 + 1) * 15 = 45

    所以,等角坐标 (2, 1) 对应的屏幕坐标是 (30, 45)。

    另外,你也可以使用 ScreenToIsoXScreenToIsoY 函数将屏幕坐标转换回等角坐标。例如,假设屏幕坐标是 (30, 45):

    • X 坐标:ScreenToIsoX(30, 45) = ((30 - 0) / 30 + (45 - 0) / 15) / 2 = (1 + 3) / 2 = 2
    • Y 坐标:ScreenToIsoY(30, 45) = ((45 - 0) / 15 - (30 - 0) / 30) / 2 = (3 - 1) / 2 = 1

所以,屏幕坐标 (30, 45) 对应的等角坐标是 (2, 1)。

迷宫算法DFS

  我优化了一下迷宫地图的生成方法,在原来的基础上使用了递归回溯算法的迷宫生成方式。在javascript脚本中创建一个recursiveBacktrackingMaze函数。这个算法的名称是“递归回溯法生成迷宫”(Recursive Backtracking Maze Generation)。它是一种基于深度优先搜索(Depth-First Search,DFS)的迷宫生成算法。递归回溯法通过从起点开始,随机选择一个方向移动,并创建迷宫的路径。当无法继续前进时,它会回溯到先前的路径点,直到找到新的未访问的邻居或回到起点。这个过程持续进行,直到所有可访问的单元格都被访问过。

function recursiveBacktrackingMaze(rows, cols) {
  // 创建一个空白网格,所有单元格都填充为1(墙壁)
  let grid = new Array(rows);
  for (let i = 0; i < rows; i++) {
    grid[i] = new Array(cols).fill(1);
  }
  // 初始化栈,并将起始单元格放入栈中
  let stack = [{ row: 1, col: 1 }];
  // 当栈不为空时,继续循环
  while (stack.length > 0) {
    // 获取当前单元格(栈顶元素)
    let current = stack[stack.length - 1];
    // 查找当前单元格的邻居
    let neighbors = [];
    // 检查上方邻居
    if (current.row > 2 && grid[current.row - 2][current.col] === 1) {
      neighbors.push({ row: current.row - 2, col: current.col });
    }
    // 检查左侧邻居
    if (current.col > 2 && grid[current.row][current.col - 2] === 1) {
      neighbors.push({ row: current.row, col: current.col - 2 });
    }
    // 检查下方邻居
    if (current.row < rows - 3 && grid[current.row + 2][current.col] === 1) {
      neighbors.push({ row: current.row + 2, col: current.col });
    }
    // 检查右侧邻居
    if (current.col < cols - 3 && grid[current.row][current.col + 2] === 1) {
      neighbors.push({ row: current.row, col: current.col + 2 });
    }

    // 如果有未访问的邻居
    if (neighbors.length > 0) {
      // 随机选择一个邻居
      let next = neighbors[Math.floor(Math.random() * neighbors.length)];
      // 移除墙壁(将邻居和中间单元格设为0)
      let wallRow = (current.row + next.row) / 2;
      let wallCol = (current.col + next.col) / 2;
      grid[next.row][next.col] = 0;
      grid[wallRow][wallCol] = 0;
      // 将选择的邻居添加到栈中
      stack.push(next);
    } else {
      // 如果没有未访问的邻居,从栈中弹出当前单元格
      stack.pop();
    }
  }

  // 返回生成的迷宫网格
  return grid;
}

  递归回溯算法是一种深度优先搜索(DFS)算法,它从一个起始单元格开始,沿着未访问过的邻居单元格随机移动,并创建一个路径。当没有未访问的邻居时,它会回溯到先前的单元格,寻找其他未访问的邻居。这个过程将持续进行,直到回溯到起始单元格并且所有可访问的单元格都被访问过。我们需要先了解一下网格的结构和单元格的坐标。在这个算法中,网格是由奇数行和奇数列组成的,每个奇数行和奇数列上的单元格都是墙壁。这样,相邻的两个房间(即0值单元格)之间总是有一个墙壁(即1值单元格)。
  让我们使用一个5x5网格来演示该算法的运行过程,并提供一些代码示例。

初始状态,5x5网格:

1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1

1 设置起始单元格(1,1)为0,并将其添加到栈中。

javascriptCopy codelet stack = [{ row: 1, col: 1 }];
grid[1][1] = 0;
-----------------------------------
1 1 1 1 1
1 0 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1

2 可访问的邻居生成
  在递归回溯迷宫生成算法中,可访问的邻居是从当前单元格开始,沿上、下、左、右四个方向,跳过一个单元格的位置。这意味着邻居之间始终有一个单元格的距离,这个单元格是它们之间的墙壁。这就是为什么算法中的行和列索引增量是2,而不是1。
  在算法中,我们首先创建一个空的邻居列表。然后,我们检查当前单元格的上、下、左、右四个方向的邻居,以确保它们在网格范围内并且尚未访问(即其值为1)。如果满足条件,我们将邻居添加到列表中。

let neighbors = [];
// 检查上方邻居
if (current.row > 2 && grid[current.row - 2][current.col] === 1) {
  neighbors.push({ row: current.row - 2, col: current.col });
}
// 检查左侧邻居
if (current.col > 2 && grid[current.row][current.col - 2] === 1) {
  neighbors.push({ row: current.row, col: current.col - 2 });
}
// 检查下方邻居
if (current.row < rows - 3 && grid[current.row + 2][current.col] === 1) {
  neighbors.push({ row: current.row + 2, col: current.col });
}
// 检查右侧邻居
if (current.col < cols - 3 && grid[current.row][current.col + 2] === 1) {
  neighbors.push({ row: current.row, col: current.col + 2 });
}
-----------------------------------
假设我们有一个5x5网格,并且当前单元格位于(1,11 1 1 1 1
1 0 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1

那么可访问的邻居计算如下:

  • 上方邻居:没有,因为它超出了网格范围。
  • 左侧邻居:没有,因为它超出了网格范围。
  • 下方邻居:没有,因为它是墙壁(值为1)。
  • 右侧邻居:(1,3),因为它在网格范围内并且尚未访问(值为1)。

所以在这个例子中,可访问的邻居列表只包含一个元素:[{ row: 1, col: 3 }]

3 当前单元格(1,1)有一个可访问的邻居:(1,3)。选择(1,3)并移除(1,1)和(1,3)之间的墙壁。

​ 这段代码的目的是移除两个相邻单元格之间的墙壁。为了理解这段代码,我们需要先了解一下网格的结构和单元格的坐标。在这个算法中,网格是由奇数行和奇数列组成的,每个奇数行和奇数列上的单元格都是墙壁。这样,相邻的两个房间(即0值单元格)之间总是有一个墙壁(即1值单元格)。
  这里,current 是当前单元格,next 是选择的邻居单元格。由于我们在处理奇数行和奇数列,所以这两个单元格之间的距离始终是2。
  因此,我们可以通过对它们的行和列分别求平均值来找到它们之间的墙壁单元格。这就是 wallRowwallCol 的计算方法。接下来,我们将 next 单元格(邻居单元格)的值设为0,表示这个单元格已被访问并且成为通路。同时,我们也将 wallRowwallCol 对应的单元格设为0,表示移除了墙壁,连接了 currentnext 两个房间。

javascriptCopy codelet current = stack[stack.length - 1]; // { row: 1, col: 1 }
let neighbors = [{ row: 1, col: 3 }];
let next = neighbors[0];
let wallRow = (current.row + next.row) / 2;
let wallCol = (current.col + next.col) / 2;
grid[next.row][next.col] = 0;
grid[wallRow][wallCol] = 0;
stack.push(next);
-----------------------------------
1 1 1 1 1
1 0 0 0 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1

4 当前位置:(1,3),向下移动,移动到(3,3) 并移除墙壁((1,3) 和 (3,3) 之间)。
  当前位置在(1,3),接下来我们要向下移动,即沿列方向移动。首先,我们要找到下一个可移动的邻居位置。在算法中,这部分由以下代码实现:

// 查找当前单元格的邻居
let neighbors = [];
...
// 检查下方邻居
if (current.row < rows - 3 && grid[current.row + 2][current.col] === 1) {
  neighbors.push({ row: current.row + 2, col: current.col });
}

  这段代码检查了下方邻居是否可达。current.row < rows - 3 确保我们不会超出网格的边界。grid[current.row + 2][current.col] === 1 确保下方邻居(距离2个单位的位置)还没有被访问过(值为1表示墙壁,也表示未访问)。如果满足条件,我们将这个邻居添加到邻居列表中。
  接下来,我们从邻居列表中随机选择一个邻居作为下一个要访问的位置。这个过程由以下代码实现:

// 随机选择一个邻居
let next = neighbors[Math.floor(Math.random() * neighbors.length)];

  这个例子中,我们选择了下方邻居,即(3,3)。接下来,我们需要移除当前位置(1,3)和目标位置(3,3)之间的墙壁。墙壁位于这两个位置的中间,即(2,3)。以下代码实现了墙壁的移除:

javascriptCopy code// 移除墙壁(将邻居和中间单元格设为0)
let wallRow = (current.row + next.row) / 2;
let wallCol = (current.col + next.col) / 2;
grid[next.row][next.col] = 0;
grid[wallRow][wallCol] = 0;

  wallRowwallCol 计算了墙壁的位置。grid[next.row][next.col] = 0; 将目标位置(3,3)设置为0,表示这是一个通路。grid[wallRow][wallCol] = 0; 将墙壁位置(2,3)设置为0,表示墙壁已经移除。
  最后,将目标位置(3,3)添加到栈中,表示我们已经访问过这个位置。这由以下代码实现:

// 将选择的邻居添加到栈中
stack.push(next);

  现在,我们已经从(1,3)移动到了(3,3),并移除了它们之间的墙壁。这就是向下移动的生成过程。在迭代过程中,这个过程会不断重复,直到所有可访问的单元格都被访问。

1 1 1 1 1
1 0 0 0 1
1 1 1 0 1
1 1 1 0 1
1 1 1 1 1

5 当前位置:(3,3),向左移动,移动到(3,1) 并移除墙壁((3,3) 和 (3,1) 之间)

1 1 1 1 1
1 0 0 0 1
1 1 1 0 1
1 0 0 0 1
1 1 1 1 1

  这些数据表示了迷宫生成过程中每个步骤的网格状态。请注意,由于算法的随机性,实际生成的迷宫可能有所不同。
如果大家有兴趣,可以改成我前面的文章中的迷宫生成算法,来生产自己的2.5D地图迷宫。

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

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

相关文章

洛谷B2096 直方图

直方图 题目描述 给定一个非负整数数组&#xff0c;统计里面每一个数的出现次数。我们只统计到数组里最大的数。 假设 F m a x &#xff08; F m a x ≤ 100000 &#xff09; Fmax&#xff08;Fmax \le 100000&#xff09; Fmax&#xff08;Fmax≤100000&#xff09;是数组…

scratch绘制直尺 中国电子学会图形化编程 少儿编程 scratch编程等级考试四级真题和答案解析2023年3月

目录 scratch绘制直尺 一、题目要求 1、准备工作 2、功能实现 二、案例分析

NSSCTF之Misc篇刷题记录⑨

NSSCTF之Misc篇刷题记录⑨ [GKCTF 2021]签到[NISACTF 2022]bmpnumber[领航杯江苏省赛 2021]签到题[鹤城杯 2021]Misc2[鹤城杯 2021]A_MISC[GXYCTF 2019]CheckIn[HDCTF 2023]hardMisc[NSSRound#1 Basic]cut_into_thirds[闽盾杯 2021]Modbus的秘密[NISACTF 2022]神秘数字[INSHack…

asp.net+C#超市商品进销存管理系统

本超市商品管理系统主要超市内部提供服务&#xff0c;系统分为管理员员工两部分。 本研究课题重点主要包括了下面几大模块&#xff1a;管用户登录&#xff0c;员工管理&#xff0c;商品管理&#xff0c;进货管理&#xff0c;销售管理&#xff0c;供应商信息&#xff0c;会员信…

2023年6月DAMA-CDGP数据治理专家认证考试,火热报名中

目前6月18日CDGA&CDGP考试目前开放的城市有&#xff1a;北京、上海、广州、深圳、长沙、呼和浩特、杭州、南京、济南、成都、西安、武汉、天津。 新增了武汉、天津这2个城市。另外合肥、厦门、长春等地区还在接近开考人数中&#xff0c;打算参加6月考试的朋友们可以抓紧时间…

前端HTML学习笔记(一)

1、基础知识 网页概述&#xff1a;1、HTML概念&#xff1a;HTML (Hyper Text Markup Language)中文译为超文本标记语言专门用于网页开发的语言&#xff0c;主要通过HTML标签对网页中的文本、图片、音频、视频等内容进行描述。2、网页通常由文字、图片、音频、视频、超链接等部…

Julia入门-0、在Windows下安装Julia

文章目录 0、前言1、相关网站2、Windows 系统下安装Julia3、Julia 交互式命令窗口 0、前言 Julia 是一个面向科学计算的高性能动态高级程序设计语言。 Julia 最初是为了满足高性能数值分析和计算科学的需要而设计的&#xff0c;不需要解释器&#xff0c;速度快。 1、相关网站…

C++类与对象Plus

我们之前讲的都是类与对象的基础&#xff0c;以及类中的几个默认函数等&#xff0c;今天我们就讲一下类与对象的其他东西 初始化列表 在我们的默认构造函数的时候&#xff0c;我们在初始化的时候我们都是在构造函数中完成我们的初始化任务 我们现在来看一个类 我们看一下我们…

基于 LSTM 进行多类文本分类( TensorFlow 2.0)

NLP 的许多创新是如何将上下文添加到词向量中。一种常见的方法是使用循环神经网络。以下是循环神经网络的概念&#xff1a; 他们利用顺序信息。他们可以捕捉到到目前为止已经计算过的内容&#xff0c;即&#xff1a;我最后说的内容会影响我接下来要说的内容。RNNs 是文本和语音…

mac下删除python3.7,并将版本更新到3.9

如何卸载python3.7 有些小伙伴想直接从3.7升级到3.9 那恐怕是不行的&#xff0c;python3.7的库占的空间不少&#xff0c;所以首先我们应该来删除它. python安装后的路径分类 在删除之前需要先了解&#xff1a;python安装后有几类路径需要我们去查看删除 python存储库路径&am…

【分组码系列】线性分组码的网格图和维特比译码

线性分组码的网格图 由于码字的比特位是统计独立的,所以编码过程可以利用有限状态机来描述,它能精确地确定初始和最终状态。可以利用网格图进一步描述编码过程[36],采用维特比算法进行最大似然译码. 在GF(2)上定义线性分组码(n,k)。相应的(n-k)Xn维校验阵可以写成 令码字为系…

TensorFlow vs PyTorch:哪一个更适合您的深度学习项目?

在深度学习领域中&#xff0c;TensorFlow 和 PyTorch 都是非常流行的框架。这两个框架都提供了用于开发神经网络模型的工具和库&#xff0c;但它们在设计和实现上有很大的差异。在本文中&#xff0c;我们将比较 TensorFlow 和 PyTorch&#xff0c;并讨论哪个框架更适合您的深度…

队列、栈专题

队列、栈专题 LeetCode 20. 有效的括号解题思路代码实现 LeetCode 921. 使括号有效的最少添加解题思路代码实现 LeetCode 1541. 平衡括号字符串的最少插入次数解题思路代码实现 总结 不要纠结&#xff0c;干就完事了&#xff0c;熟练度很重要&#xff01;&#xff01;&#xff…

icevision环境安装

Installation - IceVision # 1. git clone 代码# pip 换源&#xff1a; ~/.pip/pip.conf 隐藏文件[global] index-url https://pypi.tuna.tsinghua.edu.cn/simple [install] trusted-hostmirrors.aliyun.compip install -e .[all,dev]ImportError: cannot import name Multi…

chatgpt-4它的未来是什么?该如何应用起来?

在当今快节奏的数字通信世界中&#xff0c;ChatGPT已成为一个强大的在线聊天平台&#xff0c;改变了人们互动和沟通的方式。凭借其先进的AI功能、用户友好的界面和创新技术&#xff0c;ChatGPT已成为个人和企业的热门选择。 然而&#xff0c;ChatGPT的未来有望更加激动人心和具…

VSCode的安装以及相关插件配置

VSCode是什么&#xff1f; VSCode严格来说&#xff0c;也是一款编辑器&#xff0c;强大之处在于集成了各种各样的插件。至此往后&#xff0c;将使用VSCode来取代vim。话不多说&#xff0c;步骤如下&#xff1a; 安装步骤 1、VSCode的下载 https://vscode.cdn.azure.cn/stabl…

NSSCTF (3)

[GDOUCTF 2023]hate eat snake 我们打开js源码 很明显这里当score大于60会出flag score = getScore 我们寻找到了getScore方法所在的地方 之后发现他存在于Snake

Python多线程之_thread与threading模块

Python多线程之_thread与threading模块 在Python程序中&#xff0c;多线程的应用程序会创建一个函数&#xff0c;来执行需要重复执行多次的程序代码&#xff0c;然后创建一个线程执行该函数。一个线程是一个应用程序单元&#xff0c;用于在后台并行执行多个耗时的动作。 在多…

DBWeaver 连接H2数据库 详细教程

1.DBWwaver下载网址 https://github.com/dbeaver/dbeaver/releases 2. 软件安装 点击安装文件&#xff0c;一直下一步即可 3. DBWeaver连接H2数据库 3.1打开软件在搜索框里面输入&#xff1a;h2 3.2 查询到h2数据库 3.3 点击选中的数据库&#xff0c;出现这样的页面&#xf…

铁路信号计轴设备简介

设备概述 计轴设备是铁路信号系统中的一个重要组成部分。它的主要功能是&#xff1a; 利用安装在钢轨上的传感器&#xff0c;来探测进入和出清轨道区段的车轮对数&#xff0c;进而判别轨道区段的占用和出清&#xff0c;其作用与轨道电路等效。 根据两站办理发车进路情况及区…