Skip to content
This repository has been archived by the owner on Dec 27, 2023. It is now read-only.

Commit

Permalink
On the way to implement block breaking / placing, currently the wrong…
Browse files Browse the repository at this point in the history
… blocks are being placed / broken
  • Loading branch information
Adamkob12 committed Sep 24, 2023
1 parent 233fe38 commit bfac205
Show file tree
Hide file tree
Showing 7 changed files with 401 additions and 37 deletions.
136 changes: 136 additions & 0 deletions src/add_break_blocks.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
use crate::{one_d_cords, three_d_cords, *};
use bevy::prelude::*;
use bevy_meshem::prelude::*;

const RAY_FORWARD_STEP: f32 = 0.1;
const REACH_DISTANCE: u8 = 4;

#[derive(Event)]
pub struct BlockChange {
pub blocks: Vec<([i32; 2], usize)>,
pub change: VoxelChange,
}

pub fn add_break_detector(
mut block_change_event_writer: EventWriter<BlockChange>,
player_query: Query<(&CurrentChunk, &Transform), With<FlyCam>>,
buttons: Res<Input<MouseButton>>,
) {
if let Ok((chunk, tran)) = player_query.get_single() {
if tran.translation.y > HEIGHT as f32 || tran.translation.y < 0.0 {
return;
}
let chunk = (*chunk).0;
let forward = tran.forward();
let pos = tran.translation;

if buttons.just_pressed(MouseButton::Left) {
println!("Heya");
block_change_event_writer.send(BlockChange {
blocks: blocks_in_the_way(pos, forward, REACH_DISTANCE)
.iter()
.map(|(x, y, z)| (*x, one_d_cords(*y, CHUNK_DIMS)))
.collect(),
change: VoxelChange::Broken,
});
}
if buttons.just_pressed(MouseButton::Right) {
block_change_event_writer.send(BlockChange {
change: VoxelChange::Added,
blocks: blocks_in_the_way(pos, forward, REACH_DISTANCE)
.iter()
.map(|&(x, y, z)| {
let tmp = one_d_cords(y, CHUNK_DIMS);
if let Some(block) = get_neighbor(tmp, z, CHUNK_DIMS) {
dbg!((x, block));
(x, block)
} else {
match z {
Top => panic!(
"\nIn-Game Error: \nMaximum build limit has been reached"
),
Bottom => {
panic!("\nIn-Game Error: \nCan't build lower than y = 0.")
}
Right => ([x[0] + 1, x[1]], tmp - WIDTH + 1),
Left => ([x[0] - 1, x[1]], tmp + WIDTH - 1),
Back => ([x[0], x[1] + 1], tmp - WIDTH * (LENGTH - 1)),
Forward => ([x[0], x[1] - 1], tmp + WIDTH * (LENGTH - 1)),
}
}
})
.collect(),
});
}
}
}

fn blocks_in_the_way(pos: Vec3, forward: Vec3, distance: u8) -> Vec<([i32; 2], [usize; 3], Face)> {
let step = forward * RAY_FORWARD_STEP;
let mut point = pos;
let mut current_block = [
point.x.floor() + 0.5,
point.y.floor() + 0.5,
point.z.floor() + 0.5,
];
let mut to_return: Vec<([i32; 2], [usize; 3], Face)> = vec![];

while point.distance(pos) < distance as f32 {
point += step;
let tmp = [
point.x.floor() + 0.5,
point.y.floor() + 0.5,
point.z.floor() + 0.5,
];
if tmp != current_block {
current_block = tmp;
let face = {
let mut r: Face = Top;
let mut p = point - step;
let nano_step = step / 20.0;
for _ in 1..21 {
p += nano_step;
let tmp = [p.x.floor() + 0.5, p.y.floor() + 0.5, p.z.floor() + 0.5];
if tmp == current_block {
r = closest_face(p);
break;
}
}
r
};
let block_pos = position_to_chunk_position(point, CHUNK_DIMS);
to_return.push((block_pos.0, block_pos.1, face));
}
}
to_return
}

fn closest_face(p: Vec3) -> Face {
let mut min = f32::MAX;
let mut face = Top;

if (p.x.floor() - p.x).abs() < min {
min = (p.x.floor() - p.x).abs();
face = Left;
}
if (p.x.ceil() - p.x).abs() < min {
min = (p.x.ceil() - p.x).abs();
face = Right;
}
if (p.z.floor() - p.z).abs() < min {
min = (p.z.floor() - p.z).abs();
face = Forward;
}
if (p.z.ceil() - p.z).abs() < min {
min = (p.z.ceil() - p.z).abs();
face = Back;
}
if (p.y.floor() - p.y).abs() < min {
min = (p.y.floor() - p.y).abs();
face = Bottom;
}
if (p.y.ceil() - p.y).abs() < min {
face = Top;
}
return face;
}
10 changes: 6 additions & 4 deletions src/block_reg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ pub const DIRT: Block = 1;
pub const GRASS: Block = 2;
pub const STONE: Block = 3;

