基于cocos2dx-js开发的仿《英雄难过棍子关》

游戏设计说明

最终效果图

设计思想

整体结构

1.游戏主要分为StartScene和GameScene两个场景,StartScene只有一个开始按钮,不做过多解释。

2.GameScene又分GameLayer和ResultLayer,这里的分数直接写在GameLayer中了,稍复杂的游戏一般会再开一个StatusLayer

3.在代码上还添加了GameModel对象,主要负责记录游戏数据以及对不同的Layer的引用

主要的cocos2dx-js API

Action: rotate,move,animate

Node:Sprite,Scene,Layer,LabelTTF

代码

GameScne.js

/**
 * Created by ccy on 2015/7/12.
 */
var GameLayer = cc.Layer.extend({
    //parameter
    moveDistance:-10,
    moveTime:0.7,
    bk:null,
    //footstep
    footstep1:null,
    footstep2:null,
    footstepHeight:300,
    //status
    isTouch:false,
    isPlayingAniamtion:false,
    // bridge
    bridgeScaleY:1.0,
    bridgeAddScalePercent:0.3,
    bridgeSprite:null,
    //role
    role:null,
    roleAnimate:null,
    //score
    score:0,
    scoreLabel:null,
    ctor:function() {
        this._super();
        GameModel.getInstance().setGameLayer(this);

        this.bk = new cc.Sprite(res.bk1);
        this.addChild((this.bk));
        this.schedule(this.addSnow,1);
        this.schedule(this.addLeng,0.03);

        // add touch callback
        var touchListener = cc.EventListener.create({
            event:cc.EventListener.TOUCH_ONE_BY_ONE,
            swallowTouches:false,
            onTouchBegan:function(touch,event){
                var pos = touch.getLocation();
                var target = event.getCurrentTarget();
                if (target.isPlayingAniamtion){
                    return false;
                }
                target.isTouch = true;
                target.bridgeLeng = 0;
                return true;
            },
            onTouchMoved:function(touch,event){

            },
            onTouchEnded:function(touch,event){
                var target = event.getCurrentTarget();
                target.isTouch = false;
                var rotate = cc.rotateBy(1.0,90);
                var callback = cc.callFunc(function(){
                    target.move();
                });
                var seq = cc.sequence(rotate,callback);
                target.bridgeSprite.runAction(seq);
                target.isPlayingAniamtion = true;
            }
        });
        cc.eventManager.addListener(touchListener,this);

        this.bridgeSprite = new cc.Sprite(res.bridge);
        this.addChild(this.bridgeSprite,11);

        this.role = new cc.Sprite(res.bird_0);
        var animation = new cc.Animation();
        animation.addSpriteFrameWithFile(res.bird_0);
        animation.addSpriteFrameWithFile(res.bird_1);
        animation.setDelayPerUnit(2.8 / 14);
        animation.setRestoreOriginalFrame(true);
        animation.setLoops(100000);
        this.animate = cc.animate(animation);
        this.addChild(this.role,1100);

        this.scoreLabel = new cc.LabelTTF("score:"+this.score, "Arial", 40);

        var tip = new cc.LabelTTF("come on !!","Arial",60);
        tip.attr({
            x:cc.winSize.width/2,
            y:cc.winSize.height/8*6,
        });
        this.addChild(tip);

        this.addChild(this.scoreLabel);
        this.reset();

    },
    move:function(){
        var deltaPositionX = this.footstep2.getPosition().x-this.footstep1.getPosition().x;
        var roleMoveDistance1 = deltaPositionX + (this.getRealWidth(this.footstep2)-this.getRealWidth(this.footstep1));
        var roleMoveDistance2 = this.getRealHeight(this.bridgeSprite) ;
        var callbackSuccess = cc.callFunc(function(selectTarget){
            selectTarget.getParent().role.stopAllActions();
            var moveAction = cc.moveBy(selectTarget.getParent().moveTime,selectTarget.getParent().moveDistance,0);
            selectTarget.getParent().bk.runAction(moveAction);
            var allMove = cc.moveBy(0.4,-deltaPositionX,0);
            var callbackReset = cc.callFunc(function(){
                selectTarget.getParent().resetLittle();
            });
            selectTarget.getParent().footstep1.runAction(allMove);
            selectTarget.getParent().footstep2.runAction(allMove.clone());
            selectTarget.getParent().role.runAction(cc.sequence(allMove.clone(),callbackReset));
            selectTarget.getParent().bridgeSprite.runAction(allMove.clone());
            selectTarget.getParent().score++;
        },this.role);

        var callbackFailed = cc.callFunc(function(selectTarget){
            selectTarget.getParent().role.stopAllActions();
            var callback = cc.callFunc(function(){
                selectTarget.getParent().getParent().addChild(new ResultLayer());
            });
            var move1 = cc.moveBy(1.0,150,0);
            var move2 = cc.moveBy(1.0,0,-400).easing(cc.easeIn(1.0));
            selectTarget.runAction(move1);
            selectTarget.getParent().role.runAction(move2.clone());
            var rotate = cc.rotateBy(1.0,120).easing(cc.easeIn(3.0));
            selectTarget.getParent().bridgeSprite.runAction(move2);
            selectTarget.getParent().bridgeSprite.runAction(cc.sequence(rotate,callback));
        },this.role);
        var bridgeMinDistance = this.footstep2.getPositionX()-this.footstep1.getPositionX()-
            this.getRealWidth(this.footstep1);
        var bridgeMaxDistance = bridgeMinDistance + this.getRealWidth(this.footstep2);
        if(roleMoveDistance2 > bridgeMaxDistance || roleMoveDistance2 < bridgeMinDistance){
            var roleMoveAction = cc.moveBy(this.moveTime,roleMoveDistance2,0);
            this.role.runAction(cc.sequence( roleMoveAction,callbackFailed));
            this.role.runAction(this.animate.clone());
        }
        else{
            var roleMoveAction = cc.moveBy(this.moveTime,roleMoveDistance1,0);
            this.role.runAction(cc.sequence( roleMoveAction,callbackSuccess));
            this.role.runAction(this.animate.clone());
        }
    },
    addLeng:function(){
        if(this.isTouch && this.isPlayingAniamtion == false){
            this.bridgeScaleY += this.bridgeAddScalePercent;
            this.bridgeSprite.setScaleY(this.bridgeScaleY);
        }
    },
    reset:function(){
        var size = cc.winSize;
        this.bk.attr({
            x: 0,
            y: 0,
            anchorX: 0.0,
            anchorY: 0.0,
        });
        var bkSize = this.bk.getContentSize();
        this.bk.setScale(size.height/bkSize.height);
        if(this.footstep1 != null){
            this.footstep1.removeFromParent(true);
            this.footstep1 = null;
        }
        if (this.footstep2 != null){
            this.footstep2.removeFromParent(true);
            this.footstep2 = null;
        }

        this.scoreLabel.attr({
            x:0,
            y:size.height,
            anchorX:0,
            anchorY:1.0,
        })
        this.score = 0;
        this.resetLittle();

        var x = this.getRealWidth(this.footstep1) - this.getRealWidth(this.bridgeSprite);
        this.role.attr({
            x:x,
            y:this.footstepHeight,
            anchorX:1.0,
            anchorY:0
        });

    },
    resetLittle:function(){
      if(this.footstep1 != null) {
          this.footstep1.removeFromParent(true);
      };
        this.footstep1 = this.footstep2;
        this.footstep2 = null;
        this.addFootStep();

        //reset bridge
        var y = this.footstepHeight - this.bridgeSprite.getContentSize().width;
        var x = this.getRealWidth(this.footstep1);
        this.bridgeSprite.attr({
            x:x,
            y:y,
            anchorX:1.0,
            anchorY:0,
            scale:1.0,
        });
        this.bridgeSprite.setRotation(0);
        this.bridgeScaleY = 1.0;

        this.isPlayingAniamtion = false;

        this.scoreLabel.setString("score:"+this.score);
        GameModel.getInstance().setScore(this.score);

    },
    addFootStep:function(){
        //ad  footstep2
        var size = cc.winSize;
        if (this.footstep1 == null){
            // add footstep
            this.footstep1 = new cc.Sprite(res.footstep);
            this.footstep1.setColor(new cc.Color(125,0,56));
            var stepSize = this.footstep1.getContentSize();
            var bridgeScaleX1 = (cc.random0To1()*150+80)/stepSize.width;
            var scaleY = this.footstepHeight/stepSize.height;
            this.footstep1.setScale(bridgeScaleX1,scaleY);
            this.footstep1.attr({
                x:0,
                y:0,
                anchorX:0,
                anchorY:0,
            });
            this.addChild(this.footstep1,100);
        }
        if (this.footstep2 != null){
            this.footstep2.removeFromParent(true);
        }
        this.footstep2 = new cc.Sprite(res.footstep);
        this.footstep2.setColor(new cc.Color(125,0,56));
        var stepSize = this.footstep2.getContentSize();
        var bridgeScaleX2 = (cc.random0To1()*150+80)/stepSize.width;
        var scaleY = this.footstepHeight/stepSize.height;
        this.footstep2.setScale(bridgeScaleX2,scaleY);
        var x = cc.random0To1()*(size.width-this.getRealWidth(this.footstep1)-20-this.getRealWidth(this.footstep2)) +
            this.getRealWidth(this.footstep1)+20;
        this.footstep2.attr({
            x:size.width,
            y:0,
            anchorX:0,
            anchorY:0,
        });
        var footstepMove = cc.moveTo(0.3,x,0);
        this.addChild(this.footstep2,100);
        this.footstep2.runAction(footstepMove);
    },
    getRealWidth:function(sprite){
        var width = sprite.getContentSize().width;
        var scaleX = sprite.getScaleX();
        return width*scaleX;
    },
    getRealHeight:function(sprite){
        var height = sprite.getContentSize().height;
        var scaleY = sprite.getScaleY();
        return height*scaleY;
    },
    addSnow:function(){
        var apple = new cc.Sprite(res.snow);
        var size = cc.winSize;
        var x = cc.random0To1()*(size.width-apple.width)+apple.width/2;
        var y = size.height + apple.height/2;
        apple.attr({
            x:x,
            y:y,
            scale:cc.random0To1()*0.6+0.2,
        });
        apple.runAction(cc.sequence(
            cc.moveBy(3.0,0,-(size.height+apple.height)),
            cc.callFunc(function(){
                apple.removeFromParent(true);
                cc.log("apple remove from parent");
            })
        ));
        this.addChild(apple);
        var touchListener = cc.EventListener.create({
            event:cc.EventListener.TOUCH_ONE_BY_ONE,
            swallowTouches:false,
            onTouchBegan:function(touch,event){
                var pos = touch.getLocation();
                var target = event.getCurrentTarget();
                if (cc.rectContainsPoint(target.getBoundingBox(),pos)){
                    target.getParent().move();
                    target.removeFromParent(true);
                    cc.log("you click apple");
                    return ;
                }
                return false;
            }
        });
        cc.eventManager.addListener(touchListener,apple);
    }
});

