Cocos2d项目实战之飞机大战(二)----背景滚动

494 阅读3分钟

首先我们需要修改一下AppDelegate.cpp文件,需要把分辨率设置成图片大小。我们资源文件的图片背景都是480*800的尺寸,所以我们需要设置一下

#include "AppDelegate.h"
#include "HelloWorldScene.h"

USING_NS_CC;

//把designResolutionSize的尺寸设置为480*800
static cocos2d::Size designResolutionSize = cocos2d::Size(480, 800);
static cocos2d::Size smallResolutionSize = cocos2d::Size(480, 320);
static cocos2d::Size mediumResolutionSize = cocos2d::Size(1024, 768);
static cocos2d::Size largeResolutionSize = cocos2d::Size(2048, 1536);

AppDelegate::AppDelegate() {

}

AppDelegate::~AppDelegate() 
{
}

void AppDelegate::initGLContextAttrs()
{
    GLContextAttrs glContextAttrs = {8, 8, 8, 8, 24, 8};

    GLView::setGLContextAttrs(glContextAttrs);
}

static int register_all_packages()
{
    return 0;
}

bool AppDelegate::applicationDidFinishLaunching() {
    auto director = Director::getInstance();
    auto glview = director->getOpenGLView();
    if(!glview) {
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) || (CC_TARGET_PLATFORM == CC_PLATFORM_MAC) || (CC_TARGET_PLATFORM == CC_PLATFORM_LINUX)
        glview = GLViewImpl::createWithRect("Plane", Rect(0, 0, designResolutionSize.width, designResolutionSize.height));
#else
        glview = GLViewImpl::create("Plane");
#endif
        director->setOpenGLView(glview);
    }

    //这段代码是在窗口的左下角显示fps信息,不需要显示,给false
    director->setDisplayStats(false);
    director->setAnimationInterval(1.0 / 60);

    glview->setDesignResolutionSize(designResolutionSize.width, designResolutionSize.height, ResolutionPolicy::NO_BORDER);
    
	//这段代码是做屏幕适配的,暂时可以注释掉不要
	//Size frameSize = glview->getFrameSize();
    //// if the frame's height is larger than the height of medium size.
    //if (frameSize.height > mediumResolutionSize.height)
    //{        
    //    director->setContentScaleFactor(MIN(largeResolutionSize.height/designResolutionSize.height, largeResolutionSize.width/designResolutionSize.width));
    //}
    //// if the frame's height is larger than the height of small size.
    //else if (frameSize.height > smallResolutionSize.height)
    //{        
    //    director->setContentScaleFactor(MIN(mediumResolutionSize.height/designResolutionSize.height, mediumResolutionSize.width/designResolutionSize.width));
    //}
    //// if the frame's height is smaller than the height of medium size.
    //else
    //{        
    //    director->setContentScaleFactor(MIN(smallResolutionSize.height/designResolutionSize.height, smallResolutionSize.width/designResolutionSize.width));
    //}

    //register_all_packages();

    auto scene = HelloWorld::createScene();

    director->runWithScene(scene);

    return true;
}

void AppDelegate::applicationDidEnterBackground() {
    Director::getInstance()->stopAnimation();
}

void AppDelegate::applicationWillEnterForeground() {
    Director::getInstance()->startAnimation();
}

要实现背景滚动功能,我在这里创建了一个背景类Bg。

Bg.h

#pragma once
#include "cocos2d.h"
using namespace cocos2d;
//背景是可移动的精灵
class Bg : public Sprite {
private:
	float speed;
public:
	static Bg* create();//创建方法
	bool init() override;//初始化的方法
	void update(float dt);
	Bg();
	~Bg();
};

Bg.cpp

#include "Bg.h"

Bg::Bg() :speed(100) {
}

Bg::~Bg() {

}

Bg* Bg::create() {
	//1.申请Bg的内存
	Bg* ret = new(std::nothrow) Bg();
	//2.判断ret不等于空且初始化成功
	if (ret && ret->init()) {
		//3.加入自动释放池
		ret->autorelease();
		return ret;
	}

	delete ret;
	ret = nullptr;
	return ret;
}

bool Bg::init() {
	//调用父类Sprite的initWithFile方法
	if (!Sprite::initWithFile("image/bg/bg1.jpg")) {
		return false;
	}
	//设置自己的锚点
	setAnchorPoint(Vec2(0, 0));
	//开启默认调度器
	scheduleUpdate();
	return true;
}

void Bg::update(float dt) {
	// 背景向下滚动
	float y = getPositionY();
	y = y - speed * dt;
	//当前背景的y<=图片的高度时
	float h = getContentSize().height;

	if (y <= -h) {
		//为了避免有缝隙的产生,我们需要对y轴进行一个判断
		y = y + h * 2;
	}
	setPositionY(y);
}

在bg.h文件中我重写了默认调度器方法,因为背景滚动是需要一直执行的一个操作,放在调度器里面最合适。这里背景滚动的思想就是图片会一直向下移动,当图片移出了屏幕的范围,就把这张图片设置到屏幕的最上方,接着往下移动。

HelloWorldScene.cpp编写创建背景的逻辑

#include "HelloWorldScene.h"
#include "Bg.h"

USING_NS_CC;

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

	return scene;
}

bool HelloWorld::init() {
	if (!Layer::init()) {
		return false;
	}

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

	//创建背景
	for (int i = 0; i < 2; i++) {
		Bg* bg = Bg::create();
		float h = bg->getContentSize().height;
		bg->setPositionY(i * h);
		this->addChild(bg, 0);
	}

	return true;
}

因为背景滚动使用一张图片是完成不了滚动效果的,我们需要两张,把第二张图片的位置设置在第一张图片高度之上。等第一张图片移出屏幕的那一刻,第二张图片就往下移动,然后第一张图片在移动到第二张图片的高度之上,这样就实现了背景滚动的效果