基于HT for Web的3D呈现A* Search Algorithm

最近搞个游戏遇到最短路径的常规游戏问题,正巧看到老同事写的3D机房最短路径巡线文章,一时起兴基于HT for Web写了个A*算法的WebGL 3D呈现,算法基于开源 https://github.com/bgrins/javascript-astar 的javascript实现,其实作者也有个不错的2D例子实现 http://www.briangrinstead.com/files/astar/ ,只不过觉得所有A*算法的可视化实现都是平面的不够酷,另外还有不少参数需要调节控制,还是值得好好搞个全面的Demo,先上张2D和3D例子的对照图。

实现代码比较容易一百多行,不过算法核心在astar.js了,界面核心在ht.js里面了,我只需要构建网格信息,只需监听用户点击,然后调用astar.js进行最短路径计算,将结果通过动画的方式呈现出走动的过程,所有代码如下:
function init() {
w = 40; m = 20; d = w * m / 2;
gridRows = [];
dm = new ht.DataModel();
g3d = new ht.graph3d.Graph3dView(dm);
g3d.setGridVisible(true);
g3d.setGridColor('#BBBBBB');
g3d.setGridSize(m);
g3d.setGridGap(w);
g3d.addToDOM();
g3d.sm().setSelectionMode('none');
anim = startBall = endBall = null;
g3d.getView().addEventListener(ht.Default.isTouchable ? 'touchstart' : 'mousedown', function(e){
if(!anim){
var p = g3d.getHitPosition(e);
var x = Math.floor((p[0] + d)/ w);
var y = Math.floor((p[2] + d)/ w);
var endBall = dm.getDataByTag("cell_" + x + "_" + y);
if(endBall && endBall.s('batch') !== 'wall'){
if(startBall.a('x') === x && startBall.a('y') === y){
return;
}
var g = new Graph(gridRows, {
diagonal: formPane.v('diagonal')
});
var start = g.grid[startBall.a('x')][startBall.a('y')];
var end = g.grid[x][y];
var result = astar.search(g, start, end, {
closest: formPane.v('closest')
});
if(!result.length){
return;
}
x = result[result.length-1].x;
y = result[result.length-1].y;
endBall = dm.getDataByTag("cell_" + x + "_" + y);
endBall.s('3d.visible', true);
startBall.s('3d.visible', false);
formPane.setDisabled(true);
anim = ht.Default.startAnim({
duration: 700,
finishFunc: function(){
for(var i=0; i<result.length; i++){
var ball = dm.getDataByTag("cell_" + result[i].x + "_" + result[i].y);
ball.s({
'3d.visible': false,
'shape3d.opacity': 1,
'shape3d.transparent': false
});
startBall.p3(-d+w*x+w/2, w/2, -d+w*y+w/2);
startBall.a({x: x, y: y});
startBall.s('3d.visible', true);
}
anim = null;
formPane.setDisabled(false);
},
action: function(v){
var index = Math.round(v*result.length);
for(var i=0; i<index; i++){
var ball = dm.getDataByTag("cell_" + result[i].x + "_" + result[i].y);
ball.s({
'3d.visible': true,
'shape3d.opacity': i/index*0.3 + 0.7,
'shape3d.transparent': true
});
}
}
});
}
}
}, false);
createFormPane();
createGrid();
}
function createGrid(){
dm.clear();
var ball;
gridRows.length = 0;
for(var x = 0; x < m; x++) {
var nodeRow = [];
gridRows.push(nodeRow);
for(var y = 0; y < m; y++) {
var isWall = Math.floor(Math.random()*(1/formPane.v('frequency')));
if(isWall === 0){
nodeRow.push(0);
createNode(x, y).s({
'batch': 'wall',
'all.color': '#9CA69D'
});
}else{
nodeRow.push(1);
ball = createNode(x, y).s({
'shape3d': 'sphere',
'shape3d.color': '#FF703F',
'3d.visible': false
});
}
}
}
if(!ball){
createGrid();
return;
}
startBall = createNode(ball.a('x'), ball.a('y'), 'start').s({
'shape3d': 'sphere',
'shape3d.color': '#FF703F'
});
shape = new ht.Shape();
shape.setPoints(new ht.List([
{x: -d, y: d},
{x: d, y: d},
{x: d, y: -d},
{x: -d, y: -d},
{x: -d, y: d}
]));
shape.setThickness(4);
shape.setTall(w);
shape.setElevation(w/2);
shape.setClosePath(true);
shape.s({
'all.color': 'rgba(187, 187, 187, 0.8)',
'all.transparent': true,
'all.reverse.cull': true
});
dm.add(shape);
}
function createNode(x, y, tag){
var node = new ht.Node();
tag = tag || "cell_" + x + "_" + y;
node.setTag(tag);
node.a({ x: x, y: y });
node.s3(w*0.9, w*0.9, w*0.9);
node.p3(-d+w*x+w/2, w/2, -d+w*y+w/2);
node.s({
'all.reverse.cull': true,
'shape3d.reverse.cull': true
});
dm.add(node);
return node;
}
function createFormPane() {
formPane = new ht.widget.FormPane();
formPane.setWidth(230);
formPane.setHeight(70);
formPane.getView().className = 'formpane';
document.body.appendChild(formPane.getView());
formPane.addRow(['Wall Frequency', {
id: 'frequency',
slider: {
min: 0,
max: 0.8,
value: 0.1,
onValueChanged: function(){
createGrid();
}
}
}], [100, 0.1]);
formPane.addRow([
{
id: 'closest',
checkBox: {
label: 'Try Closest'
}
},
{
id: 'diagonal',
checkBox: {
label: 'Allow Diagonal'
}
}
], [0.1, 0.1]);
}
只从iOS8支持WebGL后在移动终端上测试3D应用比当前的大部分Android平板舒服多了,以上的例子在iOS系统下呈现和算法都挺流畅,http://v.youku.com/v_show/id_XODMzOTU1Njcy.html,当然这个小例子数据量也不大,本质其实还是2D的最短路径算法,并非真正意义的3D空间最短路径,但还是足够解决很多实际应用问题了。