var GameScene = cc.Scene.extend({
    ctor:function(){
        this._super();
        var layer = new GameLayer();
        this.addChild(layer);
    }
});

代码分析

ctor

构造函数,在这里添加游戏需要用到的大部分Node以及相关的Listener,还有两个schedule,一个schedule是增长棍子用的,还有一个schedule添加雪花(没什么用处)

reset

开始游戏或者重开游戏时调用,调整在ctor函数中添加的Node的相关属性

resetLittle

每走一步都会调用,调整某些细节

addFootStep

添加台阶

addLeng

点击屏幕时,变长棍子

相关信息

文章只给出主要代码,想要完整代码可以通过以下方式获取

[email protected]:http://git.oschina.net/dogonline/dogEatCat

百度云:http://pan.baidu.com/s/1jGD0Ryu

从git上拷贝到完整的工程目录后,到根目录,用以下方式运行,工程只在浏览器里运行过

cocos run -p web

作者联系方式:[email protected]

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-27 00:37:59

基于cocos2dx-js开发的仿《英雄难过棍子关》的相关文章

基于AGS JS开发自定义贴图图层

文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.前言 假设一个景区有多张图片需要在地图上展示,并且随着地图的缩放而缩放(不是单纯的以气泡来展示).如果利用传统方案,则是我们首先将图片纠正赋予地理信息,然后根据地图级别进行切图,最后以瓦片的形式叠加至地图上,工作量是很大的.然而考虑到图片本身不会太大(小于3M),那么有没有其他方法来解决呢.这里我和大家一起探讨几种解决思路. 2.解决思路 2.1基于grahpic和

