diff --git a/client/src/App.js b/client/src/App.js index 57e3214..4c1507c 100644 --- a/client/src/App.js +++ b/client/src/App.js @@ -4,9 +4,9 @@ import {io} from 'socket.io-client'; import {DrawingApp, Layer} from './DrawingApp'; -const socket = io(); +const socket = io('http://localhost:7777'); -var id = ""; +var id = ''; var drawing_app = null; var game_info = document.getElementById('game_state_info'); @@ -17,14 +17,14 @@ function setGameInfo(info) { } socket.on('connect', () => { - console.log("\n*** CONNECTED TO SOCKET *** ", socket.id); + console.log('\n*** CONNECTED TO SOCKET *** ', socket.id); id = socket.id; - console.log("\n*** Startup! ***"); + console.log('\n*** Startup! ***'); }); -document.getElementById('join_room_btn').addEventListener("click", (e) => { +document.getElementById('join_room_btn').addEventListener('click', (e) => { var room_code = document.getElementById('room_code').value; var username = document.getElementById('username').value; @@ -36,18 +36,21 @@ socket.on('room', (room_id) => { console.log(room_id); document.getElementById('game_room_code').innerHTML = room_id; - document.getElementById('game_setup').style.display = "none"; - document.getElementById('game_info').style.display = "initial"; + document.getElementById('game_setup').style.display = 'none'; + document.getElementById('game_info').style.display = 'initial'; + + document.getElementById('copy_image').style.display = 'none'; + document.getElementById('download_image').style.display = 'none'; }); socket.on('room_error', (error_msg) => { alert(error_msg); }); -document.getElementById('create_room_btn').addEventListener("click", (e) => { +document.getElementById('create_room_btn').addEventListener('click', (e) => { // Tell the server we want a new room var username = document.getElementById('username').value; - socket.emit("create_room", username); + socket.emit('create_room', username); }); socket.on('player_data', (player_arr) => { @@ -56,13 +59,13 @@ socket.on('player_data', (player_arr) => { var player_list = document.getElementById('player_list'); - player_list.innerHTML = ""; - + player_list.innerHTML = ''; + player_arr.forEach((player) => { - player_list.innerHTML += "
  • " + player.player_name + "
  • "; + player_list.innerHTML += '
  • ' + player.player_name + '
  • '; }) - document.getElementById('start_game_btn').disabled = (count < 5); + document.getElementById('start_game_btn').disabled = (count < 2); }); document.getElementById('start_game_btn').addEventListener('click', (e) => { @@ -70,54 +73,129 @@ document.getElementById('start_game_btn').addEventListener('click', (e) => { }); socket.on('game_started', () => { - // game_data.game_leader = - console.log("yooo"); - document.getElementById('pre_game_player_list').style.display = "none"; + // game_data.game_leader = + console.log('yooo'); + document.getElementById('pre_game_player_list').style.display = 'none'; }); socket.on('leader_selected', (leader) => { console.log(leader); console.log(id); - setGameInfo(`Please wait while the leader ${leader.player_name} is selecting a topic to be painted`); - if(leader.id == id) { - setGameInfo("You are the game leader! Please choose a topic and a category that the topic fits in."); - document.getElementById('game_leader_input').style.display = "initial"; + setGameInfo(`Please wait while the leader ${ + leader.player_name} is selecting a hint to be painted`); + if (leader.id == id) { + setGameInfo( + 'You are the game leader! Please choose a hint and a category that the hint fits in.'); + document.getElementById('game_leader_input').style.display = 'initial'; - document.getElementById('submit_topic').addEventListener('click', (e) => { - var topic = document.getElementById('game_topic').value; - var category = document.getElementById('game_category').value; + const game_hint = document.getElementById('game_hint'); + const game_topic = document.getElementById('game_topic'); + const submit_topic_btn = document.getElementById('submit_topic'); - socket.emit('topic_selected', topic, category); + function updateSubmitButtonState() { + submit_topic_btn.disabled = + game_hint.value.length < 2 || game_topic.value.length < 2; + } + + game_hint.addEventListener('input', (e) => { + updateSubmitButtonState(); + }); + + game_topic.addEventListener('input', (e) => { + updateSubmitButtonState(); + }); + + + submit_topic_btn.addEventListener('click', (e) => { + socket.emit('topic_selected', game_topic.value, game_hint.value); }) } }); -socket.on('topic_selected', (topic, category) => { - console.log(topic, category); - document.getElementById('game_leader_input').style.display = "none"; - setGameInfo(`Topic: ${topic}
    Category: ${category}`); +socket.on('topic_selected', (topic, hint) => { + console.log(topic, hint); + document.getElementById('game_leader_input').style.display = 'none'; + setGameInfo(`Hint: ${hint}
    Topic: ${topic}`); }); socket.on('game_finished', (leader, player_list) => { - var pl = document.getElementById("endgame_player_list"); - - pl.innerHTML = ""; - + var pl = document.getElementById('endgame_player_list'); + + pl.innerHTML = ''; + player_list.forEach((player) => { if (player.id == leader.id) { - pl.innerHTML += `
  • ${player.player_name} (Leader)
  • `; - } - else { - pl.innerHTML += `
  • ${player.player_name}
  • `; + pl.innerHTML += `
  • ${ + player.player_name} (Leader)
  • `; + } else { + pl.innerHTML += `
  • ${ + player.player_name}
  • `; } }) - pl.style.display = "initial"; + pl.style.display = 'initial'; var ink_bar = document.getElementById('myBar'); - ink_bar.style.display = "none"; + ink_bar.style.display = 'none'; - document.getElementById('current_user_text').style.display = "none"; + document.getElementById('current_user_text').style.display = 'none'; + + document.getElementById('copy_image').style.display = 'initial'; + document.getElementById('download_image').style.display = 'initial'; + + + document.getElementById('download_image').addEventListener('click', (e) => { + const base64_image = drawing_app.app.renderer.extract.base64( + drawing_app.app.stage, 'image/png', 1); + + base64_image.then((str) => { + console.log(str); + const linkSource = str; + const downloadLink = document.createElement('a'); + downloadLink.href = linkSource; + downloadLink.download = 'image.png'; + downloadLink.click(); + downloadLink.remove(); + }); + }); + + document.getElementById('copy_image').addEventListener('click', (e) => { + const base64_image = drawing_app.app.renderer.extract.base64( + drawing_app.app.stage, 'image/png', 1); + + + + function b64toBlob(b64Data, contentType = null, sliceSize = null) { + contentType = contentType || 'image/png' + sliceSize = sliceSize || 512 + let byteCharacters = atob(b64Data); + let byteArrays = []; + for (let offset = 0; offset < byteCharacters.length; + offset += sliceSize) { + let slice = byteCharacters.slice(offset, offset + sliceSize) + let byteNumbers = new Array(slice.length); + for (let i = 0; i < slice.length; i++) { + byteNumbers[i] = slice.charCodeAt(i) + } + var byteArray = new Uint8Array(byteNumbers) + byteArrays.push(byteArray) + } + return new Blob(byteArrays, {type: contentType}) + } + + + base64_image.then((str) => { + try { + navigator.clipboard.write([ + new ClipboardItem({ + 'image/png': b64toBlob(str) + }) + ]); + } catch (error) { + console.error(error); + } + }); + }); }); socket.on('actually_start_game', (player_data) => { @@ -127,7 +205,7 @@ socket.on('actually_start_game', (player_data) => { }); socket.on('draw_data', (round_num, data) => { - console.log("Draw Data: ", round_num); + console.log('Draw Data: ', round_num); var cur_layer = drawing_app.layers[round_num]; cur_layer.drawPointLine(data[0], data[1], true); @@ -135,33 +213,36 @@ socket.on('draw_data', (round_num, data) => { socket.on('advance_round', (round_num, current_player) => { var ink_bar = document.getElementById('myBar'); - ink_bar.style.width = "100%"; + ink_bar.style.width = '100%'; - var current_user_text = `It's ${current_player.player_name}'s turn to draw!` + var current_user_text = + `It's ${ + current_player.player_name}'s turn to draw!` document.getElementById('current_user_text').innerHTML = current_user_text; - if(id == current_player.id) { + if (id == current_player.id) { ink_bar.style.backgroundColor = current_player.player_color; - ink_bar.style.visibility = "visible"; + ink_bar.style.visibility = 'visible'; const cur_layer = drawing_app.layers[round_num]; cur_layer.enable(); cur_layer.setLivePaintProgressCallback((old_pos, new_pos) => { - var ink_pct = cur_layer.getPaintPercentage(); + var ink_pct = cur_layer.getPaintPercentage(); - ink_bar.style.width = ((1.0 - ink_pct) * 100) + "%"; + ink_bar.style.width = ((1.0 - ink_pct) * 100) + '%'; console.log(ink_pct); - - socket.emit("draw_data", [old_pos, new_pos]); + + socket.emit('draw_data', [old_pos, new_pos]); }); cur_layer.setFinishedPaintingCallback(() => { cur_layer.disable(); - socket.emit("round_finished"); + socket.emit('round_finished'); }); /*player_data.forEach((p) => { @@ -172,9 +253,8 @@ socket.on('advance_round', (round_num, current_player) => { // yeah... } });*/ - } - else { - ink_bar.style.visibility = "hidden"; + } else { + ink_bar.style.visibility = 'hidden'; } // TODO: Set current drawing layer, activate if WE are drawing @@ -212,4 +292,3 @@ socket.on('advance_round', (round_num, current_player) => { })*/ // Test - diff --git a/client/src/DrawingApp.js b/client/src/DrawingApp.js index 628374c..05c04c9 100644 --- a/client/src/DrawingApp.js +++ b/client/src/DrawingApp.js @@ -8,7 +8,7 @@ const max_ink_per_layer = 1000; const layer_width = 512; const layer_height = 512; -const brush_size = 16; +const brush_size = 8; const brush_smoothing = 0.01; export class Layer { @@ -182,9 +182,16 @@ export class DrawingApp { this.layers = []; + const base_render_texture = PIXI.RenderTexture.create({width: 512, height: 512}); + + + /*this.layers.push(new Layer( + this.app, base_render_texture, this.brushGenerator, "-1", + "0xFFFFFF"));*/ + for (var i = 0; i < player_data.length * 2; i++) { const render_texture = - PIXI.RenderTexture.create({width: 1024, height: 1024}); + PIXI.RenderTexture.create({width: 512, height: 512}); var cur_player = player_data[i % player_data.length]; this.layers.push(new Layer( this.app, render_texture, this.brushGenerator, cur_player.id, diff --git a/client/src/index.html b/client/src/index.html index 4eabc42..df7202d 100644 --- a/client/src/index.html +++ b/client/src/index.html @@ -93,6 +93,10 @@ label { color: white; } + + #copy_image {} + + #download_image {} @@ -133,12 +137,12 @@
    - +
    @@ -156,6 +160,10 @@
    +
    + + +
    diff --git a/client/src/server/server.js b/client/src/server/server.js index 25d0848..4a78e06 100644 --- a/client/src/server/server.js +++ b/client/src/server/server.js @@ -57,7 +57,7 @@ const GAME_STATE = { class Game { room_id = ''; topic = ''; - category = ''; + hint = ''; players = []; // Player Class actual_players = []; current_game_state = 0; @@ -178,6 +178,11 @@ io.on('connection', (socket) => { var room_id = socket.room; var game = active_games[room_id]; + if(game.game_state == GAME_STATE.TOPIC_SELECTION) { + // TODO: Check what happens after replay + return; + } + game.game_state = GAME_STATE.TOPIC_SELECTION; io.to(room_id).emit('game_started'); @@ -202,24 +207,37 @@ io.on('connection', (socket) => { } }); - socket.on('topic_selected', (topic, category) => { - console.log(topic, category); + socket.on('topic_selected', (topic, hint) => { + console.log(topic, hint); if (socket.room) { var room_id = socket.room; var game = active_games[room_id]; + if(game.game_state != GAME_STATE.TOPIC_SELECTION) { + return; + } + + if(socket.id != game.leader.id) { + // Ignore other people trying to set a topic + return; + } + + if(topic.length < 2 || hint.length < 2) { + return; + } + game.topic = topic; - game.category = category; + game.hint = hint; game.players.forEach((player) => { console.log(player.id); if (player.id != game.fake_artist.id) { console.log('OK'); - io.to(player.id).emit('topic_selected', topic, category); + io.to(player.id).emit('topic_selected', topic, hint); } else { console.log('FAKE'); - io.to(player.id).emit('topic_selected', '???', category); + io.to(player.id).emit('topic_selected', '', hint); } }); @@ -251,7 +269,7 @@ io.on('connection', (socket) => { if (game.current_round >= game.player_turns.length) { game.game_state = GAME_STATE.VOTING; console.log('GAME FINISHED!'); - io.to(game.room_id).emit('game_finished', game.leader, game.players); + io.to(game.room_id).emit('game_finished', game.leader, game.player_turns.slice(0, [Math.ceil(game.player_turns.length / 2)])); game.game_state = GAME_STATE.VOTING; // TODO: Pass fake artist after voting... implement voting in the first // place