cocos2d-x 游戏创作过程(-)

游戏开发过程

开发一款自己的游戏。:

  • 熟悉c++
  • 页面跳转
  • 制作动画
  • box2d的引用
  • box2d的具体 状态
  • 问题

cocos2d-x 可以用C++来写的语言

在创建 游戏的时候 对于类的创建。用的是 xxxxx *fff. = xxxxx::create(); 内置的预编译就可以帮助你创建需要的类。


#define CREATE_FUNC(__TYPE__) \
static __TYPE__* create() \
{ \
    __TYPE__ *pRet = new(std::nothrow) __TYPE__(); \
    if (pRet && pRet->init()) \
    { \
        pRet->autorelease(); \
        return pRet; \
    } \
    else \
    { \
        delete pRet; \
        pRet = nullptr; \
        return nullptr; \
    } \
}

就是这样的一个预编译。 所以创建之初 在xxx.h中 CREATE_FUNC(xxxxx); 当然要
include “cocos2d.h”


cocos2d-x 的场景跳转

这很简单 ,因为场景的引用多数是由于 导演来控制的。 也就是说用director->runWithScene(startScene);


    SceneManager *manager = new SceneManager();
    manager->createScene();
    director->runWithScene(manager->startScene);

也就是说 需要创建一个中间类调配 场景的变换。所以我创建了一个SceneManager 去管理场景。当场景替换的时候导演进行就可以了。 所以场景跳转也不是什么问题。

    Director::getInstance()->replaceScene(gameScene);

cocos2d-x 制作动画

制作动画的问题的难点还是动画的制作 。 比如画一个连续的画 。 最开始我以为需要7个连续的动作就可以形成一幅画。 连贯动作但是后来发现 除了左腿还有右腿 。所以连贯的画至少需要14幅。 才可以出现连贯的动作这一点很困难。

  1. cocos2d-x 游戏创作过程(-)_第1张图片

放在程序上实际上也是很简单的。用cocos2d 给的软件。 去综合所有图片去 生成一个plist文件。 然后再读区他,就可以了。

而读取的时候 只需要创建spriteFrameCache. 读区 plist文件 。和 一张综合的png的图片就可以了。
plist 就是那张png图片的坐标。

 Vector*> spriteFrameVec;
    spriteFrameCache = SpriteFrameCache::getInstance();
    spriteFrameCache->addSpriteFramesWithFile("Animation10.plist","Animation10.png");
    char path[256] ={0};
    for(int i=1;i<=6;i++){
        sprintf(path, "picture%d.png", i);
        log("path = %s", path);
        SpriteFrame *pSpriteFrame = spriteFrameCache->getSpriteFrameByName(path);
        spriteFrameVec.pushBack(pSpriteFrame);
    }

这样就可以把帧动画的坐标传入一个集合中去。 然后用Animation 去遍历集合。然后不断的设置无线循环它。

    auto animation = Animation::createWithSpriteFrames(spriteFrameVec, 0.1);
    animation->setDelayPerUnit(2.8f / 60.0f);//必须设置否则不会动态播放
    animation->setRestoreOriginalFrame(true);//是否回到第一帧
    animation->setLoops(-1);//重复次数 (-1:无限循环)
    finiteTimeAction = Animate::create(animation);

当想启动的时候只需要 你定义的精灵 sprite runAction(this->getFiniteTimeAction()) ;就可以了。
而关闭。就用this->getSprite()->stopAllActions();


box2d的引用

本来希望用的内置引擎作为基础,制作一个打弹球,但是内置引擎的缺点时,刚体总是不断的晃动,无法再一个位置保持静止。 所以问题很严重。而且很容易两个刚体重合不分开,需要手动制作。 所用用box2d来制作游戏刚体。是正确的。

    Size s = Director::getInstance()->getVisibleSize();

    //重力参数
    b2Vec2 gravity;
    gravity.Set(0.0f, -60.0f);
    //创建世界
    world = new b2World(gravity);
    // 允许物体是否休眠
    world->SetAllowSleeping(true);
    // 开启连续物理测试
    world->SetContinuousPhysics(true);
    //
    retain();

创建世界这很简单,还需要设置一些什么。 这样容易。 世界的变化,遵循重力的变化,你可以设置。而里边刚体的移动变化需要迭代才能变化。
而box2d 的迭代 是迭代世界所有刚体,如果有那么根据物理定律调整它的物理位置。

