战棋游戏通常指以回合制为基础,角色在地图上按格移动作战的游戏,好比下棋一样,该类型游戏更侧重于策略,节奏较缓慢,注重精美、绚丽的画面,考验的是玩家运筹全局的智慧。耳熟能详的比如《梦幻模拟战》、《火焰纹章》、《大战略》、《炎龙骑士团》、《幻世录》等经典。

战棋游戏占据了我太多记忆,每次看到类似的游戏都会激动不已,尤其是远距离攻击类型的弓箭手和魔法师,战局扭转往往就在一步之间。

今天,作为一名游戏开发者,当技术与思想逐步成熟,理想似乎已不再是那么的遥不可及。以SLG战棋游戏战斗范围为例,我们可以巧妙的通过集合运算来实现几乎所有你能想到的角色战斗范围设定。

动手前我们不妨先看一下《曹操传》中所有的战斗范围图例:

见到此类素材大家会否觉得实在亲切。没错,就是我们小时候读书最常玩的找规律数学题。

既然要找出规律,那么就得先分析出其中的共性与变化。最直接的共性便是所有的格子均是“对称”的;而发生变化的则是某些图例似乎都被“挖”去了一些;再往下想,这些被“挖”掉的格子同样也是“对称”的。由此,基于集合的差集运算第一时间浮现在脑海。

规律把握的是否正确离不开证明过程,接下来我们随便以上图中任意几个图例为例加以验证:

……

是不是开始有些激动了?

最后的总结:所有“对称”的战斗范围都可以是基于某种规律N格长度的范围与基于另一种规律M格长度范围的差集,其中这两种规律可以相同,N与M也可以相同。由此便可衍生出如文中开头所有的战斗范围,以及更多未列出来的。

有了以上强大的理论依据作为基础,接下来的编码便是手到擒来,我的思路大致如下。

第一步,定义最常用的基本规律(即连续的战斗范围类型):

/// <summary>
    /// 战斗范围类型
    /// </summary>
    public enum AttackRangeTypes {
        /// <summary>
        /// 无
        /// </summary>
        None = 0,
        /// <summary>
        /// 全八面(方形)
        /// </summary>
        Square = 1,
        /// <summary>
        /// 斜四面(菱形)
        /// </summary>
        Diamond = 2,
        /// <summary>
        /// 正四向(十字)
        /// </summary>
        Cross = 3,
        /// <summary>
        /// 斜四向(交叉)
        /// </summary>
        Oblique = 4,
    }

除None外,它们2长度范围分别对应以下图例:

第二步,以这些战斗范围(List<Point>)为返回值构造方法:

List<Point> GetRange(Point center, AttackRangeTypes attackRangeType, int range) {
            List<Point> points = new List<Point>();
            for (int x = -range; x <= range; x++) {
                for (int y = -range; y <= range; y++) {
                    switch (attackRangeType) {
                        case AttackRangeTypes.None:
                            continue;
                        case AttackRangeTypes.Square:
                            break;
                        case AttackRangeTypes.Diamond:
                            if (Math.Abs(x) + Math.Abs(y) > range) { continue; }
                            break;
                        case AttackRangeTypes.Cross:
                            if (Math.Abs(x) != 0 && Math.Abs(y) != 0) { continue; }
                            break;
                        case AttackRangeTypes.Oblique:
                            if (Math.Abs(x) != Math.Abs(y)) { continue; }
                            break;
                    }
                    points.Add(new Point(center.X + x, center.Y + y));
                }
            }
            return points;
        }

/// <summary>
        /// 获取攻击范围坐标列表
        /// </summary>
        /// <param name="rangeType">范围类型</param>
        /// <param name="range">范围</param>
        /// <param name="exclusionRangeType">排除范围类型</param>
        /// <param name="exclusionRange">排除范围</param>
        /// <returns></returns>
        public List<Point> AttackRange(AttackRangeTypes rangeType, int range, AttackRangeTypes exclusionRangeType, int exclusionRange) {
            List<Point> points = GetRange(Coordinate, rangeType, range);
            List<Point> excludePoints = GetRange(Coordinate, exclusionRangeType, exclusionRange);
            return points.Except(excludePoints).ToList();
        }

第三步,游戏中,将玩家控制的角色坐标Coordinate作为以上方法的Center参数,通过前文提到的组合方式最终完成SLG战棋角色战斗范围动态设定:

……

这是一款基于Silverlight的SLG游戏引擎的一部分,在线演示Demo 如下(点击下载该Demo源码):

通过动态组合差集的方式设定SLG战棋角色的攻击范围,无论是灵活性、适用性还是拓展性都显得极其强大。当然,每个人的思维方式不一样,写出的算法也会大相径庭,游戏开发的乐趣就在于此:优化永无止尽。

手记思考:当问题出现时若能正确的把握其本质规律,一切都将显得那么的简单。

