a lot of stuff

This commit is contained in:
Jonas Weinz 2019-03-10 00:29:15 +01:00
parent c68ae8f812
commit 465d809137
10 changed files with 629 additions and 139 deletions

View File

@ -1,26 +1,31 @@
class GameManager class GameManager
{ {
constructor(grid, n) constructor(grid, game_server_connection)
{ {
this.grid = grid; 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.remote_player = new Player("you", 0,255,0);
this.local_player_b = new Player("green player", "rgb(0,128,0"); this.remote_opponent = new Player("remote player", 255,0,0);
this.is_local_player_a = false;; this.remote_is_local_turn = false;
this.grid.player_change_listener(this.dummy_player); this.grid.player_change_listener(this.dummy_player);
// possible modes: // possible modes:
// -- none // -- none
// -- local // -- local
// -- remote //TODO // -- remote
this.game_mode = "none"; 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)); 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.toggle_local_player();
this.grid.block_all() this.grid.block_all()
this.grid.subgrids[y][x].unblock(); 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) 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() toggle_local_player()
{ {
this.is_local_player_a = !this.is_local_player_a; this.is_local_player_a = !this.is_local_player_a;
@ -83,9 +234,34 @@ class GameManager
this.grid.player_change_listener(next_player); 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() end_game()
{ {
if (this.game_mode == "remote")
{
this.game_server_connection.close();
}
this.set_game_mode("none"); this.set_game_mode("none");
this.grid.block_all(); this.grid.block_all();
} }
connection_error_listener()
{
this.status_change_listener("connection error");
this.end_game();
}
} }

199
game_server_connection.js Normal file
View 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();
}
}
}

View File

@ -12,15 +12,18 @@
<div id="grid-container" class="grid-container"></div> <div id="grid-container" class="grid-container"></div>
<div id="sidebar-container" class="sidebar-container"> <div id="sidebar-container" class="sidebar-container">
<div id="create-game-container" class="create-game-container"></div> <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="control-container" class="control-container"></div>
<div id="info-container" class="info-container"></div> <div id="info-container" class="info-container"></div>
</div> </div>
</div> </div>
<script src="settings.js"></script>
<script src="player.js"></script> <script src="player.js"></script>
<script src="tile.js"></script> <script src="tile.js"></script>
<script src="grid.js"></script> <script src="grid.js"></script>
<script src="subgrid.js"></script> <script src="subgrid.js"></script>
<script src="game_manager.js"></script> <script src="game_manager.js"></script>
<script src="game_server_connection.js"></script>
<script src="sidebar.js"></script> <script src="sidebar.js"></script>
<script src="main.js"></script> <script src="main.js"></script>

View File

