end screen, more ships, chat

This commit is contained in:
Evert Prants 2017-04-04 19:35:17 +03:00
parent 063fbd92be
commit 624e47af63
Signed by: evert
GPG Key ID: 1688DA83D222D0B5
4 changed files with 212 additions and 15 deletions

View File

@ -68,7 +68,6 @@ canvas {
height: 512px; height: 512px;
background-color: #03A9F4; background-color: #03A9F4;
margin: 10px; margin: 10px;
/*border: 5px solid #2196F3;*/
} }
.boxlayout { .boxlayout {
text-align: center; text-align: center;
@ -151,5 +150,47 @@ button#leave {
width: 200px; width: 200px;
} }
#game_canvas { #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;
} }

View File

@ -60,6 +60,24 @@
<span class="stat">You have <span id="g_s_num">0</span> ships left.</span> <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">Your opponent has <span id="o_s_num">0</span> ships left.</span>
<span class="stat" id="g_s_stat">Your turn.</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> </div>
</div> </div>

View File

@ -10,12 +10,9 @@
played: 0, played: 0,
Game: { Game: {
gameId: null, gameId: null,
inGame: false,
myTurn: true, myTurn: true,
opponentID: '', opponentID: '',
opponentName: '', opponentName: '',
ships: 0,
oShips: 0,
gridHome: {ships: [], strikes: []}, gridHome: {ships: [], strikes: []},
gridOpponent: [] 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: () => { click: () => {
if (GameDrawer.placingShips && GameDrawer.canPlace && GameDrawer.shipIndex != -1) { if (GameDrawer.placingShips && GameDrawer.canPlace && GameDrawer.shipIndex != -1) {
let shipData = Battleship.ships[GameDrawer.shipIndex] let shipData = Battleship.ships[GameDrawer.shipIndex]
@ -377,6 +420,8 @@
Battleship.Game.opponentName = game.opponentName Battleship.Game.opponentName = game.opponentName
Battleship.DOM.opponentName.innerHTML = game.opponentName Battleship.DOM.opponentName.innerHTML = game.opponentName
Battleship.DOM.chatbox.innerHTML = ''
io.emit('game_poll', {gameId: Battleship.Game.gameId}) io.emit('game_poll', {gameId: Battleship.Game.gameId})
logStatus('Place your ships onto the board.<br>Press `r` to rotate') logStatus('Place your ships onto the board.<br>Press `r` to rotate')
@ -386,6 +431,7 @@
Battleship.DOM.waitlistBtns.style.display = 'block' Battleship.DOM.waitlistBtns.style.display = 'block'
Battleship.DOM.waitlistQuit.style.display = 'none' Battleship.DOM.waitlistQuit.style.display = 'none'
GameDrawer.startGame() GameDrawer.startGame()
addChatMessage('event', null, 'Game started!')
} }
function attemptJoin (name) { function attemptJoin (name) {
@ -446,8 +492,10 @@
if (reason === 1) { if (reason === 1) {
if (winner === true) { if (winner === true) {
alert('You won!') alert('You won!')
Battleship.DOM.winStatus.innerHTML = 'Won'
} else { } else {
alert('You lost.') alert('You lost.')
Battleship.DOM.winStatus.innerHTML = 'Lost'
} }
} }
@ -458,8 +506,15 @@
Battleship.locked = false Battleship.locked = false
Battleship.Game.gameId = null Battleship.Game.gameId = null
io.emit('poll_games') io.emit('poll_games')
Battleship.DOM.gameScreen.style.display = 'none' Battleship.DOM.gameScreen.style.display = 'none'
if (reason === 1) {
Battleship.DOM.resultScreen.style.display = 'block'
} else {
Battleship.DOM.selectionScreen.style.display = 'block' Battleship.DOM.selectionScreen.style.display = 'block'
Battleship.DOM.resultScreen.style.display = 'none'
}
Battleship.DOM.waitlistBtns.style.display = 'block' Battleship.DOM.waitlistBtns.style.display = 'block'
Battleship.DOM.waitlistQuit.style.display = 'none' Battleship.DOM.waitlistQuit.style.display = 'none'
@ -475,16 +530,37 @@
Battleship.DOM.gameScreen.style.display = 'none' Battleship.DOM.gameScreen.style.display = 'none'
Battleship.DOM.selectionScreen.style.display = 'none' Battleship.DOM.selectionScreen.style.display = 'none'
Battleship.DOM.startScreen.style.display = 'block' Battleship.DOM.startScreen.style.display = 'block'
Battleship.DOM.resultScreen.style.display = 'none'
Battleship.locked = false Battleship.locked = false
Battleship.playerName = '' Battleship.playerName = ''
Battleship.Game.gameId = null Battleship.Game.gameId = null
} }
function escapeHtml(unsafe) {
return unsafe
.replace(/&/g, "&amp;")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;")
.replace(/"/g, "&quot;")
.replace(/'/g, "&#039;")
}
function addChatMessage (type, senderName, message) {
let msgElem = '<div class="message t_' + type + '">'
if (senderName) {
msgElem += '<span class="sender">' + senderName + '</span>&nbsp;'
}
msgElem += '<span class="line">' + escapeHtml(message) + '</span>'
Battleship.DOM.chatbox.innerHTML += msgElem
}
window.onload = () => { window.onload = () => {
const startScreen = Battleship.DOM.startScreen = $.querySelector('#start') const startScreen = Battleship.DOM.startScreen = $.querySelector('#start')
const selectionScreen = Battleship.DOM.selectionScreen = $.querySelector('#selection') const selectionScreen = Battleship.DOM.selectionScreen = $.querySelector('#selection')
const gameScreen = Battleship.DOM.gameScreen = $.querySelector('#game') const gameScreen = Battleship.DOM.gameScreen = $.querySelector('#game')
const resultScreen = Battleship.DOM.resultScreen = $.querySelector('#endresult')
const warning = Battleship.DOM.joinWarn = startScreen.querySelector('#warning_message') const warning = Battleship.DOM.joinWarn = startScreen.querySelector('#warning_message')
const playerName = startScreen.querySelector('#player_name') const playerName = startScreen.querySelector('#player_name')
@ -515,6 +591,12 @@
const dataMineDestroyed = Battleship.DOM.dataMineDestroyed = gameScreen.querySelector('#g_s_num') const dataMineDestroyed = Battleship.DOM.dataMineDestroyed = gameScreen.querySelector('#g_s_num')
Battleship.DOM.statusCurrent = gameScreen.querySelector('#g_s_stat') 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() GameDrawer.initialize()
let uname = getStored('name') let uname = getStored('name')
@ -528,6 +610,16 @@
} }
}, false) }, 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) => { startButton.addEventListener('click', (e) => {
attemptJoin(playerName.value) attemptJoin(playerName.value)
}, false) }, false)
@ -544,6 +636,10 @@
io.emit('poll_games') io.emit('poll_games')
}) })
doneBtn.addEventListener('click', (e) => {
gameEnds(0, null)
})
waitlistQuit.addEventListener('click', (e) => { waitlistQuit.addEventListener('click', (e) => {
io.emit('leave_game', {gameId: Battleship.Game.gameId}) 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) => { io.on('update_hits', (data) => {
if (data.me) { if (data.me) {
Battleship.Game.gridHome.strikes = data.strikes 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) { for (let i in Battleship.Game.gridHome.ships) {
let ship = Battleship.Game.gridHome.ships[i] let ship = Battleship.Game.gridHome.ships[i]
if (ship.name === dship.name) { if (ship.name === dship.name) {
@ -623,6 +723,10 @@
forceRelogin() 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) => { io.on('game_end', (data) => {
gameEnds(data.result, data.win) gameEnds(data.result, data.win)
}) })

View File

@ -4,17 +4,18 @@ const http = require('http')
const path = require('path') const path = require('path')
// TODO LIST: // TODO LIST:
// * More ships
// * Timer // * Timer
// * Chat box // * Chat box
// * Side-by-side board display
const ships = [ const ships = [
{name: 'biggest', tiles: 5, destCount: 4}, {name: 'aircraft_carrier1', tiles: 5, destCount: 4},
{name: 'bigger', tiles: 4, destCount: 3}, {name: 'aircraft_carrier2', tiles: 5, destCount: 4},
{name: 'medium', tiles: 3, destCount: 2}, {name: 'cruiser', tiles: 4, destCount: 3},
{name: 'smaller', tiles: 3, destCount: 2}, {name: 'ferry', tiles: 3, destCount: 2},
{name: 'smallest', tiles: 2, destCount: 1} {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() let app = express()
@ -202,6 +203,8 @@ function waitingGamesList (uid) {
function determinePlayerById (gameId, uid) { function determinePlayerById (gameId, uid) {
let game = games[gameId] let game = games[gameId]
if (!game) return null
if (game.player1 && game.player1.uid === uid) { if (game.player1 && game.player1.uid === uid) {
return 'player1' return 'player1'
} else if (game.player2 && game.player2.uid === uid) { } else if (game.player2 && game.player2.uid === uid) {
@ -476,7 +479,7 @@ io.on('connection', (socket) => {
let me = game[playerInGame] let me = game[playerInGame]
if (result.ship) { 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}) 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!') clients[me.uid].socket.emit('infmessage', 'You missed!')
break break
case 6: 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) endGame(data.gameId, client, opponentObj.uid)
break 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', () => { socket.on('disconnect', () => {
let client = clientsBySocketID(socket.conn.id) let client = clientsBySocketID(socket.conn.id)
if (!client) return if (!client) return