Basic turn structure
This commit is contained in:
130
static/game.html
130
static/game.html
@@ -23,18 +23,25 @@
|
||||
|
||||
.player-area {
|
||||
display: grid;
|
||||
grid-template-columns: 100px auto 100px;
|
||||
border: 1px solid black;
|
||||
grid-template-columns: 100px auto 90px;
|
||||
grid-template-rows: auto auto;
|
||||
width: 100%;
|
||||
height: 145px;
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
grid-gap: 10px;
|
||||
}
|
||||
|
||||
.player-area .buttons {
|
||||
grid-column-start: 3;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.card {
|
||||
position: relative;
|
||||
width: 90px;
|
||||
margin: 1px;
|
||||
height: 144px;
|
||||
}
|
||||
|
||||
.player-hand {
|
||||
@@ -45,6 +52,10 @@
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.player-hand img.card:hover {
|
||||
box-shadow: 0 0 5px blue;
|
||||
}
|
||||
|
||||
.chat-window {
|
||||
border: 1px solid black;
|
||||
width: 300px;
|
||||
@@ -89,15 +100,36 @@
|
||||
}
|
||||
|
||||
.setup-screen {
|
||||
}
|
||||
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.discard-pile {
|
||||
width: 90px;
|
||||
border: 1px dotted green;
|
||||
height: 145px;
|
||||
height: 144px;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.discard-pile img.card {
|
||||
margin-top: -1px;
|
||||
margin-left: -1px;
|
||||
}
|
||||
|
||||
.discard-pile::after {
|
||||
color: dimgray;
|
||||
content: "Discard Pile";
|
||||
font-size: 14px;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
white-space: nowrap;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
.inplay-area {
|
||||
width: 100%;
|
||||
@@ -136,7 +168,6 @@
|
||||
}
|
||||
|
||||
.opponent-area {
|
||||
height: 180px;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
@@ -148,6 +179,7 @@
|
||||
border: 1px solid saddlebrown;
|
||||
display: grid;
|
||||
grid-gap: 2px;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
.opponent-status.active {
|
||||
@@ -206,7 +238,9 @@
|
||||
view: function(vnode) {
|
||||
return m(".chat-window",
|
||||
m("h4", "Players"),
|
||||
m("ul", m("li", "Markus (you)")),
|
||||
m("ul", vnode.attrs.players.map(function(p) {
|
||||
return m("li", p.name);
|
||||
})),
|
||||
m("h4", "Messages"),
|
||||
m("ul", {id: "chat"}),
|
||||
m("input", {
|
||||
@@ -248,7 +282,11 @@
|
||||
function DiscardPile(initialVnode) {
|
||||
return {
|
||||
view: function(vnode) {
|
||||
return m(".discard-pile", "Discard Pile")
|
||||
var c;
|
||||
if (vnode.attrs.card) {
|
||||
c = m("img", {class: "card", src: "/static/images/cards/" + vnode.attrs.card.toLowerCase() + ".jpg"});
|
||||
}
|
||||
return m(".discard-pile", c)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -304,12 +342,21 @@
|
||||
}
|
||||
|
||||
function PlayerArea(initialVnode) {
|
||||
var end_turn_click = function(e) {
|
||||
var msg = { type: "EndTurn" };
|
||||
webSocket.send(JSON.stringify(msg));
|
||||
}
|
||||
|
||||
return {
|
||||
view: function(vnode) {
|
||||
var local_player = vnode.attrs.players[my_player_id];
|
||||
return m(".player-area",
|
||||
m(DrawPile, {count: vnode.attrs.player_drawpile_count}),
|
||||
m(DrawPile, {count: local_player.draw_pile_count}),
|
||||
m(PlayerHand, vnode.attrs.player),
|
||||
m(DiscardPile)
|
||||
m(DiscardPile, {card: local_player.discard_pile}),
|
||||
m(".buttons",
|
||||
m("button", {onclick: end_turn_click}, "Pass turn")
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -318,10 +365,10 @@
|
||||
function OpponentStatus(initialVnode) {
|
||||
return {
|
||||
view: function(vnode) {
|
||||
var active = vnode.attrs.active ? "active" : "";
|
||||
var active = vnode.attrs.id == game_state.active_player ? "active" : "";
|
||||
return m(".opponent-status", {class: active },
|
||||
m(".name", vnode.attrs.name),
|
||||
m(DiscardPile),
|
||||
m(DiscardPile, {card: vnode.attrs.discard_pile}),
|
||||
m(DrawPile, {count: vnode.attrs.draw_pile_count}),
|
||||
m(OpponentHand, {count: vnode.attrs.hand_count })
|
||||
)
|
||||
@@ -333,8 +380,10 @@
|
||||
return {
|
||||
view: function(vnode) {
|
||||
return m(".opponent-area",
|
||||
vnode.attrs.opponents.map(function(o) {
|
||||
return m(OpponentStatus, o)
|
||||
vnode.attrs.players
|
||||
.filter((p, i) => i != my_player_id)
|
||||
.map(function(o) {
|
||||
return m(OpponentStatus, o)
|
||||
})
|
||||
)
|
||||
}
|
||||
@@ -344,7 +393,8 @@
|
||||
function GameScreen(initialVnode) {
|
||||
return {
|
||||
view: function(vnode) {
|
||||
return m(".game-screen",
|
||||
var cls = vnode.attrs.active ? "" : "hidden";
|
||||
return m(".game-screen", {class: cls},
|
||||
m(OpponentArea, vnode.attrs),
|
||||
m(InPlayArea, vnode.attrs.opponent_turn_state),
|
||||
m(SupplyArea, vnode.attrs),
|
||||
@@ -358,16 +408,15 @@
|
||||
|
||||
function SetupScreen(initialVnode) {
|
||||
var start_click = function(e) {
|
||||
console.log("start_click", e);
|
||||
|
||||
let msg = { id: "start_game" };
|
||||
let msg = { type: "StartGame" };
|
||||
initialVnode.attrs.socket.send(JSON.stringify(msg));
|
||||
}
|
||||
|
||||
|
||||
return {
|
||||
view: function(vnode) {
|
||||
return m(".setup-screen",
|
||||
var cls = vnode.attrs.active ? "" : "hidden";
|
||||
return m(".setup-screen", {class: cls},
|
||||
m("h3", "Setup"),
|
||||
m("h4", "Basic cards"),
|
||||
m(".basic-cards",
|
||||
@@ -394,6 +443,9 @@
|
||||
}
|
||||
|
||||
var game_state;
|
||||
var setup_state;
|
||||
var my_player_id = 0;
|
||||
var webSocket;
|
||||
|
||||
function App(initialVnode) {
|
||||
if (document.location.protocol == "https:") {
|
||||
@@ -401,9 +453,9 @@
|
||||
} else {
|
||||
url = document.location.href.replace("http://", "ws://") + "/ws";
|
||||
}
|
||||
const webSocket = new WebSocket(url);
|
||||
webSocket = new WebSocket(url);
|
||||
|
||||
var setup_state = {
|
||||
setup_state = {
|
||||
starting_deck: [],
|
||||
basic_cards: ["Copper", "Silver", "Gold", "Estate", "Duchery", "Province", "Curse"],
|
||||
kingdom_cards: ["Cellar", "Moat", "Village", "Merchant", "Workshop", "Smithy", "Remodel", "Militia", "Market", "Mine"],
|
||||
@@ -414,7 +466,7 @@
|
||||
setup_state.starting_deck = data.deck;
|
||||
}
|
||||
|
||||
game_state = {
|
||||
game_state = {
|
||||
supply: [
|
||||
{ name: "Copper", count: 46 },
|
||||
{ name: "Silver", count: 38 },
|
||||
@@ -448,16 +500,19 @@
|
||||
coin: 0,
|
||||
active: true
|
||||
},
|
||||
player_drawpile_count: 10,
|
||||
player: {
|
||||
hand: []
|
||||
},
|
||||
opponents: [
|
||||
players: [
|
||||
{
|
||||
name: "YOU",
|
||||
draw_pile_count: 10,
|
||||
hand_count: 0
|
||||
},
|
||||
{
|
||||
name: "Alice",
|
||||
draw_pile_count: 10,
|
||||
hand_count: 5,
|
||||
active: true
|
||||
},
|
||||
{
|
||||
name: "Bob",
|
||||
@@ -469,13 +524,34 @@
|
||||
draw_pile_count: 10,
|
||||
hand_count: 3
|
||||
}
|
||||
]
|
||||
],
|
||||
active_player: 0
|
||||
}
|
||||
|
||||
var chat_state = {
|
||||
players: [],
|
||||
socket: webSocket
|
||||
}
|
||||
|
||||
var handle_game_state = function(state) {
|
||||
game_state = {
|
||||
...game_state,
|
||||
...state,
|
||||
};
|
||||
game_state.opponent_turn_state.active = game_state.active_player != my_player_id;
|
||||
game_state.player_turn_state.active = game_state.active_player == my_player_id;
|
||||
chat_state.players = state.players;
|
||||
|
||||
if (state.state == "Setup") {
|
||||
setup_state.active = true;
|
||||
game_state.active = false;
|
||||
} else {
|
||||
setup_state.active = false;
|
||||
game_state.active = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
webSocket.onopen = function(event) {
|
||||
console.log("ws open");
|
||||
//webSocket.send("HALLO");
|
||||
@@ -496,8 +572,12 @@
|
||||
newmsg.innerHTML = msg.player + " joined the game.";
|
||||
chatDiv.append(newmsg);
|
||||
//newmsg.scrollIntoView();
|
||||
} else if (msg.id == "setup") {
|
||||
} else if (msg.type == "GameState") {
|
||||
handle_game_state(msg);
|
||||
} else if (msg.type == "GameSetup") {
|
||||
handle_setup(msg.setup);
|
||||
} else if (msg.type == "PlayerHand") {
|
||||
game_state.player.hand = msg.hand;
|
||||
} else {
|
||||
console.log("event?");
|
||||
console.log(event.data);
|
||||
|
@@ -11,6 +11,7 @@
|
||||
<div>
|
||||
<form id="login_form" method="post" action="/game">
|
||||
Your name: <input type="text" name="name"> <br />
|
||||
<input type="hidden" name="type" value="CreateGame">
|
||||
<input type="submit" value="Create game">
|
||||
</form>
|
||||
</div>
|
||||
|
Reference in New Issue
Block a user