CocosEditor-java开发关键函数汇总【更新中】

参考CocosEditor管网提供的,运黄金完整源码:https://github.com/makeapp/cocoseditor-java-goldship

1.点击按钮弹窗代码

  @Bind("pausedBtn")
    public Button pausedBtn;

    @Bind("pausedBtn")
    @Action(Action.ActionType.WidgetTouchUp)
    public void onPausedClicked(Ref ref) {
        Logger.log("paused");

        setTouchEnabled(false);
        pausedBtn.setTouchEnabled(false);
        NodeReader.create().showNode(owner, "layouts/pause.cce");
        Director.getInstance().pause();
    }

1.1 游戏结束自动弹窗

    //游戏结束后弹出的窗口
    //游戏结束窗口弹出后,暂停按钮不能点击
    //屏幕触摸失效,游戏暂停
    private void showGameLayer() {
        final ControllerMessage controller = (ControllerMessage)
                NodeReader.create().showNode(owner, "layout/GameOver.cce");
        controller.score = Integer.parseInt(score.getString());
        setTouchEnabled(false);
        pauseButton.setTouchEnabled(false);
        this.playGame = false;
//        FunctionFactory.callFunction("ad", "show Interstitial");
    }

2.java项目内部,全局调用自定义函数

调用

    @Bind("sharing")
    @Action(Action.ActionType.WidgetTouchUp)
    public void onShareTouched(Ref ref) {
        FunctionFactory.callFunction("weixin", "sendSession appData 运黄金 我得了" + score + "个黄金,你也来试试手气.");
    }
注册
       FunctionFactory.callFunction("ad", "show Banner Top " + width + " " + height);
//        FunctionFactory.callFunction("ad", "show Banner Top");
        FunctionFactory.registerFunction("onApplicationDidEnterBackground", new Function() {
            @Override
            public Object apply(Object o) {
                onStop();
                return null;
            }
        });

3.碰撞检测

如果不打开物理世界,是不会侦测到碰撞的。打开办法如图:

设置Scene的参数为true。

包括创建监听器GroundAndGoldContact和注册监听器addPhysicsContactListner()

 //给陆地加入碰撞监听器以及参数
    //陆地本身的位掩码setCategoryBitmask(十六进制)
    //与陆地所要接触的对象的位掩码setContactTestBitmask(十六进制)
    private void setGroundCollsition() {

        PhysicsBody gBody = groundSprite.getPhysicsBody();
        gBody.setCategoryBitmask(0x08);
        gBody.setContactTestBitmask(0x02);
        groundSprite.addPhysicsContactListener(new GroundAndGoldContact());
    }
 /**
     * 创建陆地和金子碰撞监听类
     * 实现物理相交监听这个类里面的方法
     * 首先,注册要使用的方法,用的的方法都要先注册
     * 如:regContactBegin();
     * *
     */
    public class GroundAndGoldContact
            extends PhysicsContactListener {
        {
            regContactBegin();
        }

        @Override
        public boolean onContactBegin(PhysicsContact contact) {
            Node goldNode = contact.getNode(1000);
            Node groundNode = contact.getNode(5555);

            if (goldNode != null && groundNode != null) {
                Vec2 loc = goldNode.getPosition();
                goldExplode(loc);
                goldNode.removeFromParent();
                golds.remove(goldNode);
                ggCount++;
            }
            return false;
        }
    }

4.爆炸效果

  //金子爆炸,金子掉落到地上爆炸碎了
    private void goldExplode(Vec2 loc) {
        final Sprite goldSprite = NodeReader.create().readSprite("layout/GoldExplode.cce");
        if (loc != null && goldSprite != null) {
            goldSprite.setPosition(loc);//爆炸位置
            owner.addChild(goldSprite);
        }
        if (goldSprite != null) {
            goldSprite.runAction(Sequence.create(DelayTime.create(0.3f), new CallFunc() {
                @Override
                public void execute() {
                    super.execute();
                    goldSprite.removeFromParent();
                }
            }));
        }
        AudioEngine.getInstance().playEffect("audio/fallgd.mp3");
    }


5.创建复杂Sprite

(包括多个图片,多个Action轨迹,根据指定数目创建新刚体)

已经给不清楚的地方作了注释。。

