在这里我们将构造一个基于HT for Web的HTML5+JavaScript来实现汉诺塔游戏。
http://hightopo.com/demo/hanoi_20151106/index.html
汉诺塔的游戏规则及递归算法分析请参考http://en.wikipedia.org/wiki/Tower_of_Hanoi。
知道了汉诺塔的规则和算法,现在就开始创建元素。用HT for Web(http://www.hightopo.com)现有的3D模板创建底盘和3根柱子不是问题,问题是要创建若干个中空的圆盘。一开始的想法是:创建一个圆柱体,将圆柱体的上下两端隐藏,设置柱面的宽度来实现圆盘的效果,经过多次尝试并查阅相关api文档,发现柱面是没有厚度的,改方法不可行。
后来在HT for Web自定义3D模型的WebGL应用(http://www.hightopo.com/blog/381.html)受到启发,圆盘的形成就是在xy平面上的一个矩形,根据y轴旋转一周产生的,通过查阅相关文档,最总决定采用ht.Default.createRingModel方法来创建圆盘模型,然后在创建node的时候通过shape3d属性引用创建好的模型。
在逻辑实现上,采用了栈的先进后出的原理,对圆柱上的圆盘做顺序控制,确保每次移动的圆盘都是最小的圆盘。
在算法上,采用的是递归算法,通过递归算法,将搬迁过程一步一步记录下来,再采用堆的原理一步一步地执行搬迁过工作。
http://v.youku.com/v_show/id_XODcwMTk4MDI4.html
http://hightopo.com/demo/hanoi_20151106/index.html
var barNum = 5, // 圆盘个数 cylinderHeight = barNum * 20 + 40, // 圆柱高度 barrelMinORadius = 50, // 圆盘最大外半径 barrelIRadius = 10, // 圆盘内半径 poorRadius = 20, // 圆盘外半径差值 barrelMaxORadius = barrelMinORadius + barNum * poorRadius, barrelHeight = 20, // 圆盘高 barPadding = 20, // 柱体之间的间隙 floorX = barrelMaxORadius * 6 + barPadding * 4, // 底盘长 floorY = 20, // 底盘高 floorZ = 2 * barrelMaxORadius + barPadding * 2, // 底盘宽 // 柱体集 positions = [ { barrels: [], position: [-(2*barrelMaxORadius + barPadding), cylinderHeight / 2 + 1, 0] },{ barrels: [], position: [0, cylinderHeight / 2 + 1, 0] },{ barrels: [], position: [(2*barrelMaxORadius + barPadding), cylinderHeight / 2 + 1, 0] } ], runOrder = [], // 圆盘移动顺序集 // 动画参数 params = { delay: 10, duration: 500, easing: Easing['easeBoth'] }; /** * 初始化程序 * */ function init(){ dataModel = new ht.DataModel(); g3d = new ht.graph3d.Graph3dView(dataModel); view = g3d.getView(); view.className = 'main'; document.body.appendChild(view); window.addEventListener('resize', function (e) { g3d.invalidate(); }, false); g3d.setEye([0, cylinderHeight * 2, floorX * sin(2*PI/360*60)]); // 初始化节点 initNodes(); moveAnimation(); } /** * 构造游戏移动队列 * diskQuantity:圆盘个数 * positionA:起点 * positionB:中转点 * positionC:终点 * */ function buildRunOrder(diskQuantity, positionA, positionB, positionC){ if (diskQuantity == 1) { runOrder.push([positionA, positionC]); } else { buildRunOrder(diskQuantity - 1, positionA, positionC, positionB); buildRunOrder(1, positionA, positionB, positionC); buildRunOrder(diskQuantity - 1, positionB, positionA, positionC); } } /** * 移动动画 * positionA:起点 * positionC:终点 * */ function moveAnimation(positionA, positionC){ if(!positionA){ var poses = runOrder.shift(); if(!poses){ setTimeout(reset, 500); }else{ moveAnimation(positions[poses[0]], positions[poses[1]]); } }else { var barrel = positionA.barrels.pop(); var position = positionC.cylinder.p3(), barPos = barrel.getPosition3d(); position[1] = position[1] + floorY + barrelHeight * positionC.barrels.length - cylinderHeight / 2; setPolylinePoints(polyline, barPos, position); params.action = function (v, t) { var length = g3d.getLineLength(polyline), offset = g3d.getLineOffset(polyline, length * v), point = offset.point, px = point.x, py = point.y, pz = point.z; barrel.p3(px, py, pz); }; params.finishFunc = function () { positionC.barrels.push(barrel); var poses = runOrder.shift(); if (!poses) { moveAnimation(); } else { moveAnimation(positions[poses[0]], positions[poses[1]]); } }; anim = ht.Default.startAnim(params); } } /** * 重置游戏 * */ function reset(){ if(positions[0].barrels.length == 0){ positions[0].barrels = positions[2].barrels; } positions[2].barrels = []; for(var i = 0, len = positions[0].barrels.length; i < len; i++){ var pos = positions[0].cylinder.p3(); pos[1] = pos[1] + floorY + i * barrelHeight - cylinderHeight / 2; positions[0].barrels[i].p3(pos); } buildRunOrder(barNum, 0, 1, 2); setTimeout(moveAnimation, 500); } /** * 初始化节点 * */ function initNodes(){ // 底盘 floor = createNode([0, floorY / 2, 0], [floorX, floorY, floorZ]).s({ 'shape3d': 'box', '3d.movable': false }); // 创建柱子 for(var i = 0, len = 3; i < len; i++){ positions[i].cylinder = createNode(positions[i].position, [20, cylinderHeight, 20], floor).s({ 'shape3d': 'cylinder', 'shape3d.color': '#E5BB77', '3d.movable': false }); } // 创建圆盘 createBarrels(barNum, positions[0].cylinder); // 创建圆盘运行轨迹 polyline = new ht.Polyline(); polyline.setSegments([1, 2, 4, 2]); polyline.s({ 'shape.background': null, 'shape.border.color': 'rgba(0,0,0,0)', 'shape.border.gradient.color': 'rgba(0,0,0,0)', 'shape.border.pattern': [20, 10], 'shape3d.resolution': 50 }); dataModel.add(polyline); } /** * 设置路线节点 * */ function setPolylinePoints(polyline, from, to){ polyline.setPoints([ {x: from[0], y: from[2], e: from[1]}, {x: from[0], y: from[2], e: cylinderHeight}, {x: from[0], y: from[2], e: cylinderHeight + 60}, {x: to[0], y: to[2], e: cylinderHeight + 60}, {x: to[0], y: to[2], e: cylinderHeight}, {x: to[0], y: to[2], e: to[1]} ]); return polyline; } /** * 创建圆盘 * barNum:圆盘个数 * host:吸附节点 * */ function createBarrels(barNum, host){ // 圆盘初始x位置 var pos = host.p3(); for(var i = barNum, j = 0; i > 0; i--, j++){ pos[1] = barrelHeight * j + floorY; positions[0].barrels.push(createBarrel(pos, [1, barrelHeight, 1], barrelMinORadius + i*poorRadius, barrelIRadius, host).s({ 'shape3d.color': randomColor(), '3d.movable': false })); } } /** * 创建节点 * p3:节点位置 * s3:节点大小 * host:吸附节点 * */ function createNode(p3, s3, host){ var node = new ht.Node(); node.p3(p3); node.s3(s3); node.setHost(host); node.s({ 'wf.visible': 'selected', 'wf.color': '#FF6B10', 'wf.width': 2, 'wf.short': true }); dataModel.add(node); return node; } /** * 创建空心圆柱 * p3:圆桶位置 * s3:圆桶大小 * oRadius:圆桶外径 * iRadius:圆桶内径 * host:吸附节点 * */ function createBarrel(p3, s3, oRadius, iRadius, host){ return createNode(p3, s3, host).s({ 'shape3d': ht.Default.createRingModel([ oRadius, 1, oRadius, 0, iRadius, 0, iRadius, 1, oRadius, 1 ], null, 20, false, false, 70) }); }
相关推荐
HTML5 WebGL 3D 仓储管理系统是一种利用现代网络技术实现的高效、直观的库存管理解决方案。这个系统通过在网页上构建三维模型,为用户提供了更真实、更直观的仓库环境展示,使得库存物品的管理变得更加可视化和易于...
HTML5、CSS和WebGL是现代网页开发中的关键技术,它们共同为创建互动性强、视觉效果丰富的3D网页游戏提供了强大的支持。在这个经典教程中,我们将深入探讨这些技术如何结合,以构建引人入胜的网页游戏。 HTML5是超...
HTML5是下一代网页标记语言,它的出现极大地扩展了网页的交互性和功能,其中WebGL(Web Graphics Library)是一项关键的技术,它使得浏览器可以直接在用户的设备上进行硬件加速的3D图形渲染,无需任何插件。WebGL...
仓储系统!仓库管理可以说即不省力也不省事,而且使用范围还很广,数学中经常使用仓储系统来计算市场需求,物流中的动力学建模等等,所以仓储系统必不可少,在这个时间就是金钱的时代,能省时就能带来非常大的效益,...
基于HTML5 WebGL 3D樱花飘落动画 1.网页作品简介 :HTML期末大学生网页设计作业 A+水平 ,喜欢的可以下载,文章页支持手机PC响应式布局。 2.网页作品编辑:作品下载后可使用任意HTML编辑软件(如:DW、HBuilder、...
用 WebGL 渲染的 3D 机房现在也不是什么新鲜事儿了,这篇文章的主要目的是说明一下,3D 机房中的 eye 和 center 的问题,刚好在项目中用上了,好生思考了一番,最终觉得这个例子最符合我的要求,就拿来作为记录。...
该项目为基于WebGL的feng3d TypeScript 3D游戏引擎设计源码,包含555个文件,涵盖454个TypeScript源文件、81个GLSL着色器文件、6个JSON配置文件、6个YAML配置文件、3个JavaScript文件、2个Markdown文件,以及若干...
基于WebGL和HTML5的网页3D动画的设计与实现 本文主要介绍了基于WebGL和HTML5的网页3D动画的设计与实现,讲述了如何使用WebGL将JavaScript和OpenGL ES 2.0结合在一起,实现网页中的三维可视化图像。文章还讲述了基于...
总之,"HTML5 WebGL酷炫3D旋转星云动画特效"是结合HTML5的WebGL技术和JavaScript的创新应用,通过精心设计的代码和视觉效果,为用户呈现了一种极具沉浸感的3D体验。对于想要学习WebGL或者提升网页互动性的开发者来说...
"Threejs 开发指南:基于 WebGL 和 HTML5 在网页上渲染 3D 图形和动画" 本文将对 Threejs 开发指南进行详细的介绍,包括 Threejs 的重要性、与其他 3D 渲染技术的比较、为什么要使用 Threejs 等。 首先,Threejs ...
基于HTML5 WebGl的VR DEMO展示了如何利用WebGL技术创建沉浸式的虚拟现实环境。这个DEMO项目(WebGL-VR-master)可能包含了实现VR体验所需的各种文件,如HTML文件、JavaScript代码、CSS样式表以及可能的纹理图片和...
总的来说,"基于WebGL实现3D图片特效"是一个结合HTML5库和WebGL技术的创新应用,通过编程技巧将2D图像转化为互动式的3D视图,为用户带来生动的视觉体验。开发者通过理解并运用JavaScript、WebGL和相关的HTML5库,...
此外,为了成为一名成功的HTML5游戏开发者,还需要掌握JavaScript基础,理解DOM操作,熟悉现代前端框架(如React或Vue),以及对游戏设计原理的理解。通过不断地实践和项目开发,你的技能将会不断提升,创作出更多令...
综上所述,"HTML5 WebGL 摇杆+按钮"的主题涵盖了WebGL的基本使用、浏览器安全策略、前端交互设计、3D动画和性能优化等多个方面,是Web开发中的一个重要实践。通过学习和实践这个项目,开发者能够提升自己的3D Web...
网页动画素材 WebGL基于canvas画布绘制3D噪音线条酷炫动画特效。(抖音资料)网页动画素材 WebGL基于canvas画布绘制3D噪音线条酷炫动画特效。(抖音资料)网页动画素材 WebGL基于canvas画布绘制3D噪音线条酷炫动画...
Create engaging 3D applications for the Web with HTML5 and the emerging web graphics standard, WebGL. With this book, you'll learn hands-on how to take your website's production value to a new level ...
课程分享——地图Web3D可视化-WebGL、Three.js,附源码 课程概述 - 本课程讲解如何在web上实现地图3D可视化 - 学习本课程有前端基础即可,如果了解three.js更好 适用人群 有前端基础,想基于Web实现地图数据的3D...
总的来说,这个项目展示了HTML5和WebGL在创建动态、交互式3D内容方面的强大能力,同时也涉及到JavaScript编程、3D图形学和用户体验设计等多个领域。对于想要学习或提高这些技能的开发者来说,这是一个非常有价值的...