IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> Cocos Creator学习のTiledMap -> 正文阅读

[游戏开发]Cocos Creator学习のTiledMap

目前正在学习Cocos creator,版本是2.4.x

PS: 业余兴趣进行学习一下,体会一下做游戏的感受,而且逻辑语言也可以使用JS和TS进行编写

关于cocos creatortiledMap的一些简单介绍可以参考:

Cocos Creator,这是一款游戏开发引擎。 Tiled,是一款可以用来绘制瓦片地图的工具。

本次学习的来源主要为: B站的视频

Cocos Creator使用Tiled地图

创建地图的步骤:

  1. 先划分好需要的地图层次,最底部是地面层。然后是地面上的装饰层,这些装饰玩家可以踩在上面。之后是对象层,玩家和一些可以交互的物体基本就位于这一层。再上一层可以是遮盖层,比如一些树,玩家经过可以被遮挡住。最上层可以是阻挡物层,玩家不可通过
地图层次作用
阻挡层玩家不可通过,会产生碰撞
遮盖层玩家可通过,但是会被遮盖住
对象层玩家所在层
地面装饰层玩家可通过,地面上可能会有一些花花草草,玩家可以踩在上面
地面层玩家可通过,最基本的地面,玩家可以踩在上面
  1. 素材的话可以自己去寻找,本人是从爱给网上获取的。
    在这里插入图片描述
  2. 先在Tiled 右侧的图层上建立好五层,中间是对象层,然后经过了一些时间的绘制,一张简单的分层地图就出现了。 中间的十字墓碑是之后玩家将要初始出现的地方
    在这里插入图片描述
  3. 将创建好的tile地图拖到项目中,可以看到forestAndCity下面具有五层节点。
    在这里插入图片描述
  4. 可以在playObj节点下添加一个单色精灵player作为之后要运动的玩家,上面挂在一个playerControl作为运动脚本。然后把这个精灵拖到下方资源文件夹中变成预设体prefab
    在这里插入图片描述
  5. 可以把canvas和camera的大小缩小,为了让之后的玩家运动起来后摄像机跟随运行看起来跟舒服
    在这里插入图片描述
  6. 创建一个newMapControl脚本挂在到 forestAndCity节点 上面,用来获取Tiledmap地图

关于更多地图方法可参考:官方TiledMap的API

下面是newMapControl的代码:(现在运行后,玩家就会出现在startPos的位置上,并且摄像机也会跟随移动到此位置)

export default class newMapControl extends cc.Component {
    //  获取瓦片图资源
    map: cc.TiledMap;
    player: cc.Node = null;
    // onLoad () {}
    start () {
        this.map = this.getComponent(cc.TiledMap);
        // 获取指定的对象层 
        let playerObj = this.map.getObjectGroup('playObj');
        // 获取对象
        let playerStartPos = playerObj.node.getChildByName("startPos");
        // 在开始位置创建玩家对象
        // 加载资源
        cc.resources.load('prefab/tilemap/player', cc.Prefab,  (err, playerPre)=> { 
            // 实例化预设体
            this.player = cc.instantiate(playerPre);
            this.player.setParent(this.node.getChildByName('playObj'));
            
            // // // 设置玩家位置
            this.player.x= playerStartPos.x;
            this.player.y = playerStartPos.y;
        })
    }
    update (dt) {
        // 摄像头跟随玩家
        if (this.player != null) {
            cc.Camera.main.node.x = this.player.x;
            cc.Camera.main.node.y = this.player.y;
        }
    }
}

效果:
在这里插入图片描述
8. 然后封装一个移动的ts文件,取名为moveInput,对应按键按下,横轴竖轴上运动方向改变。

