热门标签 | HotTags
当前位置:  开发笔记 > 前端 > 正文

Flash务实主义(二)最短路径原则(上)_MySQL

Flash务实主义(二)——最短路径原则(上)
最短路径原则,就是将复杂的问题简单化。

达到目标并不是只有一条路,眼前的那条往往也不是最短的一条。所以,解决问题前的第一步,应该是要找实现目标的最短路线。虽然有些人可能会喜欢完成些复杂的算法来获得成就感,但这就是另一个话题了。

要明白,我们是作为实现工具的工人,而不是授命在空中楼阁中研究的学者。

魔术师视角,而不是观众视角

首先是一个比较典型的例子。

那位兄台提出这个问题的时候,问的是碰撞检测。

而且是不规则形状,有凹的也有凸的碰撞检测。判断两个物体是否边缘匹配,可以拼在一起。最后还要在放下时自动检测周围的方块,并自动吸附。必须得说,这个课题真的很困难,倒不是说找不出方法,而是找不出效率可以接受的方法。优化的办法应该是有的,但是我不会,因为这个还得吸附啊,我哪知道哪边才是边。但后来我觉得不对劲,就问了下他实际要做的东西。

才知道这家伙原来是做——拼图。

所谓拼图,就是一个图片被拆成各种不规则形状然后打乱,然后让玩家重拼起来,需求就是这样。好吧,既然是这样,那么记下这些碎片的原始位置,然后判断你手上的碎片目前坐标是否接近这个位置不就好了。

电脑没有必要使用人的思维,设计者没必要使用玩家的思维。完全模拟,并不是最好的方案。

首先考虑简单的近似实现

老外的东西总是能有惊喜。老外的思路常常都很单纯,过度设计的情况很少见。不管怎么说,他们的经验还是要丰富一些的。虽然一个需求怎么都能实现,但细微之处的积累依然会产生大的变化。这次嘛,是关于一个同事在玩的SNS游戏,它里面捡钱会曲线飞到表示钱的数字上这个效果挺别致的。

国内的情况,连做个直线飞就已经多余了,更不要说曲线了。但曲线的效果的确比直线生动很多。然后我就在仔细观察它的轨迹,考虑它是怎么实现的,想做一个类准备着以后来用。一般的想法,是用二次贝尔法曲线公式计算出运动轨迹,虽然需要一定的数学公式但曾经做过应该不成问题,而且TweenMax也提供了这个功能,但既然是曲线就有曲率的问题,而参考的效果并不是固定的1/4圆,况且这种做法有些太小题大作了。然后就是考虑物理移动,但原效果看起来使用了圆缓冲,越接近目标越慢,而且是平行y轴结束,这个用物理模拟会比较困难……

最后我脑子突然灵光了。让X轴方向用匀速移动,Y轴方向减速圆缓冲移动,看起来貌似就是画面里的样子……

也就是代码:

TweenLite.to(target,{x:tx }); TweenLite.to(target,{y:ty,ease:Circ.easeIn }); 

其结果就是弧线,和原品一模一样的。很显然,这还要做类会很无聊。

即使有复杂的解决方案,也应该考虑是否有更简单的方案。复杂的方案只是适用范围更广泛而已,但既然有“这么简单”的,何必去费那个事呢。

到现在还不知道TweenLite是什么的参见以下地址:http://www.greensock.com/tweenlite/

“根据需求选择技术”VS“将适用的技术用于需求”

说到这里,正好提下四叉树的问题。四叉树的确是一个很经典的解决屏幕物品筛选遍历的方案。具体是怎么做的可以参考网上的其它资料,可惜原理讲起来有些拗口,实现也比较恶心,所以目前并没有被广泛使用。

但是这东西不就是筛选屏幕内物品用的么?因为有两个坐标,可以将物品按坐标归类。这里我们又犯了“将适用的技术用于需求”而不是“根据需求选择技术”的错误。四叉树的确可以用来快速筛选屏幕内的物品,但并不是说筛选屏幕内的物品就只能用四叉树。要知道四叉树可以处理任意缩放屏幕,以及无限大的坐标系内的快速筛选,但我们实际上需要的就是几十屏以内固定屏幕大小内的筛选。

实际上,有个很好理解的代替方案。我们可以创建一个二维数据,诸如地图是10000*10000的,屏幕大小是1000*1000,我们就创建一个20*20的二维数组,然后将坐标范围在(0-500,0-500)的物品存在数组的(0,0)项内,将(500-1000,0-500)存在数组的(1,0)项内,将(1000-1500,0-500)存在数组的(2,0)项内,将(1000-1500,500-1000)存在数组的(2,1)项内,将(1000-1500,1000-1500)存在数组的(2,2)项内……然后将地图里的所有物品按这个方式保存在二维数组里,物品移动时则更新数组。