Silverlight.XNA(C#)跨平台3D游戏研发手记:(一)差集运算在SLG战斗范围设定中的应用相关推荐

  1. Silverlight.XNA(C#)跨平台3D游戏研发手记:(八)向Windows Phone移植之2D跨平台迁移

    Silverlight 5集成了XNA,Windows Phone 7.1同样也拥有SL.XNA模式,基于Mono的开源产品Moonlight更能实现多平台部署:可见,Silverlight离跨平台的 ...

  2. Silverlight.XNA(C#)跨平台3D游戏研发手记:(十)3D 场景与控制设计①

    模型和骨骼动画仅仅是开启3D游戏的敲门砖,置入基于摄像机的场景设计方能呈现最完美的3D游戏.本节,我们依旧从简单着手,一步步创建基于模型的3D游戏场景. <XNA4.0学习指南(中文)>是 ...

  3. Silverlight.XNA(C#)跨平台3D游戏研发手记:(七)向Windows Phone移植之双向交互

    继完成游戏主体框架搭建后,接下来我将通过SL.XNA模式中Silverlight控件与XNA对象之间双向交互操作的例子,向大家进一步讲解框架的拓展使用及简单的承载演示.在此之前大家需要理解Window ...

  4. Silverlight.XNA(C#)跨平台3D游戏研发手记:(十一)3D SLG(策略战棋游戏)设计案例

    某天,当你一不小心发现已经够随心所欲的驾驭3D摄像机之时,任何类型的3D游戏都将成为囊中玩物,过往如烟. 回忆逝去的童年让我极度惦记的SLG策略战棋游戏,或许对于大多数玩家来说,它费时费力不被讨好:然 ...

  5. Silverlight.XNA(C#)跨平台3D游戏研发手记:(一)差集运算在SLG战斗范围设定中的应用...

    战棋游戏通常指以回合制为基础,角色在地图上按格移动作战的游戏,好比下棋一样,该类型游戏更侧重于策略,节奏较缓慢,注重精美.绚丽的画面,考验的是玩家运筹全局的智慧.耳熟能详的比如<梦幻模拟战> ...

  6. Silverlight.XNA(C#)跨平台3D游戏研发手记:(五)SLG动感增效之《幻影粒子》

    随着电子技术发展与普及,人们使用电脑时间越来越长,由于人类自身身体比如眩晕症.眼球衰老等客观因素存在,未来玩家会更加倾向于低视疲劳度/低神经刺激的绿色健康休闲2D游戏而非3D.<希魔复活> ...

  7. Silverlight游戏研发手记:(一)差集运算在SLG战斗范围设定中的应用

    战棋游戏通常指以回合制为基础,角色在地图上按格移动作战的游戏,好比下棋一样,该类型游戏更侧重于策略,节奏较缓慢,注重精美.绚丽的画面,考验的是玩家运筹全局的智慧.耳熟能详的比如<梦幻模拟战> ...

  8. Unity3D ——强大的跨平台3D游戏开发工具教程

    http://unity3d.9ria.com/?p=22 众所周知,Unity3D是一个能够实现轻松创作的多平台的游戏开发工具,是一个全面整合的专业游戏引擎.在现有的版本中,其强大的游戏制作功能已经 ...

  9. 【Unity 3D 学习】 《Unity 3D 游戏开发》(第二版 宣雨凇著) 书中一些名字注解

    前言 在学习<Unity 3D 游戏开发>这本书的过程中碰到了一些术语,比如序列化.反序列化.反射等,这些基本都是常见的程序员行话,但是感觉自己对这些术语总是一知半解,为了让自己更清楚地知 ...

最新文章

  1. android线程及线程池
  2. 区块链最积极的布局者:国内5大银行已将“区块链”应用到5大场景当中
  3. asp.net c#截取指定字符串函数
  4. BZOJ 1738: [Usaco2005 mar]Ombrophobic Bovines 发抖的牛( floyd + 二分答案 + 最大流 )
  5. 【Linux系统编程】特殊进程之僵尸进程
  6. C语言log日志管理-支持文件与终端输出
  7. PERCONA-TOOLKIT 安装
  8. SharePoint 2007:该表单无法显示,因为会话状态不可用。
  9. MongoDB Hot Backup 测试及痛点
  10. SQL中,like的SQL注入防止,使用预编译SQL(?)的写法
  11. 第004讲 浮动窗口 表单及表单控件
  12. 老版本iOS simulator链接
  13. 云计算的工作原理是什么?
  14. Ubuntu虚拟机安装
  15. hr标签html样式,hr标签样式修改及美化(css的hr标签实现精美线条)
  16. Java实现MD5和国密SM3摘要算法
  17. 淘宝店铺宝贝批量复制工具
  18. 安装anaconda时需要卸载python么_怎么卸载python 安装 anaconda
  19. 常用IP地址端口对照表
  20. CCleaner注册码

热门文章

  1. MacBook Air和MacBook Pro到底选哪款?
  2. 电脑术语科普:什么是“显卡交火”?
  3. RHCE(十三)用postfix搭建邮件服务器
  4. MySQL查询的时候出现 Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggre报错
  5. qq录制视频保存到哪了?如何更改qq录屏存储位置
  6. 【光波电子学】期末复习资料汇总
  7. Xfce4快捷键个性化配置(个人向)
  8. 计算机的自动播放功能有什么用,电脑问题---关闭自动播放功能.doc
  9. 点击箭头 切图 html,项目切图规范 css精灵图 css小箭头代码 BFC (Block Formatting Context) 块级格式化上下文...
  10. 什么是语法糖?Java中有哪些语法糖?