Skip to content

Commit 0a39858

Browse files
authored
Client (#90)
* fix build * glcanvas is already present * screen size * minimize * add test * screen size * cleanup * use primitives directly * avoid option in actions because mongo strips null values * cleanup * cleanup * cleanup * cleanup
1 parent bec0b9e commit 0a39858

File tree

69 files changed

+1581
-310
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

69 files changed

+1581
-310
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020
- `cd server`
2121
- `cargo install wasm-pack` (if you haven't already)
22-
- `./build-wasm.sh`
22+
- `./build-remote-server.sh`
2323

2424
# Notes
2525

client/Cargo.lock

+2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

client/Cargo.toml

+2
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ log = "0.4.20"
2727
async-std = "1.13.0"
2828
serde-wasm-bindgen = "0.6.5"
2929
console_error_panic_hook = "0.1.7"
30+
web-sys = { version = "0.3.72", features = ["Window"] }
31+
js-sys = "0.3.72"
3032

3133
[[bin]]
3234
name = "local_client"

client/js/src/control.js

+4-3
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@ export class Control extends EventEmitter {
4444
this.emit("ready");
4545
}
4646

47+
get canvas_size() {
48+
return document.getElementById("glcanvas").getBoundingClientRect();
49+
}
50+
4751
get assets_url() {
4852
return this._assets_url;
4953
}
@@ -53,9 +57,6 @@ export class Control extends EventEmitter {
5357
}
5458
}
5559

56-
export function get_control() {
57-
return window.clash_control;
58-
}
5960

6061

6162

client/js/src/run.js

+19-27
Original file line numberDiff line numberDiff line change
@@ -9,32 +9,24 @@ function dynamicallyLoadScript(url, onload) {
99
}
1010

1111
export async function run({selector, control}) {
12-
const root = document.querySelector(selector);
13-
const canvas = document.createElement("canvas");
14-
canvas.setAttribute("id", "glcanvas");
15-
canvas.setAttribute("style", `
16-
margin: 0px;
17-
padding: 0px;
18-
width: 100%;
19-
height: 100%;
20-
overflow: hidden;
21-
position: absolute;
22-
z-index: 0;
23-
`);
24-
root.appendChild(canvas);
25-
26-
dynamicallyLoadScript("https://not-fl3.github.io/miniquad-samples/mq_js_bundle.js", async () => {
2712
let wbg = await init();
28-
miniquad_add_plugin({
29-
register_plugin: (a) => (a.wbg = wbg),
30-
on_init: () => set_wasm(wasm_exports),
31-
version: "0.0.1",
32-
name: "wbg",
33-
});
34-
const src = document.head.getElementsByTagName("script")[0].src;
35-
control.assets_url = src.replace("client.js", "assets/");
36-
const url = src.replace("client.js", "client.wasm");
37-
console.log("Loading wasm from", url);
38-
await load(url);
39-
});
13+
miniquad_add_plugin({
14+
register_plugin: (a) => {
15+
console.log("register_plugin", a);
16+
return (a.wbg = wbg)
17+
},
18+
on_init: () => {
19+
console.log("on_init", wasm_exports);
20+
window.clash_control.send_ready()
21+
return set_wasm(wasm_exports)
22+
},
23+
version: "0.0.1",
24+
name: "wbg",
25+
});
26+
const src = document.body.getElementsByTagName("script")[1].src;
27+
control.assets_url = src.replace("client.js", "assets/");
28+
const url = src.replace("client.js", "client.wasm");
29+
console.log("Loading wasm from", url);
30+
await load(url);
31+
console.log("Loaded wasm");
4032
}

client/js/webpack.config.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ module.exports = {
66
}, resolve: {
77
fallback: {"events": require.resolve("events/")}
88
}, optimization: {
9-
minimize: false
9+
minimize: true
1010
},
1111
};
1212

client/src/client.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@ use crate::status_phase_ui::raze_city_confirm_dialog;
2121
use crate::{combat_ui, dialog_ui, influence_ui, move_ui, recruit_unit_ui, status_phase_ui};
2222

2323
pub async fn init(features: &Features) -> State {
24-
State::new(features).await
24+
let state = State::new(features).await;
25+
root_ui().push_skin(&state.assets.skin);
26+
state
2527
}
2628

