台球游戏的核心算法和AI(2)


前言:
  最近研究了box2dweb, 觉得自己编写Html5版台球游戏的时机已然成熟. 这也算是圆自己的一个愿望, 一个梦想.
  承接该序列的相关博文:
  • 台球游戏核心算法和AI(1) 
  同时结合html5的学习笔记:
  • box2dweb 学习笔记--sample讲解 
  这篇文章, 具体讲解台球游戏的box2d模型抽象, 并给出一个初步版本.

演示:
  台球游戏的雏形如下所示:
  
  该台球游戏, 改编自box2dweb的demo程序, 可用鼠标拖动球来移动.
  代码的下载链接: http://pan.baidu.com/s/1sjzCwqD

分析:
  让我们对台球游戏做个简单的物理抽象, 然后"庖丁解牛", 对每个组件结合box2d进行剖析.
  
  如图所示, 其抽象为6个球袋和6个边框构成, 球袋是球落入的目标, 边框则限定了台球的活动范围.
  • 边框抽象
  台球边框相对简单, 其可视为静态物体. 其物理形状就是一条边.

// 设置为静态物体类型
wallBodyDef.type = b2Body.b2_staticBody;

// 采用多边形形状,然后SetAsEdge设置为边
wallFixDef.shape = new b2PolygonShape;
wallFixDef.shape.SetAsEdge(new b2Vec2(x1, y1), new b2Vec2(x2, y2));

  注: 边框转为box2d对象还是简单的.
  • 球袋抽象
  球袋本身也是静态物体, 但不同于边框, 其的box2d抽象, 多了点复杂和技巧.
  1). 感应设置
  球袋区域应为感应区, 球可以进入该区域, 但并不与之发生碰撞反应.
  可以通过设定定制器(Fixture)的isSensor属性为true来实现, 如下面代码所示:

var holeFixtureDef = new b2FixtureDef;
holeFixtureDef.shape = new b2CircleShape(0.5);
holeFixtureDef.isSensor = true;

  注: 其特性为能感知碰撞不发生碰撞反应
  2). 落袋有效区域变换
  球袋和球的区域相交时, 并不代表球就进洞. 如下图所示:
  
  注: 红球刚好和球袋区域相交, 但红球重心并没有落入球袋的有效范围内.
  为了完美解决球进洞的逻辑判断, 我们有两种思路去解决.
  一种思路为: 从产生的碰撞接触对象b2Contact中, 计算两者的距离, 若两者圆心距离小于球袋半径, 则算进洞, 否则不算.
  另一种思路, 是做一个trick的技巧, 构造一个半径 = 球袋半径 - 球半径, 圆心依旧是球袋中心的圆, 并代替作为球袋的box2d物理模型. 该圆若与球相交, 则可以认为球重心落入球袋区域. 这可以免去前者的计算.
  
  注: 绿色的内部圆即是构造的球袋核心圆, 其外部的圆是物理表象的圆. 该场景为球和球袋相交, 但球重心和内部圆没有相交, 即重心没有落入球袋区域.
  环绕球袋本身的3/4圆, 则采用多边形来逼近模拟(样例采用16边形), 这也是防止球出有效区域(实际上这个可以忽略).
  • 球体放置
  我们都知道, 台球模拟, 最困难的往往是开球的时候. 一堆球挤在一起, 每个瞬间, 都有好多球彼此互相接触.
  球体的堆放其实是有技巧的, 摆放的球体不需要每个都紧挨着的, 可以适当的留些空隙. 如下所示:
  
  • 整体模拟
  由于采用垂直视角看台球桌面, 重力方向是指向内部. 创建世界对象时, 可简单设置gravity为零向量.

var world = new b2World(new b2Vec2(0, 0), true)

  而台球桌面本身的摩擦阻力, 由于台球游戏在box2世界, 没有存在相关物理物体, 因此我们需要设置球的线速度减震来模拟台球桌摩擦阻力.

ballBodyDef.linearDamping = 0.25;

  最终台球游戏整体的box2d物理模型, 对转换为如下图:
  
  • 进球处理
  球进球袋后, 需要消失, 可以理解为该球从box2d的物理世界中消除.
  对于碰撞反应, box2d提供了两种方式去处理.
  1). 注册ContactListener方式
  2). 遍历ContactList列表
  样例代码采用第二种方式, 原因如下:
  1). ContactListener的回调处于step的模拟过程中, box2d明确规定step模拟过程中, 不允许修改物理属性.
  2). 由于台球游戏的物体个数并不多, 因此遍历ContactList列表其性能是可接受的.

        /* 清除落入袋中球 */
        var contactList = world.GetContactList();
        for ( var contact = contactList; contact; contact = contact.GetNext() ) {
            if ( !contact.IsTouching() ) {   /* 接触只代表AABB重合 但不代表形体碰撞 */
                continue;
            }
            var b1 = contact.GetFixtureA().GetBody();
            var b2 = contact.GetFixtureB().GetBody();

            if (b1.GetUserData() && b2.GetUserData()) {
                if (b1.GetUserData() === BALL_TYPE.BG_HOLE_TYPE && b2.GetUserData() === BALL_TYPE.BG_BALL_TYPE ) {
                    world.DestroyBody(b2);
                }
                if ( b2.GetUserData() === BALL_TYPE.BG_HOLE_TYPE && b1.GetUserData() === BALL_TYPE.BG_BALL_TYPE ) {
                    world.DestroyBody(b1);
                }
            }
        }

  注: 该处理代码在world.Step调用之后进行.

