【2dx】使用2dx 3.0 制作打地鼠游戏(第一部分)

原创
2014/05/03 03:25
阅读数 2.3K

此教程来自于子山龙人的cocos2d版本 http://www.cnblogs.com/zilongshanren/archive/2011/05/15/2045784.html

子山龙人的教程是属于cocos2d版本的   现在边学学做成cocos2d-x3.0版本

本例子的git地址:http://git.oschina.net/gejw0623/cocos2d-x3.0_Sample.git


本教程的资源文件:http://pan.baidu.com/s/1qW2PWXu

接下来  我们创建一个类 用于本教程的开发  我在这创建了一个 PlayTheMouse 类  继承了 Layer

一、添加背景层

    我们的背景层图片为 『bg_dirt.png』

    将背景层添加代码加到init()初始化方法中

        //添加背景
        auto background = Sprite::create("bg_dirt.png");
        //由于子山的博客里面用的素材不是针对800x480的  所以我们要计算一个缩放比
        float scale = background->getContentSize().width * 2 / winSize.width;
        //同理  由于有一个缩放比  所以我们在接下来使用地鼠高宽时  需要计算缩放之后才会获取正确值
        moleScale = winSize.width / (background->getContentSize().width * 2.0f);
        background->setScale(scale);
        background->setPosition(Point(winSize.width / 2, winSize.height / 2));
        //-2是z轴  在2d游戏中 z轴用于显示层级 z越大 就越在上层
        this->addChild(background, -2);

    我们运行下代码  看下效果

二、添加草坪

我们将草坪分为两块  一块上部分  一块下部分  

代码添加在背景层代码下方

        SpriteFrameCache::getInstance()->addSpriteFramesWithFile("playthemouse.plist");
         
        //下半部分的草坪
        auto lower = Sprite::createWithSpriteFrameName("grass_lower.png");
        lower->setAnchorPoint(Point(0.5, 1));
        lower->setPosition(Point(winSize.width / 2, winSize.height / 2 + 1));
        this->addChild(lower, 1);
        
        //上半部分的草坪
        auto upper = Sprite::createWithSpriteFrameName("grass_upper.png");
        upper->setAnchorPoint(Point(0.5, 0));
        upper->setPosition(Point(winSize.width / 2, winSize.height / 2));
        this->addChild(upper, -1);

为了模拟出地鼠钻出钻入洞的效果   我们将上部分z值设为1   下部分设为-1   地鼠设为0   

运行代码 我们可以看到草坪出现了

三、添加三只可爱的小地鼠

我们先在头文件中添加一个Vector对象  用于保存三只地鼠对象  方便接下来的代码中进行循环处理

Vector<Sprite*> moles;

接下来  我们在init方法中使用一个for循环来添加三只小地鼠

        //接下来添加三个小地鼠 并且初始化坐标
        for (int i = 0 ; i < 3; i++) {
            auto mole = Sprite::createWithSpriteFrameName("mole_1.png");
            mole->setScale(moleScale);
            mole->setPosition(Point(155 + 245 * i, winSize.height / 2 - mole->getContentSize().height / 2 * moleScale - 30));
            this->addChild(mole, 0);
            moles.pushBack(mole);
        }

运行代码  我们看下效果 

~~~~~~哎呀  地鼠没出现  等等  我们将地鼠的z值改为2   在草坪上方

this->addChild(mole, 1);

接下来  我们再运行下代码 看看  地鼠出现了

但是  如果地鼠在洞下面的时候  我们不该让他显示的  所以 我们将z值改回来   改成0

接下来我们要让地鼠动起来了

四、让地鼠动起来

    我们需要执行一个方法 让他每0.5s进行地鼠检测  并且有1/3的机率让地鼠钻出地面

    首先  我们创建一个方法  此方法每0.5s执行一次

     //此方法每0.5s执行一次  用于判断每一个地鼠 让它有机会钻出洞来
    void updateMole(float dt);

    接下来 我们在init中使用schedule 控制0.5s执行一次

         //每隔0.5s执行一次updateMole
        this->schedule(schedule_selector(PlayTheMouse::updateMole), 0.5f);

    现在  我们可以在updateMole中写关于检测地鼠的代码

void PlayTheMouse::updateMole(float dt){
    //循环遍历地鼠
    for(auto mole : moles){
        //计算1/3的机率可以让地鼠钻出
        if(arc4random() % 3 == 0){
            //当地鼠没有动作执行时  我们让他执行动作
            if(mole->getNumberOfRunningActions() == 0){
                this->popMole(mole);
            }
        }
    }
}

代码中注释写的很清楚  我就不解释了

上面的代码中有一个popMole方法   这个方法可以让地鼠执行一连串动作

void PlayTheMouse::popMole(Sprite *mole){
    //在此方法中 执行了一串动作,从地鼠钻出地面  然后再钻入地面
    //第一个动作 地鼠上移
    auto moveup = MoveBy::create(0.2f, Point(0, mole->getContentSize().height * moleScale));
    //第二个动作 用于延迟0.5s
    auto delay = DelayTime::create(0.5f);
    //第三个动作 钻入地面 (reverse:返回一个反向动作,即从地面钻入洞中)
    auto movedown = moveup->reverse();
    //接下来执行动作 (Sequence:按序列执行动作,这会让节点连续执行几个动作)
    mole->runAction(Sequence::create(moveup,delay,movedown, nullptr));
    
}

