From 180aad05decc7eefa87e4e45d6747c48f40e5361 Mon Sep 17 00:00:00 2001 From: Tyler Murphy Date: Mon, 17 Apr 2023 12:12:01 -0400 Subject: save --- .../net/tylermurphy/Minecraft/Scene/Camera.java | 74 +++++++++++++++ .../Minecraft/Scene/Objects/Entity.java | 105 +++++++++++++++++++++ .../Minecraft/Scene/Objects/Renderable.java | 46 +++++++++ .../Minecraft/Scene/Objects/Transform.java | 59 ++++++++++++ .../Minecraft/Scene/Objects/WorldOrigin.java | 47 +++++++++ .../net/tylermurphy/Minecraft/Scene/Player.java | 100 ++++++++++++++++++++ .../net/tylermurphy/Minecraft/Scene/World.java | 89 +++++++++++++++++ 7 files changed, 520 insertions(+) create mode 100755 src/main/java/net/tylermurphy/Minecraft/Scene/Camera.java create mode 100755 src/main/java/net/tylermurphy/Minecraft/Scene/Objects/Entity.java create mode 100755 src/main/java/net/tylermurphy/Minecraft/Scene/Objects/Renderable.java create mode 100755 src/main/java/net/tylermurphy/Minecraft/Scene/Objects/Transform.java create mode 100755 src/main/java/net/tylermurphy/Minecraft/Scene/Objects/WorldOrigin.java create mode 100755 src/main/java/net/tylermurphy/Minecraft/Scene/Player.java create mode 100755 src/main/java/net/tylermurphy/Minecraft/Scene/World.java (limited to 'src/main/java/net/tylermurphy/Minecraft/Scene') diff --git a/src/main/java/net/tylermurphy/Minecraft/Scene/Camera.java b/src/main/java/net/tylermurphy/Minecraft/Scene/Camera.java new file mode 100755 index 0000000..9752998 --- /dev/null +++ b/src/main/java/net/tylermurphy/Minecraft/Scene/Camera.java @@ -0,0 +1,74 @@ +package net.tylermurphy.Minecraft.Scene; + +import java.io.Serializable; + +import org.joml.Vector3f; + +import net.tylermurphy.Minecraft.Input.Input; +import net.tylermurphy.Minecraft.Render.Data.Display; + +public class Camera implements Serializable { + + private static final long serialVersionUID = -2612670500762524881L; + + protected Vector3f position = new Vector3f(0, 0, 0); + protected float pitch = 0; + protected float yaw = 0; + protected float roll = 0; + + public void move(){ + if(!World.player.isPaused) { + calculatePitch(); + calculateYaw(); + } + calculateCameraPosition(); + + yaw%=360; + } + + public void invertPitch(){ + this.pitch = -pitch; + } + + public Vector3f getPosition() { + return position; + } + + public float getPitch() { + return pitch; + } + + public float getYaw() { + return yaw; + } + + public float getRoll() { + return roll; + } + + public void calculateCameraPosition(){ + position.x = World.player.getTransform().getPosition().x; + position.z = World.player.getTransform().getPosition().z; + position.y = World.player.getTransform().getPosition().y + 10; + } + + protected void calculatePitch(){ + if(Display.closed()) { + float pitchChange = (float) (Input.getMouseDY() * 0.3f); + pitch -= pitchChange; + if(pitch < -90){ + pitch = -90; + }else if(pitch > 90){ + pitch = 90; + } + } + } + + protected void calculateYaw(){ + if(Display.closed()) { + float angleChange = (float) (Input.getMouseDX() * 0.4f); + yaw += angleChange; + } + } + +} diff --git a/src/main/java/net/tylermurphy/Minecraft/Scene/Objects/Entity.java b/src/main/java/net/tylermurphy/Minecraft/Scene/Objects/Entity.java new file mode 100755 index 0000000..b2e69f4 --- /dev/null +++ b/src/main/java/net/tylermurphy/Minecraft/Scene/Objects/Entity.java @@ -0,0 +1,105 @@ +package net.tylermurphy.Minecraft.Scene.Objects; + +import java.io.Serializable; + +import net.tylermurphy.Minecraft.Scene.World; +import org.joml.Vector3f; + +import net.tylermurphy.Minecraft.Chunk.Cube; + +public class Entity extends Renderable implements Serializable{ + + private static final long serialVersionUID = -1273546184611580473L; + + protected static final float RUN_SPEED = 4; + protected static final float JUMP_POWER = 6; + protected static final float GRAVITY = -15; + + protected float currentForwardSpeed = 0; + protected float currentSideSpeed = 0; + protected float upwardsSpeed = 0; + + public boolean isInAir = true; + public boolean isFlying = false; + public boolean isSwimming = false; + public boolean isBobbing = false; + public boolean isFalling = false; + public boolean wasFalling = false; + public boolean isDead = false; + + public Entity(Transform transform) { + super(null,transform,0); + } + + public boolean willCollide(float dx, float dy, float dz) { + float px = getTransform().getPosition().x; + float py = getTransform().getPosition().y; + float pz = getTransform().getPosition().z; + if(getTransform().getPosition().x<0) + px--; + if(getTransform().getPosition().z<0) + pz--; + int[] nbc = { + (int) (px+dx+.25f), + (int) (py+dy), + (int) (pz+dz+.25f), + (int) (px+dx+.75f), + (int) (py+dy+1.9f), + (int) (pz+dz+.75f) + }; + + for(int x = nbc[0]; x<=nbc[3]; x++) { + for(int y = nbc[1]; y<=nbc[4]; y++) { + for(int z = nbc[2]; z<=nbc[5]; z++) { + byte block_head = World.getBlock(x,y,z); + byte block_current_feet = World.getBlock(x,(int)(py),z); + byte block_current_upper = World.getBlock(x,(int)(py+1f),z); + byte block_current_lower = World.getBlock(x,(int)(py+.75f),z); + if(block_current_feet == 17 ) { + isSwimming = true; + isBobbing = false; + } + if(block_current_feet == 17 && block_current_lower == 17 && block_current_upper == Cube.AIR){ + isSwimming = false; + isBobbing = true; + } + if(block_current_feet != 17) { + isSwimming = false; + isBobbing = false; + } + if(dy != 0) { + if(block_head != Cube.AIR && block_head != 17) { + isInAir = !(y <= getTransform().getGlobalPosition().y); + return false; + } else isInAir = true; + }else { + if(block_head != Cube.AIR && block_head != 17) return false; + } + } + } + } + return true; + } + + public boolean collides(float x, float y, float z) { + float px = getTransform().getPosition().x; + float py = getTransform().getPosition().y; + float pz = getTransform().getPosition().z; + if(getTransform().getPosition().x<0) + px--; + if(getTransform().getPosition().z<0) + pz--; + int[] nbc = { + (int) (px+.25f), + (int) (py), + (int) (pz+.25f), + (int) (px+.75f), + (int) (py+1.9f), + (int) (pz+.75f) + }; + return x >= nbc[0] && x <= nbc[3] && + y >= nbc[1] && y <= nbc[4] && + z >= nbc[2] && z <= nbc[5]; + } + +} diff --git a/src/main/java/net/tylermurphy/Minecraft/Scene/Objects/Renderable.java b/src/main/java/net/tylermurphy/Minecraft/Scene/Objects/Renderable.java new file mode 100755 index 0000000..476e2c6 --- /dev/null +++ b/src/main/java/net/tylermurphy/Minecraft/Scene/Objects/Renderable.java @@ -0,0 +1,46 @@ +package net.tylermurphy.Minecraft.Scene.Objects; + +import java.io.Serializable; + +import net.tylermurphy.Minecraft.Render.Data.Mesh; + +public class Renderable implements Serializable { + + private static final long serialVersionUID = -5017401455504595815L; + + public Renderable(Mesh mesh, Transform transform, int texture) { + this.mesh = mesh; + this.transform = transform; + this.texture = texture; + } + + private Transform transform; + private Mesh mesh; + private int texture; + + public Mesh getMesh() { + return mesh; + } + + public void setMesh(Mesh mesh) { + this.mesh = mesh; + } + + public int getTexture(){ + return texture; + } + + public void setTexture(int texture){ + this.texture = texture; + } + + public Transform getTransform(){ + if(transform == null) this.transform = new Transform(); + return transform; + } + + public void setTransform(Transform transform){ + this.transform = transform; + } + +} diff --git a/src/main/java/net/tylermurphy/Minecraft/Scene/Objects/Transform.java b/src/main/java/net/tylermurphy/Minecraft/Scene/Objects/Transform.java new file mode 100755 index 0000000..2da820f --- /dev/null +++ b/src/main/java/net/tylermurphy/Minecraft/Scene/Objects/Transform.java @@ -0,0 +1,59 @@ +package net.tylermurphy.Minecraft.Scene.Objects; + +import net.tylermurphy.Minecraft.Scene.World; +import org.joml.Vector3f; + +public class Transform { + + private Vector3f position = new Vector3f(0f, 0f, 0f); + private Vector3f rotation = new Vector3f(0f, 0f, 0f); + private float scale = 1.0f; + + public Transform setPosition(Vector3f position){ + this.position = position; + return this; + } + + public Transform setGlobalPosition(Vector3f position) { + this.position = new Vector3f( + position.x - World.world_origin.x(), + position.y, + position.z - World.world_origin.z() + ); + return this; + } + + public Transform increasePosition(float dx, float dy, float dz) { + this.position.x += dx; + this.position.y += dy; + this.position.z += dz; + return this; + } + + public Transform setRotation(Vector3f rotation){ + this.rotation = rotation; + return this; + } + + public Transform setScale(float scale){ + this.scale = scale; + return this; + } + + public Vector3f getPosition(){ + return position; + } + + public Vector3f getGlobalPosition() { + return new Vector3f(position.x+ World.world_origin.x(),position.y,position.z+ World.world_origin.z()); + } + + public Vector3f getRotation(){ + return rotation; + } + + public float getScale(){ + return scale; + } + +} diff --git a/src/main/java/net/tylermurphy/Minecraft/Scene/Objects/WorldOrigin.java b/src/main/java/net/tylermurphy/Minecraft/Scene/Objects/WorldOrigin.java new file mode 100755 index 0000000..a5fa73e --- /dev/null +++ b/src/main/java/net/tylermurphy/Minecraft/Scene/Objects/WorldOrigin.java @@ -0,0 +1,47 @@ +package net.tylermurphy.Minecraft.Scene.Objects; + +import net.tylermurphy.Minecraft.Scene.World; +import org.joml.Vector3f; + +public class WorldOrigin { + + private int x; + private int z; + + public WorldOrigin(int x, int z){ + this.x = x; + this.z = z; + } + + public int x(){ + return x; + } + + public int z(){ + return z; + } + + public void recalculateOrigin(){ + Vector3f position = World.player.getTransform().getPosition(); + if((int)position.x>=256) { + int changes = (int) (position.x / 256); + x += 256*changes; + World.player.getTransform().setPosition(new Vector3f(position.x - 256*changes ,position.y,position.z)); + } else if((int)position.x<=-256) { + int changes = (int) (position.x / 256); + x += 256*changes; + World.player.getTransform().setPosition(new Vector3f(position.x - 256*changes ,position.y,position.z)); + } + + if((int)position.z>=256) { + int changes = (int) (position.z / 256); + z += 256*changes; + World.player.getTransform().setPosition(new Vector3f(position.x,position.y,position.z - 256*changes)); + } else if((int)position.z<=-256) { + int changes = (int) (position.z / 256); + z += 256*changes; + World.player.getTransform().setPosition(new Vector3f(position.x,position.y,position.z - 256*changes)); + } + } + +} diff --git a/src/main/java/net/tylermurphy/Minecraft/Scene/Player.java b/src/main/java/net/tylermurphy/Minecraft/Scene/Player.java new file mode 100755 index 0000000..69e741a --- /dev/null +++ b/src/main/java/net/tylermurphy/Minecraft/Scene/Player.java @@ -0,0 +1,100 @@ +package net.tylermurphy.Minecraft.Scene; + +import java.io.Serializable; + +import net.tylermurphy.Minecraft.Scene.Objects.Transform; +import org.lwjgl.glfw.GLFW; + +import net.tylermurphy.Minecraft.Input.Input; +import net.tylermurphy.Minecraft.Scene.Objects.Entity; +import net.tylermurphy.Minecraft.Render.Data.Display; + +public class Player extends Entity implements Serializable { + + private static final long serialVersionUID = 5135364541978251987L; + + public int health = 20; + + public boolean isPaused; + + public Player(Transform transform) { + super(transform); + } + + public void move() { + if(!isPaused) + checkInputs(); + else { + this.currentForwardSpeed = 0; + this.currentSideSpeed = 0; + } + float distance = (float) (currentForwardSpeed * Display.getFrameTimeSeconds() * (isFlying == true ? 2 : 1) * ((isSwimming || isBobbing) && !isFlying ? .25 : 1) ); + float dx = (float) (distance * Math.sin(Math.toRadians(getTransform().getRotation().y))); + float dz = (float) (distance * Math.cos(Math.toRadians(getTransform().getRotation().y))); + float distance2 = (float) (currentSideSpeed * Display.getFrameTimeSeconds() * (isFlying == true ? 2 : 1) * ((isSwimming || isBobbing) && !isFlying ? .25 : 1) ); + dx += (float) (distance2 * Math.sin(Math.toRadians(90-getTransform().getRotation().y))); + dz += (float) (distance2 * Math.cos(Math.toRadians(90+getTransform().getRotation().y))); + if(isInAir && !(isFlying || isSwimming)) upwardsSpeed += GRAVITY * Display.getFrameTimeSeconds(); + upwardsSpeed *= (isSwimming && !isFlying ? .5 : 1); + upwardsSpeed *= (isBobbing) ? -1 : 1; + float dy = (float) (upwardsSpeed * Display.getFrameTimeSeconds()); + + if(willCollide(dx, 0, 0)) + getTransform().increasePosition(dx, 0, 0); + + if(willCollide(0, dy, 0)) { + getTransform().increasePosition(0, dy, 0); + } + + if(willCollide(0, 0, dz)) + getTransform().increasePosition(0, 0, dz); + + if(getTransform().getPosition().y < 0) { + getTransform().increasePosition(0, 256, 0); + } + } + + private void checkInputs() { + int keys_pressed = 0; + + if(Input.isKeyDown(GLFW.GLFW_KEY_W)) { + this.currentForwardSpeed = -RUN_SPEED; keys_pressed++; + }else if(Input.isKeyDown(GLFW.GLFW_KEY_S)) { + this.currentForwardSpeed = RUN_SPEED; keys_pressed++; + }else { + this.currentForwardSpeed = 0; + } + + if(Input.isKeyDown(GLFW.GLFW_KEY_A)) { + this.currentSideSpeed = -RUN_SPEED; keys_pressed++; + }else if(Input.isKeyDown(GLFW.GLFW_KEY_D)) { + this.currentSideSpeed = RUN_SPEED; keys_pressed++; + }else { + this.currentSideSpeed = 0; + } + + if(keys_pressed == 2) { + this.currentForwardSpeed /=1.25; + this.currentSideSpeed /=1.25; + } + + if(Input.isKeyDown(GLFW.GLFW_KEY_LEFT_CONTROL)) { + this.currentForwardSpeed *= 1.5; + this.currentSideSpeed *= 1.5; + } + + if(Input.isKeyDown(GLFW.GLFW_KEY_SPACE)) { + if(!isInAir && !(isFlying || isSwimming)) { + this.upwardsSpeed = JUMP_POWER; + isInAir = true; + }else if(isFlying || isSwimming) { + this.upwardsSpeed = JUMP_POWER; + } + } else if(Input.isKeyDown(GLFW.GLFW_KEY_LEFT_SHIFT) && isFlying || isSwimming && !isFlying) { + this.upwardsSpeed = -JUMP_POWER; + } else if(isFlying) { + this.upwardsSpeed = 0; + } + } + +} diff --git a/src/main/java/net/tylermurphy/Minecraft/Scene/World.java b/src/main/java/net/tylermurphy/Minecraft/Scene/World.java new file mode 100755 index 0000000..d54ed92 --- /dev/null +++ b/src/main/java/net/tylermurphy/Minecraft/Scene/World.java @@ -0,0 +1,89 @@ +package net.tylermurphy.Minecraft.Scene; + +import java.util.Collection; +import java.util.HashMap; +import java.util.stream.Collectors; + +import net.tylermurphy.Minecraft.Chunk.Cube; +import net.tylermurphy.Minecraft.Scene.Objects.WorldOrigin; + +import net.tylermurphy.Minecraft.Chunk.Chunk; +import net.tylermurphy.Minecraft.Tick.BlockUpdate; + +public class World { + + private static final HashMap chunks = new HashMap<>(); + + public static Camera camera; + public static Player player; + public static int seed; + public static int renderDistance; + + public static WorldOrigin world_origin; + + public static byte getBlock(int x, int y, int z) { + if(y<0 || y> 255) return Cube.AIR; + int cx = (int)Math.floor(x/16.0) + world_origin.x()/16; + int cz = (int)Math.floor(z/16.0) + world_origin.z()/16; + Chunk chunk = getChunk(cx, cz); + if(chunk==null) return Cube.NULL; + int rx = x-16*(int)Math.floor(x/16.0); + int rz = z-16*(int)Math.floor(z/16.0); + return chunk.cubes[rx][y][rz]; + } + + public static int getHighestBlock(int fx, int fz) { + for(int y=255;y>=0;y--) { + if(getBlock(fx,y,fz) != -1) return y; + } + return 255; + } + + public static void setBlock(int x, int y, int z, byte id) { + if(y<0 || y> 255) return; + int cx = (int)Math.floor(x/16.0) + world_origin.x()/16; + int cz = (int)Math.floor(z/16.0) + world_origin.z()/16; + Chunk chunk = getChunk(cx, cz); + if(chunk==null) return; + int rx = x-16*(int)Math.floor(x/16.0); + int rz = z-16*(int)Math.floor(z/16.0); + BlockUpdate.createBlockUpdate(x, y, z, chunk.cubes[rx][y][rz], id); + chunk.scheduleFutureMeshUpdate(); + chunk.cubes[rx][y][rz] = id; + if(id != -1 && y > 0 && chunk.cubes[rx][y - 1][rz] == 0) + chunk.cubes[rx][y -1][rz] = 1; + int ox = (rx%16) == 0 ? -1 : (rx%16) == 15 ? 1 : 0; + int oz = (rz%16) == 0 ? -1 : (rz%16) == 15 ? 1 : 0; + Chunk coc = null,coz = null; + if(ox != 0) coc = getChunk(chunk.gridX + ox, chunk.gridZ); + if(oz != 0) coz = getChunk(chunk.gridX, chunk.gridZ + oz); + if(coc != null) { + coc.scheduleFutureMeshUpdate(); + } + if(coz != null) { + coz.scheduleFutureMeshUpdate(); + } + } + + public static Chunk getChunk(int x, int z){ + Chunk c = chunks.get(x+":"+z); + return c == null ? null : c.isSafe() ? c : null; + } + + public static Chunk getChunkUnsafe(int x, int z){ + return chunks.get(x+":"+z); + } + + public static void addChunk(Chunk c){ + chunks.put(c.gridX+":"+c.gridZ, c); + } + + public static void removeChunk(int x, int z){ + chunks.remove(x+":"+z); + } + + public static Collection getChunks(){ + return chunks.values().stream().filter(Chunk::isSafe).collect(Collectors.toList()); + } + +} \ No newline at end of file -- cgit v1.2.3-freya