a lot of stuff
This commit is contained in:
parent
c68ae8f812
commit
465d809137
190
game_manager.js
190
game_manager.js
@ -1,26 +1,31 @@
|
||||
class GameManager
|
||||
{
|
||||
constructor(grid, n)
|
||||
constructor(grid, game_server_connection)
|
||||
{
|
||||
this.grid = grid;
|
||||
|
||||
this.n = n;
|
||||
this.dummy_player = new Player("test_player", 0,255,0);
|
||||
|
||||
this.dummy_player = new Player("test_player", "rgb(0,128,0)");
|
||||
this.local_player_a = new Player("red player", 255,0,0);
|
||||
this.local_player_b = new Player("green player", 0,255,0);
|
||||
this.is_local_player_a = false;
|
||||
|
||||
this.local_player_a = new Player("red player", "rgb(128,0,0)");
|
||||
this.local_player_b = new Player("green player", "rgb(0,128,0");
|
||||
this.is_local_player_a = false;;
|
||||
this.remote_player = new Player("you", 0,255,0);
|
||||
this.remote_opponent = new Player("remote player", 255,0,0);
|
||||
this.remote_is_local_turn = false;
|
||||
|
||||
this.grid.player_change_listener(this.dummy_player);
|
||||
|
||||
// possible modes:
|
||||
// -- none
|
||||
// -- local
|
||||
// -- remote //TODO
|
||||
// -- remote
|
||||
|
||||
this.game_mode = "none";
|
||||
|
||||
this.game_server_connection = game_server_connection;
|
||||
game_server_connection.set_game_manager(this);
|
||||
|
||||
this.grid.register_click_callback((i,j,k,l) => this.click_listener(i,j,k,l));
|
||||
|
||||
|
||||
@ -41,9 +46,54 @@ class GameManager
|
||||
this.toggle_local_player();
|
||||
this.grid.block_all()
|
||||
this.grid.subgrids[y][x].unblock();
|
||||
if (this.grid.subgrids[y][x].is_draw())
|
||||
{
|
||||
this.grid.unblock_all();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(this.game_mode == "remote")
|
||||
{
|
||||
|
||||
this.grid.block_all();
|
||||
|
||||
if (this.remote_is_local_turn)
|
||||
{
|
||||
this.game_server_connection.send_move(sub_x, sub_y, x, y);
|
||||
}
|
||||
|
||||
if (grid.is_won())
|
||||
{
|
||||
if (this.remote_is_local_turn)
|
||||
{
|
||||
this.status_change_listener("Congratulation, you won!");
|
||||
}
|
||||
else
|
||||
{
|
||||
this.status_change_listener("Game over, you lost!");
|
||||
}
|
||||
this.end_game();
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
this.toggle_remote_player();
|
||||
|
||||
if (this.remote_is_local_turn)
|
||||
{
|
||||
this.grid.block_all();
|
||||
|
||||
this.grid.subgrids[y][x].unblock();
|
||||
|
||||
if (this.grid.subgrids[y][x].is_draw())
|
||||
{
|
||||
this.grid.unblock_all();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
register_game_mode_change_listener(func)
|
||||
{
|
||||
@ -74,6 +124,107 @@ class GameManager
|
||||
|
||||
}
|
||||
|
||||
register_remote_game(player_name)
|
||||
{
|
||||
console.log("set player name to: " + player_name);
|
||||
if (player_name == "")
|
||||
{
|
||||
this.status_change_listener("enter your name first!");
|
||||
return;
|
||||
}
|
||||
this.set_game_mode("remote");
|
||||
this.grid.deactivate_all();
|
||||
this.grid.block_all();
|
||||
|
||||
this.remote_player.set_name(player_name);
|
||||
|
||||
this.status_change_listener("connect to server...");
|
||||
|
||||
this.game_server_connection.connect(() => {
|
||||
this.game_server_connection.set_player(this.remote_player);
|
||||
this.game_server_connection.register();
|
||||
});
|
||||
}
|
||||
|
||||
register_response_listener(is_accepted)
|
||||
{
|
||||
|
||||
if (this.game_mode != "remote")
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_accepted)
|
||||
{
|
||||
this.status_change_listener("Waiting for matchmaking");
|
||||
}
|
||||
else
|
||||
{
|
||||
this.status_change_listener("could not register for matchmaking. Maybe the name is already in use?");
|
||||
this.set_game_mode("none");
|
||||
this.grid.deactivate_all();
|
||||
this.grid.block_all();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
start_game_listener(opponent_name, is_first_move)
|
||||
{
|
||||
if (this.game_mode != "remote")
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.remote_opponent.set_name(opponent_name);
|
||||
this.remote_is_local_turn = is_first_move;
|
||||
|
||||
if (is_first_move)
|
||||
{
|
||||
this.grid.deactivate_all();
|
||||
this.grid.unblock_all();
|
||||
|
||||
this.grid.player_change_listener(this.remote_player);
|
||||
|
||||
this.status_change_listener("game aginst " + opponent_name + " started. It's your turn");
|
||||
}
|
||||
else
|
||||
{
|
||||
this.grid.deactivate_all();
|
||||
this.grid.block_all();
|
||||
|
||||
this.grid.player_change_listener(this.remote_opponent);
|
||||
|
||||
this.status_change_listener("game started, it's " + opponent_name + " turn");
|
||||
}
|
||||
}
|
||||
|
||||
move_listener(sub_x, sub_y, x, y)
|
||||
{
|
||||
if (this.game_mode != "remote" || this.remote_is_local_turn)
|
||||
{
|
||||
console.log("received unexpected move");
|
||||
return;
|
||||
}
|
||||
|
||||
this.grid.block_all();
|
||||
this.grid.subgrids[sub_y][sub_x].unblock();
|
||||
this.grid.subgrids[sub_y][sub_x].cells[y][x].on_click();
|
||||
|
||||
}
|
||||
|
||||
end_game_listener()
|
||||
{
|
||||
|
||||
if (this.game_mode != "remote")
|
||||
{
|
||||
return;
|
||||
}
|
||||
this.set_game_mode("none");
|
||||
this.grid.block_all();
|
||||
|
||||
this.status_change_listener("game was closed by server or opponent");
|
||||
}
|
||||
|
||||
toggle_local_player()
|
||||
{
|
||||
this.is_local_player_a = !this.is_local_player_a;
|
||||
@ -83,9 +234,34 @@ class GameManager
|
||||
this.grid.player_change_listener(next_player);
|
||||
}
|
||||
|
||||
toggle_remote_player()
|
||||
{
|
||||
this.remote_is_local_turn = !this.remote_is_local_turn;
|
||||
if (this.remote_is_local_turn)
|
||||
{
|
||||
this.status_change_listener("your turn");
|
||||
this.grid.player_change_listener(this.remote_player);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.status_change_listener("waiting for opponents turn...");
|
||||
this.grid.player_change_listener(this.remote_opponent);
|
||||
}
|
||||
}
|
||||
|
||||
end_game()
|
||||
{
|
||||
if (this.game_mode == "remote")
|
||||
{
|
||||
this.game_server_connection.close();
|
||||
}
|
||||
this.set_game_mode("none");
|
||||
this.grid.block_all();
|
||||
}
|
||||
|
||||
connection_error_listener()
|
||||
{
|
||||
this.status_change_listener("connection error");
|
||||
this.end_game();
|
||||
}
|
||||
}
|
199
game_server_connection.js
Normal file
199
game_server_connection.js
Normal file
@ -0,0 +1,199 @@
|
||||
class GameServerConnection
|
||||
{
|
||||
constructor(ip, port)
|
||||
{
|
||||
this.ip = ip;
|
||||
this.port = port;
|
||||
this.player = null;
|
||||
this.socket = null;
|
||||
this.registered = false;
|
||||
|
||||
this.game_manager = null;
|
||||
this.connected = false;
|
||||
}
|
||||
|
||||
set_player(p)
|
||||
{
|
||||
this.player = p;
|
||||
}
|
||||
|
||||
set_game_manager(gm)
|
||||
{
|
||||
this.game_manager = gm;
|
||||
}
|
||||
|
||||
is_registered()
|
||||
{
|
||||
return this.registered;
|
||||
}
|
||||
|
||||
is_connected()
|
||||
{
|
||||
return this.connected;
|
||||
}
|
||||
|
||||
on_open(callback_func)
|
||||
{
|
||||
// TODO
|
||||
console.log("connected to " + this.ip + ":" + this.port);
|
||||
this.connected = true;
|
||||
callback_func();
|
||||
}
|
||||
|
||||
on_close()
|
||||
{
|
||||
this.game_manager.end_game_listener()
|
||||
}
|
||||
|
||||
on_error()
|
||||
{
|
||||
console.log("error in websocket connection");
|
||||
this.game_manager.connection_error_listener();
|
||||
}
|
||||
|
||||
on_message(event)
|
||||
{
|
||||
var json_msg = event.data;
|
||||
var msg = JSON.parse(json_msg);
|
||||
|
||||
if (!msg.hasOwnProperty("type") || !msg.hasOwnProperty("data"))
|
||||
{
|
||||
console.log("received wrong formatted message");
|
||||
return;
|
||||
}
|
||||
|
||||
switch(msg.type)
|
||||
{
|
||||
case "register_response":
|
||||
this.on_register_response(msg.data);
|
||||
break;
|
||||
|
||||
case "game_starts":
|
||||
this.on_game_starts(msg.data);
|
||||
break;
|
||||
|
||||
case "move":
|
||||
this.on_move(msg.data);
|
||||
break;
|
||||
|
||||
case "move_response":
|
||||
this.on_move_response(msg.data);
|
||||
break;
|
||||
|
||||
case "end_game":
|
||||
this.on_end_game(msg.data);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
on_register_response(data)
|
||||
{
|
||||
var success = data.success;
|
||||
this.game_manager.register_response_listener(success);
|
||||
|
||||
if (!success)
|
||||
{
|
||||
this.socket.close();
|
||||
}
|
||||
}
|
||||
|
||||
on_game_starts(data)
|
||||
{
|
||||
var op_name = data.opponent_name;
|
||||
var is_first_move = data.is_first_move;
|
||||
|
||||
this.game_manager.start_game_listener(op_name, is_first_move);
|
||||
}
|
||||
|
||||
on_move(data)
|
||||
{
|
||||
var sub_x = data.sub_x;
|
||||
var sub_y = data.sub_y;
|
||||
var x = data.x;
|
||||
var y = data.y;
|
||||
|
||||
this.game_manager.move_listener(sub_x, sub_y, x, y);
|
||||
}
|
||||
|
||||
on_move_response(data)
|
||||
{
|
||||
if (data.success)
|
||||
{
|
||||
console.log("move accepted");
|
||||
}
|
||||
else
|
||||
{
|
||||
console.error("move not accepted");
|
||||
}
|
||||
}
|
||||
|
||||
on_end_game(data)
|
||||
{
|
||||
this.game_manager.end_game_listener();
|
||||
this.close();
|
||||
}
|
||||
|
||||
connect(callback_func)
|
||||
{
|
||||
this.socket = new WebSocket("ws://" + this.ip + ":" + this.port);
|
||||
this.socket.onmessage = (e => this.on_message(e));
|
||||
this.socket.onopen = (() => this.on_open(callback_func));
|
||||
this.socket.onerror = (() => this.on_error());
|
||||
this.socket.onclose = (() => this.on_close());
|
||||
}
|
||||
|
||||
send_move(sub_x, sub_y, x, y)
|
||||
{
|
||||
var msg_object = {
|
||||
type: "move",
|
||||
data: {
|
||||
sub_x: "" + sub_x,
|
||||
sub_y: "" + sub_y,
|
||||
x: "" + x,
|
||||
y: "" + y
|
||||
}
|
||||
};
|
||||
|
||||
this.socket.send(JSON.stringify(msg_object));
|
||||
}
|
||||
|
||||
register()
|
||||
{
|
||||
// register for game queue
|
||||
var msg_object = {
|
||||
type: "register",
|
||||
data: {
|
||||
id: this.player.get_id(),
|
||||
name: this.player.get_name()
|
||||
}
|
||||
};
|
||||
|
||||
this.socket.send(JSON.stringify(msg_object));
|
||||
}
|
||||
|
||||
send_disconnect()
|
||||
{
|
||||
if (!this.is_connected)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var msg_object = {
|
||||
type: "end_game",
|
||||
data: {
|
||||
msg: ""
|
||||
}
|
||||
};
|
||||
|
||||
this.socket.send(JSON.stringify(msg_object));
|
||||
}
|
||||
|
||||
close()
|
||||
{
|
||||
if (this.is_connected)
|
||||
{
|
||||
this.is_connected = false;
|
||||
this.socket.close();
|
||||
}
|
||||
}
|
||||
}
|
@ -12,15 +12,18 @@
|
||||
<div id="grid-container" class="grid-container"></div>
|
||||
<div id="sidebar-container" class="sidebar-container">
|
||||
<div id="create-game-container" class="create-game-container"></div>
|
||||
<div id="setting-container" class="setting-container"></div>
|
||||
<div id="control-container" class="control-container"></div>
|
||||
<div id="info-container" class="info-container"></div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="settings.js"></script>
|
||||
<script src="player.js"></script>
|
||||
<script src="tile.js"></script>
|
||||
<script src="grid.js"></script>
|
||||
<script src="subgrid.js"></script>
|
||||
<script src="game_manager.js"></script>
|
||||
<script src="game_server_connection.js"></script>
|
||||
<script src="sidebar.js"></script>
|
||||
<script src="main.js"></script>
|
||||
|
||||
|
6
main.js
6
main.js
@ -5,12 +5,14 @@ var default_opacity = style.getPropertyValue("--opacity");
|
||||
var ground_color = style.getPropertyValue("--ground-color");
|
||||
|
||||
var create_game_container = document.getElementById("create-game-container");
|
||||
var setting_container = document.getElementById("setting-container");
|
||||
var control_container = document.getElementById("control-container");
|
||||
var info_container = document.getElementById("info-container");
|
||||
|
||||
var grid = new Grid(n, document.getElementById("grid-container"), tilesize, tilesize, ground_color);
|
||||
var game_manager = new GameManager(grid);
|
||||
var sidebar = new Sidebar(create_game_container, control_container, info_container, game_manager);
|
||||
var server_connection = new GameServerConnection(server_url, server_port);
|
||||
var game_manager = new GameManager(grid, server_connection);
|
||||
var sidebar = new Sidebar(create_game_container, setting_container, control_container, info_container, game_manager);
|
||||
|
||||
window.addEventListener("resize", function() {
|
||||
var tilesize = getComputedStyle(document.body).getPropertyValue("--tile-size");
|
||||
|
25
player.js
25
player.js
@ -1,20 +1,25 @@
|
||||
class Player
|
||||
{
|
||||
constructor(name, color)
|
||||
constructor(name, r,g,b)
|
||||
{
|
||||
this.name = name;
|
||||
this.color = color;
|
||||
this.r = r;
|
||||
this.g = g;
|
||||
this.b = b;
|
||||
this.id = name;
|
||||
}
|
||||
|
||||
set_name(name)
|
||||
{
|
||||
this.name = name;
|
||||
this.id = name; // TODO: distinguish between name and id
|
||||
}
|
||||
|
||||
set_color(color)
|
||||
set_color(r,g,b)
|
||||
{
|
||||
this.color = color;
|
||||
this.r = r;
|
||||
this.g = g;
|
||||
this.b = b;
|
||||
}
|
||||
|
||||
get_name()
|
||||
@ -29,7 +34,17 @@ class Player
|
||||
|
||||
get_color()
|
||||
{
|
||||
return this.color;
|
||||
return "rgb(" + this.r + "," + this.g + "," + this.b + ")";
|
||||
}
|
||||
|
||||
get_color_values()
|
||||
{
|
||||
var col = {
|
||||
r: this.r,
|
||||
g: this.g,
|
||||
b: this.b
|
||||
};
|
||||
return col;
|
||||
}
|
||||
|
||||
|
||||
|
2
settings.js
Normal file
2
settings.js
Normal file
@ -0,0 +1,2 @@
|
||||
var server_url = "127.0.0.1";
|
||||
var server_port = "5555";
|
55
sidebar.js
55
sidebar.js
@ -1,8 +1,9 @@
|
||||
class Sidebar
|
||||
{
|
||||
constructor(create_game_container, control_container, info_container, game_manager)
|
||||
constructor(create_game_container, setting_container, control_container, info_container, game_manager)
|
||||
{
|
||||
this.create_game_container = create_game_container;
|
||||
this.setting_container = setting_container;
|
||||
this.control_container = control_container;
|
||||
this.info_container = info_container;
|
||||
|
||||
@ -12,6 +13,8 @@ class Sidebar
|
||||
this.bind_events();
|
||||
|
||||
this.activate_create_game();
|
||||
this.activate_setting();
|
||||
this.activate_info();
|
||||
}
|
||||
|
||||
create_button(text)
|
||||
@ -22,6 +25,15 @@ class Sidebar
|
||||
return b;
|
||||
}
|
||||
|
||||
create_input(text)
|
||||
{
|
||||
var i = document.createElement("input");
|
||||
i.className = "sidebar-input";
|
||||
i.type = "text";
|
||||
i.value = text;
|
||||
return i;
|
||||
}
|
||||
|
||||
create_label(text)
|
||||
{
|
||||
var l = document.createElement("label");
|
||||
@ -34,12 +46,24 @@ class Sidebar
|
||||
{
|
||||
|
||||
// create new game area:
|
||||
this.create_game_container.appendChild(this.create_label("Start new game"));
|
||||
this.create_game_container.appendChild(this.create_label("Choose game type"));
|
||||
this.b_local = this.create_button("local game")
|
||||
this.create_game_container.appendChild(this.b_local);
|
||||
|
||||
this.b_remote = this.create_button("remote game");
|
||||
this.create_game_container.appendChild(this.b_remote);
|
||||
|
||||
this.create_game_container.style.display = "none";
|
||||
|
||||
|
||||
// settings area
|
||||
this.setting_container.appendChild(this.create_label("select online name:"));
|
||||
|
||||
this.i_player_name = this.create_input("");
|
||||
this.setting_container.appendChild(this.i_player_name);
|
||||
|
||||
this.setting_container.style.display = "none";
|
||||
|
||||
// control area:
|
||||
|
||||
this.b_end_game = this.create_button("end game");
|
||||
@ -49,7 +73,7 @@ class Sidebar
|
||||
|
||||
|
||||
// status area:
|
||||
this.info_container.appendChild(this.create_label("status"));
|
||||
this.info_container.appendChild(this.create_label("status:"));
|
||||
|
||||
this.status_text = this.create_label("select gamemode");
|
||||
this.info_container.appendChild(this.status_text);
|
||||
@ -68,6 +92,7 @@ class Sidebar
|
||||
|
||||
this.b_local.addEventListener("click", () => this.game_manager.start_local_game());
|
||||
this.b_end_game.addEventListener("click", () => this.game_manager.end_game());
|
||||
this.b_remote.addEventListener("click", () => this.game_manager.register_remote_game(this.get_player_name()));
|
||||
}
|
||||
|
||||
set_status(text)
|
||||
@ -75,11 +100,21 @@ class Sidebar
|
||||
this.status_text.innerHTML = text;
|
||||
}
|
||||
|
||||
get_player_name()
|
||||
{
|
||||
return this.i_player_name.value;
|
||||
}
|
||||
|
||||
activate_create_game()
|
||||
{
|
||||
this.create_game_container.style.display = "inline-block";
|
||||
}
|
||||
|
||||
activate_setting()
|
||||
{
|
||||
this.setting_container.style.display = "inline-block";
|
||||
}
|
||||
|
||||
activate_control()
|
||||
{
|
||||
this.control_container.style.display = "inline-block";
|
||||
@ -95,6 +130,11 @@ class Sidebar
|
||||
this.create_game_container.style.display = "none";
|
||||
}
|
||||
|
||||
deactivate_setting()
|
||||
{
|
||||
this.setting_container.style.display = "none";
|
||||
}
|
||||
|
||||
deactivate_control()
|
||||
{
|
||||
this.control_container.style.display = "none";
|
||||
@ -110,6 +150,7 @@ class Sidebar
|
||||
if (gamemode == "none")
|
||||
{
|
||||
this.activate_create_game();
|
||||
this.activate_setting();
|
||||
this.deactivate_control();
|
||||
this.activate_info();
|
||||
return
|
||||
@ -117,6 +158,14 @@ class Sidebar
|
||||
if (gamemode == "local")
|
||||
{
|
||||
this.deactivate_create_game();
|
||||
this.deactivate_setting();
|
||||
this.activate_control();
|
||||
this.activate_info();
|
||||
}
|
||||
if (gamemode == "remote")
|
||||
{
|
||||
this.deactivate_create_game();
|
||||
this.deactivate_setting();
|
||||
this.activate_control();
|
||||
this.activate_info();
|
||||
}
|
||||
|
90
style.css
90
style.css
@ -4,7 +4,7 @@ html, body {
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
background: rgb(70, 76, 92);
|
||||
background: rgb(30, 36, 119) ;
|
||||
outline: 0;
|
||||
position: relative;
|
||||
}
|
||||
@ -13,12 +13,12 @@ body {
|
||||
--tictactoe_n: 3;
|
||||
--button-margin: 0.5vh;
|
||||
--tile-size: calc((100vh / (var(--tictactoe_n) * var(--tictactoe_n))) - 2 * var(--button-margin));
|
||||
--opacity: 0.2;
|
||||
--opacity: 1;
|
||||
--border-radius: 1vh;
|
||||
--sidebar-width: 25vh;
|
||||
--ground-color: rgb(214, 214, 214);
|
||||
--ground-color: rgb(30, 36, 119) ;
|
||||
--board-size: calc(var(--tictactoe_n) * var(--tictactoe_n) * var(--tile-size) + (var(--tictactoe_n) * var(--tictactoe_n) + var(--tictactoe_n)) * var(--button-margin) );
|
||||
--sidebar-height: none; /* unused if not in portrait mode */
|
||||
--sidebar-height: calc(var(--board-size) - 2 * var(--border-radius));
|
||||
}
|
||||
|
||||
/* override settings on portrait mode: */
|
||||
@ -28,7 +28,7 @@ body {
|
||||
--button-margin: 0.5vw;
|
||||
--tile-size: calc((100vw / (var(--tictactoe_n) * var(--tictactoe_n))) - 2 * var(--button-margin));
|
||||
--border-radius: 1vw;
|
||||
--sidebar-width: 40vw;
|
||||
--sidebar-width: calc(var(--board-size) - 2 * var(--border-radius));
|
||||
--sidebar-height: 15vw;
|
||||
}
|
||||
|
||||
@ -65,6 +65,7 @@ body {
|
||||
height: calc(var(--tile-size) - (var(--button-margin) * 2));
|
||||
display: inline-block;
|
||||
outline: 0;
|
||||
font-size: calc(3 * var(--border-radius));
|
||||
transition-duration: 0.1s;
|
||||
}
|
||||
|
||||
@ -87,7 +88,7 @@ body {
|
||||
margin: var(--button-margin);
|
||||
width: calc(var(--tictactoe_n) * var(--tile-size));
|
||||
height: calc(var(--tictactoe_n) * var(--tile-size));
|
||||
background: rgba(0, 0, 0, var(--opacity));
|
||||
background: rgba(255, 255, 255,0.05);
|
||||
display: inline-block;
|
||||
transition-duration: 0.5s;
|
||||
}
|
||||
@ -98,7 +99,7 @@ body {
|
||||
margin: var(--button-margin);
|
||||
width: calc(var(--tictactoe_n) * var(--tile-size));
|
||||
height: calc(var(--tictactoe_n) * var(--tile-size));
|
||||
background: rgba(0,25,64,var(--opacity));
|
||||
background: rgba(255, 255, 255, 0.2);
|
||||
display: inline-block;
|
||||
transition-duration: 0.5s;
|
||||
}
|
||||
@ -107,11 +108,12 @@ body {
|
||||
border-radius: var(--border-radius);
|
||||
padding: var(--border-radius);
|
||||
vertical-align: top;
|
||||
background: rgba(0, 0, 0, var(--opacity));
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
display: inline-flex;
|
||||
justify-content: space-between;
|
||||
flex-direction:column;
|
||||
height: calc(var(--board-size) - 2 * var(--border-radius));
|
||||
height: var(--sidebar-height);
|
||||
width: var(--sidebar-width);
|
||||
position: relative;
|
||||
transition-duration: 0.5s;
|
||||
}
|
||||
@ -120,11 +122,8 @@ body {
|
||||
@media (orientation: portrait) {
|
||||
|
||||
.sidebar-container {
|
||||
display: inline-flex;
|
||||
justify-content: space-between;
|
||||
flex-direction:row;
|
||||
height: var(--sidebar-height);
|
||||
width: calc(var(--board-size));
|
||||
padding: none;
|
||||
}
|
||||
|
||||
}
|
||||
@ -138,6 +137,7 @@ body {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
|
||||
.control-container {
|
||||
border-radius: var(--border-radius);
|
||||
padding: var(--border-radius);
|
||||
@ -147,6 +147,16 @@ body {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
|
||||
.setting-container {
|
||||
border-radius: var(--border-radius);
|
||||
padding: var(--border-radius);
|
||||
top: 0;
|
||||
background: none;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.info-container {
|
||||
border-radius: var(--border-radius);
|
||||
padding: var(--border-radius);
|
||||
@ -162,6 +172,16 @@ body {
|
||||
color: white;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
font-size: calc(2 * var(--border-radius));
|
||||
width: calc(var(--sidebar-width) - 4 * var(--border-radius));
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
@media (orientation: portrait) {
|
||||
.sidebar-label
|
||||
{
|
||||
width: calc(var(--sidebar-width) * 0.3);
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar-button {
|
||||
@ -170,20 +190,54 @@ body {
|
||||
border: none;
|
||||
outline: 0;
|
||||
transition-duration: 0.3s;
|
||||
background: rgba(0, 0, 0, var(--opacity));
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
color: rgb(255, 255, 255);
|
||||
font-size: calc(3 * var(--border-radius));
|
||||
width: var(--sidebar-width);
|
||||
height: calc(5 * var(--border-radius));
|
||||
height: calc(4 * var(--border-radius));
|
||||
width: calc(var(--sidebar-width) - 4 * var(--border-radius));
|
||||
vertical-align: middle;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
@media (orientation: portrait) {
|
||||
|
||||
.sidebar-button{
|
||||
width: calc(0.25 * var(--sidebar-width));
|
||||
height: calc(0.3 * var(--sidebar-height));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.sidebar-button:hover {
|
||||
background: rgba(255, 255, 255, var(--opacity));
|
||||
background: rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
|
||||
.sidebar-button:active {
|
||||
background: rgba(255, 255, 255, calc(var(--opacity) * 2));
|
||||
background: rgba(255, 255, 255, 0.4);
|
||||
}
|
||||
|
||||
.sidebar-input {
|
||||
border-radius: var(--border-radius);
|
||||
margin: var(--border-radius);
|
||||
border: none;
|
||||
outline: 0;
|
||||
transition-duration: 0.3s;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
color: rgb(255, 255, 255);
|
||||
font-size: calc(3 * var(--border-radius));
|
||||
height: calc(4 * var(--border-radius));
|
||||
width: calc(var(--sidebar-width) - 4 * var(--border-radius));
|
||||
vertical-align: middle;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
@media (orientation: portrait) {
|
||||
|
||||
.sidebar-input{
|
||||
height: calc(0.3 * var(--sidebar-height));
|
||||
width: calc(0.25 * var(--sidebar-width));
|
||||
}
|
||||
}
|
173
subgrid.js
173
subgrid.js
@ -1,7 +1,5 @@
|
||||
class Subgrid
|
||||
{
|
||||
constructor(n, sub_x, sub_y,subgrid_container_div, tile_width, tile_height, ground_color)
|
||||
{
|
||||
class Subgrid {
|
||||
constructor(n, sub_x, sub_y, subgrid_container_div, tile_width, tile_height, ground_color) {
|
||||
this.n = n;
|
||||
this.subgrid_container_div = subgrid_container_div;
|
||||
this.tile_height = tile_height;
|
||||
@ -9,27 +7,28 @@ class Subgrid
|
||||
|
||||
this.cells = [];
|
||||
this.won_player = null;
|
||||
this.draw = false;
|
||||
this.clicked_fields = 0;
|
||||
|
||||
this.sub_x = sub_x;
|
||||
this.sub_y = sub_y;
|
||||
|
||||
this.ground_color = ground_color;
|
||||
|
||||
this.bgcolor = null;
|
||||
|
||||
this.create();
|
||||
this.block();
|
||||
|
||||
console.log("new subgrid created");
|
||||
}
|
||||
|
||||
create()
|
||||
{
|
||||
var x,y;
|
||||
for (y = 0; y < this.n; y++)
|
||||
{
|
||||
create() {
|
||||
var x, y;
|
||||
for (y = 0; y < this.n; y++) {
|
||||
var div_row = this.subgrid_container_div.appendChild(document.createElement("div"));
|
||||
var row = [];
|
||||
for (x = 0; x < this.n; x++)
|
||||
{
|
||||
for (x = 0; x < this.n; x++) {
|
||||
var div_button = div_row.appendChild(document.createElement("div"));
|
||||
div_button.className = "grid-tile";
|
||||
var button = document.createElement("button");
|
||||
@ -42,73 +41,67 @@ class Subgrid
|
||||
var b_h = this.tile_height;
|
||||
|
||||
row.push(new Tile(b_x, b_y, b_w, b_h, button, this.ground_color, div_button));
|
||||
// TODO: register listener?
|
||||
row[x].register_click_callback((i,j) => this.click_listener(i,j));
|
||||
row[x].register_unlock_request_callback((i,j) => this.unlock_request_listener(i,j));
|
||||
|
||||
row[x].register_click_callback((i, j) => this.click_listener(i, j));
|
||||
row[x].register_unlock_request_callback((i, j) => this.unlock_request_listener(i, j));
|
||||
|
||||
}
|
||||
this.cells.push(row);
|
||||
}
|
||||
}
|
||||
|
||||
register_click_callback(func)
|
||||
{
|
||||
register_click_callback(func) {
|
||||
this.click_callback = func;
|
||||
}
|
||||
|
||||
click_listener(x,y)
|
||||
{
|
||||
click_listener(x, y) {
|
||||
|
||||
this.check_win(x,y);
|
||||
this.check_win(x, y);
|
||||
this.clicked_fields++;
|
||||
this.check_draw();
|
||||
|
||||
this.click_callback(this.sub_x, this.sub_y, x, y);
|
||||
}
|
||||
|
||||
player_change_listener(player)
|
||||
{
|
||||
var x,y;
|
||||
for (y = 0; y < this.n; y++)
|
||||
{
|
||||
for (x = 0; x < this.n; x++)
|
||||
{
|
||||
player_change_listener(player) {
|
||||
var x, y;
|
||||
for (y = 0; y < this.n; y++) {
|
||||
for (x = 0; x < this.n; x++) {
|
||||
this.cells[y][x].player_change_listener(player);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unlock_request_listener(x,y)
|
||||
{
|
||||
unlock_request_listener(x, y) {
|
||||
// TODO: unused so far
|
||||
|
||||
//return this.unlock_request_callback(x,y);
|
||||
return false;
|
||||
}
|
||||
|
||||
is_won()
|
||||
{
|
||||
is_won() {
|
||||
return this.won_player != null;
|
||||
}
|
||||
|
||||
get_won_player()
|
||||
{
|
||||
is_draw() {
|
||||
return this.draw;
|
||||
}
|
||||
|
||||
get_won_player() {
|
||||
return this.won_player;
|
||||
}
|
||||
|
||||
check_win(x,y)
|
||||
{
|
||||
check_win(x, y) {
|
||||
// check whether this subfield is won
|
||||
|
||||
if (this.won_player == null)
|
||||
{
|
||||
if (this.won_player == null) {
|
||||
var i;
|
||||
var player = this.cells[y][x].get_activated_player();
|
||||
|
||||
// check column
|
||||
var is_col = true;
|
||||
for (i = 0; i < this.n; i++)
|
||||
{
|
||||
if (!this.cells[i][x].get_is_activated() || player.get_id() != this.cells[i][x].get_activated_player().get_id())
|
||||
{
|
||||
for (i = 0; i < this.n; i++) {
|
||||
if (!this.cells[i][x].get_is_activated() || player.get_id() != this.cells[i][x].get_activated_player().get_id()) {
|
||||
is_col = false;
|
||||
break;
|
||||
}
|
||||
@ -116,10 +109,8 @@ class Subgrid
|
||||
|
||||
// check row
|
||||
var is_row = true;
|
||||
for (i = 0; i < this.n; i++)
|
||||
{
|
||||
if (!this.cells[y][i].get_is_activated() || player.get_id() != this.cells[y][i].get_activated_player().get_id())
|
||||
{
|
||||
for (i = 0; i < this.n; i++) {
|
||||
if (!this.cells[y][i].get_is_activated() || player.get_id() != this.cells[y][i].get_activated_player().get_id()) {
|
||||
is_row = false;
|
||||
break;
|
||||
}
|
||||
@ -129,13 +120,10 @@ class Subgrid
|
||||
|
||||
// main diag
|
||||
var is_main_diag = false;
|
||||
if (x == y)
|
||||
{
|
||||
if (x == y) {
|
||||
is_main_diag = true;
|
||||
for (i = 0; i < this.n; i++)
|
||||
{
|
||||
if (!this.cells[i][i].get_is_activated() || player.get_id() != this.cells[i][i].get_activated_player().get_id())
|
||||
{
|
||||
for (i = 0; i < this.n; i++) {
|
||||
if (!this.cells[i][i].get_is_activated() || player.get_id() != this.cells[i][i].get_activated_player().get_id()) {
|
||||
is_main_diag = false;
|
||||
break;
|
||||
}
|
||||
@ -144,89 +132,86 @@ class Subgrid
|
||||
|
||||
// secundary diag
|
||||
var is_sec_diag = false;
|
||||
if (x + y == this.n - 1)
|
||||
{
|
||||
if (x + y == this.n - 1) {
|
||||
is_sec_diag = true;
|
||||
for (i = 0; i < this.n; i++)
|
||||
{
|
||||
if (!this.cells[i][this.n - i - 1].get_is_activated() || player.get_id() != this.cells[i][this.n - i - 1].get_activated_player().get_id())
|
||||
{
|
||||
for (i = 0; i < this.n; i++) {
|
||||
if (!this.cells[i][this.n - i - 1].get_is_activated() || player.get_id() != this.cells[i][this.n - i - 1].get_activated_player().get_id()) {
|
||||
is_sec_diag = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (is_row || is_col || is_main_diag || is_sec_diag)
|
||||
{
|
||||
if (is_row || is_col || is_main_diag || is_sec_diag) {
|
||||
this.won_player = player;
|
||||
this.subgrid_container_div.style.backgroundColor = player.get_color();
|
||||
this.bgcolor = player.get_color_values();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
activate_all()
|
||||
{
|
||||
var x,y;
|
||||
for (y = 0; y < this.n; y++)
|
||||
{
|
||||
for (x = 0; x < this.n; x++)
|
||||
{
|
||||
check_draw() {
|
||||
this.draw = (!(this.clicked_fields < this.n * this.n));
|
||||
}
|
||||
|
||||
activate_all() {
|
||||
var x, y;
|
||||
for (y = 0; y < this.n; y++) {
|
||||
for (x = 0; x < this.n; x++) {
|
||||
this.cells[y][x].activate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
deactivate_all()
|
||||
{
|
||||
var x,y;
|
||||
for (y = 0; y < this.n; y++)
|
||||
{
|
||||
for (x = 0; x < this.n; x++)
|
||||
{
|
||||
deactivate_all() {
|
||||
var x, y;
|
||||
for (y = 0; y < this.n; y++) {
|
||||
for (x = 0; x < this.n; x++) {
|
||||
this.cells[y][x].deactivate();
|
||||
}
|
||||
}
|
||||
this.won_player = null;
|
||||
this.draw = false;
|
||||
this.clicked_fields = 0;
|
||||
this.subgrid_container_div.style.backgroundColor = ""; // reset to css color
|
||||
}
|
||||
|
||||
block()
|
||||
{
|
||||
var x,y;
|
||||
for (y = 0; y < this.n; y++)
|
||||
{
|
||||
for (x = 0; x < this.n; x++)
|
||||
{
|
||||
block() {
|
||||
var x, y;
|
||||
for (y = 0; y < this.n; y++) {
|
||||
for (x = 0; x < this.n; x++) {
|
||||
this.cells[y][x].lock();
|
||||
}
|
||||
}
|
||||
this.subgrid_container_div.className = "subgrid-container";
|
||||
if (this.is_won())
|
||||
{
|
||||
var c = this.bgcolor;
|
||||
this.subgrid_container_div.style.backgroundColor = "rgba(" + c.r + "," + c.g + "," + c.b + ", 0.2)";
|
||||
}
|
||||
}
|
||||
|
||||
unblock()
|
||||
{
|
||||
var x,y;
|
||||
for (y = 0; y < this.n; y++)
|
||||
{
|
||||
for (x = 0; x < this.n; x++)
|
||||
{
|
||||
unblock() {
|
||||
var x, y;
|
||||
for (y = 0; y < this.n; y++) {
|
||||
for (x = 0; x < this.n; x++) {
|
||||
this.cells[y][x].unlock();
|
||||
}
|
||||
}
|
||||
this.subgrid_container_div.className = "subgrid-container-activated";
|
||||
if (this.is_won())
|
||||
{
|
||||
var c = this.bgcolor;
|
||||
this.subgrid_container_div.style.backgroundColor = "rgba(" + c.r + "," + c.g + "," + c.b + ", 0.4)";
|
||||
}
|
||||
}
|
||||
|
||||
on_screen_orientation_change(tile_w,tile_h)
|
||||
{
|
||||
on_screen_orientation_change(tile_w, tile_h) {
|
||||
this.tile_width = tile_w;
|
||||
this.tile_h = tile_h;
|
||||
|
||||
var x,y;
|
||||
for (y = 0; y < this.n; y++)
|
||||
{
|
||||
for (x = 0; x < this.n; x++)
|
||||
{
|
||||
var x, y;
|
||||
for (y = 0; y < this.n; y++) {
|
||||
for (x = 0; x < this.n; x++) {
|
||||
this.cells[y][x].update_css_transform(tile_w, tile_h);
|
||||
}
|
||||
}
|
||||
|
19
tile.js
19
tile.js
@ -23,6 +23,11 @@ class Tile
|
||||
this.reset();
|
||||
this.bind();
|
||||
|
||||
|
||||
this.opacity_off = 0.5;
|
||||
this.opacity_select = 0.6;
|
||||
this.opacity_on = 1;
|
||||
|
||||
}
|
||||
|
||||
update_css_transform(w,h)
|
||||
@ -76,13 +81,13 @@ class Tile
|
||||
lock()
|
||||
{
|
||||
this.locked = true;
|
||||
this.elem.style.opacity = 0.3;
|
||||
this.elem.style.opacity = this.opacity_off;
|
||||
}
|
||||
|
||||
unlock()
|
||||
{
|
||||
this.locked = false;
|
||||
this.elem.style.opacity = 0.5;
|
||||
this.elem.style.opacity = this.opacity_off;
|
||||
}
|
||||
|
||||
deactivate()
|
||||
@ -90,7 +95,7 @@ class Tile
|
||||
this.is_activated = false;
|
||||
this.activated_player = null;
|
||||
this.elem.style.background = this.ground_color;
|
||||
this.elem.style.opacity = 0.3;
|
||||
this.elem.style.opacity = this.opacity_off;
|
||||
this.elem.style.border = "none";
|
||||
}
|
||||
|
||||
@ -99,7 +104,7 @@ class Tile
|
||||
this.is_activated = true;
|
||||
this.activated_player = this.player;
|
||||
this.elem.style.background = this.player.get_color();
|
||||
this.elem.style.opacity = 1.0;
|
||||
this.elem.style.opacity = this.opacity_on;
|
||||
this.elem.style.border = "2px solid rgba(255,255,255,0.3)";
|
||||
}
|
||||
|
||||
@ -108,7 +113,7 @@ class Tile
|
||||
if (!this.is_activated && !this.locked)
|
||||
{
|
||||
this.elem.style.background = this.player.get_color();
|
||||
this.elem.style.opacity = 0.7;
|
||||
this.elem.style.opacity = this.opacity_select;
|
||||
this.elem.style.border = "1px solid rgba(255,255,255,0.3)";
|
||||
}
|
||||
}
|
||||
@ -120,11 +125,11 @@ class Tile
|
||||
this.elem.style.background = this.ground_color;
|
||||
if (this.locked)
|
||||
{
|
||||
this.elem.style.opacity = 0.3;
|
||||
this.elem.style.opacity = this.opacity_off;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.elem.style.opacity = 0.5;
|
||||
this.elem.style.opacity = this.opacity_select;
|
||||
}
|
||||
this.elem.style.border = "none";
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user