commit
5d2db7eed0
@ -32,8 +32,7 @@ public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void registerStompEndpoints(StompEndpointRegistry registry) {
|
public void registerStompEndpoints(StompEndpointRegistry registry) {
|
||||||
// Allow all origins: for JSFiddle, lol
|
registry.addEndpoint("/stomp").withSockJS();
|
||||||
registry.addEndpoint("/stomp").setAllowedOrigins("*").withSockJS();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -7,22 +7,6 @@ var SIDE = 50;
|
|||||||
var MARGIN_TOP = 100;
|
var MARGIN_TOP = 100;
|
||||||
var MARGIN_BOTTOM = 75;
|
var MARGIN_BOTTOM = 75;
|
||||||
|
|
||||||
var myScore = 0;
|
|
||||||
var myGuess;
|
|
||||||
var myGuesses;
|
|
||||||
var myProgress;
|
|
||||||
var myResults;
|
|
||||||
var myUsername;
|
|
||||||
var opponentScore = 0;
|
|
||||||
var opponentResults;
|
|
||||||
var opponentUsername;
|
|
||||||
var lastWord;
|
|
||||||
|
|
||||||
var appDiv = document.getElementById('appDiv');
|
|
||||||
var canvasDiv = document.getElementById('canvasDiv');
|
|
||||||
var canvas = document.getElementById('canvas');
|
|
||||||
var ctx = canvas.getContext('2d');
|
|
||||||
|
|
||||||
var client;
|
var client;
|
||||||
var sessionId = null;
|
var sessionId = null;
|
||||||
|
|
||||||
@ -30,14 +14,146 @@ var vm = new Vue({
|
|||||||
el: '#vue-app',
|
el: '#vue-app',
|
||||||
data: {
|
data: {
|
||||||
games: [],
|
games: [],
|
||||||
gameId: null
|
gameId: null,
|
||||||
|
messages: [],
|
||||||
|
username: null,
|
||||||
|
usernameError: '',
|
||||||
|
myScore: 0,
|
||||||
|
myGuess: '',
|
||||||
|
myGuesses: [],
|
||||||
|
myProgress: [],
|
||||||
|
myResults: [],
|
||||||
|
opponentScore: 0,
|
||||||
|
opponentResults: [],
|
||||||
|
opponentUsername: null,
|
||||||
|
lastWord: null
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
inGame: function() {
|
inGame: function() {
|
||||||
return this.gameId !== null;
|
return this.gameId !== null;
|
||||||
|
},
|
||||||
|
inStartedGame: function() {
|
||||||
|
var game = this.getGame(this.gameId);
|
||||||
|
return game !== null && game.started === true;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
drawMyBoard: function(ctx) {
|
||||||
|
var x = 25, y = MARGIN_TOP;
|
||||||
|
this.drawUsername(ctx, x, y, this.username);
|
||||||
|
this.drawScore(ctx, x, y, this.myScore);
|
||||||
|
this.drawInput(ctx, x, y, this.myGuess);
|
||||||
|
var yStart = this.drawGuesses(ctx, x, y, this.myGuesses, this.myResults);
|
||||||
|
this.drawHint(ctx, x, yStart, this.myProgress);
|
||||||
|
this.drawGrid(ctx, x, y);
|
||||||
|
},
|
||||||
|
drawOpponentBoard: function(ctx) {
|
||||||
|
var x = 325, y = MARGIN_TOP;
|
||||||
|
this.drawUsername(ctx, x, y, this.opponentUsername);
|
||||||
|
this.drawScore(ctx, x, y, this.opponentScore);
|
||||||
|
this.drawResults(ctx, x, y, this.opponentResults);
|
||||||
|
this.drawGrid(ctx, x, y);
|
||||||
|
},
|
||||||
|
drawLastWord: function(canvas, ctx) {
|
||||||
|
if (this.lastWord) {
|
||||||
|
var x = canvas.width / 2;
|
||||||
|
var y = canvas.height - MARGIN_BOTTOM / 2;
|
||||||
|
ctx.fillStyle = 'black';
|
||||||
|
ctx.fillText('Previous word: ' + this.lastWord.toUpperCase(), x, y);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
drawUsername: function(ctx, x, y, username) {
|
||||||
|
var usernameX = x + WIDTH / 2;
|
||||||
|
var usernameY = y - 60;
|
||||||
|
ctx.fillStyle = 'black';
|
||||||
|
ctx.fillText(username, usernameX, usernameY);
|
||||||
|
},
|
||||||
|
drawScore: function(ctx, x, y, score) {
|
||||||
|
var scoreX = x + WIDTH / 2;
|
||||||
|
var scoreY = y - 25;
|
||||||
|
ctx.fillStyle = 'black';
|
||||||
|
ctx.fillText(score, scoreX, scoreY);
|
||||||
|
},
|
||||||
|
drawGrid: function(ctx, xOrigin, yOrigin) {
|
||||||
|
ctx.beginPath();
|
||||||
|
for (var x = 0; x <= WIDTH; x += SIDE) {
|
||||||
|
ctx.moveTo(xOrigin + x, yOrigin);
|
||||||
|
ctx.lineTo(xOrigin + x, yOrigin + HEIGHT);
|
||||||
|
}
|
||||||
|
for (var y = 0; y <= HEIGHT; y += SIDE) {
|
||||||
|
ctx.moveTo(xOrigin, yOrigin + y);
|
||||||
|
ctx.lineTo(xOrigin + WIDTH, yOrigin + y);
|
||||||
|
}
|
||||||
|
ctx.strokeStyle = 'black';
|
||||||
|
ctx.stroke();
|
||||||
|
},
|
||||||
|
drawInput: function(ctx, xOrigin, yOrigin, input) {
|
||||||
|
ctx.fillStyle = 'green';
|
||||||
|
var x = xOrigin + SIDE * 0.5;
|
||||||
|
var y = yOrigin + SIDE * 0.5;
|
||||||
|
for (var i = 0; i < input.length; i++) {
|
||||||
|
ctx.fillText(input[i], x, y);
|
||||||
|
x += SIDE;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
drawGuesses: function(ctx, xOrigin, yOrigin, guesses, results) {
|
||||||
|
var y = yOrigin + SIDE * 1.5;
|
||||||
|
var numGuesses = Math.min(4, guesses.length);
|
||||||
|
for (var i = 0; i < numGuesses; i++) {
|
||||||
|
var x = xOrigin + SIDE * 0.5;
|
||||||
|
var guess = guesses[guesses.length - numGuesses + i];
|
||||||
|
var result = results[results.length - numGuesses + i];
|
||||||
|
for (var j = 0; j < 5; j++) {
|
||||||
|
if (result[j] === 1) {
|
||||||
|
ctx.fillStyle = 'yellow';
|
||||||
|
ctx.fillRect(x - SIDE * 0.5, y - SIDE * 0.5, SIDE, SIDE);
|
||||||
|
} else if (result[j] === 2) {
|
||||||
|
ctx.fillStyle = 'orange';
|
||||||
|
ctx.fillRect(x - SIDE * 0.5, y - SIDE * 0.5, SIDE, SIDE);
|
||||||
|
}
|
||||||
|
ctx.fillStyle = 'green';
|
||||||
|
ctx.fillText(guess[j], x, y);
|
||||||
|
x += SIDE;
|
||||||
|
}
|
||||||
|
y += SIDE;
|
||||||
|
}
|
||||||
|
return y;
|
||||||
|
},
|
||||||
|
drawResults: function(ctx, xOrigin, yOrigin, results) {
|
||||||
|
var y = yOrigin + SIDE * 1.5;
|
||||||
|
var numResults = Math.min(4, results.length);
|
||||||
|
for (var i = 0; i < numResults; i++) {
|
||||||
|
var x = xOrigin + SIDE * 0.5;
|
||||||
|
var result = results[results.length - numResults + i];
|
||||||
|
for (var j = 0; j < 5; j++) {
|
||||||
|
if (result[j] === 1) {
|
||||||
|
ctx.fillStyle = 'yellow';
|
||||||
|
ctx.fillRect(x - SIDE * 0.5, y - SIDE * 0.5, SIDE, SIDE);
|
||||||
|
} else if (result[j] === 2) {
|
||||||
|
ctx.fillStyle = 'orange';
|
||||||
|
ctx.fillRect(x - SIDE * 0.5, y - SIDE * 0.5, SIDE, SIDE);
|
||||||
|
}
|
||||||
|
x += SIDE;
|
||||||
|
}
|
||||||
|
y += SIDE;
|
||||||
|
}
|
||||||
|
return y;
|
||||||
|
},
|
||||||
|
drawHint: function(ctx, xOrigin, yOrigin, progress) {
|
||||||
|
var x = xOrigin + SIDE * 0.5;
|
||||||
|
for (var i = 0; i < 5; i++) {
|
||||||
|
ctx.fillText(progress[i], x, yOrigin);
|
||||||
|
x += SIDE;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getGame: function(gameId) {
|
||||||
|
for (var i = 0; i < this.games.length; i++) {
|
||||||
|
if (this.games[i].id === gameId) {
|
||||||
|
return this.games[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
hostGame: function(event) {
|
hostGame: function(event) {
|
||||||
client.send('/app/hostGame');
|
client.send('/app/hostGame');
|
||||||
},
|
},
|
||||||
@ -49,6 +165,84 @@ var vm = new Vue({
|
|||||||
},
|
},
|
||||||
leaveGame: function(event) {
|
leaveGame: function(event) {
|
||||||
client.send('/app/leaveGame');
|
client.send('/app/leaveGame');
|
||||||
|
},
|
||||||
|
removeGame: function(gameId) {
|
||||||
|
var indexToRemove = null;
|
||||||
|
for (var i = 0; i < this.games.length; i++) {
|
||||||
|
if (this.games[i].id === gameId) {
|
||||||
|
indexToRemove = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.games.splice(indexToRemove, 1);
|
||||||
|
},
|
||||||
|
onCanvasKeydown: function(event) {
|
||||||
|
if (event.which === KEYCODE_BACKSPACE) {
|
||||||
|
event.preventDefault();
|
||||||
|
this.myGuess = this.myGuess.substr(0, this.myGuess.length - 1);
|
||||||
|
this.repaint();
|
||||||
|
}
|
||||||
|
else if (event.which === KEYCODE_RETURN) {
|
||||||
|
if (this.myGuess.length === 5) {
|
||||||
|
client.send("/app/guess", {}, this.myGuess);
|
||||||
|
this.myGuess = '';
|
||||||
|
this.repaint();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onCanvasKeypress: function(event) {
|
||||||
|
var charCode = event.charCode;
|
||||||
|
if (isCharacter(charCode)) {
|
||||||
|
if (isCharacterLowercase(charCode)) {
|
||||||
|
charCode = charCode - 32;
|
||||||
|
}
|
||||||
|
var char = String.fromCharCode(charCode);
|
||||||
|
if (this.myGuess.length < 5) {
|
||||||
|
this.myGuess += char;
|
||||||
|
this.repaint();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onChatKeypress: function(event) {
|
||||||
|
var messageInput = event.target;
|
||||||
|
if (event.which === KEYCODE_RETURN) {
|
||||||
|
// Shift+Enter -> new line
|
||||||
|
if (!event.shiftKey) {
|
||||||
|
event.preventDefault();
|
||||||
|
var text = messageInput.value.trim();
|
||||||
|
if (text.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
messageInput.value = '';
|
||||||
|
client.send('/app/chat', {}, text);
|
||||||
|
addChatMessage(this.username, text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
repaint: function() {
|
||||||
|
var canvas = document.getElementById('canvas');
|
||||||
|
var ctx = canvas.getContext('2d');
|
||||||
|
ctx.font = '25px Monospace';
|
||||||
|
ctx.textBaseline = 'middle';
|
||||||
|
ctx.textAlign = 'center';
|
||||||
|
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||||
|
this.drawMyBoard(ctx);
|
||||||
|
this.drawOpponentBoard(ctx);
|
||||||
|
this.drawLastWord(canvas, ctx);
|
||||||
|
},
|
||||||
|
reset: function(firstLetter, clearScore) {
|
||||||
|
if (!firstLetter) {
|
||||||
|
firstLetter = '';
|
||||||
|
}
|
||||||
|
this.myGuess = '';
|
||||||
|
this.myGuesses = [];
|
||||||
|
this.myProgress = [firstLetter, '', '', '', ''];
|
||||||
|
this.myResults = [];
|
||||||
|
this.opponentResults = [];
|
||||||
|
if (clearScore) {
|
||||||
|
this.myScore = 0;
|
||||||
|
this.opponentScore = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -70,8 +264,6 @@ function main() {
|
|||||||
client = Stomp.over(new SockJS('/stomp'));
|
client = Stomp.over(new SockJS('/stomp'));
|
||||||
client.connect({}, afterConnected);
|
client.connect({}, afterConnected);
|
||||||
|
|
||||||
var usernameDiv = document.getElementById('usernameDiv');
|
|
||||||
var usernameError = document.getElementById('usernameError');
|
|
||||||
var usernameInput = document.getElementById('nicknameInput');
|
var usernameInput = document.getElementById('nicknameInput');
|
||||||
|
|
||||||
var usernameTopic = '/user/topic/sessionUsername';
|
var usernameTopic = '/user/topic/sessionUsername';
|
||||||
@ -80,26 +272,23 @@ function main() {
|
|||||||
var response = JSON.parse(message.body);
|
var response = JSON.parse(message.body);
|
||||||
if (response.success === true) {
|
if (response.success === true) {
|
||||||
console.log('Username: ' + response.username);
|
console.log('Username: ' + response.username);
|
||||||
myUsername = response.username;
|
vm.username = response.username;
|
||||||
start();
|
start();
|
||||||
usernameDiv.classList.add('hidden');
|
|
||||||
appDiv.classList.remove('hidden');
|
|
||||||
} else {
|
} else {
|
||||||
usernameError.innerHTML = response.errorMessage;
|
vm.usernameError = response.errorMessage;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
usernameInput.focus();
|
|
||||||
usernameInput.addEventListener('keydown', function(e) {
|
usernameInput.addEventListener('keydown', function(e) {
|
||||||
if (e.keyCode === KEYCODE_RETURN) {
|
if (event.keyCode === KEYCODE_RETURN) {
|
||||||
e.preventDefault();
|
event.preventDefault();
|
||||||
if (sessionId === null) {
|
if (sessionId === null) {
|
||||||
usernameError.innerHTML = 'Not connected to server';
|
vm.usernameError = 'Not connected to server';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var usernameValue = usernameInput.value.trim();
|
var usernameValue = usernameInput.value.trim();
|
||||||
if (usernameValue.length === 0) {
|
if (usernameValue.length === 0) {
|
||||||
usernameError.innerHTML = 'Name cannot be empty';
|
vm.usernameError = 'Name cannot be empty';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (usernameSubscription === null) {
|
if (usernameSubscription === null) {
|
||||||
@ -115,22 +304,12 @@ function main() {
|
|||||||
}
|
}
|
||||||
var usernameValue = usernameInput.value.trim();
|
var usernameValue = usernameInput.value.trim();
|
||||||
if (usernameValue.length !== 0) {
|
if (usernameValue.length !== 0) {
|
||||||
usernameError.innerHTML = '';
|
vm.usernameError = '';
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function start() {
|
function start() {
|
||||||
ctx.font = '25px Monospace';
|
|
||||||
ctx.textBaseline = 'middle';
|
|
||||||
ctx.textAlign = 'center';
|
|
||||||
|
|
||||||
addKeydownListener();
|
|
||||||
addKeypressListener();
|
|
||||||
addChatMessageListener();
|
|
||||||
|
|
||||||
reset();
|
|
||||||
repaint();
|
|
||||||
|
|
||||||
// Load initial data
|
// Load initial data
|
||||||
doHttpGet('/games', function(games) {
|
doHttpGet('/games', function(games) {
|
||||||
@ -158,89 +337,23 @@ function start() {
|
|||||||
client.subscribe('/user/topic/playerReports', onPlayerReport);
|
client.subscribe('/user/topic/playerReports', onPlayerReport);
|
||||||
}
|
}
|
||||||
|
|
||||||
// special keys
|
function addChatAnnouncement(body) {
|
||||||
function addKeydownListener() {
|
addMessageItem({
|
||||||
canvasDiv.addEventListener('keydown', function(e) {
|
body: body
|
||||||
if (e.which === KEYCODE_BACKSPACE) {
|
})
|
||||||
e.preventDefault();
|
|
||||||
myGuess = myGuess.substr(0, myGuess.length - 1);
|
|
||||||
repaint();
|
|
||||||
}
|
|
||||||
else if (e.which === KEYCODE_RETURN) {
|
|
||||||
if (myGuess.length === 5) {
|
|
||||||
client.send("/app/guess", {}, myGuess);
|
|
||||||
myGuess = '';
|
|
||||||
repaint();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// characters
|
|
||||||
function addKeypressListener() {
|
|
||||||
canvasDiv.addEventListener('keypress', function(e) {
|
|
||||||
var charCode = e.charCode;
|
|
||||||
if (isCharacter(charCode)) {
|
|
||||||
if (isCharacterLowercase(charCode)) {
|
|
||||||
charCode = charCode - 32;
|
|
||||||
}
|
|
||||||
var char = String.fromCharCode(charCode);
|
|
||||||
if (myGuess.length < 5) {
|
|
||||||
myGuess += char;
|
|
||||||
repaint();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function addChatMessageListener() {
|
|
||||||
var messageInput = document.getElementById('messageInput');
|
|
||||||
messageInput.addEventListener('keypress', function(e) {
|
|
||||||
if (e.which === KEYCODE_RETURN) {
|
|
||||||
// Shift+Enter -> new line
|
|
||||||
if (!e.shiftKey) {
|
|
||||||
e.preventDefault();
|
|
||||||
var text = messageInput.value.trim();
|
|
||||||
if (text.length === 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
messageInput.value = '';
|
|
||||||
client.send('/app/chat', {}, text);
|
|
||||||
addChatMessage(myUsername, text);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function addChatMessage(sender, body) {
|
function addChatMessage(sender, body) {
|
||||||
var messageList = document.getElementById('messageList');
|
addMessageItem({
|
||||||
var usernameNode = document.createElement('strong');
|
sender: sender,
|
||||||
var usernameTextNode = document.createTextNode(sender);
|
body: body
|
||||||
usernameNode.appendChild(usernameTextNode);
|
})
|
||||||
var messageTextNode = document.createTextNode(' ' + body);
|
|
||||||
var messageItem = document.createElement('div');
|
|
||||||
messageItem.classList.add('message-item');
|
|
||||||
messageItem.appendChild(usernameNode);
|
|
||||||
messageItem.appendChild(messageTextNode);
|
|
||||||
addMessageItem(messageList, messageItem);
|
|
||||||
}
|
|
||||||
|
|
||||||
function addChatAnnouncement(body) {
|
|
||||||
var messageList = document.getElementById('messageList');
|
|
||||||
var messageTextNode = document.createTextNode(body);
|
|
||||||
var messageItem = document.createElement('div');
|
|
||||||
messageItem.classList.add('message-item');
|
|
||||||
messageItem.classList.add('log');
|
|
||||||
messageItem.appendChild(messageTextNode);
|
|
||||||
addMessageItem(messageList, messageItem);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Auto-scrolls the message list
|
// Auto-scrolls the message list
|
||||||
function addMessageItem(messageList, messageItem) {
|
function addMessageItem(messageItem) {
|
||||||
if (!messageList.hasChildNodes()) {
|
vm.messages.push(messageItem);
|
||||||
messageItem.classList.add('first');
|
var messageList = document.getElementById('messageList');
|
||||||
}
|
|
||||||
messageList.appendChild(messageItem);
|
|
||||||
messageList.scrollTop = messageList.scrollHeight;
|
messageList.scrollTop = messageList.scrollHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -256,124 +369,6 @@ function doHttpGet(url, callback) {
|
|||||||
xhr.send();
|
xhr.send();
|
||||||
}
|
}
|
||||||
|
|
||||||
function drawMyBoard() {
|
|
||||||
var x = 25, y = MARGIN_TOP;
|
|
||||||
drawUsername(x, y, myUsername);
|
|
||||||
drawScore(x, y, myScore);
|
|
||||||
drawInput(x, y, myGuess);
|
|
||||||
var yStart = drawGuesses(x, y, myGuesses, myResults);
|
|
||||||
drawHint(x, yStart, myProgress);
|
|
||||||
drawGrid(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
function drawOpponentBoard() {
|
|
||||||
var x = 325, y = MARGIN_TOP;
|
|
||||||
drawUsername(x, y, opponentUsername);
|
|
||||||
drawScore(x, y, opponentScore);
|
|
||||||
drawResults(x, y, opponentResults);
|
|
||||||
drawGrid(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
function drawLastWord() {
|
|
||||||
if (lastWord) {
|
|
||||||
var x = canvas.width / 2;
|
|
||||||
var y = canvas.height - MARGIN_BOTTOM / 2;
|
|
||||||
ctx.fillStyle = 'black';
|
|
||||||
ctx.fillText('Previous word: ' + lastWord.toUpperCase(), x, y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function drawUsername(x, y, username) {
|
|
||||||
var usernameX = x + WIDTH / 2;
|
|
||||||
var usernameY = y - 60;
|
|
||||||
ctx.fillStyle = 'black';
|
|
||||||
ctx.fillText(username, usernameX, usernameY);
|
|
||||||
}
|
|
||||||
|
|
||||||
function drawScore(x, y, score) {
|
|
||||||
var scoreX = x + WIDTH / 2;
|
|
||||||
var scoreY = y - 25;
|
|
||||||
ctx.fillStyle = 'black';
|
|
||||||
ctx.fillText(score, scoreX, scoreY);
|
|
||||||
}
|
|
||||||
|
|
||||||
function drawGrid(xOrigin, yOrigin) {
|
|
||||||
ctx.beginPath();
|
|
||||||
for (var x = 0; x <= WIDTH; x += SIDE) {
|
|
||||||
ctx.moveTo(xOrigin + x, yOrigin);
|
|
||||||
ctx.lineTo(xOrigin + x, yOrigin + HEIGHT);
|
|
||||||
}
|
|
||||||
for (var y = 0; y <= HEIGHT; y += SIDE) {
|
|
||||||
ctx.moveTo(xOrigin, yOrigin + y);
|
|
||||||
ctx.lineTo(xOrigin + WIDTH, yOrigin + y);
|
|
||||||
}
|
|
||||||
ctx.strokeStyle = 'black';
|
|
||||||
ctx.stroke();
|
|
||||||
}
|
|
||||||
|
|
||||||
function drawInput(xOrigin, yOrigin, input) {
|
|
||||||
ctx.fillStyle = 'green';
|
|
||||||
var x = xOrigin + SIDE * 0.5;
|
|
||||||
var y = yOrigin + SIDE * 0.5;
|
|
||||||
for (var i = 0; i < myGuess.length; i++) {
|
|
||||||
ctx.fillText(myGuess[i], x, y);
|
|
||||||
x += SIDE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function drawGuesses(xOrigin, yOrigin, guesses, results) {
|
|
||||||
var y = yOrigin + SIDE * 1.5;
|
|
||||||
var numGuesses = Math.min(4, guesses.length);
|
|
||||||
for (var i = 0; i < numGuesses; i++) {
|
|
||||||
var x = xOrigin + SIDE * 0.5;
|
|
||||||
var guess = guesses[guesses.length - numGuesses + i];
|
|
||||||
var result = results[results.length - numGuesses + i];
|
|
||||||
for (var j = 0; j < 5; j++) {
|
|
||||||
if (result[j] === 1) {
|
|
||||||
ctx.fillStyle = 'yellow';
|
|
||||||
ctx.fillRect(x - SIDE * 0.5, y - SIDE * 0.5, SIDE, SIDE);
|
|
||||||
} else if (result[j] === 2) {
|
|
||||||
ctx.fillStyle = 'orange';
|
|
||||||
ctx.fillRect(x - SIDE * 0.5, y - SIDE * 0.5, SIDE, SIDE);
|
|
||||||
}
|
|
||||||
ctx.fillStyle = 'green';
|
|
||||||
ctx.fillText(guess[j], x, y);
|
|
||||||
x += SIDE;
|
|
||||||
}
|
|
||||||
y += SIDE;
|
|
||||||
}
|
|
||||||
return y;
|
|
||||||
}
|
|
||||||
|
|
||||||
function drawResults(xOrigin, yOrigin, results) {
|
|
||||||
var y = yOrigin + SIDE * 1.5;
|
|
||||||
var numResults = Math.min(4, results.length);
|
|
||||||
for (var i = 0; i < numResults; i++) {
|
|
||||||
var x = xOrigin + SIDE * 0.5;
|
|
||||||
var result = results[results.length - numResults + i];
|
|
||||||
for (var j = 0; j < 5; j++) {
|
|
||||||
if (result[j] === 1) {
|
|
||||||
ctx.fillStyle = 'yellow';
|
|
||||||
ctx.fillRect(x - SIDE * 0.5, y - SIDE * 0.5, SIDE, SIDE);
|
|
||||||
} else if (result[j] === 2) {
|
|
||||||
ctx.fillStyle = 'orange';
|
|
||||||
ctx.fillRect(x - SIDE * 0.5, y - SIDE * 0.5, SIDE, SIDE);
|
|
||||||
}
|
|
||||||
x += SIDE;
|
|
||||||
}
|
|
||||||
y += SIDE;
|
|
||||||
}
|
|
||||||
return y;
|
|
||||||
}
|
|
||||||
|
|
||||||
function drawHint(xOrigin, yOrigin, progress) {
|
|
||||||
var x = xOrigin + SIDE * 0.5;
|
|
||||||
for (var i = 0; i < 5; i++) {
|
|
||||||
ctx.fillText(progress[i], x, yOrigin);
|
|
||||||
x += SIDE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function isCharacter(charCode) {
|
function isCharacter(charCode) {
|
||||||
return isCharacterLowercase(charCode) || isCharacterUppercase(charCode);
|
return isCharacterLowercase(charCode) || isCharacterUppercase(charCode);
|
||||||
}
|
}
|
||||||
@ -395,64 +390,13 @@ function isValidResult(result) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeGame(gameId) {
|
|
||||||
var indexToRemove = null;
|
|
||||||
for (var i = 0; i < vm.games.length; i++) {
|
|
||||||
if (vm.games[i].id === gameId) {
|
|
||||||
indexToRemove = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
vm.games.splice(indexToRemove, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
function repaint() {
|
|
||||||
// clear the canvas
|
|
||||||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
||||||
|
|
||||||
// draw the components
|
|
||||||
drawMyBoard();
|
|
||||||
drawOpponentBoard();
|
|
||||||
drawLastWord();
|
|
||||||
}
|
|
||||||
|
|
||||||
function reset(firstLetter, clearScore) {
|
|
||||||
if (!firstLetter) {
|
|
||||||
firstLetter = '';
|
|
||||||
}
|
|
||||||
myGuess = '';
|
|
||||||
myGuesses = [];
|
|
||||||
myProgress = [firstLetter, '', '', '', ''];
|
|
||||||
myResults = [];
|
|
||||||
opponentResults = [];
|
|
||||||
if (clearScore) {
|
|
||||||
myScore = 0;
|
|
||||||
opponentScore = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggleView() {
|
|
||||||
var lobbyColumn = document.getElementById('lobbyColumn');
|
|
||||||
var gameColumn = document.getElementById('gameColumn')
|
|
||||||
if (lobbyColumn.classList.contains('primary')) {
|
|
||||||
lobbyColumn.classList.remove('primary');
|
|
||||||
} else {
|
|
||||||
lobbyColumn.classList.add('primary');
|
|
||||||
}
|
|
||||||
if (gameColumn.classList.contains('primary')) {
|
|
||||||
gameColumn.classList.remove('primary');
|
|
||||||
} else {
|
|
||||||
gameColumn.classList.add('primary');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function onChat(message) {
|
function onChat(message) {
|
||||||
var chatMessage = JSON.parse(message.body);
|
var chatMessage = JSON.parse(message.body);
|
||||||
var messageSender = chatMessage.username;
|
var messageSender = chatMessage.username;
|
||||||
var messageBody = chatMessage.message;
|
var messageBody = chatMessage.message;
|
||||||
if (messageSender === null) {
|
if (messageSender === null) {
|
||||||
addChatAnnouncement(messageBody);
|
addChatAnnouncement(messageBody);
|
||||||
} else if (messageSender === myUsername) {
|
} else if (messageSender === vm.username) {
|
||||||
// Ignore messages sent by yourself
|
// Ignore messages sent by yourself
|
||||||
} else {
|
} else {
|
||||||
console.log('Message from ' + messageSender + ": " + messageBody);
|
console.log('Message from ' + messageSender + ": " + messageBody);
|
||||||
@ -464,22 +408,26 @@ function onGameClosed(message) {
|
|||||||
var game = JSON.parse(message.body);
|
var game = JSON.parse(message.body);
|
||||||
var gameId = game.id;
|
var gameId = game.id;
|
||||||
var playerOne = game.playerOne.username;
|
var playerOne = game.playerOne.username;
|
||||||
if (playerOne === myUsername) {
|
console.log(playerOne + ' closed Game ' + gameId);
|
||||||
|
if (playerOne === vm.username) {
|
||||||
vm.gameId = null;
|
vm.gameId = null;
|
||||||
}
|
}
|
||||||
console.log(playerOne + ' closed Game ' + gameId);
|
vm.removeGame(gameId);
|
||||||
removeGame(gameId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function onGameHosted(message) {
|
function onGameHosted(message) {
|
||||||
var game = JSON.parse(message.body);
|
var game = JSON.parse(message.body);
|
||||||
var gameId = game.id;
|
var gameId = game.id;
|
||||||
var playerOne = game.playerOne.username;
|
var playerOne = game.playerOne.username;
|
||||||
if (playerOne === myUsername) {
|
console.log(playerOne + ' hosted Game ' + gameId);
|
||||||
|
vm.games.push({
|
||||||
|
id: gameId,
|
||||||
|
playerOne: playerOne,
|
||||||
|
started: false
|
||||||
|
});
|
||||||
|
if (playerOne === vm.username) {
|
||||||
vm.gameId = gameId;
|
vm.gameId = gameId;
|
||||||
}
|
}
|
||||||
console.log(playerOne + ' hosted Game ' + gameId);
|
|
||||||
vm.games.push({ id: gameId, playerOne: playerOne, started: false });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function onGameJoined(message) {
|
function onGameJoined(message) {
|
||||||
@ -487,9 +435,6 @@ function onGameJoined(message) {
|
|||||||
var gameId = game.id;
|
var gameId = game.id;
|
||||||
var playerOne = game.playerOne.username;
|
var playerOne = game.playerOne.username;
|
||||||
var playerTwo = game.playerTwo.username;
|
var playerTwo = game.playerTwo.username;
|
||||||
if (playerTwo === myUsername) {
|
|
||||||
vm.gameId = gameId;
|
|
||||||
}
|
|
||||||
console.log(playerTwo + ' joined ' + playerOne + "'s game");
|
console.log(playerTwo + ' joined ' + playerOne + "'s game");
|
||||||
for (var i = 0; i < vm.games.length; i++) {
|
for (var i = 0; i < vm.games.length; i++) {
|
||||||
if (vm.games[i].id === gameId) {
|
if (vm.games[i].id === gameId) {
|
||||||
@ -498,8 +443,8 @@ function onGameJoined(message) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (playerOne === myUsername || playerTwo === myUsername) {
|
if (playerTwo === vm.username) {
|
||||||
toggleView();
|
vm.gameId = gameId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -509,6 +454,7 @@ function onGameLeft(message) {
|
|||||||
var gameId = game.id;
|
var gameId = game.id;
|
||||||
var playerOne = game.playerOne.username;
|
var playerOne = game.playerOne.username;
|
||||||
var gameLeaver = report.gameLeaver.username;
|
var gameLeaver = report.gameLeaver.username;
|
||||||
|
console.log(gameLeaver + ' left ' + playerOne + "'s game");
|
||||||
var previousPlayers = [];
|
var previousPlayers = [];
|
||||||
for (var i = 0; i < vm.games.length; i++) {
|
for (var i = 0; i < vm.games.length; i++) {
|
||||||
if (vm.games[i].id === gameId) {
|
if (vm.games[i].id === gameId) {
|
||||||
@ -520,13 +466,11 @@ function onGameLeft(message) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
console.log(gameLeaver + ' left ' + playerOne + "'s game");
|
if (gameLeaver === vm.username) {
|
||||||
if (gameLeaver === myUsername) {
|
|
||||||
vm.gameId = null;
|
vm.gameId = null;
|
||||||
}
|
}
|
||||||
if (previousPlayers.indexOf(myUsername) != -1) {
|
if (previousPlayers.indexOf(vm.username) != -1) {
|
||||||
onOpponentLeft();
|
onOpponentLeft();
|
||||||
toggleView();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -534,9 +478,9 @@ function onGameStarted(message) {
|
|||||||
var report = JSON.parse(message.body);
|
var report = JSON.parse(message.body);
|
||||||
var playerOne = report[0];
|
var playerOne = report[0];
|
||||||
var playerTwo = report[1];
|
var playerTwo = report[1];
|
||||||
if (playerOne === myUsername) {
|
if (playerOne === vm.username) {
|
||||||
addChatAnnouncement('You are playing with ' + playerTwo);
|
addChatAnnouncement('You are playing with ' + playerTwo);
|
||||||
} else if (playerTwo === myUsername) {
|
} else if (playerTwo === vm.username) {
|
||||||
addChatAnnouncement('You are playing with ' + playerOne);
|
addChatAnnouncement('You are playing with ' + playerOne);
|
||||||
} else {
|
} else {
|
||||||
addChatAnnouncement(playerOne + ' is playing with ' + playerTwo);
|
addChatAnnouncement(playerOne + ' is playing with ' + playerTwo);
|
||||||
@ -546,18 +490,16 @@ function onGameStarted(message) {
|
|||||||
function onOpponentJoined(message) {
|
function onOpponentJoined(message) {
|
||||||
var report = JSON.parse(message.body);
|
var report = JSON.parse(message.body);
|
||||||
var firstLetter = report[0];
|
var firstLetter = report[0];
|
||||||
opponentUsername = report[1];
|
vm.opponentUsername = report[1];
|
||||||
console.log('Opponent username: ' + opponentUsername);
|
console.log('Opponent username: ' + vm.opponentUsername);
|
||||||
reset(firstLetter, true);
|
vm.reset(firstLetter, true);
|
||||||
canvasDiv.classList.remove('hidden');
|
vm.repaint();
|
||||||
repaint();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function onOpponentLeft(message) {
|
function onOpponentLeft(message) {
|
||||||
opponentUsername = null;
|
vm.opponentUsername = null;
|
||||||
lastWord = null;
|
vm.lastWord = null;
|
||||||
canvasDiv.classList.add('hidden');
|
vm.repaint();
|
||||||
repaint();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function onOpponentReport(message) {
|
function onOpponentReport(message) {
|
||||||
@ -566,15 +508,15 @@ function onOpponentReport(message) {
|
|||||||
var guess = report.guess;
|
var guess = report.guess;
|
||||||
var firstLetter = report.firstLetter;
|
var firstLetter = report.firstLetter;
|
||||||
console.log('Opponent guessed correctly! ' + guess);
|
console.log('Opponent guessed correctly! ' + guess);
|
||||||
opponentScore = opponentScore + 100;
|
vm.opponentScore = vm.opponentScore + 100;
|
||||||
lastWord = guess;
|
vm.lastWord = guess;
|
||||||
reset(firstLetter, false);
|
vm.reset(firstLetter, false);
|
||||||
repaint();
|
vm.repaint();
|
||||||
} else {
|
} else {
|
||||||
var result = report.result;
|
var result = report.result;
|
||||||
console.log('Opponent result: ' + result);
|
console.log('Opponent result: ' + result);
|
||||||
opponentResults.push(result);
|
vm.opponentResults.push(result);
|
||||||
repaint();
|
vm.repaint();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -585,27 +527,27 @@ function onPlayerReport(message) {
|
|||||||
var guess = report.guess;
|
var guess = report.guess;
|
||||||
var firstLetter = report.firstLetter;
|
var firstLetter = report.firstLetter;
|
||||||
console.log('I guessed correctly!');
|
console.log('I guessed correctly!');
|
||||||
myScore = myScore + 100;
|
vm.myScore = vm.myScore + 100;
|
||||||
lastWord = guess;
|
vm.lastWord = guess;
|
||||||
reset(firstLetter, false);
|
vm.reset(firstLetter, false);
|
||||||
repaint();
|
vm.repaint();
|
||||||
} else {
|
} else {
|
||||||
var guess = report.guess;
|
var guess = report.guess;
|
||||||
var result = report.result;
|
var result = report.result;
|
||||||
console.log('My result: ' + result);
|
console.log('My result: ' + result);
|
||||||
// TODO: use isValidResult function
|
// TODO: use isValidResult function
|
||||||
if (result[0] === 9) {
|
if (result[0] === 9) {
|
||||||
myGuesses.push('-----');
|
vm.myGuesses.push('-----');
|
||||||
} else {
|
} else {
|
||||||
for (var i = 0; i < 5; i++) {
|
for (var i = 0; i < 5; i++) {
|
||||||
if (result[i] === 2) {
|
if (result[i] === 2) {
|
||||||
myProgress[i] = guess[i];
|
vm.myProgress[i] = guess[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
myGuesses.push(guess);
|
vm.myGuesses.push(guess);
|
||||||
}
|
}
|
||||||
myResults.push(result);
|
vm.myResults.push(result);
|
||||||
repaint();
|
vm.repaint();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -613,7 +555,7 @@ function onUserJoined(message) {
|
|||||||
var report = JSON.parse(message.body);
|
var report = JSON.parse(message.body);
|
||||||
var username = report[0];
|
var username = report[0];
|
||||||
var numUsers = report[1];
|
var numUsers = report[1];
|
||||||
if (username === myUsername) {
|
if (username === vm.username) {
|
||||||
addChatAnnouncement('Welcome to Lingo!');
|
addChatAnnouncement('Welcome to Lingo!');
|
||||||
if (numUsers === 1) {
|
if (numUsers === 1) {
|
||||||
addChatAnnouncement('You are the only player online');
|
addChatAnnouncement('You are the only player online');
|
||||||
|
@ -8,19 +8,19 @@
|
|||||||
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.1.10/vue.js"></script>
|
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.1.10/vue.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div>
|
<div id="vue-app" v-cloak>
|
||||||
<div class="main column">
|
<div class="main column">
|
||||||
<div class="header row">Lingo</div>
|
<div class="header row">Lingo</div>
|
||||||
<div class="body row nofooter">
|
<div class="body row nofooter">
|
||||||
<div id="usernameDiv" class="form">
|
<div v-show="!username" class="form">
|
||||||
<h2>What is your name?</h2>
|
<h2>What is your name?</h2>
|
||||||
<input id="nicknameInput" type="text" class="form-control" maxlength="16">
|
<input id="nicknameInput" type="text" class="form-control" maxlength="16" autofocus>
|
||||||
<p id="usernameError" class="error-message"></p>
|
<p class="error-message">{{ usernameError }}</p>
|
||||||
</div>
|
</div>
|
||||||
<div id="appDiv" class="hidden">
|
<div v-show="username">
|
||||||
<div id="lobbyColumn" class="lobby column primary">
|
<div v-bind:class="{ primary: !inStartedGame }" class="lobby column">
|
||||||
<div id="vue-app" class="body row noheader nofooter scroll-y">
|
<div class="body row noheader nofooter scroll-y">
|
||||||
<div class="panel panel-default">
|
<div class="panel">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
<h3 class="panel-title">Games</h3>
|
<h3 class="panel-title">Games</h3>
|
||||||
</div>
|
</div>
|
||||||
@ -40,9 +40,9 @@
|
|||||||
<button v-show="!inGame" @click="hostGame" type="button" class="create button">Create game</button>
|
<button v-show="!inGame" @click="hostGame" type="button" class="create button">Create game</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="gameColumn" class="game column">
|
<div v-bind:class="{ primary: inStartedGame }" class="game column">
|
||||||
<div class="body row noheader nofooter">
|
<div class="body row noheader nofooter">
|
||||||
<div id="canvasDiv" class="hidden">
|
<div v-show="inStartedGame" @keydown="onCanvasKeydown" @keypress="onCanvasKeypress">
|
||||||
<canvas id="canvas" class="centered" width="600" height="475" tabindex="1"></canvas>
|
<canvas id="canvas" class="centered" width="600" height="475" tabindex="1"></canvas>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -52,9 +52,18 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="chat column">
|
<div class="chat column">
|
||||||
<div class="header row">Chat</div>
|
<div class="header row">Chat</div>
|
||||||
<div id="messageList" class="body row scroll-y"></div>
|
<div id="messageList" class="body row scroll-y">
|
||||||
|
<template v-for="message in messages">
|
||||||
|
<div v-if="message.sender" class="message-item">
|
||||||
|
<strong>{{ message.sender }}</strong> {{ message.body }}
|
||||||
|
</div>
|
||||||
|
<div v-else class="log message-item">
|
||||||
|
{{ message.body }}
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
<div class="footer row">
|
<div class="footer row">
|
||||||
<textarea id="messageInput" placeholder="Send a message" tabindex="2"></textarea>
|
<textarea @keypress="onChatKeypress" placeholder="Send a message" tabindex="2"></textarea>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -9,6 +9,10 @@
|
|||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[v-cloak] {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
font-family: sans-serif;
|
font-family: sans-serif;
|
||||||
background: linen;
|
background: linen;
|
||||||
@ -46,15 +50,15 @@ button:hover:disabled {
|
|||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
}
|
}
|
||||||
|
|
||||||
.message-item.first {
|
.message-item:first-child {
|
||||||
border: none;
|
border-top: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.log {
|
.log {
|
||||||
color: green;
|
color: green;
|
||||||
}
|
}
|
||||||
|
|
||||||
#messageInput {
|
.chat.column textarea {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
@ -66,15 +70,15 @@ button:hover:disabled {
|
|||||||
resize: none;
|
resize: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
#messageInput::-webkit-input-placeholder {
|
.chat.column textarea::-webkit-input-placeholder {
|
||||||
color: steelblue;
|
color: steelblue;
|
||||||
}
|
}
|
||||||
|
|
||||||
#messageInput::-moz-placeholder {
|
.chat.column textarea::-moz-placeholder {
|
||||||
color: steelblue;
|
color: steelblue;
|
||||||
}
|
}
|
||||||
|
|
||||||
#messageInput:-ms-input-placeholder {
|
.chat.column textarea:-ms-input-placeholder {
|
||||||
color: steelblue;
|
color: steelblue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,10 +108,6 @@ button:hover:disabled {
|
|||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.panel-heading+.list-group .list-group-item:first-item {
|
|
||||||
border-top-width: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.panel>.list-group .list-group-item {
|
.panel>.list-group .list-group-item {
|
||||||
font-size: 1em;
|
font-size: 1em;
|
||||||
border-width: 1px 0;
|
border-width: 1px 0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user