关卡编辑器用于游戏关卡界面元素的可视化编辑,包括元素的位置、尺寸以及其它自定义属性。通过解析生成的数据文件即可获取关卡信息,并能随时调整,以减少开发工作量,提高开发效率。
主界面
图01_主界面
1) 画布
① 简介
画布用于关卡元素的预览,并提供元素选择和坐标设置等功能;画布的尺寸与其正在显示的关卡的尺寸相同
图02_画布
② 选择元素
a. 单选:鼠标左键单击即可选中单个元素,选中后的元素周围出现蓝色的方框,未选中的则为灰色虚线框
b. 多选:按住Ctrl键不放,再依次点击要多选的元素即可多选
c. 取消选择:点击画布的任意空白区域即可取消选中
③ 移动元素
选中要移动的元素,用鼠标拖拽或者借助键盘的方向按键均可移动所选元素,也可以通过在属性列表中直接输入元素的坐标来移动元素
2) 菜单栏
① 简介
菜单栏是编辑器常用操作的集合,包括“文件”和“帮助”菜单两大类。
图03_菜单栏
② 文件菜单
a. 新建项目
用于打开“新建项目”窗口,在该窗口中输入新项目名称后点击确定按钮即可创建一个新项目
图04_新建项目
注意:新项目名称不能与已有项目的名称重复
b. 打开项目
用于打开已有项目。
点击菜单按钮,在弹出窗口中选择要打开的项目配置文件(xml格式的)即可打开项目
图05_打开项目
c. 保存项目
用于保存对项目的修改
d. 导出项目
用于导出项目所生成的关卡数据文件。
点击菜单,在弹出窗口中选择要导出的目标文件夹,再点击确定后将在指定目录下 生成关卡数据文件
图06_导出项目
③ 帮助菜单
打开帮助
3) 快捷工具栏
① 简介
快捷工具栏是常用功能按钮的集合
图07_快捷工具栏
② 项目相关按钮
用于新建、打开和保存项目
③ 对齐按钮组
用于对齐界面元素,仅当画布中已选中了多个元素时有效;对齐时,以多选时第一个选中的元素为标准
a. 顶端对齐
将所有选中元素的纵坐标设为第一个选中的元素的纵坐标
b. 底端对齐
将所有选中元素的底端与第一个选中的元素的底端对齐
c. 左对齐
将所有选中元素的横坐标设为第一个选中的元素的横坐标
d. 右对齐
将所有选中元素的右端与第一个选中的元素的右侧对齐
e. 横向居中对齐
将所有选中元素的中心点的纵坐标设为第一个选中的元素的中心点的纵坐标
f. 纵向居中对齐
将所有选中元素的中心点的横坐标设为第一个选中的元素的中心点的横坐标
g. 中心对齐
将所有选中元素的中心点的坐标设为第一个选中的元素的中心点的坐标
④ 布局按钮组
用于快速设置界面元素的位置,只对单个元素有效
a. 置顶
将选中元素的纵坐标设为0
b. 置底
将选中元素的底端与画布的底端对齐
c. 左置
将选中元素的横坐标设为0
d. 右置
将选中元素的右端与画布右端对齐
e. 横向居中
将选中元素的中心点的纵坐标设置为画布中心点的纵坐标
f. 纵向居中
将选中元素的中心点的横坐标设置为画布中心点的横坐标
g. 居中
将选中元素的中心点的坐标设置为画布中心点的坐标
⑤ 删除按钮
用于删除画布中选中的元素,支持多选
4) 元素列表
① 简介
元素列表区域显示精灵列表和关卡元素列表
② 精灵列表
精灵列表显示项目的所有精灵,选中某个精灵后,“属性列表”和“自定义属性列表”
将显示该精灵的属性信息
图08_精灵列表
a. 精灵简介
精灵指关卡编辑器中可以在关卡内或者关卡间复用的界面元素,将精灵添加到关卡后,关卡中将生成一个与精灵的各项属性相同的关卡元素
b. 添加精灵按钮
点击后添加一个新的精灵
c. 删除精灵按钮
点击后删除选中的精灵
d. 将精灵添加到关卡中
选择要添加的精灵,将其用鼠标拖拽到画布中即可将该精灵添加到当前的关卡中
5) 关卡列表
关卡列表显示项目中的所有关卡及关卡的元素列表,是一个树形结构
图09_关卡列表
① 关卡
树形结构的第一层显示项目中的关卡列表,选中某个关卡后,“属性列表”和“自定义属性列表”将显示其相关属性,画布将切换到该关卡的布局
② 元素
树形结构的第二层显示关卡的元素列表,选中某个元素后,“属性列表”和“自定义属性列表”将显示其相关属性,画布将切换到该元素所属关卡的布局,并框选该元素对应的画布元素
③ 添加关卡按钮
点击后添加一个新的关卡
④ 删除关卡按钮
点击后删除选中的关卡
6) 属性列表
① 简介
属性列表区域用于显示和修改精灵、关卡及关卡元素的基本信息(如果“元素列表”区域中选中的选项卡为“精灵列表”,则显示当前选中的精灵信息,反之则显示关卡或者关卡元素信息),包括坐标和尺寸等
图10_属性列表
② 名称
用于显示和修改当前对象的名称(注:名称仅用于方便编辑器的显示,在引擎中无意义)
③ 位置
用于显示和修改当前对象的坐标,仅当显示对象为关卡元素时有效
④ 尺寸
用于显示和修改当前对象的宽和高,如果修改了关卡的尺寸,画布将同步更新
⑤ 类型
用于显示和修改当前对象的类型值,仅当显示对象为精灵和关卡元素时有效
⑥ 图片
用于设置该元素的背景图片(仅用于方便编辑器的显示,在引擎中无意义),仅当显示对象为精灵或者关卡元素时有效,点击右侧的按钮可以导入图片资源
7) 自定义属性列表
① 简介
自定义属性列表区域用于显示和修改精灵、关卡及关卡元素的扩展信息(如果“元素列表”区域中选中的选项卡为“精灵列表”,则显示当前选中的精灵信息,反之则显示关卡或者关卡元素信息)
图11_自定义属性
② 修改自定义属性
用鼠标选中要修改的单元格,再单击单元格或按下F2即可修改自定义属性的名称或者值
③ 添加自定义属性
在标有“*”的行(一般为列表的最后一行)中依次输入属性名称和值即可添加一个自定义属性
④ 删除自定义属性
选则要删除的属性所在的行,按Delete键即可删除
注意:自定义属性的名称不能重复,如果输入了重复的名称,将会被自动设置为一个不重复的默认值Property_N
1. 新建项目
1) 点击文件菜单,选择新建项目
2) 在弹出的对话框中输入项目名称,点击确定
2. 创建精灵
1) 选中程序右上角的“精灵列表”选项卡
2) 点击“添加精灵”按钮,将创建一个新的精灵,如图12
图12_示例_创建精灵
3) 依次修改精灵的名称、尺寸和类型
4) 设置精灵的图片,如果列表中没有需要的图片,可以通过点击右侧的“+”按钮来导入
5) 重复上述步骤,创建需要的精灵
3. 创建关卡
1) 选中程序右上角的“关卡列表”选项卡
2) 点击“添加关卡”按钮,将创建一个新的关卡,如图13
图13_示例_添加关卡
3) 依次设置关卡的名称和尺寸
4. 添加关卡元素
1) 选中“精灵列表”
2) 选中需要的精灵,将其拖拽到“画布”中,如图14
图14_示例_添加元素
3) 重复上述步骤,添加需要的关卡元素
5. 修改元素属性
1) 选中“关卡列表”选项卡
2) 展开指定的关卡,选中指定元素(也可以用鼠标左键单击画布中的图片来选中指定的关卡元素)如图15
图15_示例_选择元素
3) 设置自定义属性
① 选中“自定义属性”列表中,最左标识有“*”的行
② 选中“名称”单元格,再用鼠标左键单击一次该单元格
③ 输入新的名称
④ 选中“值”单元格,再用鼠标左键单击一次该单元格
⑤ 输入新的值
⑥ 重复上述步骤
1. 导出为数据文件
在关卡编辑器中将关卡导出,生成相应的xml数据文件,然后将数据文件拷贝到项目的合适位置
2. 加载关卡数据文件并使用
注:关卡加载器已集成到引擎中,所在包名:com.orange.util.level
//自定义属性的名称
public static final String TAG_ENTITY_ATTRIBUTE_TYPE_VALUE_BOX = "box";
public static final String TAG_ENTITY_ATTRIBUTE_TYPE_VALUE_CIRCLE = "circle";
public static final String TAG_ENTITY_ATTRIBUTE_TYPE_VALUE_TRIANGLE = "triangle";
public static final String TAG_ENTITY_ATTRIBUTE_TYPE_VALUE_HEXAGON = "hexagon";
@Override
public void onSceneCreate(SceneBundle bundle) {
// TODO Auto-generated method stub
super.onSceneCreate(bundle);
final String FACE_BOX = "face_box.png";
RegionRes.loadBitmapTextureFromAssets(FACE_BOX);
//关卡的容器
final EntityGroup entityGroup = new EntityGroup(this);
this.attachChild(entityGroup);
//初始化关卡加载器对象
final LevelLoader levelLoader = new LevelLoader();
//关卡元素的容器
levelLoader.registerEntityLoader(LevelConstants.TAG_LEVEL, new IEntityLoader() {
@Override
public IEntity onLoadEntity(final String pEntityName, final Attributes pAttributes) {
final int width = SAXUtils.getIntAttributeOrThrow(pAttributes, LevelConstants.TAG_LEVEL_ATTRIBUTE_WIDTH);
final int height = SAXUtils.getIntAttributeOrThrow(pAttributes, LevelConstants.TAG_LEVEL_ATTRIBUTE_HEIGHT);
entityGroup.setWidth(width);
entityGroup.setHeight(height);
return entityGroup;
}
});
//关卡元素
levelLoader.registerEntityLoader(LevelConstants.TAG_ENTITY, new IEntityLoader() {
@Override
public IEntity onLoadEntity(final String pEntityName, final Attributes pAttributes) {
final int x = SAXUtils.getIntAttributeOrThrow(pAttributes, LevelConstants.TAG_ENTITY_ATTRIBUTE_X);
final int y = SAXUtils.getIntAttributeOrThrow(pAttributes, LevelConstants.TAG_ENTITY_ATTRIBUTE_Y);
final int width = SAXUtils.getIntAttributeOrThrow(pAttributes, LevelConstants.TAG_ENTITY_ATTRIBUTE_WIDTH);
final int height = SAXUtils.getIntAttributeOrThrow(pAttributes, LevelConstants.TAG_ENTITY_ATTRIBUTE_HEIGHT);
final String type = SAXUtils.getAttributeOrThrow(pAttributes, LevelConstants.TAG_ENTITY_ATTRIBUTE_TYPE);
Debug.d("x=" + x);
Debug.d("y=" + y);
final VertexBufferObjectManager vertexBufferObjectManager = LevelScene.this.getVertexBufferObjectManager();
final AnimatedSprite face;
if(type.equals(TAG_ENTITY_ATTRIBUTE_TYPE_VALUE_BOX)) {
face = new AnimatedSprite(x, y, FACE_BOX, vertexBufferObjectManager);
} else if(type.equals(TAG_ENTITY_ATTRIBUTE_TYPE_VALUE_CIRCLE)) {
face = new AnimatedSprite(x, y, FACE_BOX, vertexBufferObjectManager);
} else if(type.equals(TAG_ENTITY_ATTRIBUTE_TYPE_VALUE_TRIANGLE)) {
face = new AnimatedSprite(x, y, FACE_BOX, vertexBufferObjectManager);
} else if(type.equals(TAG_ENTITY_ATTRIBUTE_TYPE_VALUE_HEXAGON)) {
face = new AnimatedSprite(x, y, FACE_BOX, vertexBufferObjectManager);
} else {
throw new IllegalArgumentException();
}
face.animate(200);
return face;
}
});
try {
//开始加载
levelLoader.loadLevelFromAsset("Level_1.lvl");
} catch (final IOException e) {
Debug.e(e);
}
}