fixed physics
This commit is contained in:
parent
d6d0ad0a85
commit
143707f925
10 changed files with 118 additions and 35 deletions
|
@ -14,20 +14,21 @@
|
|||
</classpathentry>
|
||||
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
|
||||
<attributes>
|
||||
<attribute name="test" value="true"/>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
<attribute name="test" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
<attribute name="optional" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-17">
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-21">
|
||||
<attributes>
|
||||
<attribute name="module" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
|
|
4
notes.txt
Normal file
4
notes.txt
Normal file
|
@ -0,0 +1,4 @@
|
|||
don't forget when detecting collisions with moving players I should first check if they already overlap, if yes then push the ball out
|
||||
if two players overlap with the ball then I don't know if you can combine the pushing do it if you can't push it away somehow
|
||||
away I mean so like the ball has the largest possible same angle to both players
|
||||
look I'm too young college how am I supposed to know things
|
6
pom.xml
6
pom.xml
|
@ -9,15 +9,15 @@
|
|||
<version>0.0.1-SNAPSHOT</version>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>17</maven.compiler.source>
|
||||
<maven.compiler.target>17</maven.compiler.target>
|
||||
<maven.compiler.source>21</maven.compiler.source>
|
||||
<maven.compiler.target>21</maven.compiler.target>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>net.minestom</groupId>
|
||||
<artifactId>minestom-snapshots</artifactId>
|
||||
<version>90fb708739</version>
|
||||
<version>d606051f1e</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ package net.pivipi;
|
|||
import net.minestom.server.coordinate.Pos;
|
||||
import net.minestom.server.entity.GameMode;
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.entity.attribute.Attribute;
|
||||
import net.minestom.server.event.GlobalEventHandler;
|
||||
import net.minestom.server.event.player.AsyncPlayerConfigurationEvent;
|
||||
import net.minestom.server.event.player.PlayerDisconnectEvent;
|
||||
|
@ -33,7 +34,7 @@ public class LoginHandler {
|
|||
event.setSpawningInstance(spawningInstance);
|
||||
event.setHardcore(true);
|
||||
|
||||
player.setRespawnPoint(new Pos(0, 5, 0));
|
||||
player.setRespawnPoint(new Pos(5, 5, 0));
|
||||
stadium.players.add(player);
|
||||
}
|
||||
|
||||
|
@ -45,11 +46,13 @@ public class LoginHandler {
|
|||
Player player = event.getPlayer();
|
||||
|
||||
player.setGameMode(GameMode.CREATIVE);
|
||||
player.getAttribute(Attribute.GENERIC_MOVEMENT_SPEED).setBaseValue(0.2);
|
||||
player.getAttribute(Attribute.GENERIC_JUMP_STRENGTH).setBaseValue(0.36813); // just enough to jump a block
|
||||
|
||||
if (stadium.ball == null) {
|
||||
Ball ball = new Ball(stadium);
|
||||
ball.setInstance(event.getInstance());
|
||||
ball.teleport(new Pos(0.5, 15, 0.5));
|
||||
ball.teleport(new Pos(0, 15, 0));
|
||||
stadium.ball = ball;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,14 +8,13 @@ import net.minestom.server.instance.InstanceManager;
|
|||
import net.minestom.server.instance.LightingChunk;
|
||||
import net.minestom.server.registry.DynamicRegistry.Key;
|
||||
import net.minestom.server.world.DimensionType;
|
||||
import net.pivipi.ball.BallKicker;
|
||||
import net.pivipi.world.FancyDimension;
|
||||
import net.pivipi.world.SoccerGenerator;
|
||||
import net.pivipi.world.WorldConstraints;
|
||||
|
||||
public class Main {
|
||||
public static void main(String[] args) {
|
||||
System.setProperty("minestom.tps", "60");
|
||||
System.setProperty("minestom.tps", "100");
|
||||
|
||||
MinecraftServer minecraftServer = MinecraftServer.init();
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@ import net.minestom.server.coordinate.Vec;
|
|||
import net.minestom.server.entity.Entity;
|
||||
import net.minestom.server.entity.EntityType;
|
||||
import net.minestom.server.entity.metadata.other.FallingBlockMeta;
|
||||
import net.minestom.server.event.player.PlayerDisconnectEvent;
|
||||
import net.minestom.server.instance.block.Block;
|
||||
import net.pivipi.physics.Physics;
|
||||
import net.pivipi.world.Stadium;
|
||||
|
@ -19,7 +18,6 @@ public class Ball extends Entity {
|
|||
super(EntityType.FALLING_BLOCK); // not block display because its movement lags for some reason
|
||||
|
||||
this.setNoGravity(true);
|
||||
this.setGlowing(true);
|
||||
this.hasPhysics = true;
|
||||
|
||||
this.editEntityMeta(FallingBlockMeta.class, meta -> {
|
||||
|
@ -41,7 +39,7 @@ public class Ball extends Entity {
|
|||
|
||||
long delay = time - this.lastTick;
|
||||
|
||||
physics.applyPhysics(delay / 1000.0, stadium.players);
|
||||
physics.process(delay / 1000.0, stadium.players);
|
||||
|
||||
this.lastTick = time;
|
||||
}
|
||||
|
|
|
@ -1,22 +1,13 @@
|
|||
package net.pivipi.ball;
|
||||
|
||||
import java.awt.Event;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import net.minestom.server.MinecraftServer;
|
||||
import net.minestom.server.ServerFlag;
|
||||
import net.minestom.server.collision.VisibleSweepResult;
|
||||
import net.minestom.server.coordinate.Point;
|
||||
import net.minestom.server.coordinate.Pos;
|
||||
import net.minestom.server.coordinate.Vec;
|
||||
import net.minestom.server.entity.Entity;
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.event.GlobalEventHandler;
|
||||
import net.minestom.server.event.player.PlayerMoveEvent;
|
||||
import net.minestom.server.event.player.PlayerStartSneakingEvent;
|
||||
import net.minestom.server.event.player.PlayerStopSneakingEvent;
|
||||
import net.minestom.server.instance.Instance;
|
||||
import net.pivipi.physics.Collision;
|
||||
import net.pivipi.world.Stadium;
|
||||
|
||||
|
@ -26,6 +17,11 @@ public class BallKicker { // TODO apply physics settings here
|
|||
private long lastSneak;
|
||||
private int sneakStreak;
|
||||
|
||||
private double headHeight = 0.3; // too low head kicks will be broken too high normal kicks will be broken
|
||||
private double touchStrength = 1; // when the player walks into a ball
|
||||
private double headJumpStrength = 5; // when the player jumps with a ball on their head, this is multiplied by touchstrength
|
||||
private double dragDownStrength = 1; // when the player touches a ball
|
||||
|
||||
public BallKicker(Stadium stadium) {
|
||||
this.stadium = stadium;
|
||||
}
|
||||
|
@ -36,15 +32,66 @@ public class BallKicker { // TODO apply physics settings here
|
|||
globalEventHandler.addListener(PlayerStopSneakingEvent.class, event -> onStopSneaking(event));
|
||||
}
|
||||
|
||||
private void onMove(PlayerMoveEvent event) {
|
||||
private void onMove(PlayerMoveEvent event) { // is width x
|
||||
Player player = event.getPlayer();
|
||||
Vec movementVec = player.getPosition().sub(player.getPreviousPosition()).asVec();
|
||||
|
||||
Pos deltaPos = player.getPosition().sub(player.getPreviousPosition());// TODO
|
||||
boolean collides = Collision.collidesWithEntity(stadium.ball, player);
|
||||
if (collides) {
|
||||
System.out.println(deltaPos);
|
||||
stadium.ball.addPos(deltaPos.asVec());
|
||||
stadium.ball.addVelocity(deltaPos.asVec().mul(2, 2, 2));
|
||||
double ballXSize = stadium.ball.getBoundingBox().width();
|
||||
double playerXSize = player.getBoundingBox().width();
|
||||
double ballZSize = stadium.ball.getBoundingBox().depth();
|
||||
double playerZSize = player.getBoundingBox().depth();
|
||||
double ballHeight = stadium.ball.getBoundingBox().height();
|
||||
double playerHeight = player.getBoundingBox().height();
|
||||
Pos ballCenterPos = stadium.ball.getPosition();
|
||||
Pos playerCenterPos = event.getNewPosition();
|
||||
|
||||
Pos ballPos = ballCenterPos.sub(ballXSize / 2, 0, ballZSize / 2);
|
||||
Pos playerPos = playerCenterPos.sub(playerXSize / 2, 0, playerZSize / 2);
|
||||
Vec ballDistance = ballCenterPos.sub(playerCenterPos).asVec();
|
||||
|
||||
|
||||
if (ballDistance.y() > 0) {
|
||||
if (ballPos.y() > playerPos.y() + playerHeight) return;
|
||||
} else {
|
||||
if (playerPos.y() > ballPos.y() + ballHeight) return;
|
||||
}
|
||||
|
||||
Vec newBallOffset = new Vec(0);
|
||||
double diffX = 0, diffZ = 0;
|
||||
|
||||
if (ballDistance.x() > 0) {
|
||||
diffX = ballPos.x() - (playerPos.x() + playerXSize);
|
||||
if (diffX < 0) // collides on x+
|
||||
newBallOffset = newBallOffset.withX(-diffX);
|
||||
} else {
|
||||
diffX = playerPos.x() - (ballPos.x() + ballXSize);
|
||||
if (diffX < 0) // collides on x-
|
||||
newBallOffset = newBallOffset.withX(diffX);
|
||||
}
|
||||
|
||||
if (ballDistance.z() > 0) {
|
||||
diffZ = ballPos.z() - (playerPos.z() + playerZSize);
|
||||
if (diffZ < 0)
|
||||
newBallOffset = newBallOffset.withZ(-diffZ);
|
||||
} else {
|
||||
diffZ = playerPos.z() - (ballPos.z() + ballZSize);
|
||||
if (diffZ < 0)
|
||||
newBallOffset = newBallOffset.withZ(diffZ);
|
||||
ballDistance = ballDistance.withY(-dragDownStrength);
|
||||
}
|
||||
|
||||
if (diffX < 0 && diffZ < 0) {
|
||||
if (ballPos.y() - player.getPreviousPosition().y() > playerHeight - headHeight) { // ball on head
|
||||
System.out.println("jumped");
|
||||
double jumpHeight = movementVec.y();
|
||||
if (jumpHeight == 0) return;
|
||||
newBallOffset = new Vec(0, jumpHeight, 0);
|
||||
ballDistance = ballDistance.withY(headJumpStrength);
|
||||
}
|
||||
|
||||
stadium.ball.addPos(diffX < diffZ ? newBallOffset.withX(0) : newBallOffset.withZ(0));
|
||||
stadium.ball.addVelocity(ballDistance.mul(touchStrength));
|
||||
System.out.println(ballDistance);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,6 @@ import net.minestom.server.collision.SweepResult;
|
|||
import net.minestom.server.collision.VisibleSweepResult;
|
||||
import net.minestom.server.coordinate.Vec;
|
||||
import net.minestom.server.entity.Entity;
|
||||
import net.minestom.server.entity.Player;
|
||||
|
||||
public class Collision {
|
||||
/**
|
||||
|
|
|
@ -6,6 +6,8 @@ import net.minestom.server.collision.VisibleSweepResult;
|
|||
import net.minestom.server.coordinate.Vec;
|
||||
import net.minestom.server.entity.Entity;
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.network.packet.server.play.ParticlePacket;
|
||||
import net.minestom.server.particle.Particle;
|
||||
|
||||
public class Physics {
|
||||
private final double gravity = 9.8;
|
||||
|
@ -13,18 +15,47 @@ public class Physics {
|
|||
private final double playerHeadBounciness = 0.5;
|
||||
private final double playerSneakingHeadBounciness = 0.2;
|
||||
private final double playerBodyBounciness = 0.2;
|
||||
private final double playerSneakingBodyBounciness = 0;
|
||||
private final double groundFriction = 0.5;
|
||||
private final double airFriction = 0.1;
|
||||
|
||||
private final double flame = 20; // flame starts at speed
|
||||
private final double flameFreq = 100; // ms per flame
|
||||
private final double flameIncrement = 0.5; // ms per flame decrement per speed unit
|
||||
private final float flameSpread = 0.2f;
|
||||
|
||||
private Vec velocity = new Vec(0, 0, 0);
|
||||
|
||||
private final Entity entity;
|
||||
private int p;
|
||||
|
||||
public Physics(Entity entity) {
|
||||
this.entity = entity;
|
||||
}
|
||||
|
||||
public void applyPhysics(double delta, Set<Player> players) {
|
||||
public void process(double delta, Set<Player> players) {
|
||||
velocity = applyPhysics(delta, players);
|
||||
entity.teleport(entity.getPosition().add(velocity.mul(delta)));
|
||||
|
||||
double dist = velocity.distance(0, 0, 0);
|
||||
if (dist > flame) {
|
||||
int f = (int) (flameFreq - (dist - flame) * flameIncrement);
|
||||
p += delta * 1000;
|
||||
|
||||
if (p < f) return;
|
||||
else p = 0;
|
||||
|
||||
float offset = 0.5f;
|
||||
int count = (int) (f > delta / 1000 ? f / delta / 1000 : 1);
|
||||
System.out.println(f);
|
||||
System.out.println(dist);
|
||||
System.out.println(count);
|
||||
|
||||
entity.getInstance().sendGroupedPacket(new ParticlePacket(Particle.FLAME, false, entity.getPosition().x(), entity.getPosition().y() + 0.5, entity.getPosition().z(), offset, offset, offset, flameSpread, count));
|
||||
}
|
||||
}
|
||||
|
||||
public Vec applyPhysics(double delta, Set<Player> players) {
|
||||
velocity = velocity.sub(0, gravity * delta, 0).mul(1 - (airFriction * delta), 1, 1 - (airFriction * delta));
|
||||
|
||||
if (Collision.collidesWithGround(2, entity)) {
|
||||
|
@ -39,16 +70,18 @@ public class Physics {
|
|||
for (Player player : players) {
|
||||
boolean collides = Collision.collidesWithEntity(player, entity);
|
||||
if (collides) {
|
||||
velocity = velocity.mul(-playerBodyBounciness, player.isSneaking() ? -playerSneakingHeadBounciness : -playerHeadBounciness, -playerBodyBounciness);
|
||||
if (player.isSneaking())
|
||||
velocity = velocity.mul(-playerSneakingBodyBounciness, -playerSneakingHeadBounciness, -playerSneakingBodyBounciness);
|
||||
else velocity = velocity.mul(-playerBodyBounciness, -playerHeadBounciness, -playerBodyBounciness);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
entity.teleport(entity.getPosition().add(velocity.mul(delta)));
|
||||
//entity.setVelocity(velocity);
|
||||
return velocity;
|
||||
}
|
||||
|
||||
|
||||
public void addVelocity(Vec velocity) {
|
||||
this.velocity = this.velocity.add(velocity);
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@ import java.util.Set;
|
|||
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.pivipi.ball.Ball;
|
||||
import net.pivipi.ball.BallKicker;
|
||||
|
||||
public class Stadium {
|
||||
public final Set<Player> players = new HashSet<Player>();
|
||||
|
|
Loading…
Reference in a new issue