Compare commits
3 Commits
129e9ccc5e
...
7837ab49b0
| Author | SHA1 | Date | |
|---|---|---|---|
| 7837ab49b0 | |||
| 62c84aceaf | |||
| 7ac3882e9e |
@@ -8,7 +8,10 @@ use bevy::{
|
|||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use tungstenite::{WebSocket, http::Response, stream::MaybeTlsStream};
|
use tungstenite::{WebSocket, http::Response, stream::MaybeTlsStream};
|
||||||
|
|
||||||
use crate::ui::{despawn_main_menu, spawn_main_menu};
|
use crate::ui::{
|
||||||
|
despawn_connection_wait_screen, despawn_main_menu, spawn_connection_wait_screen,
|
||||||
|
spawn_main_menu,
|
||||||
|
};
|
||||||
|
|
||||||
mod ui;
|
mod ui;
|
||||||
|
|
||||||
@@ -23,8 +26,24 @@ fn main() {
|
|||||||
.add_systems(OnExit(GameState::MainMenu), despawn_main_menu)
|
.add_systems(OnExit(GameState::MainMenu), despawn_main_menu)
|
||||||
.add_observer(ui::button_hover_start)
|
.add_observer(ui::button_hover_start)
|
||||||
.add_observer(ui::button_hover_stop)
|
.add_observer(ui::button_hover_stop)
|
||||||
// TODO: System to operate buttons & other UI widgets
|
.add_systems(
|
||||||
// .add_systems(Update, )
|
OnEnter(GameState::Connecting),
|
||||||
|
(
|
||||||
|
spawn_connection_wait_screen,
|
||||||
|
// Closure to immediately dispatch a setup-connection request.
|
||||||
|
|mut messages: MessageWriter<WebSocketConnectionMessage>| {
|
||||||
|
messages.write(WebSocketConnectionMessage::SetupConnection);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.add_systems(
|
||||||
|
OnExit(GameState::Connecting),
|
||||||
|
despawn_connection_wait_screen,
|
||||||
|
)
|
||||||
|
.add_systems(
|
||||||
|
Update,
|
||||||
|
(setup_connection, handle_tasks).run_if(in_state(GameState::Connecting)),
|
||||||
|
)
|
||||||
.add_systems(OnEnter(GameState::Playing), setup_game)
|
.add_systems(OnEnter(GameState::Playing), setup_game)
|
||||||
.add_systems(
|
.add_systems(
|
||||||
Update,
|
Update,
|
||||||
@@ -48,6 +67,7 @@ fn main() {
|
|||||||
#[derive(Clone, Debug, Eq, Hash, PartialEq, States)]
|
#[derive(Clone, Debug, Eq, Hash, PartialEq, States)]
|
||||||
enum GameState {
|
enum GameState {
|
||||||
MainMenu,
|
MainMenu,
|
||||||
|
Connecting,
|
||||||
Playing,
|
Playing,
|
||||||
ConnectionDemo, // TODO: Remove this state.
|
ConnectionDemo, // TODO: Remove this state.
|
||||||
}
|
}
|
||||||
@@ -76,6 +96,7 @@ fn setup_game(
|
|||||||
) {
|
) {
|
||||||
// ball
|
// ball
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
|
Ball,
|
||||||
Mesh2d(meshes.add(Circle::new(10.0))),
|
Mesh2d(meshes.add(Circle::new(10.0))),
|
||||||
MeshMaterial2d(materials.add(Color::srgb(1.0, 0.0, 0.0))),
|
MeshMaterial2d(materials.add(Color::srgb(1.0, 0.0, 0.0))),
|
||||||
Transform::default(),
|
Transform::default(),
|
||||||
@@ -85,23 +106,32 @@ fn setup_game(
|
|||||||
let paddle_material = materials.add(Color::WHITE);
|
let paddle_material = materials.add(Color::WHITE);
|
||||||
// Player 1
|
// Player 1
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
// TODO: Marker component for player
|
Paddle,
|
||||||
// Maybe one for each player?
|
|
||||||
// Maybe it can hold the WebSocket, too.
|
|
||||||
// *Maybe* I can have one struct with an Option<Ws> to know which
|
|
||||||
// player is the local one (the one with a socket).
|
|
||||||
Mesh2d(paddle_mesh.clone()),
|
Mesh2d(paddle_mesh.clone()),
|
||||||
MeshMaterial2d(paddle_material.clone()),
|
MeshMaterial2d(paddle_material.clone()),
|
||||||
Transform::from_xyz(-window.width() / 2.0 + PADDLE_GAP, 0.0, 1.0),
|
Transform::from_xyz(-window.width() / 2.0 + PADDLE_GAP, 0.0, 1.0),
|
||||||
));
|
));
|
||||||
// Player 2
|
// Player 2
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
|
Paddle,
|
||||||
Mesh2d(paddle_mesh),
|
Mesh2d(paddle_mesh),
|
||||||
MeshMaterial2d(paddle_material),
|
MeshMaterial2d(paddle_material),
|
||||||
Transform::from_xyz(window.width() / 2.0 - PADDLE_GAP, 0.0, 1.0),
|
Transform::from_xyz(window.width() / 2.0 - PADDLE_GAP, 0.0, 1.0),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Component)]
|
||||||
|
struct Ball;
|
||||||
|
|
||||||
|
/// Marker component for player paddles
|
||||||
|
///
|
||||||
|
/// Maybe one for each player?
|
||||||
|
/// Maybe it can hold the WebSocket, too.
|
||||||
|
/// *Maybe* I can have one struct with an Option<Ws> to know which
|
||||||
|
/// player is the local one (the one with a socket).
|
||||||
|
#[derive(Component)]
|
||||||
|
struct Paddle;
|
||||||
|
|
||||||
/// ECS Component to hold the WebSocket. I guess there's going to be a magic
|
/// ECS Component to hold the WebSocket. I guess there's going to be a magic
|
||||||
/// entity that controls the networking.
|
/// entity that controls the networking.
|
||||||
#[derive(Component)]
|
#[derive(Component)]
|
||||||
@@ -208,12 +238,17 @@ fn setup_connection(
|
|||||||
///
|
///
|
||||||
/// The task is self-removing, so we don't need to delete the [`WsSetupTask`]
|
/// The task is self-removing, so we don't need to delete the [`WsSetupTask`]
|
||||||
/// component here.
|
/// component here.
|
||||||
fn handle_tasks(mut commands: Commands, mut transform_tasks: Query<&mut WsSetupTask>) {
|
fn handle_tasks(
|
||||||
|
mut commands: Commands,
|
||||||
|
mut transform_tasks: Query<&mut WsSetupTask>,
|
||||||
|
mut states: ResMut<NextState<GameState>>,
|
||||||
|
) {
|
||||||
for mut task in &mut transform_tasks {
|
for mut task in &mut transform_tasks {
|
||||||
if let Some(result) = block_on(future::poll_once(&mut task.0)) {
|
if let Some(result) = block_on(future::poll_once(&mut task.0)) {
|
||||||
match result {
|
match result {
|
||||||
Ok(mut commands_queue) => {
|
Ok(mut commands_queue) => {
|
||||||
commands.append(&mut commands_queue);
|
commands.append(&mut commands_queue);
|
||||||
|
states.set(GameState::Playing);
|
||||||
}
|
}
|
||||||
Err(e) => info!("Connection failed. Err: {e:?}"),
|
Err(e) => info!("Connection failed. Err: {e:?}"),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ pub fn spawn_main_menu(mut commands: Commands) {
|
|||||||
let mut start_button = cmds.spawn(button_bundle("Start game"));
|
let mut start_button = cmds.spawn(button_bundle("Start game"));
|
||||||
start_button.observe(
|
start_button.observe(
|
||||||
|_trigger: On<Pointer<Click>>, mut game_state: ResMut<NextState<GameState>>| {
|
|_trigger: On<Pointer<Click>>, mut game_state: ResMut<NextState<GameState>>| {
|
||||||
game_state.set(GameState::Playing);
|
game_state.set(GameState::Connecting);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
let mut quit_button = cmds.spawn(button_bundle("Quit Game"));
|
let mut quit_button = cmds.spawn(button_bundle("Quit Game"));
|
||||||
@@ -58,6 +58,29 @@ pub fn despawn_main_menu(
|
|||||||
commands.entity(top_node.into_inner()).despawn();
|
commands.entity(top_node.into_inner()).despawn();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn spawn_connection_wait_screen(mut commands: Commands) {
|
||||||
|
info!("Spawning connecting notice.");
|
||||||
|
commands.spawn((
|
||||||
|
Node {
|
||||||
|
width: Val::Percent(100.0),
|
||||||
|
height: Val::Percent(100.0),
|
||||||
|
align_items: AlignItems::Center,
|
||||||
|
justify_content: JustifyContent::Center,
|
||||||
|
flex_direction: FlexDirection::Column,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
children![Text::new("Connecting...")],
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn despawn_connection_wait_screen(
|
||||||
|
mut commands: Commands,
|
||||||
|
text_nodes: Single<Entity, (With<Node>, With<Text>)>,
|
||||||
|
) {
|
||||||
|
info!("Despawning connecting notice.");
|
||||||
|
commands.entity(text_nodes.into_inner()).despawn();
|
||||||
|
}
|
||||||
|
|
||||||
/// The basic bundle for generic buttons.
|
/// The basic bundle for generic buttons.
|
||||||
///
|
///
|
||||||
/// It's mostly so I don't have to copy & paste this everywhere I want to use it.
|
/// It's mostly so I don't have to copy & paste this everywhere I want to use it.
|
||||||
|
|||||||
Reference in New Issue
Block a user