到时候要取屏幕范围,就以屏幕中心坐标开始,除以500获得一个区块的坐标,然后取他周围的九个区块,这些区块内保持的物品实例肯定覆盖了整个屏幕。虽然会多出一些屏幕外的物品,但这点多余消耗是可以接受的。

这和使用四叉树的结果是相同的,都可以快速定位屏幕内物品,做到游戏中存在大量物体,但只要不同时出现在同屏,就不会耗费过多遍历性能的目的。

关于四叉树遍历可以参考衰人的日志:(http://wxsr.blogbus.com/logs/60788934.html

特殊情况应当使用特殊处理

子弹会穿墙,这是个经典问题。

现实的子弹是线性移动的,电脑中的却不是。子弹的移动一定是间隔进行的,而子弹的速度很快,体积小,墙壁薄的时候,就有几率正好跨过去导致碰撞检测失效。这其实是满经典的问题,像以前玩沙罗曼蛇,全部吃加速吃到一定程度就可以玩穿墙了,毕竟碰撞检测是一个高消耗的操作,能简化就简化,尤其是在飞行射击游戏出现大量子弹的情况下,采用复杂的判断逻辑实在不合算。

需要注意到,在设定好的环境里,子弹穿墙的几率实际上是很低的。这种游戏子弹是要能看到并躲避的,速度就不能太快。就算那子弹的确比较快,只要你墙壁别薄到看不到,一般也是穿不过去的。如果这两个条件都满足,我只能认为你游戏设计稍微有点问题。

好吧,说到解决方案,最彻底的当然是计算移动轨迹并判断是否和障碍物的边缘相交,这并不算困难,但是性能消耗会翻倍,仅仅是为了特殊状况,确实有这样做必要么?

如果游戏里所有子弹都是会穿墙的速度,这游戏基本就不用玩了。所以,能穿墙的只会是某些特定的高速弹。仅仅为了这个而使其它正常速度的子弹的碰撞判断降低性能,这个做法并不妥当,那实际上可以怎么做呢?

你只要将你的特定子弹尾部延长就可以,就是修改子弹素材,在尾部添加一条透明的尾巴并参与碰撞。虽然看起来是点,却是线。这样要想穿墙难度就高很多了。而这个延长部分是感受不出来的,因为它是高速弹,来无踪去无影,不可能抓得到尾巴。

步骤的对调可能大幅简化逻辑

当时是心血来潮想做个爆炸效果。就是那种哐啷一声一块玻璃被切成一片片散落的样子。例子可以参考FFX的战斗切换,以及DMC3关卡结束的切换动画。

这个效果其它部分都很简单,难点在于切割。碎裂的方式是随机的,首先是创建一堆随机的点,然后三点组合成三角形,问题就在于如何组合。三角形当然是不能交叠的,所以你需要将接近的点组合成三角形,而且保证它们不会叠在一起,问题就转变为“什么样的点才叫接近的点”。这个算法倒是在哪看到过,不过我不记得就是了……

查也查不到,所以我就找个了近似方案代替。这里关键的问题在于点的随机性,只要点不是随机的,组合三角形就可以用((0,0),(0,1),(1,0)),((0,1),(1,0),(1,1))这个约定的组合,然后保证随机的时候不会交叉就可以了。

首先是创建出不考虑随机的状况,差不多就像下面这样,平均切成矩形,矩形再分成两个三角形。此时顶点到三角形的组合规律是固定的。

把这个作为原始状态,再调整顶点的位置,可以看到,即使将各个顶点分开移动,每个顶点只要还在矩形范围内活动,三角形就不会交叠。

其结果就是这样,虽然不是完全随机,但基本可以符合要求。

除去必须在边缘上的点之外,中间自由活动的点的坐标可以这样简单地求出来

x = dx * (i + Math.random()) y = dy * (j + Math.random()) 

其中dx,dy是分割的小矩形的长宽,i,j是顶点的x,y序号。

换个思路,就有新的方向。先创建顶点再组合三角形,和创建三角形再调整顶点,难易程度就会完全不同。

推荐阅读
  • 阿里Treebased Deep Match(TDM) 学习笔记及技术发展回顾
    本文介绍了阿里Treebased Deep Match(TDM)的学习笔记,同时回顾了工业界技术发展的几代演进。从基于统计的启发式规则方法到基于内积模型的向量检索方法,再到引入复杂深度学习模型的下一代匹配技术。文章详细解释了基于统计的启发式规则方法和基于内积模型的向量检索方法的原理和应用,并介绍了TDM的背景和优势。最后,文章提到了向量距离和基于向量聚类的索引结构对于加速匹配效率的作用。本文对于理解TDM的学习过程和了解匹配技术的发展具有重要意义。 ... [详细]
  • 本文由编程笔记#小编为大家整理,主要介绍了logistic回归(线性和非线性)相关的知识,包括线性logistic回归的代码和数据集的分布情况。希望对你有一定的参考价值。 ... [详细]
  • Monkey《大话移动——Android与iOS应用测试指南》的预购信息发布啦!
    Monkey《大话移动——Android与iOS应用测试指南》的预购信息已经发布,可以在京东和当当网进行预购。感谢几位大牛给出的书评,并呼吁大家的支持。明天京东的链接也将发布。 ... [详细]
  • 本文介绍了使用CentOS7.0 U盘刻录工具进行安装的详细步骤,包括使用USBWriter工具刻录ISO文件到USB驱动器、格式化USB磁盘、设置启动顺序等。通过本文的指导,用户可以轻松地使用U盘安装CentOS7.0操作系统。 ... [详细]
  • Lodop中特殊符号打印设计和预览样式不同的问题解析
    本文主要解析了在Lodop中使用特殊符号打印设计和预览样式不同的问题。由于调用的本机ie引擎版本可能不同,导致在不同浏览器下样式解析不同。同时,未指定文字字体和样式设置也会导致打印设计和预览的差异。文章提出了通过指定具体字体和样式来解决问题的方法,并强调了以打印预览和虚拟打印机测试为准。 ... [详细]
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • Final关键字的含义及用法详解
    本文详细介绍了Java中final关键字的含义和用法。final关键字可以修饰非抽象类、非抽象类成员方法和变量。final类不能被继承,final类中的方法默认是final的。final方法不能被子类的方法覆盖,但可以被继承。final成员变量表示常量,只能被赋值一次,赋值后值不再改变。文章还讨论了final类和final方法的应用场景,以及使用final方法的两个原因:锁定方法防止修改和提高执行效率。 ... [详细]
  • GetWindowLong函数
    今天在看一个代码里头写了GetWindowLong(hwnd,0),我当时就有点费解,靠,上网搜索函数原型说明,死活找不到第 ... [详细]
  • 本文介绍了求解gcdexgcd斐蜀定理的迭代法和递归法,并解释了exgcd的概念和应用。exgcd是指对于不完全为0的非负整数a和b,gcd(a,b)表示a和b的最大公约数,必然存在整数对x和y,使得gcd(a,b)=ax+by。此外,本文还给出了相应的代码示例。 ... [详细]
  • EPICS Archiver Appliance存储waveform记录的尝试及资源需求分析
    本文介绍了EPICS Archiver Appliance存储waveform记录的尝试过程,并分析了其所需的资源容量。通过解决错误提示和调整内存大小,成功存储了波形数据。然后,讨论了储存环逐束团信号的意义,以及通过记录多圈的束团信号进行参数分析的可能性。波形数据的存储需求巨大,每天需要近250G,一年需要90T。然而,储存环逐束团信号具有重要意义,可以揭示出每个束团的纵向振荡频率和模式。 ... [详细]
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • Nginx使用(server参数配置)
    本文介绍了Nginx的使用,重点讲解了server参数配置,包括端口号、主机名、根目录等内容。同时,还介绍了Nginx的反向代理功能。 ... [详细]
  • 基于layUI的图片上传前预览功能的2种实现方式
    本文介绍了基于layUI的图片上传前预览功能的两种实现方式:一种是使用blob+FileReader,另一种是使用layUI自带的参数。通过选择文件后点击文件名,在页面中间弹窗内预览图片。其中,layUI自带的参数实现了图片预览功能。该功能依赖于layUI的上传模块,并使用了blob和FileReader来读取本地文件并获取图像的base64编码。点击文件名时会执行See()函数。摘要长度为169字。 ... [详细]
  • 电销机器人作为一种人工智能技术载体,可以帮助企业提升电销效率并节省人工成本。然而,电销机器人市场缺乏统一的市场准入标准,产品品质良莠不齐。创业者在代理或购买电销机器人时应注意谨防用录音冒充真人语音通话以及宣传技术与实际效果不符的情况。选择电销机器人时需要考察公司资质和产品品质,尤其要关注语音识别率。 ... [详细]
author-avatar
遗忘不能忘
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有