基于HT for Web的3D呈现A* Search Algorithm的更多相关文章
- 基于WebGL 的3D呈现A* Search Algorithm
http://www.hightopo.com/demo/astar/astar.html 最近搞个游戏遇到最短路径的常规游戏问题,一时起兴基于HT for Web写了个A*算法的WebGL 3D呈现 ...
- 基于HT for Web的3D拓扑树的实现
在HT for Web中2D和3D应用都支持树状结构数据的展示,展现效果各异,2D上的树状结构在展现层级关系明显,但是如果数据量大的话,看起来就没那么直观,找到指定的节点比较困难,而3D上的树状结构在 ...
- 基于HT for Web的3D树的实现
在HT for Web中2D和3D应用都支持树状结构数据的展示,展现效果各异,2D上的树状结构在展现层级关系明显,但是如果数据量大的话,看起来就没那么直观,找到指定的节点比较困难,而3D上的树状结构在 ...
- 基于HT for Web 3D呈现Box2DJS物理引擎
上篇我们基于HT for Web呈现了A* Search Algorithm的3D寻路效果,这篇我们将采用HT for Web 3D来呈现Box2DJS物理引擎的碰撞效果,同上篇其实Box2DJS只是 ...
- 基于HT for Web矢量实现3D叶轮旋转
在上一篇<基于HT for Web矢量实现2D叶轮旋转>中讲述了叶轮旋转在2D上的应用,今天我们就来讲讲叶轮旋转在3D上的应用. 在3D拓扑上可以创建各种各样的图元,在HT for Web ...
- 基于HT for Web 快速搭建3D机房设备面板
以真实设备为模型,搭建出设备面板,并实时获取设备运行参数,显示在设备面板上,这相比于纯数值的设备监控系统显得更加生动直观.今天我们就在HT for Web的3D技术上完成设备面板的搭建. 我们今天模拟 ...
- 基于HT for Web 3D技术快速搭建设备面板
以真实设备为模型,搭建出设备面板,并实时获取设备运行参数,显示在设备面板上,这相比于纯数值的设备监控系统显得更加生动直观.今天我们就在HT for Web的3D技术上完成设备面板的搭建. 我们今天模拟 ...
- HT for Web中3D流动效果的实现与应用
流动效果在3D领域有着广泛的应用场景,如上图中医学领域可通过3D的流动直观的观察人体血液的流动,燃气领域可用于监控管道内流动的液体或气体的流向.流速和温度等指标. 如今企业数据中心机房普遍面临着设备散 ...
- 基于HT for Web的Web SCADA工控移动应用
在电力.油田燃气.供水管网等工业自动化领域Web SCADA的概念已经提出了多年,早先年的Web SCADA前端技术大部分还是基于Flex.Silverlight甚至Applet这样的重客户端方案,在 ...
随机推荐
- ORACLE索引失效原因归纳[转]
1.隐式转换导致索引失效.这一点应当引起重视.也是开发中经常会犯的错误. 由于表的字段tu_mdn定义为varchar2(20),但在查询时把该字段作为number类型以where条件传给Orac ...
- 【腾讯Bugly干货分享】Android ListView与RecyclerView对比浅析--缓存机制
本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/5811d3e3ab10c62013697408 作者:黄宁源 一,背景 Recy ...
- [.net 面向对象编程基础] (21) 委托
[.net 面向对象编程基础] (20) 委托 上节在讲到LINQ的匿名方法中说到了委托,不过比较简单,没了解清楚没关系,这节中会详细说明委托. 1. 什么是委托? 学习委托,我想说,学会了就感觉简 ...
- zendframework 2
我想我的生活需要新的挑战 zf2整个框架里面都应用了namespace,并且他的每个模块,我们都可以根据自己的需要去命名路径,对我来说,zf2的模块化更加的清晰,对于外包来说,或许很方便. 创建他,我 ...
- 在.net中使用aquiles访问Cassandra(二)
上文中我们已经建立了项目的基本结构,今天实现数据的修改.在NoSQL中,通常添加和修改都认为是对数据的一种Mutation. 1.建立描述修改Row的实体. public class RowMut ...
- C# Azure 存储-分布式缓存Redis的新建&配置&查看
1. 介绍 Redis 是一款开源的,基于 BSD 许可的,高级键值 (key-value) 缓存 (cache) 和存储 (store) 系统.由于 Redis 的键包括 string,hash,l ...
- 为什么占位符可以防止sql注入?
先看下面用占位符来查询的一句话 String sql = "select * from administrator where adminname=?"; psm = con.pr ...
- js实现一个可以兼容PC端和移动端的div拖动效果
前段时间写了一个简单的div拖动效果,不料昨天项目上正好需要一个相差不多的需求,就正好用上了,但是在移动端的时候却碰到了问题,拖动时候用到的三个事件:mousedown.mousemove.mouse ...
- png图片尺寸大小调整
Android 开发中经常遇到各种hdpi,xhdpi,xxhdpi....很多尺寸大小的png图片要求. 网上也有不少工具,今天我又发现一款在线转换大小的网站,用了一下,一个png 114X114 ...
- JS的prototype和__proto__ Constructor
一.prototype和__proto__的概念 prototype是 注意是 只有函数的一个属性才有的(每个函数都有一个prototype属性),这个属性是一个指针,指向一个普通对象并且不是原型对象 ...