@ -5,12 +5,14 @@ var default_opacity = style.getPropertyValue("--opacity");
var ground_color = style.getPropertyValue("--ground-color"); var ground_color = style.getPropertyValue("--ground-color");
var create_game_container = document.getElementById("create-game-container"); var create_game_container = document.getElementById("create-game-container");
var setting_container = document.getElementById("setting-container");
var control_container = document.getElementById("control-container"); var control_container = document.getElementById("control-container");
var info_container = document.getElementById("info-container"); var info_container = document.getElementById("info-container");
var grid = new Grid(n, document.getElementById("grid-container"), tilesize, tilesize, ground_color); var grid = new Grid(n, document.getElementById("grid-container"), tilesize, tilesize, ground_color);
var game_manager = new GameManager(grid); var server_connection = new GameServerConnection(server_url, server_port);
var sidebar = new Sidebar(create_game_container, control_container, info_container, game_manager); 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() { window.addEventListener("resize", function() {
var tilesize = getComputedStyle(document.body).getPropertyValue("--tile-size"); var tilesize = getComputedStyle(document.body).getPropertyValue("--tile-size");

View File

@ -1,20 +1,25 @@
class Player class Player
{ {
constructor(name, color) constructor(name, r,g,b)
{ {
this.name = name; this.name = name;
this.color = color; this.r = r;
this.g = g;
this.b = b;
this.id = name; this.id = name;
} }
set_name(name) set_name(name)
{ {
this.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() get_name()
@ -29,7 +34,17 @@ class Player
get_color() 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
View File

@ -0,0 +1,2 @@
var server_url = "127.0.0.1";
var server_port = "5555";

View File

@ -1,8 +1,9 @@
class Sidebar 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.create_game_container = create_game_container;
this.setting_container = setting_container;
this.control_container = control_container; this.control_container = control_container;
this.info_container = info_container; this.info_container = info_container;
@ -12,6 +13,8 @@ class Sidebar
this.bind_events(); this.bind_events();
this.activate_create_game(); this.activate_create_game();
this.activate_setting();
this.activate_info();
} }
create_button(text) create_button(text)
@ -22,6 +25,15 @@ class Sidebar
return b; 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) create_label(text)
{ {
var l = document.createElement("label"); var l = document.createElement("label");
@ -34,12 +46,24 @@ class Sidebar
{ {
// create new game area: // 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.b_local = this.create_button("local game")
this.create_game_container.appendChild(this.b_local); 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"; 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: // control area:
this.b_end_game = this.create_button("end game"); this.b_end_game = this.create_button("end game");
@ -49,7 +73,7 @@ class Sidebar
// status area: // 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.status_text = this.create_label("select gamemode");
this.info_container.appendChild(this.status_text); 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_local.addEventListener("click", () => this.game_manager.start_local_game());
this.b_end_game.addEventListener("click", () => this.game_manager.end_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) set_status(text)
@ -75,11 +100,21 @@ class Sidebar
this.status_text.innerHTML = text; this.status_text.innerHTML = text;
} }
get_player_name()
{
return this.i_player_name.value;
}
activate_create_game() activate_create_game()
{ {
this.create_game_container.style.display = "inline-block"; this.create_game_container.style.display = "inline-block";
} }
activate_setting()
{
this.setting_container.style.display = "inline-block";
}
activate_control() activate_control()
{ {
this.control_container.style.display = "inline-block"; this.control_container.style.display = "inline-block";
@ -95,6 +130,11 @@ class Sidebar
this.create_game_container.style.display = "none"; this.create_game_container.style.display = "none";
} }
deactivate_setting()
{
this.setting_container.style.display = "none";
}
deactivate_control() deactivate_control()
{ {
this.control_container.style.display = "none"; this.control_container.style.display = "none";
@ -110,6 +150,7 @@ class Sidebar
if (gamemode == "none") if (gamemode == "none")
{ {
this.activate_create_game(); this.activate_create_game();
this.activate_setting();
this.deactivate_control(); this.deactivate_control();
this.activate_info(); this.activate_info();
return return
@ -117,6 +158,14 @@ class Sidebar
if (gamemode == "local") if (gamemode == "local")
{ {
this.deactivate_create_game(); 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_control();
this.activate_info(); this.activate_info();
} }

View File

@ -4,7 +4,7 @@ html, body {
body { body {
margin: 0; margin: 0;
background: rgb(70, 76, 92); background: rgb(30, 36, 119) ;
outline: 0; outline: 0;
position: relative; position: relative;
} }
@ -13,12 +13,12 @@ body {
--tictactoe_n: 3; --tictactoe_n: 3;
--button-margin: 0.5vh; --button-margin: 0.5vh;
--tile-size: calc((100vh / (var(--tictactoe_n) * var(--tictactoe_n))) - 2 * var(--button-margin)); --tile-size: calc((100vh / (var(--tictactoe_n) * var(--tictactoe_n))) - 2 * var(--button-margin));
--opacity: 0.2; --opacity: 1;
--border-radius: 1vh; --border-radius: 1vh;
--sidebar-width: 25vh; --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) ); --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: */ /* override settings on portrait mode: */
@ -28,7 +28,7 @@ body {
--button-margin: 0.5vw; --button-margin: 0.5vw;
--tile-size: calc((100vw / (var(--tictactoe_n) * var(--tictactoe_n))) - 2 * var(--button-margin)); --tile-size: calc((100vw / (var(--tictactoe_n) * var(--tictactoe_n))) - 2 * var(--button-margin));
--border-radius: 1vw; --border-radius: 1vw;
--sidebar-width: 40vw; --sidebar-width: calc(var(--board-size) - 2 * var(--border-radius));
--sidebar-height: 15vw; --sidebar-height: 15vw;
} }
@ -65,6 +65,7 @@ body {
height: calc(var(--tile-size) - (var(--button-margin) * 2)); height: calc(var(--tile-size) - (var(--button-margin) * 2));
display: inline-block; display: inline-block;
outline: 0; outline: 0;
font-size: calc(3 * var(--border-radius));
transition-duration: 0.1s; transition-duration: 0.1s;
} }
@ -87,7 +88,7 @@ body {
margin: var(--button-margin); margin: var(--button-margin);
width: calc(var(--tictactoe_n) * var(--tile-size)); width: calc(var(--tictactoe_n) * var(--tile-size));
height: 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; display: inline-block;
transition-duration: 0.5s; transition-duration: 0.5s;
} }
@ -98,7 +99,7 @@ body {
margin: var(--button-margin); margin: var(--button-margin);
width: calc(var(--tictactoe_n) * var(--tile-size)); width: calc(var(--tictactoe_n) * var(--tile-size));
height: 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; display: inline-block;
transition-duration: 0.5s; transition-duration: 0.5s;
} }
@ -107,11 +108,12 @@ body {
border-radius: var(--border-radius); border-radius: var(--border-radius);
padding: var(--border-radius); padding: var(--border-radius);
vertical-align: top; vertical-align: top;
background: rgba(0, 0, 0, var(--opacity)); background: rgba(255, 255, 255, 0.05);
display: inline-flex; display: inline-flex;
justify-content: space-between; justify-content: space-between;
flex-direction:column; flex-direction:column;
height: calc(var(--board-size) - 2 * var(--border-radius)); height: var(--sidebar-height);
width: var(--sidebar-width);
position: relative; position: relative;
transition-duration: 0.5s; transition-duration: 0.5s;
} }
@ -120,11 +122,8 @@ body {
@media (orientation: portrait) { @media (orientation: portrait) {
.sidebar-container { .sidebar-container {
display: inline-flex;
justify-content: space-between;
flex-direction:row; flex-direction:row;
height: var(--sidebar-height); padding: none;
width: calc(var(--board-size));
} }
} }
@ -138,6 +137,7 @@ body {
vertical-align: middle; vertical-align: middle;
} }
.control-container { .control-container {
border-radius: var(--border-radius); border-radius: var(--border-radius);
padding: var(--border-radius); padding: var(--border-radius);
@ -147,6 +147,16 @@ body {
vertical-align: middle; 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 { .info-container {
border-radius: var(--border-radius); border-radius: var(--border-radius);
padding: var(--border-radius); padding: var(--border-radius);
@ -162,6 +172,16 @@ body {
color: white; color: white;
display: flex; display: flex;
flex-direction: column; 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 { .sidebar-button {
@ -170,20 +190,54 @@ body {
border: none; border: none;
outline: 0; outline: 0;
transition-duration: 0.3s; transition-duration: 0.3s;
background: rgba(0, 0, 0, var(--opacity)); background: rgba(0, 0, 0, 0.5);
color: rgb(255, 255, 255); color: rgb(255, 255, 255);
font-size: calc(3 * var(--border-radius)); font-size: calc(3 * var(--border-radius));
width: var(--sidebar-width); height: calc(4 * var(--border-radius));
height: calc(5 * var(--border-radius)); width: calc(var(--sidebar-width) - 4 * var(--border-radius));
vertical-align: middle; vertical-align: middle;
display: flex; display: flex;
flex-direction: column; 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 { .sidebar-button:hover {
background: rgba(255, 255, 255, var(--opacity)); background: rgba(255, 255, 255, 0.2);
} }
.sidebar-button:active { .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));
}
} }

View File

@ -1,7 +1,5 @@
class Subgrid class Subgrid {
{ constructor(n, sub_x, sub_y, subgrid_container_div, tile_width, tile_height, ground_color) {
constructor(n, sub_x, sub_y,subgrid_container_div, tile_width, tile_height, ground_color)
{
this.n = n; this.n = n;
this.subgrid_container_div = subgrid_container_div; this.subgrid_container_div = subgrid_container_div;
this.tile_height = tile_height; this.tile_height = tile_height;
@ -9,27 +7,28 @@ class Subgrid
this.cells = []; this.cells = [];
this.won_player = null; this.won_player = null;
this.draw = false;
this.clicked_fields = 0;
this.sub_x = sub_x; this.sub_x = sub_x;
this.sub_y = sub_y; this.sub_y = sub_y;
this.ground_color = ground_color; this.ground_color = ground_color;
this.bgcolor = null;
this.create(); this.create();
this.block(); this.block();
console.log("new subgrid created"); console.log("new subgrid created");
} }
create() create() {
{ var x, y;
var x,y; for (y = 0; y < this.n; y++) {
for (y = 0; y < this.n; y++)
{
var div_row = this.subgrid_container_div.appendChild(document.createElement("div")); var div_row = this.subgrid_container_div.appendChild(document.createElement("div"));
var row = []; 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")); var div_button = div_row.appendChild(document.createElement("div"));
div_button.className = "grid-tile"; div_button.className = "grid-tile";
var button = document.createElement("button"); var button = document.createElement("button");
@ -42,73 +41,67 @@ class Subgrid
var b_h = this.tile_height; var b_h = this.tile_height;
row.push(new Tile(b_x, b_y, b_w, b_h, button, this.ground_color, div_button)); 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_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_unlock_request_callback((i, j) => this.unlock_request_listener(i, j));
} }
this.cells.push(row); this.cells.push(row);
} }
} }
register_click_callback(func) register_click_callback(func) {
{
this.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); this.click_callback(this.sub_x, this.sub_y, x, y);
} }
player_change_listener(player) player_change_listener(player) {
{ var x, y;
var x,y; for (y = 0; y < this.n; y++) {
for (y = 0; y < this.n; y++) for (x = 0; x < this.n; x++) {
{
for (x = 0; x < this.n; x++)
{
this.cells[y][x].player_change_listener(player); this.cells[y][x].player_change_listener(player);
} }
} }
} }
unlock_request_listener(x,y) unlock_request_listener(x, y) {
{
// TODO: unused so far // TODO: unused so far
//return this.unlock_request_callback(x,y); //return this.unlock_request_callback(x,y);
return false; return false;
} }
is_won() is_won() {
{
return this.won_player != null; return this.won_player != null;
} }
get_won_player() is_draw() {
{ return this.draw;
}
get_won_player() {
return this.won_player; return this.won_player;
} }
check_win(x,y) check_win(x, y) {
{
// check whether this subfield is won // check whether this subfield is won
if (this.won_player == null) if (this.won_player == null) {
{
var i; var i;
var player = this.cells[y][x].get_activated_player(); var player = this.cells[y][x].get_activated_player();
// check column // check column
var is_col = true; var is_col = true;
for (i = 0; i < this.n; i++) 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()) {
if (!this.cells[i][x].get_is_activated() || player.get_id() != this.cells[i][x].get_activated_player().get_id())
{
is_col = false; is_col = false;
break; break;
} }
@ -116,10 +109,8 @@ class Subgrid
// check row // check row
var is_row = true; var is_row = true;
for (i = 0; i < this.n; i++) 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()) {
if (!this.cells[y][i].get_is_activated() || player.get_id() != this.cells[y][i].get_activated_player().get_id())
{
is_row = false; is_row = false;
break; break;
} }
@ -129,13 +120,10 @@ class Subgrid
// main diag // main diag
var is_main_diag = false; var is_main_diag = false;
if (x == y) if (x == y) {
{
is_main_diag = true; is_main_diag = true;
for (i = 0; i < this.n; i++) 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()) {
if (!this.cells[i][i].get_is_activated() || player.get_id() != this.cells[i][i].get_activated_player().get_id())
{
is_main_diag = false; is_main_diag = false;
break; break;
} }
@ -144,89 +132,86 @@ class Subgrid
// secundary diag // secundary diag
var is_sec_diag = false; var is_sec_diag = false;
if (x + y == this.n - 1) if (x + y == this.n - 1) {
{
is_sec_diag = true; is_sec_diag = true;
for (i = 0; i < this.n; i++) 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()) {
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; is_sec_diag = false;
break; 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.won_player = player;
this.subgrid_container_div.style.backgroundColor = player.get_color(); this.bgcolor = player.get_color_values();
} }
} }
} }
activate_all() check_draw() {
{ this.draw = (!(this.clicked_fields < this.n * this.n));
var x,y; }
for (y = 0; y < this.n; y++)
{ activate_all() {
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].activate(); this.cells[y][x].activate();
} }
} }
} }
deactivate_all() deactivate_all() {
{ var x, y;
var x,y; for (y = 0; y < this.n; y++) {
for (y = 0; y < this.n; y++) for (x = 0; x < this.n; x++) {
{
for (x = 0; x < this.n; x++)
{
this.cells[y][x].deactivate(); this.cells[y][x].deactivate();
} }
} }
this.won_player = null; this.won_player = null;
this.draw = false;
this.clicked_fields = 0;
this.subgrid_container_div.style.backgroundColor = ""; // reset to css color this.subgrid_container_div.style.backgroundColor = ""; // reset to css color
} }
block() block() {
{ var x, y;
var x,y; for (y = 0; y < this.n; y++) {
for (y = 0; y < this.n; y++) for (x = 0; x < this.n; x++) {
{
for (x = 0; x < this.n; x++)
{
this.cells[y][x].lock(); this.cells[y][x].lock();
} }
} }
this.subgrid_container_div.className = "subgrid-container"; 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() unblock() {
{ var x, y;
var x,y; for (y = 0; y < this.n; y++) {
for (y = 0; y < this.n; y++) for (x = 0; x < this.n; x++) {
{
for (x = 0; x < this.n; x++)
{
this.cells[y][x].unlock(); this.cells[y][x].unlock();
} }
} }
this.subgrid_container_div.className = "subgrid-container-activated"; 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_width = tile_w;
this.tile_h = tile_h; this.tile_h = tile_h;
var x,y; var x, y;
for (y = 0; y < this.n; y++) for (y = 0; y < this.n; y++) {
{ for (x = 0; x < this.n; x++) {
for (x = 0; x < this.n; x++)
{
this.cells[y][x].update_css_transform(tile_w, tile_h); this.cells[y][x].update_css_transform(tile_w, tile_h);
} }
} }

19
tile.js
View File

@ -23,6 +23,11 @@ class Tile
this.reset(); this.reset();
this.bind(); this.bind();
this.opacity_off = 0.5;
this.opacity_select = 0.6;
this.opacity_on = 1;
} }
update_css_transform(w,h) update_css_transform(w,h)
@ -76,13 +81,13 @@ class Tile
lock() lock()
{ {
this.locked = true; this.locked = true;
this.elem.style.opacity = 0.3; this.elem.style.opacity = this.opacity_off;
} }
unlock() unlock()
{ {
this.locked = false; this.locked = false;
this.elem.style.opacity = 0.5; this.elem.style.opacity = this.opacity_off;
} }
deactivate() deactivate()
@ -90,7 +95,7 @@ class Tile
this.is_activated = false; this.is_activated = false;
this.activated_player = null; this.activated_player = null;
this.elem.style.background = this.ground_color; 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"; this.elem.style.border = "none";
} }
@ -99,7 +104,7 @@ class Tile
this.is_activated = true; this.is_activated = true;
this.activated_player = this.player; this.activated_player = this.player;
this.elem.style.background = this.player.get_color(); 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)"; this.elem.style.border = "2px solid rgba(255,255,255,0.3)";
} }
@ -108,7 +113,7 @@ class Tile
if (!this.is_activated && !this.locked) if (!this.is_activated && !this.locked)
{ {
this.elem.style.background = this.player.get_color(); 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)"; 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; this.elem.style.background = this.ground_color;
if (this.locked) if (this.locked)
{ {
this.elem.style.opacity = 0.3; this.elem.style.opacity = this.opacity_off;
} }
else else
{ {
this.elem.style.opacity = 0.5; this.elem.style.opacity = this.opacity_select;
} }
this.elem.style.border = "none"; this.elem.style.border = "none";
} }