From 16e7453cf70b1b01707e70a54b0abff44279b34d Mon Sep 17 00:00:00 2001 From: Jonas Weinz Date: Thu, 28 Mar 2019 15:43:37 +0100 Subject: [PATCH 1/3] changed .gitignore --- .gitignore | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 6d3fb34..e49e4ad 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,6 @@ # ---> VisualStudioCode .settings - - +push_to_beta.sh +push_to_prod.sh +settings_beta.js +settings_prod.js From 87cf4ead9629273fcca3d4066e62416ad809acd9 Mon Sep 17 00:00:00 2001 From: Jonas Weinz Date: Thu, 28 Mar 2019 15:50:22 +0100 Subject: [PATCH 2/3] changed .gitignore --- .gitignore | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index e49e4ad..0c875e3 100644 --- a/.gitignore +++ b/.gitignore @@ -2,5 +2,5 @@ .settings push_to_beta.sh push_to_prod.sh -settings_beta.js -settings_prod.js +settings_beta +settings_prod From 25c42dd569310dc93a0570a610e220bc71745c35 Mon Sep 17 00:00:00 2001 From: Jonas Weinz Date: Fri, 29 Mar 2019 12:47:49 +0100 Subject: [PATCH 3/3] rate my elo system --- infobar.js | 8 ++-- infocontainer.js | 45 +++++++++++++++++-- local_match_manager.js | 17 +++++--- main.js | 65 ++++++++++++++++++---------- online_match_manager.js | 95 ++++++++++++++++++++++++++++++++++++----- player.js | 5 +++ settings.js | 5 ++- style.css | 59 +++++++++++++++++++------ websocket_connection.js | 89 ++++++++++++++++++++++++-------------- 9 files changed, 297 insertions(+), 91 deletions(-) diff --git a/infobar.js b/infobar.js index 1c6c2ce..33f3d21 100644 --- a/infobar.js +++ b/infobar.js @@ -1,15 +1,15 @@ class Infobar { - constructor(parent) + constructor(parent, css_class) { this.parent = parent; this.container = document.createElement("div"); - this.container.className = "infobar-container"; + this.container.className = css_class; this.parent.appendChild(this.container); } - create_infocontainer() + create_infocontainer(head_text = null) { - return new Infocontainer(this.container); + return new Infocontainer(this.container, head_text); } } \ No newline at end of file diff --git a/infocontainer.js b/infocontainer.js index 748abc1..12653ac 100644 --- a/infocontainer.js +++ b/infocontainer.js @@ -1,18 +1,56 @@ class Infocontainer { - constructor(parent) + constructor(parent, heading_text=null) { this.parent = parent; this.container = document.createElement("div"); this.container.className = "info-container"; this.parent.appendChild(this.container); + this.head_elem = null; + this.timeout_id = null; + + if (heading_text != null) + { + this.head_elem = document.createElement("label"); + this.head_elem.className = "infobar-head-label"; + this.head_elem.innerHTML = heading_text; + this.container.appendChild(this.head_elem); + } + + } + + update_head(text) + { + if (this.head_elem == null) + { + console.warn("cannot update head text"); + return; + } + this.head_elem.innerHTML = text; + } + + set_background_color(color) + { + this.container.style.backgroundColor = color; + } + + clear_background_color() + { + this.container.style.backgroundColor = null; + } + + blink(color, time = 500) + { + this.set_background_color(color); + this.timeout_id = setTimeout(c => this.clear_background_color(), time); + } create_button(text) { var b = document.createElement("button"); b.className = "infobar-button"; - b.appendChild(document.createTextNode(text)); + b.innerHTML = text; this.container.appendChild(b) return b; } @@ -51,9 +89,8 @@ class Infocontainer b1.style.width = "80%"; b2.style.width = "20%"; - - b1.appendChild(document.createTextNode(text)); + b1.innerHTML = "" + text + "" b2.appendChild(document.createTextNode(option)); div.appendChild(b1); diff --git a/local_match_manager.js b/local_match_manager.js index b4d2b81..ce585b5 100644 --- a/local_match_manager.js +++ b/local_match_manager.js @@ -8,6 +8,8 @@ class LocalMatchManager this.control_container = control_container; this.control_container.show(); + this.control_container.clear_background_color(); + this.control_container.update_head("local game"); this.local_player_a = new Player("red player", 255,0,0); this.local_player_b = new Player("green player", 0,255,0); @@ -25,15 +27,18 @@ class LocalMatchManager click_listener(sub_x, sub_y, x,y) { // check whether the game is over: - if (grid.is_won()) + if (this.grid.is_won()) { - this.status_label.innerHTML = "" + grid.get_won_player().get_name() + " has won."; - this.end_game(); + this.status_label.innerHTML = "" + this.grid.get_won_player().get_name() + " has won."; + this.control_container.update_head("" + this.grid.get_won_player().get_name() + " won"); + this.control_container.set_background_color(this.grid.get_won_player().get_color_with_alpha(0.4)); } - else if (grid.is_complete()) + else if (this.grid.is_complete()) { this.status_label.innerHTML = "Draw. Everybody looses!"; - this.end_game(false); + this.control_container.update_head("Draw"); + this.control_container.set_background_color(theme_color_highlight); + } else { @@ -56,6 +61,8 @@ class LocalMatchManager var next_player = this.is_local_player_a ? this.local_player_a : this.local_player_b; this.status_label.innerHTML = "" + "it's " + next_player.get_name() + "'s turn..."; + this.control_container.update_head("" + next_player.get_name() + "'s move"); + this.control_container.blink(theme_color_highlight); this.grid.player_change_listener(next_player); } diff --git a/main.js b/main.js index 9978035..0efebdd 100644 --- a/main.js +++ b/main.js @@ -6,9 +6,9 @@ var ground_color = style.getPropertyValue("--ground-color"); var main_container = document.getElementById("main-container"); -var main_menu = new Infobar(main_container); +var main_menu = new Infobar(main_container, "infobar-container"); var grid = new Grid(n, main_container, tilesize, tilesize, ground_color); -var sub_menu = new Infobar(main_container); +var sub_menu = new Infobar(main_container, "infobar-container"); // fill containers with buttons and containers: @@ -18,41 +18,37 @@ dummy_main = main_menu.create_infocontainer(); dummy_sub = sub_menu.create_infocontainer(); // start container: -create_game_container = main_menu.create_infocontainer(); -create_game_container.create_label("Start Local Game"); +create_game_container = main_menu.create_infocontainer("Start Local Game"); b_local_game = create_game_container.create_button("Local Game"); // register container: -register_container = main_menu.create_infocontainer(); -register_container.create_label("Login to play online"); +register_container = main_menu.create_infocontainer("Login to play online"); i_register_username = register_container.create_input("username"); i_register_pw = register_container.create_input("password", true); b_register = register_container.create_button("register/login"); //register_container.create_label("(creates new account for a new username)"); // logout: -logout_container = main_menu.create_infocontainer(); -l_username = logout_container.create_label("logged in as: "); +logout_container = main_menu.create_infocontainer("logged in as: "); b_logout = logout_container.create_button("logout"); // fill subcontainer: -match_slot_container = sub_menu.create_infocontainer(); -match_slot_container.create_label("Running Matches
(click to open)"); +match_slot_container = sub_menu.create_infocontainer("Running Matches
(click to open)"); -// local match control: -match_control = sub_menu.create_infocontainer(); +// match control: +match_control = sub_menu.create_infocontainer(" -- vs. --"); b_end_game = match_control.create_button("Close Match"); -// search match: -search_match_container = sub_menu.create_infocontainer(); -search_match_container.create_label("Create Online Match"); -b_match_search = search_match_container.create_button("random match"); +// search match: +search_match_container = sub_menu.create_infocontainer("Create Online Match"); +b_match_search = search_match_container.create_button("random match"); +search_match_container.create_label("invite player by name:"); l_match_op = search_match_container.create_input("player name"); b_match_invite = search_match_container.create_button("invite player"); @@ -61,9 +57,9 @@ search_match_container.create_label("Invite friends:") //status: -status_container = main_menu.create_infocontainer(); -l_status_head = status_container.create_label("Status:"); -l_status = status_container.create_label("select gamemode. click
[here] for the rules!"); +status_container = main_menu.create_infocontainer("Status"); +l_status = status_container.create_label(""); + // global vars: @@ -109,7 +105,27 @@ function check_cookie(cname) { return false; } +status_message = function(text, blink = true) +{ + l_status.innerHTML = text; + if (blink) + { + status_container.blink("rgba(126,87,194, 0.5)"); + } +} +status_error = function(text, blink=true) +{ + l_status.innerHTML = text; + if (blink) + { + status_container.blink("rgba(128,0,0,0.5"); + } +} + + + +status_message("select gamemode. click
[here] for the rules!"); // global funcs: @@ -172,6 +188,8 @@ start_local_game = function() status_container.show(); + b_end_game.innerHTML="Close Match"; + game_manager = new LocalMatchManager(grid, l_status, match_control, end_local_game); } @@ -188,7 +206,8 @@ login_callback = function() } end_local_game(); - l_username.innerHTML = "logged in as: " + connection.player.get_name(); + logout_container.update_head("logged in as: " + connection.player.get_name()); + //logout_container.blink("rgba(128,128,128,0.5)"); set_cookie("sessionid", connection.session_id, 30); @@ -227,7 +246,7 @@ reconnect = function() { connection.close(); } - connection = new WebsocketConnection(server_url, server_port, grid, l_status, match_slot_container, match_control, search_match_container, login_callback, on_connection_error); + connection = new WebsocketConnection(server_url, server_port, grid, status_message, status_error, match_slot_container, match_control, b_end_game, logout_container, search_match_container, login_callback, on_connection_error); connection.reconnect(session_id); } } @@ -244,7 +263,7 @@ login = function(){ { connection.close(); } - connection = new WebsocketConnection(server_url, server_port, grid, l_status, match_slot_container, match_control, search_match_container, login_callback, on_connection_error); + connection = new WebsocketConnection(server_url, server_port, grid, status_message, status_error, match_slot_container, match_control, b_end_game, logout_container, search_match_container, login_callback, on_connection_error); connection.connect(i_register_username.value.toLowerCase(), i_register_pw.value); } @@ -262,7 +281,7 @@ invite_player = function() { if (l_match_op.value == "") { - l_status.innerHTML = "choose your opponent first!"; + status_error("choose your opponent first!"); } else { diff --git a/online_match_manager.js b/online_match_manager.js index 768631b..4ac0d2f 100644 --- a/online_match_manager.js +++ b/online_match_manager.js @@ -1,12 +1,13 @@ class OnlineMatchManager { - constructor(grid, status_label, matches_container, control_container, game_server_connection, match_id, match_state, player_name) + constructor(grid, info_func, matches_container, control_container, end_button, game_server_connection, match_id, match_state, player_name) { this.grid = grid; - this.status_label = status_label; this.match_id = match_id; + this.info_func = info_func; + this.game_server_connection = game_server_connection; @@ -21,6 +22,7 @@ class OnlineMatchManager // create match button in match list: this.control_container = control_container; + this.end_button = end_button; this.matches_container = matches_container; var tmp = matches_container.create_double_button("" + this.online_opponent.get_name(), "+") @@ -62,7 +64,7 @@ class OnlineMatchManager this.game_server_connection.send_move(sub_x, sub_y, x, y, this.match_id); - this.status_label.innerHTML = "waiting for " + this.online_opponent.get_name() + "'s move"; + this.info_func("waiting for " + this.online_opponent.get_name() + "'s move", false); } on_user_close() @@ -80,7 +82,7 @@ class OnlineMatchManager this.matches_container.container.removeChild(this.match_button_div); this.match_button_div = null; } - this.status_label.innerHTML = "match is closed"; + this.info_func("match is closed"); this.control_container.hide(); this.is_closed = true; @@ -125,6 +127,55 @@ class OnlineMatchManager { this.match_button.className = "infobar-button-green" } + + this.control_container.clear_background_color(); + this.control_container.update_head(""); + } + + update_button_text() + { + + if (this.match_state.game_over) + { + this.end_button.innerHTML = "Close Match"; + return; + } + + var contains_move_of_a = false; + var contains_move_of_b = false; + var i; + for (i = 0; i < this.match_state.complete_field.length; i++) + { + if (this.match_state.complete_field[i].includes(1)) + { + contains_move_of_a = true; + } + if (this.match_state.complete_field[i].includes(2)) + { + contains_move_of_b = true; + } + } + + if (contains_move_of_a && contains_move_of_b) + { + this.end_button.innerHTML = "Abandon Match"; + return; + } + + if (this.match_state.player_a == this.player_name && !contains_move_of_a) + { + this.end_button.innerHTML = "Reject Invite"; + return; + } + + if (this.match_state.player_b == this.player_name && !contains_move_of_b) + { + this.end_button.innerHTML = "Reject Invite"; + return; + } + + this.end_button.innerHTML = "Close Match"; + } open_match() @@ -194,6 +245,11 @@ class OnlineMatchManager } } + var control_head = ""; + this.control_container.clear_background_color(); + + this.update_button_text(); + this.grid.block_all(); this.grid.register_click_callback((i,j,k,l) => this.click_listener(i,j,k,l)); @@ -201,24 +257,35 @@ class OnlineMatchManager { if (player_won == this.player_name) { - this.status_label.innerHTML = "Congratulation, you won!"; + this.info_func("Congratulation, you won!"); + control_head += "You won!" + this.control_container.set_background_color(this.local_player.get_color_with_alpha(0.4)); + } else { - this.status_label.innerHTML = "Game over, you lost!"; + status_mesage("Game over, you lost!"); + control_head += "You lost"; + this.control_container.set_background_color(this.online_opponent.get_color_with_alpha(0.4)); } + this.control_container.update_head(control_head); return; } else if(game_over) { if (this.grid.is_complete()) { - this.status_label.innerHTML = "Draw. Everyone looses!"; + this.info_func("Draw. Everyone looses!"); + control_head += "Draw"; + this.control_container.set_background_color(theme_color_highlight); } else { - this.status_label.innerHTML = "Game was closed by server or opponent"; + this.info_func("Game was closed by server or opponent"); + control_head += "Game Closed" + this.control_container.set_background_color(theme_color_highlight); } + this.control_container.update_head(control_head); return; } @@ -239,18 +306,26 @@ class OnlineMatchManager { this.grid.unblock(x,y); } - this.status_label.innerHTML = "It's your turn!"; + this.info_func("It's your turn!", false); + this.control_container.blink(theme_color_highlight); } else { + this.info_func("It's your turn!", false); + this.control_container.blink(theme_color_highlight); this.grid.unblock_all(); } } else { - this.status_label.innerHTML = "waiting for " + this.online_opponent.get_name() + "'s move"; + this.info_func("waiting for " + this.online_opponent.get_name() + "'s move", false); + this.control_container.blink(theme_color_highlight); } + control_head += "" + current_player_name + "'s move"; + + this.control_container.update_head(control_head); + } diff --git a/player.js b/player.js index 3560442..669eae4 100644 --- a/player.js +++ b/player.js @@ -37,6 +37,11 @@ class Player return "rgb(" + this.r + "," + this.g + "," + this.b + ")"; } + get_color_with_alpha(alpha) + { + return "rgba(" + this.r + "," + this.g + "," + this.b + "," + alpha + ")"; + } + get_color_values() { var col = { diff --git a/settings.js b/settings.js index 692cf89..7ada4cf 100644 --- a/settings.js +++ b/settings.js @@ -3,4 +3,7 @@ var server_url = "127.0.0.1"; var server_port = "5556"; var home = "https://the-cake-is-a-lie.net/website/ultimate_tictactoe/"; -var rel_home = "/website/ultimate_tictactoe"; \ No newline at end of file +var rel_home = "/website/ultimate_tictactoe"; + +var theme_color = "rgb(126,87,194)"; +var theme_color_highlight = "rgba(126,87,194, 0.5)"; \ No newline at end of file diff --git a/style.css b/style.css index 19fd1db..ad34779 100644 --- a/style.css +++ b/style.css @@ -2,6 +2,10 @@ html, body { overflow-x: hidden; } +input, body, button, textarea{ + font-family: 'Trebuchet MS', 'Lucida Sans Unicode', 'Lucida Grande', 'Lucida Sans', Arial, sans-serif; +} + body { margin: 0; background: rgb(49, 54, 74) ; @@ -9,6 +13,10 @@ body { position: relative; } +small { + font-size: x-small; +} + :root{ --tictactoe_n: 3; --button-margin: 0.5vh; @@ -156,14 +164,15 @@ a:visited { } .info-container { - border-radius: var(--border-radius); - padding: var(--border-radius); + border-radius: var(--button-margin); + padding: var(--button-margin); bottom: 0; display: inline-block; vertical-align: middle; text-align: center; - background: none; + background: rgba(0,0,0,0); white-space: normal; + transition-duration: 0.3s; overflow-y: auto; } @@ -186,6 +195,18 @@ a:visited { } +.infobar-head-label { + color: rgba(224, 217, 235, 0.8); + font-size: calc(2.5 * var(--border-radius)); + margin-left: 0; + margin-right: 0; + width: 100%; + display: flex; + flex-direction: column; + text-align: center; + +} + .option-button-container { border-radius: 0%; @@ -200,8 +221,9 @@ a:visited { .infobar-button { - border-radius: var(--border-radius); - margin: var(--border-radius); + border-radius: var(--button-margin); + margin: var(--button-margin); + padding-top: 1%; border: none; outline: 0; transition-duration: 0.3s; @@ -217,18 +239,21 @@ a:visited { vertical-align: middle; flex-direction: column; text-align: center; + overflow-x: auto; } @media (max-aspect-ratio: 1/1) { .infobar-button{ + padding-top: 2%; height: calc(0.18 * var(--sidebar-height)); } } .infobar-button-green { - border-radius: var(--border-radius); - margin: var(--border-radius); + border-radius: var(--button-margin); + margin: var(--button-margin); + padding-top: 1%; border: none; outline: 0; transition-duration: 0.3s; @@ -242,18 +267,21 @@ a:visited { display: flex; vertical-align: middle; flex-direction: column; + overflow-x: auto; } @media (max-aspect-ratio: 1/1) { .infobar-button-green{ + padding-top: 2%; height: calc(0.18 * var(--sidebar-height)); } } .infobar-button-red { - border-radius: var(--border-radius); - margin: var(--border-radius); + border-radius: var(--button-margin); + margin: var(--button-margin); + padding-top: 1%; border: none; outline: 0; transition-duration: 0.3s; @@ -267,18 +295,21 @@ a:visited { display: flex; vertical-align: middle; flex-direction: column; + overflow-x: auto; } @media (max-aspect-ratio: 1/1) { .infobar-button-red{ + padding-top: 2%; height: calc(0.18 * var(--sidebar-height)); } } .infobar-button-active { - border-radius: var(--border-radius); - margin: var(--border-radius); + border-radius: var(--button-margin); + margin: var(--button-margin); + padding-top: 1%; border: none; outline: 0; transition-duration: 0.3s; @@ -292,11 +323,13 @@ a:visited { display: flex; vertical-align: middle; flex-direction: column; + overflow-x: auto; } @media (max-aspect-ratio: 1/1) { .infobar-button-active{ + padding-top: 2%; height: calc(0.18 * var(--sidebar-height)); } } @@ -316,8 +349,8 @@ a:visited { } .infobar-input { - border-radius: var(--border-radius); - margin: var(--border-radius); + border-radius: var(--button-margin); + margin: var(--button-margin); border: none; outline: 0; transition-duration: 0.3s; diff --git a/websocket_connection.js b/websocket_connection.js index 36b2552..c38111a 100644 --- a/websocket_connection.js +++ b/websocket_connection.js @@ -1,6 +1,6 @@ class WebsocketConnection { - constructor(ip, port, grid, status_label, matches_container, control_container, search_container, login_callback_func, error_callback_func) + constructor(ip, port, grid, info_func, err_func,matches_container, control_container, end_button, logout_container, search_container, login_callback_func, error_callback_func) { this.ip = ip; this.port = port; @@ -9,18 +9,21 @@ class WebsocketConnection this.socket = null; this.registered = false; + this.info_func = info_func; + this.err_func = err_func; + this.grid = grid; - this.status_label = status_label; this.matches_container = matches_container; this.control_container = control_container; + this.logout_container = logout_container; this.search_container = search_container; + this.end_button = end_button; + this.active_match = null; this.connected = false; - this.current_end_button = null; - this.login_callback_func = login_callback_func; this.openmatches = {}; @@ -30,6 +33,7 @@ class WebsocketConnection this.friends = []; + this.elos = []; this.friend_name_divs = []; @@ -103,7 +107,7 @@ class WebsocketConnection this.connected = false; if (!this.closed_by_user && !login_failed) { - this.status_label.innerHTML = "connection to server closed"; + this.err_func("connection to server closed"); this.error_callback_func(); } @@ -136,7 +140,7 @@ class WebsocketConnection this.connected = false; if (!this.closed_by_user) { - this.status_label.innerHTML = "connection to server lost"; + this.err_func("connection to server lost"); this.error_callback_func(); } } @@ -184,6 +188,11 @@ class WebsocketConnection case "friends_update": this.on_friends_update(msg.data); break; + + case "elo_update": + this.on_elo_update(msg.data); + break; + } } @@ -209,12 +218,6 @@ class WebsocketConnection } - - if (this.current_end_button != null) - { - this.control_container.container.deleteChild(this.current_end_button); - this.current_end_button = null; - } } @@ -229,15 +232,6 @@ class WebsocketConnection if (id in this.openmatches) { delete this.openmatches[id]; - if (this.active_match == id) - { - if (this.current_end_button != null) - { - this.control_container.container.deleteChild(this.current_end_button); - this.current_end_button = null; - } - - } } } else @@ -249,16 +243,21 @@ class WebsocketConnection { this.openmatches[id].open_match(); } + else + { + this.matches_container.blink(theme_color_highlight); + } } else { if (!match_state.game_over) { - this.openmatches[id] = new OnlineMatchManager(this.grid, this.status_label, this.matches_container, this.control_container, this, id, match_state, this.player.get_name()); + this.openmatches[id] = new OnlineMatchManager(this.grid, this.info_func, this.matches_container, this.control_container, this.end_button, this, id, match_state, this.player.get_name()); if (match_state.last_move == null) { this.notify("new Game against " + this.openmatches[id].online_opponent.get_name()); } + this.matches_container.blink(theme_color_highlight); } } @@ -273,8 +272,10 @@ class WebsocketConnection this.registered = true; this.session_id = data.id; this.login_callback_func(); + this.info_func(data.msg); + return; } - this.status_label.innerHTML = data.msg; + this.err_func(data.msg); } @@ -286,36 +287,48 @@ class WebsocketConnection this.session_id = data.id; this.player.set_name(data.user); this.login_callback_func(); + this.info_func(data.msg); + return; } - - this.status_label.innerHTML = data.msg; + this.err_func(data.msg); } on_match_request_response(data) { if (data.success) { - this.status_label.innerHTML = "match request sent"; + this.info_func("match request sent"); } else { - this.status_label.innerHTML = "could not send request: " + data.msg; + this.err_func("could not send request: " + data.msg); } } on_friend_request_response(data) { - this.status_label.innerHTML = data.msg; + if (data.success) + { + this.info_func(data.msg); + return; + } + this.err_func(data.msg); } on_unfriend_request_response(data) { - this.status_label.innerHTML = data.msg; + if (data.success) + { + this.info_func(data.msg); + return; + } + this.err_func(data.msg); } on_friends_update(data) { this.friends = data.friends; + this.elos = data.elos; // remove complete friend list: var n = this.friend_name_divs.length; @@ -334,7 +347,13 @@ class WebsocketConnection for (i = 0; i < n; i++) { - var tmp = this.search_container.create_double_button("" + this.friends[i], "-"); + var display_name = this.friends[i]; + if (display_name.length > 10) + { + display_name = display_name.substr(0,8) + "…"; + } + + var tmp = this.search_container.create_double_button("" + display_name + "" + this.elos[i] + "", "-"); tmp[1].name = this.friends[i]; tmp[2].name = this.friends[i]; @@ -354,6 +373,14 @@ class WebsocketConnection } } + on_elo_update(data) + { + console.log("received elo update: " + data.elo); + this.logout_container.update_head("logged in as: " + connection.player.get_name() + "
Score: " + data.elo); + this.logout_container.blink(theme_color_highlight); + // TODO + } + connect(username, pw) @@ -491,7 +518,7 @@ class WebsocketConnection close() { - this.status_label.innerHTML = "logged out"; + this.info_func("logged out"); this.closed_by_user = true; this.socket.close(); }