这篇文章讨论如何在基于Babylon.js的WebGL场景中,建立棋盘状的地块和多个可选择的棋子对象,在点选棋子时显示棋子的移动范围,并且在点击移动范围内的空白地块时向目标地块移动棋子。在这一过程中要考虑不同棋子的移动力和影响范围不同,以及不同地块的移动力消耗不同。
一、显示效果:
1、访问https://ljzc002.github.io/CardSimulate/HTML/TEST3tiled.html查看“棋盘测试页面”:
场景中是一个20*20的棋盘,地块随机为草地、土地、雪地,棋盘中央是四个“棋子”(用卡牌网格对象客串)。使用鼠标和wasd、Shift、空格键控制相机网格对象在场景中漫游,4个棋子会努力让自己面朝相机。
2、点击一个棋子或棋子所在的地块,棋子将被选中并显示棋子的可移动范围和影响范围:
棋子可以到达的地块覆盖蓝色半透明遮罩,棋子不能到达但可以影响的地块覆盖红色半透明遮罩。这里规定“铜卡”的移动力为10、影响范围为2,“银卡”的移动力为15、影响范围为3,草地、泥地、雪地对移动力的消耗分别为2、3、4.
3、点击蓝色地块,将用黄色半透明遮罩标出棋子到达目标地块的路径,点击红色地块,则标出到达距这个红色地块最近的蓝色地块的路径:
4、点击黄色地块,则棋子缓缓移动到目标黄色地块,到达目标后,在棋子周围显示棋子的影响范围:
在更新版的程序里,取消了棋子下面的红色遮罩
5、点击棋子可以将镜头拉近到棋子附近;点击影响范围外的地块,可以取消棋子的选定;点击其他的棋子或者含有其他棋子的地块,可以改变选定的棋子。
二、代码实现:
这个棋盘场景是在上一个卡牌场景(https://www.cnblogs.com/ljzc002/p/9660676.html)的基础上改进而来的,这里只讨论改变和新增的代码中比较重要的部分,大部分新增方法在Tiled.js中。
1、在initArena中建立棋盘:
复制代码
1 mesh_tiledGround=new BABYLON.Mesh("mesh_tiledGround", scene);//这是所有地块的父网格也是所有棋盘上的棋子的爷爷网格
2 mesh_tiledGround.position.y=-7;//设定棋盘高度
3 MakeTileds2(0,20,20);//产生正方形的棋盘网格,20*20大小。
复制代码
MakeTileds2方法内容如下:
复制代码
1 arr_tilednodes=[];//一个二维数组,保存棋盘中的每个地块对象
2 mesh_tiledCard=null;//所有棋子对象的父网格,是mesh_tiledGround的子元素
3 function MakeTileds2(type,sizex,sizez)//换一种地块构造方式,想到tiledGround事实上并没有必要性,如果忽略掉性能上可能存在的优势
4 {
5 //给几种遮罩层建立材质:蓝色、红色、黄色、绿色、全透明
6 var mat_alpha_blue=new BABYLON.StandardMaterial("mat_alpha_blue", scene);
7 mat_alpha_blue.diffuseTexture = new BABYLON.Texture("../ASSETS/IMAGE/LANDTYPE/alpha_blue.png",scene);
8 mat_alpha_blue.diffuseTexture.hasAlpha=true;//声明漫反射纹理图片具有透明度
9 mat_alpha_blue.useAlphaFromDiffuseTexture=true;//启用漫反射纹理的透明度
10 //mat_alpha_blue.hasVertexAlpha=true;
11 //mat_alpha_blue.diffuseColor = new BABYLON.Color3(0, 0,1);
12 //mat_alpha_blue.alpha=0.2;//不透明度
13 mat_alpha_blue.useLogarithmicDepth=true;//为了和卡牌之间正常显示,它也必须这样设置深度?
14 MyGame.materials.mat_alpha_blue=mat_alpha_blue;
15 var mat_alpha_red=new BABYLON.StandardMaterial("mat_alpha_red", scene);
16 mat_alpha_red.diffuseTexture = new BABYLON.Texture("../ASSETS/IMAGE/LANDTYPE/alpha_red.png",scene);
17 mat_alpha_red.diffuseTexture.hasAlpha=true;
18 mat_alpha_red.useAlphaFromDiffuseTexture=true;
19 //mat_alpha_red.diffuseColor = new BABYLON.Color3(1, 0,0);
20 //mat_alpha_red.alpha=0.2;//不透明度
21 mat_alpha_red.useLogarithmicDepth=true;
22 MyGame.materials.mat_alpha_red=mat_alpha_red;
23 var mat_alpha_green=new BABYLON.StandardMaterial("mat_alpha_green", scene);
24 mat_alpha_green.diffuseTexture = new BABYLON.Texture("../ASSETS/IMAGE/LANDTYPE/alpha_green.png",scene);
25 mat_alpha_green.diffuseTexture.hasAlpha=true;
26 mat_alpha_green.useAlphaFromDiffuseTexture=true;
27 //mat_alpha_green.diffuseColor = new BABYLON.Color3(0, 1,0);
28 //mat_alpha_green.alpha=0.2;//不透明度
29 mat_alpha_green.useLogarithmicDepth=true;
30 MyGame.materials.mat_alpha_green=mat_alpha_green;
31 var mat_alpha_yellow=new BABYLON.StandardMaterial("mat_alpha_yellow", scene);
32 mat_alpha_yellow.diffuseTexture = new BABYLON.Texture("../ASSETS/IMAGE/LANDTYPE/alpha_yellow.png",scene);
33 mat_alpha_yellow.diffuseTexture.hasAlpha=true;
34 mat_alpha_yellow.useAlphaFromDiffuseTexture=true;
35 //mat_alpha_yellow.diffuseColor = new BABYLON.Color3(1, 1,0);
36 //mat_alpha_yellow.alpha=0.2;//不透明度
37 mat_alpha_yellow.useLogarithmicDepth=true;
38 MyGame.materials.mat_alpha_yellow=mat_alpha_yellow;
39 var mat_alpha_null=new BABYLON.StandardMaterial("mat_alpha_null", scene);//或者直接将遮罩设为不可见?
40 mat_alpha_null.diffuseColor = new BABYLON.Color3(1, 1,1);
41 mat_alpha_null.alpha=0;//不透明度
42 mat_alpha_null.useLogarithmicDepth=true;
43 MyGame.materials.mat_alpha_null=mat_alpha_null;
44
45 mesh_tiledCard=new BABYLON.Mesh("mesh_tiledCard",scene);//所有单位的父元素
46 mesh_tiledCard.parent=mesh_tiledGround;
47 if(type==0)// 两层循环
48 {
49 var obj_p={xmin:-30,xmax:30,zmin:-30,zmax:30,precision :{"w" : 2,"h" : 2},subdivisions:{"w" : sizex,"h" : sizez}
50 };
51 var heightp=(obj_p.zmax-obj_p.zmin)/sizez;//每一个小块的高度
52 var widthp=(obj_p.xmax-obj_p.xmin)/sizex;
53 obj_p.heightp=heightp;
54 obj_p.widthp=widthp;
55 mesh_tiledGround.obj_p=obj_p;//将地块的初始化参数记录下来
56
57 //认为行数从上向下延伸,列数从左向右延伸
58 for(var i=0;i
还是一行一行处理更好
60 var z=obj_p.zmax-(heightp*i+0.5*heightp);
61 var arr_rownodes=[];
62 for(var j=0;j