地图编辑器开发(二)

系列教程:

  1. 地图编辑器开发(一)加载地图
  2. 地图编辑器开发(二)编辑地图
  3. 地图编辑器开发(三)测试阻挡
  4. 地图编辑器开发(四)导出阻挡信息
  5. 地图编辑器开发(五)导出地图资源

上一节已经把地图加载到游戏中了,这一节主要实现地图的编辑能功能,也是地图编辑器最主要的功能,可以拆分为如下几个功能:

  1. 地图滚动
  2. 地图缩放
  3. 画网格
  4. 编辑格子信息

地图滚动

上一节中加载进来的地图,只显示了地图的一部分,要能编辑整个地图,需要地图能够滚动。因此需要将地图 sprite 放入到一个 ScrollView 中,设置水平和竖直方向都能滚动,删除滚动条,防止挡住地图,如图:

滚动
运行结果如下图:
drag
这样地图就滚动了,按住鼠标就能拖动地图。但是还有问题,窗口显示的范围并没有变大,希望能通过缩放,在窗口中显示更多的内容。

地图缩放

在工具栏上,放一个滑块,用于控制地图的缩放比例。监听滑块值变化,在响应函数中,调整地图的宽高。scale
实现效果如上图所示,核心代码如下:

onScaleChange(slider) {
    this.mapScale = slider.progress;
    // 显示地图宽高
    this.mapW = this.oriW * this.mapScale;
    this.mapH = this.oriH * this.mapScale;
    this.ndSvContent.width = this.mapW;
    this.ndSvContent.height = this.mapH;
},

画网格

A星寻路都是以格子为单位,因此需要将地图划分成很多小格子,然后才能编辑每个格子的数据。Cocos Creator 提供了一个 画图组件,就用这个组件来画网格。在编辑器中,创建一个 Graphic组件,作为地图spMap的子节点,这样格子才会随着地图一起缩放和移动。

为了方便查看,让格子和地图都可以隐藏和显示,在界面上加上复选框。另外,在设置界面中,可以设置格子的大小。做好之后如图:
tool

setting
ui都编辑好之后,就可以写代码实现画格子了。

drawGrid() {
    this.gphPath.strokeColor = this.colorGrid;
    this.gphPath.lineWidth = 1;
    let cnt_w = Math.floor(this.mapW / this.cellW);
    for (let i = 1; i < cnt_w; i++) {
        let x = this.cellW * i;
        this.gphPath.moveTo (x, 0)
        this.gphPath.lineTo (x, this.mapH);
    }

    let cnt_h = Math.floor(this.mapH / this.cellH);
    for (let i = 0; i < cnt_h; i++) {
        let y = this.cellH * i;
        this.gphPath.moveTo (0, y)
        this.gphPath.lineTo (this.mapW, y);
    }

    this.gphPath.stroke();
},

运行可以看到地图已经被划分成了很多小格子,如图:
grid

编辑格子

格子划分好之后,以格子为单位编辑,可以将格子设置阻挡状态,遮罩状态,或者删除已设置的状态,除此之外,鼠标还要完成拖动操作。根据前面的分析,将鼠标分为4种状态,这4种状态是不可以叠加的,可以使用单选框来实现,当修改单选框的值时,更新鼠标的状态。如图:
tool

  1. 当鼠标状态处于拖动状态时,将 ScrollView 设置为可以滚动,其他状态禁止滚动,避免编辑格子时,地图跟着滚动。
  2. 当鼠标处理其他阻挡状态时,获取鼠标所在的格子,然后其状态改为阻挡状态,用红色表示;
  3. 当鼠标处理其他遮罩状态时,获取鼠标所在的格子,然后其状态改为遮罩状态,用蓝色表示;
  4. 当鼠标处理其他清除状态时,获取鼠标所在的格子,然后其状态改为默认状态;
  5. 最后根据格子的状态信息,绘制阻挡和遮罩。

用代码实现上述过程:

onLoad(){
	this.ndSvContent.on(cc.Node.EventType.TOUCH_START, (event) => {
	    this.udpatePosSt(event);
	}, this);
}

udpatePosSt(event) {
    let pos = this.getCellPosByEvent(event);
    if (pos[0] < 0 || pos[0] >= this.blockInfoList.length ||
        pos[1] < 0 || pos[1] >= this.blockInfoList[0].length) {
        return;
    }
    switch(this.mouseOp) {
        case 0:
            break;
        case 1:
            this.blockInfoList[pos[0]][pos[1]] = 1;
            break;
        case 2:
            this.blockInfoList[pos[0]][pos[1]] = 2;
            break;
        case 3:
            this.blockInfoList[pos[0]][pos[1]] = 0;
            break;
        default:
            break;
    }
},

drawBlockMask() {
    for (let x = 0; x < this.blockInfoList.length; x++) {
        let xList = this.blockInfoList[x];
        for (let y = 0; y < xList.length; y++) {
            let st = xList[y];
            if (st) {
                this.gphPath.rect(x * this.cellW, y * this.cellH, this.cellW, this.cellH);
                this.gphPath.fillColor = st == 1 ? this.colorBlock : this.colorMask;
                this.gphPath.fill();
            }
        }
    }
},

运行结果:
edit
这样编辑器基本上就可以使用了,下一节基于当前编辑的信息,实现一个A星寻路算法,测试当前的地图阻挡信息。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值