【Cocos Creator实战教程(3)】——炸弹人(TiledMap相关)

制作地图

Tiled Map Editor的基本使用参考我之前写的一篇文章
http://blog.csdn.net/potato47/article/details/51366481

1.新建19x19的地图,Tile大小32x32,导入图块资源

2.建立三个图层(ground,hide,main)和一个对象层(objects)
ground是背景层,用绿色的草坪图块填充满
这里写图片描述
hide是道具层,挑选道具图块(包括出口的门)放在几个位置
这里写图片描述
main是障碍物层,还原经典炸弹人的地图布局,每隔一个位置放一个钢块,用土块覆盖道具层的道具,在其他位置再放几个土块
这里写图片描述
objects层有两个对象(player,enemy)标记玩家和敌人的位置信息
最终效果如图
这里写图片描述
3.将除了草坪图块的其他图块添加type属性,属性值分别为,soil(土块),steel(钢块),door(门),prop1(道具1)。。。
这里写图片描述
4.保存地图文件和图集文件放在一起

绑定地图

1.新建工程Bomberman,将所需资源全部导入,项目结构如下(有些是后来添加的)
这里写图片描述
2.将地图拖入场景(自动生成map和layer节点),将锚点改为(0,0),下面出现的player等节点也都是00为锚点
3.新建脚本game.js添加为map节点组件,声明全局变量,在属性面板中拖入相关层节点
4.在脚本中添加地图加载方法loadMap

properties: {
    map:{
        default:null,
        type:cc.TiledMap,
    },
    hideLayer:{
        default:null,
        type:cc.TiledLayer,
    },
    mainLayer:{
        default:null,
        type:cc.TiledLayer,
    },
}

这里写图片描述

虚拟手柄

1.我们准备了上下左右炸弹五个按钮的原始状态和按下状态共十张图片素材,在场景编辑器中看着顺眼的地方摆放这五个按钮(将label删除),并将按钮的相应状态的按钮图片添加到右侧属性面板中
2.为每个按钮添加点击事件,(map->game->btnBomb,btnUp,btnDown,btnLeft,btnRight)
这里写图片描述

炸弹动画

1.将炸弹图片集中的任意一个拖入场景中,将其宽高改为32x32,再拖回资源管理器中制作一个炸弹的prefab bomb,为其添加Animation组件
2.新建炸弹爆炸动画clip explode,拖入bomb的属性面板
3.在动画播放完成的最后一帧加入一个帧事件,响应事件方法名为exploded
这里写图片描述
这里写图片描述
4.新建炸弹脚本bomb.js添加到炸弹prefab节点上

cc.Class({
    extends: cc.Component,

    properties: {

    },

    onLoad: function () {

    },

    exploded: function(){
        this.node.parent.emit('exploded');//向父节点发射一个事件  
    },

});

主角和敌人

1.添加player和enemy为map节点的两个子节点,锚点0,0,大小32x32
(位置随意,一会我们要在代码中动态设置他们的位置)
这里写图片描述

游戏逻辑

game.js

/*
*博客原文:blog.csdn.net/potato47
*教程更新提醒微信公众号:xinshouit
*/

var DIR = cc.Enum({
    UP : 0,
    RIGHT : 1,
    DOWN : 2,
    LEFT : 3
});

