基于CocosCreator的切水果小游戏(一)

刚接触CocosCreator,写个小游戏练练手,熟悉一下cocos creator。

水果忍者的游戏,逻辑部分应该还是比较简单的,主要应该就涉及到水果的运动、分开,刀光效果等等。

CocosCreator版本是2.1.2,相关图片资源来源于网上。

首先先做一下主界面,以及刀光的制作。完成后大概像这个样子:

首先创建场景start,并且拖动相应的图片放进去做为Canvas下的子节点,这里面水果和炸弹应当需要制作成预制体(prefab)的形式,方便之后继续调用。

接下来写脚本,创建start.js,并写上相应的逻辑。

properties: {
        // 这里是一些背景图片、logo等等
        home_mask:{
            default: null,
            type: cc.Node
        },
        logo:{
            default: null,
            type: cc.Node
        },
        ninja:{
            default: null,
            type: cc.Node
        },
        home_desc:{
            default: null,
            type: cc.Node
        },
        background:{
            default: null,
            type: cc.Node
        },
        
        // 这里是下面的那三个东西
        dojo: {
            default: null,
            type: cc.Node
        },
        // 这里刚开始写的时候直接把水果作为节点引用进去了。
        peach: {
            default: null,
            type: cc.Node
        },
        new_game: {
            default: null,
            type: cc.Node
        },
        sandia: {
            default: null,
            type: cc.Node
        },
        quit_game: {
            default: null,
            type: cc.Node
        },
        boom: {
            default: null,
            type: cc.Node
        },
        knife_part: {
            default: null,
            type: cc.Prefab
        },
       
        // 刀光相关
        pooled_knifves: [],
        num_pooled_knifves: 10,
        knife_width: 10,
        knife_height: 10,

        _rotation: 0.7,

        // 水果预制体
        peach_prefab:{
            default: null,
            type: cc.Prefab
        },
        peach_part_1: {
            default: null,
            type: cc.Prefab
        },
        peach_part_2: {
            default: null,
            type: cc.Prefab
        },
        sandia_prefab:{
            default: null,
            type: cc.Prefab
        },
        sandia_part_1: {
            default: null,
            type: cc.Prefab
        },
        sandia_part_2: {
            default: null,
            type: cc.Prefab
        },
},
        

        

刚开始做的时候,直接把下面的水果和炸弹作为节点引用进去了,其实可以直接用prefab,当然效果没有什么变化。

在update函数中,让他们旋转就行了。

update (dt) {
        
        this.dojo.angle = (this._rotation); 
        this.peach.angle = -this._rotation;
        this.new_game.angle = (-this._rotation); 
        this.sandia.angle = this._rotation;
        this.quit_game.angle = (-this._rotation); 
        
        
        this._rotation++;
        // cc.log(this.node);

    },

接下来,就是刀光的制作部分了。我这里的逻辑实现是,滑动时产生的刀光,应当是由多个相同的“刀身”组成的,也就是由一小段一小段组成起来的,每一小段的刀的长度,随着时间递减,这样就形成一种滑过的轨迹效果。当然,cocos creator里似乎MotionStreak这个组件也能实现一样的效果,性能方面应该也会更好一点。不过我这里就单纯是用这种逻辑来写的。

简单的创建一个刀的prefab,不需要太长,只要一小段就行。接下来,写刀的脚本knife.js

cc.Class({
    extends: cc.Component,

    properties: {
        color: "#cbd3db",
        life: 0.2,
        isActivate: true,
        width: 10,
        height: 10,
    },

    // LIFE-CYCLE CALLBACKS:

    onLoad () {
        this.node.color = new cc.Color().fromHEX(this.color);
        // cc.log(this.node.color);
    },

    start () {
        
    },

    set() {

    },

    resetProperties(){
        this.color = "#cbd3db";
        this.life = 0.2;
        this.isActivate = true,
        this.width = 10;
        this.height = 10;
        this.node.width = this.width;
        this.node.height = this.height;
        this.node.angle = 0;
    },

    update (dt) {

        if(!this.isActivate){
            this.life -= dt;
            if(this.node.width > 0){
                this.node.width -= dt / this.life * this.width;
            }
            
        }
        // cc.log(this.node.width,this.node.height);
        
    },
});