/**
     * 创建矿车设置它的tag(获取需要通过它),设置矿车物理碰撞监听器以及物理参数
     * 矿车本身的位掩码setCategoryBitmask(十六进制)
     * 与矿车发生相交的对象的位掩码setContactTestBitmask(十六进制)
     * 矿车移动过程:从右下角--->左下角--->左上角--->右上角--->右下角
     * 移动过程是无限循环过程,移动的过程中接受金子,并将金子倒入矿槽
     * *
     */
    public synchronized void createTramcar() {

        if (this.currentTime - this.lastCreateCarTime >= 5) {

            carCount += 1;
            NodeReader reader = NodeReader.create();
            final Node tramcarNode = reader.readNode("layout/Tramcar.cce");
            tramcarNode.setPosition(new Vec2(675, 180));
            tramcarNode.setTag(0);
            tramcarNode.setZOrder(10);
            //车身刚体
            PhysicsBody physicsBody2 = tramcarNode.getPhysicsBody();
            physicsBody2.setCategoryBitmask(0x08);
            physicsBody2.setContactTestBitmask(0x02);
            tramcarNode.addPhysicsContactListener(new TramcarAndGoldContact());
            owner.addChild(tramcarNode);
            final Node cheshen = tramcarNode.getChildByTag(100);
            //矿车运行线路
            tramcarNode.runAction(RepeatForever.create(Sequence.create(
                    MoveTo.create(WHEEL_TIME, new Vec2(50, 180)),
                    new CallFunc() {
                        @Override
                        public void execute() {
                            super.execute();
                            goldChangeTag = 0;
                        }
                    },
                    Sequence.create(MoveTo.create(WHEEL_TIME, new Vec2(50, 1100))),
                    //2.5f表示运行到水平中间位置,就执行倒金子到金子池的动作。
                    Sequence.create(MoveTo.create(2.5f, new Vec2(360, 1100)), new CallFunc() {
                        @Override
                        public void execute() {
                            super.execute();
                            //获取该小车接收多少个金子,并根据金子数,在for循环中,创建gold个精灵
                            int gold = tramcarNode.getTag();
                            tramcarNode.setTag(0);
                            cheshen.removeAllChildren();
                            tramcarNode.getPhysicsBody().setEnable(true);
                            if (gold > 0 && gold != 1001) {
                                for (int a = 0; a < gold; a++) {
                                    //创建gold Sprite,然后添加到场景Scene——这是倒金子的动作。
                                    NodeReader reader = NodeReader.create();
                                    String goldName = "Gold" + ((int) Math.floor(Math.random() * 4) + 1) + ".cce";
                                    Sprite sprite = reader.readSprite("layout/" + goldName);
                                    sprite.setTag(1000);
                                    sprite.setZOrder(5);
                                    sprite.setPosition(new Vec2(a * 15 + 300, 1050));
                                    //黄金刚体
                                    PhysicsBody physicsBody1 = sprite.getPhysicsBody();
                                    physicsBody1.setCategoryBitmask(0x02);
                                    physicsBody1.setContactTestBitmask(0x08);
                                    owner.addChild(sprite);
                                }
                            }
                        }
                    }, Sequence.create(MoveTo.create(2.5f, new Vec2(675, 1100)))),
                    MoveTo.create(WHEEL_TIME, new Vec2(675, 180)))));
            this.lastCreateCarTime = this.currentTime;
        }
    }

6.精灵Sprite的获取办法

6.1通过tag

  @Bind(tag = 1002)
    public Sprite board;//挡板

6.2通过name
6.3通过NodeReader

直接根据cce文件的布局create,并可通过强制类型转化,获取Controller类。

参考1.1中的

      final ControllerMessage controller = (ControllerMessage)NodeReader.create().showNode(owner, "layout/GameOver.cce");
把数据传递给该Node,然后把背景设置为不可触碰,点击事件会被controller捕捉到。再看看代码全貌

    //游戏结束后弹出的窗口
    //游戏结束窗口弹出后,暂停按钮不能点击
    //屏幕触摸失效,游戏暂停
    private void showGameLayer() {
        final ControllerMessage controller = (ControllerMessage)
                NodeReader.create().showNode(owner, "layout/GameOver.cce");
        controller.score = Integer.parseInt(score.getString());
        setTouchEnabled(false);
        pauseButton.setTouchEnabled(false);
        this.playGame = false;
//        FunctionFactory.callFunction("ad", "show Interstitial");
    }

7.声音播放停止

        AudioEngine.getInstance().playBackgroundMusic("audio/bg.mp3", true);
        AudioEngine.getInstance().playEffect("audio/click.mp3");
        AudioEngine.getInstance().pauseBackgroundMusic();


8.创建大量Sprite

