《一个都不能死》 游戏开发 (物理引擎)

《一个都不能死》 游戏开发 (物理引擎)

//创建物理场景
auto scene = Scene::createWithPhysics();
//设置重力
scene->getPhysicsWorld()->setGravity(Vec2(0,-1000));

Scene* HelloWorld::createScene()
{
    // 'scene' is an autorelease object
    //auto scene = Scene::create();
    auto scene = Scene::createWithPhysics();
    //scene->getPhysicsWorld()->setDebugDrawMask(PhysicsWorld::DEBUGDRAW_ALL);
    scene->getPhysicsWorld()->setGravity(Vec2(0,-1000));

    // 'layer' is an autorelease object
    auto layer = HelloWorld::create();

    // add layer as a child to scene
    scene->addChild(layer);

    // return the scene
    return scene;
}

// on "init" you need to initialize your instance
bool HelloWorld::init()
{
    //////////////////////////////
    // 1. super init first
    if (!LayerColor::initWithColor(Color4B(255, 255, 255, 255)))
    {
        return false;
    }

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

    //gcs.pushBack(GameController::create(this, 30));
    gcs.insert(0, GameController::create(this, 30));
    //gcs.insert(0, GameController::create(this, 250));

    scheduleUpdate();

    //创建碰撞检测监听
    auto listener = EventListenerPhysicsContact::create();
    listener->onContactBegin = [this](PhysicsContact &contact){
        this->unscheduleUpdate();

        Director::getInstance()->replaceScene(GameOver::createScene());

        return true;

    };

    Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener, this);

    //添加点击监听
    auto touchListener = EventListenerTouchOneByOne::create();
    touchListener->onTouchBegan = [this](Touch * t, Event *e){

        for (auto it = gcs.begin(); it != gcs.end(); it++){
            if ((*it)->hitTestPoint(t->getLocation())){
                (*it)->onUserTouch();
                break;
            }
        }
        return false;
    };
    Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(touchListener, this);



    return true;
}
void HelloWorld::update(float dt)
{
    for (auto it = gcs.begin(); it != gcs.end(); it++)
    {
        (*it)->onUpdate(dt);
    }
}

创建一个物理世界边缘(一般是窗口大小),

class Edge:public Node{
public:
    virtual bool init();
    CREATE_FUNC(Edge);
};

bool Edge::init(){
    Node::init();

    Size visibleSize = Director::getInstance()->getVisibleSize();
    //创建一个物理世界边缘
    setPhysicsBody(PhysicsBody::createEdgeBox(visibleSize));

    setContentSize(visibleSize);
    return true;
}

创建人物(刚体)

class Hero :public Sprite{
public:
    virtual bool init();
    CREATE_FUNC(Hero);

};

bool Hero::init(){
    Sprite::init();

    Size s = Size(44, 52);

    runAction(RepeatForever::create(FlashTool::readJsonSpriteSheet("Hero.json", 0.2f)));

    setPhysicsBody(PhysicsBody::createBox(s));
    setContentSize(s);

    //被撞击后不旋转
    getPhysicsBody()->setRotationEnable(false);
    //开启碰撞检测
    getPhysicsBody()->setContactTestBitmask(1);
    //getPhysicsBody()->setCategoryBitmask(1);

    //getPhysicsBody()->setCollisionBitmask(1);


    return true;
}

创建阻挡物

class Block :public Sprite{
public:
    virtual bool init();

    //实现向左移动  超出后删除
    virtual void update(float dt);
    CREATE_FUNC(Block);


};


bool Block::init(){
    Sprite::init();

    Size s = Size((rand() % 20) + 5, (rand()%30) + 10);

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

    setPhysicsBody(PhysicsBody::createBox(s));
    setTextureRect(Rect(0, 0, s.width, s.height));
    setColor(Color3B(0,0,0));
    setContentSize(s);

    setPositionX(visibleSize.width);
    scheduleUpdate();

    //设置静态,不会因为人物卡住 持续运动
    getPhysicsBody()->setDynamic(false);
    //设置碰撞检测
    getPhysicsBody()->setContactTestBitmask(1);

    return true;
}

void Block::update(float dt)
{
    this->setPositionX(getPositionX() - 3);
    if (getPositionX() < 0){    
        unscheduleUpdate();
        removeFromParent();
    }
}

//创建控制器

class GameController :public Ref{
private:
    Layer *_layer;
    float _positionY;
    Size visibleSize;
    int currentFrameIndex;
    int nextFrameCount;
    Edge *edge;
    Hero *hero;

private:
    void resetFrames();
    void addBlock();
public:
    virtual bool init(Layer *layer,float positionY);
    //每过一段时间添加一个障碍物
    void onUpdate(float dt);
    //是否包含点  用于判断用户点击的位置是否在edgebody中 
    bool hitTestPoint(Vec2 point);
    //用户点击后给英雄一个向上的冲力。
    void onUserTouch();

    static GameController * create(Layer *layer, float position);
};



GameController * GameController::create(Layer *layer, float position)
{
    auto _ins = new GameController();
    _ins->init(layer, position);
    _ins->autorelease();

    return _ins;

}

bool GameController::init(Layer *layer, float positionY)
{
    _layer = layer;
    _positionY = positionY;

    visibleSize = Director::getInstance()->getVisibleSize();

    //add edge
    edge = Edge::create();
    edge->setPosition(visibleSize.width / 2, visibleSize.height / 2 + positionY);
    edge->setContentSize(visibleSize);
    layer->addChild(edge);

    //add ground
    auto ground = Sprite::create();
    ground->setColor(Color3B(0, 0, 0));
    ground->setTextureRect(Rect(0, 0, visibleSize.width, 3));
    ground->setPosition(visibleSize.width/2, 1.5 + positionY);
    layer->addChild(ground);
    //add hero
    hero = Hero::create();
    hero->setPosition(50, hero->getContentSize().height/2 + positionY);
    layer->addChild(hero);

    resetFrames();
    return true;
}

void GameController::resetFrames()
{
    currentFrameIndex = 0;
    nextFrameCount = (rand() % 120) + 100;
}

void GameController::addBlock()
{
    auto b = Block::create();
    _layer->addChild(b);
    b->setPositionY(b->getContentSize().height / 2 + _positionY);


}
void GameController::onUpdate(float dt)
{
    currentFrameIndex++;
    if (currentFrameIndex >= nextFrameCount){
        resetFrames();
        addBlock();
    }
}

bool GameController::hitTestPoint(Vec2 point)
{
    return edge->getBoundingBox().containsPoint(point);
}

void GameController::onUserTouch()
{
    hero->getPhysicsBody()->setVelocity(Vec2(0, 400));
}

猜你喜欢

转载自blog.csdn.net/wu745187355/article/details/45047037