cocos飞机游戏地图滚动速度由快到慢的实现

时间:2021-04-26 14:56:16

相信大家都玩飞机射击游戏时,刚进入场景,感觉飞机飞速前进,然后速度慢慢变慢,最终到正常速度,然后开始正常的游戏。其实就是背景地图滚动由快到慢的过程。现在我们就是要实现这个功能,让地图滚动速度由快到慢。

  • 我们把这个功能封装到一个background类里面,然后再主场景的update函数里面进行调用。
  • 在给出之前我们先来讲解一下地图滚动的原理:在这次实现当中我们准备的是两张可以拼接在一起的图片(跟飞机游戏的屏幕大小一样),第一张图片放在屏幕正中心,第二张放在屏幕的上方,两张图片一起按照一个速度往下移动,当第一张图片移动到屏幕下面(第一张图片移动完毕,完全消失,这时第二张图片刚好在屏幕正中心)时,将第一张图片的位置调整为屏幕上方(还没开始移动时第二张图片的位置)。这样不断的移动,图片到下方就将图片移动到屏幕正上方,就形成了地图无限滚动的视觉效果。
    下面给出background类的定义和实现:
class Background :public Sprite
{
public :
    //创建地图
    static Background* create(std::string);
    bool init();
    //地图滚动逻辑,判断是否更换地图的位置。
    static void rollLogic(Background*, Background*);
    //地图滚动函数
    void backgroudMove();
private:
    //速度
    int m_speedx = 0;
    //速度的变化值
    static int m_speedy[4];
    //控制速度变化的时间计时器。
    static int m_timer ;
};

下面是类的实现:

int Background::m_timer = 288;
//速度是负值,方便计算
//速度的值一定要能被图片的高度所整除,稍后讲解!
int Background::m_speedy[] = {-6,-12,-16,-24};
Background*Background::create(std::string str)
{
    Background* ref = new Background;
    if (ref&&ref->init())
    {
        ref->initWithFile(str);
        ref->autorelease();
        return ref;
    }
    else
    {
        ref->release();
        return nullptr;
    }
}
bool Background::init()
{
    return true;
}
void Background::rollLogic(Background* bac1, Background* bac2)
{
    //判断第一张图片是否滚动完毕
    if (bac1->getPositionY() <= -bac2->getContentSize().height / 2)
    {
        bac1->setPositionY(bac2->getContentSize().height + bac2->getContentSize().height / 2);
    }
    //判断第二张图片是否滚动完毕
    if (bac2->getPositionY() <= -bac2->getContentSize().height / 2)
        bac2->setPositionY(bac2->getContentSize().height + bac2->getContentSize().height / 2);
}
void Background::backgroudMove()
{
    //在主场景每次调用这个函数地图就会移动,每调用一次计时器-1,
    //也就是当m_timer在288到216之间,地图移动速度都是24.
    //216到216-72 之间就是16的速度,以此类推,就实现了速度的由快到慢。
    if (m_timer>0)
    m_timer-=1;
    //log("%d", m_timer / 72);
    setPositionY(getPositionY() + m_speedy[m_timer/72]);
}
  • 对于速度必须要被图片高度所能整除,是因为我们这个地图移动算法必须满足这个要求,大家可以自己思考下,如果不能整除 ,就会出现两张图片在移动的过程中,中间会出现间隙,不能完美的连接在一起,大家可以自己试试。
    最后我们可以在主场景的update函数中来调用这个类的接口,进行图片的移动:
void mainsecen::update()
{
        //两张图片一起移动。
        m_ptbac1->backgroudMove();
        m_ptbac2->backgroudMove();
        //判断逻辑
        Background::rollLogic(m_ptbac1, m_ptbac2);
}

这样就OK,还是很简单呀。