用js重建星际争霸


Posted in Javascript onDecember 22, 2006

演示地址

    http://www.script8.com/works/sc/index.htm

 

背景介绍

对很多人来说,javaScript是一种颇为神秘的语言,这种语言由浏览器解析,可以实现很复杂的功能,但在实际中又使用甚少。在以相对定位为基础的网站体系中,js并不是必不可少的,最早的浏览器并不支持js,只需使用纯静态的html,也能建立功能完备的网站。对于页面开发人员来说,使用js的时候估计也就是用于数据合法性检查而已。近年来,随着ajax概念崛起,js的使用有所增加,不过除了web邮箱等少数工具型的网站之外,其作用仍然是辅助性的。

实际上,js作为最流行的脚本语言,功能是非常强大的,笔者就曾经利用js来模拟星际争霸。大家都知道,星际争霸是即时战略游戏史上的里程碑,在玩家心目中的地位是不言而喻的,泡在各种各样的网吧里玩星际曾经是笔者生活的一部分。仅凭一腔热血,我就着手用js来开发星际,这是一次坚难的历程,充满了挫折,也享受到了乐趣,最后能够完成,却是开始时我也没有奢望到的。

js星际源码最早发布于无忧脚本的论坛里,得到了很多网友的好评,让我感动之余,也唯有更加努力。通过这次开发,我的js开发技术有了很多提高,还认识了许多喜欢js开发的朋友,幸哉!js星际现在的存放地址是http://www.script8.com/works/sc/index.htm,有兴趣的朋友欢迎参与讨论。

解决方案

寻径算法是游戏的基础,也是运算量最大的部分。我没有使用A*算法,因为对脚本来说开销太大了,而是自主开发一种新算法,称之为交点法,特点是线性寻径,运算量比较小,缺点是不能保证结果为最短路径。交点法的基本思路简述如下:

1.从起点到终点画直线,与障碍物相交时,总会出现对应的穿入点和穿出点。

2.从穿入点的两个方向同时绕行障碍物,选择先到达穿出点的路线作为前进路线,这样就得到了一条比较原始的路线。

3.对路线进行优化,判断两点是否形成通路,删除冗余点,得到最终的路径。

寻径时大量使用了判断是否障碍点的运算,一般的做法是遍历数组,分别比较才能得到结果。我把障碍点序列变成一个长字符串,通过字符串包含关系就可以判断出当前点是否障碍点,这样就减少了很多运算量。

js星际所实现的,相当于是星际争霸的开场部分,即采矿、制造建筑物和生产士兵,战斗部分略有涉及。在编码之前,就需要有许多准备工作,光是图片的制作就非常烦锁,需要万分的耐心才行。另外,我还用hta技术开发了一个地图编辑器,用于生成地图数据。

游戏里的控制面板比较精简,缩略地图和选择信息集成到右上角的一个小面板里,其他部分都属于游戏场景。每个移动单位有8个方向,以枪兵为例,需要用24张图片来表现站立和走动各种姿态。这些图片都集成在一张大图里,根据走动或站立情况,显示其中的对应部分,比如在走动时,判断出走动方向,一边移动枪兵位置,一边三张图片轮显,表现出走动的情形。

游戏初始化时,载入地图数据,根据不同的建筑物属性,一方面生成场景,另一方面生成障碍物列表,用于寻路之用。默认情况下,地图上有几个矿工,圈选后,点击目标可以自主行走,根据游戏要求,如果点击到的是矿石,就会在矿区和总部间来回走动,每次往返都会增加矿藏量。

至于哪一种建筑物能生产什么兵,每个兵需要多少资源,建筑物的生产顺序是什么,这些相对来说都比较容易,无非是做更多的图片处理和更多的逻辑判断而已,限于篇幅就不详细介绍了。

经验分享

不用太担心功能的实现,因为js已经非常完善了,可以随心所欲地进行各种运算,使用绝对定位的机制,可以轻松创建界面,再利用时钟模拟多线程,实时移动图片,就可以表现动画了,问题主要体现在速度和性能上。因为js作为一种脚本语言,其计算性能无疑是先天不足的,同时浏览器也不支持directX和openGL等硬加速,动画能力无法另人满意。只有通过减轻运算量,合理分配动画资源,才能保证游戏的平滑运行。js星际的开发,正是处处遵循了这个原则,能简则简,能省则省,非常节约地使用各种资源,才最终得以实现。

千万不要在游戏中使用滤镜技术,特别是动态滤镜,滤镜渲染时会占用大量的cpu,在cpu占用达到80%以上时,游戏就会感觉比较卡。这一点和flash做的同类程序有明显区别,即使cpu占用率接近100%,flash程序仍然能保持相当的平滑。