好了  我们运行代码   可以看到  三个地鼠在不停的钻出  钻入  

 

不过   我们现在也不能打它们   我们怎么打他们  下一章讲

五、本章完整代码

//
//  PlayTheMouse.h
//  study
//
//  Created by Robin on 14-5-3.
//
//

#ifndef __study__PlayTheMouse__
#define __study__PlayTheMouse__

#include <iostream>
#include "cocos2d.h"

USING_NS_CC;

class PlayTheMouse : public Layer{
public:
    static Scene* createScene();
    virtual bool init();
    CREATE_FUNC(PlayTheMouse);
private:
    Size winSize;
    //由于我们的素材不是按照800x480来的  所以需要计算一个缩放值
    float moleScale;
    //用于保存地鼠的数组
    Vector<Sprite*> moles;
    //此方法每0.5s执行一次  用于判断每一个地鼠 让它有机会钻出洞来
    void updateMole(float dt);
    //弹出地鼠
    void popMole(Sprite* mole);

};

#endif /* defined(__study__PlayTheMouse__) */

    

//
//  PlayTheMouse.cpp
//  study
//
//  Created by Robin on 14-5-3.
//
//

#include "PlayTheMouse.h"

Scene* PlayTheMouse::createScene(){
    auto scene = Scene::create();
    auto layer = PlayTheMouse::create();
    scene->addChild(layer);
    return scene;
}

bool PlayTheMouse::init(){
    bool bRet = false;
    do {
        winSize = Director::getInstance()->getWinSize();
        
        SpriteFrameCache::getInstance()->addSpriteFramesWithFile("playthemouse.plist");
        
        //添加背景
        auto background = Sprite::create("bg_dirt.png");
        float scale = background->getContentSize().width * 2 / winSize.width;
        moleScale = winSize.width / (background->getContentSize().width * 2.0f);
        background->setScale(scale);
        background->setPosition(Point(winSize.width / 2, winSize.height / 2));
        this->addChild(background, -2);
        
        //下半部分的草坪
        auto lower = Sprite::createWithSpriteFrameName("grass_lower.png");
        lower->setAnchorPoint(Point(0.5, 1));
        lower->setPosition(Point(winSize.width / 2, winSize.height / 2 + 1));
        this->addChild(lower, 1);
        
        //上半部分的草坪
        auto upper = Sprite::createWithSpriteFrameName("grass_upper.png");
        upper->setAnchorPoint(Point(0.5, 0));
        upper->setPosition(Point(winSize.width / 2, winSize.height / 2));
        this->addChild(upper, -1);
        
        //接下来添加三个小地鼠 并且初始化坐标
        for (int i = 0 ; i < 3; i++) {
            auto mole = Sprite::createWithSpriteFrameName("mole_1.png");
            mole->setScale(moleScale);
            mole->setPosition(Point(155 + 245 * i, winSize.height / 2 - mole->getContentSize().height / 2 * moleScale - 30));
            this->addChild(mole, 0);
            moles.pushBack(mole);
        }
        
        //每隔0.5s执行一次updateMole
        this->schedule(schedule_selector(PlayTheMouse::updateMole), 0.5f);
       
        bRet = true;
    } while (0);
    return bRet;
}

void PlayTheMouse::updateMole(float dt){
    //循环遍历地鼠
    for(auto mole : moles){
        //计算1/3的机率可以让地鼠钻出
        if(arc4random() % 3 == 0){
            //当地鼠没有动作执行时  我们让他执行动作
            if(mole->getNumberOfRunningActions() == 0){
                this->popMole(mole);
            }
        }
    }
}

void PlayTheMouse::popMole(Sprite *mole){
    //在此方法中 执行了一串动作,从地鼠钻出地面  然后再钻入地面
    //第一个动作 地鼠上移
    auto moveup = MoveBy::create(0.2f, Point(0, mole->getContentSize().height * moleScale));
    //第二个动作 用于延迟0.5s
    auto delay = DelayTime::create(0.5f);
    //第三个动作 钻入地面 (reverse:返回一个反向动作,即从地面钻入洞中)
    auto movedown = moveup->reverse();
    //接下来执行动作 (Sequence:按序列执行动作,这会让节点连续执行几个动作)
    mole->runAction(Sequence::create(moveup,delay,movedown, nullptr));
    
}

Animate* PlayTheMouse::createAnimate(){
    auto animation = Animation::create();
    animation->addSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("mole_laugh1.png"));
    animation->addSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("mole_laugh2.png"));
    animation->addSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("mole_laugh3.png"));
    animation->setDelayPerUnit(0.1f);
    animation->setRestoreOriginalFrame(true);
    return Animate::create(animation);
}

素材已经在开始给出

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部