可以玩了
This commit is contained in:
parent
0e47630eeb
commit
af239b349e
36
public/client.js
Normal file
36
public/client.js
Normal file
@ -0,0 +1,36 @@
|
||||
const player = io()
|
||||
let myNumber = 0
|
||||
|
||||
player.on('alert', (message) => {
|
||||
alert(message)
|
||||
})
|
||||
|
||||
player.on('onlineNumber', (number) => {
|
||||
onlineNumber.innerText = number
|
||||
})
|
||||
|
||||
player.on('playersNumber', (number) => {
|
||||
playersNumber.innerText = number
|
||||
})
|
||||
|
||||
player.on('join', (number) => {
|
||||
myNumber = number
|
||||
playerNumber.innerText = number
|
||||
buttonJoin.innerText = number == 0 ? '加入' : '退出'
|
||||
buttonJoin.style.color = number == 0 ? 'red' : 'black'
|
||||
})
|
||||
|
||||
player.on('status', (status) => {
|
||||
const { players, cards, current } = status
|
||||
player1.innerText = makeCards(players[0] || 0)
|
||||
player2.innerText = makeCards(players[1] || 0)
|
||||
player3.innerText = makeCards(players[2] || 0)
|
||||
currentPlayerNumber.innerText = current + 1
|
||||
buttonGo.style.color = myNumber > 0 && myNumber === current + 1 ? 'red' : 'black'
|
||||
cardsDisplay.innerText = cards
|
||||
})
|
||||
|
||||
function makeCards(n) {
|
||||
if (n == 0) return ''
|
||||
return '['.repeat(n) + ']'
|
||||
}
|
@ -5,47 +5,25 @@
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" ,content="width=device-width, initial-scale=1.0">
|
||||
<link rel="shortcut icon" href="data:" type="image/x-icon">
|
||||
<!-- <link rel="stylesheet" href="style.css"> -->
|
||||
<title>小猫钓鱼</title>
|
||||
<style>
|
||||
.ready {
|
||||
color: red;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>小猫钓鱼</h1>
|
||||
<h2>在线人数:<var id="onlineNumber">0</var></h2>
|
||||
<h2>玩家人数:<var id="playersNumber">0</var></h2>
|
||||
<button id="buttonReady">我准备好了</button>
|
||||
<div id="players"></div>
|
||||
<div id="cards"></div>
|
||||
<p>[ 在线 <var id="onlineNumber">0</var> ] [ 玩家 <var id="playersNumber">0</var> ] [ 我是 玩家<var
|
||||
id="playerNumber">0</var>
|
||||
]</p>
|
||||
<p>玩家1 <var id="player1"></var></p>
|
||||
<p>玩家2 <var id="player2"></var></p>
|
||||
<p>玩家3 <var id="player3"></var></p>
|
||||
<p>当前 = 玩家<var id="currentPlayerNumber">0</var></p>
|
||||
<p>
|
||||
<button id="buttonJoin" style="color:red;" onclick="player.emit('join')">加入</button>
|
||||
<button id="buttonGo" onclick="player.emit('go')">出牌</button>
|
||||
</p>
|
||||
<p id="cardsDisplay"></p>
|
||||
<script src="/socket.io/socket.io.js"></script>
|
||||
<script>
|
||||
const player = io()
|
||||
|
||||
player.on('onlineNumber', (number) => {
|
||||
onlineNumber.innerText = number
|
||||
})
|
||||
|
||||
player.on('playersNumber', (number) => {
|
||||
playersNumber.innerText = number
|
||||
buttonReady.classList.remove('ready')
|
||||
})
|
||||
|
||||
player.on('ready', (ready) => {
|
||||
if(ready) buttonReady.classList.add('ready')
|
||||
else buttonReady.classList.remove('ready')
|
||||
})
|
||||
|
||||
player.on('status', (status)=>{
|
||||
console.table(status)
|
||||
})
|
||||
buttonReady.addEventListener('click', (e) => player.emit('ready'))
|
||||
|
||||
</script>
|
||||
<script src="client.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
254
server.js
254
server.js
@ -1,71 +1,217 @@
|
||||
const express = require('express')
|
||||
const game = express()
|
||||
game.use(express.static('public'))
|
||||
const host = process.env.HOST || '0.0.0.0'
|
||||
const port = process.env.PORT || 3000
|
||||
const server = game.listen(port, host, () => console.log(`小猫钓鱼游戏服务运行在 http://${host}:${port}/`))
|
||||
const io = require('socket.io')(server)
|
||||
const 游戏 = express()
|
||||
游戏.use(express.static('public'))
|
||||
const 主机 = process.env.HOST || '0.0.0.0'
|
||||
const 端口 = process.env.PORT || 3000
|
||||
const 服务器 = 游戏.listen(端口, 主机, () => console.log(`小猫钓鱼游戏服务运行在 http://${主机}:${端口}/`))
|
||||
const IO = require('socket.io')(服务器)
|
||||
|
||||
const clients = []
|
||||
const players = []
|
||||
const cards = []
|
||||
let current = 0
|
||||
let started = false
|
||||
const clients = [] // 所有客户
|
||||
const players = [] // 所有玩家
|
||||
let cardsOnTable = [] // 桌上的牌
|
||||
let currentPlayerNumber = -1 // 当前玩家序号
|
||||
|
||||
function isGameStarted() {
|
||||
if (players.length < 2) return false
|
||||
for (let player of players) {
|
||||
if (!player.ready) return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
IO.on('connection', (client) => {
|
||||
addClient(client)
|
||||
client.on('disconnect', () => removeClient(client))
|
||||
client.on('join', () => playerJoin(client))
|
||||
client.on('go', () => go(client))
|
||||
})
|
||||
|
||||
io.on('connection', (client) => {
|
||||
client.ready = false
|
||||
function addClient(client) {
|
||||
client.cards = []
|
||||
clients.push(client)
|
||||
io.emit('onlineNumber', clients.length)
|
||||
io.emit('playersNumber', players.length)
|
||||
IO.emit('onlineNumber', clients.length)
|
||||
client.emit('playersNumber', players.length)
|
||||
client.emit('join', 0)
|
||||
gameStatus() // TODO:只告诉当前加入的客户端
|
||||
console.info(`新客户端已连接,当前客户端${clients.length}个`)
|
||||
}
|
||||
|
||||
client.on('ready', () => {
|
||||
if (!isGameStarted()) {
|
||||
client.ready = !client.ready
|
||||
if (client.ready) {
|
||||
players.push(client)
|
||||
} else {
|
||||
const index = players.indexOf(client)
|
||||
players.splice(index, 1)
|
||||
}
|
||||
io.emit('playersNumber', players.length)
|
||||
client.emit('ready', client.ready)
|
||||
if (isGameStarted()) gameStart()
|
||||
function removeClient(client) {
|
||||
let index = clients.indexOf(client)
|
||||
clients.splice(index, 1)
|
||||
IO.emit('onlineNumber', clients.length)
|
||||
console.log(`已断开,当前客户端${clients.length}个`)
|
||||
if (players.includes(client)) {
|
||||
index = players.indexOf(client)
|
||||
players.splice(index, 1)
|
||||
IO.emit('playersNumber', players.length)
|
||||
// 游戏被迫结束?
|
||||
if (players.length == 2) {
|
||||
gameFinished()
|
||||
IO.emit('alert', `玩家${index + 1}掉线了`)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
client.on('disconnect', () => {
|
||||
const index = clients.indexOf(client)
|
||||
clients.splice(index, 1)
|
||||
io.emit('onlineNumber', clients.length)
|
||||
})
|
||||
})
|
||||
function playerJoin(player) {
|
||||
if (players.length < 3) {
|
||||
let playerIndex = players.indexOf(player)
|
||||
let playerNumber = playerIndex + 1
|
||||
if (playerNumber > 0) {
|
||||
playerNumber = 0
|
||||
players.splice(playerIndex, 1)
|
||||
console.log(`玩家${playerNumber} 已退出,当前玩家数:${players.length}`)
|
||||
} else {
|
||||
players.push(player)
|
||||
playerNumber = players.indexOf(player) + 1
|
||||
console.log(`玩家${playerNumber} 已加入,当前玩家数:${players.length}`)
|
||||
player.cards = []
|
||||
if (players.length === 3) gameStart()
|
||||
}
|
||||
player.emit('join', playerNumber)
|
||||
IO.emit('playersNumber', players.length)
|
||||
}
|
||||
}
|
||||
|
||||
function gameStart() {
|
||||
console.log('游戏开始')
|
||||
// cards = []
|
||||
cards.length = 0
|
||||
current = 0
|
||||
// 洗牌 -> players.cards 每家18张
|
||||
// players[0].cards = [1, 2, 3]
|
||||
// players[1].cards = [1, 2, 3, 4]
|
||||
// players[2].cards = [1, 2, 3, 4, 5]
|
||||
// ...
|
||||
emitStatus()
|
||||
cardsOnTable.length = 0
|
||||
currentPlayerNumber = 0
|
||||
// 洗牌,每玩家发18张
|
||||
const drawer = [
|
||||
{ color: '♠️', value: '2' },
|
||||
{ color: '♠️', value: '3' },
|
||||
{ color: '♠️', value: '4' },
|
||||
{ color: '♠️', value: '5' },
|
||||
{ color: '♠️', value: '6' },
|
||||
{ color: '♠️', value: '7' },
|
||||
{ color: '♠️', value: '8' },
|
||||
{ color: '♠️', value: '9' },
|
||||
{ color: '♠️', value: '10' },
|
||||
{ color: '♠️', value: 'J' },
|
||||
{ color: '♠️', value: 'Q' },
|
||||
{ color: '♠️', value: 'K' },
|
||||
{ color: '♠️', value: 'A' },
|
||||
{ color: '♥️', value: '2' },
|
||||
{ color: '♥️', value: '3' },
|
||||
{ color: '♥️', value: '4' },
|
||||
{ color: '♥️', value: '5' },
|
||||
{ color: '♥️', value: '6' },
|
||||
{ color: '♥️', value: '7' },
|
||||
{ color: '♥️', value: '8' },
|
||||
{ color: '♥️', value: '9' },
|
||||
{ color: '♥️', value: '10' },
|
||||
{ color: '♥️', value: 'J' },
|
||||
{ color: '♥️', value: 'Q' },
|
||||
{ color: '♥️', value: 'K' },
|
||||
{ color: '♥️', value: 'A' },
|
||||
{ color: '♣️', value: '2' },
|
||||
{ color: '♣️', value: '3' },
|
||||
{ color: '♣️', value: '4' },
|
||||
{ color: '♣️', value: '5' },
|
||||
{ color: '♣️', value: '6' },
|
||||
{ color: '♣️', value: '7' },
|
||||
{ color: '♣️', value: '8' },
|
||||
{ color: '♣️', value: '9' },
|
||||
{ color: '♣️', value: '10' },
|
||||
{ color: '♣️', value: 'J' },
|
||||
{ color: '♣️', value: 'Q' },
|
||||
{ color: '♣️', value: 'K' },
|
||||
{ color: '♣️', value: 'A' },
|
||||
{ color: '♦️', value: '2' },
|
||||
{ color: '♦️', value: '3' },
|
||||
{ color: '♦️', value: '4' },
|
||||
{ color: '♦️', value: '5' },
|
||||
{ color: '♦️', value: '6' },
|
||||
{ color: '♦️', value: '7' },
|
||||
{ color: '♦️', value: '8' },
|
||||
{ color: '♦️', value: '9' },
|
||||
{ color: '♦️', value: '10' },
|
||||
{ color: '♦️', value: 'J' },
|
||||
{ color: '♦️', value: 'Q' },
|
||||
{ color: '♦️', value: 'K' },
|
||||
{ color: '♦️', value: 'A' },
|
||||
{ color: '小', value: 'Joker' },
|
||||
{ color: '大', value: 'Joker' },
|
||||
]
|
||||
|
||||
while (drawer.length > 0) {
|
||||
let index = Math.floor(Math.random() * drawer.length)
|
||||
let card = drawer[index]
|
||||
players[currentPlayerNumber].cards.push(card)
|
||||
drawer.splice(index, 1)
|
||||
currentPlayerNumber = (currentPlayerNumber + 1) % 3
|
||||
}
|
||||
|
||||
gameStatus()
|
||||
}
|
||||
|
||||
function emitStatus() {
|
||||
function gameStatus() {
|
||||
const cardsNumbers = []
|
||||
for (let p of players) {
|
||||
cardsNumbers.push(p.cards.length)
|
||||
|
||||
for (let player of players) {
|
||||
cardsNumbers.push(player.cards.length)
|
||||
}
|
||||
io.emit('status', { players: cardsNumbers, cards, current })
|
||||
|
||||
const cardsStrings = []
|
||||
for (let card of cardsOnTable) {
|
||||
cardsStrings.push(`[${card.color}${card.value}]`)
|
||||
}
|
||||
|
||||
IO.emit('status', {
|
||||
players: cardsNumbers,
|
||||
cards: cardsStrings.join(''),
|
||||
current: currentPlayerNumber,
|
||||
})
|
||||
}
|
||||
|
||||
function go(client) {
|
||||
if (currentPlayerNumber != -1 && players.indexOf(client) === currentPlayerNumber) {
|
||||
let card = players[currentPlayerNumber].cards[0]
|
||||
players[currentPlayerNumber].cards.splice(0, 1)
|
||||
console.log(`玩家${currentPlayerNumber + 1} 出牌 [${card.color} ${card.value}]`)
|
||||
|
||||
// 判断有没有钓到
|
||||
let i = 0
|
||||
let getit = false
|
||||
for (i = 0; i < cardsOnTable.length; i++) {
|
||||
if (cardsOnTable[i].value == card.value) {
|
||||
getit = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if (getit) {
|
||||
// 将第i张牌后面的牌和玩家刚出的牌一起拿走放回玩家手中的牌后面
|
||||
const fishes = [...cardsOnTable.slice(i), card]
|
||||
console.log(`玩家${currentPlayerNumber + 1} 钓到 ${fishes.length} 条鱼`)
|
||||
players[currentPlayerNumber].cards = players[currentPlayerNumber].cards.concat(fishes)
|
||||
cardsOnTable = cardsOnTable.slice(0, i)
|
||||
} else {
|
||||
cardsOnTable.push(card)
|
||||
if (players[currentPlayerNumber].cards.length == 0) {
|
||||
client.emit('alert', '你输了')
|
||||
}
|
||||
currentPlayerNumber = (currentPlayerNumber + 1) % 3
|
||||
while (players[currentPlayerNumber].cards.length == 0) {
|
||||
currentPlayerNumber = (currentPlayerNumber + 1) % 3
|
||||
}
|
||||
}
|
||||
|
||||
gameStatus()
|
||||
|
||||
// 游戏结束了?
|
||||
let looser = 0
|
||||
let winner = 0
|
||||
for (let index = 0; index < players.length; index++) {
|
||||
const player = players[index]
|
||||
if (player.cards.length == 0) looser++
|
||||
else winner = index + 1
|
||||
}
|
||||
if (looser >= 2) {
|
||||
gameFinished()
|
||||
players[index].emit('alert', '你赢了!')
|
||||
players[index].broadcast.emit('alert', `玩家${winner} 获胜了!`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function gameFinished() {
|
||||
players.length = 0
|
||||
cardsOnTable.length = 0
|
||||
currentPlayerNumber = -1
|
||||
IO.emit('join', 0)
|
||||
IO.emit('playersNumber', 0)
|
||||
IO.emit('status', { players: [0, 0, 0], cards: '', current: currentPlayerNumber })
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user