1.此案例只用于学习
2.未接入游戏规则
HTML代码部分
<!DOCTYPE html>
<html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width"><meta name="Poker Skin" content="Poker Skin"><meta name="keywords" content="Reece, Poker, Camp"><title>德州扑克</title><link rel="stylesheet" href="style.css"></head><body><div id="poker-wrapper" class="poker-wrapper"><!-- 桌面 --><div class="pocker-desktop"><h3>Total Pot: $<span class="total-amount"></span></h3><div class="poker-cards-list"></div></div><!-- 用户 --><div class="poker-user-list"></div><!-- 按钮 --><div class="btn-wrapper"><!-- 游戏开始 --><div class="btn start-game">开始游戏</div><div class="btn user-call">玩家跟注</div><div class="btn user-raise">玩家加注</div><div class="btn user-abstention">玩家弃牌</div></div><!-- 公布栏 --><div class="bulletin-board-wrapper"><div class="bulletin-board-title">公布栏</div><div class="bulletin-board-info"><div class="info-list"></div></div></div></div></body><script src="index.js"></script>
</html>
CSS代码部分
/* 设置css 变量 */
/* ♠ ♥ ♣ ♦ */
:root {--bg-color: #676769;--font-color: #fff;--default-border-color: #fff;--desktop-bg-color: #151515;/* 花色 */--decor1: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABmJLR0QA/wD/AP+gvaeTAAAA/0lEQVQ4jd3Tu0oDQRiG4XfUIHgCm5QWip2ghfeiiOJF2HgRopWVt2Bjr3cggpVFOk9oGRIbxbwWu4vDJrvubgTBrxrm8MzMzwz8i6httf1b2Kx6pV6qM+Niq+qN37lWV5pi+2rP4XTVnTrQtHo2AsrnVG39hLXUiwpYlnN1qgw8rIFlOSgDnxuAj7ERImwO6FWtdS7zIYQ+wETU+QY8NcAeMmwo6nbBtfqOfkKqW6XbqXvqazp5YPJDOupd2h6kYy/qbn59KEAngSWgCywCnXRomaTOC8B9COGzal1i/CS63lFtIIetqe8R+KGul60pfuVJNoHjXN8GcDvOQf82X/BctEYp31GBAAAAAElFTkSuQmCC");--decor2: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABsAAAAbCAYAAACN1PRVAAAABmJLR0QA/wD/AP+gvaeTAAABS0lEQVRIie3VO0vkYBSH8eeI4JYyohYLWlpZiiOCImptpx9hOrfcarFV/AAWfhQRtPZSumxp4QW8deuFkcfCGXnBjJlL0vlvQpKT88t5eUPgOwUksi6q/cAyMAdUgBvgANiPCJO6AJaAeWAYuAcOgb2IeM3V1Wn1r9k5VquNuqp60qLuTJ3Kg2bVxxYNmnlStxvHr/JfnclcRvUH8A8Yyx2//ZwDExHxDNCX3FgrGAIYB1abJym2WDD0qW+KjZSEjWZhVyVhl1nYaUnYR990Nw4BF8BAgdAL8DMibiGZLCLugN0CIYCdJvQpakW9zvlY282VOvjlq6gLar1H6FVdbmt29VeP2HpHi61udAn96QhKwO0Ooa2uoAT83Sa02ROUgDVbb5q6WisESsAV3/9RaZ7U1fynuwOr6m0DelDnSoEScFI9UidLhb7TKm+AhYgg79ihTAAAAABJRU5ErkJggg==");--decor3: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABsAAAAbCAYAAACN1PRVAAAABmJLR0QA/wD/AP+gvaeTAAABmklEQVRIid2VTUsWYRSGr/Pqpg+RaFUgWIEWta5VtdBWUlDLVtHCv6F/I1Bc9LGrfkDLNtGmAoNcaLxChQv7glTy43LhvDDORzOj08YbBobzPHNfZ+ac8wwcVUWTzepx4BZwFvgCvIqI9dazUsfVb+7XV3WsbdBldc1i/VEvtQl7WgLq6XGbsM8VsKU6Pp2avL+HXG8Em69Y/9gmrKomT2r6FEs9mcwVakd9U1Kvt2pfsu+YeqIJ5I76IV18dVq9oW5mQFvqTXVKXUzF36u3q0AP1Z2SN1hRlzOxZfOD3tOO+iDtHynQKaALDNT+DNX6BQxHxE/Y3yBjLYMABhNfsrDTLYNyvmnYwn+CfcpF1L5MFxZpVf2e3P9Irn/pnVo8y+qo2i14aFudUc+pG0lsQz2vzlncwV11JO2f+3mqg8AkcB3YZO+oehYRC+pd4EVq+72IeKleBO4DV4B+4DXwKCJ+H+S79xKZzWQ/c2CzClDH/ACvlNbkkLBrJU1wta5Hk6wmGsZz6m8AGwKeA6vANnunwxngQgOPI6pdr9tid+Wth7QAAAAASUVORK5CYII=");--decor4: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA0AAAANCAYAAABy6+R8AAAABmJLR0QA/wD/AP+gvaeTAAAAYElEQVQoka3SsQ2AIBBAUToMc1g4kQ0rMA0mjmXhJoYBPgWaoIHgEX7/Qu4OpUYFaGAHtARtpPxfsPLOtsAMXB8UgKUGJuCg3AmYEnIV8OTGvNQ1U/f2Mii7043kP6JVBFVS6LUMrztBAAAAAElFTkSuQmCC");--poker-bg-default: #c1c1c1;--poker-bg-color1: #2bbf29;--poker-bg-color2: #df4538;--poker-bg-color3: #3077cc;--poker-bg-color4: #FEC801;--poker-border-color: #fff;/* 筹码 */--big-blind-bg-color: #3077cc;--small-blind-bg-color: #ff0000;--info-panel-bg-color: rgba(0, 0, 0, 0.2);/* 按钮背景色*/--btn-type1: #2bbf29;--btn-type2: #3077cc;--btn-type3: #FEC801;--btn-type4: #df4538;--btn-border-color: #333;--btn-box-shadow: 1px 1px 5px 0px rgba(50, 50, 50, 0.75);
}* {margin: 0;padding: 0;box-sizing: border-box;font-family: Serif;
}body {width: 100vw;height: 100vh;display: flex;flex-direction: column;justify-content: center;align-items: center;background-color: var(--bg-color);
}.poker-wrapper {width: 100%;height: 100%;display: flex;flex-direction: column;justify-content: center;align-items: center;position: relative;
}.poker-wrapper .pocker-desktop {width: 48em;height: 24em;color: var(--font-color);background-color: var(--desktop-bg-color);border-radius: 20em;border: 2em solid var(--desktop-border-color);z-index: 2;position: relative;display: flex;flex-direction: column;justify-content: center;align-items: center;gap: 1.0em;
}.poker-wrapper .pocker-desktop .total-amount {}/* 扑克样式 */
.poker-cards-list {display: flex;justify-content: center;align-items: center;gap: 1.0em;position: relative;z-index: 10;color: var(--font-color);
}.poker-cards-list .poker-card {padding: 0.3em;width: 3em;height: 4em;border: 3px solid var(--poker-border-color);border-radius: 5%;background-color: var(--poker-bg-default);color: var(--poker-bg-default);display: flex;flex-direction: column;justify-content: center;gap: 0.2em;
}.poker-cards-list .poker-card.active .poker-number {color: var(--font-color);
}.poker-cards-list .poker-card.active .poker-decor {margin: auto;width: 2em;height: 2em;background-repeat: no-repeat;background-position: center center;background-size: auto 100%;
}.poker-cards-list .poker-card.active.poker-card1 {background-color: var(--poker-bg-color1);
}.poker-cards-list .poker-card.active.poker-card1 .poker-decor {background-image: var(--decor1);
}.poker-cards-list .poker-card.active.poker-card2 {background-color: var(--poker-bg-color2);
}.poker-cards-list .poker-card.active.poker-card2 .poker-decor {background-image: var(--decor2);
}.poker-cards-list .poker-card.active.poker-card3 {background-color: var(--poker-bg-color3);
}.poker-cards-list .poker-card.active.poker-card3 .poker-decor {background-image: var(--decor3);
}.poker-cards-list .poker-card.active.poker-card4 {background-color: var(--poker-bg-color4);
}.poker-cards-list .poker-card.active.poker-card4 .poker-decor {background-image: var(--decor4);
}/* 用户列表 */
.poker-user-list {width: 60em;height: 30em;position: absolute;z-index: 20;
}.poker-user-list .poker-user-item {width: 10em;height: 5em;position: absolute;/* top: 50%;left: 50%; */transform: translateX(-50%) translateY(-50%);
}/*弃牌样式 */
.poker-user-list .poker-user-item.abstention::before {display: block;content: "已弃牌";padding: .2em;z-index: 30;color: var(--font-color);background-color: #df4538;position: absolute;top: 50%;left: 50%;transform: translateX(-50%) translateY(-50%);
}.poker-user-list .poker-user-item .poker-cards-list {gap: 0.4em;
}.poker-user-list .poker-user-item .user-info {width: 10em;height: 3.5em;padding: 1em;color: var(--font-color);background-color: var(--info-panel-bg-color);border-radius: 0.5em;display: flex;flex-direction: column;justify-content: center;align-items: center;overflow: hidden;position: absolute;top: 50%;left: 0%;z-index: 20;
}.poker-user-list .poker-user-item.rank .user-info::before {display: block;content: "";padding: 0.2em;border-bottom-right-radius: 0.5em;font-size: 12px;background-color: red;position: absolute;top: 0%;left: 0%;
}.poker-user-list .poker-user-item.rank1 .user-info::before {content: "庄家";
}.poker-user-list .poker-user-item.rank2 .user-info::before {content: "小盲";
}.poker-user-list .poker-user-item.rank3 .user-info::before {content: "大盲";
}.poker-user-list .poker-user-item .user-info .user-name {font-size: 16px;font-weight: bold;}
/*用户的筹码 */.poker-user-list .poker-user-item .user-info .user-chips{display: flex;flex-direction: row;justify-content: center;gap: 0.4em;position: absolute;right: 5%;bottom:15% ;/* transform: translateX(-50%) translateY(-50%); */
}.poker-user-list .poker-user-item .user-info .user-chips .blind {width: 1em;
}.poker-user-list .poker-user-item .user-info .user-chips .chips {margin-top: -1.2em;width: 1em;height: 1em;border-radius: 50%;border: 1px solid #fff;
}.poker-user-list .poker-user-item .user-info .user-chips .big-blind .chips {background-color: var(--big-blind-bg-color);
}.poker-user-list .poker-user-item .user-info .user-chips .small-blind .chips {background-color: var(--small-blind-bg-color);
}/* 按钮样式 */.btn-wrapper {width: fit-content;height: fit-content;display: flex;flex-direction: column;gap: 20px;position: absolute;right: 100px;bottom: 50%;transform: translateY(50%);
}.btn-wrapper .btn {width: 100px;height: 40px;border: 1px solid var(--btn-border-color);border-radius: 4px;text-align: center;line-height: 40px;font-size: 16px;color: var(--font-color);cursor: pointer;user-select: none;box-shadow: var(--btn-box-shadow) transition: .2s;
}.btn {transform: scale(1);
}.btn:active {transform: scale(0.97);
}/* 开始游戏 */
.btn.start-game {background-color: var(--btn-type1);
}/* 跟注 */
.btn.user-call {background-color: var(--btn-type2);
}/* 加注 */
.btn.user-raise {background-color: var(--btn-type3);
}/* 放弃 */
.btn.user-abstention {background-color: var(--btn-type4);
}/* 公布栏 */
.bulletin-board-wrapper {width: 20em;height: 17em;border-radius: 0.2em;background-color: var(--info-panel-bg-color);position: absolute;top: 2em;left: 2em;
}.bulletin-board-wrapper .bulletin-board-title {width: 100%;height: 2.5em;font-size: 14px;color: var(--font-color);text-align: center;font-weight: bold;line-height: 2.5em;border-bottom: 1px solid rgba(0, 0, 0, 0.3);
}.bulletin-board-wrapper .bulletin-board-info {padding: 0.5em 1em;}.bulletin-board-wrapper .bulletin-board-info .info-list {padding-right: 4px;width: 100%;height: 13.5em;overflow: auto;
}.bulletin-board-wrapper .bulletin-board-info .info-list .info-item {margin-bottom: 0.4em;padding: 0.4em 0.4em 0.4em 2.5em;width: 100%;border-radius: 0.2em;color: var(--font-color);background-color: #666;display: flex;flex-direction: row;justify-content: space-between;align-items: center;position: relative;overflow: hidden;
}.bulletin-board-wrapper .bulletin-board-info .info-list .info-item .info-name.rank::before {display: block;content: "";padding: 0.2em;border-bottom-right-radius: 0.5em;font-size: 12px;background-color: red;position: absolute;top: 0%;left: 0%;
}.bulletin-board-wrapper .bulletin-board-info .info-list .info-item .info-name.rank1::before {content: "庄家";
}.bulletin-board-wrapper .bulletin-board-info .info-list .info-item .info-name.rank2::before {content: "小盲";
}.bulletin-board-wrapper .bulletin-board-info .info-list .info-item .info-name.rank3::before {content: "大盲";
}.bulletin-board-wrapper .bulletin-board-info .info-list .info-item .info-total.type3 {color: var(--poker-bg-color3);
}.bulletin-board-wrapper .bulletin-board-info .info-list .info-item .info-total.type4 {color: var(--poker-bg-color4);
}.info-list::-webkit-scrollbar {width: 4px;
}.info-list::-webkit-scrollbar-thumb {border-radius: 10px;box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);background: rgba(0, 0, 0, 0.2);
}.info-list::-webkit-scrollbar-track {box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);border-radius: 0;background: rgba(0, 0, 0, 0.1);
}
JS代码部分
//扑克的点数
const pokerNumberArr = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K']
//扑克花色 /* ♠ ♥ ♣ ♦ */
const pokerDecorArr = [1, 2, 3, 4]// 总金额
let totalAmount = 0;
let totalAmountEl = document.querySelector(".total-amount");
//设置总金额的值
totalAmountEl.innerHTML = totalAmount// 获取 牌桌的信息
let pokerCardsList = document.querySelector(".poker-cards-list");
const pokerNumber = 5; //桌面卡片数量
let pokerList = []; //扑克列表
addPokerCard(pokerNumber)// 获取用户信息
let pokerUserList = document.querySelector(".poker-user-list");//添加用户
let userList = []; //用户列表
const userNumber = 10; //人数
const angleIncrement = 360 / userNumber; // 计算角度增量
addUser(userNumber)// 获取公示栏
let bulletinBboardInfoList = document.querySelector(".info-list");// 开始游戏
let startGame = document.querySelector(".start-game");
//游戏开始标记
let startGameFlag = true;
// 庄家
let declarer = null;
let declarerIndex = null;
// 当前玩家
let currentUser = null;
// 当前玩家的索引
let currentUserIndex = null;
//下注执行顺序 从庄家开始进行
let userOrder = []// 下注金额
let wagerTotal = 2
// 用户索引
let userIndex = null// 列表索引
let userOrderIndex = 0
// 伦数
let number = 0startGame.addEventListener("click", () => {if (startGameFlag) {startGameFlag = false;declarerIndex = Math.floor((Math.random() * userNumber));currentUserIndex = Math.floor((Math.random() * userNumber));// declarer = pokerUserList.children[declarerIndex];// declarer.classList.add("active");currentUser = pokerUserList.children[currentUserIndex];currentUser.querySelectorAll(".poker-card")[0].classList.add("active");currentUser.querySelectorAll(".poker-card")[1].classList.add("active");//重新开始游戏用户执行顺序userOrder = userOrder.concat(userList.splice(declarerIndex + 1)).concat(userList.splice(0,declarerIndex + 1));// 设置标记setMarker()// 从庄家用户开始检索startRaise(0)}
})// 设置标记
function setMarker() {userOrder[userNumber - 1]['rank'] = 1 //庄userOrder[0]['rank'] = 2 //小盲userOrder[1]['rank'] = 3 //大盲pokerUserList.children[userOrder[userNumber - 1]['userIndex']].classList.add("rank", "rank1");pokerUserList.children[userOrder[0]['userIndex']].classList.add("rank", "rank2");pokerUserList.children[userOrder[1]['userIndex']].classList.add("rank", "rank3");
}function startRaise(i) {for (i; i < userNumber; i++) {userOrderIndex = ilet userInfo = userOrder[i]userIndex = userInfo.userIndexif (userInfo.status === 1) { //判断用户是否弃牌if (userIndex === currentUserIndex) { //是否是当前用户return} else { //机器人用户setUserTotal(i)}if (userIndex === declarerIndex) {userOrderIndex = 0number++;if (number === 1) {pokerCardsList.children[0].classList.add("active");pokerCardsList.children[1].classList.add("active");pokerCardsList.children[2].classList.add("active");} else if (number === 2) {pokerCardsList.children[3].classList.add("active");} else if (number === 3) {pokerCardsList.children[4].classList.add("active");} else {return;}startRaise(0)wagerTotal *= 2;}}}
}// 玩家跟注
let userCall = document.querySelector(".user-call");
userCall.addEventListener("click", () => {if (currentUser && userIndex === currentUserIndex) {userOrder[userOrderIndex].wagerType = 2; //跟注setUserTotal(userOrderIndex)startRaise(userOrderIndex + 1)}
})// 玩家加注
let userRaise = document.querySelector(".user-raise");
userRaise.addEventListener("click", () => {if (currentUser && userIndex === currentUserIndex) {wagerTotal *= 2;userOrder[userOrderIndex].wagerType = 3; //加注setUserTotal(userOrderIndex)startRaise(userOrderIndex + 1)}
})
// 玩家弃牌
let userAbstention = document.querySelector(".user-abstention");
userAbstention.addEventListener("click", () => {if (currentUser && userIndex === currentUserIndex) {userOrder[userOrderIndex].status = 2addBulletinBoardInfo(userOrder[userOrderIndex])pokerUserList.children[userIndex].classList.add('abstention')startRaise(userOrderIndex + 1)}
})// 重新设置当前用户金额的信息
function setUserTotal(index) {userOrder[index].total = wagerTotal;let userTotal = pokerUserList.children[userIndex].querySelector('.user-total')userTotal.innerHTML = "$" + userOrder[index].total.toFixed(2)totalAmount += userOrder[index].total; //重新设置总金额totalAmountEl.innerHTML = totalAmount.toFixed(2)addBulletinBoardInfo(userOrder[index])
}// 添加扑克
function addPokerCard(pokerNumber) {for (let i = 1; i <= pokerNumber; i++) {let poker = { //随机生成扑克牌信息"pokerNumber": pokerNumberArr[Math.floor((Math.random() * 13))],"pokerDecor": "poker-card" + pokerDecorArr[Math.floor((Math.random() * 4))]}pokerList.push(poker)let pokerCard = document.createElement("div")pokerCard.setAttribute("class", `poker-card ${poker.pokerDecor}`)pokerCard.innerHTML = setPokerInfo(poker)pokerCardsList.appendChild(pokerCard)}
}// 设置扑克信息
function setPokerInfo(poker) {return `<div class="poker-number">${poker.pokerNumber}</div><div class="poker-decor"></div>`
}// 添加用户
function addUser(userNumber) {for (let i = 1; i <= userNumber; i++) {let poker1 = {"pokerNumber": pokerNumberArr[Math.floor((Math.random() * 13))],"pokerDecor": pokerDecorArr[Math.floor((Math.random() * 4))]}; //第一张扑克牌信息let poker2 = {"pokerNumber": pokerNumberArr[Math.floor((Math.random() * 13))],"pokerDecor": pokerDecorArr[Math.floor((Math.random() * 4))]}; //第一张扑克牌信息 //第二张扑克牌let pokerInfo = [poker1, poker2]; //扑克牌点数let userName = `用户${i}`; //用户姓名let total = 0; //下注金额totalAmount += total; //重新设置总金额totalAmountEl.innerHTML = totalAmount.toFixed(2)// 计算位置let angle = (i - 1) * angleIncrement; // 计算角度let radius = 50; // 设置半径,可以根据需要调整let positionTop = 50 + radius * Math.sin((angle * Math.PI) / 180);let positionLeft = 50 + radius * Math.cos((angle * Math.PI) / 180);let pokerUser = document.createElement("div")pokerUser.setAttribute("class", "poker-user-item")pokerUser.setAttribute("style", `top:${positionTop}%;left:${positionLeft}%;`)pokerUser.innerHTML = setUserInfo(pokerInfo, userName, total)pokerUserList.appendChild(pokerUser)userList.push({userId: i, //用户userIduserIndex: (i - 1), //用户序号userName,pokerInfo,total,status: 1, //1.未弃牌 2.已弃牌wagerType: 1, //1.底注 2.跟注 3.加注rank: 0, //0.普通玩家 1.庄家 2.小盲 3.大盲})}
}// 设置用户信息
function setUserInfo(pokerInfo, userName, total) {return `<div class="poker-cards-list"><div class="poker-card poker-card${pokerInfo[0].pokerDecor}"><div class="poker-number">${pokerInfo[0].pokerNumber}</div><div class="poker-decor"></div></div><div class="poker-card poker-card${pokerInfo[1].pokerDecor}" ><div class="poker-number">${pokerInfo[1].pokerNumber}</div><div class="poker-decor"></div></div></div><div class="user-info"><div class="user-name">${userName}</div><div class="user-total">$${total.toFixed(2)}</div><div class="user-chips"><div class="blind big-blind"><div class="chips"></div><div class="chips"></div><div class="chips"></div><div class="chips"></div></div><div class="blind small-blind"><div class="chips"></div><div class="chips"></div></div></div></div>`
}// 添加 公布栏 信息
function addBulletinBoardInfo(userInfo) {let infoItem = document.createElement("div")infoItem.setAttribute("class", "info-item")infoItem.innerHTML = setBulletinBoardInfo(userInfo)bulletinBboardInfoList.appendChild(infoItem)
}// 设置公布栏 信息
function setBulletinBoardInfo(userInfo) {let info = null;let className = ""; //类名let wagerType = +userInfo.wagerType //转为number类型 1.底注 2.跟注 3.加注let status = userInfo.status; //1.未弃牌 2.已弃牌let wagerTypeInfo = ["", "底注:", "跟注:", "加注:"]let statusInfo = ["", "未弃牌", "弃牌"]if (status === 1) {info = wagerTypeInfo[wagerType] + userInfo.total.toFixed(2);} else {info = statusInfo[status];wagerType = 4}className = userInfo.rank === 0 ? "" : `rank rank${userInfo.rank}`;return `<div class="info-name ${className}" >${userInfo.userName}</div><div class="info-total type${wagerType}">${info}</div>`
}