当前位置: 首页 > news >正文

使用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

http://www.lryc.cn/news/625847.html

相关文章:

  • 为了提高项目成功率,项目预算如何分配
  • Datawhale工作流自动化平台n8n入门教程(一):n8n简介与平台部署
  • LeetCode算法日记 - Day 16: 连续数组、矩阵区域和
  • 免费导航规划API接口详解:调用指南与实战示例
  • 海滨浴场应急广播:守护碧海蓝天的安全防线
  • Shopee本土店账号安全运营:规避封禁风险的多维策略
  • 云存储的高效安全助手:阿里云国际站 OSS
  • 技术攻坚全链铸盾 锁定12月济南第26届食品农产品安全高峰论坛
  • https如何保证传递参数的安全
  • 学习嵌入式的第二十一天——数据结构——链表
  • 乾元通渠道商中标六盘水应急指挥能力提升项目
  • 路由器最大传输速率测试
  • 首届机器人足球运动会技术复盘:从赛场表现看智能机器人核心技术突破
  • GTSAM中实现多机器人位姿图优化(multi-robot pose graph optimization)示例
  • 用机器人实现OpenAI GPT-5视觉驱动的闲聊:OpenAIAPI Key获取并配置启动视觉项目
  • sfc_os!SfcQueueValidationRequest函数分析之sfc_os!IsFileInQueue
  • 当MySQL的int不够用了
  • 差速转向机器人研发:创新驱动的未来移动技术探索
  • 实现进度条
  • 1分钟批量生成100张,Coze扣子智能体工作流批量生成人物一致的治愈系漫画图文(IP形象可自定义)
  • 华为鸿蒙系统SSH如何通过私钥连接登录
  • 如何成功初始化一个模块
  • Infusing fine-grained visual knowledge to Vision-Language Models
  • 传输层协议——UDP和TCP
  • 如何理解关系型数据库的ACID?
  • 【集合框架LinkedList底层添加元素机制】
  • ⭐CVPR2025 建模部件级动态的 4D 重建框架
  • 数据安全治理——解读67页2024金融数据安全治理白皮书【附全文阅读】
  • 路由器详解
  • Java JDK官网下载渠道