使用java做出minecraft2.0版本
经过这一次的更新,minecraft2.0版本增添了树木,矿物,村庄,掠夺者,前哨塔等。我还增加了移动和飞行!!
这是代码:
import org.lwjgl.*;
import org.lwjgl.glfw.*;
import org.lwjgl.opengl.*;
import org.lwjgl.system.*;
import java.nio.*;
import java.util.*;
import static org.lwjgl.glfw.Callbacks.*;
import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.system.MemoryStack.*;
import static org.lwjgl.system.MemoryUtil.*;
public class MinecraftWorldGenerator {
// 窗口尺寸
private static final int WIDTH = 1200;
private static final int HEIGHT = 800;
private long window;
// 摄像机参数
private float cameraX = 50.0f;
private float cameraY = 20.0f;
private float cameraZ = 50.0f;
private float cameraPitch = -30.0f;
private float cameraYaw = 45.0f;
// 世界参数
private static final int WORLD_SIZE = 64;
private static final int CHUNK_SIZE = 16;
private static final int WORLD_HEIGHT = 64;
private int[][][] world = new int[WORLD_SIZE][WORLD_HEIGHT][WORLD_SIZE];
// 方块类型
private static final int AIR = 0;
private static final int GRASS = 1;
private static final int DIRT = 2;
private static final int STONE = 3;
private static final int WOOD = 4;
private static final int LEAVES = 5;
private static final int PLANKS = 6;
private static final int COBBLESTONE = 7;
private static final int WATER = 8;
// 颜色映射
private static final Map<Integer, float[]> blockColors = new HashMap<>();
static {
blockColors.put(GRASS, new float[]{0.2f, 0.8f, 0.3f}); // 绿色
blockColors.put(DIRT, new float[]{0.5f, 0.35f, 0.2f}); // 棕色
blockColors.put(STONE, new float[]{0.5f, 0.5f, 0.5f}); // 灰色
blockColors.put(WOOD, new float[]{0.6f, 0.4f, 0.2f}); // 棕色
blockColors.put(LEAVES, new float[]{0.2f, 0.6f, 0.2f}); // 深绿色
blockColors.put(PLANKS, new float[]{0.8f, 0.6f, 0.4f}); // 浅棕色
blockColors.put(COBBLESTONE, new float[]{0.4f, 0.4f, 0.4f}); // 深灰色
blockColors.put(WATER, new float[]{0.2f, 0.4f, 0.8f, 0.7f}); // 蓝色(半透明)
}
// 村庄和哨塔位置
private List<int[]> villages = new ArrayList<>();
private List<int[]> pillagerOutposts = new ArrayList<>();
public static void main(String[] args) {
new MinecraftWorldGenerator().run();
}
public void run() {
init();
loop();
// 释放资源
glfwFreeCallbacks(window);
glfwDestroyWindow(window);
glfwTerminate();
Objects.requireNonNull(glfwSetErrorCallback(null)).free();
}
private void init() {
// 设置错误回调
GLFWErrorCallback.createPrint(System.err).set();
// 初始化 GLFW
if (!glfwInit()) {
throw new IllegalStateException("Unable to initialize GLFW");
}
// 配置 GLFW
glfwDefaultWindowHints();
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
// 创建窗口
window = glfwCreateWindow(WIDTH, HEIGHT, "Minecraft World Generator", NULL, NULL);
if (window == NULL) {
throw new RuntimeException("Failed to create the GLFW window");
}
// 设置按键回调
glfwSetKeyCallback(window, (window, key, scancode, action, mods) -> {
if (key == GLFW_KEY_ESCAPE && action == GLFW_RELEASE) {
glfwSetWindowShouldClose(window, true);
}
});
// 设置光标位置回调
glfwSetCursorPosCallback(window, (window, xpos, ypos) -> {
float sensitivity = 0.1f;
cameraYaw += (float) (xpos - WIDTH / 2.0) * sensitivity;
cameraPitch -= (float) (ypos - HEIGHT / 2.0) * sensitivity;
// 限制俯仰角
if (cameraPitch > 89.0f) cameraPitch = 89.0f;
if (cameraPitch < -89.0f) cameraPitch = -89.0f;
// 重置光标位置
glfwSetCursorPos(window, WIDTH / 2.0, HEIGHT / 2.0);
});
// 获取分辨率
try (MemoryStack stack = stackPush()) {
IntBuffer pWidth = stack.mallocInt(1);
IntBuffer pHeight = stack.mallocInt(1);
glfwGetWindowSize(window, pWidth, pHeight);
// 获取显示器分辨率
GLFWVidMode vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
// 居中窗口
glfwSetWindowPos(
window,
(vidmode.width() - pWidth.get(0)) / 2,
(vidmode.height() - pHeight.get(0)) / 2
);
}
// 设置 OpenGL 上下文
glfwMakeContextCurrent(window);
// 启用垂直同步
glfwSwapInterval(1);
// 显示窗口
glfwShowWindow(window);
// 初始化 OpenGL
GL.createCapabilities();
glEnable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glClearColor(0.6f, 0.8f, 1.0f, 1.0f); // 天蓝色背景
// 生成世界
generateWorld();
}
private void generateWorld() {
// 基础地形生成
generateTerrain();
// 生成树木
generateTrees(50);
// 生成村庄
generateVillages(3);
// 生成掠夺者哨塔
generatePillagerOutposts(2);
}
private void generateTerrain() {
Random random = new Random(12345);
// 生成基础地形(Perlin噪声)
float[][] heightMap = new float[WORLD_SIZE][WORLD_SIZE];
for (int x = 0; x < WORLD_SIZE; x++) {
for (int z = 0; z < WORLD_SIZE; z++) {
// 使用多层噪声创建更自然的地形
float height = noise(x * 0.1f, z * 0.1f, random) * 10;
height += noise(x * 0.05f, z * 0.05f, random) * 20;
height += noise(x * 0.02f, z * 0.02f, random) * 5;
height = Math.max(10, height);
heightMap[x][z] = height;
}
}
// 填充方块
for (int x = 0; x < WORLD_SIZE; x++) {
for (int z = 0; z < WORLD_SIZE; z++) {
int height = (int) heightMap[x][z];
// 地表层
world[x][height][z] = GRASS;
// 地下层
for (int y = height - 1; y > height - 4; y--) {
if (y >= 0) world[x][y][z] = DIRT;
}
// 岩石层
for (int y = height - 4; y >= 0; y--) {
if (y >= 0) world[x][y][z] = STONE;
}
// 水面
if (height < 15) {
world[x][15][z] = WATER;
}
}
}
}
private void generateTrees(int count) {
Random random = new Random(67890);
for (int i = 0; i < count; i++) {
int x = random.nextInt(WORLD_SIZE - 10) + 5;
int z = random.nextInt(WORLD_SIZE - 10) + 5;
// 找到地表高度
int y = 0;
for (int h = WORLD_HEIGHT - 1; h >= 0; h--) {
if (world[x][h][z] != AIR) {
y = h + 1;
break;
}
}
// 确保在地表上
if (y < 10 || y > WORLD_HEIGHT - 10) continue;
// 生成树干(4-6格高)
int trunkHeight = 4 + random.nextInt(3);
for (int h = 0; h < trunkHeight; h++) {
if (y + h < WORLD_HEIGHT) {
world[x][y + h][z] = WOOD;
}
}
// 生成树叶(球形树冠)
int topY = y + trunkHeight;
for (int dx = -2; dx <= 2; dx++) {
for (int dz = -2; dz <= 2; dz++) {
for (int dy = -1; dy <= 2; dy++) {
int nx = x + dx;
int nz = z + dz;
int ny = topY + dy;
// 跳过树干位置
if (dx == 0 && dz == 0 && (dy == 0 || dy == -1)) continue;
// 距离树冠中心的距离
float dist = (float) Math.sqrt(dx*dx + dz*dz + dy*dy);
if (nx >= 0 && nx < WORLD_SIZE &&
nz >= 0 && nz < WORLD_SIZE &&
ny >= 0 && ny < WORLD_HEIGHT &&
dist <= 2.5f) {
world[nx][ny][nz] = LEAVES;
}
}
}
}
}
}
private void generateVillages(int count) {
Random random = new Random(54321);
for (int i = 0; i < count; i++) {
int centerX = random.nextInt(WORLD_SIZE - 30) + 15;
int centerZ = random.nextInt(WORLD_SIZE - 30) + 15;
villages.add(new int[]{centerX, centerZ});
// 找到地表高度
int centerY = 0;
for (int h = WORLD_HEIGHT - 1; h >= 0; h--) {
if (world[centerX][h][centerZ] != AIR) {
centerY = h + 1;
break;
}
}
// 村庄中心广场
createSquare(centerX, centerY, centerZ, 10, PLANKS);
// 生成房屋
for (int j = 0; j < 4 + random.nextInt(3); j++) {
int angle = random.nextInt(360);
int distance = 10 + random.nextInt(10);
int houseX = centerX + (int)(Math.cos(Math.toRadians(angle)) * distance;
int houseZ = centerZ + (int)(Math.sin(Math.toRadians(angle)) * distance);
// 找到地表高度
int houseY = 0;
for (int h = WORLD_HEIGHT - 1; h >= 0; h--) {
if (world[houseX][h][houseZ] != AIR) {
houseY = h + 1;
break;
}
}
generateHouse(houseX, houseY, houseZ);
}
}
}
private void generateHouse(int x, int y, int z) {
// 地基
for (int dx = -3; dx <= 3; dx++) {
for (int dz = -3; dz <= 3; dz++) {
setBlockIfAir(x + dx, y - 1, z + dz, COBBLESTONE);
}
}
// 墙壁
for (int dy = 0; dy < 4; dy++) {
for (int dx = -3; dx <= 3; dx++) {
setBlockIfAir(x + dx, y + dy, z - 3, PLANKS);
setBlockIfAir(x + dx, y + dy, z + 3, PLANKS);
}
for (int dz = -3; dz <= 3; dz++) {
setBlockIfAir(x - 3, y + dy, z + dz, PLANKS);
setBlockIfAir(x + 3, y + dy, z + dz, PLANKS);
}
}
// 屋顶
for (int dx = -2; dx <= 2; dx++) {
for (int dz = -2; dz <= 2; dz++) {
setBlockIfAir(x + dx, y + 4, z + dz, WOOD);
}
}
// 门
world[x][y][z - 3] = AIR;
world[x][y + 1][z - 3] = AIR;
// 窗户
world[x - 3][y + 1][z] = AIR;
world[x + 3][y + 1][z] = AIR;
world[x][y + 1][z + 3] = AIR;
}
private void generatePillagerOutposts(int count) {
Random random = new Random(13579);
for (int i = 0; i < count; i++) {
int x = random.nextInt(WORLD_SIZE - 20) + 10;
int z = random.nextInt(WORLD_SIZE - 20) + 10;
pillagerOutposts.add(new int[]{x, z});
// 找到地表高度
int y = 0;
for (int h = WORLD_HEIGHT - 1; h >= 0; h--) {
if (world[x][h][z] != AIR) {
y = h + 1;
break;
}
}
// 地基
for (int dx = -4; dx <= 4; dx++) {
for (int dz = -4; dz <= 4; dz++) {
setBlockIfAir(x + dx, y - 1, z + dz, COBBLESTONE);
}
}
// 塔身
int towerHeight = 10 + random.nextInt(5);
for (int dy = 0; dy < towerHeight; dy++) {
// 塔基
for (int dx = -2; dx <= 2; dx++) {
for (int dz = -2; dz <= 2; dz++) {
if (Math.abs(dx) == 2 || Math.abs(dz) == 2) {
setBlockIfAir(x + dx, y + dy, z + dz, COBBLESTONE);
}
}
}
// 塔楼平台(每3层一个)
if (dy % 3 == 0 && dy > 0) {
for (int dx = -3; dx <= 3; dx++) {
for (int dz = -3; dz <= 3; dz++) {
if (Math.abs(dx) == 3 || Math.abs(dz) == 3) {
setBlockIfAir(x + dx, y + dy, z + dz, WOOD);
}
}
}
}
}
// 塔顶
for (int dx = -3; dx <= 3; dx++) {
for (int dz = -3; dz <= 3; dz++) {
if (Math.abs(dx) <= 1 && Math.abs(dz) <= 1) {
setBlockIfAir(x + dx, y + towerHeight, z + dz, WOOD);
}
}
}
// 塔顶旗帜
for (int dy = 1; dy <= 3; dy++) {
setBlockIfAir(x, y + towerHeight + dy, z, WOOD);
}
}
}
private void setBlockIfAir(int x, int y, int z, int blockType) {
if (x >= 0 && x < WORLD_SIZE &&
y >= 0 && y < WORLD_HEIGHT &&
z >= 0 && z < WORLD_SIZE &&
world[x][y][z] == AIR) {
world[x][y][z] = blockType;
}
}
private void createSquare(int x, int y, int z, int size, int blockType) {
for (int dx = -size; dx <= size; dx++) {
for (int dz = -size; dz <= size; dz++) {
if (x + dx >= 0 && x + dx < WORLD_SIZE &&
z + dz >= 0 && z + dz < WORLD_SIZE) {
setBlockIfAir(x + dx, y, z + dz, blockType);
}
}
}
}
private float noise(float x, float z, Random random) {
return (float) Math.sin(x * 0.1) * (float) Math.cos(z * 0.1) + random.nextFloat() * 0.2f;
}
private void loop() {
// 设置光标位置
glfwSetCursorPos(window, WIDTH / 2.0, HEIGHT / 2.0);
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
// 主循环
while (!glfwWindowShouldClose(window)) {
// 处理输入
processInput();
// 清除颜色和深度缓冲
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// 设置投影矩阵
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
float aspect = (float) WIDTH / HEIGHT;
gluPerspective(60.0f, aspect, 0.1f, 300.0f);
// 设置模型视图矩阵
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// 计算摄像机方向
float yawRad = (float) Math.toRadians(cameraYaw);
float pitchRad = (float) Math.toRadians(cameraPitch);
float lookX = (float) (Math.cos(yawRad) * Math.cos(pitchRad));
float lookY = (float) Math.sin(pitchRad);
float lookZ = (float) (Math.sin(yawRad) * Math.cos(pitchRad));
// 设置摄像机位置和方向
gluLookAt(
cameraX, cameraY, cameraZ,
cameraX + lookX, cameraY + lookY, cameraZ + lookZ,
0.0f, 1.0f, 0.0f
);
// 渲染世界
renderWorld();
// 显示信息
renderInfo();
// 交换缓冲
glfwSwapBuffers(window);
// 轮询事件
glfwPollEvents();
}
}
private void processInput() {
float cameraSpeed = 0.2f;
if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) {
cameraX += Math.sin(Math.toRadians(cameraYaw)) * cameraSpeed;
cameraZ -= Math.cos(Math.toRadians(cameraYaw)) * cameraSpeed;
}
if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) {
cameraX -= Math.sin(Math.toRadians(cameraYaw)) * cameraSpeed;
cameraZ += Math.cos(Math.toRadians(cameraYaw)) * cameraSpeed;
}
if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS) {
cameraX -= Math.cos(Math.toRadians(cameraYaw)) * cameraSpeed;
cameraZ -= Math.sin(Math.toRadians(cameraYaw)) * cameraSpeed;
}
if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS) {
cameraX += Math.cos(Math.toRadians(cameraYaw)) * cameraSpeed;
cameraZ += Math.sin(Math.toRadians(cameraYaw)) * cameraSpeed;
}
if (glfwGetKey(window, GLFW_KEY_SPACE) == GLFW_PRESS) {
cameraY += cameraSpeed;
}
if (glfwGetKey(window, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS) {
cameraY -= cameraSpeed;
}
}
private void renderWorld() {
// 只渲染玩家附近的区块
int renderDistance = 10;
int playerChunkX = (int) cameraX / CHUNK_SIZE;
int playerChunkZ = (int) cameraZ / CHUNK_SIZE;
for (int cx = playerChunkX - renderDistance; cx <= playerChunkX + renderDistance; cx++) {
for (int cz = playerChunkZ - renderDistance; cz <= playerChunkZ + renderDistance; cz++) {
if (cx < 0 || cz < 0 || cx >= WORLD_SIZE / CHUNK_SIZE || cz >= WORLD_SIZE / CHUNK_SIZE) {
continue;
}
// 渲染区块
for (int x = cx * CHUNK_SIZE; x < (cx + 1) * CHUNK_SIZE; x++) {
for (int z = cz * CHUNK_SIZE; z < (cz + 1) * CHUNK_SIZE; z++) {
for (int y = 0; y < WORLD_HEIGHT; y++) {
int block = world[x][y][z];
if (block != AIR) {
renderBlock(x, y, z, block);
}
}
}
}
}
}
}
private void renderBlock(int x, int y, int z, int blockType) {
float[] color = blockColors.get(blockType);
if (color == null) return;
if (blockType == WATER) {
glColor4f(color[0], color[1], color[2], color[3]);
} else {
glColor3f(color[0], color[1], color[2]);
}
// 绘制方块
glPushMatrix();
glTranslatef(x, y, z);
// 绘制立方体的六个面
glBegin(GL_QUADS);
// 顶面(稍微亮一点)
if (blockType != WATER) {
glColor3f(color[0] * 1.2f, color[1] * 1.2f, color[2] * 1.2f);
}
glVertex3f(0, 1, 0);
glVertex3f(1, 1, 0);
glVertex3f(1, 1, 1);
glVertex3f(0, 1, 1);
if (blockType != WATER) {
glColor3f(color[0], color[1], color[2]);
}
// 底面
glVertex3f(0, 0, 1);
glVertex3f(1, 0, 1);
glVertex3f(1, 0, 0);
glVertex3f(0, 0, 0);
// 前面
glVertex3f(0, 0, 1);
glVertex3f(1, 0, 1);
glVertex3f(1, 1, 1);
glVertex3f(0, 1, 1);
// 后面
glVertex3f(1, 0, 0);
glVertex3f(0, 0, 0);
glVertex3f(0, 1, 0);
glVertex3f(1, 1, 0);
// 左面(稍微暗一点)
if (blockType != WATER) {
glColor3f(color[0] * 0.8f, color[1] * 0.8f, color[2] * 0.8f);
}
glVertex3f(0, 0, 0);
glVertex3f(0, 0, 1);
glVertex3f(0, 1, 1);
glVertex3f(0, 1, 0);
if (blockType != WATER) {
glColor3f(color[0], color[1], color[2]);
}
// 右面(稍微暗一点)
if (blockType != WATER) {
glColor3f(color[0] * 0.8f, color[1] * 0.8f, color[2] * 0.8f);
}
glVertex3f(1, 0, 1);
glVertex3f(1, 0, 0);
glVertex3f(1, 1, 0);
glVertex3f(1, 1, 1);
glEnd();
glPopMatrix();
}
private void renderInfo() {
// 切换到正交投影以渲染文本
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrtho(0, WIDTH, HEIGHT, 0, -1, 1);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
// 禁用深度测试以便文本显示在最前面
glDisable(GL_DEPTH_TEST);
// 绘制信息面板
glColor3f(1.0f, 1.0f, 1.0f);
glBegin(GL_QUADS);
glVertex2f(10, 10);
glVertex2f(300, 10);
glVertex2f(300, 130);
glVertex2f(10, 130);
glEnd();
// 设置文本颜色
glColor3f(0.0f, 0.0f, 0.0f);
// 绘制文本
drawString(20, 30, "Minecraft World Generator");
drawString(20, 50, "Position: " + String.format("%.1f, %.1f, %.1f", cameraX, cameraY, cameraZ));
drawString(20, 70, "Villages: " + villages.size());
drawString(20, 90, "Pillager Outposts: " + pillagerOutposts.size());
drawString(20, 110, "Controls: WASD - Move, Space/Shift - Up/Down, Mouse - Look, ESC - Exit");
// 恢复设置
glEnable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
}
private void drawString(int x, int y, String text) {
glRasterPos2f(x, y);
for (char c : text.toCharArray()) {
glutBitmapCharacter(GLUT_BITMAP_9_BY_15, c);
}
}
}
Wds移动Ese退出程序!!
往后的更新会越来越高级,有些可能需要VIP