Marauroa Core API
Marauroa公开了精简后的非常简单的API,因此您可以轻松地开发自己的游戏. A nightly build JavaDoc API Documentation is available, too.
内容[编辑]
您应该了解的主要实体:
- Attributes
- RPAction
- RPObject
- RPSlot
- RPClass
- IRPZone interface
- IRPRuleProcessor interface
- RPWorld
要了解这些元素,请参阅 RolePlayingDesign 和 GameDesign.
或者,如果您希望使用Python来开发游戏规则,请参阅:
- PythonRP
- PythonWorld
The Python API can be found at PyArianneAPIDefinition and an example of its use at PyArianneAPIExample. 您可以在我们的游戏教程中阅读有关使用Python进行开发的更多信息。 HowToWriteGamesUsingArianne. Please note that Python support is dormant.
Attributes[编辑]
属性是存储在列表中的数据对. 每个属性由 name 和 value 元素组成. 属性是在Arianne中存储数据的标准方式. 一个属性的例子是您的年龄, 即 name="age" 和 value=21
每个属性还具有与之关联的类型,在 RPClass 中定义. 属性是 RPClass 的实例(关于 RPClass 的更多内容请参阅下节).
属性中有两个特殊条目:
- type: 定义对象所属的RPClass的名称.
- id: 定义一个唯一的标识符
Attributes类向游戏开发人员公开的方法如下所示。 可以用来修改属性的功能.
设置属性的值:
public void put(String name, String value)
public void put(String name, int value)
向已经存在的属性的值元素添加数量:
public void add(String name, int quantity)
返回属性的值:
public String get(String name)
public int get(String name)
从属性列表中删除属性条目:
public void remove(String name)
如果属性存在则返回True:
public boolean has(String name)
例子:
Attributes test=new Attributes();
test.put("name","Test attribute");
test.put("hp",100);
if(test.has("hp")) {
test.add("hp",10);
}
test.remove("name");
RPClass[编辑]
此类是Arianne的关键概念。 RPClass非常类似于Java类,但是对于Arianne RPObjects来说:RPClass定义了组成对象(对象是属性的集合,例如对于人类而言,年龄、身高等属性)的属性的类型(字符串、整数、布尔值...)和可见性(隐藏,私有或可见)。
RPClass 由5个不同部分组成:
数据类型定义:
- String: 字符串,最多 2^32 字节
- Short String: 字符串,最多 255 字节
- Integer: 32 位整数
- Short: 16 位整数
- Byte: 8 位整数
- Flag: 二进制标志.
数据的可见性:
- Visible: 属性对客户端可见.
- Hidden: 属性对客户端不可见.
- Private: 该属性仅对与之关联的客户端可见(如客户端控制的玩家对象)
RPClass的创建方法: (这些是每个RPClass实例的一部分,有关用法,请参见下面的示例)
public void add(String name, byte type)
public void add(String name, byte type, byte visibility)
public void isA(String parent)
public void isA(RPClass parent)
这些方法将属性添加到RPClass并设置其类型和可见性。 您也可以设置此类的父类。 当然也可以没有父类.
填充完类后,您可以使用这些方法查询数据。 这些方法使您可以获取类的类名称,属性的类型,确定属性是否存在以及知道RPClass是否为另一个的子类.
查询:
public String getName()
public byte getType(String name)
public byte getVisibility(String name)
public boolean hasAttribute(String name)
public boolean subclassOf(String parentclass)
您可以使用以下方法查询系统类. 注意在运行时修改类 不是 一个好主意. 类定义在连接时发送到客户端,因此,如果您在游戏过程中更改类定义,则会使客户端崩溃!
Class wide query:
boolean hasRPClass(String name)
RPClass getRPClass(String name)
当编写类定义时您可以跳过 id 和 type 属性,它们由 RPClass 自动定义.
例子:
// 一个带位置信息的实体
RPClass objclass = new RPClass("entity");
objclass.add("x", RPClass.BYTE);
objclass.add("y", RPClass.BYTE);
// 一个玩家实体
objclass = RPClass("player");
objclass.isA("entity");
objclass.add("name", RPClass.SHORT_STRING);
objclass.add("direction", RPClass.SHORT_STRING);
objclass.add("score", RPClass.INT);
objclass.add("super", RPClass.BYTE);
objclass.add("!vdir", RPClass.STRING,RPClass.HIDDEN);
objclass.add("!hdir", RPClass.STRING,RPClass.HIDDEN);
objclass.add("?kill", RPClass.FLAG);
每次您创建一个新的RPClass时,只要您给它命名(例如:entity,player,...),它将被添加到系统的类列表中.
注意,在示例中,如果您希望RPClass具有此属性,则必须指定hidden属性,否则默认情况下,该属性可见.
注意:您可以选择在应用程序中不使用RPClass,但是这会增加网络带宽的使用率.
RPAction[编辑]
RPAction是一个对象,用于表示玩家想要执行的动作. 在设计游戏时,由您自己决定,因为它们是针对每个游戏的(您还应该为它们定义RPClass).
RPObject 和 RPSlot[编辑]
RPObject是Arianne中数据的容器。 一个RPObject是附加了RPSlot列表的Attributes元素.
RPSlot是RPObject拥有的插槽,可以在其中放置其他RPObject(例如背包中的物品)
RPObject修改插槽的方法是:
public void addSlot(RPSlot slot)
public RPSlot getSlot(String name)
public void removeSlot(String name)
public boolean hasSlot(String name)
public Iterator slotIterator()
以上方法用于将插槽添加到对象,对其进行检索,将其删除并测试该插槽是否存在。 最后,插槽迭代器用于访问对象中的所有插槽.
public RPObject.ID getID()
这是获取对象唯一ID的辅助方法.
RPSlot的简单API:
public void add(RPObject object)
public RPObject get(RPObject.ID id)
public boolean has(RPObject.ID id)
public RPObject remove(RPObject.ID id)
public void clear()
这些方法修改RPSlot中的对象。 clear()方法删除插槽中的所有对象.
public Iterator iterator()
用于访问该插槽的所有对象.
// 创建一个玩家RPClass的对象并设置一些属性值
RPObject object = new RPObject("player");
object.put("name", "example");
object.put("score", 0);
// 创建一个名为背包的插槽
RPSlot slot = new RPSlot("backpack");
object.addSlot(slot);
// 创建一个钱币RPClass的对象并且放入插槽
RPObject coin = new RPObject("coin");
slot.add(coin);
现在来看最复杂的部分。 稍微有点疯狂!: IRPZone 和 IRPRuleProcessor 接口
RPWorld[编辑]
此类只是区域Zone的容器.
RPWorld 提供了几种方法来简化RPZone的处理.
在服务器启动和完成时调用onInit和onFinish。 您需要将RPWorld子类化以使其具有适当的行为.
public void onInit() throws Exception
public void onFinish() throws Exception
一些添加区域并对其进行迭代的辅助方法.
public void addRPZone(IRPZone zone)
public IRPZone getRPZone(IRPZone.ID zoneid)
public IRPZone getRPZone(RPObject.ID objectid)
public Iterator<IRPZone> iterator()
public int size()
添加,获取,测试存在,删除和修改对象的方法。 modify() 采用delta ^ 2算法.
public void add(RPObject object) throws NoRPZoneException, RPObjectInvalidException
public RPObject get(RPObject.ID id) throws NoRPZoneException, RPObjectInvalidException
public boolean has(RPObject.ID id) throws NoRPZoneException, RPObjectInvalidException
public RPObject remove(RPObject.ID id) throws NoRPZoneException, RPObjectNotFoundException
public void modify(RPObject object) throws NoRPZoneException
这些是用于更改对象区域的辅助方法。 用它们代替手工操作.
public void changeZone(IRPZone.ID oldzoneid, IRPZone.ID newzoneid, RPObject object) throws NoRPZoneException
public void changeZone(String oldzone, String newzone, RPObject object) throws NoRPZoneException
IRPZone[编辑]
IRPZone是处理世界内容和感知的接口。 在大多数情况下,您应该使用实现MarauroaRPZone并将其扩展.
这些方法是:
/** This method is called when the zone is created to populate it */
public void onInit() throws Exception;
/** This method is called when the server finish to save the content of the zone */
public void onFinish() throws Exception;
/** This method adds an object to the Zone */
public void add(RPObject object) throws RPObjectInvalidException;
/** This method tag an object of the Zone as modified */
public void modify(RPObject object) throws RPObjectInvalidException;
/** This method removed an object of the Zone and return it.*/
public RPObject remove(RPObject.ID id) throws RPObjectNotFoundException;
/** This method returns an object of the Zone */
public RPObject get(RPObject.ID id) throws RPObjectNotFoundException;
/** This method returns true if the object exists in the Zone */
public boolean has(RPObject.ID id);
/** This method create a new RPObject with a valid id */
public RPObject create();
/** Iterates over the elements of the zone */
public Iterator iterator();
/** Returns the number of elements of the zone */
public long size();
/** This method return the perception of a zone for a player */
public Perception getPerception(RPObject.ID id, byte type);
/** This method is called to take zone to the next turn */
public void nextTurn();
/** Method to create the map to send to player's client */
public java.util.List buildMapObjectsList(RPObject.ID id);
在大多数情况下,您希望修改的只是:
- onInit
- onFinish
- buildMapObjectsList
IRPRuleProcessor[编辑]
此类必须完全实现,但与IRPZone :)相比,它是一个儿童玩具。 这是您编写所有游戏规则的地方.
API如下:
/** Set the context where the actions are executed.
* @param zone The zone where actions happens. */
public void setContext(IRPZone zone);
/** Pass the whole list of actions so that it can approve or deny the actions in it.
* @param id the id of the object owner of the actions.
* @param actionList the list of actions that the player wants to execute. */
public void approvedActions(RPObject.ID id, RPActionList actionList);
/** Execute an action in the name of a player.
* @param id the id of the object owner of the actions.
* @param action the action to execute
* @return the action status, that can be Success, Fail or incomplete, please
* refer to Actions Explained for more info. */
public RPAction.Status execute(RPObject.ID id, RPAction action);
/** Notify it when a new turn happens */
public void nextTurn();
/** Callback method called when a new player enters in the game
* @param object the new player that enters in the game. */
public boolean onInit(RPObject object) throws RPObjectInvalidException;
/** Callback method called when a new player exits the game
* @param id the new player id that exits the game.
* @return true to update the player on database. */
public boolean onExit(RPObject.ID id) throws RPObjectNotFoundException;
/** Callback method called when a new player time out
* @param id the new player id that timeouts. */
public boolean onTimeout(RPObject.ID id) throws RPObjectNotFoundException;