主要就是给它设置一个颜色和一个显示时间(life),在update中让它随着时间改变长度而已。最后还要记得在刀的prefab中添加脚本组件,并把knife.js拖进去。

就像前面说的滑动的刀光需要有很多段knife组成,因此,将它作为一个对象池去写。cocos里面好像已经有个poolnode的对象池了,这里我是自己手写的。

在start.js中,添加从对象池中获取knife的方法:

getPooledKnife(){
        
        for(let i=0; i<this.num_pooled_knifves; i++){
            if(this.pooled_knifves[i].getComponent('knife').isActivate){
                this.pooled_knifves[i].getComponent('knife').isActivate = false;
                return this.pooled_knifves[i];
            }
        }
        
        let new_knife = cc.instantiate(this.knife_part);
        this.pooled_knifves.push(new_knife);
        new_knife.getComponent('knife').isActivate = false;
        this.num_pooled_knifves++;
        return new_knife;
    },

并且在onload里面初始化pool knife,同时需要添加监听事件:

onload(){

    //...

    for(let i=0;i<this.num_pooled_knifves;i++){
            this.pooled_knifves.push(cc.instantiate(this.knife_part));
        }

    //...
    this.node_h = this.node.height;
    this.node_w = this.node.width;
    this.node.on(cc.Node.EventType.TOUCH_START, this.onTouchStart, this, true);
    this.node.on(cc.Node.EventType.TOUCH_MOVE, this.onTouchMove, this, true);

    //...
}

TouchStart 触摸开始方法:

onTouchStart(event){
        
        //if(!this.last_event_id)
            //this.last_event_id = event.getID();
        
        this.prev_pos = event.getLocation();
        this.sx = event.getLocationX();
        this.sy = event.getLocationY();
        
        let knife_part = this.getPooledKnife();
        this.node.addChild(knife_part);
        knife_part.setPosition(this.sx-this.node_w/2,this.sy-this.node_h/2);
      
    },

TouchMove 触摸移动方法:

onTouchMove(event){
        
        this.curent_pos = event.getLocation();
        this.ex = event.getLocationX();
        this.ey = event.getLocationY();
        
        let lenV = this.curent_pos.sub(this.prev_pos).mag(); 
        

        if(lenV > this.knife_height){
            let tempVec = cc.v2(0,10)
            let roateV = this.curent_pos.sub(this.prev_pos).signAngle(tempVec) / Math.PI * 180

           
            let end_pooledKnife = this.getPooledKnife();
            if(end_pooledKnife != null){
                this.node.addChild(end_pooledKnife);
                end_pooledKnife.height = lenV;
                end_pooledKnife.setPosition((this.sx+this.ex)/2-this.node_w/2,(this.sy+this.ey)/2-this.node_h/2);
                end_pooledKnife.angle = -roateV;
            }

            this.prev_pos = this.curent_pos;
            this.sx = this.ex;
            this.sy = this.ey;
        }


}

触摸移动里面,涉及到的就是如何把你经过的轨迹的knife给画出来。

首先是计算当前监听到位置curent_pos和前一位置prev_pos之间的距离lenV,来做为这段刀的长度,通过sub函数做向量减法以及mag函数来计算。接着计算滑动的方向来做为刀旋转的角度,通过signAngle函数,计算它和竖直向量tempVec之间的角度就可以得到了。最后根据自己设置的锚点位置,设置好刀的position就可以了。

同时,需要在start的update中,将超出时间(life<0)的刀移除(或者是在knife的update中),完成之后就会有那种刀光的轨迹效果了。

update(){
this.pooled_knifves.forEach(e => {
            
            if(!e.getComponent('knife').isActivate && e.getComponent('knife').life <= 0){
                // cc.log('remove!');
                this.node.removeChild(e);
                e.getComponent('knife').resetProperties();
            }
        });

}

接下来,准备做的就是水果的分开、掉落部分,由于水果(炸弹)属性差不多,因此可以考虑写成一个类来进行相关操作。

 

  • 4
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值