2729
pub fn render_and_update(
@@ -45,13 +47,14 @@ pub fn render_and_update(
4547
}
4648

4749
fn render(game: &Game, state: &mut State, features: &Features) -> StateUpdate {
48-
root_ui().push_skin(&state.assets.skin);
4950
clear_background(BLACK);
5051

5152
let player = &state.shown_player(game);
5253

54+
let s = state.screen_size;
55+
5356
state.camera = Camera2D {
54-
zoom: vec2(state.zoom, state.zoom * screen_width() / screen_height()),
57+
zoom: vec2(state.zoom, state.zoom * s.x / s.y),
5558
offset: state.offset,
5659
..Default::default()
5760
};

client/src/client_state.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,7 @@ pub struct ShownPlayer {
221221
pub can_play_action: bool,
222222
pub active_dialog: ActiveDialog,
223223
pub pending_update: bool,
224+
pub screen_size: Vec2,
224225
}
225226

226227
impl ShownPlayer {
@@ -239,6 +240,7 @@ pub struct State {
239240
pub camera: Camera2D,
240241
pub zoom: f32,
241242
pub offset: Vec2,
243+
pub screen_size: Vec2,
242244
}
243245

244246
pub const ZOOM: f32 = 0.001;
@@ -257,6 +259,7 @@ impl State {
257259
},
258260
zoom: ZOOM,
259261
offset: OFFSET,
262+
screen_size: vec2(0., 0.),
260263
}
261264
}
262265

@@ -270,6 +273,7 @@ impl State {
270273
can_play_action: control && game.state == GameState::Playing && game.actions_left > 0,
271274
active_dialog: self.active_dialog.clone(),
272275
pending_update: self.pending_update.is_some(),
276+
screen_size: self.screen_size,
273277
}
274278
}
275279

