wip bevy tiles

This commit is contained in:
Henri Bourcereau 2023-11-05 17:14:58 +01:00
parent ac2f139dbc
commit a7bb630816
10 changed files with 82 additions and 7 deletions

1
Cargo.lock generated
View file

@ -3115,6 +3115,7 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
name = "store" name = "store"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"log",
"rand", "rand",
"serde", "serde",
] ]

Binary file not shown.

BIN
client/assets/sound/throw.wav Executable file

Binary file not shown.

BIN
client/assets/tac.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

BIN
client/assets/tic.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

View file

@ -3,7 +3,7 @@ use std::{net::UdpSocket, time::SystemTime};
use renet::transport::{NetcodeClientTransport, NetcodeTransportError, NETCODE_USER_DATA_BYTES}; use renet::transport::{NetcodeClientTransport, NetcodeTransportError, NETCODE_USER_DATA_BYTES};
use store::{EndGameReason, GameEvent, GameState}; use store::{EndGameReason, GameEvent, GameState};
use bevy::prelude::*; use bevy::{prelude::*, utils::HashMap};
use bevy::window::PrimaryWindow; use bevy::window::PrimaryWindow;
use bevy_renet::{ use bevy_renet::{
renet::{transport::ClientAuthentication, ConnectionConfig, RenetClient}, renet::{transport::ClientAuthentication, ConnectionConfig, RenetClient},
@ -73,7 +73,7 @@ fn main() {
.insert_resource(transport) .insert_resource(transport)
.insert_resource(CurrentClientId(client_id)) .insert_resource(CurrentClientId(client_id))
.add_systems(Startup, setup) .add_systems(Startup, setup)
.add_systems(Update, (update_waiting_text, input, panic_on_error_system)) .add_systems(Update, (update_waiting_text, input, update_board, panic_on_error_system))
.add_systems( .add_systems(
PostUpdate, PostUpdate,
receive_events_from_server.run_if(client_connected()), receive_events_from_server.run_if(client_connected()),
@ -88,7 +88,70 @@ struct UIRoot;
#[derive(Component)] #[derive(Component)]
struct WaitingText; struct WaitingText;
#[derive(Component)]
struct Board {
squares: [Square; 26]
}
impl Default for Board {
fn default() -> Self {
Self {
squares: [Square { count: 0, color: None, position: 0}; 26]
}
}
}
impl Board {
fn square_at(&self, position: usize) -> Square {
self.squares[position]
}
}
#[derive(Component, Clone, Copy)]
struct Square {
count: usize,
color: Option<bool>,
position: usize,
}
////////// UPDATE SYSTEMS ////////// ////////// UPDATE SYSTEMS //////////
fn update_board(
mut commands: Commands,
game_state: Res<BevyGameState>,
mut game_events: EventReader<BevyGameEvent>,
asset_server: Res<AssetServer>,
) {
for event in game_events.iter() {
match event.0 {
GameEvent::Move { player_id, from, to } => {
// backgammon postions, TODO : dépend de player_id
let (x, y) = if to < 13 { (13 - to, 1) } else { (to - 13, 0)};
let texture =
asset_server.load(match game_state.0.players[&player_id].color {
store::Color::Black => "tac.png",
store::Color::White => "tic.png",
});
info!("spawning tictac sprite");
commands.spawn(SpriteBundle {
transform: Transform::from_xyz(
83.0 * (x as f32 - 1.0),
-30.0 + 540.0 * (y as f32 - 1.0),
0.0,
),
sprite: Sprite {
custom_size: Some(Vec2::new(83.0, 83.0)),
..default()
},
texture: texture.into(),
..default()
});
}
_ => {}
}
}
}
fn update_waiting_text(mut text_query: Query<&mut Text, With<WaitingText>>, time: Res<Time>) { fn update_waiting_text(mut text_query: Query<&mut Text, With<WaitingText>>, time: Res<Time>) {
if let Ok(mut text) = text_query.get_single_mut() { if let Ok(mut text) = text_query.get_single_mut() {
let num_dots = (time.elapsed_seconds() as usize % 3) + 1; let num_dots = (time.elapsed_seconds() as usize % 3) + 1;
@ -115,7 +178,6 @@ fn input(
return; return;
} }
// let window = windows.get_primary().unwrap();
let window = primary_query.get_single().unwrap(); let window = primary_query.get_single().unwrap();
if let Some(mouse_position) = window.cursor_position() { if let Some(mouse_position) = window.cursor_position() {
// Determine the index of the tile that the mouse is currently over // Determine the index of the tile that the mouse is currently over
@ -127,7 +189,14 @@ fn input(
// remove the middle bar offset // remove the middle bar offset
tile_x = tile_x - 1 tile_x = tile_x - 1
} }
let tile = tile_x + tile_y * 12; // let tile = tile_x + tile_y * 12;
// traduction en position backgammon
let tile = if tile_y == 0 {
13 + tile_x
} else {
12 - tile_x
};
// If mouse is outside of board we do nothing // If mouse is outside of board we do nothing
if 23 < tile { if 23 < tile {
@ -191,6 +260,7 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
}) })
.insert(UIRoot) .insert(UIRoot)
.with_children(|parent| { .with_children(|parent| {
// parent.spawn(Board::default()); // panic
parent parent
.spawn(TextBundle::from_section( .spawn(TextBundle::from_section(
"Waiting for an opponent...", "Waiting for an opponent...",

View file

@ -6,5 +6,6 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
log = "0.4.20"
rand = "0.8.5" rand = "0.8.5"
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }

View file

@ -2,7 +2,7 @@ use crate::player::{Player, Color};
use crate::Error; use crate::Error;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
/// Represents the Backgammon board /// Represents the Tric Trac board
/// ///
/// A Tric-Trac board consists of 24 fields, each of which can hold 0 or more checkers. /// A Tric-Trac board consists of 24 fields, each of which can hold 0 or more checkers.
/// ///
@ -75,7 +75,7 @@ impl Board {
/// ///
/// This method adds the amount of checkers for a player on a field. The field is numbered from /// This method adds the amount of checkers for a player on a field. The field is numbered from
/// 0 to 23, starting from the last field of each player in the home board, the most far away /// 0 to 23, starting from the last field of each player in the home board, the most far away
/// field for each player (where there are 2 checkers to start with) is number 23. /// field for each player is number 23.
/// ///
/// If the field is blocked for the player, an error is returned. If the field is not blocked, /// If the field is blocked for the player, an error is returned. If the field is not blocked,
/// but there is already one checker from the other player on the field, that checker is hit and /// but there is already one checker from the other player on the field, that checker is hit and

View file

@ -3,6 +3,7 @@ use crate::player::{Color, Player, PlayerId};
use crate::board::{Board, Move}; use crate::board::{Board, Move};
use crate::dice::{Dices, Roll}; use crate::dice::{Dices, Roll};
use crate::Error; use crate::Error;
use log::{error, info, trace, warn};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::collections::HashMap; use std::collections::HashMap;
@ -137,10 +138,12 @@ impl GameState {
Move { player_id, from, to } => { Move { player_id, from, to } => {
// Check player exists // Check player exists
if !self.players.contains_key(player_id) { if !self.players.contains_key(player_id) {
error!("Player {} unknown", player_id);
return false; return false;
} }
// Check player is currently the one making their move // Check player is currently the one making their move
if self.active_player_id != *player_id { if self.active_player_id != *player_id {
error!("Player not active : {}", self.active_player_id);
return false; return false;
} }

View file

@ -2,7 +2,7 @@ mod game;
pub use game::{EndGameReason, GameEvent, GameState, Stage}; pub use game::{EndGameReason, GameEvent, GameState, Stage};
mod player; mod player;
pub use player::Player; pub use player::{Player, Color};
mod error; mod error;
pub use error::Error; pub use error::Error;