[JavaScript游戏开发] Q版地图上让英雄、地图都动起来

news/2024/3/4 0:30:29

系列文章目录

第一章 2D二维地图绘制、人物移动、障碍检测
第二章 跟随人物二维动态地图绘制、自动寻径、小地图显示(人物红点显示)
第三章 绘制冰宫宝藏地图、人物鼠标点击移动、障碍检测
第四章 绘制Q版地图、键盘上下左右地图场景切换
第五章 Q版地图上让英雄、地图都动起来


文章目录

  • 系列文章目录
  • 前言
  • 一、本章节效果图
  • 二、任务拆解
    • 2.1、准备【物料层】
      • 2.1.1、在可视窗口里加载地图
      • 2.1.2、加载英雄对象
      • 2.1.3、 加载物料
      • 2.1.4、 编辑地图数据
    • 2.2、设置物料层可视区域的行、列
    • 2.3、调整地图和英雄的步骤跨度一致
    • 2.4、在键盘上下左右事件里,增加英雄动作的逻辑,融合英雄、地图的移动逻辑,增加边界检测
    • 2.5、看看最终效果
      • 2.5.1、荷花池边打卡
      • 2.5.2、西梁女国打卡
      • 2.5.3、跑累了在后花园休息
      • 2.5.4、休息完去大礼堂门口转一转
      • 2.5.5、最后在后山瞅一眼
  • 总结


前言

本章内容在第一章【2D二维地图绘制、人物移动、障碍检测】、第四章【绘制Q版地图、键盘上下左右地图场景切换】的基础上进行了升级,因此带大家回顾下这两章的内容

  • 使用JavaScript绘制简单的二维地图(第一章实现)
    采用二维数组存储地图信息,使用表格绘制地图,每个td单元格存储数据
  • 键盘上下左右控制(第一章实现,本章节增加地图层控制)
    使用JavaScript keyPress键盘事件监听WASD键,按键触发时人物做出相应操作
  • 障碍物碰撞检测(采用格子碰撞检测,第一章实现)
    人物下一步碰撞到障碍时,提示遇到障碍,终止人物运动
  • 增加地图层(第四章实现)
    地图层与数据层(二维网格、人物)分离;主地图在初始化时加载,显示可视区域
  • 人物、地图跟随变动
    保持人物在地图中心,检测特殊情况( 进入边界内时保持地图不动、人物运动)

一、本章节效果图

请添加图片描述

二、任务拆解

在第四章基础上继续添加任务
1、准备【物料层】,设置为地图图片高、宽, 计算物料层2D网格的行、列
2、设置物料层可视区域的行、列;
3、调整地图和英雄的步骤跨度一致;
4、在键盘上下左右事件里,增加英雄动作的逻辑,融合英雄、地图的移动逻辑,增加边界检测
5、看看最终效果

2.1、准备【物料层】

2.1.1、在可视窗口里加载地图

