Rewrote Camera Movement to be FPS consistent

In the future, CameraEntity.MAX_SPEED (and derived variables) can be modified to change the Camera Movement Speed and Acceleration.
This commit is contained in:
CrushedPixel
2015-06-03 02:30:40 +02:00
parent acdce121ba
commit 0cca67a552
5 changed files with 125 additions and 101 deletions

View File

@@ -102,6 +102,8 @@ public class ReplayMod {
MinecraftForge.EVENT_BUS.register(guiEventHandler = new GuiEventHandler());
FMLCommonHandler.instance().bus().register(keyInputHandler);
MinecraftForge.EVENT_BUS.register(keyInputHandler);
FMLCommonHandler.instance().bus().register(mouseInputHandler);
MinecraftForge.EVENT_BUS.register(mouseInputHandler);
recordingHandler = new RecordingHandler();

View File

@@ -18,10 +18,12 @@ import org.lwjgl.Sys;
public class CameraEntity extends EntityPlayer {
private static final double MAX_SPEED = 20;
private static final double MAX_SPEED = 10;
private static final double THRESHOLD = MAX_SPEED / 20;
private static final double DECAY = MAX_SPEED/3;
private Vec3 direction;
private double motion;
private double decay = 4;
private final Minecraft mc = Minecraft.getMinecraft();
@@ -56,7 +58,22 @@ public class CameraEntity extends EntityPlayer {
//frac = time since last tick
public void updateMovement() {
Minecraft mc = Minecraft.getMinecraft();
long frac = Sys.getTime() - lastCall;
if(frac == 0) return;
double decFac = Math.max(0, 1 - (DECAY * (frac / 1000D)));
if(speedup) {
if(motion < THRESHOLD) motion = THRESHOLD;
motion /= decFac;
} else {
motion *= decFac;
}
motion = Math.min(motion, MAX_SPEED);
if(ReplayHandler.getCameraEntity() != null && mc.thePlayer != null
&& mc.getRenderViewEntity() != null) {
//Aligns the particle rotation
@@ -69,36 +86,26 @@ public class CameraEntity extends EntityPlayer {
mc.thePlayer.posZ = 0;
}
if(direction == null || motion < 0.1) {
lastCall = Sys.getTime();
lastCall = Sys.getTime();
if(direction == null || motion < THRESHOLD) {
return;
}
long frac = Sys.getTime() - lastCall;
if(frac == 0) return;
Vec3 movement = direction.normalize();
double factor = motion * (frac / 1000D);
moveRelative(movement.xCoord * factor, movement.yCoord * factor, movement.zCoord * factor);
double decFac = Math.max(0, 1 - (decay * (frac / 1000D)));
if(!speedup) {
motion *= decFac;
} else {
speedup = false;
}
lastCall = Sys.getTime();
}
public void speedUp() {
this.motion = Math.min(MAX_SPEED, motion + 0.1);
speedup = true;
}
public void stopSpeedUp() {
speedup = false;
}
public void setMovement(MoveDirection dir) {
Vec3 oldDir = direction;
@@ -205,14 +212,14 @@ public class CameraEntity extends EntityPlayer {
}
public enum MoveDirection {
UP, DOWN, LEFT, RIGHT, FORWARD, BACKWARD;
UP, DOWN, LEFT, RIGHT, FORWARD, BACKWARD
}
@Override
public MovingObjectPosition rayTrace(double p_174822_1_, float p_174822_3_) {
MovingObjectPosition pos = super.rayTrace(p_174822_1_, 1f);
if(pos.typeOfHit == MovingObjectPosition.MovingObjectType.BLOCK) {
if(pos != null && pos.typeOfHit == MovingObjectPosition.MovingObjectType.BLOCK) {
pos.typeOfHit = MovingObjectPosition.MovingObjectType.MISS;
}

View File

@@ -2,104 +2,120 @@ package eu.crushedpixel.replaymod.events;
import eu.crushedpixel.replaymod.ReplayMod;
import eu.crushedpixel.replaymod.entities.CameraEntity.MoveDirection;
import eu.crushedpixel.replaymod.gui.GuiCancelRender;
import eu.crushedpixel.replaymod.gui.GuiKeyframeRepository;
import eu.crushedpixel.replaymod.gui.GuiMouseInput;
import eu.crushedpixel.replaymod.registry.KeybindRegistry;
import eu.crushedpixel.replaymod.replay.ReplayHandler;
import eu.crushedpixel.replaymod.replay.ReplayProcess;
import eu.crushedpixel.replaymod.registry.PlayerHandler;
import eu.crushedpixel.replaymod.replay.ReplayHandler;
import net.minecraft.client.Minecraft;
import net.minecraft.client.settings.KeyBinding;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.InputEvent.KeyInputEvent;
import org.lwjgl.LWJGLException;
import net.minecraftforge.fml.common.gameevent.InputEvent;
import org.lwjgl.Sys;
import org.lwjgl.input.Keyboard;
public class KeyInputHandler {
private final Minecraft mc = Minecraft.getMinecraft();
private boolean escDown = false;
private long prevKeysDown = Sys.getTime();
public void onKeyInput() throws Exception {
if(!Keyboard.isCreated()) Keyboard.create();
Keyboard.poll();
KeyBinding[] keyBindings = Minecraft.getMinecraft().gameSettings.keyBindings;
boolean speedup = false;
if(mc.currentScreen == null) {
for(KeyBinding kb : keyBindings) {
if(!ReplayMod.replaySender.paused() && !kb.isKeyDown()) continue;
//keyCode has to be positive, otherwise it's a Mouse key and will horribly crash
if(ReplayMod.replaySender.paused() && kb.getKeyCode() >= 0 && !Keyboard.isKeyDown(kb.getKeyCode()))
continue;
try {
if(ReplayHandler.isCamera()) {
if(kb.getKeyDescription().equals("key.forward")) {
ReplayHandler.getCameraEntity().setMovement(MoveDirection.FORWARD);
speedup = true;
}
if(kb.getKeyDescription().equals("key.back")) {
ReplayHandler.getCameraEntity().setMovement(MoveDirection.BACKWARD);
speedup = true;
}
if(kb.getKeyDescription().equals("key.jump")) {
ReplayHandler.getCameraEntity().setMovement(MoveDirection.UP);
speedup = true;
}
if(kb.getKeyDescription().equals("key.left")) {
ReplayHandler.getCameraEntity().setMovement(MoveDirection.LEFT);
speedup = true;
}
if(kb.getKeyDescription().equals("key.right")) {
ReplayHandler.getCameraEntity().setMovement(MoveDirection.RIGHT);
speedup = true;
}
}
if(kb.getKeyDescription().equals("key.sneak")) {
if(ReplayHandler.isCamera()) {
ReplayHandler.getCameraEntity().setMovement(MoveDirection.DOWN);
speedup = true;
} else {
ReplayHandler.spectateCamera();
}
}
} catch(Exception e) {
e.printStackTrace();
}
}
}
if(ReplayHandler.getCameraEntity() != null) {
if(speedup) {
ReplayHandler.getCameraEntity().speedUp();
prevKeysDown = Sys.getTime();
} else {
if(Sys.getTime() - prevKeysDown > 100) {
ReplayHandler.getCameraEntity().stopSpeedUp();
}
}
}
}
@SubscribeEvent
public void onKeyInput(KeyInputEvent event) throws LWJGLException {
if(!ReplayHandler.isInReplay()) return;
if(mc.currentScreen != null && !(mc.currentScreen instanceof GuiMouseInput)) {
return;
public void keyInput(InputEvent.KeyInputEvent event) {
try {
onKeyInput();
} catch(Exception e) {
e.printStackTrace();
}
if(Keyboard.getEventKeyState() && !Keyboard.isRepeatEvent() && Keyboard.isKeyDown(Keyboard.KEY_ESCAPE)
&& ReplayHandler.isInPath() && ReplayProcess.isVideoRecording()
&& mc.currentScreen == null && !escDown) {
mc.displayGuiScreen(new GuiCancelRender());
}
if(!Keyboard.isCreated()) Keyboard.create();
escDown = Keyboard.isKeyDown(Keyboard.KEY_ESCAPE) && Keyboard.getEventKeyState();
KeyBinding[] keyBindings = Minecraft.getMinecraft().gameSettings.keyBindings;
boolean found = false;
KeyBinding[] keyBindings = Minecraft.getMinecraft().gameSettings.keyBindings;
for(KeyBinding kb : keyBindings) {
if(!kb.isKeyDown()) {
continue;
if(!kb.isKeyDown()) continue;
if(kb.getKeyDescription().equals("key.chat") && kb.isPressed()) {
mc.displayGuiScreen(new GuiMouseInput(ReplayMod.overlay));
break;
}
try {
boolean speedup = false;
if(ReplayHandler.isCamera()) {
if(kb.getKeyDescription().equals("key.forward")) {
ReplayHandler.getCameraEntity().setMovement(MoveDirection.FORWARD);
speedup = true;
}
if(kb.getKeyDescription().equals("key.back")) {
ReplayHandler.getCameraEntity().setMovement(MoveDirection.BACKWARD);
speedup = true;
}
if(kb.getKeyDescription().equals("key.jump")) {
ReplayHandler.getCameraEntity().setMovement(MoveDirection.UP);
speedup = true;
}
if(kb.getKeyDescription().equals("key.left")) {
ReplayHandler.getCameraEntity().setMovement(MoveDirection.LEFT);
speedup = true;
}
if(kb.getKeyDescription().equals("key.right")) {
ReplayHandler.getCameraEntity().setMovement(MoveDirection.RIGHT);
speedup = true;
}
}
if(kb.getKeyDescription().equals("key.sneak")) {
if(ReplayHandler.isCamera()) {
ReplayHandler.getCameraEntity().setMovement(MoveDirection.DOWN);
speedup = true;
} else {
ReplayHandler.spectateCamera();
}
}
if(speedup) {
ReplayHandler.getCameraEntity().speedUp();
}
if(kb.getKeyDescription().equals("key.chat") && kb.isPressed()) {
mc.displayGuiScreen(new GuiMouseInput(ReplayMod.overlay));
break;
}
handleCustomKeybindings(kb, found, -1);
} catch(Exception e) {
e.printStackTrace();
}
handleCustomKeybindings(kb, found, -1);
found = true;
}
}
public void handleCustomKeybindings(KeyBinding kb, boolean found, int keyCode) {

View File

@@ -10,6 +10,7 @@ import net.minecraft.entity.Entity;
import net.minecraft.util.MathHelper;
import net.minecraft.util.ReportedException;
import net.minecraftforge.client.event.MouseEvent;
import org.lwjgl.LWJGLException;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
@@ -18,7 +19,8 @@ import java.lang.reflect.InvocationTargetException;
public class MinecraftTicker {
public static void runMouseKeyboardTick(Minecraft mc) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, IOException {
public static void runMouseKeyboardTick(Minecraft mc) throws IllegalAccessException, IllegalArgumentException,
InvocationTargetException, IOException, LWJGLException {
ReplayMod.mouseInputHandler.mouseEvent(new MouseEvent());
if(mc.thePlayer == null) return;
try {
@@ -201,6 +203,7 @@ public class MinecraftTicker {
}
}
}
net.minecraftforge.fml.common.FMLCommonHandler.instance().fireKeyInput();
}

View File

@@ -15,9 +15,6 @@ import net.minecraftforge.fml.common.gameevent.TickEvent;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.Display;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
public class TickAndRenderListener {
private static Minecraft mc = Minecraft.getMinecraft();
@@ -35,8 +32,7 @@ public class TickAndRenderListener {
}
@SubscribeEvent
public void onRenderWorld(RenderWorldLastEvent event) throws
InvocationTargetException, IOException, IllegalAccessException, IllegalArgumentException {
public void onRenderWorld(RenderWorldLastEvent event) throws Exception {
if(!ReplayHandler.isInReplay()) return; //If not in Replay, cancel
if (ReplayProcess.isVideoRecording()) return; // If recording, cancel