总结:
  这边的demo图形是借助box2d的DrawDebug来渲染的. 下一步计划用漂亮的素材替换, 并完善台球的游戏规则. 虽然水平有限, 但感觉向前迈出了坚实的一步, 这种感觉挺好的.

写在最后:
  
如果你觉得这篇文章对你有帮助, 请小小打赏下. 其实我想试试, 看看写博客能否给自己带来一点小小的收益. 无论多少, 都是对楼主一种由衷的肯定.

   

网络多人对战台球(服务器完整版)使用自己论坛的虚拟币 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 网络台球(服务器+完整文件版) 原作者是谁不清楚了,反正不是我,我只是整理了一下,顺便把台球页面改了改以适应不同的皮肤而已。 测试地址:http://www.flagnet.net/bbs/(内蒙古大学旗帜网站) 测试帐号:注册名:dv 密码:123456 另外本站是内蒙古大学学生自己建立的网站,如果你不打算光临,请节约我们的资源不要注册了,当然,如果你经常来的话我会很欢迎你的:) 程序下载地址:http://bak.flagnet.net/cx/zzdv7.0/tq.rar ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 插件安装方法详解: 一、将服务器端目录下的文件放到任意目录(无须论坛所在目录)用记事本打开jh.sml文件,修改里面的“旗帜”字样为你自己论坛的名称,打开控制面板==》》管理工具==》》数据源 (ODBC),在ODBC数据源中设置一个名为MData的Access型系统DSN数据源(名称一定要是MData,否则你就要手动修改jh.sml),数据库指向你的论坛数据库。 二、将压缩包中的tq.mdb中的user表导入你的论坛数据库中,将tq目录z_tq.asp,z_tq_config.asp两文件都放在你论坛的根目录下。修改z_tq.asp里的“192.168.1.234”为你自己的IP,修改z_tq.asp中“旗帜”字样为你自己论坛的名称。 三、运行:此处分两种处理情况,推荐使用第二种方式(即作为Sevice在后台自动运行) (1)直接执行展开目录下的jh.bat即可(此方式使得服务器管理起来不太方便,不能注销没,但使用起来简单) (2)作为Sevice在后台自动运行(可以注销服务器,但方法较繁,看仔细了^_^),方法如下:   首先,确定你的系统是WINNT/2K/XP中的一种,如果你用的是win98,那么抱歉,你无法使用我们介绍的这种方法。   1、service文件夹中的内容是微软公司提供的设置WINNT/2K服务的工具。在解压到一个目录后你可以看到两个文件,分别是Instsrv.exe, Srvany.exe。   2、用CMD进入DOS命令行方式,进入解压的目录,运行 instsrv taiqiu x:***xsrvany.exe,注意,上例中taiqiu代表要安装的服务的名称,x:***x代表srvany.exe所在硬盘的目录。例如将压缩包中的文件解压到g:service,那么就应该在g:service目录下执行instsrv taiqiu g:servicesrvany.exe。   3、用REGEDIT命令进入注册表编辑器,找到HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServices键,应该可以看到刚才建立的服务taiqiu。   4、右键点击服务名taiqiu,点选New,Key(中文版中为新建,项),输入Parameters,这样一个新键被建立,右键点Parameters,点选New, String value(中文版中为新建,字符串值),输入Application。完成后会看到右边窗口中创立了一个名为Application的主键,双击它,输入jh.bat的位置。   5、按上面同样办法创建AppDirectoryAppParameters两个主键,AppDirectory的键值为taiqiu所在的目录,AppParameters的键值则是运行taiqiu的参数(不用设值),然后关闭注册表编辑器。   6、从控制面板-->管理工具-->服务中找到添加的叫taiqiu的服务,双击修改其属性,将Log ON(中文版中为登录)选项卡中的Log on as(中文版中为登录身份)选项改为Local System account(中文版中为本地系统账户),然后点击OK退出。   7、到此为止,taiqiu的后台服务就基本上配置好了让它自动运行就可以运行服务来看一看是否成功了,用右键点击taiqiu,选择Start(中文版中为运行),然后稍等一会儿,等taiqiu读取完以后,就可以正常使用了。在第一次运行的时候,可以在Log On选项卡中,注意不要选中Allow service to interact
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值