|
|
|
@ -6,10 +6,11 @@ use bevy::window::{PrimaryWindow, WindowResized};
|
|
|
|
use crate::{
|
|
|
|
use crate::{
|
|
|
|
game::{Board, BoardIndex, Piece, Side, Tile},
|
|
|
|
game::{Board, BoardIndex, Piece, Side, Tile},
|
|
|
|
prelude::*,
|
|
|
|
prelude::*,
|
|
|
|
|
|
|
|
tweak::Tweakfile,
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
use serde::Deserialize;
|
|
|
|
|
|
|
|
|
|
|
|
const SCALE: f32 = 4.0;
|
|
|
|
const SCALE: f32 = 4.0;
|
|
|
|
const TILE_SIZE: f32 = 16.0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pub(crate) struct Display2dPlugin;
|
|
|
|
pub(crate) struct Display2dPlugin;
|
|
|
|
|
|
|
|
|
|
|
|
@ -63,6 +64,41 @@ pub(crate) struct Display2d;
|
|
|
|
#[derive(Debug, Component)]
|
|
|
|
#[derive(Debug, Component)]
|
|
|
|
struct BackgroundImage;
|
|
|
|
struct BackgroundImage;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// All possible sprites
|
|
|
|
|
|
|
|
#[derive(Debug, Deserialize, Component, Clone, PartialEq)]
|
|
|
|
|
|
|
|
pub(crate) enum GameSprite {
|
|
|
|
|
|
|
|
RedQueen,
|
|
|
|
|
|
|
|
RedDrone,
|
|
|
|
|
|
|
|
RedPawn,
|
|
|
|
|
|
|
|
BlueQueen,
|
|
|
|
|
|
|
|
BlueDrone,
|
|
|
|
|
|
|
|
BluePawn,
|
|
|
|
|
|
|
|
LightTile,
|
|
|
|
|
|
|
|
DarkTile,
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
impl From<(game::Piece, game::Side)> for GameSprite {
|
|
|
|
|
|
|
|
fn from((piece, side): (game::Piece, game::Side)) -> GameSprite {
|
|
|
|
|
|
|
|
match (piece, side) {
|
|
|
|
|
|
|
|
(Piece::Queen, Side::A) => GameSprite::RedQueen,
|
|
|
|
|
|
|
|
(Piece::Drone, Side::A) => GameSprite::RedDrone,
|
|
|
|
|
|
|
|
(Piece::Pawn, Side::A) => GameSprite::RedPawn,
|
|
|
|
|
|
|
|
(Piece::Queen, Side::B) => GameSprite::BlueQueen,
|
|
|
|
|
|
|
|
(Piece::Drone, Side::B) => GameSprite::BlueDrone,
|
|
|
|
|
|
|
|
(Piece::Pawn, Side::B) => GameSprite::BluePawn,
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
impl From<Tile> for GameSprite {
|
|
|
|
|
|
|
|
fn from(tile: game::Tile) -> GameSprite {
|
|
|
|
|
|
|
|
match tile {
|
|
|
|
|
|
|
|
Tile::Light => GameSprite::LightTile,
|
|
|
|
|
|
|
|
Tile::Dark => GameSprite::DarkTile,
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// STARTUP: Initialize 2d gameplay Camera
|
|
|
|
/// STARTUP: Initialize 2d gameplay Camera
|
|
|
|
fn initialize_camera(mut commands: Commands) {
|
|
|
|
fn initialize_camera(mut commands: Commands) {
|
|
|
|
commands.spawn((
|
|
|
|
commands.spawn((
|
|
|
|
@ -84,13 +120,19 @@ fn initialize_camera(mut commands: Commands) {
|
|
|
|
fn load_spritesheet(
|
|
|
|
fn load_spritesheet(
|
|
|
|
mut texture_atlases: ResMut<Assets<TextureAtlas>>,
|
|
|
|
mut texture_atlases: ResMut<Assets<TextureAtlas>>,
|
|
|
|
server: Res<AssetServer>,
|
|
|
|
server: Res<AssetServer>,
|
|
|
|
|
|
|
|
tweaks: Res<Assets<tweak::Tweakfile>>,
|
|
|
|
mut commands: Commands,
|
|
|
|
mut commands: Commands,
|
|
|
|
) {
|
|
|
|
) {
|
|
|
|
|
|
|
|
let handle: Handle<tweak::Tweakfile> = server.load("martian.tweak.toml");
|
|
|
|
|
|
|
|
let tweak = tweaks.get(&handle).expect("Load tweakfiles");
|
|
|
|
let atlas = TextureAtlas::from_grid(
|
|
|
|
let atlas = TextureAtlas::from_grid(
|
|
|
|
server.load("images/sprites.png"),
|
|
|
|
server.load(tweak.display2d.sprites.file.clone()),
|
|
|
|
Vec2::new(TILE_SIZE, TILE_SIZE),
|
|
|
|
Vec2::new(
|
|
|
|
8,
|
|
|
|
tweak.display2d.sprites.tile_size.x,
|
|
|
|
1,
|
|
|
|
tweak.display2d.sprites.tile_size.y,
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
tweak.display2d.sprites.columns,
|
|
|
|
|
|
|
|
tweak.display2d.sprites.rows,
|
|
|
|
None,
|
|
|
|
None,
|
|
|
|
None,
|
|
|
|
None,
|
|
|
|
);
|
|
|
|
);
|
|
|
|
@ -156,8 +198,11 @@ fn initialize_board(board: Option<Res<Board>>, mut commands: Commands) {
|
|
|
|
.with_children(|parent| {
|
|
|
|
.with_children(|parent| {
|
|
|
|
// Spawn tiles
|
|
|
|
// Spawn tiles
|
|
|
|
game::tiles().for_each(|(index, tile)| {
|
|
|
|
game::tiles().for_each(|(index, tile)| {
|
|
|
|
|
|
|
|
let game_sprite: GameSprite = tile.clone().into();
|
|
|
|
|
|
|
|
|
|
|
|
parent.spawn((
|
|
|
|
parent.spawn((
|
|
|
|
tile,
|
|
|
|
game_sprite,
|
|
|
|
|
|
|
|
tile.clone(),
|
|
|
|
index,
|
|
|
|
index,
|
|
|
|
Display2d,
|
|
|
|
Display2d,
|
|
|
|
SpriteSheetBundle { ..default() },
|
|
|
|
SpriteSheetBundle { ..default() },
|
|
|
|
@ -169,11 +214,14 @@ fn initialize_board(board: Option<Res<Board>>, mut commands: Commands) {
|
|
|
|
board.pieces().iter().for_each(|(index, piece)| {
|
|
|
|
board.pieces().iter().for_each(|(index, piece)| {
|
|
|
|
let side = Board::side(*index).expect("Spawn valid side");
|
|
|
|
let side = Board::side(*index).expect("Spawn valid side");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let game_sprite: GameSprite = (*piece, side.clone()).into();
|
|
|
|
|
|
|
|
|
|
|
|
parent.spawn((
|
|
|
|
parent.spawn((
|
|
|
|
|
|
|
|
game_sprite,
|
|
|
|
piece.clone(),
|
|
|
|
piece.clone(),
|
|
|
|
Display2d,
|
|
|
|
Display2d,
|
|
|
|
index.clone(),
|
|
|
|
index.clone(),
|
|
|
|
side,
|
|
|
|
side.clone(),
|
|
|
|
SpriteSheetBundle { ..default() },
|
|
|
|
SpriteSheetBundle { ..default() },
|
|
|
|
game::Selectable,
|
|
|
|
game::Selectable,
|
|
|
|
));
|
|
|
|
));
|
|
|
|
@ -187,54 +235,57 @@ fn set_piece_sprite(
|
|
|
|
(
|
|
|
|
(
|
|
|
|
&mut TextureAtlasSprite,
|
|
|
|
&mut TextureAtlasSprite,
|
|
|
|
&mut Handle<TextureAtlas>,
|
|
|
|
&mut Handle<TextureAtlas>,
|
|
|
|
&Piece,
|
|
|
|
&GameSprite,
|
|
|
|
&Side,
|
|
|
|
|
|
|
|
),
|
|
|
|
),
|
|
|
|
(With<Display2d>, Or<(Added<Piece>, Changed<Side>)>),
|
|
|
|
(With<Display2d>, Or<(Added<Piece>, Changed<Side>)>),
|
|
|
|
>,
|
|
|
|
>,
|
|
|
|
sprite_sheet: Option<Res<SpriteSheet>>,
|
|
|
|
sprite_sheet: Option<Res<SpriteSheet>>,
|
|
|
|
|
|
|
|
tweaks: Res<Assets<Tweakfile>>,
|
|
|
|
|
|
|
|
server: Res<AssetServer>,
|
|
|
|
) {
|
|
|
|
) {
|
|
|
|
if let Some(sprite_sheet) = sprite_sheet {
|
|
|
|
let handle: Handle<Tweakfile> = server.load("martian.tweak.toml");
|
|
|
|
|
|
|
|
let tweak = tweaks
|
|
|
|
|
|
|
|
.get(&handle)
|
|
|
|
|
|
|
|
.expect("Load tweaksfile in set piece sprite");
|
|
|
|
|
|
|
|
let sprite_sheet = sprite_sheet.expect("Sprite sheet");
|
|
|
|
events
|
|
|
|
events
|
|
|
|
.iter_mut()
|
|
|
|
.iter_mut()
|
|
|
|
.for_each(|(mut sprite, mut texture_atlas, piece, side)| {
|
|
|
|
.for_each(|(mut sprite, mut texture_atlas, game_sprite)| {
|
|
|
|
debug!("Updating sprite {:?} {:?}", piece, side);
|
|
|
|
if let Some(index) = tweak.display2d.sprites.locate(game_sprite) {
|
|
|
|
if *texture_atlas != sprite_sheet.handle {
|
|
|
|
if *texture_atlas != sprite_sheet.handle {
|
|
|
|
*texture_atlas = sprite_sheet.handle.clone();
|
|
|
|
*texture_atlas = sprite_sheet.handle.clone();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
sprite.index = match (piece, side) {
|
|
|
|
sprite.index = index;
|
|
|
|
(Piece::Queen, Side::A) => 2,
|
|
|
|
|
|
|
|
(Piece::Queen, Side::B) => 5,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(Piece::Drone, Side::A) => 3,
|
|
|
|
|
|
|
|
(Piece::Drone, Side::B) => 6,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(Piece::Pawn, Side::A) => 4,
|
|
|
|
|
|
|
|
(Piece::Pawn, Side::B) => 7,
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn set_tile_sprite(
|
|
|
|
fn set_tile_sprite(
|
|
|
|
mut events: Query<
|
|
|
|
mut events: Query<
|
|
|
|
(&mut TextureAtlasSprite, &mut Handle<TextureAtlas>, &Tile),
|
|
|
|
(
|
|
|
|
(Added<game::Tile>, With<Display2d>),
|
|
|
|
&mut TextureAtlasSprite,
|
|
|
|
|
|
|
|
&mut Handle<TextureAtlas>,
|
|
|
|
|
|
|
|
&GameSprite,
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
(Added<GameSprite>, With<Display2d>),
|
|
|
|
>,
|
|
|
|
>,
|
|
|
|
sprite_sheet: Option<Res<SpriteSheet>>,
|
|
|
|
sprite_sheet: Option<Res<SpriteSheet>>,
|
|
|
|
|
|
|
|
tweaks: Res<Assets<Tweakfile>>,
|
|
|
|
|
|
|
|
server: Res<AssetServer>,
|
|
|
|
) {
|
|
|
|
) {
|
|
|
|
if let Some(sprite_sheet) = sprite_sheet {
|
|
|
|
let handle: Handle<Tweakfile> = server.load("martian.tweak.toml");
|
|
|
|
|
|
|
|
let tweak = tweaks
|
|
|
|
|
|
|
|
.get(&handle)
|
|
|
|
|
|
|
|
.expect("Load tweaksfile in set tile sprite");
|
|
|
|
|
|
|
|
let sprite_sheet = sprite_sheet.expect("Sprite sheet");
|
|
|
|
events
|
|
|
|
events
|
|
|
|
.iter_mut()
|
|
|
|
.iter_mut()
|
|
|
|
.for_each(|(mut sprite, mut texture_atlas, tile)| {
|
|
|
|
.for_each(|(mut sprite, mut texture_atlas, game_sprite)| {
|
|
|
|
|
|
|
|
if let Some(index) = tweak.display2d.sprites.locate(game_sprite) {
|
|
|
|
*texture_atlas = sprite_sheet.handle.clone();
|
|
|
|
*texture_atlas = sprite_sheet.handle.clone();
|
|
|
|
let s = match tile {
|
|
|
|
*sprite = TextureAtlasSprite::new(index);
|
|
|
|
Tile::Dark => 0,
|
|
|
|
|
|
|
|
Tile::Light => 1,
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
*sprite = TextureAtlasSprite::new(s);
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Sets a piece location given it's board index
|
|
|
|
/// Sets a piece location given it's board index
|
|
|
|
@ -348,3 +399,33 @@ fn move_piece(
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pub(crate) mod tweaks {
|
|
|
|
|
|
|
|
use super::*;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, Deserialize, Default)]
|
|
|
|
|
|
|
|
pub(crate) struct Display2dTweaks {
|
|
|
|
|
|
|
|
#[serde(default)]
|
|
|
|
|
|
|
|
pub sprites: SpriteTweaks,
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, Deserialize, Default)]
|
|
|
|
|
|
|
|
pub(crate) struct SpriteTweaks {
|
|
|
|
|
|
|
|
#[serde(default)]
|
|
|
|
|
|
|
|
pub file: String,
|
|
|
|
|
|
|
|
#[serde(default)]
|
|
|
|
|
|
|
|
pub tile_size: Vec2,
|
|
|
|
|
|
|
|
#[serde(default)]
|
|
|
|
|
|
|
|
pub columns: usize,
|
|
|
|
|
|
|
|
#[serde(default)]
|
|
|
|
|
|
|
|
pub rows: usize,
|
|
|
|
|
|
|
|
#[serde(default)]
|
|
|
|
|
|
|
|
pub sprite_order: Vec<GameSprite>,
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
impl SpriteTweaks {
|
|
|
|
|
|
|
|
pub(crate) fn locate(&self, s: &GameSprite) -> Option<usize> {
|
|
|
|
|
|
|
|
self.sprite_order.iter().position(|x| x == s)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|