前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >CreatorPrimer|飞机大战(一)

CreatorPrimer|飞机大战(一)

作者头像
张晓衡
发布2019-09-11 18:01:22
1.3K0
发布2019-09-11 18:01:22
举报

前两天在Cocos官方公众号上学习了「大掌教」的Cocos Creator 2.x Camera教程,总算是对摄像机组件有了一个初步的认识,乘热打铁Shawn用Camera摄像机练习了一个飞机大战游戏,目前主要实现3个功能:

1.无限滚动背景 2.控制飞机移动 3.子弹发射

本次教程是图文+视频的超强组合

如果你对编写代码不感兴趣或怕看不明白,建议先现看下面视频

1. 无限滚动背景

滚动背景我们是使用最新的摄像机来实现,我这里做了一个卷轴摄像机组件ScrollCamera,我们先来看一下组件暴露的属性

ScrollCamera组件很像真实世界中的摄像机的推进器,Speed是推进速度,LoopGrounds是一个节点数组,他们是一组可首尾衔接的精灵节点

我们再看一下ScrollCamera组件的代码

代码语言:javascript
复制
cc.Class({
    editor: {
        requireComponent: cc.Camera,  //前置要求摄像机组件
    },
    extends: cc.Component,

    properties: {
        speed: 300,              //滚动速度
        loopGrounds: [cc.Node],  //循环节点
    },

    start () {
        //获取节点上的摄像机组件
        this.camera = this.getComponent(cc.Camera);
    },

    /**
    *每帧更新函数
    *1. 更新摄像机位置
    *2. 检查循环节点,设置新位置
    **/
    update(dt) {
        //获取当前节点
        let current = this.loopGrounds[0];
        //计算当前节点在摄像机中的位置
        let pt = this.camera.getWorldToCameraPoint(current.position);
        //当前节点超出摄像机范围(摄像机可视范围就是屏幕大小)
        if (pt.y <= -cc.winSize.height) {
            //取最后一个地图节点
            let last = this.loopGrounds[this.loopGrounds.length - 1];
            //将当前节点从数组中移除
            this.loopGrounds.shift();
            //将当前节点放到数组最后 
            this.loopGrounds.push(current);
            //将当前节点位置移动到最顶部位置
            current.y = last.y + (last.height + current.height) / 2;
        }
        //更新摄像机节点位置
        this.node.y += dt * this.speed;
    }
});

推动摄像机的代码很简单,update函数中的最后一行

代码语言:javascript
复制
this.node.y += dt * this.speed;

update中前面的几行代码是在做loopGrounds节点的检查和位置更新,每一行都注释的哦!这里就不再过多赘述。

直接将这个组件拖动到场景编辑器或层级管理器即可,设置background节点为background分组

同时设置ScrollCamera的cullingMask属性只勾选background,看下图

通过上面的设置和ScrollCamera的十几代码,无限滚动背景就搞定了。

2. 控制飞机移动

不知道大家还记得公众号之前的一篇文章《Cocos Creator基础教程(11)—可拖拽组件》

我直接将Dragable.js组件脚本拿过来,挂载到飞机节点上就OK了,代码很简单

代码语言:javascript
复制
/**
 * 可拖动组件
 */
cc.Class({
    extends: cc.Component,

    onLoad() {
        //注册TOUCH_MOVE事件
        this.node.on(cc.Node.EventType.TOUCH_MOVE, this._onTouchMove, this);
        cc.log('onload');
    },

    _onTouchMove(touchEvent) {
        //let location = touchEvent.getLocation();
        //this.node.position = this.node.parent.convertToNodeSpaceAR(location); 

        //获取触摸移动增量
        let delta = touchEvent.getDelta();
        //当前节点位置+增量,更新节点位置
        this.node.position = delta.add(this.node.position);
    }
});

Shawn在做这个飞机游戏过程中,尝试了消灭病毒当下这个火热的游戏,他的整个屏幕任意位置都可以控制飞机移动,它是怎么做的呢?大家先可以想一下自己的方案...