<div style="width: 95%; height: 95%; position: absolute; background-color: red; overflow: hidden;  " id="parentDiv"><div style="z-index: 1; height: 2480px; width: 3280px"  id="mapDiv" ><table class="main bg" id="map1001"></table></div>
</div><style>table.main  {border-collapse: collapse;}table.main td {/*border: 0.5px red solid;*/  //调试地图时可开启width: 79px;height: 79px;}
</style>

2.1.2、加载英雄对象

    <script>// 英雄对象var hero = {currentPoint : [4, 6],   //初始化英雄的位置是 4,6}</script>

2.1.3、 加载物料

导入物料js
<script src="../js/item.js"></script>

item.js

// 物品
var item = {};item.initItem = function (){item.empty = 0;   //空地或草坪item.stone = 1;   //石头的标记是1item.factory = 2; //工厂item.girl = 3;  //女子item.girl_01 = 4; //女孩item.kt = 5; //空投大礼包item.lz = 6; //路障item.pz = 7; //喷子item.zz = 8; //沼泽item.hero = 9;   //英雄的标记是9item.heroHasPath = 10;   //自动寻径的英雄标记是10item.wdss = 11;  //僵尸的标记是11item.lzAndempty = 12;  //空白的路障item.datas = [];  // 物品的图片集合var itemPrefixPath = "../img/item/";item.datas[0] = "";  // 可行走的路径item.datas[1] = itemPrefixPath + "stone.png";item.datas[2] = itemPrefixPath + "gc.png";item.datas[3] = itemPrefixPath + "girl.png";item.datas[4] = itemPrefixPath + "girl.bmp";item.datas[5] = itemPrefixPath + "kt.png";item.datas[6] = itemPrefixPath + "lz.png";item.datas[7] = itemPrefixPath + "pz.png";item.datas[8] = itemPrefixPath + "zz.png";item.datas[9] = itemPrefixPath + "/spine/hero002.gif";item.datas[10] = itemPrefixPath + "/spine/tank.gif";item.datas[11] = itemPrefixPath + "wdss.gif";item.datas[12] = "";  //看不见的路障
}

2.1.4、 编辑地图数据

根据地图绘制可行走路径,

	/*** 加载地图数据* 0 可走的路径* 12 看不见的路障* @type {number[]}*/var mapData = [[12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12 ],[12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12 ],[12, 12, 12, 12,  0, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,  0, 12, 12, 12, 12, 12 ],[12, 12, 12,  0,  0, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,  0,  0, 12, 12, 12, 12, 12 ],[12, 12, 12,  0,  0,  0,  0,  0,  0,  0, 12, 12, 12, 12, 12, 12,  0, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,  0,  0,  0,  0,  0,  0,  0, 12, 12, 12, 12, 12 ],[12, 12, 12,  0,  0,  0,  0,  0,  0,  0, 12, 12, 12, 12, 12, 12,  0, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,  0,  0,  0,  0,  0,  0,  0,  0, 12, 12, 12, 12, 12 ],[12, 12,  0,  0,  0,  0,  0,  0,  0,  0, 12, 12, 12, 12, 12, 12,  0,  0,  0, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,  0,  0, 12, 12,  0,  0, 12, 12, 12, 12, 12 ],[12, 12, 12, 12, 12, 12, 12, 12,  0,  0,  0, 12, 12, 12, 12, 12, 12, 12,  0,  0,  0,  0,  0,  0,  0,  0, 12, 12, 12, 12, 12, 12, 12, 12,  0,  0, 12, 12, 12, 12 ],[12, 12, 12, 12, 12, 12, 12, 12,  0,  0,  0,  0, 12, 12, 12, 12, 12, 12, 12, 12,  0,  0,  0,  0,  0,  0,  0,  0, 12, 12,  0,  0,  0,  0,  0,  0,  0, 12, 12, 12 ],[12, 12, 12, 12, 12, 12, 12, 12, 12,  0,  0,  0, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 12, 12, 12, 12, 12 ],[12, 12, 12, 12, 12, 12, 12, 12, 12, 12,  0,  0,  0,  0, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,  0,  0,  0,  0,  0,  0, 12, 12, 12, 12, 12, 12, 12, 12 ],[12, 12, 12, 12, 12, 12, 12, 12, 12, 12,  0,  0,  0,  0,  0,  0, 12, 12,  0,  0,  0,  0,  0, 12, 12,  0,  0,  0,  0, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12 ],[12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12 ],[12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,  0,  0,  0,  0,  0,  0, 12,  0, 12, 12, 12, 12, 12, 12,  0,  0, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12 ],[12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,  0,  0,  0,  0, 12,  0,  0,  0,  0,  0, 12, 12, 12, 12, 12,  0,  0, 12,  0,  0,  0, 12, 12, 12, 12, 12, 12 ],[12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,  0,  0,  0,  0, 12,  0,  0,  0,  0,  0, 12, 12, 12, 12, 12, 12,  0, 12,  0,  0,  0, 12, 12, 12, 12, 12, 12 ],[12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,  0,  0,  0,  0, 12, 12, 12, 12,  0, 12, 12, 12, 12, 12, 12, 12,  0,  0,  0,  0,  0, 12, 12, 12, 12, 12, 12 ],[12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,  0,  0, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,  0,  0,  0,  0, 12, 12, 12, 12, 12, 12, 12 ],[12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,  0,  0, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,  0,  0,  0,  0,  0,  0, 12, 12, 12, 12, 12 ],[12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,  0,  0, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,  0,  0,  0, 12, 12,  0,  0,  0,  0, 12, 12 ],[12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,  0,  0, 12, 12, 12, 12, 12, 12, 12, 12, 12,  0,  0,  0,  0, 12, 12, 12,  0, 12, 12,  0, 12, 12 ],[12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,  0,  0,  0, 12, 12, 12, 12,  0,  0,  0,  0,  0,  0,  0, 12, 12, 12,  0, 12, 12,  0, 12, 12 ],[12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 12, 12,  0,  0,  0,  0,  0,  0, 12, 12 ],[12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,  0,  0,  0,  0, 12, 12,  0,  0,  0,  0,  0,  0,  0, 12, 12,  0,  0,  0,  0,  0,  0, 12, 12 ],[12, 12, 12, 12, 12, 12, 12, 12,  0,  0, 12, 12, 12, 12, 12, 12, 12, 12,  0,  0, 12, 12, 12,  0,  0,  0,  0,  0,  0,  0, 12, 12,  0,  0,  0,  0,  0,  0, 12, 12 ],[12, 12, 12, 12, 12, 12, 12, 12, 12,  0,  0, 12, 12, 12, 12,  0,  0,  0,  0,  0, 12, 12, 12, 12, 12,  0,  0,  0,  0,  0, 12, 12,  0,  0,  0,  0,  0,  0, 12, 12 ],[12, 12, 12, 12, 12, 12, 12, 12,  0,  0,  0, 12, 12,  0,  0,  0,  0,  0, 12, 12, 12, 12, 12, 12, 12,  0, 12,  0,  0,  0,  0, 12,  0,  0,  0,  0, 12, 12, 12, 12 ],[12, 12, 12, 12, 12, 12, 12, 12,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 12, 12, 12, 12, 12, 12, 12, 12,  0,  0, 12,  0,  0, 12, 12, 12, 12, 12, 12, 12, 12, 12 ],[12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,  0,  0,  0,  0,  0,  0, 12, 12, 12, 12, 12, 12, 12, 12, 12,  0, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12 ],[12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12 ]]

2.2、设置物料层可视区域的行、列

1、加载物料到地图对象里
2、设置可视区域的行、列
3、增加英雄与上下边框的距离计算方法
4、增加英雄与左右边框的距离计算方法

	// 地图对象var mapObj = {data: mapData,  //地图上的物品数据// 设定地图最大的高度maxRow: 8,// 地图的行row: function (){return mapObj.data.length > this.maxRow ? this.maxRow : mapObj.data.length},// 设定地图最大的列maxCol: 12,//地图的列col: function (){return mapObj.data[0].length > this.maxCol ? this.maxCol : mapObj.data[0].length;},// 英雄与上下边框的距离heroMarginTop: function () {return  Math.floor( this.row() / 2)},// 英雄与左右边框的距离heroMarginLeft: function () {return  Math.floor( this.col() / 2)},}

2.3、调整地图和英雄的步骤跨度一致

	var stepDistance = 80;   // td的高、宽也设置成80或79px

2.4、在键盘上下左右事件里,增加英雄动作的逻辑,融合英雄、地图的移动逻辑,增加边界检测

在这里插入图片描述
1、在body标签上增加键盘事件
2、在文档准备好之后开始执行初始化方法
3、定义游戏窗口层、游戏地图层,并渲染页面
4、定义 键盘上下左右事件
5、在第四章基础上,上下左右事件里增加英雄动作的逻辑,融合英雄、地图的移动逻辑
6、增加双重地图检测,保持英雄在地图的中心位置(地图、英雄一起移动)
7、增加英雄边界检测(英雄在边界内时,只移动人物,不移动地图)
8、简单的碰撞检测,下一步到达的目标只有是空地的情况,英雄才能移动

		<body onkeydown="keydown(event)"></body>//文档准备好之后开始执行window.onload = function () {init();}/*** 定义游戏窗口层、游戏地图层,并渲染页面*/function init() {// 定义游戏窗口层parentDivEle = document.getElementById("parentDiv");// 定义游戏地图层mapDivEle = document.getElementById('mapDiv');// 获取 1001地图 Dom元素mapDiv = document.getElementById("map1001");parentDivEle.style.width =  (mapObj.col() + 1) * stepDistance  + "px";parentDivEle.style.height = (mapObj.row() + 1) * stepDistance + "px";item.initItem();//二维数组里,去初始化熊猫的位置mapObj.data[hero.currentPoint[0]][hero.currentPoint[1]] = item.hero;loadData();}/*** 人物移动方法* @param point*/function operateHero(point) {mapObj.data[hero.currentPoint[0]][hero.currentPoint[1]] = item.heromapObj.data[point[0]][point[1]] = item.emptyloadData();}/***  渲染地图* @param mapData*/function loadData() {// 加载地图mapDivEle.style.background= 'url("../img/item/bg/os.jpg")';//渲染一行 row 列的数据var mapHTML = "";for (var i = 0; i < mapObj.data.length; i++) {mapHTML += "<tr>";for (var j = 0; j < mapObj.data[0].length ;j++) {if (mapObj.data[i][j] == item.empty) {   //只有点击路,才能自动寻径mapHTML += "<td οnclick='tdClick(" + i + "," + j + ")'></td>";} else if(  mapObj.data[i][j] == item.lzAndempty ) {mapHTML += "<td></td>";} else {mapHTML += '<td><img src="'+ item.datas[mapObj.data[i][j]] +'" style="width: 100%; height: 100%; border-radius: 0%;" ></td>';}}mapHTML += "</tr>";}// 渲染大地图mapDiv.innerHTML = mapHTML;}/*** 定义 键盘上下左右事件* 并判断边界* @param e*/var keydown = function (e) {if (e.keyCode == 37) {console.log("向左")if( Number(mapDivEle.style.marginLeft.replaceAll("px", "")) - stepDistance < 0 ) {var point = hero.currentPoint;var xPoint = hero.currentPoint[1] -1;var yPoint = hero.currentPoint[0];if (checkStone(yPoint, xPoint)) {console.log("碰撞到障碍了,停止动作")return}console.log("移动后的位置:x:" + xPoint + " , y:" + yPoint)if( xPoint <= (mapObj.data[0].length - mapObj.heroMarginLeft()) && Number(mapDivEle.style.marginLeft.replaceAll("px", "")) ) {mapDivEle.style.marginLeft = Number(mapDivEle.style.marginLeft.replaceAll("px", "")) + stepDistance + "px";}hero.currentPoint = [yPoint, xPoint]operateHero(point);} else {console.log("超出边界")}} else if (e.keyCode == 38) {console.log("向上")if( Number(mapDivEle.style.marginTop.replaceAll("px", "") ) - stepDistance < 0 ) {var point = hero.currentPoint;var xPoint = hero.currentPoint[1];var yPoint = hero.currentPoint[0] - 1;if (checkStone(yPoint, xPoint)) {console.log("碰撞到障碍了,停止动作")return}console.log("移动后的位置:x:" + xPoint + " , y:" + yPoint)if( yPoint <= (mapObj.data.length - mapObj.heroMarginTop()) &&  Number(mapDivEle.style.marginTop.replaceAll("px", "")) < 0 ) {mapDivEle.style.marginTop = Number(mapDivEle.style.marginTop.replaceAll("px", "")) + stepDistance + "px";}hero.currentPoint = [yPoint, xPoint]operateHero(point);} else {console.log("超出边界")}} else if (e.keyCode == 39) {console.log("向右")if ( (parentDivEle.clientWidth) - mapDivEle.clientWidth <= Number(mapDivEle.style.marginLeft.replaceAll("px", ""))) {var point = hero.currentPoint;var xPoint = hero.currentPoint[1] + 1;var yPoint = hero.currentPoint[0];if (checkStone(yPoint, xPoint)) {console.log("碰撞到障碍了,停止动作")return}// 超出边界,只移动英雄, 不移动地图if (  xPoint > mapObj.heroMarginLeft()  && (parentDivEle.clientWidth) - mapDivEle.clientWidth + stepDistance <= Number(mapDivEle.style.marginLeft.replaceAll("px", ""))) {mapDivEle.style.marginLeft = Number(mapDivEle.style.marginLeft.replaceAll("px", "")) - stepDistance + "px";}console.log( "移动后的x轴距离:" + xPoint * stepDistance);console.log("移动后的位置:x:" + xPoint + " , y:" + yPoint)hero.currentPoint = [yPoint, xPoint]operateHero(point);} else {console.log("超出边界")}} else if (e.keyCode == 40) {console.log("向下")if( (parentDivEle.clientHeight) - mapDivEle.clientHeight  <= Number(mapDivEle.style.marginTop.replaceAll("px", "")) ) {var point = hero.currentPoint;var xPoint = hero.currentPoint[1];var yPoint = hero.currentPoint[0] + 1;if (checkStone(yPoint, xPoint)) {console.log("碰撞到障碍了,停止动作")return}console.log("移动后的位置:x:" + xPoint + " , y:" + yPoint)// 超出边界,只移动英雄, 不移动地图if( yPoint > mapObj.heroMarginTop()  &&  (parentDivEle.clientHeight) - mapDivEle.clientHeight + stepDistance <= Number(mapDivEle.style.marginTop.replaceAll("px", "")) ) {mapDivEle.style.marginTop = Number(mapDivEle.style.marginTop.replaceAll("px", "")) - stepDistance + "px";}hero.currentPoint = [yPoint, xPoint]operateHero(point);} else {console.log("超出边界")}}loadData();}/*** 障碍检测(可加多个障碍条件)* @param yPoint* @param xPoint* @returns {boolean}*/function checkStone(yPoint, xPoint) {return mapObj.data[yPoint][xPoint] != item.empty;}

2.5、看看最终效果

2.5.1、荷花池边打卡

在这里插入图片描述

2.5.2、西梁女国打卡

在这里插入图片描述

2.5.3、跑累了在后花园休息

在这里插入图片描述

2.5.4、休息完去大礼堂门口转一转

在这里插入图片描述

2.5.5、最后在后山瞅一眼

在这里插入图片描述


总结

以上就是今天要讲的内容,本文简单介绍Q版地图的绘制,地图/英雄的移动、边界检测,喜欢的同学可以参考第二张把自动寻径加上。
原生JavaScript知识点就到这里结束了,以后前端知识点主要以Vue为主。


http://www.ppmy.cn/news/1010172.html

相关文章

linux下载软件包

linux下载软件包 linux下只有两种软件包 源码包(tar 压缩包&#xff0c;如有.tar.gz 和.tar.bz2) 二进制包(rpm) centos下 (除了rpm还有srpm&#xff0c;srpm 包为未编译过的 rpm 包&#xff0c;需要以 rpm 管理的方式编译&#xff0c;然后以 rpm 的安装方式安装) RPM包操作 rp…

训练强化学习的经验回放策略:experience replay

经验回放&#xff1a;Experience Replay&#xff08;训练DQN的一种策略&#xff09; 优点&#xff1a;可以重复利用离线经验数据&#xff1b;连续的经验具有相关性&#xff0c;经验回放可以在离线经验BUFFER随机抽样&#xff0c;减少相关性&#xff1b; 超参数&#xff1a;Rep…

SSE技术和WebSocket技术实现即时通讯

文章目录 一、SSE1.1 什么是SSE1.2 工作原理1.3 特点和适用场景1.4 API用法1.5 代码实现 二、WebSocket2.1 什么是WebSocket2.2 工作原理2.3 特点和适用场景2.4 API用法2.5 代码实现 三、SSE与WebSocket的比较 当涉及到实现实时通信的Web应用程序时&#xff0c;两种常见的技术选…

Tomcat 编程式启动 JMX 监控

通过这篇文章&#xff0c;我们可以了解到&#xff0c;利用 JMX 技术可以方便获取 Tomcat 监控情况。但是我们采用自研的框架而非大家常见的 SpringBoot&#xff0c;于是就不能方便地通过设置配置开启 Tomcat 的 JMX&#xff0c;——尽管我们也是基于 Tomcat 的 Web 容器&#x…

JAVA实现二分法查找算法

现实生活中经常会遇到将具有某个特征的元素选择出来&#xff0c;并找出对应的位置。 现在来一个小测验&#xff0c;在以数组【1&#xff0c;4&#xff0c;8&#xff0c;3&#xff0c;0&#xff0c;7&#xff0c;56】中找到8所在的位置&#xff0c;很明显大家可以通过直观的感受…

Linux 系统编程 开篇/ 文件的打开/创建

从本节开始学习关于Linux系统编程的知识&#xff01; 学习Linux的系统编程有非常多的知识点&#xff0c;在应用层面&#xff0c;很重要的一点就是学习如何“用代码操作文件来实现文件创建&#xff0c;打开&#xff0c;编辑等自动化执行” 那如何自动化实现对文件的创建&#…

学python的心得体会1000字,学python的心得体会2000字

这篇文章主要介绍了学python的心得体会2000字&#xff0c;具有一定借鉴价值&#xff0c;需要的朋友可以参考下。希望大家阅读完这篇文章后大有收获&#xff0c;下面让小编带着大家一起了解一下。 1. 初学者应该从简单的练习开始&#xff0c;先掌握基本的语法和概念&#xff0c;…

【网络基础实战之路】基于三个分公司的内网搭建并连接运营商的实战详解

系列文章传送门&#xff1a; 【网络基础实战之路】设计网络划分的实战详解 【网络基础实战之路】一文弄懂TCP的三次握手与四次断开 【网络基础实战之路】基于MGRE多点协议的实战详解 【网络基础实战之路】基于OSPF协议建立两个MGRE网络的实验详解 PS&#xff1a;本要求基于…

6年资深测试整理,接口测试总结,你不知道的都在这了...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 接口测试 是测试…

如何将 dubbo filter 拦截器原理运用到日志拦截器中?

业务背景 我们希望可以在使用日志拦截器时&#xff0c;定义属于自己的拦截器方法。 实现的方式有很多种&#xff0c;我们分别来看一下。 拓展阅读 java 注解结合 spring aop 实现自动输出日志 java 注解结合 spring aop 实现日志traceId唯一标识 java 注解结合 spring ao…

Java - 两种判断闰年的方法

&#x1f914;️判断一个年份是否是闰年的常规方法是遵循以下规则&#xff1a; 如果年份能够被4整除&#xff0c;但不能被100整除&#xff0c;那么它是闰年。如果年份能够被400整除&#xff0c;那么它也是闰年。 boolean b1 (y & 3) 0 && ((y % 100 ! 0) || (y %…

Netty:通过Channel发送ByteBuf的数据,只发送可读的字节

说明 使用Netty Channel发送数据的时候&#xff0c;如果发送的数据存放在ByteBuf中&#xff0c;那么只会发送ByteBuf中可读的字节。即便容量&#xff08;capacity&#xff09;大于可读字节数&#xff0c;那也不会多发送数据。 示例 代码片段 package com.thb.power.termina…

嵌入式开发学习(STC51-13-温度传感器)

内容 通过DS18B20温度传感器&#xff0c;在数码管显示检测到的温度值&#xff1b; DS18B20介绍 简介 DS18B20是由DALLAS半导体公司推出的一种的“一线总线&#xff08;单总线&#xff09;”接口的温度传感器&#xff1b; 与传统的热敏电阻等测温元件相比&#xff0c;它是一…

Gof23设计模式之组合模式

1.定义 ​组合模式又名部分整体模式&#xff0c;是用于把一组相似的对象当作一个单一的对象。组合模式依据树形结构来组合对象&#xff0c;用来表示部分以及整体层次。这种类型的设计模式属于结构型模式&#xff0c;它创建了对象组的树形结构。 2.结构 组合模式主要包含三种…

MySql的Windows安装指南

目录 一、MySQL的4大版本 二、软件的下载 三、MySQL8.0 版本的安装 四、配置MySQL8.0 五、配置MySQL8.0 环境变量 六、登录验证 一、MySQL的4大版本 MySQL Community Server 社区版本&#xff0c;开源免费&#xff0c;自由下载&#xff0c;但不提供官方技术支持&#xff…

Detecting Everything in the Open World: Towards Universal Object Detection

1. 论文简介 论文题目《Detecting Everything in the Open World: Towards Universal Object Detection》发表情况&#xff0c;CVPR2023[论文地址][https://arxiv.org/pdf/2303.11749.pdf][代码地址][https://github.com/zhenyuw16/UniDetector] 2.背景与摘要 本文旨在解决通…

Effective Java笔记(20)接口优于抽象类

Java提供了两种机制&#xff0c;可以用来定义允许多个实现的类型&#xff1a;接口和抽象类。自从Java 8为继承引入了缺省方法( default method)&#xff0c;这两种机制都允许为某些实例方法提供实现。主要的区别在于&#xff0c;为了实现由抽象类定义的类型&#xff0c;类必须成…

c++实现Qt信号和槽机制

文章目录 简介信号槽信号与槽的连接 特点观察者模式定义观察者模式结构图 实现简单的信号和槽 简介 信号槽机制与Windows下消息机制类似&#xff0c;消息机制是基于回调函数&#xff0c;Qt中用信号与槽来代替函数指针&#xff0c;使程序更安全简洁。  信号和槽机制是 Qt 的核心…

Python-面向对象:面向对象、成员方法 、类和对象、构造方法、魔术方法、封装、继承、类型注解、多态(抽象类(接口))

版本说明 当前版本号[20230806]。 版本修改说明20230806初版 目录 文章目录 版本说明目录知识总览图面向对象初识对象生活中数据的组织程序中数据的组织使用对象组织数据 成员方法类的定义和使用成员变量和成员方法成员方法的定义语法注意事项 类和对象现实世界的事物和类使…

六、ESP32数码管显示数字

1. 本节课的成功 2. 数码管 为什么会亮呢? 答:里面就是LED灯
最新文章