Skip to content

Commit 51872ce

Browse files
committed
👯 Work on multiplayer
1 parent 40394e2 commit 51872ce

29 files changed

Lines changed: 718 additions & 182 deletions

‎build.gradle‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ repositories {
3535
}
3636

3737
dependencies {
38+
implementation 'io.netty:netty-all:4.2.5.Final'
3839
implementation "org.joml:joml:1.10.8"
3940
implementation 'org.lz4:lz4-java:1.8.0'
4041
}

‎src/main/java/com/james090500/BlockGame.java‎

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import com.james090500.gui.ScreenManager;
1010
import com.james090500.io.AssetManager;
1111
import com.james090500.renderer.RenderManager;
12+
import com.james090500.utils.GameLogger;
1213
import com.james090500.utils.SoundManager;
1314
import com.james090500.utils.ThreadUtil;
1415
import com.james090500.world.World;
@@ -25,7 +26,7 @@ public class BlockGame {
2526

2627
@Getter private static BlockGame instance;
2728
private final Config config = new Config();
28-
@Getter private static final Logger logger = Logger.getLogger("BlockGame");
29+
@Getter private static final Logger logger = GameLogger.get("BlockGame");
2930
private final ClientWindow clientWindow;
3031

3132
private LocalPlayer localPlayer;
@@ -84,7 +85,20 @@ public void start(String name, String seed) {
8485

8586
this.world = new World(name, seed);
8687

87-
this.localPlayer = new LocalPlayer(name);
88+
this.localPlayer = new LocalPlayer();
89+
this.localPlayer.loadGui();
90+
91+
this.unpause();
92+
93+
ScreenManager.add(new DebugScreen());
94+
}
95+
96+
public void startRemote() {
97+
this.camera = new Camera(0, 150, 0);
98+
99+
this.world = new World();
100+
101+
this.localPlayer = new LocalPlayer();
88102
this.localPlayer.loadGui();
89103

90104
this.unpause();
@@ -104,7 +118,7 @@ public void exit() {
104118
RenderManager.clear();
105119

106120
BlockGame.getInstance().getLocalPlayer().savePlayer();
107-
BlockGame.getInstance().getWorld().saveWorld();
121+
BlockGame.getInstance().getWorld().exitWorld();
108122

109123
this.localPlayer = null;
110124
this.world = null;

‎src/main/java/com/james090500/client/ClientInput.java‎

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.james090500.client;
22

33
import com.james090500.BlockGame;
4+
import com.james090500.gui.DebugScreen;
45
import com.james090500.gui.Screen;
56
import com.james090500.gui.ScreenManager;
67
import lombok.Getter;
@@ -56,9 +57,11 @@ public void mouseClicked(long win, int button, int action, int mods) {
5657
}
5758

5859
public void mouseScroll(long window, double xOffset, double yOffset) {
59-
if (xOffset > 0) {
60+
if(BlockGame.getInstance().getConfig().isPaused()) return;
61+
62+
if (xOffset > 0 || yOffset > 0) {
6063
BlockGame.getInstance().getLocalPlayer().changeHand(1);
61-
} else if (xOffset < 0) {
64+
} else if (xOffset < 0 || yOffset < 0) {
6265
BlockGame.getInstance().getLocalPlayer().changeHand(-1);
6366
}
6467
}
@@ -74,8 +77,10 @@ public void keyPressed(long window, int key, int scancode, int action, int mods)
7477
keys.put(key, action > GLFW_RELEASE);
7578

7679
if (keys.getOrDefault(GLFW_KEY_ESCAPE, false)) {
77-
if (ScreenManager.active().stream().anyMatch(Screen::isCloseable)) {
80+
if (BlockGame.getInstance().getConfig().isPaused() && BlockGame.getInstance().getWorld() != null) {
7881
ScreenManager.clear();
82+
ScreenManager.add(new DebugScreen());
83+
BlockGame.getInstance().unpause();
7984
} else if(!BlockGame.getInstance().getConfig().isPaused()) {
8085
BlockGame.getInstance().pause();
8186
}

‎src/main/java/com/james090500/client/LocalPlayer.java‎

Lines changed: 60 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
import com.james090500.blocks.Blocks;
66
import com.james090500.renderer.gui.ArmOverlay;
77
import com.james090500.renderer.gui.BlockOverlay;
8+
import com.james090500.renderer.gui.CrosshairOverlay;
9+
import com.james090500.utils.AABB;
810
import com.james090500.utils.Clock;
911
import com.james090500.utils.SoundManager;
1012
import lombok.Getter;
@@ -28,8 +30,9 @@ public class LocalPlayer {
2830
private boolean swimming = false;
2931

3032
Clock clock = new Clock();
33+
private final AABB aabb;
3134
private final float playerWidth = 0.4f;
32-
private final float playerHeight = 1.5f;
35+
private final float playerHeight = 1.75f;
3336
private final Vector3f velocity = new Vector3f();
3437
private final Vector3f fallVelocity = new Vector3f();
3538
private double jumpStartTime = 0;
@@ -38,50 +41,58 @@ public class LocalPlayer {
3841

3942
BlockOverlay blockOverlay = new BlockOverlay();
4043
ArmOverlay armOverlay = new ArmOverlay();
44+
CrosshairOverlay crosshairOverlay = new CrosshairOverlay();
4145

42-
public LocalPlayer(String worldName) {
43-
this.worldName = worldName;
44-
45-
File playerPath = new File("worlds/" + worldName + "/players");
46-
File playerData = new File(playerPath + "/player.dat");
46+
public LocalPlayer() {
47+
this.aabb = new AABB(playerWidth, playerHeight);
48+
this.worldName = BlockGame.getInstance().getWorld().getWorldName();
4749
Camera camera = BlockGame.getInstance().getCamera();
4850

49-
if(!playerPath.exists()) {
50-
playerPath.mkdirs();
51-
52-
savePlayer();
51+
if(BlockGame.getInstance().getWorld().isRemote()) {
52+
camera.setPosition(0, 100, 0);
5353
} else {
54-
try (RandomAccessFile raf = new RandomAccessFile(playerData, "rw")) {
55-
float x = raf.readFloat();
56-
float y = raf.readFloat();
57-
float z = raf.readFloat();
58-
float pitch = raf.readFloat();
59-
float yaw = raf.readFloat();
54+
File playerPath = new File("worlds/" + worldName + "/players");
55+
File playerData = new File(playerPath + "/player.dat");
6056

61-
camera.setPosition(x, y, z);
62-
camera.setRotation(pitch, yaw);
57+
if (!playerPath.exists()) {
58+
playerPath.mkdirs();
6359

64-
} catch (IOException e) {
65-
e.printStackTrace();
60+
savePlayer();
61+
} else {
62+
try (RandomAccessFile raf = new RandomAccessFile(playerData, "rw")) {
63+
float x = raf.readFloat();
64+
float y = raf.readFloat();
65+
float z = raf.readFloat();
66+
float pitch = raf.readFloat();
67+
float yaw = raf.readFloat();
68+
69+
camera.setPosition(x, y, z);
70+
camera.setRotation(pitch, yaw);
71+
72+
} catch (IOException e) {
73+
e.printStackTrace();
74+
}
6675
}
6776
}
6877
}
6978

7079
public void savePlayer() {
71-
File playerPath = new File("worlds/" + worldName + "/players");
72-
File playerData = new File(playerPath + "/player.dat");
73-
Camera camera = BlockGame.getInstance().getCamera();
80+
if(!BlockGame.getInstance().getWorld().isRemote()) {
81+
File playerPath = new File("worlds/" + worldName + "/players");
82+
File playerData = new File(playerPath + "/player.dat");
83+
Camera camera = BlockGame.getInstance().getCamera();
7484

75-
// Write to file
76-
try (RandomAccessFile raf = new RandomAccessFile(playerData, "rw")) {
77-
raf.setLength(0);
78-
raf.writeFloat(camera.getPosition().x);
79-
raf.writeFloat(camera.getPosition().y);
80-
raf.writeFloat(camera.getPosition().z);
81-
raf.writeFloat(camera.pitch);
82-
raf.writeFloat(camera.yaw);
83-
} catch (IOException e) {
84-
e.printStackTrace();
85+
// Write to file
86+
try (RandomAccessFile raf = new RandomAccessFile(playerData, "rw")) {
87+
raf.setLength(0);
88+
raf.writeFloat(camera.getPosition().x);
89+
raf.writeFloat(camera.getPosition().y);
90+
raf.writeFloat(camera.getPosition().z);
91+
raf.writeFloat(camera.pitch);
92+
raf.writeFloat(camera.yaw);
93+
} catch (IOException e) {
94+
e.printStackTrace();
95+
}
8596
}
8697
}
8798

@@ -216,19 +227,16 @@ private void updateMovement(double delta) {
216227

217228
float yVelocity = (float) (this.fallVelocity.y * delta);
218229

219-
// Half the players width
220-
float halfWidth = this.playerWidth / 2;
221-
222-
if (!this.tryMove(new Vector3f(0, yVelocity, 0), 1, halfWidth, this.playerHeight)) {
230+
if (!this.tryMove(new Vector3f(0, yVelocity, 0), 1)) {
223231
this.fallVelocity.y = 0;
224232
this.falling = false;
225233
} else if (!this.noclip) {
226234
this.falling = true;
227235
}
228236

229237
// Try horizontal movement along X and Z axes
230-
boolean canMove1 = this.tryMove(this.velocity, 0, halfWidth, this.playerHeight);
231-
boolean canMove2 = this.tryMove(this.velocity, 2, halfWidth, this.playerHeight);
238+
boolean canMove1 = this.tryMove(this.velocity, 0);
239+
boolean canMove2 = this.tryMove(this.velocity, 2);
232240

233241
if(canMove1 && canMove2) {
234242
// Play the movement sound
@@ -237,8 +245,7 @@ private void updateMovement(double delta) {
237245
if (stepCooldown <= 0f) {
238246
Block blockAtFeet = BlockGame.getInstance().getWorld().getBlock(camera.getPosition().sub(new Vector3f(0, 2, 0)));
239247
if(blockAtFeet != null && blockAtFeet.getSound() != null) {
240-
int sound = 1 + (int) (Math.random() * 4);
241-
SoundManager.play("assets/sound/block/" + blockAtFeet.getSound() + sound + ".ogg");
248+
SoundManager.play("assets/sound/block/" + blockAtFeet.getSound(), 4);
242249
stepCooldown = 0.5f; // play every half second while moving
243250
}
244251
}
@@ -250,9 +257,8 @@ private void updateMovement(double delta) {
250257

251258
/**
252259
* Update interaction via mouse picking
253-
* @param delta
254260
*/
255-
private void updateInteraction(double delta) {
261+
private void updateInteraction() {
256262
Camera camera = BlockGame.getInstance().getCamera();
257263
Vector3f origin = new Vector3f(camera.getPosition());
258264
Vector3f dir = new Vector3f(camera.getDirection()).normalize();
@@ -267,52 +273,26 @@ private void updateInteraction(double delta) {
267273

268274
HashMap<Integer, Boolean> mouse = BlockGame.getInstance().getClientWindow().getClientInput().getMouse();
269275
if(mouse.getOrDefault(GLFW_MOUSE_BUTTON_LEFT, false)) {
276+
Block currentBlock = BlockGame.getInstance().getWorld().getBlock(raycast[1].x, raycast[1].y, raycast[1].z);
270277
BlockGame.getInstance().getWorld().setBlock(raycast[1].x, raycast[1].y, raycast[1].z, (byte) 0);
278+
SoundManager.play("assets/sound/block/" + currentBlock.getSound(), 4);
271279
mouse.put(GLFW_MOUSE_BUTTON_LEFT, false);
272280
}
273281

274282
if(mouse.getOrDefault(GLFW_MOUSE_BUTTON_RIGHT, false)) {
275-
BlockGame.getInstance().getWorld().setBlock(raycast[0].x, raycast[0].y, raycast[0].z, (byte) this.currentBlock);
283+
if(!aabb.isColliding(origin, raycast[0])) {
284+
Block currentBlock = Blocks.ids[this.currentBlock];
285+
BlockGame.getInstance().getWorld().setBlock(raycast[0].x, raycast[0].y, raycast[0].z, currentBlock.getId());
286+
SoundManager.play("assets/sound/block/" + currentBlock.getSound(), 4);
287+
}
276288
mouse.put(GLFW_MOUSE_BUTTON_RIGHT, false);
277289
}
278-
279-
// if(mouse.getOrDefault(GLFW_MOUSE_))
280290
}
281291
}
282292

283293
public void render() {
284294
armOverlay.render();
285-
}
286-
287-
/**
288-
* Checks if the player's AABB collides with any solid blocks in the world.
289-
* @param {Vector3} min - Minimum bounds of the AABB.
290-
* @param {Vector3} max - Maximum bounds of the AABB.
291-
* @param {Object} futureBlock - Are we attempting to place a block?
292-
* @returns {boolean} If the player is colliding
293-
*/
294-
private boolean isAABBColliding(Vector3f min, Vector3f max) {
295-
for (int x = (int) Math.floor(min.x); x <= Math.floor(max.x); x++) {
296-
for (int y = (int) Math.floor(min.y); y <= Math.floor(max.y); y++) {
297-
for (int z = (int) Math.floor(min.z); z <= Math.floor(max.z); z++) {
298-
// if (futureBlock) {
299-
// if (
300-
// futureBlock[0] === x &&
301-
// futureBlock[1] === y &&
302-
// futureBlock[2] === z
303-
// ) {
304-
// return true
305-
// }
306-
// }
307-
308-
Block block = BlockGame.getInstance().getWorld().getBlock(x, y, z);
309-
if(block != null && block.isSolid()) {
310-
return true;
311-
}
312-
}
313-
}
314-
}
315-
return false;
295+
crosshairOverlay.render();
316296
}
317297

318298
/**
@@ -325,19 +305,11 @@ private boolean isAABBColliding(Vector3f min, Vector3f max) {
325305
* @param {Object} world - The world object to query blocks from.
326306
* @returns {boolean} True if the move was successful.
327307
*/
328-
public boolean tryMove(Vector3f velocity, int axis, float halfWidth, float playerHeight) {
308+
public boolean tryMove(Vector3f velocity, int axis) {
329309
Vector3f pos = new Vector3f(BlockGame.getInstance().getCamera().getPosition());
330310
pos.setComponent(axis,pos.get(axis) + velocity.get(axis));
331311

332-
Vector3f min = new Vector3f(
333-
pos.x - halfWidth,
334-
pos.y - playerHeight,
335-
pos.z - halfWidth
336-
);
337-
338-
Vector3f max = new Vector3f(pos.x + halfWidth, pos.y, pos.z + halfWidth);
339-
340-
if (!this.isAABBColliding(min, max) || this.noclip) {
312+
if (!aabb.isColliding(pos) || this.noclip) {
341313
BlockGame.getInstance().getCamera().setPosition(axis, pos.get(axis));
342314
return true;
343315
}
@@ -428,7 +400,7 @@ private float intBound(float s, float ds) {
428400

429401
public void update(double delta) {
430402
this.updateControls();
431-
this.updateInteraction(delta);
403+
this.updateInteraction();
432404
this.updateMovement(delta);
433405
}
434406

‎src/main/java/com/james090500/gui/DebugScreen.java‎

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -28,19 +28,20 @@ public void render() {
2828
int playerPosZ = (int) Math.floor(position.z / 16);
2929
Chunk chunk = BlockGame.getInstance().getWorld().getChunk(playerPosX, playerPosZ);
3030

31-
FontManager.create().text("Current Chunk Info", 20f, 10f, 170f);
32-
FontManager.create().text("Chunk Coords: " + playerPosX + ", " + playerPosZ, 20f, 10f, 190f);
33-
FontManager.create().text("Chunk Generated: " + chunk.generated, 20f, 10f, 210f);
34-
FontManager.create().text("Chunk Loaded: " + chunk.loaded, 20f, 10f, 230f);
35-
FontManager.create().text("Chunk Needs Update: " + chunk.needsUpdate, 20f, 10f, 250f);
36-
FontManager.create().text("Chunk Needs Queued: " + chunk.queued, 20f, 10f, 270f);
37-
FontManager.create().text("Chunk Needs Saving: " + chunk.needsSaving, 20f, 10f, 290f);
38-
FontManager.create().text("Chunk Solid Vertices: " + chunk.getChunkRenderer().solidVertexCount, 20f, 10f, 310f);
39-
FontManager.create().text("Chunk Trans Vertices: " + chunk.getChunkRenderer().transVertexCount, 20f, 10f, 330f);
31+
if(chunk != null) {
32+
FontManager.create().text("Current Chunk Info", 20f, 10f, 170f);
33+
FontManager.create().text("Chunk Coords: " + playerPosX + ", " + playerPosZ, 20f, 10f, 190f);
34+
FontManager.create().text("Chunk Generated: " + chunk.generated, 20f, 10f, 210f);
35+
FontManager.create().text("Chunk Loaded: " + chunk.loaded, 20f, 10f, 230f);
36+
FontManager.create().text("Chunk Needs Update: " + chunk.needsUpdate, 20f, 10f, 250f);
37+
FontManager.create().text("Chunk Needs Queued: " + chunk.queued, 20f, 10f, 270f);
38+
FontManager.create().text("Chunk Needs Saving: " + chunk.needsSaving, 20f, 10f, 290f);
39+
FontManager.create().text("Chunk Solid Vertices: " + chunk.getChunkRenderer().solidVertexCount, 20f, 10f, 310f);
40+
FontManager.create().text("Chunk Trans Vertices: " + chunk.getChunkRenderer().transVertexCount, 20f, 10f, 330f);
4041

41-
42-
FontManager.create().text("Player Info", 20f, 10f, 350f);
43-
FontManager.create().text("Player Hand: " + Blocks.ids[BlockGame.getInstance().getLocalPlayer().getCurrentBlock()].getName(), 20f, 10f, 370f);
42+
FontManager.create().text("Player Info", 20f, 10f, 350f);
43+
FontManager.create().text("Player Hand: " + Blocks.ids[BlockGame.getInstance().getLocalPlayer().getCurrentBlock()].getName(), 20f, 10f, 370f);
44+
}
4445

4546
super.render();
4647
}

0 commit comments

Comments
 (0)