跳转到内容

维基少年:树莓派/Minecraft 地牢迷宫

来自维基教科书,开放世界开放书籍

树莓派 Minecraft 地牢迷宫

Steve Martin 和 Andrew Oakley 的教程

公有领域 2018 年 5 月 17 日 www.cotswoldjam.org

要启动 Minecraft,请点击 Pi 菜单 - 游戏 - Minecraft Pi

点击开始游戏,然后点击现有游戏或点击创建新游戏

Tab ↹ 键在 Minecraft 世界和桌面上的正常鼠标之间切换。 Tab ↹ 键位于字母 Q 的左侧。

Esc 用于游戏菜单。

控制
鼠标看0 选择剑
WSAD 移动E 重新分配块 0-9
Space 跳跃Space 两次飞行
左键点击破坏块Space 再次两次停止飞行
右键点击创建块Space 飞行时一次向上
19 选择块类型⇧ Shift 飞行时向下

要使用 Minecraft 编程,请保持 Minecraft 运行。按下 Tab ↹ 键从游戏中释放鼠标,以便您可以使用桌面上的鼠标。

点击 Pi 菜单 - 编程 - Python3 (IDLE) 文件菜单 - 打开 - python/minecraft-dungeon/myDungeon.py

from Dungeon import Dungeon
dungeon = Dungeon()
entrance = dungeon.create()
room1 = dungeon.newRoom(entrance, "N")

使用运行菜单 - 运行模块运行程序。您应该看到一个通往房间的楼梯。

在程序中添加更多房间,例如

room1 = dungeon.newRoom(entrance, "N")
hallway = dungeon.newRoom(room1, "N")
bedroom = dungeon.newRoom(hallway, "W")
lounge = dungeon.newRoom(hallway, "E")

做一个迷宫!

Cjam-minecraft-dungeon.pdf

[编辑 | 编辑源代码]

本教程的原始 PDF 文件位于维基共享资源:Cjam-minecraft-dungeon.pdf

Dungeon.py

[编辑 | 编辑源代码]
from mcpi.minecraft import Minecraft
from mcpi import block
import DungeonError