@@ -374,7 +378,7 @@ impl State {
374378
GameState::StatusPhase(state) => match state {
375379
StatusPhaseState::CompleteObjectives => ActiveDialog::CompleteObjectives,
376380
StatusPhaseState::FreeAdvance => ActiveDialog::FreeAdvance,
377-
StatusPhaseState::RaseSize1City => ActiveDialog::RazeSize1City,
381+
StatusPhaseState::RazeSize1City => ActiveDialog::RazeSize1City,
378382
StatusPhaseState::ChangeGovernmentType => ActiveDialog::ChangeGovernmentType,
379383
StatusPhaseState::DetermineFirstPlayer => ActiveDialog::DetermineFirstPlayer,
380384
},

client/src/combat_ui.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use server::action::{Action, CombatAction};
1+
use server::action::{Action, CombatAction, PlayActionCard};
22
use server::game::Game;
33
use server::position::Position;
44
use server::unit::Unit;
@@ -105,7 +105,9 @@ pub fn remove_casualties_dialog(
105105
pub fn play_action_card_dialog(player: &ShownPlayer) -> StateUpdate {
106106
active_dialog_window(player, "Play action card", |ui| {
107107
if ui.button(None, "None") {
108-
return StateUpdate::Execute(Action::Combat(CombatAction::PlayActionCard(None)));
108+
return StateUpdate::Execute(Action::Combat(CombatAction::PlayActionCard(
109+
PlayActionCard::None,
110+
)));
109111
}
110112
StateUpdate::None
111113
})

client/src/construct_ui.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use server::city_pieces::Building;
1010
use server::content::custom_actions::CustomAction;
1111
use server::game::Game;
1212
use server::map::{Map, Terrain};
13-
use server::playing_actions::PlayingAction;
13+
use server::playing_actions::{Construct, PlayingAction};
1414
use server::position::Position;
1515
use server::resource_pile::PaymentOptions;
1616
use server::unit::UnitType;
@@ -106,13 +106,13 @@ pub fn pay_construction_dialog(
106106
|cp| cp.payment.get(ResourceType::Discount).selectable.current == 0,
107107
|cp| match &cp.project {
108108
ConstructionProject::Building(b, pos) => StateUpdate::execute_activation(
109-
Action::Playing(PlayingAction::Construct {
109+
Action::Playing(PlayingAction::Construct(Construct {
110110
city_position: cp.city_position,
111111
city_piece: b.clone(),
112112
payment: cp.payment.to_resource_pile(),
113113
port_position: *pos,
114114
temple_bonus: None,
115-
}),
115+
})),
116116
vec![],
117117
game.get_any_city(cp.city_position).unwrap(),
118118
),

client/src/dialog_ui.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,8 @@ use crate::client_state::{PendingUpdate, ShownPlayer, StateUpdate};
22
use crate::layout_ui::{cancel_pos, ok_only_pos, ok_pos};
33
use macroquad::hash;
44
use macroquad::math::{vec2, Vec2};
5-
use macroquad::prelude::screen_height;
65
use macroquad::ui::widgets::Window;
76
use macroquad::ui::{root_ui, Ui};
8-
use macroquad::window::screen_width;
97

108
pub fn active_dialog_window<F>(player: &ShownPlayer, title: &str, f: F) -> StateUpdate
119
where
@@ -24,11 +22,12 @@ pub fn dialog<F>(player: &ShownPlayer, title: &str, f: F) -> StateUpdate
2422
where
2523
F: FnOnce(&mut Ui) -> StateUpdate,
2624
{
27-
let width = screen_width() - 20.;
25+
let size = player.screen_size;
26+
let width = size.x - 20.;
2827
let size = if player.active_dialog.is_map_dialog() {
2928
vec2(width / 2.0, 270.)
3029
} else {
31-
vec2(width, screen_height() - 40.)
30+
vec2(width, size.y - 40.)
3231
};
3332
custom_dialog(title, vec2(10., 10.), size, f)
3433
}

client/src/layout_ui.rs

+27-18
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,58 @@
11
use crate::client_state::ShownPlayer;
22
use macroquad::math::{vec2, Vec2};
3-
use macroquad::prelude::screen_height;
43
use macroquad::ui::root_ui;
5-
use macroquad::window::screen_width;
64

75
pub fn top_left_label(p: Vec2, label: &str) {
86
root_ui().label(p, label);
97
}
108

11-
pub fn top_center_label(p: Vec2, label: &str) {
12-
root_ui().label(vec2(screen_width() / 2.0, 0.) + p, label);
9+
pub fn top_center_label(player: &ShownPlayer, p: Vec2, label: &str) {
10+
root_ui().label(vec2(player.screen_size.x / 2.0, 0.) + p, label);
1311
}
1412

15-
pub fn right_center_label(p: Vec2, label: &str) {
16-
root_ui().label(vec2(screen_width(), screen_height() / 2.0) + p, label);
13+
pub fn right_center_label(player: &ShownPlayer, p: Vec2, label: &str) {
14+
root_ui().label(
15+
vec2(player.screen_size.x, player.screen_size.y / 2.0) + p,
16+
label,
17+
);
1718
}
1819

19-
pub fn right_center_button(p: Vec2, label: &str) -> bool {
20-
root_ui().button(vec2(screen_width(), screen_height() / 2.0) + p, label)
20+
pub fn right_center_button(player: &ShownPlayer, p: Vec2, label: &str) -> bool {
21+
root_ui().button(
22+
vec2(player.screen_size.x, player.screen_size.y / 2.0) + p,
23+
label,
24+
)
2125
}
2226

23-
pub fn bottom_left_button(p: Vec2, label: &str) -> bool {
24-
root_ui().button(vec2(0., screen_height()) + p, label)
27+
pub fn bottom_left_button(player: &ShownPlayer, p: Vec2, label: &str) -> bool {
28+
root_ui().button(vec2(0., player.screen_size.y) + p, label)
2529
}
2630

27-
pub fn bottom_right_button(p: Vec2, label: &str) -> bool {
28-
root_ui().button(vec2(screen_width(), screen_height()) + p, label)
31+
pub fn bottom_right_button(player: &ShownPlayer, p: Vec2, label: &str) -> bool {
32+
root_ui().button(vec2(player.screen_size.x, player.screen_size.y) + p, label)
2933
}
3034

3135
pub fn cancel_pos(player: &ShownPlayer) -> Vec2 {
3236
small_dialog(player)
33-
.then(|| Vec2::new(screen_width() / 4.0, 190.))
34-
.unwrap_or_else(|| Vec2::new(screen_width() / 2., screen_height() - 130.))
37+
.then(|| Vec2::new(player.screen_size.x / 4.0, 190.))
38+
.unwrap_or_else(|| Vec2::new(player.screen_size.x / 2., player.screen_size.y - 130.))
3539
}
3640

3741
pub fn ok_pos(player: &ShownPlayer) -> Vec2 {
3842
small_dialog(player)
39-
.then(|| Vec2::new(screen_width() / 4.0 - 150., 190.))
40-
.unwrap_or_else(|| Vec2::new(screen_width() / 2. - 150., screen_height() - 130.))
43+
.then(|| Vec2::new(player.screen_size.x / 4.0 - 150., 190.))
44+
.unwrap_or_else(|| {
45+
Vec2::new(
46+
player.screen_size.x / 2. - 150.,
47+
player.screen_size.y - 130.,
48+
)
49+
})
4150
}
4251

4352
pub fn ok_only_pos(player: &ShownPlayer) -> Vec2 {
4453
small_dialog(player)
45-
.then(|| Vec2::new(screen_width() / 4.0 - 75., 190.))
46-
.unwrap_or_else(|| Vec2::new(screen_width() / 2. - 75., screen_height() - 130.))
54+
.then(|| Vec2::new(player.screen_size.x / 4.0 - 75., 190.))
55+
.unwrap_or_else(|| Vec2::new(player.screen_size.x / 2. - 75., player.screen_size.y - 130.))
4756
}
4857

4958
fn small_dialog(player: &ShownPlayer) -> bool {

client/src/local_client/bin/main.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22

33
use client::client::{init, render_and_update, Features, GameSyncRequest, GameSyncResult};
44
use macroquad::miniquad::window::set_window_size;
5-
use macroquad::prelude::next_frame;
5+
use macroquad::prelude::{next_frame, screen_width, vec2};
6+
use macroquad::window::screen_height;
67
use server::city::City;
78
use server::game::{Game, GameData};
89
use server::leader::Leader;
@@ -39,6 +40,7 @@ pub async fn run(mut game: Game, features: &Features) {
3940
state.show_player = game.active_player();
4041
loop {
4142
state.control_player = Some(game.active_player());
43+
state.screen_size = vec2(screen_width(), screen_height());
4244

4345
let message = render_and_update(&game, &mut state, &sync_result, features);
4446
sync_result = GameSyncResult::None;

0 commit comments

Comments
 (0)