使用TileMap制作游戏,在cocos2d-x中使用(二)

本篇博客出自阿修罗道,转载请注明出处:http://blog.csdn.net/fansongy/article/details/8877118


书接前文。

创造出世界之后要制定规则。游戏中有些地方是不可以穿过的。有些地方是会触发特殊效果的。现在来实现。

墙壁、石堆、牌子这些都是不可以穿过的。

首先在TileMap中编辑一下,大概方法是创建一个新层,专门负责碰撞部分。

具体可见:子龙翻译的 http://www.cnblogs.com/andyque/archive/2011/05/03/2033620.html 

编辑好了之后保存,替换到工程中。

开始编码。

首先要取得控制层,另外这层也不能显示出来。

头文件中增加:

	CCTMXLayer* m_meta;

在init中显示tmx之前加入:

		m_meta = m_tileMap->layerNamed("Meta");
		m_meta->setVisible(false);

接下来是Gid的转换。将点的坐标转化到相应的格子中,即取得究竟想获取信息的贴图是哪张。


使用TileMap制作游戏,在cocos2d-x中使用(二)_第1张图片

没找到Qt版本的怎么显示这个数字。另外似乎没有写好的函数,有的话请留言告诉一下 哈 。自己写:

CCPoint HelloWorld::posToMapBlock(CCPoint pos)
{
	int x = pos.x / m_tileMap->getTileSize().width;
	int y = ( m_tileMap->getContentSize().height - pos.y)/m_tileMap->getTileSize().height;
	return ccp(x,y);
}


有了这个坐标点就可以找出Gid了。这东西就是个Key。value就是图源的属性表,以字典形式返回。

这部分加在响应里。

	CCPoint pConverted = posToMapBlock(ccp(moveTo.x,moveTo.y));
	int tileGID = m_meta->tileGIDAt(pConverted);
	if(tileGID)
	{
		CCDictionary* pro = m_tileMap->propertiesForGID(tileGID);
		if(pro)
		{
			CCString* collision =const_cast<CCString*>(pro->valueForKey("Collidable"));
			if(collision && collision->compare("true") == 0)
			{
				return;
			}
		}
	}


行了,有这个gid返回的字典,就可以取到在地图中设定的信息。数据、消息一到位,也就基本完成了。

编译运行,就成了。

有限制不够,还要有奖励。地图上的西瓜可以吃掉,加个血什么的。

新建一个层,专门放西瓜。把之前的西瓜挪到这层中。在meta层用绿色的块填充这部分,并设置属性。

具体可以看一开始那个外链。

接下来就是要弄一个层专门显示吃掉的西瓜数了。

自己写个ScoreScene:

#pragma once
#include "cocos2d.h"
USING_NS_CC;

class ScoreLayer:public CCLayer
{
public:
	CREATE_FUNC(ScoreLayer);
	virtual bool init();
	void numberadd();
private:
	CCLabelTTF* m_label;
	int m_score;
};


#include "ScoreLayer.h"

bool ScoreLayer::init()
{
	bool bRet = false;
    do 
    {
        CC_BREAK_IF(! CCLayer::init());
	CCSize winSize = CCDirector::sharedDirector()->getWinSize();
	m_label = CCLabelTTF::create();
	m_label->initWithString("0","Verdana-Bold",18);
	m_label->setColor(ccc3(0,0,0));
	int magin = 10;
	m_label->setPosition(ccp(winSize.width - m_label->getContentSize().width/2 - magin,
		m_label->getContentSize().height + magin));
	m_score = 0;
	this->addChild(m_label);
	bRet = true;
    }while(0);
    return bRet;
}
void ScoreLayer::numberadd()
{
	m_score++;
	m_label->setString(CCString::createWithFormat("%d",m_score)->getCString());	
}


没什么可解释的。

在HelloWorld.cpp中创建一个全局变量:

ScoreLayer *score_layer;


在scene中加入这个Layer:

score_layer = ScoreLayer::create();
CC_BREAK_IF(! score_layer);
scene->addChild(score_layer);


这样就可以显示了,更改数值的部分自然是要放到响应中了。

CCString* collectable = const_cast<CCString*>(pro->valueForKey("Collectable"));
if(collectable && collectable->compare("true") == 0)
{
	//此处地图已经更改过了,将西瓜放在foreground上了。
	m_meta->removeTileAt(pConverted);
	m_foreground->removeTileAt(pConverted);
	score_layer->numberadd();
}

此处要注意。这个层是与HelloWorld同级的。helloWorld是主场景,自然是要动的。这个层是状态场景,不可以移动。

它们都应该是在Scene层的管制之下,互相之间是不应该有关联的。

此处我是用全局变量了,这种最省事的方法。大型项目的话应该封一个管理的类,不然该乱了。

行了,编译运行就成了。

0资源分 代码:http://download.csdn.net/detail/fansongy/5323719



你可能感兴趣的:(使用TileMap制作游戏,在cocos2d-x中使用(二))