当前位置: 首页 > news >正文

织梦网站图片怎么修改不了/百度账号中心官网

织梦网站图片怎么修改不了,百度账号中心官网,wordpress 会员支付,淘宝网站是怎么做的吗目录 效果如下 目录结构 GameEntity.js GrawGame.js konva.min.js PlayGame.js veriable.js index.html 结语: 前期回顾 卡通形象人物2 写代码-睡觉 丝滑如德芙_0.活在风浪里的博客-CSDN博客本文实现了包含形象的卡通小人吃、睡、电脑工作的网页动画https://…

目录

效果如下

 目录结构

 GameEntity.js

 GrawGame.js

konva.min.js

PlayGame.js

veriable.js

index.html

结语:


前期回顾

卡通形象人物2 写代码-睡觉 丝滑如德芙_0.活在风浪里的博客-CSDN博客本文实现了包含形象的卡通小人吃、睡、电脑工作的网页动画https://blog.csdn.net/m0_57904695/article/details/128981376?spm=1001.2014.3001.5501

本文实现了包含形象斗地主网页游戏,js循环动画,简单生动的画面设计。非常丝滑有意思,欢迎对此代码感兴趣的朋友前来下载参考。

如果大家非常好奇该段代码所带来的网页游戏效果的话,那就直接拷贝到自己电脑上,不上传了资源了,方便大家直接玩乐,如果对你有些微帮助还请收藏以备下次及时找到!

  本文直接复制可以用,

效果如下

 目录结构

 GameEntity.js


