目前正在学习Cocos creator,版本是2.4.x
PS: 业余兴趣进行学习一下,体会一下做游戏的感受,而且逻辑语言也可以使用JS和TS进行编写
关于cocos creator和tiledMap的一些简单介绍可以参考:
Cocos Creator,这是一款游戏开发引擎。 Tiled,是一款可以用来绘制瓦片地图的工具。
本次学习的来源主要为: B站的视频
Cocos Creator使用Tiled地图
创建地图的步骤:
- 先划分好需要的地图层次,最底部是地面层。然后是地面上的装饰层,这些装饰玩家可以踩在上面。之后是对象层,玩家和一些可以交互的物体基本就位于这一层。再上一层可以是遮盖层,比如一些树,玩家经过可以被遮挡住。最上层可以是阻挡物层,玩家不可通过
地图层次 | 作用 |
---|
阻挡层 | 玩家不可通过,会产生碰撞 | 遮盖层 | 玩家可通过,但是会被遮盖住 | 对象层 | 玩家所在层 | 地面装饰层 | 玩家可通过,地面上可能会有一些花花草草,玩家可以踩在上面 | 地面层 | 玩家可通过,最基本的地面,玩家可以踩在上面 |
- 素材的话可以自己去寻找,本人是从爱给网上获取的。
- 先在Tiled 右侧的图层上建立好五层,中间是对象层,然后经过了一些时间的绘制,一张简单的分层地图就出现了。 中间的十字墓碑是之后玩家将要初始出现的地方
- 将创建好的tile地图拖到项目中,可以看到forestAndCity下面具有五层节点。
- 可以在playObj节点下添加一个单色精灵player作为之后要运动的玩家,上面挂在一个
playerControl 作为运动脚本。然后把这个精灵拖到下方资源文件夹中变成预设体prefab - 可以把canvas和camera的大小缩小,为了让之后的玩家运动起来后摄像机跟随运行看起来跟舒服
- 创建一个
newMapControl 脚本挂在到 forestAndCity节点 上面,用来获取Tiledmap地图
关于更多地图方法可参考:官方TiledMap的API
下面是newMapControl 的代码:(现在运行后,玩家就会出现在startPos 的位置上,并且摄像机也会跟随移动到此位置)
export default class newMapControl extends cc.Component {
map: cc.TiledMap;
player: cc.Node = null;
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 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 () {
let gp:cc.PhysicsManager = cc.director.getPhysicsManager();
gp.enabled = true;
var Bits = cc.PhysicsManager.DrawBits;
gp.debugDrawFlags = Bits.e_shapeBit;
}
在玩家的预设体上面也需要添加物理组件,并且将玩家的重力设置为0,否则会下落 效果:
- 设置当前的阻挡层刚体,现在地图的四周已经设置好了范围,玩家出不去了,但是阻挡层玩家还是可以通过。
因为阻挡层的形状变化过多,如果一个刚体一个刚体添加过于麻烦,所以可以通过分组来进行动态设置。 定义一个mapInit方法,用于动态生成刚体,并且对应的hinder 节点的anchor最好也调整成(0,0),
const {ccclass, property} = cc._decorator;
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);
body.type = cc.RigidBodyType.Static;
tiled.node.group = 'hinder';
tiled.node.groupIndex = groupIndex;
let collider = tiled.node.addComponent(cc.PhysicsBoxCollider);
collider.offset = cc.v2(tileSize.width/2, tileSize.height/2)
collider.size = tileSize;
collider.apply();
}
}
}
}
现在就出现了地图阻挡层的刚体了 之后可以把绘制调试区域隐藏,一个简单的TiledMap学习就到此结束了。
|