Uploaded the base of the project the working demo of CH1 Multiplayer Game Development with HTML5

This commit is contained in:
2021-06-01 11:12:45 +02:00
parent 8ff9857e43
commit 4f8071fffe
1258 changed files with 181409 additions and 0 deletions
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
+97
View File
@@ -0,0 +1,97 @@
@font-face {
font-family: 'Lato';
font-style: normal;
font-weight: 400;
src: local('Lato Regular'), local('Lato-Regular'), url(Lato.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
}
@font-face {
font-family: 'Quicksand';
font-style: normal;
font-weight: 400;
src: local('Quicksand'), local('Quicksand'), url(Quicksand.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
}
::selection {
background: transparent;
}
body {
background: #A5DAD2;
font-family: Quicksand, san-serif;
}
.bgWhite {
background: #F5F2F5;
}
.colorWhite {
color: #F5F2F5 !important;
}
.bgDark {
background: #516D66;
}
.colorDark {
color: #516D66;
}
.bgRed {
background: #F286A0;
}
.colorRed {
color: #F286A0 !important;
}
.gameBoard, .scoreBoard {
font-weight: 400;
}
.gameBoard {
width: 100%;
}
.gameBoard td {
text-align: center;
color: #516D66;
font-size: 8em;
cursor: pointer;
transition: all 0.5s;
}
.gameCell {
width: 181px;
height: 181px;
}
.gameCell:not(.marked):hover {
box-shadow: 0 0 42px #555;
}
.gameBoard td.gameCell.notActive:hover, .gameBoard td.gameCell.notActive:active {
box-shadow: none !important;
cursor: default;
}
.scoreBoard {
color: #516D66;
height: 100px;
}
.boardCol {
width: 5px;
cursor: default !important;
}
.boardRow {
height: 5px;
cursor: default !important;
}
.scoreBoard span.active {
border-bottom: 4px solid #F286A0;
}
+241
View File
@@ -0,0 +1,241 @@
/**
*
* @constructor
*/
var Board = function(scoreBoard) {
this.cells = [];
this.dom = document.createElement('table');
this.dom.addEventListener('click', this.mark.bind(this));
this.players = [];
this.currentTurn = 0;
this.ready = false;
this.scoreBoard = scoreBoard;
this.init();
};
Board.prototype.onMark = function(cellId){};
/**
*
*/
Board.prototype.init = function() {
var row = document.createElement('tr');
var rowCol = document.createElement('td');
var col = document.createElement('td');
var cell = document.createElement('td');
rowCol.classList.add('boardRow');
rowCol.classList.add('bgWhite');
rowCol.setAttribute('colspan', 5);
row.appendChild(rowCol);
col.classList.add('boardCol');
col.classList.add('bgWhite');
cell.classList.add('gameCell');
cell.classList.add('notActive');
cell.setAttribute('marked', 'false');
cell.setAttribute('data-intent', 'gameCell');
this.dom.classList.add('gameBoard');
for (var i = 0; i < 9; i++) {
this.cells.push(cell.cloneNode(true));
}
for (var r, i = 0; i < 9; i += 3) {
r = row.cloneNode(false);
r.appendChild(this.cells[i]);
r.appendChild(col.cloneNode(false));
r.appendChild(this.cells[i + 1]);
r.appendChild(col.cloneNode(false));
r.appendChild(this.cells[i + 2]);
this.dom.appendChild(r);
if (i < 6) {
this.dom.appendChild(row.cloneNode(true));
}
}
};
/**
*
* @param container
*/
Board.prototype.bindTo = function(container) {
container.appendChild(this.dom);
};
Board.prototype.disableAll = function() {
this.cells.forEach(function(cell) {
cell.classList.add('notActive');
});
};
Board.prototype.enableAll = function() {
this.cells.forEach(function(cell) {
cell.classList.remove('notActive');
cell.setAttribute('marked', 'false');
});
};
Board.prototype.enableTurn = function() {
this.cells.forEach(function(cell) {
if (cell.getAttribute('marked') === 'false') {
cell.classList.remove('notActive');
cell.setAttribute('active', 'true');
}
});
};
Board.prototype.highlightCells = function(pos) {
var cells = this.cells;
pos.forEach(function(i) {
cells[i].classList.add('colorRed');
});
cells.forEach(function(cell) {
cell.setAttribute('marked', 'true');
});
};
Board.prototype.lowlightCells = function() {
var cells = this.cells;
cells.forEach(function(cell) {
cell.classList.add('colorWhite');
});
};
/**
*
* @param event
*/
Board.prototype.mark = function(event) {
var target = event.target;
if (this.ready && target.getAttribute('data-intent') === 'gameCell' && target.getAttribute('active') === 'true') {
this.onMark(this.cells.indexOf(target));
this.disableAll();
}
};
/**
*
* @param cellId
* @param label
*/
Board.prototype.doMark = function(cellId, label) {
var cell = this.cells[cellId];
cell.textContent = label;
cell.classList.add('notActive');
cell.setAttribute('marked', 'true');
};
/**
*
* @param pos
*/
Board.prototype.doWinner = function(pos) {
this.disableAll();
this.highlightCells(pos);
};
/**
*
*/
Board.prototype.doDraw = function() {
this.lowlightCells();
};
/**
*
*/
Board.prototype.highlightScoreboard = function(playerId) {
this.scoreBoard.forEach(function(score) {
score.classList.remove('active');
});
this.scoreBoard.forEach(function(board){
if (board.getAttribute('playerId') == playerId) {
board.classList.add('active');
}
});
};
/**
*
* @returns {{win: boolean, pos: Array}}
*/
Board.prototype.checkWinner = function() {
var winPosition = [
[0, 1, 2],
[3, 4, 5],
[6, 7, 8],
[0, 3, 6],
[1, 4, 7],
[2, 5, 8],
[0, 4, 8],
[6, 4, 2]
];
var player = this.players[this.currentTurn];
var pos = [];
var win = winPosition.some(function(win) {
if (this.cells[win[0]].textContent === player.label) {
var res = this.cells[win[0]].textContent === this.cells[win[1]].textContent && this.cells[win[1]].textContent === this.cells[win[2]].textContent;
if (res) {
pos = win;
return true;
}
}
return false;
}, this);
return {
win: win,
pos: pos
};
};
/**
*
* @returns {boolean}
*/
Board.prototype.checkDraw = function() {
return this.cells.every(function(cell) {
return cell.textContent === this.players[0].label || cell.textContent === this.players[1].label;
}, this);
};
/**
*
* @param player
*/
Board.prototype.addPlayer = function(player) {
if (this.players.length < 2) {
var isNew = this.players.filter(function(p) {
return p.id == player.id;
}).length === 0;
if (isNew) {
this.players.push(player);
if (this.players.length === 1) {
this.scoreBoard[this.players.length - 1].textContent = player.label + ' ' + player.name;
} else {
this.scoreBoard[this.players.length - 1].textContent = player.name + ' ' + player.label;
}
this.scoreBoard[this.players.length - 1].setAttribute('playerId', player.id);
}
}
};
+133
View File
@@ -0,0 +1,133 @@
var socket = new WebSocket('ws://192.168.188.23:2667');
var events = {
outgoing: {
JOIN_GAME: 'csJoinGame',
MARK: 'csMark',
QUIT: 'csQuit'
},
incoming: {
JOIN_GAME: 'scJoinGame',
MARK: 'scMark',
SET_TURN: 'scSetTurn',
OPPONENT_READY: 'scOpponentReady',
GAME_OVER: 'scGameOver',
ERROR: 'scError',
QUIT: 'scQuit'
}
};
var container = document.querySelector('#gameBoard');
var startBtn = document.querySelector('#startBtn');
var nameInput = document.querySelector('#nickname');
var scoreBoard = [
document.querySelector('#p1Score'),
document.querySelector('#p2Score')
];
var hero = {};
var board = new Board(scoreBoard);
startBtn.setAttribute('disabled', true);
nameInput.setAttribute('disabled', true);
nameInput.setAttribute('placeholder', 'Loading...');
/**
*
* @param action
* @param data
* @returns {*}
*/
function makeMessage(action, data){
var resp = {
action: action,
data: data
};
return JSON.stringify(resp);
}
/**
*
* @param cellId
*/
board.onMark = function(cellId){
socket.send(makeMessage(events.outgoing.MARK, {playerId: hero.id, cellId: cellId}));
};
/**
*
*/
function start() {
while (container.lastChild) {
container.removeChild(container.lastChild);
}
if (board.players.length === 1) {
scoreBoard[1].textContent = 'waiting...';
}
board.bindTo(container);
}
startBtn.addEventListener('click', function(event) {
var name = nameInput.value.trim();
if (name.length > 0) {
hero.name = name;
socket.send(makeMessage(events.outgoing.JOIN_GAME, name));
}
});
socket.onmessage = function(event){
var msg = JSON.parse(event.data);
switch (msg.action) {
case events.incoming.ERROR:
alert('Error: ' + msg.data);
break;
case events.incoming.JOIN_GAME:
board.addPlayer(msg.data);
if (msg.data.name === hero.name) {
hero = msg.data;
start();
}
break;
case events.incoming.SET_TURN:
board.highlightScoreboard(msg.data.id);
board.ready = true;
if (msg.data.id === hero.id) {
board.enableTurn();
}
break;
case events.incoming.MARK:
board.doMark(msg.data.cellId, msg.data.player.label);
break;
case events.incoming.GAME_OVER:
if (msg.data.player) {
board.doWinner(msg.data.pos);
} else {
board.doDraw();
}
socket.send(makeMessage(events.outgoing.QUIT, hero.id));
break;
case events.incoming.QUIT:
socket.close();
break;
}
};
socket.onopen = function(event) {
startBtn.removeAttribute('disabled');
nameInput.removeAttribute('disabled');
nameInput.removeAttribute('placeholder');
nameInput.focus();
};