/*** 实体类;有些实体其中的行为,* 可能没有严格符合面向对象规范,* 原因在于对象与过程之间的界限难以区分*/// 玩家
class Player{constructor(BoardList, name, color){this.Color = color// Board对象this.BoardList = BoardListthis.name = namethis.GroupBoard = null}// 通过ID获取牌GetBoardOfID(id){if(this.BoardList.length>0){for(let i=0;i<this.BoardList.length;i++){if(this.BoardList[i].id == id)return i}}return -1}// 根据ID删除节点DeleteIDOfBoard(id){if(this.BoardList.length<1) returnlet index_ = this.GetBoardOfID(id)this.BoardList.splice(index_, 1)}// 将手中的牌按照顺序排列BoardListSort(){BoardSort(this.BoardList)}// 提示出牌AutoSendBoard(){// 提示出牌需要满足几个条件,// 首先上家没有出牌时,那么按照最大的类型出牌(炸弹除外),如Y2>Y1// 如果上家有出牌,那么需要判断当前牌组之中是否有相对应类型的牌// 玩家需要自己维护自己所有的牌总量(机器人由程序维护),如一手牌组当中有几个飞机几个顺子}// 将当前的牌聚类为一个个的牌组合;返回牌组合数组// 如:987654333 return: Y5,Y3,Y2ClusterType(){}
}// 牌对象
// type ♥,♠,♦,♣
class Board{constructor(surface, type, id){this.surface = surfacethis.type = typethis.id = type + idthis.DrawBoardFront = CreateBorad(width/2-30, height/2-45, this)this.DrawBoardFront._id = id// id必须是要唯一的this.DrawBoardBack = BoardBack(width/2-30, height/2-45, this)this.DrawBoardBack._id = '0'+id}}// 组合牌
class BoardCombin{constructor(BoardList, Type, Value, length){this.BoardList = BoardListthis.Type = Typethis.Value = Valuethis.Length = length}
}// 这里可以优化,使用有限状态机会更好,逻辑更清晰
// 判定出牌边界,类型一致,牌的数量一致,不小于桌面价值量
// 单:    1;     Y1
// 对:    2;     Y2  *
// 三带:  3~5;   Y3 
// 顺:    5~12;  Y4
// 连对:   6~16;  Y5  *
// 飞机:   6~16;  Y6
// 四带二: 6~8;   Y7  *
// 炸弹:   4      Y8  *
// 王炸:   2      Y8  *
// 牌组分类器
class BoardType{constructor(BoardList, Boards){this.Boards = BoardListthis.BoardList = new Array()if(Boards!=null) this.BoardList = Boards// 将牌对象划为简单的字面量this.BoardListValue = new Array();for(let i=0;i<BoardList.length;i++){this.BoardList.push( BoardList[i].surface )this.BoardListValue.push(BoardMarkMap.get(BoardList[i].surface))}}// 获取出牌的类型,判定牌是否严格属于哪一类型GetType(){var length = this.BoardList.length;// 单牌if(length === 1){return this.FiltrateSign(this.BoardList)}// 对子,王炸if(length === 2){return this.FiltrateTow(this.BoardList)}// 三带,炸弹if(length>=3 && length<=5){return this.FiltrateThree(this.BoardList)}// 飞机,连对,顺子,四带二if(length>=5 && length<=16){return this.FiltrateLine(this.BoardList)}}// 单牌过滤FiltrateSign(BoardList_){var value_ = BoardMarkMap.get(BoardList_[0])return new BoardCombin(this.Boards, "Y1", value_, 1)}// 双牌过滤=》王炸FiltrateTow(BoardList_){if(BoardList_[0]===BoardList_[1]){var value_ = BoardMarkMap.get(BoardList_[0])return new BoardCombin(this.Boards, "Y2", value_, 2)} else{return this.FiltrateKingMax(BoardList_)}}// 三带过滤=》顺子=》炸弹FiltrateThree(BoardList_){var temp = BoardList_.join('')// 其中任一一张牌出现三次以上var reg = /(\d|J|Q|K|A)\1{2}/var index = temp.search(reg)if(!reg.test(temp)) {// 如果没有匹配到三带,那么有可能是顺子if(temp.length===5) return this.FiltrateLine(BoardList_)return null};var value_ = BoardMarkMap.get(BoardList_[index])// 判断是三不带|三带一|三带对temp = temp.replace(reg, '')if(temp.length==0)return new BoardCombin(this.Boards, "Y3", value_, 3)if(temp.length==1 && temp!=BoardList_[index])return new BoardCombin(this.Boards, "Y3", value_, 4)else if(temp.length==1){return this.FiltrateBomb(BoardList_);}if(temp.length==2 && temp[0] == temp[1])return new BoardCombin(this.Boards, "Y3", value_, 5)return null}// 顺子过滤=》连对=》飞机=》四带二FiltrateLine(BoardList_){var temp = BoardList_.join('')// 如果牌组数量大于5,那么更有可能是连对或者飞机,四带二if(temp.length>5){var tempData = null;// 过滤连对,过滤四带二,只有偶数才可if(temp.length%2===0){tempData = this.FiltrateLineTwo(BoardList_)if(tempData != null) return tempDatavar tempData = this.FiltrateFour(BoardList_)if(tempData != null) return tempData}// 飞机过滤tempData = this.FiltrateAir(BoardList_)if(tempData != null) return tempData}// 如果出现2,小鬼,大鬼那么就不是顺子var reg = /(2|C|G)/if(reg.test(temp)) return null;var value_ = this.BoardListValue[0]for(var i=1; i<BoardList_.length; i++){// 顺子必须是连续的,即每个数之间相差要等于1if(this.BoardListValue[i-1]-this.BoardListValue[i]!=1)return null;}return new BoardCombin(this.Boards,'Y4', value_, BoardList_.length)}// 飞机过滤// 飞机可带两张单牌,或者两个对子,亦或者不带FiltrateAir(BoardList_){var temp = BoardList_.join('')// 其中任多张牌出现三次var reg = /(0|[3-9]|J|Q|K|A)\1{2}/g // 三带var tempList_1 = temp.match(reg)if(tempList_1==null) return nullvar recode = 0// 飞机至少要是两个连起来的三带for(var i=1; i<tempList_1.length; i++){var i1 = BoardMarkMap.get(tempList_1[i][0])var i2 = BoardMarkMap.get(tempList_1[i-1][0])if(i2-i1==1){temp = temp.replace(tempList_1[i],'')temp = temp.replace(tempList_1[i-1],'')}elserecode++}var len = tempList_1.length-recodeif(len<2) return null// 返回牌组对象var value_ = BoardMarkMap.get(tempList_1[0][0])// 三不带if(temp.length===0)return new BoardCombin(this.Boards, 'Y6', value_, BoardList_.length)// 判断剩余的牌,剩余的牌有可能是单牌也可能是对子var reg_Two = /(\d|J|Q|K|A|2)\1{1}/g // 对子var tempList_2 = temp.match(reg_Two)// 飞机带对子,每个飞机可以带一个对子所以必须数量一致if(tempList_2!=null && tempList_2.length!=len && temp.length!=len)return nullif(tempList_2==null && temp.length!=len)return nullreturn new BoardCombin(this.Boards, 'Y6', value_, BoardList_.length)}// 四带二,四可带两张or两对FiltrateFour(BoardList_){if(BoardList_.length>8) return null// 因为四带二是由炸弹组成,匹配四张牌var temp = BoardList_.join('')// 其中任一一张牌出现四次var reg = /(\d|J|Q|K|A)\1{3}/var index = temp.search(reg)if(index==-1) return null// 将四张一样的牌剔除掉temp = temp.replace(reg,'')var reg_Two = /(\d|J|Q|K|A|C|G)\1{1}/g// 匹配剩余的牌;var temp_list2 = temp.match(reg_Two)if(temp.length==4 && temp_list2.length!=2) return null if(temp.length==2 && temp_list2.length==0)return null// 获取四带二的价值面var value_ = BoardMarkMap.get(BoardList_[index])return new BoardCombin(this.Boards, 'Y7', value_, BoardList_.length)}// 连对FiltrateLineTwo(BoardList_){var temp = BoardList_.join('')// 连对边缘判断,包含2,小鬼,大鬼就不是连对,且连对为偶数if((/(2|C|G)/).test(temp) || temp.length%2!=0) return null;var reg = /(\d|J|Q|K)\1{1}/gif(temp.replace(reg,'')!=='')return null;var tempList = temp.match(reg)if(tempList.length>=3){// 判断连续的对子是否为顺序的for(let j=1; j<tempList.length; j++){var tempData_1 = BoardMarkMap.get(tempList[j][0])var tempData_2 = BoardMarkMap.get(tempList[j-1][0])if(tempData_2-tempData_1!==1)return null;}}var value_ = BoardMarkMap.get(tempList[0][0])return new BoardCombin(this.Boards, 'Y5', value_, BoardList_.length)}// 炸弹FiltrateBomb(BoardList_){var temp = BoardList_.join('')// 其中任一一张牌出现四次var reg = /(\d|J|Q|K)\1{3}/if(!reg.test(temp)) return nullvar value_1 = BoardMarkMap.get(BoardList_[0])return new BoardCombin(this.Boards, 'Y8', value_1, 4)}// 王炸FiltrateKingMax(BoardList_){if(BoardList_[0]==="G" && BoardList_[1]==="C"){var value_1 = BoardMarkMap.get(BoardList_[0])var value_2 = BoardMarkMap.get(BoardList_[1])return new BoardCombin(this.Boards, "Y8", value_1+value_2, 2)}return null}// 将牌变为所有该类型GetAllType(type, value_){switch(type){case 'Y1':return this.FiltrateSign_All(value_)}}// 返回最小的一张单牌FiltrateSign_All(value_){for(let i=this.BoardListValue.length; i>0; i--){if(this.BoardListValue[i-1]>value_)return [this.Boards[i-1]]}return null}}// 玩家出牌记录器
class BoardPlayer{constructor(BoardList, PlayerIndex){if(BoardList instanceof Map)BoardList = Array.from(BoardList.values())// 先将牌面进行排序BoardSort(BoardList)let Boards = new BoardType(BoardList)// 再将牌变为合法的规则牌this.CurrentBoardCombin = Boards.GetType()this.CurrentBoards = Boards.Boardsthis.PlayerIndex = PlayerIndex}Show(){let typeShow = this.CurrentBoardCombinif(typeShow==null) {TxtInfo.innerText = '无效牌'return null}TxtInfo.innerText = BoardTypeMap.get(typeShow.Type)+'-'+typeShow.Valuereturn typeShow}
}// 已出牌池
class BoardPond{constructor(){this.CurrentBoardPond = new Array()}// 出牌,将牌置入出牌池SetAddBoard(BoardPlayer){this.CurrentBoardPond.unshift(BoardPlayer)}// 获取牌顶的类型GetCurrentBoard(){return this.CurrentBoardPond[0].CurrentBoardCombin}
}

