diff --git a/client/index.css b/client/index.css
index 9ab203e..b5eb064 100644
--- a/client/index.css
+++ b/client/index.css
@@ -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;
}
diff --git a/client/index.html b/client/index.html
index 37c73bc..cf2bbf0 100644
--- a/client/index.html
+++ b/client/index.html
@@ -60,6 +60,24 @@
You have 0 ships left.
Your opponent has 0 ships left.
Your turn.
+
+
+
+
+
+ You Lost!
+
+
+
+
Opponent's ships
+
+
+
+
Your ships
+
diff --git a/client/index.js b/client/index.js
index 01fc9fa..7b8d5a3 100644
--- a/client/index.js
+++ b/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.
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'
- Battleship.DOM.selectionScreen.style.display = 'block'
+ 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, "'")
+ }
+
+ function addChatMessage (type, senderName, message) {
+ let msgElem = ''
+ if (senderName) {
+ msgElem += '' + senderName + ' '
+ }
+ msgElem += '' + escapeHtml(message) + ''
+
+ 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)
})
diff --git a/server.js b/server.js
index b67efcd..80d553a 100644
--- a/server.js
+++ b/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