CocosCreator c++ 实践与利用

CocosCreator c++ 实践与利用

用cocosCreator 制作一款简易的游戏。 史莱姆跳跃,碰到星星,然后星星+1.

上一章显示的是如果使用cocosCreator的基本应用。这一章是CocosCreator的稍微复杂应用。

参考cocosCreator 教程 js里的游戏 用C++写一款 游戏:
在这里插入图片描述

1.看似简单,仔细做就不简单了。 首先史莱姆是没有脚的,所以只能一跳一跳的移动。所以在行走的时候要保持跳跃。 当然这个是没有物理引擎的。 需要让史莱姆 的跳跃频率不同。
MoveBy() 通过设置值来确定移动的方向,与距离。不是MoveTo,这两个别的博客已经写满了。

    auto myMoveBy = MoveBy::create(0.3f, Vec2(10, 190));
    myMoveBy->startWithTarget(player);
    //逆向上一个动作。
    MoveBy *myMoveBy1=myMoveBy->reverse();
    //由快向慢
    ActionEase *actionEase = EaseOut::create(myMoveBy,2);
    //由慢向快。
    ActionEase *actionEase1 = EaseIn::create(myMoveBy1,2);
    //一组动作。
    ActionInterval *ac=Sequence::create(actionEase,actionEase1, NULL);

这样就可以模仿,类似有重力的动作了。 而大幅度跳跃动作。只要调整MoveBy参数就可以了。
当update()更新的时候,跳跃不能像 player 移动遍历一样,持续动作。否则叠加会飞出屏幕。因为跳跃在不断的叠加中。 你需要给跳跃写一个延迟。 ** 完成动作后再继续。

//aaa 设置在外层。
    if(aaa>=35){
        gameFMS->changeJump1();
        aaa=0;
    }
    aaa++;

本来想找找键盘控制优先级问题。但是没有找到!!!。 不知道有没有意识到这个问题!我查了很多博客和书,对这个问题意识到的不多!!!!!
就是当按下A键的时候。如果快速按下D键和放下D键。 那么弹回A键的动作就会和按下D键发生冲突导致player停止运动。 并不能快速长按键盘切换。 所以只能给每一个键,做一个boolean值。
当按下D键的时候为true,那么A键的弹回就会没用。 反之亦然。

void ControlLayer::onKeyPressed(EventKeyboard::KeyCode keyCode, cocos2d::Event *event){
    CCLOG("aaaaaa&&&&&&&&&&& %d",(int)keyCode);
    
    switch((int)keyCode){
//D键
        case 127:
            this->schedule(schedule_selector(ControlLayer::onMoveKeyboard));
            move=2;
            aboolean=true;
            break;
//A键
        case 124:
            this->schedule(schedule_selector(ControlLayer::onMoveKeyboard));
            move=1;
            aboolean1=true;
            break;
        case 59:
            gameFMS->changeJump();
            break;
        case 6:
            toMenu1Layer();
            break;
    };
}

void ControlLayer::onKeyReleased(EventKeyboard::KeyCode keyCode, cocos2d::Event *event){
    switch((int)keyCode){
        case 127:
            if(!aboolean1){
                this->unschedule(schedule_selector(ControlLayer::onMoveKeyboard));
            }
            aboolean=false;
            aboolean1=false;

            break;
        case 124:
            if(!aboolean){
                this->unschedule(schedule_selector(ControlLayer::onMoveKeyboard));
            }
            aboolean=false;
            aboolean1=false;
            break;
            
        default:
            break;
    };
}

不知道有没有什么好的方法。 以前拳皇的时候,超高速按下 上下左右 jkl 没有问题。

继续创建小星星。

当包围小星星的一个Node里 小星星的类为空时,或者查找不到小星星,那么小星星就可以再生。 曾经想偷懒,把CocosCreator里的类,重新克隆出来,但是创建出来被删除以后,只能new 了,原来CocosCreator已经被删除不能再生了。 所以只能重新把数据导出来,放进新的Sprite里。再添加

        spriteEnemy=Sprite::create();
        spriteEnemy->setTexture("starSprite.png");
        spriteEnemy->setName("spriteEnemy");
        spriteEnemy->setPosition(Vec2(146, 170));
        camera1->addChild(spriteEnemy);

碰撞检测小星星

上上一章,打飞机游戏有一个半误区。 就是其实碰撞检测已经封装好了。 虽然只是用来测试我能力的一个白板游戏。就是根本不偷懒,也不用封装,就是纯写。这样就要检测长宽高。来做碰撞检测。
其实很简单 把找出精灵的方块大小。然后检测就可以了。
Rect rect_player=player->getBoundingBox();
Rect rect_spriteEnemy=spriteEnemy->getBoundingBox();

        Rect rect_player=player->getBoundingBox();
        Rect rect_spriteEnemy=spriteEnemy->getBoundingBox();
        //碰撞检测。
        if(rect_player.intersectsRect(rect_spriteEnemy)){
            start++;
            camera1->removeChild(spriteEnemy);
        }

检测完成小星星+1。 我在左上角有一个计数统计。

核心代码

如果写这么点那么1个小时就可以完成。 重要的是第一次尝试写一个菜单。类似于网络游戏的一个装备仓库。存储武器的的东西。 在这里插入图片描述

