【Cocos2d-x】手柄與計分板功能的實現

這裏我們基於一個cocos2dx-x引擎的貪食豆小遊戲,簡單實現手柄與計分板等交互功能。


運行遊戲發現,吃到了豆豆也不會有分數獎勵,甚至手柄連豆豆的上下移動都沒有實現。

可以發現,源碼是指定左右和暫停來控制角色的移動,我們改用計算角度和力度來控制角色移動。


// 獲取搖桿角度
float Joystick::getAngle()
{
	TouchPoint_Angle = atan2f((m_currentPoint - m_centerPoint).y, (m_currentPoint - m_centerPoint).x);
	return TouchPoint_Angle;
}

// 獲取搖桿力度
float Joystick::getVelocity()
{
	TouchPoint_Distanse = m_centerPoint.getDistance(m_currentPoint);
	return 1.0 * TouchPoint_Distanse / m_radius;
}

然後通過計算所得的角度和力度分別更新角色橫縱座標,而且需要防止超出遊戲界面

// 通過角度和力度控制角色移動
if (m_joystick->getVelocity() > 0)
{
	if (((bean->getPositionX() - bean->getContentSize().width / 2) >= 200 && cos(m_joystick->getAngle()) < 0)
		|| (bean->getPositionX() + bean->getContentSize().width / 2 <= 680 && cos(m_joystick->getAngle()) > 0))
	{
		bean->setPositionX(bean->getPositionX() + 4 * m_joystick->getVelocity() * cos(m_joystick->getAngle()));
	}
	if (((bean->getPositionY() + bean->getContentSize().width) <= 667 && sin(m_joystick->getAngle()) > 0)
		|| ((bean->getPositionY() - bean->getContentSize().width) >= 0 && sin(m_joystick->getAngle()) < 0))
	{
		bean->setPositionY(bean->getPositionY() + 4 * m_joystick->getVelocity() * sin(m_joystick->getAngle()));
	}
}

這樣,我們就基本實現了手柄對角色的操控(手柄繪製源碼中實現),然後只需實現計分板的功能

public:
        void updategrade(int); 
        //gradeboard init
        void gradeboard();
private:
        // tag for ball or grade
	static const int BALL1_TAG = 110;
	static const int BALL2_TAG = 111;
	static const int BALL3_TAG = 112;
	static const int GRADE_TAG = 113;
	int grade = 0;        //grade init
	string FNT_PATH = "fonts/futura-48.fnt";	//	fnt file path
顯然,我們應當有一個計分板初始化的實現,此外,應當實現分數的動態更新。爲了能夠得到指定的node,有必要使用tag來標記跟蹤每種類型的ball以及grade。在創建豆豆時進行setTag(ball_tag)操作,然後就可以通過getTag()判斷出vector中的當前ball的類型,並根據球的類型進行分數的更新。
for (auto ball : ballVector)
	{
		//進行碰撞檢測,更新分數
		auto balltype = ball->getTag();
		if (bean->getBoundingBox().intersectsRect(ball->getBoundingBox()))
		{
			auto actionDown = CallFunc::create(CC_CALLBACK_0(HelloWorld::removeBall, this, ball));
			ball->runAction(actionDown);
			if (balltype==BALL1_TAG)
				updategrade(1);
			else if(balltype == BALL2_TAG)
				updategrade(2);
			else if(balltype == BALL3_TAG)
				updategrade(3);
			else ;
		}
	}

由於grade已經進行了初始化,這裏就只需將grade加上傳入的增量即可。此外,我們考慮使用LabelBMFont創建計分板,分別初始化設置字體、座標以及tag。此外,由於node不能強制轉換成label,但是能強制轉換成LabelBMFont,因此我考慮並使用了LabelBMFont.create而不是Label::createWithBMFont來創建計分板,從而能夠使用setString實時更新計分板。

 // 更新分數
void HelloWorld::updategrade(int increment)
{
	grade += increment;
	//log("%d", grade);
}
 // 計分板初始化
void HelloWorld::gradeboard()
{
	auto grades = LabelBMFont::create(StringUtils::format("Grade\n%d", grade),FNT_PATH);
	//auto grade = Label::createWithBMFont(FNT_PATH,StringUtils::format("Grade\n%d", grade));
	grades->setPosition(Vec2(100, 350));
	grades->setTag(GRADE_TAG);
	this->addChild(grades, 10);
}
init(){
        ...
        auto grades = (LabelBMFont*)this->getChildByTag(GRADE_TAG);
	grades->setString(StringUtils::format("Grade\n%d",grade));
}

到此,我們就完整實現了計分板的功能。運行遊戲如下


計分板功能和遊戲手柄的功能都已經完整實現。




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章