cocos creator 笔记-小地图

版本:3.7.4

一、3d小地图

用RenderTexture实现Sprite版小地图和炫酷的传送门 - Creator 3.x - Cocos中文社区

按照官方论坛示例构建一个3d小地图,其实就是在人物上添加一个俯视的摄像头节点,然后将内容输出到一个Sprite上,作为内容展示,按照实际内容调整 摄像机 的Ortho Height和Near参数。

优点:很简单就可以实现,并且能保留场景原本色彩。

缺点:当人物上有模型遮挡时无法体现,还有就是因为是3d摄像机投影实现的,所以性能影响较大,以我的测试场景为例,使用后Drawcall数值增加200左右。

二、2d小地图

首先先快速制作小地图图片资源,在3d设计软件(blender)中打开建筑场景,使用俯视视角,打开透视,直接截图即可,比如如下:

小地图目录结构如下

 

首先创建一个Mask遮罩,mapMask就是遮罩,大小为小地图要展示的大小,给mapres的Sprite指定资源为上面的小地图,按照实际需要设置大小,比如 500*500。为了体现小地图在屏幕的范围,创建一个Sprite为board,资源是一张四周有1px 细线的透明图片,大小和mapMask一致,point为图标指针,为了清晰表示人物方向及位置。

效果如下:

创建一个ts脚本,绑定到这个预制资源的最上层节点,我的内容如下:

@ccclass('Map2dDataController')
export class Map2dDataController extends Component {

    @property({ type: String, displayName: '目标对象名称' })
    nodeName: string = '';

    @property({ type: SpriteFrame, displayName: '2d底图资源' })
    mapImage: SpriteFrame
    //目标对象
    person: Node = null

    //当前位置,包含预设
    now_2d_position = { x: -3, y: 295 }
    //上一个点的位置
    last_2d_position = this.now_2d_position

    //上一个点的位置
    last_3d_position = { x: 0, y: 0 }

    //地图sprite
    sp: Node = null
    //自身指针
    point: Node = null

    //3d对象转换为2d对象倍率
    vary = { x: -9.91, y: 13.57 }
    start() {
        if (!this.mapImage) {
            return
        }
        this.sp = this.node.getChildByName('canvas').getChildByName('mapMask').getChildByName('mapres')
        this.sp.getComponent(Sprite).spriteFrame = this.mapImage

        this.point = this.node.getChildByName('canvas').getChildByName('board').getChildByName('point')

        if (!this.nodeName) {
            this.nodeName = RoleListUtil.getList()[0].code
        }
        //展示的数据
        this.person = find(RoleListUtil.roleBasePath + this.nodeName)
        this.sp.setPosition(new Vec3(this.now_2d_position.x, this.now_2d_position.y, 0))
        this.last_3d_position = { x: this.reduceNumber(this.person.getPosition().x), y: this.reduceNumber(this.person.getPosition().z) }
    }

    update() {
        if (this.sp) {
            this.positionHandle()
        }
        if (this.point) {
            let rota = new Vec3()
            this.person.getRotation().getEulerAngles(rota)
            this.point.setRotationFromEuler(new Vec3(0, 0, rota.y + 180))
        }
    }


    positionHandle() {
        let x = this.reduceNumber(this.person.getPosition().x)
        let y = this.reduceNumber(this.person.getPosition().z)
        /**
         * 如果 3d 位置, 上一点和当前点位置相同,不执行小地图位置移动
         */
        if (x == this.last_3d_position.x && y == this.last_3d_position.y) {
            return
        }
        // 计算移动位置并赋值
        this.now_2d_position = {
            x: this.reduceNumber(this.last_2d_position.x + (x - this.last_3d_position.x) * this.vary.x),
            y: this.reduceNumber(this.last_2d_position.y + (y - this.last_3d_position.y) * this.vary.y)
        }
        console.log(this.now_2d_position)
        this.sp.setPosition(new Vec3(this.now_2d_position.x, this.now_2d_position.y, 0))
        //记录当前2d坐标为上一点坐标
        this.last_2d_position=this.now_2d_position
        //记录下当前3d点坐标为上一点坐标
        this.last_3d_position = { x: x, y: y }
    }

    reduceNumber(num: number): number {
        return Number(num.toFixed(2))
    }
}

这里 now_2d_position 位置为需要将人物初始化到的2d地图点,vary为3d到2d的移动倍率(需要按照实际进行计算)。

计算过程如下:

当前2d点为=当前2d点坐标+3d点移动差值*倍率

倍率获取需要调试,分别选取3d和2d的左上角和右下角的四组点,将获取的点代入上述公式计算。

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

暮雪...

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值