class Dungeon:
    _mc = Minecraft.create()
    _rooms = {}
    _MIN_X = -10
    _MIN_Y = -42
    _MIN_Z = -80
    _MAX_X = 120
    _MAX_Y = -12
    _MAX_Z = 80
    _ROOM_WIDTH = 10
    _ROOM_LENGTH = 10
    _ROOM_HEIGHT = 4

    ###########################################################
    #
    # Construct a room with the given dimensions. Place torches
    # around the walls, optionally put a random piece of
    # treasure in the room.
    #
    ###########################################################
    def MakeRoom(self, x1, y1, z1, x2, y2, z2):
        # Plot the room itself
        self._mc.setBlocks(x1, y1, z1, x2, y2, z2, block.AIR.id)

        # Determine height of torch
        th = min([y1, y2]) + 2

        # Place torches along each wall.
        for i in range(x1+1, x2-1):
            if i % 6 == 0 and (self._mc.getBlock(i, th, z1-1) != block.AIR):
                self._mc.setBlock(i, th, z1, block.TORCH)
            if i % 6 == 0 and (self._mc.getBlock(i, th, z2+1) != block.AIR):
                self._mc.setBlock(i, th, z2, block.TORCH)
        for i in range(z1+1, z2-1):
            if i % 6 == 0 and (self._mc.getBlock(x1-1, th, i) != block.AIR):
                self._mc.setBlock(x1, th, i, block.TORCH)
            if i % 6 == 0 and (self._mc.getBlock(x2+1, th, i) != block.AIR):
                self._mc.setBlock(x2, th, i, block.TORCH)


    ###########################################################
    #
    # Construct a flight of steps going downwards. The steps
    # must go through water so must include walls and ceiling.
    #
    ############################################################
    def MakeSteps(self, x, y, z, l):
        for step in range(l+1):
            # Floor steps
            self._mc.setBlock(x+step, y-step, z-1, block.STAIRS_COBBLESTONE.id, 1)
            self._mc.setBlock(x+step, y-step, z, block.STAIRS_COBBLESTONE.id, 1)
            self._mc.setBlock(x+step, y-step, z+1, block.STAIRS_COBBLESTONE.id, 1)
            # Ceiling steps
            self._mc.setBlock(x+step, y-step+4, z-1, block.STAIRS_COBBLESTONE.id, 4)
            self._mc.setBlock(x+step, y-step+4, z, block.STAIRS_COBBLESTONE.id, 4)
            self._mc.setBlock(x+step, y-step+4, z+1, block.STAIRS_COBBLESTONE.id, 4)
            # Sidewalls
            self._mc.setBlocks(x+step, y-step, z-2, x+step, y-step+self._ROOM_HEIGHT, z-2, block.STONE)
            self._mc.setBlocks(x+step, y-step, z+2, x+step, y-step+self._ROOM_HEIGHT, z+2, block.STONE)
            # Ensure that nothing is in the void.
            self._mc.setBlocks(x+step, y-step+1, z-1, x+step, y-step+3, z+1, block.AIR)

    ###########################################################
    #
    # Construct a flight of steps going downwards to join rooms.
    #
    ############################################################
    def StepsDown(self, x, y, z):
        print(y)
        if (y == -12):
            fs = x+3
        else:
            fs = x+2
        self._mc.setBlocks(fs, y, z-1, x+self._ROOM_HEIGHT+2, y, z-1, block.FENCE)
        self._mc.setBlocks(fs, y, z+1, x+self._ROOM_HEIGHT+2, y, z+1, block.FENCE)
        #  self._mc.setBlocks(x+self._ROOM_HEIGHT+4, y, z-1, x+self._ROOM_HEIGHT+4, y, z+1, block.FENCE)
        for step in range(1, self._ROOM_HEIGHT+3):
            # Floor steps
            self._mc.setBlock(x+step, y-step, z, block.STAIRS_COBBLESTONE.id, 1)
            # Space to walk
            self._mc.setBlocks(x+step+1, y-step, z, x+step+3, y-step, z, block.AIR)

    ############################################################
    #
    # Construct a new room.
    #
    ############################################################
    def newRoom(self, start, direction):
        handle = len(self._rooms)
        if direction.upper() not in ["N", "S", "E", "W", "U", "D"]:
            raise DungeonError.DirectionError("Direction must be: \"N\", \"S\", \"E\", \"W\", \"U\" or \"D\"")
        else:
            if start not in self._rooms:
                raise DungeonError.RoomError("Unknown room: " + str(start))
            else:
                x, y, z = self._rooms[start]
                if (direction.upper() == "N"):
                    x += self._ROOM_LENGTH+2
                elif (direction.upper() == "S"):
                    x -= self._ROOM_LENGTH+2
                elif (direction.upper() == "E"):
                    z += self._ROOM_WIDTH+2
                elif (direction.upper() == "W"):
                    z -= self._ROOM_WIDTH+2
                elif (direction.upper() == "U"):
                    y += self._ROOM_HEIGHT+2
                else:
                    y -= self._ROOM_HEIGHT+2
                if (x > self._MAX_X-self._ROOM_LENGTH
                 or x < self._MIN_X
                 or z < self._MIN_Z
                 or x > self._MAX_Z-self._ROOM_WIDTH
                 or y > self._MAX_Y
                 or y < self._MIN_Y):
                    raise DungeonError.RoomError("Not enough space in direction \"" + direction + "\" from room " + str(start))
                else:
                    if (self._mc.getBlock(x+1, y, z+2) == block.AIR.id):
                        raise DungeonError.RoomError("There is already a room in direction \"" + direction + "\" from room " + str(start))
                    else:
                        self.MakeRoom(x, y, z, x+self._ROOM_LENGTH, y+self._ROOM_HEIGHT, z+self._ROOM_WIDTH)
                        self._rooms[handle] = [x, y, z]
                        # Create the ajoining corridore or steps
                        if (direction.upper() == "N"):
                            self._mc.setBlocks(x-2, y, z+self._ROOM_WIDTH/2, x, y+1, z+self._ROOM_WIDTH/2, block.AIR)
                        elif (direction.upper() == "S"):
                            self._mc.setBlocks(x+self._ROOM_LENGTH, y, z+self._ROOM_WIDTH/2, x+self._ROOM_LENGTH+2, y+1, z+self._ROOM_WIDTH/2, block.AIR)
                        elif (direction.upper() == "E"):
                            self._mc.setBlocks(x+self._ROOM_LENGTH/2, y, z-2, x+self._ROOM_LENGTH/2, y+1, z, block.AIR)
                        elif (direction.upper() == "W"):
                            self._mc.setBlocks(x+self._ROOM_LENGTH/2, y, z+self._ROOM_WIDTH, x+self._ROOM_LENGTH/2, y+1, z+self._ROOM_WIDTH+2, block.AIR)
                        elif (direction.upper() == "U"):
                            self.StepsDown(x+1, y, z+2)
                        else:
                            self.StepsDown(x+1, y+self._ROOM_HEIGHT+2, z+2)
        return handle


    def __init__(self):
        # Create a large underwater block of stone for the dungeon.
        self._mc.setBlocks(self._MIN_X, -4, self._MIN_Z, self._MAX_X, self._MIN_Y, self._MAX_Z, block.STONE)
        self._mc.setBlocks(self._MIN_X-2, 0, self._MIN_Z-2, self._MAX_X+2, -3, self._MAX_Z+2, block.WATER_STATIONARY)
        self._mc.setBlocks(self._MIN_X-4, 0, self._MIN_Z-4, self._MAX_X+4, 30, self._MAX_Z+4, block.AIR)

        # Create external plinth for player to stand on
        self._mc.setBlocks(-6, 0, -5, 0, -3, 5, block.STONE)


    def create(self):
        # Create a dungeon as the start point
        self.MakeRoom(10, -12, -5, 20, -8, 5)
        self._rooms[0] = [10, -12, -5]

        # Place some steps down into the dungeon.
        self.MakeSteps(1, 0, 0, 12)

        # Put the player near the dungeon entrance.
        self._mc.player.setPos(-2, 1, 0)
        self._mc.setting("world_immutable", True)
        return 0

