Welcome

首页 / 软件开发 / Silverlight / Silverlight游戏设计:(六)场景编辑器之开源畅想

Silverlight游戏设计:(六)场景编辑器之开源畅想2011-08-12 博客园 深蓝色右手所有的游戏设计辅助工具都是为了提高游戏开发效率而出现的,Silverlight-2D游戏场景编辑器 (QXSceneEditor)同样也不例外,虽然它不比《魔兽》、《星际》、《帝国》等大作的地图编辑器拥有强 大到甚至可以通过“换肤”直接创造出一款新游戏;但是大家可以通过它,配合上前几节讲述的游戏架设 方式几乎能搭建任意一款2D游戏图形框架。无论是RPG(角色扮演)、SLG(策略)、RTS(即时战略)还是ACT( 动作)、STG(射击)、CAG(卡片游戏)等游戏类型,不论精灵是2方向(如:《地下城与勇士》、《三国群英 传》) 4方向(如:《漂流幻境》)还是8方向(如:《破天一剑》)甚至16方向(如:《剑侠世界》中的魔 法),不论场景是横向、纵向、主视角、牵引模式,倾斜的还是垂直的,不论游戏空间是2层的(如:《梦 幻诸仙》),3层的(如:《奇迹》)还是N层的(如:《英雄无敌》、《铁血联盟》)等等,只要是2D的均可 用作场景的布局或架设。

场景编辑器是如何做到如此的高度通用而神乎其神的?在第二节中,我已较详细的讲解了它的核心功 能:动态坐标系系统。通过动态修改场景以及它内部的地图、坐标系等对象的某些参数即可实现场景的任 意倾斜度、单元格尺寸、参照系、2D位置,3D旋转以及主角在位置显示及移动方面的多模式。至于其中的 核心代码我一再强调其实不过就两个,是否与第一部第十节的公式吻合大家可自行比对,事实证明它们是 正确的,因此也请特别关注它的朋友们放一万个心:

/// <summary>
/// 将窗口坐标系中的坐标换算成游戏坐标系中的坐标
/// </summary>
public Point GetGameCoordinate(double angle, Point p, uint gridSize) {
if (angle == 0) {
return new Point((int)(p.X / gridSize), (int)(p.Y / gridSize));
} else {
double radian = GetRadian(angle);
return new Point(
(int)((p.Y / (2 * Math.Cos(radian)) + p.X / (2 * Math.Sin(radian))) / gridSize),
(int)((p.Y / (2 * Math.Cos(radian)) - p.X / (2 * Math.Sin(radian))) / gridSize)
);
}
}

/// <summary>
/// 将游戏坐标系中的坐标换算成窗口坐标系中的坐标
/// </summary>
public Point GetWindowCoordinate(double angle, Point p, uint gridSize) {
if (angle == 0) {
return new Point(p.X * gridSize, p.Y * gridSize);
} else {
double radian = GetRadian(angle);
return new Point(
(p.X - p.Y) * Math.Sin(radian) * gridSize,
(p.X + p.Y) * Math.Cos(radian) * gridSize
);
}
}

再回到功能上,仅有以上这些还是不够的;作为一个场景编辑器,更重要的是作为后续章节中我将为 大家展示更多Demo的基础框架,它还需要拥有更好更强大的功能。

作为场景的编辑器,光能实现坐标系的变化只能算完成了一半,如能加上任意地图的导入才能算得上 动态搭建:

//加载地图
button.Click += (s, e) => {
OpenFileDialog openFileDialog = new OpenFileDialog ();
openFileDialog.Multiselect = false;
openFileDialog.Filter = "图象文件(*.jpg *.png) |*.jpg;*.png";
try {
bool result = (bool)openFileDialog.ShowDialog ();
if (!result) {
return;
} else {
FileInfo fileInfo = openFileDialog.File;
Stream stream = fileInfo.OpenRead ();
BitmapImage bitmapImage = new BitmapImage();
bitmapImage.SetSource(stream);
if (bitmapImage.PixelWidth < this.Width || bitmapImage.PixelHeight < this.Height) {
MessageBox.Show(string.Format("地 图载入失败!图片规格小于窗口尺寸:{0} * {1}", this.Width, this.Height));
} else {
scene.MapSource = bitmapImage;
mapDetailsOutPut.Text = string.Format("宽:{0}px 高:{1}px", scene.MapWidth = bitmapImage.PixelWidth, scene.MapHeight = bitmapImage.PixelHeight);
}
stream.Close();
}
} catch {
MessageBox.Show("地图载入失败!请检查该图片格式是 否正确");
}
};