class EnchantmentSystem:
# 附魔类型定义
ENCHANTMENTS = {
# 工具类附魔
1: {"name": "效率", "max_level": 5, "cost": [1, 5, 10, 20, 30], "applicable": ["pickaxe", "axe", "shovel"]},
2: {"name": "精准采集", "max_level": 1, "cost": [25], "applicable": ["pickaxe", "axe", "shovel"]},
3: {"name": "耐久", "max_level": 3, "cost": [5, 10, 15], "applicable": ["all_tools"]},
# 武器类附魔
4: {"name": "锋利", "max_level": 5, "cost": [2, 8, 15, 25, 35], "applicable": ["sword"]},
5: {"name": "亡灵杀手", "max_level": 5, "cost": [5, 12, 20, 28, 38], "applicable": ["sword"]},
6: {"name": "击退", "max_level": 2, "cost": [5, 15], "applicable": ["sword"]},
7: {"name": "火焰附加", "max_level": 2, "cost": [15, 30], "applicable": ["sword"]},
8: {"name": "抢夺", "max_level": 3, "cost": [10, 20, 35], "applicable": ["sword"]},
# 盔甲类附魔
9: {"name": "保护", "max_level": 4, "cost": [5, 10, 15, 25], "applicable": ["armor"]},
10: {"name": "火焰保护", "max_level": 4, "cost": [8, 12, 20, 30], "applicable": ["armor"]},
11: {"name": "水下速掘", "max_level": 1, "cost": [20], "applicable": ["helmet"]},
12: {"name": "荆棘", "max_level": 3, "cost": [15, 25, 40], "applicable": ["chestplate"]},
# 弓类附魔
13: {"name": "力量", "max_level": 5, "cost": [5, 10, 15, 25, 35], "applicable": ["bow"]},
14: {"name": "火矢", "max_level": 2, "cost": [15, 30], "applicable": ["bow"]},
15: {"name": "无限", "max_level": 1, "cost": [40], "applicable": ["bow"]},
}
def __init__(self, player):
self.player = player
self.enchantment_table = None
self.open_enchantment_table = None
self.lapis_cost = 0
self.selected_enchant = None
self.enchantment_levels = 0
def get_available_enchantments(self, item):
"""获取物品可用的附魔选项"""
item_type = self.get_item_type(item)
if not item_type:
return []
available = []
for ench_id, ench_data in self.ENCHANTMENTS.items():
if item_type in ench_data["applicable"] or "all_tools" in ench_data["applicable"]:
available.append(ench_id)
# 随机选择3个选项
if len(available) > 3:
return random.sample(available, 3)
return available
def get_item_type(self, item):
"""获取物品类型"""
if 100 <= item <= 105: # 钻石工具
return "pickaxe" if item == 100 else "axe" if item == 101 else "shovel" if item == 102 else "sword" if item == 103 else "hoe" if item == 104 else None
elif 200 <= item <= 204: # 盔甲
return "helmet" if item == 200 else "chestplate" if item == 201 else "leggings" if item == 202 else "boots" if item == 203 else None
elif item == 300: # 弓
return "bow"
return None
def calculate_enchantment_levels(self):
"""计算附魔等级(基于书架数量和玩家经验)"""
if not self.enchantment_table:
return [0, 0, 0]
# 计算书架数量
bookshelves = self.count_bookshelves()
# 基础等级
base_level = min(bookshelves // 2, 15)
# 随机化三个选项
options = [
max(1, base_level + random.randint(1, 8)),
max(1, base_level + random.randint(1, 5)),
max(1, base_level + random.randint(1, 3))
]
# 按玩家等级限制
player_level = self.player.experience_level
return [
min(options[0], player_level),
min(options[1], player_level),
min(options[2], player_level)
]
def count_bookshelves(self):
"""计算附魔台周围的书籍数量"""
count = 0
x, y, z = self.enchantment_table
# 检查周围5x5区域
for dx in range(-2, 3):
for dz in range(-2, 3):
# 只检查同一层
block_pos = (x + dx, y, z + dz)
if self.player.world.get_block(block_pos) == BlockType.BOOKSHELF:
# 检查是否有阻挡物
if not self.is_blocked(block_pos):
count += 1
return min(count, 15) # 最大15个书架
def is_blocked(self, bookshelf_pos):
"""检查书架和附魔台之间是否有阻挡"""
x1, y1, z1 = self.enchantment_table
x2, y2, z2 = bookshelf_pos
# 简单直线检测
steps = max(abs(x1-x2), abs(z1-z2))
for i in range(1, steps):
t = i / steps
px = int(x1 + (x2 - x1) * t)
pz = int(z1 + (z2 - z1) * t)
block_pos = (px, y1, pz)
if self.player.world.get_block(block_pos) not in [BlockType.AIR, BlockType.CARPET]:
return True
return False
def apply_enchantment(self, item_slot, enchant_id, level):
"""应用附魔到物品"""
if not self.player.inventory.items[item_slot]:
return False
item = self.player.inventory.items[item_slot]
cost = self.ENCHANTMENTS[enchant_id]["cost"][level-1]
# 检查青金石和等级
if self.player.lapis_count < cost or self.player.experience_level < cost:
return False
# 消耗资源
self.player.lapis_count -= cost
self.player.experience_level -= cost
# 添加附魔
if "enchantments" not in item:
item["enchantments"] = {}
item["enchantments"][enchant_id] = level
# 添加发光效果
item["glowing"] = True
return True
class EnchantmentGUI:
def __init__(self, system, window_width, window_height):
self.system = system
self.width = window_width
self.height = window_height
self.batch = pyglet.graphics.Batch()
self.enchantment_options = []
self.selected_slot = None
# 创建UI元素
self.background = pyglet.shapes.Rectangle(
width/2-150, height/2-100, 300, 200,
color=(50, 50, 100), batch=self.batch)
self.title = pyglet.text.Label("附魔台",
x=width/2, y=height/2+80, anchor_x='center',
font_size=16, batch=self.batch)
# 物品槽
self.item_slot = pyglet.shapes.Rectangle(
width/2-130, height/2+40, 40, 40,
color=(100, 100, 150), batch=self.batch)
# 青金石槽
self.lapis_slot = pyglet.shapes.Rectangle(
width/2-130, height/2-10, 40, 40,
color=(30, 60, 150), batch=self.batch)
# 附魔槽
self.enchant_slots = []
for i in range(3):
slot = pyglet.shapes.Rectangle(
width/2-40 + i*60, height/2+40, 50, 50,
color=(80, 80, 120), batch=self.batch)
self.enchant_slots.append(slot)
# 附魔等级显示
level_label = pyglet.text.Label("",
x=slot.x+25, y=slot.y+10, anchor_x='center',
color=(200, 200, 50, 255), batch=self.batch)
self.enchantment_options.append({"slot": slot, "level": level_label})
def update(self, item_slot):
"""更新界面显示"""
if not item_slot or not self.system.player.inventory.items[item_slot]:
# 清空显示
for option in self.enchantment_options:
option["level"].text = ""
return
item = self.system.player.inventory.items[item_slot]
enchant_levels = self.system.calculate_enchantment_levels()
available_enchantments = self.system.get_available_enchantments(item["id"])
# 更新附魔选项
for i, option in enumerate(self.enchantment_options):
if i < len(available_enchantments):
ench_id = available_enchantments[i]
ench_data = self.system.ENCHANTMENTS[ench_id]
option["level"].text = f"{ench_data['name']} {enchant_levels[i]}"
option["ench_id"] = ench_id
option["level_value"] = min(enchant_levels[i], ench_data["max_level"])
else:
option["level"].text = ""
option["ench_id"] = None
def draw(self):
"""绘制界面"""
self.batch.draw()
# 绘制物品
if self.system.player.inventory.items[self.system.open_enchantment_table["item_slot"]]:
item = self.system.player.inventory.items[self.system.open_enchantment_table["item_slot"]]
self.draw_item_icon(item, self.item_slot.x+20, self.item_slot.y+20)
# 绘制青金石
self.draw_lapis(self.lapis_slot.x+20, self.lapis_slot.y+20)
# 绘制书架计数
bookshelf_count = self.system.count_bookshelves()
bookshelf_label = pyglet.text.Label(f"书架: {bookshelf_count}",
x=self.width/2+100, y=self.height/2+60, batch=self.batch)
bookshelf_label.draw()
def draw_item_icon(self, item, x, y):
"""绘制物品图标"""
# 简化的物品绘制
color = (200, 200, 200) # 默认灰色
if "glowing" in item and item["glowing"]:
color = (220, 220, 50) # 附魔物品为金色
pyglet.shapes.Circle(x, y, 15, color=color).draw()
# 如果有附魔,显示附魔数量
if "enchantments" in item:
ench_count = len(item["enchantments"])
label = pyglet.text.Label(str(ench_count),
x=x, y=y-2, anchor_x='center', anchor_y='center',
color=(0, 200, 0, 255))
label.draw()
def draw_lapis(self, x, y):
"""绘制青金石"""
pyglet.shapes.Circle(x, y, 15, color=(30, 80, 220)).draw()
count_label = pyglet.text.Label(str(self.system.player.lapis_count),
x=x, y=y-2, anchor_x='center', anchor_y='center',
color=(255, 255, 255, 255))
count_label.draw()
def handle_click(self, x, y):
"""处理界面点击"""
# 检查附魔选项点击
for i, slot in enumerate(self.enchant_slots):
if (slot.x <= x <= slot.x+slot.width and
slot.y <= y <= slot.y+slot.height):
self.selected_slot = i
return "enchant"
return None
# 在游戏主类中集成附魔系统
class EnchantedGameWindow(GameWindow):
def __init__(self):
super().__init__()
self.enchantment_system = EnchantmentSystem(self.player)
self.enchantment_gui = None
self.register_event_handler('on_key_press', self.handle_enchant_key)
# 添加新方块类型
BlockType.ENCHANTING_TABLE = 50
BlockType.BOOKSHELF = 51
def handle_enchant_key(self, symbol, modifiers):
"""处理附魔快捷键"""
if symbol == key.E and self.enchantment_system.open_enchantment_table:
self.open_enchantment_gui()
def on_block_interact(self, pos, block_type):
"""处理方块交互"""
if block_type == BlockType.ENCHANTING_TABLE:
# 记录打开的附魔台位置
self.enchantment_system.enchantment_table = pos
self.enchantment_system.open_enchantment_table = {
"pos": pos,
"item_slot": None # 等待玩家放置物品
}
self.open_enchantment_gui()
return True
return super().on_block_interact(pos, block_type)
def open_enchantment_gui(self):
"""打开附魔界面"""
self.enchantment_gui = EnchantmentGUI(
self.enchantment_system, self.width, self.height)
self.enchantment_gui.update(self.enchantment_system.open_enchantment_table["item_slot"])
def on_draw(self):
super().on_draw()
if self.enchantment_gui:
self.enchantment_gui.draw()
def on_mouse_press(self, x, y, button, modifiers):
if self.enchantment_gui:
action = self.enchantment_gui.handle_click(x, y)
if action == "enchant" and self.enchantment_gui.selected_slot is not None:
slot_index = self.enchantment_gui.selected_slot
option = self.enchantment_gui.enchantment_options[slot_index]
if option["ench_id"]:
success = self.enchantment_system.apply_enchantment(
self.enchantment_system.open_enchantment_table["item_slot"],
option["ench_id"],
option["level_value"]
)
if success:
# 更新界面
self.enchantment_gui.update(
self.enchantment_system.open_enchantment_table["item_slot"])
return
# 原有交互逻辑...
def apply_enchantment_effects(self):
"""应用附魔效果到游戏机制"""
# 检查玩家装备
for slot, item in self.player.equipment.items():
if item and "enchantments" in item:
for ench_id, level in item["enchantments"].items():
self.apply_single_enchant(ench_id, level, item)
def apply_single_enchant(self, ench_id, level, item):
"""应用单个附魔效果"""
# 工具效率
if ench_id == 1: # 效率
self.player.mining_speed_multiplier = 1.0 + level * 0.3
# 武器效果
elif ench_id == 4: # 锋利
self.player.attack_damage_bonus = level * 1.25
elif ench_id == 7: # 火焰附加
self.player.fire_aspect_level = level
# 盔甲效果
elif ench_id == 9: # 保护
self.player.damage_reduction += level * 0.04
elif ench_id == 12: # 荆棘
self.player.thorns_level = level
# 弓效果
elif ench_id == 13: # 力量
self.player.arrow_damage_multiplier = 1.0 + level * 0.25
def update(self, dt):
super().update(dt)
self.apply_enchantment_effects()
# 附魔效果实现
def apply_sharpness_damage(player, target, damage):
"""应用锋利附魔"""
sharpness_level = player.get_enchantment_level("sharpness")
return damage + sharpness_level * 1.25
def apply_fire_aspect(player, target):
"""应用火焰附加"""
fire_level = player.get_enchantment_level("fire_aspect")
if fire_level > 0:
target.set_on_fire(fire_level * 3) # 3秒/级
def apply_thorns_damage(player, attacker, damage):
"""应用荆棘效果"""
thorns_level = player.get_enchantment_level("thorns")
if thorns_level > 0 and random.random() < thorns_level * 0.15:
attacker.damage(thorns_level * 1.5)
return damage * 0.7 # 同时减少受到的伤害
return damage
def apply_efficiency_effect(player, block_type):
"""应用效率附魔"""
efficiency_level = player.get_enchantment_level("efficiency")
if efficiency_level > 0:
# 根据方块类型调整挖掘速度
base_time = BlockType.get_hardness(block_type)
return base_time / (1 + efficiency_level * 0.3)
return None
# 在玩家类中添加附魔相关属性
class Player:
def __init__(self):
# 原有属性...
self.experience_level = 0
self.experience_points = 0
self.lapis_count = 0
self.equipment = {
"helmet": None,
"chestplate": None,
"leggings": None,
"boots": None,
"mainhand": None,
"offhand": None
}
# 附魔效果临时属性
self.mining_speed_multiplier = 1.0
self.attack_damage_bonus = 0.0
self.fire_aspect_level = 0
self.damage_reduction = 0.0
self.thorns_level = 0
self.arrow_damage_multiplier = 1.0
def get_enchantment_level(self, enchant_name):
"""获取指定附魔等级"""
# 在装备中查找附魔
for item in self.equipment.values():
if item and "enchantments" in item:
for ench_id, level in item["enchantments"].items():
if EnchantmentSystem.ENCHANTMENTS[ench_id]["name"] == enchant_name:
return level
return 0
# 方块类型扩展
class BlockType:
# 原有方块类型...
ENCHANTING_TABLE = 50
BOOKSHELF = 51
# 方块硬度表
HARDNESS = {
# ...原有方块硬度...
ENCHANTING_TABLE: 5.0,
BOOKSHELF: 1.5
}
@staticmethod
def get_hardness(block_type):
return BlockType.HARDNESS.get(block_type, 2.0)
if __name__ == '__main__':
window = EnchantedGameWindow()
pyglet.app.run()
# 放置附魔台方块
world.add_block((x, y, z), BlockType.ENCHANTING_TABLE)
# 放置书架(至少15个效果最佳)
world.add_block((x+2, y, z), BlockType.BOOKSHELF)
# 在世界生成中添加附魔台
def generate_village(self, x, y, z):
# ...房屋生成...
if random.random() < 0.7: # 70%概率生成附魔室
self.add_block((x+2, y+1, z+2), BlockType.ENCHANTING_TABLE)
# 生成书架
for dx, dz in [(0,1),(1,0),(0,-1),(-1,0)]:
self.add_block((x+2+dx, y+1, z+2+dz), BlockType.BOOKSHELF)
# 在攻击计算中加入附魔效果
def calculate_damage(self, attacker, target):
base_damage = 4 # 钻石剑基础伤害
# 应用锋利附魔
sharpness_level = attacker.get_enchantment_level("锋利")
damage = base_damage + sharpness_level * 1.25
# 应用目标保护附魔
protection_level = target.get_enchantment_level("保护")
damage *= 1 - protection_level * 0.04
return damage
# 附魔时的特效
def play_enchantment_effect(self, pos):
for i in range(30):
velocity = (
random.uniform(-0.5, 0.5),
random.uniform(0.5, 1.5),
random.uniform(-0.5, 0.5)
)
self.world.add_particle(
pos[0]+0.5, pos[1]+1.0, pos[2]+0.5,
velocity,
lifespan=1.0,
color=(100, 100, 200), # 魔法蓝紫色
size=0.2
)