Skip to content

Commit 87556e7

Browse files
committed
🫂 Entity work and MP Fixes
1 parent 51872ce commit 87556e7

20 files changed

+387
-22
lines changed

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import com.james090500.utils.SoundManager;
1414
import com.james090500.utils.ThreadUtil;
1515
import com.james090500.world.World;
16+
import io.netty.channel.Channel;
1617
import lombok.Getter;
1718

1819
import java.util.logging.Logger;
@@ -33,6 +34,8 @@ public class BlockGame {
3334
private Camera camera;
3435
private World world;
3536

37+
private Channel channel;
38+
3639
public BlockGame() {
3740
instance = this;
3841

@@ -93,7 +96,9 @@ public void start(String name, String seed) {
9396
ScreenManager.add(new DebugScreen());
9497
}
9598

96-
public void startRemote() {
99+
public void startRemote(Channel channel) {
100+
this.channel = channel;
101+
97102
this.camera = new Camera(0, 150, 0);
98103

99104
this.world = new World();

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,10 @@ public void keyPressed(long window, int key, int scancode, int action, int mods)
8686
}
8787
}
8888

89+
if(keys.getOrDefault(GLFW_KEY_M, false)) {
90+
glfwSetInputMode(BlockGame.getInstance().getClientWindow().getWindow(), GLFW_CURSOR, GLFW_CURSOR_NORMAL);
91+
}
92+
8993
if(keys.getOrDefault(GLFW_KEY_BACKSPACE, false)) {
9094
List<Screen> screens = new ArrayList<>(ScreenManager.active());
9195
for (Screen screen : screens) {

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

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -273,17 +273,14 @@ private void updateInteraction() {
273273

274274
HashMap<Integer, Boolean> mouse = BlockGame.getInstance().getClientWindow().getClientInput().getMouse();
275275
if(mouse.getOrDefault(GLFW_MOUSE_BUTTON_LEFT, false)) {
276-
Block currentBlock = BlockGame.getInstance().getWorld().getBlock(raycast[1].x, raycast[1].y, raycast[1].z);
277276
BlockGame.getInstance().getWorld().setBlock(raycast[1].x, raycast[1].y, raycast[1].z, (byte) 0);
278-
SoundManager.play("assets/sound/block/" + currentBlock.getSound(), 4);
279277
mouse.put(GLFW_MOUSE_BUTTON_LEFT, false);
280278
}
281279

282280
if(mouse.getOrDefault(GLFW_MOUSE_BUTTON_RIGHT, false)) {
283281
if(!aabb.isColliding(origin, raycast[0])) {
284282
Block currentBlock = Blocks.ids[this.currentBlock];
285283
BlockGame.getInstance().getWorld().setBlock(raycast[0].x, raycast[0].y, raycast[0].z, currentBlock.getId());
286-
SoundManager.play("assets/sound/block/" + currentBlock.getSound(), 4);
287284
}
288285
mouse.put(GLFW_MOUSE_BUTTON_RIGHT, false);
289286
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package com.james090500.entity;
2+
3+
import com.james090500.renderer.Renderer;
4+
import org.joml.Vector3f;
5+
6+
public interface Entity {
7+
8+
void setPosition(Vector3f pos);
9+
10+
Renderer getModel();
11+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package com.james090500.entity;
2+
3+
import com.james090500.entity.model.PlayerModel;
4+
import com.james090500.renderer.Renderer;
5+
import org.joml.Vector3f;
6+
7+
public class PlayerEntity implements Entity {
8+
9+
PlayerModel playerModel = new PlayerModel();
10+
Vector3f position = new Vector3f();
11+
12+
public void setPosition(Vector3f pos) {
13+
this.position = pos;
14+
playerModel.setPosition(pos);
15+
}
16+
17+
@Override
18+
public Renderer getModel() {
19+
return this.playerModel;
20+
}
21+
}
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
package com.james090500.entity.model;
2+
3+
import com.james090500.renderer.Renderer;
4+
import com.james090500.renderer.ShaderManager;
5+
import lombok.Getter;
6+
import lombok.Setter;
7+
import org.joml.Matrix4f;
8+
import org.joml.Vector3f;
9+
import org.lwjgl.system.MemoryUtil;
10+
11+
import static org.lwjgl.opengl.GL11.GL_FLOAT;
12+
import static org.lwjgl.opengl.GL11.GL_TRIANGLES;
13+
import static org.lwjgl.opengl.GL11.GL_UNSIGNED_INT;
14+
import static org.lwjgl.opengl.GL11.glDrawElements;
15+
import static org.lwjgl.opengl.GL15.*;
16+
import static org.lwjgl.opengl.GL15.GL_STATIC_DRAW;
17+
import static org.lwjgl.opengl.GL20.glEnableVertexAttribArray;
18+
import static org.lwjgl.opengl.GL20.glVertexAttribPointer;
19+
import static org.lwjgl.opengl.GL30.glBindVertexArray;
20+
import static org.lwjgl.opengl.GL30.glGenVertexArrays;
21+
22+
public class PlayerModel implements Renderer {
23+
24+
private int vao;
25+
26+
// Cube centered at origin, side length = 1.0 (±0.5)
27+
float[] vertices = {
28+
// Back face (z = -0.5)
29+
-0.5f, -1.0f, -0.5f, // 0
30+
0.5f, -1.0f, -0.5f, // 1
31+
0.5f, 1.0f, -0.5f, // 2
32+
-0.5f, 1.0f, -0.5f, // 3
33+
34+
// Front face (z = +0.5)
35+
-0.5f, -1.0f, 0.5f, // 4
36+
0.5f, -1.0f, 0.5f, // 5
37+
0.5f, 1.0f, 0.5f, // 6
38+
-0.5f, 1.0f, 0.5f // 7
39+
};
40+
41+
int[] indices = {
42+
// Front
43+
4, 5, 6, 6, 7, 4,
44+
// Back
45+
1, 0, 3, 3, 2, 1,
46+
// Left
47+
0, 4, 7, 7, 3, 0,
48+
// Right
49+
5, 1, 2, 2, 6, 5,
50+
// Top
51+
3, 7, 6, 6, 2, 3,
52+
// Bottom
53+
0, 1, 5, 5, 4, 0
54+
};
55+
56+
57+
@Getter @Setter private Vector3f position;
58+
59+
public PlayerModel() {
60+
vao = glGenVertexArrays();
61+
glBindVertexArray(vao);
62+
63+
// Vertex Position VBO
64+
int vbo = glGenBuffers();
65+
glBindBuffer(GL_ARRAY_BUFFER, vbo);
66+
glBufferData(GL_ARRAY_BUFFER, MemoryUtil.memAllocFloat(vertices.length).put(vertices).flip(), GL_STATIC_DRAW);
67+
glVertexAttribPointer(0, 3, GL_FLOAT, false, 3 * Float.BYTES, 0);
68+
glEnableVertexAttribArray(0);
69+
70+
// Index Buffer (EBO)
71+
int ebo = glGenBuffers();
72+
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
73+
glBufferData(GL_ELEMENT_ARRAY_BUFFER, MemoryUtil.memAllocInt(indices.length).put(indices).flip(), GL_STATIC_DRAW);
74+
}
75+
76+
@Override
77+
public Vector3f getBoundingBox() {
78+
return null;
79+
}
80+
81+
public void render() {
82+
Matrix4f model = new Matrix4f().translate(this.getPosition());
83+
84+
ShaderManager.basicShader.use();
85+
ShaderManager.basicShader.setMat4("model", model);
86+
ShaderManager.basicShader.setVec3("color", new Vector3f(0, 0, 1));
87+
88+
glBindVertexArray(vao);
89+
glDrawElements(GL_TRIANGLES, indices.length, GL_UNSIGNED_INT, 0);
90+
91+
glBindVertexArray(0);
92+
ShaderManager.basicShader.stop();
93+
}
94+
95+
96+
}

‎src/main/java/com/james090500/gui/multiplayer/MultiplayerScreen.java‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public MultiplayerScreen() {
3030
400f,
3131
40f,
3232
() -> {
33-
NettyHandler test = new NettyHandler(serverIp.getTypedValue(), 25565);
33+
NettyHandler test = new NettyHandler(serverIp.getTypedValue(), 28004);
3434
test.run();
3535
}
3636
)

‎src/main/java/com/james090500/network/BlockGameMP.java‎

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,43 @@
11
package com.james090500.network;
22

33
import com.james090500.BlockGame;
4-
import com.james090500.gui.ScreenManager;
5-
import com.james090500.utils.ThreadUtil;
4+
import com.james090500.network.packets.*;
65
import io.netty.buffer.ByteBuf;
76
import io.netty.channel.ChannelHandlerContext;
87
import io.netty.channel.SimpleChannelInboundHandler;
98

10-
public class BlockGameMP extends SimpleChannelInboundHandler<ByteBuf> {
9+
import java.util.HashMap;
10+
import java.util.Map;
11+
import java.util.function.Supplier;
1112

13+
public class BlockGameMP extends SimpleChannelInboundHandler<ByteBuf> {
1214

15+
private final Map<Integer, Supplier<BlockGamePacket>> parsers = new HashMap<>();
16+
public BlockGameMP() {
17+
parsers.put(1, ConnectPacket::new);
18+
parsers.put(2, DisconnectPacket::new);
19+
parsers.put(3, ChunkPacket::new);
20+
parsers.put(4, BlockUpdatePacket::new);
21+
parsers.put(5, EntityUpdatePacket::new);
22+
}
1323

1424
@Override
15-
protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) throws Exception {
16-
int chunkX = msg.readInt();
17-
int chunkZ = msg.readInt();
18-
byte[] data = new byte[msg.readableBytes()];
19-
msg.readBytes(data);
25+
public void channelActive(ChannelHandlerContext ctx) {
26+
BlockGamePacket packet = parsers.get(1).get();
27+
packet.write(ctx.channel());
28+
}
2029

21-
ThreadUtil.getMainQueue().add(() -> {
22-
BlockGame.getInstance().getWorld().loadRemoteChunk(chunkX, chunkZ, data);
23-
});
30+
@Override
31+
protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) {
32+
int packetId = msg.readInt();
33+
BlockGamePacket packet = parsers.get(packetId).get();
34+
packet.read(ctx.channel(), msg);
2435
}
2536

2637
@Override
27-
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { // (4)
38+
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
2839
// Close the connection when an exception is raised.
40+
BlockGame.getInstance().exit();
2941
cause.printStackTrace();
3042
ctx.close();
3143
}

‎src/main/java/com/james090500/network/NettyHandler.java‎

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212
import io.netty.channel.nio.NioIoHandler;
1313
import io.netty.channel.socket.nio.NioSocketChannel;
1414

15+
import java.net.InetAddress;
16+
import java.net.InetSocketAddress;
17+
1518
public class NettyHandler {
1619

1720
private final String host;
@@ -28,14 +31,17 @@ public void run() {
2831

2932
EventLoopGroup group = new MultiThreadIoEventLoopGroup(NioIoHandler.newFactory());
3033

31-
Bootstrap bootstrap = new Bootstrap().group(group).channel(NioSocketChannel.class).handler(new NettyInitializer());
34+
Bootstrap bootstrap = new Bootstrap()
35+
.group(group)
36+
.channel(NioSocketChannel.class)
37+
.handler(new NettyInitializer());
3238

3339
ChannelFuture channelFuture = bootstrap.connect(host, port);
3440
channelFuture.addListener((ChannelFuture future) -> {
3541
if(future.isSuccess()) {
3642
ThreadUtil.getMainQueue().add(() -> {
3743
ScreenManager.clear();
38-
BlockGame.getInstance().startRemote();
44+
BlockGame.getInstance().startRemote(future.channel());
3945
});
4046
} else {
4147
String error = future.cause().getLocalizedMessage();
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package com.james090500.network.packets;
2+
3+
import io.netty.buffer.ByteBuf;
4+
import io.netty.channel.Channel;
5+
6+
public abstract class AbstractPacket implements BlockGamePacket {
7+
8+
// default write behaviour: allocate, write id, then payload, then flush
9+
@Override
10+
public void write(Channel channel) {
11+
// If you use LengthFieldPrepender in pipeline, the length will be added for you,
12+
// so here we only write the id + payload.
13+
ByteBuf buf = channel.alloc().buffer();
14+
writePayload(buf); // subclass writes its fields
15+
channel.writeAndFlush(buf); // ownership passed to Netty
16+
}
17+
18+
// subclass should write only payload (no id/length)
19+
protected abstract void writePayload(ByteBuf out);
20+
21+
// default read can be left abstract or provided here
22+
@Override
23+
public abstract void read(Channel channel, ByteBuf msg);
24+
}

0 commit comments

Comments
 (0)