凭心而论,客户端的游戏开发,应该还是以flash为主。与之相比,js的好处是可与网站无缝连接,也不需要安装插件。当然了,只要是好玩实用的游戏,即使是用js开发的,也未尝不可。

Javascript 相关文章推荐
JavaScript 事件参考手册
Dec 24 Javascript
JQuery的ajax获取数据后的处理总结(html,xml,json)
Jul 14 Javascript
js中的值类型和引用类型小结 文字说明与实例
Dec 12 Javascript
JavaScript通过RegExp实现客户端验证处理程序
May 07 Javascript
ExtJS 刷新后如何默认选中刷新前最后一次选中的节点
Apr 03 Javascript
jquery中append()与appendto()用法分析
Nov 14 Javascript
jQuery中clearQueue()方法用法实例
Dec 29 Javascript
JavaScript中用于生成随机数的Math.random()方法
Jun 15 Javascript
Javascript同时声明一连串(多个)变量的方法
Jan 23 Javascript
javascript深拷贝的原理与实现方法分析
Apr 10 Javascript
vue vue-Router默认hash模式修改为history需要做的修改详解
Sep 13 Javascript
vue框架中props的typescript用法详解
Feb 17 Javascript
js版本A*寻路算法
Dec 22 #Javascript
优化JavaScript脚本的性能的几个注意事项
Dec 22 #Javascript
网页设计常用的一些技巧
Dec 22 #Javascript
用JavaScript脚本实现Web页面信息交互
Dec 21 #Javascript
在 IE 中调用 javascript 打开 Excel 表
Dec 21 #Javascript
用js+xml自动生成表格的东西
Dec 21 #Javascript
FCK调用方法..
Dec 21 #Javascript
You might like
php数组函数序列之array_keys() - 获取数组键名
2011/10/30 PHP
PHP设计模式之建造者模式(Builder)原理与用法案例详解
2019/12/12 PHP
ThinkPHP5分页paginate代码实例解析
2020/11/10 PHP
JS面向对象编程之对象使用分析
2010/08/19 Javascript
重载toString实现JS HashMap分析
2011/03/13 Javascript
用box固定长宽实现图片自动轮播js代码
2014/06/09 Javascript
显示今天的日期js代码(阳历和农历)
2014/09/30 Javascript
Lua表达式和控制结构学习笔记
2014/12/15 Javascript
AngularJS基础学习笔记之表达式
2015/05/10 Javascript
javascript检测两个数组是否相似
2015/05/19 Javascript
微信js-sdk地理位置接口用法示例
2016/10/12 Javascript
基于MVC方式实现三级联动(JavaScript)
2017/01/23 Javascript
jQuery实现 上升、下降、删除、添加一行代码
2017/03/06 Javascript
jquery ui sortable拖拽后保存位置
2017/04/27 jQuery
react开发教程之React 组件之间的通信方式
2017/08/12 Javascript
QRCode.js二维码生成并能长按识别
2018/10/16 Javascript
微信小程序使用字体图标的方法
2019/05/23 Javascript
Vue中axios拦截器如何单独配置token
2019/12/27 Javascript
微信小程序swiper组件实现抖音翻页切换视频功能的实例代码
2020/06/24 Javascript
elementUI同一页面展示多个Dialog的实现
2020/11/19 Javascript
JS中循环遍历数组的四种方式总结
2021/01/23 Javascript
举例讲解Python中的Null模式与桥接模式编程
2016/02/02 Python
深入浅析ImageMagick命令执行漏洞
2016/10/11 Python
浅谈python中的数字类型与处理工具
2017/08/02 Python
Python+tkinter使用80行代码实现一个计算器实例
2018/01/16 Python
Python爬虫图片懒加载技术 selenium和PhantomJS解析
2019/09/18 Python
解决os.path.isdir() 判断文件夹却返回false的问题
2019/11/29 Python
使用pytorch实现论文中的unet网络
2020/06/24 Python
CSS3 实现时间轴动画
2020/11/25 HTML / CSS
我有一个char * 型指针正巧指向一些int 型变量, 我想跳过它们。 为什么如下的代码((int *)p)++; 不行?
2013/05/09 面试题
Unix控制后台进程都有哪些进程
2016/09/22 面试题
“学雷锋活动月”总结
2014/03/09 职场文书
群众路线教育实践活动总结
2014/10/30 职场文书
不知如何爱孩子,这些方法教会您
2019/08/06 职场文书
Python Flask搭建yolov3目标检测系统详解流程
2021/11/07 Python
python开发制作好看的时钟效果
2022/05/02 Python