DungeonError.py

[编辑 | 编辑源代码]
class DirectionError(Exception):
    def __init__(self, value):
        self.value = value

    def __str__(self):
        return repr(self.value)

class RoomError(Exception):
    def __init__(self, value):
        self.value = value

    def __str__(self):
        return repr(self.value)

myDungeon.py

[编辑 | 编辑源代码]
#!/usr/bin/env python3
from Dungeon import Dungeon

dungeon = Dungeon()
entrance = dungeon.create()
room1 = dungeon.newRoom(entrance, "N")

# Create more rooms by adding more "dungeon.newRoom(room, direction)"
# like the line above. "room" must be a room that you've already created.
# "direction" must be one of:
#    "N" - North
#    "S" - South
#    "E" - East
#    "W" - West
#    "U" - Up (above)
#    "D" - Down (below)
# Create one or two more rooms, then explore your dungeon to make sure
# that it is as you expect, then create more rooms.

TestDungeon.py

[编辑 | 编辑源代码]
#!/usr/bin/env python3
from Dungeon import Dungeon

dungeon = Dungeon()
hallway = dungeon.create()
d1 = dungeon.newRoom(hallway, "D")
d2 = dungeon.newRoom(d1, "D")
d3 = dungeon.newRoom(d2, "D")
d4 = dungeon.newRoom(d3, "D")
d5 = dungeon.newRoom(d4, "D")
bedroom = dungeon.newRoom(hallway, "N")
bedroom2 = dungeon.newRoom(hallway, "W")
bedroom3 = dungeon.newRoom(bedroom, "E")
bedroom4 = dungeon.newRoom(bedroom3, "D")
room5 = dungeon.newRoom(bedroom4, "N")
room6 = dungeon.newRoom(room5, "W")
room7 = dungeon.newRoom(room6, "U")
华夏公益教科书