diff --git a/modules/io.github.xenfork.freeworld.client/src/main/java/io/github/xenfork/freeworld/client/Freeworld.java b/modules/io.github.xenfork.freeworld.client/src/main/java/io/github/xenfork/freeworld/client/Freeworld.java index a81dbe0..b8c3fb0 100644 --- a/modules/io.github.xenfork.freeworld.client/src/main/java/io/github/xenfork/freeworld/client/Freeworld.java +++ b/modules/io.github.xenfork.freeworld.client/src/main/java/io/github/xenfork/freeworld/client/Freeworld.java @@ -23,6 +23,7 @@ import io.github.xenfork.freeworld.world.block.BlockTypes; import io.github.xenfork.freeworld.world.entity.Entity; import io.github.xenfork.freeworld.world.entity.EntityTypes; +import io.github.xenfork.freeworld.world.entity.component.OnGroundComponent; import org.joml.Vector2d; import org.slf4j.Logger; import overrun.marshal.Unmarshal; @@ -176,18 +177,19 @@ private void onCursorPos(double x, double y) { private void tick() { camera.preUpdate(); - final double speed = glfw.getKey(window, GLFW.KEY_LEFT_CONTROL) == GLFW.PRESS ? 1.0 : 0.5; + final boolean onGround = player.hasComponent(OnGroundComponent.ID); + double speed = onGround ? 0.1 : 0.07; + if (glfw.getKey(window, GLFW.KEY_LEFT_CONTROL) == GLFW.PRESS) speed *= 2.0; double xo = 0.0; - double yo = 0.0; double zo = 0.0; if (glfw.getKey(window, GLFW.KEY_W) == GLFW.PRESS) zo -= 1.0; if (glfw.getKey(window, GLFW.KEY_S) == GLFW.PRESS) zo += 1.0; if (glfw.getKey(window, GLFW.KEY_A) == GLFW.PRESS) xo -= 1.0; if (glfw.getKey(window, GLFW.KEY_D) == GLFW.PRESS) xo += 1.0; - if (glfw.getKey(window, GLFW.KEY_LEFT_SHIFT) == GLFW.PRESS) yo -= 1.0; - if (glfw.getKey(window, GLFW.KEY_SPACE) == GLFW.PRESS) yo += 1.0; - player.acceleration().value().set(xo, yo, zo).mul(speed); - player.velocity().value().zero(); + if (onGround && glfw.getKey(window, GLFW.KEY_SPACE) == GLFW.PRESS) { + player.velocity().value().y = 0.5; + } + player.acceleration().value().set(xo, 0.0, zo).mul(speed); world.tick(); if (blockDestroyTimer >= 2) { diff --git a/modules/io.github.xenfork.freeworld.core/src/main/java/io/github/xenfork/freeworld/world/entity/Entity.java b/modules/io.github.xenfork.freeworld.core/src/main/java/io/github/xenfork/freeworld/world/entity/Entity.java index d9eec03..27b2aeb 100644 --- a/modules/io.github.xenfork.freeworld.core/src/main/java/io/github/xenfork/freeworld/world/entity/Entity.java +++ b/modules/io.github.xenfork.freeworld.core/src/main/java/io/github/xenfork/freeworld/world/entity/Entity.java @@ -51,6 +51,10 @@ public void setComponent(EntityComponent component) { componentMap.put(component.componentId(), component); } + public void removeComponent(Identifier id) { + componentMap.remove(id); + } + @SuppressWarnings("unchecked") public T getComponent(Identifier id) { return (T) componentMap.get(id); diff --git a/modules/io.github.xenfork.freeworld.core/src/main/java/io/github/xenfork/freeworld/world/entity/component/EntityComponent.java b/modules/io.github.xenfork.freeworld.core/src/main/java/io/github/xenfork/freeworld/world/entity/component/EntityComponent.java index 0593276..89deb78 100644 --- a/modules/io.github.xenfork.freeworld.core/src/main/java/io/github/xenfork/freeworld/world/entity/component/EntityComponent.java +++ b/modules/io.github.xenfork.freeworld.core/src/main/java/io/github/xenfork/freeworld/world/entity/component/EntityComponent.java @@ -16,7 +16,14 @@ * @author squid233 * @since 0.1.0 */ -public sealed interface EntityComponent permits BoundingBoxComponent, AccelerationComponent, EyeHeightComponent, PositionComponent, RotationXYComponent, VelocityComponent { +public sealed interface EntityComponent permits + AccelerationComponent, + BoundingBoxComponent, + EyeHeightComponent, + OnGroundComponent, + PositionComponent, + RotationXYComponent, + VelocityComponent { /** * {@return a unique identifier of this component} */ diff --git a/modules/io.github.xenfork.freeworld.core/src/main/java/io/github/xenfork/freeworld/world/entity/component/OnGroundComponent.java b/modules/io.github.xenfork.freeworld.core/src/main/java/io/github/xenfork/freeworld/world/entity/component/OnGroundComponent.java new file mode 100644 index 0000000..5d90247 --- /dev/null +++ b/modules/io.github.xenfork.freeworld.core/src/main/java/io/github/xenfork/freeworld/world/entity/component/OnGroundComponent.java @@ -0,0 +1,27 @@ +/* + * freeworld - 3D sandbox game + * Copyright (C) 2024 XenFork Union + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + */ + +package io.github.xenfork.freeworld.world.entity.component; + +import io.github.xenfork.freeworld.core.Identifier; + +/** + * @author squid233 + * @since 0.1.0 + */ +public final class OnGroundComponent implements EntityComponent { + public static final Identifier ID = Identifier.ofBuiltin("on_ground"); + public static final OnGroundComponent INSTANCE = new OnGroundComponent(); + + @Override + public Identifier componentId() { + return ID; + } +} diff --git a/modules/io.github.xenfork.freeworld.core/src/main/java/io/github/xenfork/freeworld/world/entity/system/MotionSystem.java b/modules/io.github.xenfork.freeworld.core/src/main/java/io/github/xenfork/freeworld/world/entity/system/MotionSystem.java index dd72a5a..f6d5be3 100644 --- a/modules/io.github.xenfork.freeworld.core/src/main/java/io/github/xenfork/freeworld/world/entity/system/MotionSystem.java +++ b/modules/io.github.xenfork.freeworld.core/src/main/java/io/github/xenfork/freeworld/world/entity/system/MotionSystem.java @@ -45,7 +45,7 @@ public void process(World world, List entities) { velocity.add(acceleration); MathUtil.moveRelative(velocity.x(), velocity.y(), velocity.z(), rotation.y(), movement); - AABBox boundingBox = null; + AABBox boundingBox; if (entity.hasComponent(BoundingBoxComponent.ID)) { boundingBox = entity.boundingBox().value(); @@ -73,9 +73,16 @@ public void process(World world, List entities) { } } + final double originMovementY = movement.y(); for (AABBox box : boxes) { movement.y = box.clipYCollide(boundingBox, movement.y()); } + if (originMovementY != movement.y && originMovementY < 0.0) { + velocity.y = 0.0; + entity.addComponent(OnGroundComponent.INSTANCE); + } else { + entity.removeComponent(OnGroundComponent.ID); + } position.y += movement.y(); boundingBox = computeBox(boundingBox, position); @@ -95,7 +102,8 @@ public void process(World world, List entities) { position.add(movement); } - velocity.mul(0.5); + velocity.y -= 0.08; + velocity.mul(0.8, 0.98, 0.8); } } }