CS61B 课程笔记(Lab 05 Getting Started on Project 2)

1. 导入项目

  • 导入步骤

    1. 确保在 proj2 目录级别进行导入,避免包结构问题。
    2. 在 IntelliJ 中选择 File -> New -> Project From Existing Sources,选择 proj2 文件夹。
  • 项目结构:导入后,项目结构应如下:

    1
    2
    3
    byog
    ├── Core
    └── lab5

2. 预实验步骤

步骤概述

  1. 更新骨架文件

    1
    git pull skeleton master
  2. 观看入门视频:访问提供的项目 2 入门视频链接。

  3. 阅读合作伙伴指南:了解合作要求。

  4. 可选阅读:查看项目 2 规格说明,以获得全面理解。

  5. 心态调整:准备进行一个较长时间的项目。

3. 组建项目 2 团队

  • 合作伙伴表单:如果希望与他人合作,填写此表单。
  • 单人表单:如果选择独立工作,填写此表单(不推荐)。

4. 实验介绍

目标

学习如何使用瓷砖渲染引擎,并为项目 2 做准备。

注意事项

  • 如果结束实验后没有找到合作伙伴,请联系实验助教。

5. 第一部分:认识瓷砖渲染引擎

5.1 BoringWorldDemo

  • 目的:演示如何创建一个简单的世界并用默认瓷砖填充它。

  • 代码分析

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    public class BoringWorldDemo {
    public static void main(String[] args) {
    TERenderer ter = new TERenderer(); // 创建渲染器对象
    ter.initialize(WIDTH, HEIGHT); // 初始化渲染器,设置宽高
    TETile[][] world = new TETile[WIDTH][HEIGHT]; // 创建瓷砖数组

    // 填充世界
    for (int x = 0; x < WIDTH; x++) {
    for (int y = 0; y < HEIGHT; y++) {
    world[x][y] = Tileset.NOTHING; // 填充为空瓷砖
    }
    }
    ter.renderFrame(world); // 渲染世界到屏幕
    }
    }
  • 背景说明

    • TERenderer 是渲染引擎的核心类,负责将瓷砖世界渲染到屏幕上。
    • TETile 是瓷砖的基本单位,Tileset.NOTHING 是表示空白区域的瓷砖。

5.2 TETile 对象

  • 创建瓷砖数组

    • TETile[][] 数组用于存储整个世界的瓷砖状态,维度由 WIDTHHEIGHT 决定。
  • 覆盖瓷砖

    1
    2
    3
    4
    5
    for (int x = 20; x < 35; x++) {
    for (int y = 5; y < 10; y++) {
    world[x][y] = Tileset.WALL; // 替换为墙壁瓷砖
    }
    }
    • 该代码块将坐标 (20, 5) 到 (34, 9) 的区域填充为 Tileset.WALL,形成一个墙壁。
  • 渲染瓷砖

    • 使用 ter.renderFrame(world) 方法将修改后的世界传递给渲染引擎以在屏幕上显示。

5.3 随机世界:RandomWorldDemo

  • 目的:展示如何随机填充瓷砖,以生成不同的世界。

  • 代码分析

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    public class RandomWorldDemo {
    public static void main(String[] args) {
    TERenderer ter = new TERenderer();
    ter.initialize(WIDTH, HEIGHT);
    TETile[][] world = new TETile[WIDTH][HEIGHT];
    Random rand = new Random(2873123); // 初始化随机数生成器

    // 随机填充瓷砖
    for (int x = 0; x < WIDTH; x++) {
    for (int y = 0; y < HEIGHT; y++) {
    int randomNum = rand.nextInt(3); // 生成 0-2 的随机数
    if (randomNum == 0) {
    world[x][y] = Tileset.WALL; // 墙壁瓷砖
    } else if (randomNum == 1) {
    world[x][y] = Tileset.FLOWER; // 花朵瓷砖
    } else {
    world[x][y] = Tileset.NOTHING; // 空瓷砖
    }
    }
    }
    ter.renderFrame(world); // 渲染随机生成的世界
    }
    }
  • 关键点

    • 使用 Random 类生成伪随机数,通过 nextInt(3) 来随机选择瓷砖类型。
    • 可以使用 switch 语句替换 if-else 结构以提高可读性。

6. 第二部分:使用瓷砖渲染引擎

6.1 六边形世界介绍

  • 目标:创建一个随机地形生成器,生成基于六边形的世界。
    • 六边形瓷砖在视觉上比矩形更具吸引力,并且在某些类型的游戏中,六边形可以提供更自然的连接性。

6.2 HexagonTile 类

  • 类定义

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    public class HexagonTile {
    private String type; // 瓷砖类型
    private int x, y; // 瓷砖坐标

    // 构造器
    public HexagonTile(String type, int x, int y) {
    this.type = type;
    this.x = x;
    this.y = y;
    }

    // 绘制瓷砖的方法
    public void draw(TERenderer ter) {
    // 在此实现具体的绘制逻辑,可能涉及到对六边形形状的计算
    }

    // 计算邻接瓷砖
    public List<HexagonTile> calculateNeighbors(HexagonTile[][] grid) {
    List<HexagonTile> neighbors = new ArrayList<>();
    // 根据当前瓷砖坐标 (x, y),计算相邻的六边形瓷砖
    // 通常为上下左右和斜对角的六个方向
    return neighbors;
    }
    }
  • 背景说明

    • HexagonTile 类用于创建六边形瓷砖的实例,每个瓷砖都有类型和坐标属性。
    • draw() 方法需要实现具体的绘制逻辑,这可能涉及到计算六边形的形状和位置。
    • calculateNeighbors() 方法用于获取该瓷砖的邻接瓷砖,六边形的邻接逻辑相对复杂,需要考虑六个方向。

实现细节

  • 绘制六边形
    • 使用数学计算确定六边形的每个顶点,然后利用渲染引擎的绘制方法进行绘制。
  • 邻接计算
    • 根据六边形的布局,需要实现复杂的坐标转换,确保能够正确识别并返回所有相邻的瓷砖。

6.3 构建提示

  1. HexagonTile 类
    • 接收瓷砖类型和坐标。
    • draw() 方法根据坐标绘制瓷砖。
    • calculateNeighbors() 返回相邻瓷砖。
  2. 随机数生成器
    • 使用 Random 类生成随机类型。
  3. 瓷砖构造
    • 注意 Tileset.javaTETile 的构造和使用。

7. 合作与建议

  • 积极参与讨论,利用团队的力量进行学习。
  • 使用 GitHub Issues 页面报告 Bug 或请求功能。

8. 实验结束

  • 完成本实验后,你应能使用瓷砖渲染引擎生成随机世界,并理解 HexagonTile 的设计及使用。