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

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

今天,作为一名游戏开发者,当技术与思想逐步成熟,理想似乎已不再是那么的遥不可及。以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. SpringBoot学习之启动方式
  2. Fedora中安装 Shutter步骤介绍
  3. python中的正则表达式语法_Python基础教程之正则表达式基本语法以及re模块
  4. 微信遇到特殊服务器,解决微信网页授权,出现errcode:40163,errmsg:codebeenused,看似微信访问了2次这个回调接口的问题...
  5. Codeforces Round #539 Div. 1
  6. 这些全国各地甜点,你都吃过了吗?
  7. java调用kettle例子_Kettle API - Java调用示例
  8. C++ STL vector的输出
  9. 在Linux环境下搭建CCID测试环境
  10. 基于vue-cli的webpack配置优化
  11. 多线程常见问题(面试)
  12. ios开发之 -- 强制横屏
  13. 校园网络项目PT模拟
  14. ACE admin 后台管理框架
  15. iPhone开发阶段性总结
  16. 资深研发转变为架构师意味着什么
  17. Docker配置阿里云镜像加速
  18. mysql卸载不掉? 帮你清理注册表,重新安装数据库mysql
  19. mysql的ace什么概念_ACE(03):努力了,总会有收获
  20. 哈佛结构/冯诺依曼结构详细分析

热门文章

  1. B75经典门户商业版discuz模板
  2. [Fanly Submit V4.1]WordPress插件普通收录
  3. Joe博客模板Typecho主题
  4. 用ShopEx网上开店之安装Zend插件[2]
  5. csdn中一篇sock 经验贴..
  6. 淘宝自动发货申请资格
  7. vs.php中使用apache或IIS7进行外部调试
  8. FullCalendar 五:FullCalendar应用——编辑与删除日程事件
  9. 爹地,我找到了!15个极好的Linux find命令示例
  10. 对于String类型的深刻理解