其中golds是一个数组  

    List<Sprite> golds = new ArrayList<Sprite>();

   //创建一定数量的金子,设置它的tag(后面获取通过它)和物理碰撞监听器参数
    //本身的位掩码setCategoryBitmask(十六进制)
    //相交时对象的位掩码setContactTestBitmask(十六进制)
    //相交时对象的碰撞位掩码setCollisionBitmask(十六进制)
    private void showAllGold() {
        NodeReader reader = NodeReader.create();
        int goldCountHorizon = 7;
        int goldCountVertical = 7;
        for (int j = 0; j < goldCountHorizon; j++) {//横排
            for (int k = 0; k < goldCountVertical; k++) {//竖排

                String goldName = "Gold" + ((int) Math.floor(Math.random() * 4) + 1) + ".cce";
                Sprite sprite = reader.readSprite("layout/" + goldName);
                sprite.setTag(1000);
                sprite.setPosition(new Vec2(k * 40 + (size.getWidth() / 3 + 20), size.getHeight() - 350 - j * 20));
                PhysicsBody physicsBody1 = sprite.getPhysicsBody();

                physicsBody1.setCategoryBitmask(0x02);
                physicsBody1.setContactTestBitmask(0x08);
                owner.addChild(sprite);

                golds.add(sprite);
            }
        }
        AudioEngine.getInstance().playEffect("audio/down.mp3");
        formerCount = goldCountHorizon * goldCountVertical;//原有金子总数
    }


9.暂停时对所有Sprites刚体的操作。

还是通过第8点的数组获取。

   public void onStop() {
        for (Sprite sprite : golds) {
            PhysicsBody physicsBody = sprite.getPhysicsBody();
            if (physicsBody != null) {
                physicsBody.setEnable(false);
            }
        }
    }

    public void onRestart() {
        for (Sprite sprite : golds) {
            PhysicsBody physicsBody1 = sprite.getPhysicsBody();
            physicsBody1.setEnable(true);
        }
    }


10.动画效果。

在assets目录下建立一个animates文件夹(小心:不要把这个文件夹放到Texture那里了,根目录是assets),然后自定义一个loadingAnimate.cce文件,把keyFrame放进Animation控件中。

参考http://blog.cocoseditor.com/?p=928

        //loading 3s后删除
        loadingSprite.runAction(NodeReader.create().readAnimation("animates/loadingAnimate.cce"));
        owner.scheduleOnce(new Scheduler.SchedulerCallback() {
            @Override
            public void onUpdate(float delta) {
                super.onUpdate(delta);
                if (loadingSprite != null) {
                    loadingSprite.removeFromParent();
                    isLoadingFinish = true;
                }
            }
        }, 3);
        //涂鸦怪物跳跃动画
        Vec2 dsPos = doodleSprite.getPosition();
        doodleSprite.runAction(RepeatForever.create(Sequence.create(
                MoveTo.create(0.5f, new Vec2(dsPos.getX(), dsPos.getY() + 150)),
                MoveTo.create(0.4f, new Vec2(dsPos.getX(), dsPos.getY())),
                new CallFunc() {
                    @Override
                    public void execute() {
                        super.execute();
                        AudioEngine.getInstance().playEffect("sounds/bs_jump.mp3");
                    }
                }

        )));

组合动作,可以用Spawn,但是有的动作不能组合,例如下面的,用Spawn的话,Action类就不会启动了。但runAction是可以合并的,下面的例子我让鸟飞的时候还能拍打翅膀。

  @Override
    public void onEnter() {
        super.onEnter();

        org.ccj.d2.action.Action actionFlip =  NodeReader.create().readAnimation("animates/1.cce");

        waitingSprite.runAction(actionFlip);

        Vec2 position = waitingSprite.getPosition();

        Sequence actionUpDown = Sequence.create(
                MoveTo.create(0.5f, new Vec2(position.getX(), position.getY() + 50)),
                MoveTo.create(0.5f, new Vec2(position.getX(), position.getY()))
        );


        waitingSprite.runAction(RepeatForever.create(
             //   Spawn.create(
              //  actionFlip
                        actionUpDown
              //  )
        ));

    }


11.允许点击事件

默认是不允许的,后来看了源码才发现。下面是允许的代码,必须先enable

   @Override
    public void onEnter() {
        super.onEnter();
        setTouchEnabled(true);
        setTouchMode(Touch.MODE_ONE_BY_ONE);
        this.createParticle("lv01", new Vec2(360, 400));
        AudioEngine.getInstance().playBackgroundMusic("sounds/bgmusic.mp3", true);
    }