cc.Class({
    extends: cc.Component,

    properties: {
        bombPrefab:{
            default:null,
            type:cc.Prefab,
        },
        player:{
            default:null,
            type:cc.Node,
        },
        enemy:{
            default:null,
            type:cc.Node,
        },
        map:{
            default:null,
            type:cc.TiledMap,
        },
        hideLayer:{
            default:null,
            type:cc.TiledLayer,
        },
        mainLayer:{
            default:null,
            type:cc.TiledLayer,
        },
    },

    onLoad: function () {
        let self = this;
        this.node.on('exploded', function () {
            //这里判断炸弹的四个方向的物体是否可以炸毁,为了简便,这里只判定能炸毁的墙
            if(self.getTileType(self.mainLayer, cc.p(self.bombTile.x,self.bombTile.y-1)) == 'soil')
            {
                self.mainLayer.removeTileAt(cc.p(self.bombTile.x,self.bombTile.y-1));
            }
            if(self.getTileType(self.mainLayer, cc.p(self.bombTile.x,self.bombTile.y+1)) == 'soil')
            {
                self.mainLayer.removeTileAt(cc.p(self.bombTile.x,self.bombTile.y+1));
            }
            if(self.getTileType(self.mainLayer, cc.p(self.bombTile.x-1,self.bombTile.y)) == 'soil')
            {
                self.mainLayer.removeTileAt(cc.p(self.bombTile.x-1,self.bombTile.y));
            }
            if(self.getTileType(self.mainLayer, cc.p(self.bombTile.x+1,self.bombTile.y)) == 'soil')
            {
                self.mainLayer.removeTileAt(cc.p(self.bombTile.x+1,self.bombTile.y));
            }
            self.node.removeChild(self.bomb);
        });


    },
    btnUp: function(){
        this.playerDir = DIR.UP;
        var playerTarTile = cc.p(this.playerTile.x, this.playerTile.y - 1);
        this.tryMoveToTarTile(playerTarTile);
    },
    btnDown: function(){
        this.playerDir = DIR.DOWN;
        var playerTarTile = cc.p(this.playerTile.x, this.playerTile.y + 1);
        this.tryMoveToTarTile(playerTarTile);
    },
    btnLeft: function(){
        this.playerDir = DIR.LEFT;
        var playerTarTile = cc.p(this.playerTile.x - 1, this.playerTile.y);
        this.tryMoveToTarTile(playerTarTile);
    },
    btnRight: function(){
        this.playerDir = DIR.RIGHT;
        var playerTarTile = cc.p(this.playerTile.x + 1, this.playerTile.y);
        this.tryMoveToTarTile(playerTarTile);
    },
    btnBomb: function(){
        this.bomb = cc.instantiate(this.bombPrefab);
        this.bombTile = this.playerTile;
        this.bomb.setPosition(this.mainLayer.getPositionAt(this.bombTile));
        this.node.addChild(this.bomb);
    },
    tryMoveToTarTile: function(newTile) {
        //检测mainLayer是否可以通过
        if (this.mainLayer.getTileGIDAt(newTile)) {//tile不为空,返回
            cc.log('This way is blocked!');
            return false;
        }
        //检测是否与敌人碰撞
        if(cc.pointEqualToPoint(this.playerTile, this.enemyTile)){
            cc.log('Touch enemy,you lose!');
            return false;
        }

        this.playerTile = newTile;
        this.updatePlayerPos();

        if(this.getTileType(this.hideLayer,this.playerTile) == 'door')
        {
            cc.log('you win');
        }
    },
    //获得tile的type属性值
    getTileType:function(layer,tile){
        var prop = this.map.getPropertiesForGID(layer.getTileGIDAt(tile));
        if(prop)
            return prop.type;
        else
            return null;
    },
    //将地图中的像素单位坐标转化为瓦片单位坐标
    getTilePos: function(posInPixel) {
        var mapSize = this.node.getContentSize();
        var tileSize = this.map.getTileSize();
        var x = Math.floor(posInPixel.x / tileSize.width);
        var y = Math.floor((mapSize.height - posInPixel.y) / tileSize.height);
        return cc.p(x, y);
    },
    loadMap: function(){
        //获取对象层
        var objects = this.map.getObjectGroup('objects');
        //获取对象
        var playerObj = objects.getObject('player');
        var enemyObj = objects.getObject('enemy');
        //获取坐标
        var playerPos = cc.p(playerObj.x,playerObj.y);
        var enemyPos = cc.p(enemyObj.x,enemyObj.y);
        //设置玩家和敌人瓦片坐标
        this.playerTile = this.getTilePos(playerPos);
        this.enemyTile = this.getTilePos(enemyPos);
        //设置敌人位置
        var pos2 = this.mainLayer.getPositionAt(this.enemyTile);
        this.enemy.setPosition(pos2);
        this.enemyDir = DIR.RIGHT;
        //更新玩家位置
        this.updatePlayerPos();
        this.playerDir = DIR.DOWN;
    },

    updatePlayerPos: function() {
        var pos = this.mainLayer.getPositionAt(this.playerTile);
        this.player.setPosition(pos);

    },
    update: function (dt) {
        //简单怪物逻辑
        if(this.enemyDir == DIR.RIGHT){
            this.enemy.x++;
            if(this.enemy.x>544){
                this.enemyDir = DIR.LEFT;
            }
        }else{
            this.enemy.x--;
            if(this.enemy.x<32){
                this.enemyDir = DIR.RIGHT;
            }
        }
        if(cc.pDistance(this.player.getPosition(),this.enemy.getPosition())<32){
            cc.log("you lose");
        }
    },
});

最终效果:

这里写图片描述

资源以及工程源码:http://download.csdn.net/download/potato47/9520745

转载请保留原文链接:blog.csdn.net/potato47
教程更新微信提醒公众号:xinshouit

评论 20
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值