昨天实现了从ccs中导出一个动画给2dx使用。不妨就把他当成游戏的主角。今天要实现另外一个基本元素————地图。
ccs提供了地图编辑器,但是做横版四方向游戏还是推荐使用tiled编辑器。他本身是一个开源的地图编辑器,而且在2dx中使用起来很方便。
tiled拼接完成后会有一个后缀名为.tmx的地图文件和对应的图片文件。把这些资源放入2dx的资源文件夹中。接下来就是在代码中去使用他了。
CCTMXTiledMap* tmxmap = CCTMXTiledMap::create("map/cxuchang.tmx");
addChild(tmxmap);
在昨天的那个hello层中通过这两行代码创建添加了一个tmx地图,效果如下:
可以看到主角站在了地图上(无视那个按键吧,后面会提到他的)。
由于实际使用中,可能会有一些层要遮盖在主角前面,为此在tiled中编辑地图文件。新建一个图层,然后放上你要的遮盖物。在这里我放上了几把刀子,现在这个地图文件有两个图层了。把主角的z轴设在底下的那层来实现遮盖
setZOrder(tmxmap->layerNamed("ground1")->getZOrder());
效果如下:
可以看到,主角站在了地面的前面和刀子的后面。
接下去,我们要让主角动起来。为此我给他添加了一个layer来接受触摸消息。就是上图看到的大大的按钮啦。这个不在文章的讨论范围内,就不具体讨论怎么实现了。
为了让主角动起来,我添加了一个动画角色类,里面有一些可能会用到的参数。
//动作名称,和ccs中的对应
extern char* actIdname[ActIDTotal] ;
class AniNode :public CCNode
{
//x轴速度
MY_PROPERTY_READONLY(float,xspeed,xspeed);
//y轴速度
MY_PROPERTY_READONLY(float,yspeed,yspeed);
//骨骼动画
MY_PROPERTY_READONLY(CCArmature*,Myarmature,Myarmature);
//当前动作
MY_PROPERTY_READONLY(int32_t,curActId,curActId);
public:
AniNode();
~AniNode();
//上一帧动作朝向
int8_t preactDir;
//上一帧位移朝向
int8_t premoveDir;
//位移朝向
int8_t moveDir;
//动作朝向
int8_t actDir;
// Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone
virtual void update(float);
virtual void draw();
//帧事件回调函数
virtual void onFrameEvent(CCBone *bone, const char *evt, int originFrameIndex, int currentFrameIndex);
//设置动作函数
void setActid(int32_t,bool );
};
第一步,让主角在屏幕上位移。主角现在是有x轴速度和y轴速度的属性了,在主角的update函数中去换算这一定时器产生的位移
setPositionY(dt*yspeed+getPositionY());
setPositionX(dt*xspeed+getPositionX());
这里速度的单位都是像素/秒。现在我们只要给主角的速度赋值,他就可以动起来了。第二步,让主角播放动画。主角现在有当前动作这个属性,在setActid函数中改变他的动作状态
//不强制执行
if(!isenforce)
{
//动作的优先级更高,或者相同动作不同朝向
if(curActId>this->curActId||(actDir!=preactDir&&curActId==this->curActId))
{
this->curActId = curActId;
Myarmature->getAnimation()->play(actIdname[curActId]);
}
else
return;
}//强制执行
else
{
this->curActId = curActId;
Myarmature->getAnimation()->play(actIdname[curActId]);
}
}
现在我们在给主角速度的时候设置他的状态为跑步,他就跑起来啦。可是主角还不能够翻转,在setActid中添加
switch(actDir)
{
case DirRight:case DirRightDown:case DirRightUp:
setScaleX(-1*abs(getScaleX()));
break;
case DirUp:case DirDown:
break;
default:
setScaleX(1*abs(getScaleX()));
break;
}
根据主角的动作朝向来做翻转。主角就可以自由自在的跑在地图上了。接下来让镜头跟随主角移动。这里用了2dx本身有的一个follow动作
CCFollow* follow = CCFollow::create((CCNode*)armature, CCRectMake(0, 0, tmxmap->getContentSize().width*tmxmap->getScaleX(),tmxmap->getContentSize().height*tmxmap->getScaleY()));
第一个参数是跟随的对象,后面则设定了跟随者地图的矩形。run这个动作来保证主角始终在屏幕中央。
这样一来,主角就可以自由的移动了。