end screen, more ships, chat
This commit is contained in:
parent
063fbd92be
commit
624e47af63
@ -68,7 +68,6 @@ canvas {
|
||||
height: 512px;
|
||||
background-color: #03A9F4;
|
||||
margin: 10px;
|
||||
/*border: 5px solid #2196F3;*/
|
||||
}
|
||||
.boxlayout {
|
||||
text-align: center;
|
||||
@ -151,5 +150,47 @@ button#leave {
|
||||
width: 200px;
|
||||
}
|
||||
#game_canvas {
|
||||
margin-left: 265px;
|
||||
margin-left: 300px;
|
||||
}
|
||||
.endresult {
|
||||
text-align: center;
|
||||
}
|
||||
.result {
|
||||
width: 530px;
|
||||
display: inline-block;
|
||||
}
|
||||
button#lobby {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
margin-left: 15px;
|
||||
}
|
||||
.bigstat {
|
||||
font-size: 200%;
|
||||
font-weight: bold;
|
||||
margin-bottom: 50px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
.message.t_event {
|
||||
color: #b5b5b5;
|
||||
}
|
||||
.message .sender {
|
||||
color: red;
|
||||
}
|
||||
.message.me .sender {
|
||||
color: blue !important;
|
||||
}
|
||||
.chatbox {
|
||||
margin-top: 50px;
|
||||
padding: 5px;
|
||||
background-color: #f9f9f9;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 5px;
|
||||
}
|
||||
#messages {
|
||||
height: 250px;
|
||||
background-color: #fff;
|
||||
border-radius: 5px;
|
||||
overflow-y: scroll;
|
||||
word-wrap: break-word;
|
||||
white-space: pre;
|
||||
}
|
||||
|
@ -60,6 +60,24 @@
|
||||
<span class="stat">You have <span id="g_s_num">0</span> ships left.</span>
|
||||
<span class="stat">Your opponent has <span id="o_s_num">0</span> ships left.</span>
|
||||
<span class="stat" id="g_s_stat">Your turn.</span>
|
||||
<div class="chatbox">
|
||||
<div class="letterbox" id="messages"></div>
|
||||
<input type="text" id="message_send" placeholder="Send message..">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="screen endresult" style="display: none;" id="endresult">
|
||||
<div class="bigstat">
|
||||
You <span id="wonlost">Lost</span>!
|
||||
<button id="lobby">Back to the lobby</button>
|
||||
</div>
|
||||
<div class="boxlarge canvasbox result">
|
||||
<h1>Opponent's ships</h1>
|
||||
<canvas id="opponent_result_canvas" width="513" height="513"></canvas>
|
||||
</div>
|
||||
<div class="boxlarge canvasbox result">
|
||||
<h1>Your ships</h1>
|
||||
<canvas id="my_result_canvas" width="513" height="513"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
112
client/index.js
112
client/index.js
@ -10,12 +10,9 @@
|
||||
played: 0,
|
||||
Game: {
|
||||
gameId: null,
|
||||
inGame: false,
|
||||
myTurn: true,
|
||||
opponentID: '',
|
||||
opponentName: '',
|
||||
ships: 0,
|
||||
oShips: 0,
|
||||
gridHome: {ships: [], strikes: []},
|
||||
gridOpponent: []
|
||||
}
|
||||
@ -121,6 +118,52 @@
|
||||
}
|
||||
},
|
||||
|
||||
endResultCellRenderer(cells, ctx, ship) {
|
||||
for (let i in cells) {
|
||||
let cell = cells[i]
|
||||
let destVar = (cell.destroyed != null ? cell.destroyed : cell.destroy)
|
||||
let color = '#dddd00'
|
||||
if (destVar || (ship != null && ship.sunken)) {
|
||||
color = '#ff0000'
|
||||
} else {
|
||||
if (ship) {
|
||||
color = '#dddddd'
|
||||
}
|
||||
}
|
||||
ctx.fillStyle = color
|
||||
ctx.fillRect(cell.x * GameDrawer.gridSize, cell.y * GameDrawer.gridSize, GameDrawer.gridSize, GameDrawer.gridSize)
|
||||
}
|
||||
},
|
||||
|
||||
resultScreen(myShips, enemyShips, myHits, enemyHits) {
|
||||
let c1 = Battleship.DOM.resultScreen.querySelector('#opponent_result_canvas')
|
||||
let c2 = Battleship.DOM.resultScreen.querySelector('#my_result_canvas')
|
||||
let ctx1 = c1.getContext('2d')
|
||||
let ctx2 = c2.getContext('2d')
|
||||
|
||||
ctx1.clearRect(0, 0, Battleship.canvasW, Battleship.canvasH)
|
||||
ctx2.clearRect(0, 0, Battleship.canvasW, Battleship.canvasH)
|
||||
|
||||
ctx1.drawImage(GameDrawer.boardStaticState, 0, 0)
|
||||
ctx2.drawImage(GameDrawer.boardStaticState, 0, 0)
|
||||
|
||||
GameDrawer.endResultCellRenderer(myHits, ctx1, null)
|
||||
|
||||
// Render my ship tiles
|
||||
for (let i in myShips) {
|
||||
let ship = myShips[i]
|
||||
GameDrawer.endResultCellRenderer(ship.cells, ctx2, ship)
|
||||
}
|
||||
|
||||
// Render enemy ship tiles
|
||||
for (let i in enemyShips) {
|
||||
let ship = enemyShips[i]
|
||||
GameDrawer.endResultCellRenderer(ship.cells, ctx1, ship)
|
||||
}
|
||||
|
||||
GameDrawer.endResultCellRenderer(enemyHits, ctx2, null)
|
||||
},
|
||||
|
||||
click: () => {
|
||||
if (GameDrawer.placingShips && GameDrawer.canPlace && GameDrawer.shipIndex != -1) {
|
||||
let shipData = Battleship.ships[GameDrawer.shipIndex]
|
||||
@ -377,6 +420,8 @@
|
||||
Battleship.Game.opponentName = game.opponentName
|
||||
Battleship.DOM.opponentName.innerHTML = game.opponentName
|
||||
|
||||
Battleship.DOM.chatbox.innerHTML = ''
|
||||
|
||||
io.emit('game_poll', {gameId: Battleship.Game.gameId})
|
||||
|
||||
logStatus('Place your ships onto the board.<br>Press `r` to rotate')
|
||||
@ -386,6 +431,7 @@
|
||||
Battleship.DOM.waitlistBtns.style.display = 'block'
|
||||
Battleship.DOM.waitlistQuit.style.display = 'none'
|
||||
GameDrawer.startGame()
|
||||
addChatMessage('event', null, 'Game started!')
|
||||
}
|
||||
|
||||
function attemptJoin (name) {
|
||||
@ -446,8 +492,10 @@
|
||||
if (reason === 1) {
|
||||
if (winner === true) {
|
||||
alert('You won!')
|
||||
Battleship.DOM.winStatus.innerHTML = 'Won'
|
||||
} else {
|
||||
alert('You lost.')
|
||||
Battleship.DOM.winStatus.innerHTML = 'Lost'
|
||||
}
|
||||
}
|
||||
|
||||
@ -458,8 +506,15 @@
|
||||
Battleship.locked = false
|
||||
Battleship.Game.gameId = null
|
||||
io.emit('poll_games')
|
||||
|
||||
Battleship.DOM.gameScreen.style.display = 'none'
|
||||
if (reason === 1) {
|
||||
Battleship.DOM.resultScreen.style.display = 'block'
|
||||
} else {
|
||||
Battleship.DOM.selectionScreen.style.display = 'block'
|
||||
Battleship.DOM.resultScreen.style.display = 'none'
|
||||
}
|
||||
|
||||
Battleship.DOM.waitlistBtns.style.display = 'block'
|
||||
Battleship.DOM.waitlistQuit.style.display = 'none'
|
||||
|
||||
@ -475,16 +530,37 @@
|
||||
Battleship.DOM.gameScreen.style.display = 'none'
|
||||
Battleship.DOM.selectionScreen.style.display = 'none'
|
||||
Battleship.DOM.startScreen.style.display = 'block'
|
||||
Battleship.DOM.resultScreen.style.display = 'none'
|
||||
|
||||
Battleship.locked = false
|
||||
Battleship.playerName = ''
|
||||
Battleship.Game.gameId = null
|
||||
}
|
||||
|
||||
function escapeHtml(unsafe) {
|
||||
return unsafe
|
||||
.replace(/&/g, "&")
|
||||
.replace(/</g, "<")
|
||||
.replace(/>/g, ">")
|
||||
.replace(/"/g, """)
|
||||
.replace(/'/g, "'")
|
||||
}
|
||||
|
||||
function addChatMessage (type, senderName, message) {
|
||||
let msgElem = '<div class="message t_' + type + '">'
|
||||
if (senderName) {
|
||||
msgElem += '<span class="sender">' + senderName + '</span> '
|
||||
}
|
||||
msgElem += '<span class="line">' + escapeHtml(message) + '</span>'
|
||||
|
||||
Battleship.DOM.chatbox.innerHTML += msgElem
|
||||
}
|
||||
|
||||
window.onload = () => {
|
||||
const startScreen = Battleship.DOM.startScreen = $.querySelector('#start')
|
||||
const selectionScreen = Battleship.DOM.selectionScreen = $.querySelector('#selection')
|
||||
const gameScreen = Battleship.DOM.gameScreen = $.querySelector('#game')
|
||||
const resultScreen = Battleship.DOM.resultScreen = $.querySelector('#endresult')
|
||||
|
||||
const warning = Battleship.DOM.joinWarn = startScreen.querySelector('#warning_message')
|
||||
const playerName = startScreen.querySelector('#player_name')
|
||||
@ -515,6 +591,12 @@
|
||||
const dataMineDestroyed = Battleship.DOM.dataMineDestroyed = gameScreen.querySelector('#g_s_num')
|
||||
Battleship.DOM.statusCurrent = gameScreen.querySelector('#g_s_stat')
|
||||
|
||||
const doneBtn = resultScreen.querySelector('#lobby')
|
||||
Battleship.DOM.winStatus = resultScreen.querySelector('#wonlost')
|
||||
|
||||
const chatbox = Battleship.DOM.chatbox = gameScreen.querySelector('#messages')
|
||||
const chatfield = Battleship.DOM.chatfield = gameScreen.querySelector('#message_send')
|
||||
|
||||
GameDrawer.initialize()
|
||||
|
||||
let uname = getStored('name')
|
||||
@ -528,6 +610,16 @@
|
||||
}
|
||||
}, false)
|
||||
|
||||
chatfield.addEventListener('keydown', (e) => {
|
||||
if (e.keyCode === 13 && Battleship.Game.gameId) {
|
||||
if (chatfield.value != '') {
|
||||
io.emit('chat_send', {message: chatfield.value, gameId: Battleship.Game.gameId})
|
||||
addChatMessage('chat me', Battleship.playerName, chatfield.value)
|
||||
chatfield.value = ''
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
startButton.addEventListener('click', (e) => {
|
||||
attemptJoin(playerName.value)
|
||||
}, false)
|
||||
@ -544,6 +636,10 @@
|
||||
io.emit('poll_games')
|
||||
})
|
||||
|
||||
doneBtn.addEventListener('click', (e) => {
|
||||
gameEnds(0, null)
|
||||
})
|
||||
|
||||
waitlistQuit.addEventListener('click', (e) => {
|
||||
io.emit('leave_game', {gameId: Battleship.Game.gameId})
|
||||
})
|
||||
@ -568,6 +664,10 @@
|
||||
}
|
||||
})
|
||||
|
||||
io.on('chat', (data) => {
|
||||
addChatMessage('chat', data.name, data.message)
|
||||
})
|
||||
|
||||
io.on('update_hits', (data) => {
|
||||
if (data.me) {
|
||||
Battleship.Game.gridHome.strikes = data.strikes
|
||||
@ -576,7 +676,7 @@
|
||||
}
|
||||
})
|
||||
|
||||
io.on('updateShip', (dship) => {
|
||||
io.on('update_ship', (dship) => {
|
||||
for (let i in Battleship.Game.gridHome.ships) {
|
||||
let ship = Battleship.Game.gridHome.ships[i]
|
||||
if (ship.name === dship.name) {
|
||||
@ -623,6 +723,10 @@
|
||||
forceRelogin()
|
||||
})
|
||||
|
||||
io.on('display_result', (data) => {
|
||||
GameDrawer.resultScreen(Battleship.Game.gridHome.ships, data.enemyShips, Battleship.Game.gridHome.strikes, Battleship.Game.gridOpponent)
|
||||
})
|
||||
|
||||
io.on('game_end', (data) => {
|
||||
gameEnds(data.result, data.win)
|
||||
})
|
||||
|
50
server.js
50
server.js
@ -4,17 +4,18 @@ const http = require('http')
|
||||
const path = require('path')
|
||||
|
||||
// TODO LIST:
|
||||
// * More ships
|
||||
// * Timer
|
||||
// * Chat box
|
||||
// * Side-by-side board display
|
||||
|
||||
const ships = [
|
||||
{name: 'biggest', tiles: 5, destCount: 4},
|
||||
{name: 'bigger', tiles: 4, destCount: 3},
|
||||
{name: 'medium', tiles: 3, destCount: 2},
|
||||
{name: 'smaller', tiles: 3, destCount: 2},
|
||||
{name: 'smallest', tiles: 2, destCount: 1}
|
||||
{name: 'aircraft_carrier1', tiles: 5, destCount: 4},
|
||||
{name: 'aircraft_carrier2', tiles: 5, destCount: 4},
|
||||
{name: 'cruiser', tiles: 4, destCount: 3},
|
||||
{name: 'ferry', tiles: 3, destCount: 2},
|
||||
{name: 'fishing_ship', tiles: 3, destCount: 2},
|
||||
{name: 'destroyer', tiles: 2, destCount: 1},
|
||||
{name: 'submarine1', tiles: 1, destCount: 1},
|
||||
{name: 'submarine2', tiles: 1, destCount: 1}
|
||||
]
|
||||
|
||||
let app = express()
|
||||
@ -202,6 +203,8 @@ function waitingGamesList (uid) {
|
||||
function determinePlayerById (gameId, uid) {
|
||||
let game = games[gameId]
|
||||
|
||||
if (!game) return null
|
||||
|
||||
if (game.player1 && game.player1.uid === uid) {
|
||||
return 'player1'
|
||||
} else if (game.player2 && game.player2.uid === uid) {
|
||||
@ -476,7 +479,7 @@ io.on('connection', (socket) => {
|
||||
let me = game[playerInGame]
|
||||
|
||||
if (result.ship) {
|
||||
clients[opponentObj.uid].socket.emit('updateShip', result.ship)
|
||||
clients[opponentObj.uid].socket.emit('update_ship', result.ship)
|
||||
}
|
||||
|
||||
clients[me.uid].socket.emit('update_hits', {me: true, strikes: me.strikes})
|
||||
@ -499,6 +502,8 @@ io.on('connection', (socket) => {
|
||||
clients[me.uid].socket.emit('infmessage', 'You missed!')
|
||||
break
|
||||
case 6:
|
||||
clients[opponentObj.uid].socket.emit('display_result', {enemyShips: me.ships, gameId: data.gameId})
|
||||
clients[me.uid].socket.emit('display_result', {enemyShips: opponentObj.ships, gameId: data.gameId})
|
||||
endGame(data.gameId, client, opponentObj.uid)
|
||||
break
|
||||
}
|
||||
@ -513,6 +518,35 @@ io.on('connection', (socket) => {
|
||||
})
|
||||
})
|
||||
|
||||
socket.on('chat_send', (data) => {
|
||||
let client = clientsBySocketID(socket.conn.id)
|
||||
|
||||
if (!client) {
|
||||
socket.emit('game_error', {message: 'You are not logged in properly!'})
|
||||
socket.emit('force_relog')
|
||||
return
|
||||
}
|
||||
|
||||
let game = games[data.gameId]
|
||||
let playerInGame = determinePlayerById(data.gameId, client)
|
||||
|
||||
if (!playerInGame) {
|
||||
socket.emit('game_error', {message: 'unexpected error. code: 763'})
|
||||
return
|
||||
}
|
||||
|
||||
let opponent = 'player2'
|
||||
|
||||
if (playerInGame === 'player2') {
|
||||
opponent = 'player1'
|
||||
}
|
||||
|
||||
let opponentObj = game[opponent]
|
||||
let me = game[playerInGame]
|
||||
|
||||
clients[opponentObj.uid].socket.emit('chat', {name: clients[me.uid].name, message: data.message})
|
||||
})
|
||||
|
||||
socket.on('disconnect', () => {
|
||||
let client = clientsBySocketID(socket.conn.id)
|
||||
if (!client) return
|
||||
|
Loading…
Reference in New Issue
Block a user