 GrawGame.js

/*** 游戏的画面及动作绘制*///------------------- 绘制各种图形和动作// 绘制牌
function CreateBorad(x, y, Board){var group = new Konva.Group()var text = Board.surfacevar color = 'black'var width_ = 25var x_ = x+5if(text=='G'){color = 'red'}if(text=='C'||text=='G') {width_ = 14text='Joke'}if(text=='0') {text = '10' x_ = x+8}var type = Board.typevar rect = new Konva.Rect({x: x,y: y,stroke: '#555',fill: 'white',strokeWidth: 1,shadowColor: 'black',shadowBlur: 0,shadowOffset: { x: 5, y: 5 },shadowOpacity: 0.3,width: BoardWidth,height: BoardHight,});group.add(rect)if(type=='♠' || type=='♣') color = 'black'else if(type=='♥' || type=='♦') color = 'red'var BoardTxt = new Konva.Text({x: x+5,y: y+5,text: text,fontSize: 18,width: width_,fill: color});group.add(BoardTxt)if(text!='Joke'){group.add(new Konva.Text({x: x_,y: y+20,text: type,fontSize: 20,fill: color}))group.add(new Konva.Text({x: x+BoardWidth*0.33,y: y+25,text: type,fontSize: BoardWidth*0.666+5,fill: color}))}else{// 绘制大符号group.add(new Konva.Text({x: x+BoardWidth*0.266,y: y+30,text: type,fontSize: 25,fill: color}))}return group;
}// 选中牌动画绘制;IsPass:是否绕过该判断,直接对牌进行操作,一般用于牌的初始化
function GoOrOut(node, Board, IsPass=false){// console.log(node)if(!IsLockClick && !IsPass) returnlet id = 0let BoardNode = null// 有可能是直接操作的对象if(node.target){id = node.target.parent._idBoardNode = node.target.parent}else{id = node._idBoardNode = node}let tempI = 20if(!TempBorad.has(id)){TempBorad.set(id, Board)}else{tempI = -20TempBorad.delete(id)}var tween = new Konva.Tween({node: BoardNode,duration: 0.005,y: BoardNode.attrs.y-tempI,});tween.play();
}// 取消选中的牌,将牌归位
function RestoreBoard(){return new Promise((a, b)=>{IsLockClick = truelet TempBorad_ = Array.from(TempBorad)for(let i=0;i<TempBorad_.length;i++){// console.log(TempBorad_[i])GoOrOut(TempBorad_[i][1].DrawBoardFront, TempBorad_[i][1], true)}IsLockClick = falsea()})}// 绘制牌的反面
function BoardBack(x, y){var group = new Konva.Group()var rect = new Konva.Rect({x: x,y: y,stroke: '#555',fill: 'white',strokeWidth: 1,shadowColor: 'black',shadowBlur: 0,shadowOffset: { x: 5, y: 5 },shadowOpacity: 0.3,width: BoardWidth,height: BoardHight,})group.add(rect)for(var i=0; i<10; i++){let tempPoints = new Array()for(var j=0; j<10; j++){if(j%2==0){tempPoints.push(x+ i*BoardWidth/10+BoardWidth/10)}else{tempPoints.push(x+ i*BoardWidth/10)}tempPoints.push(y+BoardHight/9*j)}var redLine = new Konva.Line({points: tempPoints,stroke: 'block',strokeWidth: 1,lineCap: 'round',lineJoin: 'round'});group.add(redLine)}return group
}// 旋转牌并移动角度并移动位置
// 动画执行到百分之多少就开始停止阻塞
function RotateBoard(node, rotation, duration, x, y, stopblock){return new Promise((a, b)=>{if(stopblock==null||stopblock==undefined||stopblock>1) stopblock = 1if(stopblock<0) stopblock = 0var temp = CalcXAndY(x, y, node.children[0].attrs.x, node.children[0].attrs.y)let oldX = temp.xlet oldY = temp.yvar tween = new Konva.Tween({node: node,duration: duration,x: oldX,y: oldY,rotation: rotation});tween.play();setTimeout(() => {a()}, duration*1000*stopblock);})
}// 绘制倒计时的秒表
function DrawTime(){var simpleText = new Konva.Text({x: width / 2 - 40,y: height / 2 - 50,id: 'Time',text: EveryTime,fontSize: 40,fontFamily: 'Calibri',stroke: 'black',fill: 'white',padding: 5,align: 'center'});return simpleText
}// 绘制地主和农民的标签
function ClassTitle(){let x1 = width*0.05+3let y1 = 5let x2 = width*0.95 - BoardWidth +3let y2 = 5let myx = (width)/2 - 18 let myy = height-20BoardLayer.add(Draw(x1, y1, Loandlords_Paly_==1?'地主':'农民', Loandlords_Paly_==1?'blue':'black',  'white'))BoardLayer.add(Draw(x2, y2, Loandlords_Paly_==2?'地主':'农民', Loandlords_Paly_==2?'blue':'black', 'white'))BoardLayer.add(Draw(myx, myy, Loandlords_Paly_==0?'地主':'农民', Loandlords_Paly_==0?'blue':'black', 'white'))function Draw( x, y, text, bgcolor, txtcolor){var tooltip = new Konva.Label({x: x,y: y,opacity: 0.75});tooltip.add(new Konva.Tag({fill: bgcolor,lineJoin: 'round',shadowColor: 'black',shadowBlur: 10,shadowOffsetX: 10,shadowOffsetY: 10,shadowOpacity: 0.5}));tooltip.add(new Konva.Text({text: text,fontFamily: 'Calibri',fontSize: 15,padding: 3,fill: txtcolor}));return tooltip}
}// 绘制桌子
function DrawTable(){var play0Rect = new Konva.Rect({x: (width/2)-(((20-1)*25+BoardWidth)/2)-10,y: (height)-height*0.05-BoardHight - 10,width: ((20-1)*25+BoardWidth)+20,height: BoardHight + 20,cornerRadius: [10, 10, 10, 10],fill: PlayerList[0].Color,});var play1Rect = new Konva.Rect({x: 30,y: 20,width: BoardWidth+30,height: 18*17,cornerRadius: [10, 10, 10, 10],fill: PlayerList[1].Color});var play2Rect = new Konva.Rect({x: width - (BoardWidth+60),y: 20,width: BoardWidth+30,height: 18*17,cornerRadius: [10, 10, 10, 10],fill: PlayerList[2].Color,});Tab_ = new Konva.Rect({x: ((width/2) - 600/2),y: ((height/2) - 200/2 - 40),width: 600,height: 200,cornerRadius: [10, 10, 10, 10],fill: 'DarkGreen',});BoardLayer.add(play0Rect);BoardLayer.add(play1Rect);BoardLayer.add(play2Rect);BoardLayer.add(Tab_);
}// 绘制桌子颜色
function DrawTabColor(pIndex){var tween = new Konva.Tween({node: Tab_,duration: 1,fill: PlayerList[pIndex].Color});tween.play()
}//-------------------// 计算X和目标X,Y和目标Y相距多少
function CalcXAndY(x1, y1, x2, y2){let tempX = x1-x2let tempY = y1-y2return { x: tempX, y: tempY }
}// 发牌动画
function DrawSendBoard(){return new Promise(async (a, b)=>{// 发牌给玩家var GroupWidth = (width/2)-((16*25+BoardWidth)/2)var BaseY = (height)-height*0.05-BoardHight// 发牌给上家var BaseX_1 = width*0.05var BaseY_1 = BoardHight*0.3// 发牌给下家var BaseX_2 = width*0.95 - BoardWidthvar BaseY_2 = BoardHight*0.3var i = 0for(let i=0; i<17; i++){await RotateBoard(PlayerList[1].BoardList[i].DrawBoardBack, 0, 0.25, BaseX_1, BaseY_1+i*10, 0.05)RotateBoard(PlayerList[1].BoardList[i].DrawBoardFront, 0, 0.25, BaseX_1, BaseY_1+i*10, 0)RotateBoard(PlayerList[2].BoardList[i].DrawBoardBack, 0, 0.25, BaseX_2, BaseY_2+i*10, 0.05) RotateBoard(PlayerList[2].BoardList[i].DrawBoardFront, 0, 0.25, BaseX_2, BaseY_2+i*10, 0) RotateBoard(PlayerList[0].BoardList[i].DrawBoardFront, 0, 0.25, i*25+GroupWidth, BaseY, 0.05)}a()})
}// 将牌整理到合适位置
function InitLocationBoard(player){return new Promise(async (a,b)=>{if(player.name=='玩家一'){player.BoardListSort()IsLockClick = falselet len = player.BoardList.lengthlet width_ = (width/2)-(((len-1)*25+BoardWidth)/2)var BaseY = (height)-height*0.05-BoardHightfor(let i=0; i<player.BoardList.length; i++){player.BoardList[i].DrawBoardFront.remove()let tempDraw = player.BoardList[i].DrawBoardFrontMyBoardGroup.add(tempDraw)if(tempDraw)await RotateBoard(tempDraw, 0, 0.1, i*25+width_, BaseY, 0.2)}}a()})}// 玩家出牌信息绘制区
function PlayerMessage(player, BoardCombin){let Group_ = player.Grouplet Boards = BoardCombin.CurrentBoardslet len = Boards.lengthlet x, y;// 玩家一出牌动画function PalyerMySend(){return new Promise(async (result, reject)=>{Group_.destroyChildren()x = (width/2)-(((len-1)*25+BoardWidth)/2)y = 270-BoardHightfor(let i = 0; i<len; i++){let node = Boards[i].DrawBoardFront// 注销事件node.off('mouseenter.select')node.off('mousedown.click')node.remove()Group_.add(node)await RotateBoard(node, 0, 0.2, i*25+x, y, 0)player.DeleteIDOfBoard(Boards[i].id)}result()})}// 玩家二或三出牌动画function PalyerTwoOrThreeSend(player, BoardCombin){return new Promise(async (result, reject)=>{Group_.destroyChildren()if(player.name=='玩家二')x = ((width/2) - 600/2)elsex = ((width/2) + 600/2 - BoardWidth)y = ((height/2) - 200/2 - 40)for(let i = 0; i<len; i++){let node1 = Boards[i].DrawBoardFrontlet node2 = Boards[i].DrawBoardBacknode1.remove()node2.remove()Group_.add(node1)Group_.add(node2)RotateBoard(node1, 0, 0.2, i*25+x, y, 0)await RotateBoard(node2, 0, 0.2, i*25+x, y, 0)player.DeleteIDOfBoard(Boards[i].id)node1.show()node2.hide()}BoardLayer.draw()result()})}return new Promise(async (result, reject)=>{if(BoardCombin==null){// 画不要result()return}if(player.name=='玩家一'){await PalyerMySend(player, BoardCombin)}else{await PalyerTwoOrThreeSend(player, BoardCombin)}await InitLocationBoard(player)result()})
}

konva.min.js

这里代码比较长,已上传主页资源,也可以评论区找我要~

PlayGame.js

/*** 游戏主体逻辑,包括开始游戏,结束游戏等* 主要是开始游戏到循环游戏直到游戏结束的状态变化* 也包括初始化整个游戏*/// 牌面初始化
function InitBoard(){// 将牌打乱for(let i=53;i>0;i--){BoardListGameInit[i].DrawBoardFront.hide()BoardListGameInit[i].DrawBoardBack.hide()let randomIndex = Math.floor( Math.random()*i+1)BoardListGameInit.push(BoardListGameInit[randomIndex])BoardListGameInit.splice(randomIndex,1)}// 地主牌for(let i=0; i<6; i++){let temp = 3if(i==0) temp-=1PlayerList[0].BoardList.push(...BoardListGameInit.splice(0, temp))PlayerList[1].BoardList.push(...BoardListGameInit.splice(0, temp))PlayerList[2].BoardList.push(...BoardListGameInit.splice(0, temp))}// 将牌排列整齐BoardSort(BoardListGameInit)PlayerList[0].BoardListSort()PlayerList[1].BoardListSort()PlayerList[2].BoardListSort()}// 按钮闭包
var Button_ = (function(){// 注册事件let EventListener = new Array()// 显示按钮且添加事件function ShowButtonAndEvent(text1, text2, buttonLeftEvent, buttonRightEvent){// 添加事件之前需要先注销掉之前的事件HideButtonAndDeEvent()ShowAndHide(true)ButtonOne1.innerText = text1ButtonOne2.innerText = text2ButtonOne1.addEventListener('click',buttonLeftEvent)ButtonOne2.addEventListener('click',buttonRightEvent)EventListener[0] = buttonLeftEventEventListener[1] = buttonRightEvent}// 隐藏按钮且删除事件function HideButtonAndDeEvent(){ShowAndHide(false)// 移除事件if(EventListener.length>0){ButtonOne1.removeEventListener('click',EventListener[0])ButtonOne2.removeEventListener('click',EventListener[1])EventListener.splice(0,1)EventListener.splice(0,1)}}// 隐藏或显示function ShowAndHide(IsShow){ButtonDiv.style.display = IsShow? 'block':'none'}return {ShowButtonAndEvent: ShowButtonAndEvent,HideButtonAndDeEvent: HideButtonAndDeEvent,ShowAndHide: ShowAndHide}
})()// 倒计时闭包
var TimeSecond = (function(){let i = EveryTime// 绘制秒表let timeControl = null// 是否暂停let IsPause = false// 动画IDlet RAFId = nullfunction Show(){if(!timeControl){timeControl = DrawTime()BoardLayer.add(timeControl)}timeControl.show()DrawStart()}let oldTime = new Date()let newDate = 0// 开始倒计时function DrawStart(){newDate = new Date()if(newDate-oldTime > 1000 && !IsPause){// console.log()timeControl.text(i<10?'0'+i:i)BoardLayer.draw()i--oldTime = new Date()}if(i<0){Close()// 默认当该倒计时结束,那么触发第一个按钮的点击事件ButtonOne1.click()return} RAFId = window.requestAnimationFrame(DrawStart)}// 关闭且初始化function Close(){if(RAFId)window.cancelAnimationFrame(RAFId)i = 20IsPause = falsetimeControl.hide()BoardLayer.draw()RAFId = null}return {timeControl: timeControl,Show: Show,Close: Close,IsPause: IsPause}
})()// 发牌
async function SendBorad(){// 玩家牌组// 在玩家牌组上面注册一个组合,如果在该组合上面点击,那么将开启选牌// 离开该组合将注销let IsSelect = false // 是否可以选中牌MyBoardGroup = new Konva.Group()NotMeBoard_Group = new Konva.Group()MyBoardGroup.on('mousedown', ()=> { IsSelect=true })MyBoardGroup.on('mouseup mouseleave', ()=> { IsSelect=false;if(TempBorad!=null)new BoardPlayer(TempBorad, 0).Show()})// 给地主牌注册事件,因为该地主牌有可能是玩家的手牌for(let i=0;i<3; i++){BoardListGameInit[i].DrawBoardFront.show()BoardListGameInit[i].DrawBoardBack.hide()// 注册事件BoardListGameInit[i].DrawBoardFront.on('mouseenter.select', (node)=>{if (IsSelect && Loandlords_Paly_==0)GoOrOut(node, BoardListGameInit[i])})BoardListGameInit[i].DrawBoardFront.on('mousedown.click', (node)=>{if(Loandlords_Paly_==0)GoOrOut(node, BoardListGameInit[i])})}// 生成具体的牌对象for(let i = 0;i<3; i++){for(let j=0; j<PlayerList[i].BoardList.length;j++){let Board = PlayerList[i].BoardList[j]let group = nullif(i==0){group = Board.DrawBoardFrontgroup.on('mouseenter.select', (node)=>{if (IsSelect)GoOrOut(node, Board)})group.on('mousedown.click', (node)=>{GoOrOut(node, Board)})// console.log(group)MyBoardGroup.add(group)}else{group = Board.DrawBoardBacklet DrawBoardFront = Board.DrawBoardFrontDrawBoardFront.hide()NotMeBoard_Group.add(group)NotMeBoard_Group.add(DrawBoardFront)}group.show()}}BoardLayer.add(MyBoardGroup)BoardLayer.add(NotMeBoard_Group)// 开始发牌动画await DrawSendBoard(BoardLayer)StartGame()
}// 开始玩地主
async function StartGame(){// 将地主牌放到左上角for(let i = 0;i<3;i++){BoardLayer.add(BoardListGameInit[i].DrawBoardFront)BoardLayer.add(BoardListGameInit[i].DrawBoardBack)RotateBoard(BoardListGameInit[i].DrawBoardFront, 0, 0.2, width*0.15+i*BoardWidth, 0)RotateBoard(BoardListGameInit[i].DrawBoardBack, 0, 0.2, width*0.15+i*BoardWidth, 0.2)}// 叫地主setTimeout(() => {TimeSecond.Show()Loandlords_Paly()}, 500);// 将决定一个地主出来function Loandlords_Paly(){// 显示按钮且绑定事件Button_.ShowButtonAndEvent('不叫','叫地主', async ()=>{Loandlords_Paly_ = Math.floor( Math.random()*2+1)// 将倒计时关闭TimeSecond.Close()Button_.HideButtonAndDeEvent(true)// 必须等待动画完成await new Promise(async (a,b)=>{for(let i = 0; i<3; i++){BoardListGameInit[i].DrawBoardBack.show()PlayerList[Loandlords_Paly_].BoardList.push(BoardListGameInit[i])NotMeBoard_Group.add(BoardListGameInit[i].DrawBoardBack)if(Loandlords_Paly_==1)await RotateBoard(BoardListGameInit[i].DrawBoardBack, 0, 0.2, width*0.05, (BoardHight*0.3)+(17*10)+i*10)elseawait RotateBoard(BoardListGameInit[i].DrawBoardBack, 0, 0.2, (width*0.95 - BoardWidth), (BoardHight*0.3)+(17*10)+i*10)PlayerList[Loandlords_Paly_].BoardListSort()a()}})StartFunGame()}, async ()=>{// 将倒计时关闭TimeSecond.Close()Button_.HideButtonAndDeEvent(true)Loandlords_Paly_ = 0// 叫地主;那么将地主牌添加到玩家手牌中PlayerList[0].BoardList.push(...BoardListGameInit)// 整理牌await InitLocationBoard(PlayerList[0])StartFunGame()})}
}// 开始游戏循环
function StartFunGame(){// 实例化一个已经出了的牌池BoardPond_ = new BoardPond()// 绘制地主和农民ClassTitle()PlayerGroupCreate()BoardLayer.draw()// 玩家出牌的下标let CurrentIndex = Loandlords_Paly_// 周期回合数;用以记录当前是否已走完一个周期(即三名玩家)let Bout = 0// 绑定出牌不出牌事件Button_.ShowButtonAndEvent('不出','出牌', async ()=>{// 如果当前的回合是玩家,且第一张出牌的也是玩家,// 如果玩家还没出牌,那么需要随机出一张牌if(!CurrentBorad && CurrentIndex==0){console.log('玩家随机出牌')// 将牌复原的合适的位置await RestoreBoard()}// 当前已过完一整个周期;那么牌堆处设置为空if(Bout==1){Bout = 0CurrentBorad = null}elseBout++// 将倒计时关闭TimeSecond.Close()// 下一个回合NextGame()}, async ()=>{let Current_index = NextIndex(CurrentIndex, -1)let myBoardif(Current_index == 0){myBoard = new BoardPlayer(TempBorad, 0)TempBorad.clear()}else // 机器人{myBoard = new BoardPlayer(RobotBoards, Current_index)RobotBoards = null}// 判定是否可以出牌if(JudgeBoard(myBoard)){// 将倒计时关闭TimeSecond.Close()Button_.ShowAndHide(false)// 将牌顶换为当前牌CurrentBorad = myBoard// console.log(myBoard)BoardPond_.SetAddBoard(myBoard)await PlayerMessage(PlayerList[Current_index], myBoard)}else {console.log('不能出牌')return}// 新回合的开始重新设置Bout = 0NextGame()})// 游戏回合function NextGame(){if(PlayEnd()) returnlet CurrentIndex_ = CurrentIndexTimeSecond.Show()DrawTabColor(CurrentIndex)let isRobat = falseif(CurrentIndex==0){IsLockClick = trueButton_.ShowAndHide(true)}else{IsLockClick = falseButton_.ShowAndHide(false)isRobat = true}PlayerList[CurrentIndex].Group.removeChildren()CurrentIndex = NextIndex(CurrentIndex)if(isRobat){setTimeout(() => {let _value = 0if(CurrentBorad!=null)_value = CurrentBorad.CurrentBoardCombin.Value// 机器人出牌RobotBoards = new BoardType(PlayerList[CurrentIndex_].BoardList).GetAllType('Y1', _value)if(RobotBoards==null)ButtonOne1.click()elseButtonOne2.click()}, 1000);}}NextGame()
}// 游戏结束
function PlayEnd(){let isEnd = falseif(PlayerList[0].BoardList.length==0){alert('游戏结束;你赢了')isEnd = true}if(PlayerList[1].BoardList.length==0){alert('游戏结束;你上家赢了')isEnd = true}if(PlayerList[2].BoardList.length==0){alert('游戏结束;你下家赢了')isEnd = true}if(isEnd){IsLockClick = falseTimeSecond.Close()Button_.HideButtonAndDeEvent()}return isEnd
}// 下一个玩家
function NextIndex(CurrentIndex_, Line=1){CurrentIndex_-=Lineif(CurrentIndex_<0)CurrentIndex_=2else if(CurrentIndex_>2)CurrentIndex_=0return CurrentIndex_
}// 判定系统,判定是否可以出牌
// 当牌顶为空,且牌顶数量与牌顶的真实价值小于当前出牌真实价值
// 且类型一致
function JudgeBoard(CurrentBoard_){if(CurrentBoard_.CurrentBoardCombin==null) return falseif(CurrentBorad==null) return trueif(CurrentBorad.CurrentBoardCombin.Value < CurrentBoard_.CurrentBoardCombin.Value)if(CurrentBorad.CurrentBoardCombin.Type == CurrentBoard_.CurrentBoardCombin.Type)if(CurrentBorad.CurrentBoardCombin.Length < CurrentBoard_.CurrentBoardCombin.Length || CurrentBoard_.CurrentBoardCombin.Type != 'Y8')return truereturn false
}// 玩家们的手牌绘制区
function PlayerGroupCreate(){PlayerList[0].Group = new Konva.Group()PlayerList[1].Group = new Konva.Group()PlayerList[2].Group = new Konva.Group()BoardLayer.add(PlayerList[0].Group)BoardLayer.add(PlayerList[1].Group)BoardLayer.add(PlayerList[2].Group)
}// 将牌按照大小进行排序
function BoardSort(BoardList){// 先将牌面进行排序let len = BoardList.lengthfor (var i = 0; i < len - 1; i++) {for (var j = 0; j < len - 1 - i; j++) {let value_1 = BoardMarkMap.get(BoardList[j].surface)let value_2 = BoardMarkMap.get(BoardList[j+1].surface)if (value_1 < value_2) {        // 相邻元素两两对比var temp = BoardList[j+1];        // 元素交换BoardList[j+1] = BoardList[j];BoardList[j] = temp;}}}
}// 开始加载游戏
window.onload = function(){ButtonDiv = document.getElementById('ButtonDiv')ButtonOne1 = document.getElementById('CallLandLord')ButtonOne2 = document.getElementById('RobLandLord')TxtInfo = document.getElementById('txtInfo')// 首先必须添加一个场景Stage = new Konva.Stage({container: '#bodyPlayer',   // id of container <div>width: width,height: height});BoardLayer = new Konva.Layer()Stage.add(BoardLayer)DrawTable()InitBoard()SendBorad()}// 执行动画,第一个参数,动画执行函数
function RAF(){}

veriable.js

/*** 作者:0.活在风浪里 v1.5.0* 变量初始化,记录有关游戏的所有全局变量*///---------------------------------------游戏基本变量// 牌面映射,字面量=》价值量
var BoardMarkMap = new Map();
BoardMarkMap.set('3', 3)
BoardMarkMap.set('4', 4)
BoardMarkMap.set('5', 5)
BoardMarkMap.set('6', 6)
BoardMarkMap.set('7', 7)
BoardMarkMap.set('8', 8)
BoardMarkMap.set('9', 9)
BoardMarkMap.set('0', 10) // 10
BoardMarkMap.set('J', 11)
BoardMarkMap.set('Q', 12)
BoardMarkMap.set('K', 13)
BoardMarkMap.set('A', 14)
BoardMarkMap.set('2', 15)
BoardMarkMap.set('C', 50) // 小鬼
BoardMarkMap.set('G', 100) // 大鬼// 牌组合类型映射
var BoardTypeMap = new Map()
BoardTypeMap.set('Y1', '单牌')
BoardTypeMap.set('Y2', '对子')
BoardTypeMap.set('Y3', '三带')
BoardTypeMap.set('Y4', '顺子')
BoardTypeMap.set('Y5', '连对')
BoardTypeMap.set('Y6', '飞机')
BoardTypeMap.set('Y7', '四带二')
BoardTypeMap.set('Y8', '炸弹')
// BoardTypeMap.set('Y9', '王炸')// 牌的绘制容器管理,可以通过该容器索引到任何一张牌的绘制内容
var BoardDrawMap = new Map()// keys集合;获取牌的字面量如K,J,Q....
var BoardMarkMapKes = Array.from(BoardMarkMap.keys())//---------------------------------------游戏结构性逻辑变量(包括绘制的逻辑变量)// 画布的大小
const width = 844
const height = 390// 牌有关的全局变量
const BoardWidth = 45
const BoardHight = 80// 按钮的大小
const ButtonWidth = 120
const ButtonPadding = 20// 每个回合等待的时间
const EveryTime = 20
// 按钮的容器:控制整体是否显示与否
var ButtonDiv = document.getElementById('ButtonDiv')
// 初始:叫地主=》过牌
var ButtonOne1 = document.getElementById('CallLandLord')
// 初始:不叫=》出牌
var ButtonOne2 = document.getElementById('RobLandLord')
// 头顶信息框
var TxtInfo = document.getElementById('txtInfo')// 玩家手牌图层
var MyBoardGroup = null
// 机器人手牌图层
var NotMeBoard_Group = null//---------------------------------------游戏内容逻辑变量
// 牌面绘制映射
var GrawBoard = new Map()
// 牌面选中集合
var TempBorad = new Map()
// 是否锁住点击事件
var IsLockClick = false
// 有几个玩家发完牌
var SendBoard = 0 
// 机器人牌面
var RobotBoards// 玩家
var PlayerList = new Array()
// 自己,
PlayerList[0] = new Player([],'玩家一', 'SaddleBrown')
// 左边上家
PlayerList[1] = new Player([],'玩家二', 'DarkOliveGreen')
// 右边下家
PlayerList[2] = new Player([],'玩家三', 'MediumSlateBlue')// 场景
var Stage = null
// 是否已出牌或者叫了地主
var isSelect = false
// 地主索引=》对应的是玩家的下标
var Loandlords_Paly_ = -1// 图层
var BoardLayer = null
// 当前桌面牌堆;如果为null,则表明当前可以随意出牌
// 不然下一家必须接牌;类型:BoardPond
var CurrentBorad = null
// 牌池
var BoardPond_ = null
// 中间的桌子
var Tab_ = null// 生成各种牌
var BoardListGameInit = new Array();
for(var i=0;i<15;i++){var key = BoardMarkMapKes[i]if(key=='C'){BoardListGameInit.push(new Board(key, '🧛', i*4))continue}else if(key=='G'){BoardListGameInit.push(new Board(key, '🧙‍♂️', 53))continue}BoardListGameInit.push(new Board(key, '♠', i*4))BoardListGameInit.push(new Board(key, '♥', i*4+1))BoardListGameInit.push(new Board(key, '♣', i*4+2))BoardListGameInit.push(new Board(key, '♦', i*4+3))
}

index.html

<!DOCTYPE html>
<head><meta http-equiv="Content-Type" content="text/html" charset="UTF-8"><meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0" ><title></title><script src="script/konva.min.js"></script><script src="script/GrawGame.js" ></script><script src="script/GameEntity.js" ></script><script src="script/veriable.js" ></script><script src="script/PlayGame.js" ></script><style>body {position: fixed;width: 100%;height: 390px;padding: 0;margin: 0;overflow: hidden;}.ButtonDiv{width: 90px;height: 20px;text-align: center;border-radius: 5px;padding: 5px;cursor: pointer;position:absolute;}#CallLandLord{top: 230px;left: calc(50% - 120px);background-color: aqua;}#RobLandLord{top: 230px;left: calc(50%);background-color: rgb(244, 158, 11);}#ButtonDiv{display: none;}@media screen and (orientation: portrait) {body {position: absolute;width: 100vh;height: 390px;top: 0;left: 100vw;-webkit-transform: rotate(90deg);-moz-transform: rotate(90deg);-ms-transform: rotate(90deg);transform: rotate(90deg);transform-origin: 0% 0%;}}@media screen and (orientation: landscape) {body {position: absolute;top: 0;left: 0;width: 100vw;height: 390px;}}
</style>
</head>
<body ><div id="bodyPlayer" style="margin: 0 auto; max-width: 844px; width: 100%; height: 390px; border: solid 1px;"></div><div style="width: 300px; text-align: center;position: absolute; top: 3%; left: calc(50% - 150px);" id="txtInfo"> 信息 </div><div id="ButtonDiv"><div id="CallLandLord" class="ButtonDiv" > 不叫 </div><div id="RobLandLord" class="ButtonDiv" > 叫地主 </div></div><script></script>
</body></html>

以上则是全部代码,复制项目直接运行index.html,

结语:

本文到这也要搁笔了,感谢你们阅读至此!感谢阅读,多多提供意见参考,评论区随意放肆评论,我会一 一读,真诚参考,

 

相关文章:

开源项目 —— 原生JS实现斗地主游戏 ——代码极少、功能都有、直接粘贴即用

目录 效果如下 目录结构 GameEntity.js GrawGame.js konva.min.js PlayGame.js veriable.js index.html 结语&#xff1a; 前期回顾 卡通形象人物2 写代码-睡觉 丝滑如德芙_0.活在风浪里的博客-CSDN博客本文实现了包含形象的卡通小人吃、睡、电脑工作的网页动画https://…...

Linux第四讲

目录 四、shell脚本 4.1 shell和shell脚本 4.2 脚本语言分类 4.2.1 编译型语言 4.2.2 解释型语言 4.2.3 脚本语言 4.3 shell常见种类 4.3.1 shell分类介绍 4.3.2 查看bash版本 4.3.3 sh和bash的关系 4.4 脚本书写规范 4.4.1 选择解释器 4.4.2 开发规范 4.5 shell…...

Redis 持久化

持久化是指数据写到物理硬盘里&#xff0c;即便程序崩溃、或者电脑重启&#xff0c;依然能够恢复。Redis提供了两种持久化机制&#xff1a;RDB和AOF。 RDB(Redis Database): RDB文件相当于内存快照&#xff0c;保存了某个时间点数据库信息。使用RDB文件恢复很简单&#xff0c;将…...

Python语言零基础入门教程(十三)

Python 字典(Dictionary) 字典是另一种可变容器模型&#xff0c;且可存储任意类型对象。 字典的每个键值 key:value 对用冒号 : 分割&#xff0c;每个键值对之间用逗号 , 分割&#xff0c;整个字典包括在花括号 {} 中 ,格式如下所示&#xff1a; d {key1 : value1, key2 : …...

江苏五年制专转本应该复习几轮?

五年制专转本应该复习几轮&#xff1f; 据调查统计&#xff1a;2022年专转本17%的考生复习三轮及以上&#xff0c;23%的考生复习了两轮。这两类的考生录取率高至85%。可见复习轮数多&#xff0c;专转本上岸的概率也大。综合多方因素&#xff0c;建议同学们专转本复习四轮&#…...

微信小程序的优化方案之主包与分包的研究

什么是分包&#xff1f; 某些情况下&#xff0c;开发者需要将小程序划分成不同的子包&#xff0c;在构建时打包成不同的分包&#xff0c;用户在使用时按需进行加载。 在构建小程序分包项目时&#xff0c;构建会输出一个或多个分包。每个使用分包小程序必定含有一个主包。所谓的…...

从手工测试转型web自动化测试继而转型成专门做自动化测试的学习路线。

在开始之前先自学两个工具 商业web自动化测试工具请自学QTP&#xff1b;QTP的学习可以跳过&#xff0c;我是跳过了的。 开源web自动化测试工具请自学Selenium&#xff1b;我当年是先学watir&#xff08;耗时1周&#xff09;&#xff0c;再学selenium&#xff08;也耗时1周&…...

【计组笔记03】计算机组成原理之系统五大部件介绍、主存模型和CPU结构介绍

这篇文章,主要介绍计算机组成原理之系统五大部件、主存模型和CPU结构。 目录 一、计算机五大部件 1.1、体系结构 (1)冯诺依曼体系结构...

微信小程序解析用户加密数据

微信公众号 IT果果日记前言在上一篇文章“微信小程序如何获取用户信息”中我们完成了用户明文数据的校验工作&#xff0c;本文将学习解密用户的非明文用户信息&#xff0c;也就是获取用户的openId和unionId。解密调用wx.getUserProfile后将返回encryptedData和iv两个数据。encr…...

毕业四年换了3份软件测试工作,我为何仍焦虑?

​今天一看日历&#xff1a;2023.2.11 &#xff0c;才突然意识到自己毕业已经四年了。四年时间里一直在测试行业摸爬滚打&#xff0c;现在是时候记录一下了。 下面我来分享下我这4年软件测试经验及成长历程&#xff0c;或许能帮助你解决很多工作中的迷惑。 01、我是如何开始做…...

嵌入式C基础知识(7)

是否可以传递任何参数并从 ISR 返回值不可以。不能传递任何参数并从 ISR 返回值。 ISR 不返回任何内容&#xff0c;并且不允许传递任何参数。 当硬件或软件事件发生时调用 ISR&#xff0c;而代码不会调用它。 这就是为什么不向 ISR 传递参数的原因。 由于代码不调用 ISR&#x…...

大数据系列之:安装pulsar详细步骤

大数据系列之&#xff1a;安装pulsar详细步骤一、Pulsar版本和jdk对应关系二、安装JDK三、设置和激活jdk环境变量四、下载和解压Pulsar五、查看Pulsar目录六、启动Pulsar standalone cluster七、创建Kafka Topic八、往Topic写入数据九、消费pulsar的Topic一、Pulsar版本和jdk对…...

色彩-基础理论

颜色三大指标 色相 色相是颜色的一个属性&#xff0c;只有黑白灰没有色相这个属性(那银灰色是什么&#xff1f;) 颜色的相貌&#xff0c;指的也是给颜色一个名字 例如&#xff1a;暗红、酒红、土黄、墨绿 饱和度 颜色的鲜艳程度 纯度 饱和度主要取决于含色成分和消色成分&a…...

1629_MIT_6.828_xv6_chapter1操作系统的组织

全部学习汇总&#xff1a;GreyZhang/g_unix: some basic learning about unix operating system. (github.com) 这一次整理一下操作系统组织相关的知识&#xff0c;主要还是xv6教学操作系统相关的知识。当然&#xff0c;很多知识在这类技术领域是通用的。 1. 操作系统的主要功能…...

基于Golang哈希算法监控配置文件变化

SHA(secure hashing algorithm)表示安全哈希算法.SHA是MD5的修正版本&#xff0c;用于数据摘要和认证。哈希和加密类似&#xff0c;唯一区别是哈希是单项的&#xff0c;即哈希后的数据无法解密。SHA有不同的算法&#xff0c;主要包括SHA-1, SHA-2, SHA-256, SHA-512, SHA-224, …...

关于一笔画问题的一些思考(欧拉路Fleury算法、逐步插入回路法、以及另一种可能的解法)

前言这是一个经典的图论问题了最近复习离散的时候又恰好看到了&#xff0c;发现自己以前的解法似乎有点bug然后开始出反例卡自己&#xff0c;结果发现卡不掉&#xff1f;然后再好好想了想&#xff0c;发现这个看起来有问题的做法可能确实没问题。注意&#xff1a;欧拉路、欧拉回…...

vlookup怎么用详细步骤,看这一篇就够了

1、vlookup函数&#xff1a;使用方法 以下便是vlookup函数&#xff0c;功能、语法和参数用法&#xff1a; excel函数vlookup 2、vlookup函数&#xff1a;查询参数 首先&#xff0c;选中F2单元格&#xff0c;然后在编辑栏输入函数公式&#xff1a;VLOOKUP(E2&#xff0c;B&…...

雅思经验(9)之小作文常用词汇总结

写作&#xff1a;关于趋势的上升和下降在小作文中&#xff0c;真的是非常常见的&#xff0c;所以还是要积累一下。下面给出了很多词&#xff0c;但是在雅思写作中并不是词越丰富&#xff0c;分数就越高的。雅思写作强调的是准确性&#xff1a;在合适的地方用合适的词和句法。不…...

【Python语言基础】——Python NumPy 数组创建

Python语言基础——Python NumPy 数组创建 文章目录 Python语言基础——Python NumPy 数组创建一、Python NumPy 数组创建一、Python NumPy 数组创建 创建 NumPy ndarray 对象 NumPy 用于处理数组。 NumPy 中的数组对象称为 ndarray。 我们可以使用 array() 函数创建一个 NumP…...

【大数据】Hadoop-Kms 安装及相关详细配置,看完你就会了

简介 Hadoop KMS是基于Hadoop的KeyProvider API的加密密钥管理服务器&#xff0c;它提供了使用REST API通过HTTP进行通信的客户端和服务器组件。 客户端是一个KeyProvider实现&#xff0c;使用KMS HTTP REST API与KMS交互。 KMS及其客户端具有内置的安全性&#xff0c;它们支…...

SpringCloud分布式框架

SpringCloud分布式框架 SpringCloud框架 Spring Cloud 是一个用于创建分布式系统的开源框架。它基于 Spring Boot 和 Spring Framework&#xff0c;提供了一整套关于分布式系统的工具和技术。 Spring Cloud 是微服务架构的一种实现方式&#xff0c;它提供了一整套完整的技术…...

Csss属性display,visibility区别,对渲染页面的影响

display: none; 与 visibility: hidden; 的区别 相同&#xff1a; 它们都能让元素不可见 区别&#xff1a;display:none;会让元素完全从渲染树中消失&#xff0c;渲染的时候不占据任何空间&#xff1b; visibility: hidden;不会让元素从渲染树消失&#xff0c;渲染时元素继续…...

怎么给笔记本电脑外接两台显示器?

我们在办公室会看见不少同事的电脑不止一台显示器&#xff0c;多屏确实可以提高工作效率。有的游戏党也会选择给电脑外接显示器&#xff0c;带来绝佳的体验。 不过要怎么把将外部显示器连接到笔记本电脑上&#xff1f;驱动人生在这里教给大家给笔记本外接显示器的做法。 一、…...

生成树协议 — STP

目录 一、环路的出现 1、广播风暴&#xff1a; 2、MAC地址表翻滚&#xff1a; 二、生成树 1、定义&#xff1a; 2、生成树使用的算法&#xff1a; 三、802.1D 1、BPDU&#xff1a; 2、TCN—拓扑变更消息&#xff08;也是BPDU&#xff09;&#xff1a; 3、部分名词&am…...

git必会的知识点

注&#xff1a;本文参考https://www.liaoxuefeng.com/wiki/896043488029600 原文非常值得一读&#xff0c;作者学识渊博&#xff0c;补充了很多有意思的知识。我仅仅是拾人牙慧。 git是最先进的分布式版本控制系统。 版本控制系统——自动记录系统中文件的改动情况&#xff0…...

【hello, world】计算机系统漫游

文章目录hello程序信息就是位 上下文程序被其他程序翻译成不同的格式预处理阶段编译阶段汇编阶段链接阶段了解编译系统如何工作是大有益处的优化程序性能理解链接时出现的错误避免安全漏洞处理器读并解释储存在内存中的指令系统的硬件组成总线I/O设备主存处理器运行hello程序高…...

1. SpringMVC 简介

文章目录1. SpringMVC 概述2. SpringMVC 入门案例2.1 入门案例2.2 入门案例工作流程3. bean 加载控制4. PostMan 工具1. SpringMVC 概述 SpringMVC 与 Servlet 功能等同&#xff0c;均属于 Web 层开发技术。SpringMVC 是 Spring 框架的一部分。 对于 SpringMVC&#xff0c;主…...

《解谜三星堆:开启中华文明之门》-范勇 笔记

甲篇 应重视民间流传的疑似三星堆的文物&#xff0c;对其展开充分的研究&#xff0c;以发现更多关于三星堆的秘密&#xff0c;并且避免“敦煌窘境”&#xff0c;让我国的三星堆学术研究处于世界领先地位&#xff01;&#xff08;书中就讲到了在民间首次发现了圆形玉器&#xf…...

锐捷(十四)mpls vxn optionc的关键问题所在和具体问题分析

用锐捷的设备搭建mpls vxn optionc的基础版和带RR的版本&#xff0c;在控制平面和转发平免上分析mpls vxn optionc的关键问题所在和具体问题分析。一 基础mpls vxn optionc&#xff1a;核心&#xff1a;两pe之间之间建立MP EBGP邻居&#xff0c;从而直接传递路由解放了ASBR。关…...

Python语言零基础入门教程(十四)

Python 日期和时间 Python 程序能用很多方式处理日期和时间&#xff0c;转换日期格式是一个常见的功能。 Python 提供了一个 time 和 calendar 模块可以用于格式化日期和时间。 时间间隔是以秒为单位的浮点小数。 每个时间戳都以自从1970年1月1日午夜&#xff08;历元&…...