const {ccclass, property} = cc._decorator;
// 封装移动方向
// 单例模式
export default class moveInput{
    private static instance: moveInput = null;
    // 水平轴
    horizontal: number = 0;
    // 垂直轴
    vertical: number = 0;
    static Instance() {
        if (!this.instance) { this.instance = new moveInput(); }
        return this.instance;
    };
    // 通过private修饰符,让类无法在外部创建新的实例
    private constructor() { 
        // 键盘按下
        cc.systemEvent.on(cc.SystemEvent.EventType.KEY_DOWN, (event)=>{
            switch(event.keyCode) {
                case cc.macro.KEY.w: this.vertical = 1; break;
                case cc.macro.KEY.s: this.vertical = -1; break;
                case cc.macro.KEY.a: this.horizontal = -1; break;
                case cc.macro.KEY.d: this.horizontal = 1; break;
            }
        })
        // 键盘抬起
        cc.systemEvent.on(cc.SystemEvent.EventType.KEY_UP, (event)=>{
            switch(event.keyCode) {
                case cc.macro.KEY.w: if(this.vertical == 1) this.vertical = 0; break;
                case cc.macro.KEY.s: if(this.vertical == -1) this.vertical = 0; break;
                case cc.macro.KEY.a: if(this.horizontal == -1) this.horizontal = 0; break;
                case cc.macro.KEY.d: if(this.horizontal == 1) this.horizontal = 0; break;
            }
        })
    }
}

这样只需要在playerControl玩家运动脚本中进行控制即可,记得要import导入moveInput。这里的speed速度我设置了一百。

ps: 如果想让玩家每秒移动设置的速度,需要乘dt

update (dt) {
    // 移动
    this.node.x += this.speed * dt * moveInput.Instance().horizontal;
    this.node.y += this.speed * dt * moveInput.Instance().vertical;
}

当前效果(因为博客图片大小限制,这里我剪了一些帧数):
在这里插入图片描述
9. 但是这里会发现,虽然隐藏层已经实现了,但是阻挡层并没有阻挡物体,并且物体也可以超出界面之外。所以要开启物理系统。在newMapControl中代码开启,并且在节点上也可以添加四周边框。注意: 地图的刚体类型要选为静止,否则会掉下去

onLoad () {
    // getPhysicsManager物理管理器
    let gp:cc.PhysicsManager = cc.director.getPhysicsManager();
    gp.enabled = true;
    // 绘制调试区域
    var Bits = cc.PhysicsManager.DrawBits;
    gp.debugDrawFlags = Bits.e_shapeBit;
}

在这里插入图片描述

在玩家的预设体上面也需要添加物理组件,并且将玩家的重力设置为0,否则会下落
在这里插入图片描述
效果:
在这里插入图片描述

  1. 设置当前的阻挡层刚体,现在地图的四周已经设置好了范围,玩家出不去了,但是阻挡层玩家还是可以通过。
    因为阻挡层的形状变化过多,如果一个刚体一个刚体添加过于麻烦,所以可以通过分组来进行动态设置。
    在这里插入图片描述
    定义一个mapInit方法,用于动态生成刚体,并且对应的hinder节点的anchor最好也调整成(0,0),
const {ccclass, property} = cc._decorator;
// 动态生成地图刚体 name: 需要生成刚体的层次名字, groupIndex: 分组index  tileMap: 地图
export default function mapInit(name: string, groupIndex:number, tileMap: cc.TiledMap) {
    let tileSize = tileMap.getTileSize();  // 地图小块尺寸 
    let layer:cc.TiledLayer = tileMap.getLayer(name);  // 得到阻挡层
    let layerSize = layer.getLayerSize();  // 得到阻挡层尺寸

    for(let i = 0; i < layerSize.width; i++) {
        for (let j = 0; j < layerSize.height; j++) {   
            let tiled:cc.TiledTile = layer.getTiledTileAt(i, j, true);  // 拿到小块
            // 如果元素存在
            if (tiled.gid != 0) {
                let body:cc.RigidBody = tiled.node.addComponent(cc.RigidBody);  // 动态添加RigidBody刚体
                body.type = cc.RigidBodyType.Static;  // 设置为静态,防止下落
                tiled.node.group = 'hinder'; // 将这个节点设置为wall
                tiled.node.groupIndex = groupIndex;  // 设置节点的groupIndex
                
                let collider = tiled.node.addComponent(cc.PhysicsBoxCollider); // 添加碰撞区域
                
                collider.offset = cc.v2(tileSize.width/2, tileSize.height/2)  // 设置偏移量, 除2是为了拿到中心点
                collider.size = tileSize; //包围盒的大小
                collider.apply();  //回调
            }
        }
    }
}

现在就出现了地图阻挡层的刚体了
在这里插入图片描述
之后可以把绘制调试区域隐藏,一个简单的TiledMap学习就到此结束了。

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2022-02-28 15:58:02  更:2022-02-28 15:58:52 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/27 16:42:39-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码