下面是响应代码

    @Override
    public boolean onTouchBegan(Touch touch, Event event) {
        Vec2 pos = touch.getLocation();

        if (pausedBtn.getBoundingBox().containsPoint(pos)) {
            return false;
        }

        this.moveMonster(pos);

        return true;
    }


12.延迟时间

12.1 DelayTime.create(0.3f)

当Action用,如下

        pipeBar1.runAction(RepeatForever.create(Sequence.create(
                MoveTo.create(1.5f,new Vec2(-160,0)),
                MoveTo.create(0, new Vec2(720, 0)),
                DelayTime.create(0.5f)
        )));

12.2 DelayTIme只能放在最后的参数位置上

有时候,希望能放在最前,怎么实现呢?如下例子,先在屏幕外移动,3秒后,瞬间拉回到边缘。这就相当于DelayTime了。在屏幕内的等待,也可以用类似办法,移动1像素看看。

MoveTo.create(3.0f,new Vec2(screenWidth+100,0));
MoveTo.create(0,new Vec(screenWidth,0));


13.Sequence.create()的注意事项

为了实现flappy bird的柱子等间隔出现,今天花好大力气去测试。

发现Sequence.create()函数里,貌似是赋值了Action,但是,这些Action只赋值一次。我后面通过CallFunc修改了i[0]的值,企图改变sprite的等待时间,发现不行。它会在整个循环中一直都保持为初始化时候的值{waitTime*2}。

final float[] i = {waitTime * 2};

 pipeBar3.runAction(RepeatForever.create(Sequence.create(
                        MoveTo.create(i[0],new Vec2(designWidth+50,0)),
                        MoveTo.create(0,new Vec2(designWidth,0)),
                        MoveTo.create(timeTotal,new Vec2(-pipeWidth,0)),
                        MoveTo.create(0, new Vec2(designWidth, 0)),
                        new CallFunc(){
                            @Override
                            public void execute() {
                                System.out.println("pipe3 end");
                                System.out.println("i = "+i[0]);
                                i[0] =0f;
                                super.execute();
                            }                            ;
                        }
        )));

14.CallFunc与外部参数交互

如上面第13点的函数,i如果是数组,是可以和外部交互数据的,但是如果是普通变量,就不行。

后来发现,用全局函数是可以的。

boolean mFinishFlyFlag = true;
public void onTouchBegan(){
ActionInterval rotateUp = Sequence.create(
        RotateBy.create(0.3f, -60)
        , RotateBy.create(0.2f, 60)
        , new CallFunc(){
            @Override
            public void execute() {

                mFinishFlyFlag = true;
                super.execute();
            }
        }
);........}




15.定时创建一个Sprite

参考了Demo中的ComponetsTestScene,每次onUpdate统计elapseTime,如果超过1秒,就创建一个怪物。 

    float _addTargetTime;
    float _elapsedTime;
 public void onEnter()
    {
        super.onEnter();
        this._addTargetTime = 1;
        _targets = new ArrayList();
        _projectiles = new ArrayList();

        Node owner = this.getOwner();

        AudioEngine.getInstance().playBackgroundMusic("Sound/background-music-aac.wav", true);
        ComAttribute attribute = ComAttribute.cast(owner.getComponent("CCComAttribute"));
	//积分
        attribute.setInt("KillCount", 0);
    }

public void onUpdate(float dt)
{
    super.onUpdate(dt);
    this._elapsedTime += dt;
    if (this._elapsedTime > this._addTargetTime) {
        this.addTarget();
        this._elapsedTime = 0.0f;
    }
}

还可以用schedule,定时处理事务,但使用这个,就不能使用Controller的onUpdate()了(没验证过),除非你知道怎么处理。还有个SchedulerListener接口,已经有了Callback,暂时没发现这个接口有什么用。

    public void onCreate()
        {
            super.onCreate();

            this.schedule(new Scheduler.SchedulerCallback()
            {
                public void onUpdate(float delta)
                {
                    super.onUpdate(delta);
                    accum += delta;
                    Logger.log("Time: " + accum);
                    if (accum > 3) {
                        unschedule(this);
                        Logger.log("scheduler removed");
                    }
                }
            }, 0.5f);

            this.schedule(new Scheduler.SchedulerCallback()
            {
                public void onUpdate(float delta)
                {
                    super.onUpdate(delta);
                    Logger.log("This scheduler should not be removed");
                }
            }, 0.5f);
        }



 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值