void ControlLayer::update(float dt){
    float timeStep = 0.03f;
    int32 velocityIterations = 1;
    int32 positionIterations = 8;
   //世界的迭代。
    world->Step(timeStep, velocityIterations, positionIterations);

    for (b2Body* b = world->GetBodyList(); b; b = b->GetNext())
    {
        if (b->GetUserData() != nullptr) {
            Sprite* sprite = (Sprite*)b->GetUserData();
            sprite->setPosition( Vec2( b->GetPosition().x *PTM_RATIO, b->GetPosition().y * PTM_RATIO) );
            sprite->setRotation( -1 * CC_RADIANS_TO_DEGREES(b->GetAngle()) );
        }
    }
 }

box2d的具体 状态

现在我所开发的游戏,其实很简单 只是一个像魂斗罗一样的游戏而已。 所以我加上了。 手动摇杆。 和tmx瓦片形成的地图。
为整个地图附上刚体。 虽然把精灵附上刚体,很容易。 但是我在tmx上自动检测瓦片,然后针对瓦片 赴上刚体。 这个很难找到。
在cocos2d-x的书上有写上,在瓦片附上键值对, 再搜索键值对 用精灵的坐标在 那层瓦片上检测。 就可以判断碰撞检测, 但是无法把瓦片赋上物理的刚体。 然后用刚体去碰撞。 查遍了书,好像没有。
然后我就尝试一下找到了瓦片的坐标。然后 遍历所有瓦片。 把瓦片的GID编号,如果是相同的GID 就可以敷上一层属性的刚体。

void MapLayer::initMap(){
     int t=0;
    _background =_titleMap->getLayer("_background");
    for(int i=0;i<=99;i++){
        for(int j=0;j<=49;j++){
            log("方块!!!!!");
            int titleGid = _background->getTileGIDAt(Vec2(i,j));
            if(titleGid>0){
                CCLOG("i= %d, j = %d",i,j);
                CCLog("error buffer:%d" ,titleGid);
                if(titleGid == 1){         
                    log("fffffAAAAAA");
                    auto sprite = Sprite::create("map/collidable_tiles1.jpg");
                    Vec2 vec0=_background->getPositionAt(Vec2(i,j));
                    Vec2 vec=Vec2(vec0.x+16, vec0.y+16);
                    sprite->setTag(t);

                    CCLOG("vec = %d,,,,,,,vec1 = %d",vec.x,vec.y);
                    this->addChild(sprite,1);
                    CCLOG("t = %d",sprite->getTag());
                     t++;
                    b2BodyDef bodyDef;
                    bodyDef.type = b2_staticBody;
                    bodyDef.position.Set(vec.x/32, (vec.y/32));
                    b2Body *body=world->CreateBody(&bodyDef);
                    body->SetUserData(sprite);
                    b2PolygonShape dynamicBox;
                    dynamicBox.SetAsBox(0.5, 0.5);
                    b2FixtureDef fixtureDef;
                    fixtureDef.shape = &dynamicBox;
                    body->CreateFixture(&fixtureDef);
                }
            }
         }
    }
    this->setTMXLayer(_background);
}

cocos2d-x 游戏创作过程(-)_第2张图片

cocos2d-x 游戏创作过程(-)_第3张图片

这带来了很多的问题。


box2d的问题。

  1. 问题来了 很严重的问题。 就是视角很难移动。首先刚体状态下的地图,就算是移动了MapLayer->setposition(); 刚体还是在固定的坐标。而不会因为整座Layer移动而移动。
  2. 所以只能用
 b2Vec2 b2vec = b2Vec2((this->body->GetPosition().x)-0.2,body->GetPosition().y);
 body->SetTransform(b2vec,mapLayer->getRotation());

移动整座刚体来制作视角的移动。 但是这么做了, 就会导致游戏越来越慢, 性能浪费了很多。
因为要移动很多刚体,如果地图很大,同时移动的刚体会更多。 然后导致系统死机。

所以现在为止,我还没遇到什么好办法。 求大神帮忙。 如果地图不移动只移动主角,那么会被限制在一个很小的屏幕中。

你可能感兴趣的:(cocos2d,c++,box2d开发,box2d)