Python编程Minecraft系列(少儿编程)
第二章 Minescript的API接口说明
文章目录
Minescript API 文档
API接口分类文档
一、基础输出与通信
1.1 文本输出函数
# 向聊天窗口输出消息(仅本地可见)
echo("Hello, World!")
echo("玩家位置:", x, y, z) # 支持多参数
# 发送聊天消息(其他玩家可见)
chat("大家好!")
chat("我在坐标", x, y, z)
# 输出JSON格式文本
echo_json({"message": "Hello", "color": "green"})
# 写入日志文件
log("调试信息:", variable_value)
1.2 命令执行
# 执行Minecraft命令
execute("/gamemode creative")
execute("setblock 0 64 0 diamond_block")
# 执行Minescript命令
execute("\\my_script")
二、玩家信息与控制
2.1 玩家信息获取
# 获取玩家名称
name = player_name()
# 获取玩家位置 [x, y, z]
x, y, z = player_position()
# 获取玩家详细信息
player_info = player()
print(f"生命值: {player_info.health}")
print(f"位置: {player_info.position}")
# 获取玩家朝向 [yaw, pitch]
yaw, pitch = player_orientation()
# 获取玩家生命值
health = player_health()
2.2 玩家控制
# 设置玩家朝向
player_set_orientation(90.0, 0.0) # 面向东方
# 让玩家看向指定坐标
player_look_at(100, 64, 200)
# 模拟按键操作
player_press_forward(True) # 开始前进
player_press_jump(True) # 跳跃
player_press_sneak(True) # 潜行
2.3 物品栏管理
# 获取手持物品
hand_items = player_hand_items()
print(f"主手: {hand_items.main_hand}")
print(f"副手: {hand_items.off_hand}")
# 获取背包物品
inventory = player_inventory()
for item in inventory:
print(f"物品: {item.item}, 数量: {item.count}")
# 选择快捷栏槽位
player_inventory_select_slot(0) # 选择第一个槽位
三、方块操作与建筑
3.1 基础方块操作
execute(command: str)
执行Minecraft命令,这是操作游戏世界的主要方式。
参数:
command: 要执行的命令字符串
使用示例:
from minescript import execute
# 放置方块
execute("setblock 100 64 100 stone")
# 填充区域
execute("fill 0 64 0 10 64 10 grass_block")
# 生成实体
execute("summon pig 100 65 100")
getblock(x: int, y: int, z: int) -> str
获取指定位置的方块类型。
参数:
x, y, z: 方块的坐标位置
返回值:
- 方块类型的字符串
使用示例:
from minescript import getblock
# 获取玩家脚下的方块
pos = player_position()
block_type = getblock(int(pos.x), int(pos.y)-1, int(pos.z))
echo(f"你脚下的方块是: {block_type}")
3.2 方块信息获取
# 获取单个方块类型
block_type = getblock(100, 64, 100)
# 批量获取方块
positions = [[100, 64, 100], [101, 64, 100], [102, 64, 100]]
blocks = getblocklist(positions)
# 获取区域内所有方块
region = get_block_region((0, 64, 0), (10, 70, 10))
for x in range(region.x_length):
for y in range(region.y_length):
for z in range(region.z_length):
block = region.get_block(
region.min_pos[0] + x,
region.min_pos[1] + y,
region.min_pos[2] + z
)
print(f"方块 ({x},{y},{z}): {block}")
3.3 批量方块操作 - BlockPacker
from minescript import BlockPacker
# 创建方块打包器
packer = BlockPacker()
# 添加方块
packer.setblock((100, 64, 100), "stone")
packer.setblock((101, 64, 100), "cobblestone")
# 执行批量操作
blockpack = packer.pack()
blockpack.place((200, 64, 200)) # 在新位置放置
3.4 实用建筑函数示例
def build_wall(start_pos, end_pos, block_type="cobblestone"):
"""建造墙壁"""
x1, y1, z1 = start_pos
x2, y2, z2 = end_pos
execute(f"fill {x1} {y1} {z1} {x2} {y2} {z2} {block_type}")
def build_house(pos, width, height, depth):
"""建造简单房屋"""
x, y, z = pos
# 地基
execute(f"fill {x} {y} {z} {x+width-1} {y} {z+depth-1} stone")
# 墙壁
execute(f"fill {x} {y+1} {z} {x+width-1} {y+height} {z+depth-1} cobblestone hollow")
# 屋顶
execute(f"fill {x} {y+height+1} {z} {x+width-1} {y+height+1} {z+depth-1} oak_planks")
四、事件处理系统
4.1 EventQueue 事件队列系统
EventQueue 是 Minescript 4.0+ 版本中推荐的事件处理方式,支持上下文管理器语法,可以自动注销事件监听器。
from minescript import EventQueue, EventType
# 基本使用模式
with EventQueue() as event_queue:
# 注册需要的事件监听器
event_queue.register_chat_listener()
# 事件循环
while True:
event = event_queue.get(timeout=1.0) # 1秒超时
if event is None:
continue # 超时,继续循环
# 处理事件
if event.type == EventType.CHAT:
echo(f"收到聊天消息: {event.message}")
4.2 所有支持的事件类型
4.2.1 键盘事件 (KeyEvent)
监听键盘按键事件,包括按下、释放和重复按键。
事件属性:
type: “key”time: 事件发生时间戳key: 按键代码 (参考: https://www.glfw.org/docs/3.4/group__keys.html)scan_code: 扫描码action: 动作类型 (0=释放, 1=按下, 2=重复)modifiers: 修饰键状态screen: 当前屏幕名称
with EventQueue() as event_queue:
event_queue.register_key_listener()
while True:
event = event_queue.get()
if event.type == EventType.KEY:
if event.action == 1: # 按键按下
if event.key == 32: # 空格键
echo("空格键被按下!")
elif event.key == 71: # G键
execute("summon pig")
echo("生成了一只猪!")
4.2.2 鼠标事件 (MouseEvent)
监听鼠标点击事件。
事件属性:
type: “mouse”time: 事件发生时间戳button: 鼠标按钮 (0=左键, 1=右键, 2=中键)action: 动作类型 (0=释放, 1=按下)modifiers: 修饰键状态x,y: 鼠标坐标screen: 当前屏幕名称
with EventQueue() as event_queue:
event_queue.register_mouse_listener()
while True:
event = event_queue.get()
if event.type == EventType.MOUSE:
if event.action == 1: # 鼠标按下
if event.button == 0: # 左键
echo(f"左键点击在坐标 ({event.x:.1f}, {event.y:.1f})")
elif event.button == 1: # 右键
echo(f"右键点击在坐标 ({event.x:.1f}, {event.y:.1f})")
4.2.3 聊天事件 (ChatEvent)
监听聊天消息,包括接收和发送的消息。
事件属性:
type: “chat”time: 事件发生时间戳message: 聊天消息内容
with EventQueue() as event_queue:
event_queue.register_chat_listener()
while True:
event = event_queue.get()
if event.type == EventType.CHAT:
message = event.message.lower()
if "hello" in message:
chat("Hello there!")
elif "time" in message:
import time
chat(f"当前时间: {time.strftime('%H:%M:%S')}")
4.2.4 聊天拦截事件 (OutgoingChatIntercept)
拦截玩家发送的聊天消息,可以修改或阻止消息发送。
with EventQueue() as event_queue:
# 拦截包含特定前缀的消息
event_queue.register_outgoing_chat_interceptor(prefix="/pos")
while True:
event = event_queue.get()
if event.type == EventType.OUTGOING_CHAT_INTERCEPT:
# 将 /pos 替换为当前位置
pos = player_position()
chat(f"我的位置: {pos.x:.1f}, {pos.y:.1f}, {pos.z:.1f}")
4.2.5 实体添加事件 (AddEntityEvent)
监听新实体生成事件。
事件属性:
type: “add_entity”time: 事件发生时间戳entity: EntityData 对象,包含实体详细信息
with EventQueue() as event_queue:
event_queue.register_add_entity_listener()
while True:
event = event_queue.get()
if event.type == EventType.ADD_ENTITY:
entity = event.entity
echo(f"新实体生成: {entity.name} 在位置 {entity.position}")
# 如果是敌对生物,发出警告
if entity.type in ["zombie", "skeleton", "creeper"]:
echo(f"警告: 发现敌对生物 {entity.type}!")
4.2.6 方块更新事件 (BlockUpdateEvent)
监听方块状态变化事件。
事件属性:
type: “block_update”time: 事件发生时间戳position: BlockPos 对象,方块位置old_state: 旧方块状态new_state: 新方块状态
with EventQueue() as event_queue:
event_queue.register_block_update_listener()
while True:
event = event_queue.get()
if event.type == EventType.BLOCK_UPDATE:
pos = event.position
echo(f"方块更新: ({pos.x}, {pos.y}, {pos.z})")
echo(f" 从: {event.old_state}")
echo(f" 到: {event.new_state}")
# 检测钻石矿被挖掘
if "diamond_ore" in event.old_state and event.new_state == "air":
echo("发现钻石矿被挖掘!")
4.2.7 物品拾取事件 (TakeItemEvent)
监听玩家拾取物品事件。
事件属性:
type: “take_item”time: 事件发生时间戳player_uuid: 拾取物品的玩家UUIDitem: EntityData 对象,物品信息amount: 拾取数量
with EventQueue() as event_queue:
event_queue.register_take_item_listener()
while True:
event = event_queue.get()
if event.type == EventType.TAKE_ITEM:
item_name = event.item.name
echo(f"拾取物品: {item_name} x{event.amount}")
# 统计贵重物品
if item_name in ["diamond", "emerald", "netherite_ingot"]:
echo(f"获得贵重物品: {item_name}!")
4.2.8 伤害事件 (DamageEvent)
监听实体受到伤害事件。
事件属性:
type: “damage”time: 事件发生时间戳entity_uuid: 受伤实体UUIDcause_uuid: 伤害来源实体UUIDsource: 伤害来源类型
with EventQueue() as event_queue:
event_queue.register_damage_listener()
while True:
event = event_queue.get()
if event.type == EventType.DAMAGE:
echo(f"伤害事件: 来源 {event.source}")
# 如果玩家受到伤害,发出警告
player_uuid = player().uuid
if event.entity_uuid == player_uuid:
echo(f"警告: 你受到了来自 {event.source} 的伤害!")
4.2.9 爆炸事件 (ExplosionEvent)
监听爆炸事件。
事件属性:
type: “explosion”time: 事件发生时间戳position: Vector3f 对象,爆炸位置blockpack_base64: 受影响方块的Base64编码数据
with EventQueue() as event_queue:
event_queue.register_explosion_listener()
while True:
event = event_queue.get()
if event.type == EventType.EXPLOSION:
pos = event.position
echo(f"爆炸发生在: ({pos.x:.1f}, {pos.y:.1f}, {pos.z:.1f})")
# 检查爆炸是否靠近玩家
player_pos = player_position()
distance = ((pos.x - player_pos.x)**2 +
(pos.y - player_pos.y)**2 +
(pos.z - player_pos.z)**2)**0.5
if distance < 10:
echo("警告: 附近发生爆炸!")
4.2.10 区块事件 (ChunkEvent)
监听区块加载/卸载事件。
事件属性:
type: “chunk”time: 事件发生时间戳loaded: 是否加载 (True=加载, False=卸载)x_min,z_min: 区块最小坐标x_max,z_max: 区块最大坐标
with EventQueue() as event_queue:
event_queue.register_chunk_listener()
while True:
event = event_queue.get()
if event.type == EventType.CHUNK:
action = "加载" if event.loaded else "卸载"
echo(f"区块{action}: ({event.x_min}, {event.z_min}) 到 ({event.x_max}, {event.z_max})")
4.2.11 世界事件 (WorldEvent)
监听世界连接/断开事件。
事件属性:
type: “world”time: 事件发生时间戳connected: 是否连接 (True=连接, False=断开)
with EventQueue() as event_queue:
event_queue.register_world_listener()
while True:
event = event_queue.get()
if event.type == EventType.WORLD:
if event.connected:
world = world_info()
echo(f"连接到世界: {world.name}")
else:
echo("从世界断开连接")
4.3 事件处理最佳实践
4.3.1 多事件监听
with EventQueue() as event_queue:
# 注册多个事件监听器
event_queue.register_key_listener()
event_queue.register_chat_listener()
event_queue.register_block_update_listener()
while True:
event = event_queue.get(timeout=0.1)
if event is None:
continue
# 根据事件类型分别处理
if event.type == EventType.KEY:
handle_key_event(event)
elif event.type == EventType.CHAT:
handle_chat_event(event)
elif event.type == EventType.BLOCK_UPDATE:
handle_block_update_event(event)
def handle_key_event(event):
if event.action == 1: # 按键按下
echo(f"按键 {event.key} 被按下")
def handle_chat_event(event):
if "help" in event.message.lower():
chat("可用命令: /pos, /time, /weather")
def handle_block_update_event(event):
if "diamond" in event.new_state:
echo("发现钻石方块!")
4.3.2 事件过滤和条件处理
with EventQueue() as event_queue:
event_queue.register_add_entity_listener()
# 只关注特定类型的实体
target_entities = ["zombie", "skeleton", "creeper", "spider"]
while True:
event = event_queue.get()
if event.type == EventType.ADD_ENTITY:
entity = event.entity
# 过滤:只处理敌对生物
if entity.type in target_entities:
player_pos = player_position()
entity_pos = entity.position
# 计算距离
distance = ((entity_pos.x - player_pos.x)**2 +
(entity_pos.y - player_pos.y)**2 +
(entity_pos.z - player_pos.z)**2)**0.5
# 如果敌对生物距离太近,发出警告
if distance < 20:
echo(f"警告: {entity.type} 在 {distance:.1f} 格距离内!")
4.3.3 事件数据持久化
import json
from datetime import datetime
# 事件日志记录
event_log = []
with EventQueue() as event_queue:
event_queue.register_damage_listener()
event_queue.register_explosion_listener()
while True:
event = event_queue.get()
# 记录重要事件
if event.type in [EventType.DAMAGE, EventType.EXPLOSION]:
log_entry = {
"type": event.type,
"time": datetime.now().isoformat(),
"data": event.__dict__
}
event_log.append(log_entry)
# 每10个事件保存一次
if len(event_log) >= 10:
with open("event_log.json", "w") as f:
json.dump(event_log, f, indent=2)
event_log.clear()
echo("事件日志已保存")
五、实体管理
5.1 实体信息获取
# 获取所有玩家
all_players = players()
for player in all_players:
echo(f"玩家: {player.name}, 位置: {player.position}")
# 获取附近实体
nearby_entities = entities(max_distance=50)
for entity in nearby_entities:
echo(f"实体: {entity.name}, 类型: {entity.type}")
# 获取玩家瞄准的方块
targeted_block = player_get_targeted_block(max_distance=10)
if targeted_block:
echo(f"瞄准方块: {targeted_block.block_type} 在 {targeted_block.position}")
# 获取玩家瞄准的实体
targeted_entity = player_get_targeted_entity(max_distance=10)
if targeted_entity:
echo(f"瞄准实体: {targeted_entity.name}")
六、世界信息与管理
6.1 世界信息
# 获取版本信息
version = version_info()
echo(f"Minecraft版本: {version.minecraft_version}")
echo(f"Minescript版本: {version.minescript_version}")
# 获取世界信息
world = world_info()
echo(f"世界名称: {world.name}")
echo(f"游戏模式: {world.game_type}")
echo(f"难度: {world.difficulty}")
6.2 区域加载
# 等待区域加载完成
await_loaded_region(-100, -100, 100, 100)
echo("区域已加载完成!")
七、方块包(BlockPack)系统
7.1 方块包操作
# 创建方块包
packer = BlockPacker()
packer.add_blocks([(0, 64, 0), (1, 64, 0)], ["stone", "dirt"])
# 打包并保存
blockpack = packer.pack({"author": "作者", "description": "建筑描述"})
blockpack.write_file("my_building.bp")
# 读取和使用方块包
loaded_pack = BlockPack.read_file("my_building.bp")
loaded_pack.write_world((100, 64, 100)) # 在新位置放置
八、红石电路控制
8.1 红石电路操作
# 红石电路控制示例
def create_redstone_clock(x, y, z):
# 创建红石时钟电路
execute(f"setblock {x} {y} {z} redstone_block")
execute(f"setblock {x+1} {y} {z} repeater[facing=east,delay=4]")
execute(f"setblock {x+2} {y} {z} redstone_wire")
execute(f"setblock {x+2} {y} {z+1} repeater[facing=west,delay=4]")
execute(f"setblock {x+1} {y} {z+1} redstone_wire")
execute(f"setblock {x} {y} {z+1} redstone_wire")
# 检测红石信号
def check_redstone_power(x, y, z):
block = getblock(x, y, z)
if "powered=true" in block:
return True
return False
API功能总结
核心功能
- 方块操作: 放置、获取、批量操作方块
- 玩家控制: 获取和控制玩家状态
- 事件处理: 监听游戏内各种事件
- 实体管理: 操作和查询游戏实体
- 世界信息: 获取世界和版本信息
- 方块包系统: 保存和复用建筑结构
- 红石控制: 创建和控制红石电路
支持的操作类型
- 基础输出和通信
- 复杂建筑创建
- 实时事件响应
- 批量方块处理
- 玩家交互控制
- 世界状态查询
Minescript API详解
815

被折叠的 条评论
为什么被折叠?



