【Cocos2dx】根据窗口大小进行拉伸

为了适应多平台、不同尺寸的设备,或者我们想省去修改一次游戏尺寸就改一次图片的麻烦。我们需要将Cocos2dx上的精灵,按照根据当前的屏幕大小进行拉伸。

虽然上次在《【Cocos2dx】使用CCScale9Sprite拉伸图片》(点击打开链接)介绍过如何在Cocos2dx利用Scale9Sprite进行图片的拉伸,然而,这样做出来的效果是静态的,拉伸之后出来的结果完全是一个不能对其进一步操作的CCScale9Sprite。

如果我们想做出如下的效果,比如每次创建cocos2dx工程之后,资源文件夹Resources都会自带如下的一张480x320的Helloworld.png图片:


然而我们要求的游戏大小是300x240,当然这只是举个例子而已,实际上经常是要在800x600甚至1024x576等大屏手机运行,同时做出《【Cocos2dx】连续滚动的场景》(点击打开链接)的背景滚动效果如下:


这时就不能用CCScale9Sprite,因为根据

【Cocos2dx】根据窗口大小进行拉伸_第1张图片

来来去去就是2张完全相同的、边缘紧贴图片在不停地交换位置,形成连续滚动的视觉效果的思想,

除了把2只背景精灵放上去以后,还要对其进行进一步操作,

说白了就是非静态。

制作过程如下,新建一个ScaleBackground的cocos2dx工程,如下图,在main.cpp修改游戏运行尺寸之后。

【Cocos2dx】根据窗口大小进行拉伸_第2张图片

对HelloWorldScene.h进行重点的修改。

首先是HelloWorldScene.h,没什么好讲的就是一大堆声明,删去原版一大堆没有用的代码之后,记得补上一句USING_NS_CC;否则过不了编译。

#include "cocos2d.h"
USING_NS_CC;//头文件就用到了CCxx,精灵声明的CCSprite
class HelloWorld:public cocos2d::CCLayer
{
public:
	virtual bool init();
	static cocos2d::CCScene* scene();	
	CREATE_FUNC(HelloWorld);
private:
	void background_rolling(float delta);//计时器函数
	//两只背景精灵,其实就是同一张图片
	CCSprite *sprite1;
	CCSprite *sprite2;
};

之后是HelloWorldScene.cpp,

(1)这里在初始化的时候,便已经对精灵缩放,将屏幕缩放的窗口大小的大小,直接套用公式:将精灵横向缩放 到 (屏幕宽度/精灵宽度) 的倍数。

此处屏幕宽度通过CCSize visibleSize=CCDirector::sharedDirector()->getVisibleSize();获取,值得注意的是CCSize visibleSize=CCDirector::sharedDirector()->getVisibleSize();不可以成为全局变量,必须处于每一个类函数中,否则所有setPosition()、getPositionX()的搞出来的数值是负数,我也不知道为什么,反正如果此类成员函数,要用到尺寸,都补上CCSize visibleSize=CCDirector::sharedDirector()->getVisibleSize();声明一下就对了。

而精灵宽度通过spriteX->getTextureRect().getMaxY()来获取

(2)Cocos2dx的计时器的使用请看《【Cocos2dx】计时器的使用,计时器的嵌套,与在计时器中延时执行一段代码》(点击打开链接),这里不再赘述。

(3)两背景同时向左滚动的时候,判断其是否完全离开屏幕,就是判断其中心点是否已经到达 X轴 -屏幕宽度/2 这个位置。之后将其打回到X轴 屏幕宽度+屏幕宽度/2,这个位置,之后还要在后面向前移一个帧的移动速度,是因为实际测试的时候,发现不减ROLLING_SPEED,是会出现一个黑条的间隔的,不知道为什么,补上ROLLING_SPEED就完美了。

#include "HelloWorldScene.h"
#define FRAME_TIME 0.05f//每帧时间
#define ROLLING_SPEED 4//滚动速度,这里的4,意为每帧移动的像素值
//场景声明,一字未改
CCScene* HelloWorld::scene()
{
	CCScene *scene=CCScene::create();
	HelloWorld *layer=HelloWorld::create();
	scene->addChild(layer);
	return scene;
}

bool HelloWorld::init()
{    
	CCSize visibleSize=CCDirector::sharedDirector()->getVisibleSize();//获取屏幕大小

	//精灵声明
	sprite1=CCSprite::create("HelloWorld.png");
	sprite1->setPosition(ccp(visibleSize.width/2,visibleSize.height/2));
	//将精灵缩放到屏幕大小
	sprite1->setScaleX(visibleSize.width/sprite1->getTextureRect().getMaxX());
	sprite1->setScaleY(visibleSize.height/sprite1->getTextureRect().getMaxY());	
	this->addChild(sprite1,0);    

	sprite2=CCSprite::create("HelloWorld.png");
	sprite2->setPosition(ccp(visibleSize.width+visibleSize.width/2,visibleSize.height/2));
	sprite2->setScaleX(visibleSize.width/sprite2->getTextureRect().getMaxX());
	sprite2->setScaleY(visibleSize.height/sprite2->getTextureRect().getMaxY());	
	this->addChild(sprite2,0);  

	this->schedule(schedule_selector(HelloWorld::background_rolling),FRAME_TIME);//开启一个计时器,此计时器每FRAME_TIME执行一次  
	return true;
}

void HelloWorld::background_rolling(float delta){//这段代码每FRAME_TIME执行一次  
	CCSize visibleSize=CCDirector::sharedDirector()->getVisibleSize();    
	sprite1->setPositionX(sprite1->getPositionX()-ROLLING_SPEED);//向左移动ROLLING_SPEED
	sprite2->setPositionX(sprite2->getPositionX()-ROLLING_SPEED);
	if(sprite1->getPositionX()<-visibleSize.width/2){//如果这个背景已经完全移出屏幕
		sprite1->setPositionX(visibleSize.width+visibleSize.width/2-ROLLING_SPEED);//打回到最后
	}
	if(sprite2->getPositionX()<-visibleSize.width/2){
		sprite2->setPositionX(visibleSize.width+visibleSize.width/2-ROLLING_SPEED);
	}
}



你可能感兴趣的:(背景,缩放,cocos2dx,滚动,拉伸)