pub const VOXEL_DIMS: [f32; 3] = [1.0, 1.0, 1.0];

#[derive(Resource, Clone)]
pub struct BlockRegistry {
grass_block: Mesh,
Expand All @@ -20,7 +22,7 @@ impl Default for BlockRegistry {
fn default() -> Self {
BlockRegistry {
grass_block: generate_voxel_mesh(
[1.0, 1.0, 1.0],
VOXEL_DIMS,
[4, 4],
[
(Top, [0, 0]),
Expand All @@ -32,7 +34,7 @@ impl Default for BlockRegistry {
],
),
dirt_block: generate_voxel_mesh(
[1.0, 1.0, 1.0],
VOXEL_DIMS,
[4, 4],
[
(Top, [2, 0]),
Expand All @@ -44,7 +46,7 @@ impl Default for BlockRegistry {
],
),
stone_block: generate_voxel_mesh(
[1.0, 1.0, 1.0],
VOXEL_DIMS,
[4, 4],
[
(Top, [3, 0]),
Expand All @@ -71,7 +73,7 @@ impl VoxelRegistry for BlockRegistry {
}

fn get_voxel_dimensions(&self) -> [f32; 3] {
[1.0, 1.0, 1.0]
VOXEL_DIMS
}

fn get_center(&self) -> [f32; 3] {
Expand Down
19 changes: 14 additions & 5 deletions src/chunk.rs
Original file line number Diff line number Diff line change
@@ -1,24 +1,33 @@
use crate::block_reg::{Block, AIR, DIRT, GRASS, STONE};
use bevy::prelude::Component;
use bevy_meshem::prelude::{Dimensions, MeshMD};
use bevy_meshem::prelude::*;
use noise::{NoiseFn, Perlin, Seedable};
const CHUNK_SIZE: usize = 16;
pub const CHUNK_DIMS: Dimensions = (CHUNK_SIZE, CHUNK_SIZE, CHUNK_SIZE);
pub const HEIGHT: usize = CHUNK_DIMS.2;
pub const WIDTH: usize = CHUNK_DIMS.0;
pub const LENGTH: usize = CHUNK_DIMS.1;
pub const CHUNK_LEN: usize = CHUNK_DIMS.0 * CHUNK_DIMS.1 * CHUNK_DIMS.2;
const NOISE_FACTOR_CONT: f64 = 0.015;
const NOISE_FACTOR_CONT: f64 = 0.020;
// has to be greater than 1.0
const NOISE_FACTOR_SCALE: f64 = 2.0;
const NOISE_FACTOR_SCALE: f64 = 1.8;

#[derive(Component)]
pub struct Chunk {
pub meta_data: MeshMD<Block>,
pub cords: [i32; 2],
pub compressed_chunk: Vec<(Block, usize)>,
// pub compressed_chunk: Vec<(Block, usize)>,
pub grid: [Block; CHUNK_LEN],
}

#[derive(Component)]
pub struct BlockChangeQueue {
pub block_queue: Vec<([usize; 3], VoxelChange)>,
}

#[derive(Component)]
pub struct ChunkCloseToPlayer;

pub fn generate_chunk(cords: [i32; 2], noise: &impl NoiseFn<f64, 2>) -> [u16; CHUNK_LEN] {
let mut height_map: [usize; CHUNK_DIMS.0 * CHUNK_DIMS.1] = [0; CHUNK_DIMS.0 * CHUNK_DIMS.1];
let mut chunk = [0; CHUNK_LEN];
Expand All @@ -38,7 +47,7 @@ pub fn generate_chunk(cords: [i32; 2], noise: &impl NoiseFn<f64, 2>) -> [u16; CH
for x in 0..CHUNK_DIMS.0 {
if height_map[x + z * CHUNK_DIMS.0] < y {
chunk[x + z * CHUNK_DIMS.0 + y * CHUNK_DIMS.0 * CHUNK_DIMS.1] = AIR;
} else if height_map[x + z * CHUNK_DIMS.0] == y {
} else if height_map[x + z * CHUNK_DIMS.0] == y && y > HEIGHT / 4 {
chunk[x + z * CHUNK_DIMS.0 + y * CHUNK_DIMS.0 * CHUNK_DIMS.1] = GRASS;
} else {
chunk[x + z * CHUNK_DIMS.0 + y * CHUNK_DIMS.0 * CHUNK_DIMS.1] = DIRT;
Expand Down
4 changes: 4 additions & 0 deletions src/chunk_queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ impl ChunkMap {
self.pos_to_ent.keys()
}

pub fn iter(&self) -> bevy::utils::hashbrown::hash_map::Iter<'_, [i32; 2], Entity> {
self.pos_to_ent.iter()
}

pub fn change_ent(&mut self, cords: [i32; 2], ent: Entity) {
*(self
.pos_to_ent
Expand Down
Loading

0 comments on commit bfac205

Please sign in to comment.