跳到主要内容

2. 注册第一张地图

上一章建立了模组入口。本章添加一个空的 EliminationMap,让 FPSMatch 能根据它创建地图实例。

游戏类型与地图实例

假设服务器有 trainingcourtyard 两个竞技场,它们都使用 elimination 规则。你只需要注册一次游戏类型;每次创建竞技场时,框架都会调用工厂,生成不同的 EliminationMap 对象。

EliminationMap 中的普通字段属于那张地图。把比分写成静态字段,会让两个竞技场共享同一份比分。

地图实例还会跨越多场比赛:一场结束后,重置对象中的比赛状态即可继续使用原来的地图区域和配置。地图并不等同于只存在一次的一场比赛。

定义地图类

创建 EliminationMap.java

EliminationMap.java
package com.example.elimination;

import net.ptcrys.fpsmatch.core.data.AreaData;
import net.ptcrys.fpsmatch.core.map.BaseMap;
import net.minecraft.server.level.ServerLevel;

public final class EliminationMap extends BaseMap {
public static final String GAME_TYPE = "elimination";

public EliminationMap(ServerLevel level, String name, AreaData area) {
super(level, name, area);
}

@Override
public String getGameType() { return GAME_TYPE; }

@Override
public boolean victoryGoal() { return false; }
}

ServerLevel 是实例所在的服务端世界,name 是地图 ID,AreaData 保存地图区域。工厂创建对象时,框架会提供这三个参数。

getGameType() 将实例关联回游戏类型。victoryGoal() 是整局胜利条件,此时返回 false,因为我们还没有参赛玩家和胜负规则。

注册工厂

创建 EliminationEvents.java

EliminationEvents.java
package com.example.elimination;

import net.ptcrys.fpsmatch.common.event.register.RegisterFPSMapEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;

@Mod.EventBusSubscriber(modid = EliminationMod.MODID, bus = Mod.EventBusSubscriber.Bus.FORGE)
public final class EliminationEvents {
@SubscribeEvent
public static void registerMaps(RegisterFPSMapEvent event) {
event.registerGameType(EliminationMap.GAME_TYPE, EliminationMap::new);
}
}

RegisterFPSMapEvent 发布在 Forge 事件总线上,因此订阅 Bus.FORGEEliminationMap::new 只是工厂引用;注册时并不会立即创建竞技场。

不要在这里手动构造某张固定地图。地图持久化加载与管理员创建流程都会使用这份工厂注册。

创建地图实例

为竞技场选择一个区域,然后使用已有的地图命令:

/fpsm map create elimination training 0 64 0 32 80 32

这条命令将区域与 training 绑定。它不会替你生成地板或建筑,应选取已有的场地。地图 ID 使用小写字母、数字、下划线或连字符,长度为 1–48。

目前这张地图只有区域和类型。下一章将添加可加入的队伍与出生位置。

本章完整源码 · 上一章:接入项目 · 下一章:队伍与出生