KoaHub.JS基于Node.js开发的Koa 生成验证码插件代

ccap node.js generate captcha using c++ library CImg without install any other lib or software node-ccap -- node.js generate captcha using c++ library CImg. You can generate captcha without install any other libraries or software, only do npm install

基于Vue框架开发的仿饿了么前端小应用

主要使用vue框架进行开发.使用最新的框架版本,修正了vue1.0到vue2.0过度过程出现的几处bug. 视频教程则是黄轶老师的<vuejs高仿饿了么APP>. 源代码地址:https://github.com/waihoyu/sell 原文地址:https://www.cnblogs.com/waihoyu/p/9350175.html

基于vue来开发一个仿饿了么的外卖商城(一)

一.准备工作 1.大前提:已安装好node. npm. vue. vue-cli.stylus(此项目使用stylus来编译) 2.开发软件:Google Chrome(建议安装插件vue-devtools,方便调试),webstorm / sublime Text / VS Code (推荐使用webstorm,sublime 和 VS Code需要安装相应的插件) 3.项目结构: 4.项目结构分析: 5. 图标准备 推荐在阿里巴巴矢量图库查找需要的图标,官网地址:https://www.ic

KoaHub平台基于Node.js开发的Koa router路由插件代码信息详情

koa-router Router middleware for koa. Provides RESTful resource routing. koa-router       Router middleware for koa Express-style routing using app.get, app.put, app.post, etc. Named URL parameters. Named routes with URL generation. Responds to OPTIO

KoaHub平台基于Node.js开发的Koa的skip插件代码详情

koahub-skip koahub skip middleware koahub skip Conditionally skip a middleware when a condition is met. Install npm i koahub-skip --save Usage With existing middlewares: var skip = require('koahub-skip'); var serve = require('koa-static'); var static

KoaHub.JS基于Node.js开发的处理和显示日期代码

moment Parse, validate, manipulate, and display dates      A lightweight JavaScript date library for parsing, validating, manipulating, and formatting dates. Documentation Port to ECMAScript 6 (version 2.10.0) Moment 2.10.0 does not bring any new fea

KoaHub平台基于Node.js开发的Koa的简单包装到请求库的类似接口

co-request co-request promisify wrapper for request co-request Simple wrapper to the request library for co-like interface (node.js generator based code). You can use it with koa or co To install simply run: npm install co-request Require co first, a

KoaHub平台基于Node.js开发的Koa的rewrite and index support插件代码详情

koa-static-server Static file serving middleware for koa with directory, rewrite and index support koa-static-server static file serving middleware for koa with directory, rewrite and index support Installation $ npm install koa-static-server API var