diff --git a/README.md b/README.md
index b80768e..35f3d54 100644
--- a/README.md
+++ b/README.md
@@ -40,6 +40,7 @@ pub const CLIENT_MAP_GEN: bool = true;
- T - toggle One/Thrid Person
- E - Open composite rules list
- Q - throw active toolbar object
+- (Hold Left-Shift Left-Click)-rotation Cube Direction
# Feature List
- [x] Load unlimited maps
diff --git a/README_CN.md b/README_CN.md
index eceaeac..a77e36e 100644
--- a/README_CN.md
+++ b/README_CN.md
@@ -33,6 +33,8 @@ cargo run --release --bin client
- T 切换视角
- E 打开合成表
- Q 丢弃toolbar上激活中的物品
+- 按住左Shirt+左键单机。旋转方块方向
+
# LIB 中的配置常量
```rust
diff --git "a/assets/textures/\346\265\213\350\257\2251.png" "b/assets/textures/\346\265\213\350\257\2251.png"
new file mode 100644
index 0000000..65de122
Binary files /dev/null and "b/assets/textures/\346\265\213\350\257\2251.png" differ
diff --git "a/assets/textures/\346\265\213\350\257\2252.png" "b/assets/textures/\346\265\213\350\257\2252.png"
new file mode 100644
index 0000000..1df689b
Binary files /dev/null and "b/assets/textures/\346\265\213\350\257\2252.png" differ
diff --git "a/assets/textures/\346\265\213\350\257\2253.png" "b/assets/textures/\346\265\213\350\257\2253.png"
new file mode 100644
index 0000000..142fba7
Binary files /dev/null and "b/assets/textures/\346\265\213\350\257\2253.png" differ
diff --git "a/assets/textures/\346\265\213\350\257\2254.png" "b/assets/textures/\346\265\213\350\257\2254.png"
new file mode 100644
index 0000000..302d380
Binary files /dev/null and "b/assets/textures/\346\265\213\350\257\2254.png" differ
diff --git "a/assets/textures/\346\265\213\350\257\2255.png" "b/assets/textures/\346\265\213\350\257\2255.png"
new file mode 100644
index 0000000..6fdecba
Binary files /dev/null and "b/assets/textures/\346\265\213\350\257\2255.png" differ
diff --git "a/assets/textures/\346\265\213\350\257\2256.png" "b/assets/textures/\346\265\213\350\257\2256.png"
new file mode 100644
index 0000000..c8358b9
Binary files /dev/null and "b/assets/textures/\346\265\213\350\257\2256.png" differ
diff --git a/src/client/player/mouse_control.rs b/src/client/player/mouse_control.rs
index 238ed77..ae88421 100644
--- a/src/client/player/mouse_control.rs
+++ b/src/client/player/mouse_control.rs
@@ -1,6 +1,6 @@
use bevy::{
prelude::{
- in_state, warn, Event, EventReader, EventWriter, IVec3, Input, IntoSystemConfigs,
+ in_state, warn, Event, EventReader, EventWriter, IVec3, Input, IntoSystemConfigs, KeyCode,
MouseButton, Plugin, Query, Res, ResMut, Resource, Transform, Update, Vec3,
},
time::{Time, Timer, TimerMode},
@@ -16,7 +16,7 @@ use crate::{
},
server::player::Player,
tools::{vec3_to_chunk_key_any_xyz, zone::check_player_put_object_available},
- voxel_world::{chunk::ChunkKey, voxel::Voxel},
+ voxel_world::{chunk::ChunkKey, chunk_map::ChunkMap, voxel::Voxel},
};
use super::controller::ControllerFlag;
@@ -79,17 +79,43 @@ pub fn deal_broken_cube_event(
//鼠标操作
pub fn mouse_button_system(
mouse_button_input: Res>,
+ keyboard_input: Res>,
choose_cube: Res,
controller_flag: Res,
mut client: ResMut,
tool_bar_data: Res,
mut attack_timer: ResMut,
player_query: Query<(&Player, &Transform)>,
+ chunk_map: Res,
) {
if !controller_flag.flag {
// println!("3:{}", controller_flag.flag);
return;
}
+
+ // 移动数据的方向
+ if mouse_button_input.just_released(MouseButton::Left)
+ && keyboard_input.pressed(KeyCode::ShiftLeft)
+ {
+ if let Some(pos) = choose_cube.center {
+ let (chunk_key, xyz) = vec3_to_chunk_key_any_xyz(pos);
+ if let Some(voxel_type) = chunk_map.get_block(chunk_key, xyz) {
+ // FIXME: 这里要判断是否每种情况都可以去旋转!
+ let new_voxel = voxel_type.next_direction();
+ println!("这里发送了旋转方块的指令{:?}", new_voxel);
+ let message = bincode::serialize(&ChunkQuery::Change {
+ chunk_key,
+ pos: xyz,
+ voxel_type: new_voxel,
+ center: pos,
+ active_index: None,
+ })
+ .unwrap();
+ client.send_message(ClientChannel::ChunkQuery, message);
+ }
+ }
+ }
+
if mouse_button_input.just_pressed(MouseButton::Left) || attack_timer.pressed {
attack_timer.pressed = true;
// println!("4:{}", controller_flag.flag);
diff --git a/src/client/voxels/mesh.rs b/src/client/voxels/mesh.rs
index a971478..81c69dc 100644
--- a/src/client/voxels/mesh.rs
+++ b/src/client/voxels/mesh.rs
@@ -10,7 +10,7 @@ use ndshape::{ConstShape, ConstShape3u32, Shape};
use crate::{
client::voxels::mesh_material::ATTRIBUTE_DATA,
- voxel_world::voxel::{Voxel, VoxelMaterial, Water},
+ voxel_world::voxel::{Voxel, VoxelDirection, VoxelMaterial, Water},
CHUNK_SIZE, CHUNK_SIZE_ADD_2_U32,
};
@@ -52,14 +52,53 @@ where
indices.extend_from_slice(&face.quad_mesh_indices(positions.len() as u32));
positions.extend_from_slice(&face.quad_mesh_positions(quad, 1.0));
normals.extend_from_slice(&face.quad_mesh_normals());
- tex_coords.extend_from_slice(&face.tex_coords(
- RIGHT_HANDED_Y_UP_CONFIG.u_flip_face,
- true,
- quad,
- ));
- // 这里可以生成Data???? 但是怎么知道 是那个面的?
+ // 这里可以生成Data 但是怎么知道 是那个面的?
let index = >::linearize(quad.minimum);
+ // 这里处理一下问题
+ if block_face_normal_index == 1 || block_face_normal_index == 4 {
+ match voxels[index as usize].direction.clone() {
+ VoxelDirection::Z => {
+ tex_coords.extend_from_slice(&[
+ [0.0, quad.height as f32],
+ [quad.width as f32, quad.height as f32],
+ [0.0, 0.0],
+ [quad.width as f32, 0.0],
+ ]);
+ }
+ VoxelDirection::X => {
+ tex_coords.extend_from_slice(&[
+ [quad.width as f32, quad.height as f32],
+ [quad.width as f32, 0.0],
+ [0.0, quad.height as f32],
+ [0.0, 0.0],
+ ]);
+ }
+ VoxelDirection::NZ => {
+ tex_coords.extend_from_slice(&[
+ [quad.width as f32, 0.0],
+ [0.0, 0.0],
+ [quad.width as f32, quad.height as f32],
+ [0.0, quad.height as f32],
+ ]);
+ }
+ VoxelDirection::NX => {
+ tex_coords.extend_from_slice(&[
+ [0.0, 0.0],
+ [0.0, quad.height as f32],
+ [quad.width as f32, 0.0],
+ [quad.width as f32, quad.height as f32],
+ ]);
+ }
+ }
+ } else {
+ tex_coords.extend_from_slice(&face.tex_coords(
+ RIGHT_HANDED_Y_UP_CONFIG.u_flip_face,
+ true,
+ quad,
+ ));
+ }
+
// 法向量值
let normol_num = (block_face_normal_index as u32) << 8u32;
// 计算贴图索引
@@ -67,8 +106,10 @@ where
material_config.clone(),
block_face_normal_index as u8,
&voxels[index as usize].id,
+ voxels[index as usize].direction.clone(),
);
- // todo 这里后面要知道是那个面的方便渲染
+
+ // 这里后面要知道是那个面的方便渲染
data.extend_from_slice(&[normol_num | (txt_index); 4]);
}
}
@@ -165,6 +206,7 @@ pub fn gen_mesh_water(voxels: Vec, material_config: MaterailConfiguration
material_config.clone(),
block_face_normal_index as u8,
&Water::ID,
+ VoxelDirection::Z,
);
data.extend_from_slice(&[normol_num | (txt_index); 4]);
}
diff --git a/src/client/voxels/voxel_materail_config.rs b/src/client/voxels/voxel_materail_config.rs
index 6c85723..020c6a7 100644
--- a/src/client/voxels/voxel_materail_config.rs
+++ b/src/client/voxels/voxel_materail_config.rs
@@ -5,7 +5,7 @@ use bevy_inspector_egui::prelude::*;
use serde::{Deserialize, Serialize};
use walkdir::WalkDir;
-use crate::voxel_world::voxel::{Grass, Soli, Stone, VoxelMaterial};
+use crate::voxel_world::voxel::{Grass, Soli, Stone, VoxelDirection, VoxelMaterial};
#[derive(Debug, Clone, Serialize, Deserialize, Default, Reflect, InspectorOptions)]
#[reflect(InspectorOptions)]
@@ -124,10 +124,17 @@ impl MaterailConfiguration {
}
// 通过面 和 体素类型获取 图片的索引
- pub fn find_volex_index(self, normal: u8, volex_type: &u8) -> u32 {
+ pub fn find_volex_index(self, normal: u8, volex_type: &u8, direction: VoxelDirection) -> u32 {
+ let change_normal = match direction {
+ VoxelDirection::Z => rotate_times(normal, 0),
+ VoxelDirection::X => rotate_times(normal, 1),
+ VoxelDirection::NZ => rotate_times(normal, 2),
+ VoxelDirection::NX => rotate_times(normal, 3),
+ };
+
return match self.voxels.get(volex_type) {
Some(config) => {
- return match config.normal.get(&normal) {
+ return match config.normal.get(&change_normal) {
Some(vconfig) => vconfig.index,
None => config.default.index,
};
@@ -136,3 +143,23 @@ impl MaterailConfiguration {
};
}
}
+
+fn rotate_times(normal: u8, times: usize) -> u8 {
+ let mut ret = normal;
+ if times > 0 {
+ for _ in 0..times {
+ ret = rotate_half_pi(ret);
+ }
+ }
+ ret
+}
+
+fn rotate_half_pi(normal: u8) -> u8 {
+ return match normal {
+ 0 => 5,
+ 2 => 0,
+ 3 => 2,
+ 5 => 3,
+ _ => normal,
+ };
+}
diff --git a/src/lib.rs b/src/lib.rs
index a21f9f6..34f7ff3 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -27,7 +27,7 @@ pub const CHUNK_SIZE: i32 = 16;
pub const CHUNK_SIZE_U32: u32 = CHUNK_SIZE as u32;
pub const CHUNK_SIZE_ADD_2_U32: u32 = CHUNK_SIZE_U32 + 2;
// 贴图个数
-pub const MAX_TEXTURE_COUNT: usize = 16;
+pub const MAX_TEXTURE_COUNT: usize = 22;
// 物体选择半径
pub const TOUCH_RADIUS: f32 = 5.;
pub const CLIENT_DEBUG: bool = false;
diff --git a/src/server/async_chunk.rs b/src/server/async_chunk.rs
index 9f9c1f5..5e08a3e 100644
--- a/src/server/async_chunk.rs
+++ b/src/server/async_chunk.rs
@@ -105,7 +105,10 @@ pub fn deal_chunk_query_system(
warn!("基岩无法破坏");
continue;
}
- if old_voxel.id != Voxel::EMPTY.id && voxel_type.id != Voxel::EMPTY.id {
+ if old_voxel.id != Voxel::EMPTY.id
+ && voxel_type.id != Voxel::EMPTY.id
+ && active_index != None
+ {
warn!("放置错误");
continue;
}
@@ -130,7 +133,11 @@ pub fn deal_chunk_query_system(
}
} else {
warn!("{}|角色没有当前生成的index", client_id);
- continue;
+ if old_voxel.direction == voxel_type.direction {
+ continue;
+ } else {
+ println!("转动方向");
+ }
}
} else {
warn!("{}|{}没有找到资源对应关系", client_id, voxel_type.id);
diff --git a/src/voxel_world/voxel.rs b/src/voxel_world/voxel.rs
index b38da62..9936d37 100644
--- a/src/voxel_world/voxel.rs
+++ b/src/voxel_world/voxel.rs
@@ -4,12 +4,47 @@ use serde::{Deserialize, Serialize};
/**
* 体素类型
+ *
+ * 这里要设计使用 u32的数据
+ * voxel_data >> 8u & 0b111 8位后的数据 9 10 11位置的数据
+ * voxel_data & 255u 表示取最后的8位
+ * 方块是否透明是否要记录呢?不用在数据库中,但是转回来的时候我要知道。并且可以生成对应的mesh在地图中
+ *
+ * 存储类型:
+ * 体素类型 方块方向
+ * [0-8] [9 10]
+ * todo 在某种情况下计算不同位置的 图片索引和贴图?
+ *
+ * 展示时的数据
+ * 贴图索引 法向量 方块方向
+ * [0-8] [9-11] [12 13]
+ *
+ * 是否可视等 是在其他地方定义的
+ *
*/
#[derive(Debug, Clone, Copy, Default, Deserialize, Serialize, Reflect, PartialEq, Eq, Hash)]
pub struct Voxel {
pub id: u8,
+ pub direction: VoxelDirection,
}
+// 体素方向
+#[derive(Debug, Clone, Copy, Reflect, Serialize, Deserialize, Default, PartialEq, Eq, Hash)]
+pub enum VoxelDirection {
+ #[default]
+ Z,
+ NZ, // 指向Z的负数半轴
+ X,
+ NX, // 指向X的负数半轴
+}
+
+pub const VOXEL_DIRECTION_VEC: [VoxelDirection; 4] = [
+ VoxelDirection::Z,
+ VoxelDirection::NZ,
+ VoxelDirection::X,
+ VoxelDirection::NX,
+];
+
impl PartialOrd for Voxel {
fn partial_cmp(&self, other: &Self) -> Option {
self.id.partial_cmp(&other.id)
@@ -23,8 +58,53 @@ impl Ord for Voxel {
}
impl Voxel {
- pub const EMPTY: Self = Self { id: 0 };
- pub const FILLED: Self = Self { id: 1 };
+ pub const EMPTY: Self = Self {
+ id: 0,
+ direction: VoxelDirection::Z,
+ };
+ pub const FILLED: Self = Self {
+ id: 1,
+ direction: VoxelDirection::Z,
+ };
+
+ // 转换成32位的存在类型
+ pub fn into_save_u32(&self) -> u32 {
+ let direction_base = match self.direction {
+ VoxelDirection::Z => 0u32 << 8u32,
+ VoxelDirection::NZ => 1u32 << 8u32,
+ VoxelDirection::X => 2u32 << 8u32,
+ VoxelDirection::NX => 3u32 << 8u32,
+ };
+ (self.id as u32) | direction_base
+ }
+
+ // u32 位置类型转换成 体素类型
+ pub fn u32_into_voxel(data: u32) -> Self {
+ Self {
+ id: Self::pick_id(data),
+ direction: Self::pick_direction(data),
+ }
+ }
+
+ pub fn pick_id(data: u32) -> u8 {
+ (data & 255u32) as u8
+ }
+
+ pub fn pick_direction(data: u32) -> VoxelDirection {
+ VOXEL_DIRECTION_VEC[(data >> 8u32 & 0b11) as usize]
+ }
+
+ pub fn next_direction(&self) -> Self {
+ Self {
+ id: self.id,
+ direction: match self.direction {
+ VoxelDirection::Z => VoxelDirection::X,
+ VoxelDirection::X => VoxelDirection::NZ,
+ VoxelDirection::NZ => VoxelDirection::NX,
+ VoxelDirection::NX => VoxelDirection::Z,
+ },
+ }
+ }
}
impl MeshVoxel for Voxel {
@@ -49,7 +129,18 @@ pub trait VoxelMaterial {
const ID: u8;
fn into_voxel() -> Voxel {
- Voxel { id: Self::ID }
+ Voxel {
+ id: Self::ID,
+ ..Default::default()
+ }
+ }
+
+ // 转化成 有方向的体素数据
+ fn into_voxel_with_dir(direction: VoxelDirection) -> Voxel {
+ Voxel {
+ id: Self::ID,
+ direction,
+ }
}
}
@@ -81,3 +172,4 @@ voxel_material!(DryGrass, 干草地, 8);
voxel_material!(BuleGrass, 苍翠地, 9);
voxel_material!(AppleWood, 苹果树原木, 10);
voxel_material!(AppleLeaf, 苹果树叶子, 11);
+voxel_material!(TestCube, 测试方块, 12);
diff --git a/staff.ron b/staff.ron
index 5b02c00..49c4646 100644
--- a/staff.ron
+++ b/staff.ron
@@ -1,17 +1,18 @@
(
configs:[
- (id:0,name:"Stone",icon_string:"textures/002.png",staff_type:Voxel((id:1))),
- (id:1,name:"Grass",icon_string:"textures/草坪.png",staff_type:Voxel((id:3))),
- (id:2,name:"Soli",icon_string:"textures/003.png",staff_type:Voxel((id:2))),
- (id:3,name:"Sand",icon_string:"textures/沙子.png",staff_type:Voxel((id:6))),
- (id:4,name:"Sown",icon_string:"textures/雪.png",staff_type:Voxel((id:4))),
+ (id:0,name:"Stone",icon_string:"textures/002.png",staff_type:Voxel((id:1,direction:Z))),
+ (id:1,name:"Grass",icon_string:"textures/草坪.png",staff_type:Voxel((id:3,direction:Z))),
+ (id:2,name:"Soli",icon_string:"textures/003.png",staff_type:Voxel((id:2,direction:Z))),
+ (id:3,name:"Sand",icon_string:"textures/沙子.png",staff_type:Voxel((id:6,direction:Z))),
+ (id:4,name:"Sown",icon_string:"textures/雪.png",staff_type:Voxel((id:4,direction:Z))),
(id:5,name:"FireWork",icon_string:"staff/烟花.png",staff_type:Consumable(0)),
- (id:6,name:"DryGrass",icon_string:"textures/干草地.png",staff_type:Voxel((id:8))),
- (id:7,name:"BlueGrass",icon_string:"textures/苍翠地.png",staff_type:Voxel((id:9))),
- (id:8,name:"AppleWood",icon_string:"textures/苹果树A面.png",staff_type:Voxel((id:10))),
- (id:9,name:"AppleLeaf",icon_string:"textures/苹果叶子.png",staff_type:Voxel((id:11))),
+ (id:6,name:"DryGrass",icon_string:"textures/干草地.png",staff_type:Voxel((id:8,direction:Z))),
+ (id:7,name:"BlueGrass",icon_string:"textures/苍翠地.png",staff_type:Voxel((id:9,direction:Z))),
+ (id:8,name:"AppleWood",icon_string:"textures/苹果树A面.png",staff_type:Voxel((id:10,direction:Z))),
+ (id:9,name:"AppleLeaf",icon_string:"textures/苹果叶子.png",staff_type:Voxel((id:11,direction:Z))),
(id:10,name:"Apple",icon_string:"textures/苹果.png",staff_type:Consumable(0)),
(id:11,name:"AppleLog",icon_string:"textures/棍子.png",staff_type:Consumable(0)),
+ (id:12,name:"TestCube",icon_string:"textures/测试1.png",staff_type:Voxel((id:12,direction:Z))),
],
// 掉落配置
filled_configs:[
diff --git a/staff_rules.ron b/staff_rules.ron
index 7397063..61601ff 100644
--- a/staff_rules.ron
+++ b/staff_rules.ron
@@ -14,4 +14,16 @@
base_on:None,
desc:"测试使用的合成烟花的公式(测试一个合成多个)",
),
+ (
+ id:1,
+ input:[
+ (staff_id:0,num_needed:1),
+ ],
+ // 合成测试方块
+ output: [
+ (staff_id:12,num_needed:1),
+ ],
+ base_on:None,
+ desc:"合成测试使用的摆放方块",
+ ),
]
\ No newline at end of file
diff --git a/volex.ron b/volex.ron
index 2e4b076..90a750e 100644
--- a/volex.ron
+++ b/volex.ron
@@ -1,5 +1,13 @@
(
voxels:{
+ 12:(type_name:"TestCube",type_ch_name:"测试使用方块",default:(index:21,path:"textures/测试6.png"),normal:{
+ 1:(index:16,path:"textures/测试1.png"),
+ 2:(index:17,path:"textures/测试2.png"),
+ 3:(index:18,path:"textures/测试3.png"),
+ 4:(index:19,path:"textures/测试4.png"),
+ 5:(index:20,path:"textures/测试5.png"),
+ 0:(index:21,path:"textures/测试6.png"),
+ }),
11:(type_name:"AppleLeaf",type_ch_name:"苹果树叶子",default:(index:15,path:"textures/苹果叶子.png"),normal:{}),
10:(type_name:"AppleWood",type_ch_name:"苹果树原木",default:(index:13,path:"textures/苹果树A面.png"),normal:{
4:(index:14,path:"textures/苹果树B面.png"),
@@ -44,4 +52,11 @@
"textures/苹果树B面.png",
//15
"textures/苹果叶子.png",
+ "textures/测试1.png",
+ "textures/测试2.png",
+ "textures/测试3.png",
+ "textures/测试4.png",
+ //20
+ "textures/测试5.png",
+ "textures/测试6.png",
])
\ No newline at end of file