您的位置:首页 > 移动开发 > Cocos引擎

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

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

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

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



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



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



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

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

说白了就是非静态。

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



对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);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: