天天看點

【Cocos2dx】精靈觸摸跳躍功能

使用者觸摸螢幕,然後遊戲主角跳躍,或者你讓它做其它的事情等,這也是在手遊中極其常見的動作。

再Cocos2dx實作起來其實就是《【Cocos2dx】觸摸事件》(點選打開連結)與《【Cocos2dx】基本動作、動作序列與動作合并》(點選打開連結)兩者的結合,相當簡單的。

下面用一個小例子說明這個制作過程:

【Cocos2dx】精靈觸摸跳躍功能

觸摸(點選)螢幕,我們的關閉按鈕會上升一段距離,同時,在其“跳躍”的過程不會出現違反正常的2段跳,N段跳,當然你後續改改代碼也可以實作2段跳之類的特效。

具體制作過程如下:

0、首先利用(cocos2d-x-2.2.6安裝目錄).\tools\project-creator下的create_project.py建立一個TouchJump的Cocos2dx工程,之後打開其中的proj.win32中的HelloCpp.sln利用vs2010進行編輯,先在AppDelegate.h關閉調試資訊,設定視窗大小。這些簡單的建立Cocos2dx工程步驟,我就不再贅述了。

1、之後由于要在HelloWorldScene.h聲明觸摸事件,精靈等屬于Cocos2dx東西,是以要在此檔案的開始聲明使用cocos2dx的命名空間。同時注意在頭檔案類中不可以對任何一個變量進行初始化,因為C++要求隻有靜态常量整型資料成員才可以在類中初始化,删去HelloWorldScene.h中的無用的,自帶關閉按鈕回調函數聲明,HelloWorldScene.h修改之後的代碼如下:

#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__

#include "cocos2d.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 recommend returning the class instance pointer
	static cocos2d::CCScene* scene();

	//觸摸事件的函數聲明  
	void ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent);//開始觸摸 

	//聲明跳躍結束的回調函數
	void jumpEnd();

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

private:
	CCSprite* sprite1;//精靈1
	bool isJumping;//是否跳躍的flag

};

#endif // __HELLOWORLD_SCENE_H__
           

2、之後的任務就是在HelloWorldScene.cpp實作這些函數、使用這些變量。修改其中的初始化函數init(),初始化中,在場景中擺一隻精靈,并且将是否跳躍的flag設定為false。關鍵是使用者觸摸螢幕的事件的實作,開始先判斷精靈是否在跳躍,如果是,則直接結束這個函數。

否則,先将跳躍的flag設定為true,讓精靈跳躍後,如同《【Cocos2dx】動作監聽》(點選打開連結)一樣,監聽此動作結束之後,将跳躍的flag重新設定為false。

#include "HelloWorldScene.h"

USING_NS_CC;

CCScene* HelloWorld::scene()
{
	// 'scene' is an autorelease object
	CCScene *scene = CCScene::create();

	// 'layer' is an autorelease object
	HelloWorld *layer = HelloWorld::create();

	// add layer as a child to scene
	scene->addChild(layer);

	// return the scene
	return scene;
}

// on "init" you need to initialize your instance
bool HelloWorld::init()
{
	//擷取用于螢幕的尺寸等 
	CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();

	//聲明這個場景是存在觸摸事件的 
	this->setTouchEnabled(true);

	//添加一隻 關閉按鈕 的精靈
	sprite1 = CCSprite::create("CloseSelected.png");  
	sprite1->setPosition(ccp(visibleSize.width / 2, visibleSize.height / 6));  
	this->addChild(sprite1);  

	//開始精靈處于未跳躍的狀态,由于頭檔案中“隻有靜态常量整型資料成員才可以在類中初始化”,是以在這裡初始化聲明變量
	isJumping=false;

	return true;
}

//開始觸摸  
void HelloWorld::ccTouchesBegan(cocos2d::CCSet *pTouches, cocos2d::CCEvent *pEvent){  

	//擷取螢幕的尺寸、位置資訊等      
	CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();    

	//如果主角還在跳躍中,則不重複執行
	if(isJumping) {
		return;
	}

	//标記主角為跳躍狀态
	isJumping = true;

	//在2.0秒内,先跳起 螢幕尺寸的1/2 再落下0px,該動作重複1次
	CCJumpBy* jump = CCJumpBy::create(2.0f, ccp(0, 0), visibleSize.height / 2, 1);

	//建立回調函數,聲明跳躍結束後調用jumpEnd函數
	CCCallFunc* callFunc = CCCallFunc::create(this, callfunc_selector(HelloWorld::jumpEnd));

	//将回調函數與跳躍動作結合起來
	CCActionInterval* jumpActions = CCSequence::create(jump, callFunc, NULL);

	//執行動作
	sprite1->runAction(jumpActions);

	/*錯誤示範
	sprite1->runAction(jump);
	isJumping = false;
	*/
}; 

void HelloWorld::jumpEnd() {
	isJumping = false;
}
           

這裡可能大家非常有疑問,為何非要整這麼複雜,需要利用一個監聽的回調函數監聽跳躍動作是否結束呢?直接像錯誤示範那樣,在執行跳躍動作這條語句之後,将是否跳躍的flag改成false不就得了嗎?

這個不行,因為你在跳躍之後,将flag秒改成false,跳躍才剛開始呢!根本沒有一個等待跳躍動作結束之後才将flag改成false的過程。

繼續閱讀