Collision
This commit is contained in:
@@ -12,6 +12,7 @@ import { DimensionLogicSystem } from "./systems/dimension_logic.ts";
|
||||
import { Dimension } from "./components/dimension.ts";
|
||||
import { GuiRenderSystem, GuiTickSystem } from "./gui/gui_systems.ts";
|
||||
import { WorldGenerationSystem } from "./systems/world_generation_system.ts";
|
||||
import { CollisionSystem } from "./systems/collision_system.ts";
|
||||
|
||||
export class ClientWorld extends World {
|
||||
paused = false;
|
||||
@@ -40,9 +41,10 @@ export class ClientWorld extends World {
|
||||
this.add_system(new UIInteractionSystem(), "paused");
|
||||
this.add_system(new GuiTickSystem(), "game");
|
||||
this.add_system(new PlayerControlsSystem(), "game");
|
||||
this.add_system(new MovementSystem(), "game");
|
||||
this.add_system(new WorldGenerationSystem(), "game");
|
||||
this.add_system(new DimensionLogicSystem(), "game");
|
||||
this.add_system(new CollisionSystem(), "game");
|
||||
this.add_system(new MovementSystem(), "game");
|
||||
|
||||
// render systems
|
||||
this.add_system(new RenderSystem(), "game");
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
import { Component } from "$/common/ecs/mod.ts";
|
||||
|
||||
export class CollisionCuboid extends Component {
|
||||
width: number;
|
||||
height: number;
|
||||
depth: number;
|
||||
gravity: number;
|
||||
|
||||
colliding_x: number = 0;
|
||||
colliding_y: number = 0;
|
||||
colliding_z: number = 0;
|
||||
|
||||
constructor(width: number, height: number, depth: number, gravity = -9.8) {
|
||||
super();
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.depth = depth;
|
||||
this.gravity = gravity;
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@ import { Component } from "$/common/ecs/mod.ts";
|
||||
import { KeyCode } from "$/client/input_manager.ts";
|
||||
|
||||
export class PlayerControls extends Component {
|
||||
move_speed: number = 50;
|
||||
move_speed: number = 5;
|
||||
|
||||
// Keys
|
||||
move_forward: KeyCode = "KeyW";
|
||||
|
||||
+4
-2
@@ -6,6 +6,7 @@ import { ItemStack, PlayerInventory } from "./inventory.ts";
|
||||
import { PlayerControls } from "$/client/components/player_controls.ts";
|
||||
import { ClientWorld } from "./client_world.ts";
|
||||
import { GuiScreen } from "./gui/gui_screen.ts";
|
||||
import { CollisionCuboid } from "./components/collision.ts";
|
||||
|
||||
export class PlayerComponent extends Component {
|
||||
player_inventory = new PlayerInventory("");
|
||||
@@ -22,8 +23,8 @@ export class PlayerComponent extends Component {
|
||||
|
||||
export function create_player(world: ClientWorld) {
|
||||
const player = new Entity("player");
|
||||
player.add(new Position(0, 0));
|
||||
player.add(new Velocity(0, 0));
|
||||
player.add(new Position(0, 100, 0));
|
||||
player.add(new Velocity(0, 0, 0));
|
||||
player.add(new PlayerControls());
|
||||
|
||||
player.add(new PlayerComponent());
|
||||
@@ -40,6 +41,7 @@ export function create_player(world: ClientWorld) {
|
||||
// player_inventory.container.add_item(new ItemStack("bworld:carrot_seeds", 64));
|
||||
player_inventory.container.add_item(new ItemStack("bworld:furnace", 1));
|
||||
player.add(new Camera());
|
||||
player.add(new CollisionCuboid(0.5, 1.79, 0.5));
|
||||
|
||||
world.add_entity(player);
|
||||
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
import { System } from "$/common/ecs/mod.ts";
|
||||
import { Position } from "$/common/components/position.ts";
|
||||
import { ClientWorld } from "../client_world.ts";
|
||||
import { CollisionCuboid } from "$/client/components/collision.ts";
|
||||
import { Velocity } from "$/common/components/velocity.ts";
|
||||
import { Dimension } from "../components/dimension.ts";
|
||||
|
||||
export class CollisionSystem extends System {
|
||||
override update(world: ClientWorld, delta: number): void {
|
||||
for (const entity of world.get_entities()) {
|
||||
const position = entity.get(Position);
|
||||
const velocity = entity.get(Velocity);
|
||||
const cuboid = entity.get(CollisionCuboid);
|
||||
|
||||
if (!position || !velocity || !cuboid) {
|
||||
continue;
|
||||
}
|
||||
|
||||
velocity.vy += cuboid.gravity * delta;
|
||||
|
||||
let new_position = position.clone();
|
||||
|
||||
new_position.x += velocity.vx * delta;
|
||||
|
||||
let collisions = this.check_collision(new_position, velocity, cuboid, world.dimension);
|
||||
|
||||
cuboid.colliding_x = collisions.x;
|
||||
if (collisions.x !== 0) {
|
||||
velocity.vx = 0;
|
||||
}
|
||||
|
||||
new_position = position.clone();
|
||||
|
||||
new_position.y += velocity.vy * delta;
|
||||
|
||||
collisions = this.check_collision(new_position, velocity, cuboid, world.dimension);
|
||||
|
||||
cuboid.colliding_y = collisions.y;
|
||||
if (collisions.y !== 0) {
|
||||
velocity.vy = 0;
|
||||
}
|
||||
|
||||
new_position = position.clone();
|
||||
|
||||
new_position.z += velocity.vz * delta;
|
||||
|
||||
collisions = this.check_collision(new_position, velocity, cuboid, world.dimension);
|
||||
|
||||
cuboid.colliding_z = collisions.z;
|
||||
if (collisions.z !== 0) {
|
||||
velocity.vz = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
check_collision(
|
||||
position: Position,
|
||||
velocity: Velocity,
|
||||
cuboid: CollisionCuboid,
|
||||
dimension: Dimension,
|
||||
): { x: number; y: number; z: number } {
|
||||
const collisions = { x: 0, y: 0, z: 0 };
|
||||
|
||||
const min_x = Math.floor(position.x - cuboid.width / 2);
|
||||
const max_x = Math.floor(position.x + cuboid.width / 2);
|
||||
const min_y = Math.floor(position.y);
|
||||
const max_y = Math.floor(position.y + cuboid.height);
|
||||
const min_z = Math.floor(position.z - cuboid.depth / 2);
|
||||
const max_z = Math.floor(position.z + cuboid.depth / 2);
|
||||
|
||||
for (let x = min_x; x <= max_x; x++) {
|
||||
for (let y = min_y; y <= max_y; y++) {
|
||||
for (let z = min_z; z <= max_z; z++) {
|
||||
const block = dimension.get_block(x, y, z);
|
||||
if (block && block !== 0) {
|
||||
if (velocity.vx > 0) {
|
||||
collisions.x = -1;
|
||||
}
|
||||
if (velocity.vx < 0) {
|
||||
collisions.x = 1;
|
||||
}
|
||||
if (velocity.vy > 0) {
|
||||
collisions.y = -1;
|
||||
}
|
||||
if (velocity.vy < 0) {
|
||||
collisions.y = 1;
|
||||
}
|
||||
if (velocity.vz > 0) {
|
||||
collisions.z = -1;
|
||||
}
|
||||
if (velocity.vz < 0) {
|
||||
collisions.z = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return collisions;
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@ import { Camera } from "../components/camera.ts";
|
||||
import { Position } from "../../common/components/position.ts";
|
||||
import { PlayerComponent } from "../player.ts";
|
||||
import { GuiPlayerInventory } from "../gui/gui_player_inventory.ts";
|
||||
import { CollisionCuboid } from "../components/collision.ts";
|
||||
|
||||
export class PlayerControlsSystem extends System {
|
||||
constructor() {
|
||||
@@ -55,12 +56,10 @@ export class PlayerControlsSystem extends System {
|
||||
velocity.vx = (forwardX * input_z + rightX * input_x) * controls.move_speed;
|
||||
velocity.vz = (forwardZ * input_z + rightZ * input_x) * controls.move_speed;
|
||||
|
||||
if (InputManager.is_key_down("Space")) {
|
||||
velocity.vy += controls.move_speed / 10;
|
||||
} else if (InputManager.is_key_down("ShiftLeft")) {
|
||||
velocity.vy -= controls.move_speed / 10;
|
||||
} else {
|
||||
velocity.vy = 0;
|
||||
const cuboid = player.get(CollisionCuboid);
|
||||
|
||||
if (InputManager.is_key_pressed("Space") && cuboid?.colliding_y === 1) {
|
||||
velocity.vy += controls.move_speed;
|
||||
}
|
||||
|
||||
if (InputManager.is_key_pressed(controls.open_inventory)) {
|
||||
|
||||
Reference in New Issue
Block a user