一个动态的仓库。 当键盘按下ESC的时候,场景Scene会转换。跳到一个新的场景中
replaceScene、pushScene、popScene

    creator::CreatorReader* reader = creator::CreatorReader::createWithFilename("cocosMenu.ccreator");
    reader->setup();
    Scene *menu1Scene=reader->getSceneGraph();
    menu1Layer=Menu1Layer::create();
    menu1Layer->score=start;
    //把菜单传入进去
    menu1Layer->init_L(menu1Scene);
    menu1Scene->addChild(menu1Layer);
    //替换场景。 应该用pushScene什么,否则以前的数据就丢失了。除非提前 存储好。比如生成json或者xml或者什么的。
    Director::getInstance()->replaceScene(menu1Scene);

进入MenuScene里边。
新的MenuScene里边,首先我做了一个ScrollView。 把数据放进里边,当然我往里边里边传递的值仅仅是一个数字,这个数字是加载的小星星。 所以新的界面小星星会非常多。 由于是动态加载的,小星星不固定。所以 当我在CocosCreator里,画了一个小星星的卡片。

    layout = scene->getChildByName<Sprite *>("Layout");
    auto layout1 = layout->getChildByName<Sprite *>("Layout1");
    auto sprite1 = layout1->getChildByName<Sprite *>("sprite");
    auto label   = layout1->getChildByName<Label *>("label");

  for(int i=0;i<score;i++){
        auto layout_0 = Sprite::create();
        layout_0->setName("layout");
        layout_0->setAnchorPoint(Vec2(0.5, 0.5));
        layout_0->setColor(Color3B(48, 47, 47));
        layout_0->setTexture("background2.png");
        layout_0->setPosition(Vec2(scroll->getPositionX()/3,2000));
        layout_0->setContentSize(layout->getContentSize());
        
        auto layout_1 = Sprite::create();
        layout_1->setTexture("background2.png");
        layout_1->setPosition(Vec2(layout1->getPositionX(),layout1->getPositionY()));
        layout_1->setColor(Color3B(255, 255, 255));
        layout_1->setContentSize(layout1->getContentSize());
        layout_0->addChild(layout_1);
        
        auto Sprite_start=Sprite::create();
        Sprite_start->setTexture("starSprite.png");
        Sprite_start->setPosition(sprite1->getPosition());
        Sprite_start->setContentSize(sprite1->getContentSize());
        layout_1->addChild(Sprite_start);
    
        auto label_0 = Label::create();
        label_0->setString("jaweklfjaiowjgifta");
        label_0->setColor(Color3B(0, 0, 0));
        label_0->setPosition(label->getPosition());
        label_0->setContentSize(label->getContentSize());
        layout_1->addChild(label_0);
        vector.pushBack(layout_0);
    }

取出数据,创建new 加载它。
当然一串的星星,不可能并排写,所以用%把Sprite 排开

    for(int i=0;i<score;i++){
        Sprite *layout=vector.at(i);
        //如果除以3 为0,那么增加一行。
        if(i%3==0){
         j++;
         }
         Vec2 vec(scroll->getPositionX()/3 +300 *(i%3),4800 -j*(layout->getContentSize().height+20));
         layout->setPosition(vec);
         layout->setName("ddddfdfafasd");
         scroll->addChild(layout,5);
    }

这样就可以排成一个每行3个图标。j行的代码。
当然如果这么完了,那么就没有意义了。
放进仓库里的Sprite 需要选择, 首先从把Vector里,放进update(float dt) 迭代。迭代区域选择的部分高亮。
在.h类中设置一个值 score_l。当作键盘值。
设置键盘监听
当按一下D值,score_l +1,当A score_l-1 ,当 按下s键score_l/6 的整数值为1的时候,那么显示区域增加%12,如果按下w那么如果score_l/9 整数为一 那么显示区域减少%12。


void Menu1Layer::onKeyPressed(EventKeyboard::KeyCode keyCode, cocos2d::Event *event){
    CCLOG("aaaaaa&&&&&&&&&&& %d",(int)keyCode);
    int c=score_l/6;
    int g=score_l/9;
    switch((int)keyCode){
            //D键
        case 127:
            score_l=score_l+1;
            break;
            //A键
        case 124:
            if(score_l>0&&score_l<score){
            score_l=score_l-1;
            }
            break;
            //W键
        case 146:
        	//注意调整显示区域。找了很久才找到,其他的没用!!!
            scroll->jumpToPercentVertical(g*15);
            if(score_l>=3){
                score_l=score_l-3;
            }
            break;
            //S键
        case 142:
            if(score-score_l>=3&&score_l+3<=score){
                score_l=score_l+3;
            }
            scroll->jumpToPercentVertical(c*12);
            break;
        case 6:
            creator::CreatorReader* reader = creator::CreatorReader::createWithFilename("cocosGameShao.ccreator");
            reader->setup();
            Scene *creatorGame=reader->getSceneGraph();
            ControlLayer *control1=ControlLayer::create();
            control1->init();
            control1->Scene_init(creatorGame);
            creatorGame->addChild(control1);
            Director::getInstance()->replaceScene(creatorGame);
            break;
    }
}

高亮部分

注意Sprite需要一个白色的图片做背景,才能setColor。 其他颜色或者没有调整不了。

    for(int i=0;i<vector.size();i++){
        Sprite *sprite=vector.at(i);
        if(i==score_l){
        	//高亮
            sprite->setColor(Color3B(232,201 ,100));
        }else{
        	//普通
            sprite->setColor(Color3B(72,71 ,71));
        }
    }

最后替换场景。跳转到游戏区域。

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 17
    评论
评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

昏暗的夜晚

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值