我这里的方案是修改一下Dragable组件,增加一个target节点属性,将它从飞机节点上移到外层foreground节点,看下图

触摸事件发生在foreground节点上,但移动的是target属性所指向的节点,看下面代码

代码语言:javascript
复制
/**
 * 可拖动组件
 */
cc.Class({
    extends: cc.Component,
    properties: {
        target: cc.Node,
    },
    ...
    _onTouchMove(touchEvent) {
        //获取触摸移动增量
        let delta = touchEvent.getDelta();
        //如果this.target未设置,使用移动当前节点(兼容之前的用法)
        let node = this.target || this.node;
        //当前节点位置+增量,更新节点位置
        node.position = delta.add(node.position);
    }
});

代码就增加了一个target节点的定义,在TouchMove事件中检查this.target存在就用它,不存在默认移动当前节点,这样可以兼容曾经该组件的地方,不用做修改。

3. 子弹发射

飞机游戏的一个亮点就是子弹发射的华丽视觉效果,Shawn在网上找了些子弹特效图片。

我们编辑一个子弹Bullet的预制体,这里使用到之前文章《Cocos Creator基础教程(12)—精灵变身》中的SpriteEx.js组件

在SpriteEx上面配置了几张子弹图片,使用index属性可以方便切换子弹的表现效果

Bullet子弹只是表现效果,要让子弹运动起来,我这里编写了一个LineEmmiter.js(线性发射器)的脚本

将它挂载到飞机节点上,用它来实例化Bullet预制体并让它动起来,先看一下LineEmmiter组件的属性:

之前的文章中提到过:组件为节点赋予能力

飞机节点上有一个Sprite可显示图片纹理

我们再挂上LineEmmiter组件,让它具有发射子弹的能力。

发射器的主要属性是子弹预制体、发射频率、子弹飞行速度

OffsetX属性要特别一点,它可以控制子弹与飞机的偏移位置,以实现同时发射多行子弹的效果,看下图

我们再看发射器组件代码

代码语言:javascript
复制
cc.Class({
    extends: cc.Component,

    properties: {
        prefab: cc.Prefab,
        rate: 1,        //发射间隔
        speed: 1000,    //移动速度
        offsetX: 0,
    },

    start() {
        this.schedule(this._emmitNode, this.rate);
    },

    _emmitNode() {
        //实例化节点,设置位置&父节
        let node = cc.instantiate(this.prefab);
        node.position = this.node.position;
        node.x += this.offsetX;
        node.parent = this.node.parent;
        //计算子弹需要飞行的距离,飞行时间 = 距离 / 速度
        let distance = ((cc.winSize.height / 2) - this.node.y);
        let duration = distance / this.speed;
        //使用moveBy动作,完成后删除子弹节点
        let moveBy = cc.moveBy(duration, cc.v2(0, distance));
        let removeSelf = cc.removeSelf();
        let sequence = cc.sequence(moveBy, removeSelf);
        node.runAction(sequence);    
    }
});

发射器代码也很简单

1.创建子弹

2.让子弹飞

我们这里子弹是垂直飞行的,直接使moveBy动作就可以完成

子弹从当前飞机节点出发直到屏幕顶部结束

公式:距离/速度=时间

计算每颗子弹的飞行时间,保证飞机在不同位置,所有子弹都是按同样的速度飞行。

4. 小结

本次教程我们实现了一个最小飞机游戏的简单原型

核心地图滚动与子弹发射代码只有70多行,有没有觉得使用Cocos Creator开发游戏飞一般的简单呢...

不过还有很多欠缺的地方

比如:限制飞机不要跑出屏幕之外、子弹应该使用内存池进行优化

在功能上还缺少敌机生成、少子弹碰撞、得分计算等等,这些内容我们留到下次继续。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-05-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Creator星球游戏开发社区 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 无限滚动背景
  • 2. 控制飞机移动
  • 3. 子弹发射
  • 4. 小结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档