1. 程式人生 > >cocos2d-x學習日誌(1)--視角跟隨主角

cocos2d-x學習日誌(1)--視角跟隨主角

本篇講解一個主視角跟隨主角的效果,先上效果圖。


很簡單,就是整個視角(螢幕)隨主角的移動而移動,這在ARPG,ACT等遊戲中非常常用,首先看一下我們程式的結構。

在HelloWorldScene.h中新增如下:

#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__

#include "cocos2d.h"

#include "SimpleAudioEngine.h"
using namespace cocos2d;

class HelloWorld : public cocos2d::CCLayer
{
public:
    // Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone
    virtual bool init();  

    // there's no 'id' in cpp, so we recommand to return the exactly class pointer
    static cocos2d::CCScene* scene();
    
    // a selector callback
    void menuCloseCallback(CCObject* pSender);


	//ADD Begin
	CCSprite* m_tamara;
	void update(float dt);
	//ADD End

    // implement the "static node()" method manually
    CREATE_FUNC(HelloWorld);
};

#endif  // __HELLOWORLD_SCENE_H__

場景方法很簡單,就是建立場景,並加入我們例子的核心部分----層

在HelloWorldScene.cpp中新增如下:
//ADD Begin
using namespace CocosDenshion;
enum{
	//!Default tag
	KtagTileMap,
};
//ADD End
// on "init" you need to initialize your instance
bool HelloWorld::init()
{
	if (!CCLayer::init())
	{
		return false;
	}
	CCMenuItemImage *pCloseItem = CCMenuItemImage::create(
		"CloseNormal.png",
		"CloseSelected.png",
		this,
		menu_selector(HelloWorld::menuCloseCallback));
	pCloseItem->setPosition(ccp(CCDirector::sharedDirector()->getWinSize().width-20,20));
	//create menu,it's an autorelease object
	CCMenu* pMenu = CCMenu::create(pCloseItem,NULL);
	pMenu->setPosition(CCPointZero);
	this->addChild(pMenu,1);

	CCParallaxNode* voidNode = CCParallaxNode::create();
	//新增資源路徑
	CCTMXTiledMap *map = CCTMXTiledMap::create("iso-test-zorder.tmx");
	this->addChild(map,0,KtagTileMap);
	//cocos2d-x中使用getContentSize獲得的就是邏輯點的大小
	CCSize s = map->getContentSize();
	CCSize winSize = CCDirector::sharedDirector()->getWinSize();
	map->setPosition(ccp(-s.width/2+winSize.width/2,0));

	m_tamara = CCSprite::create("grossinis_sister1.png");
	map->addChild(m_tamara,map->getChildren()->count());
	m_tamara->retain();
	int mapWidth = map->getMapSize().width * map ->getTileSize().width;
	m_tamara->setPosition(ccp(mapWidth/2,0));
	m_tamara->setAnchorPoint(ccp(0.5f,0));
	CCActionInterval* move = CCMoveBy::create(10,ccpMult(ccp(300,250),1/CC_CONTENT_SCALE_FACTOR()));
	CCActionInterval* back = move->reverse();
	CCFiniteTimeAction* seq = CCSequence::create(move,back,NULL);
	m_tamara->runAction(CCRepeatForever::create((CCActionInterval*)seq));
	scheduleUpdate();
	return true;
}

/*場景的初始化就是首先通過tmx檔案定義地圖,然後定義主角,並把主角放在地圖上,然後為主角定義動作,來回運動,然後加入scheduleUpate,使得每幀呼叫update。在update中我們將修改我們的視角。*/

void HelloWorld::update(float dt)
{
	char mch[256];
	CCPoint herop = m_tamara->getPosition();
	sprintf(mch,"x->%.2f---y->%.2f",herop.x,herop.y);
	CCLog(mch);
	CCTMXTiledMap* map = (CCTMXTiledMap*)getChildByTag(KtagTileMap);
	int mapWidth = map->getMapSize().width * map->getTileSize().width;
	float deltax = herop.x - mapWidth/2;
	float deltay = herop.y;
	CCSize s = map->getContentSize();
	CCSize winSize = CCDirector::sharedDirector()->getWinSize();
	map->setPosition(ccp(-s.width/2+winSize.width/2-deltax,-deltay));
}

在update中,我們獲得主角的位置,並把它和主角初始座標作比較,得到deltax和deltay,然後,視角隨主角移動其實就是視角和主角相對靜止,地圖向相反方向移動即可,所以我們把地圖的初始座標減去剛才獲得的座標差就得到了地圖的正確位置。

出現問題:TMX瓦片地圖無法載入問題。Get date from file(iso-test.png) failed!

解決:將官方示例自帶的tmx和對應瓦片的png扔進去測一下。