標籤:cocos2d-x 精靈隨手指移動
林炳文Evankaka原創作品。轉載請註明出處http://blog.csdn.net/evankaka
本文要實現飛機遊戲中,人的手指按著飛機,就能拖著飛機走動,這裡實現了當你手指按在手機的圖片上,手指一直按著螢幕,飛機就會跟著你走。同時,還加入了邊界判斷條件,讓飛機在你的視野內移動,實現的效果完全和我們手機上的飛機遊戲一樣。
效果:
Cocos2d-x版本:3.4
工程環境:VS30213
一、代碼編寫
1、標頭檔GameMain.h
/***@作者 林炳文(郵箱:[email protected])*@部落格 http://blog.csdn.net/evankaka*@時間 2015.3.8*@功能 遊戲的主介面*/#ifndef __GameMain_H__#define __GameMain_H__#include "BackLayerDown.h"#include "BackLayerUp.h"#include "cocos2d.h"USING_NS_CC;class GameMain : public cocos2d::Layer{public: static cocos2d::Scene* createScene(); virtual bool init();virtual bool onTouchBegan(cocos2d::Touch *touch, cocos2d::Event *unused_event);virtual void onTouchMoved(cocos2d::Touch *touch, cocos2d::Event *unused_event);virtual void onTouchEened(cocos2d::Touch *touch, cocos2d::Event *unused_event);virtual void onTouchCancelled(cocos2d::Touch *touch, cocos2d::Event *unused_even); CREATE_FUNC(GameMain);private:bool isHeroPlaneControl;//飛機是否被控制著float mDeltaX;//英雄飛機隨手指移動時的X位移量float mDeltaY;//英雄飛機隨手指移動時的Y位移量Sprite *mHeroPlane;//英雄飛機};#endif // __GameMain_H__
然後在GameMain.cpp中增加:
#include "GameMain.h"USING_NS_CC;Scene* GameMain::createScene(){ auto scene = Scene::create(); auto layer = GameMain::create(); scene->addChild(layer); return scene;}bool GameMain::init(){Size visibleSize = Director::getInstance()->getVisibleSize();Point origin = Director::getInstance()->getVisibleOrigin();//這是地面圖層this->addChild(BackLayerUp::create());//這是白雲圖層this->addChild(BackLayerDown::create());//加個飛機mHeroPlane = Sprite::create("air1.png");mHeroPlane->setPosition(Vec2(visibleSize.width / 2, visibleSize.height / 5));this->addChild(mHeroPlane, 1, 100);isHeroPlaneControl = false;//開啟觸摸,增加觸摸監聽事件this->setTouchEnabled(true);auto listen = EventListenerTouchOneByOne::create();listen->onTouchBegan = CC_CALLBACK_2( GameMain::onTouchBegan,this);listen->onTouchMoved = CC_CALLBACK_2(GameMain::onTouchMoved, this);listen->onTouchEnded = CC_CALLBACK_2(GameMain::onTouchEened, this);listen->onTouchCancelled = CC_CALLBACK_2(GameMain::onTouchCancelled, this);listen->setSwallowTouches(false);//不截取觸摸事件Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listen,this); return true;}bool GameMain::onTouchBegan(cocos2d::Touch *touch, cocos2d::Event *unused_event){Point mHeroPos = mHeroPlane->getPosition();Point mBeganPos = touch->getLocationInView();mBeganPos = Director::getInstance()->convertToGL(mBeganPos);//判斷當前手指按下地區是否是英雄飛機的地區,並且計算飛機要移動時的位移量if (mBeganPos.x > mHeroPos.x - mHeroPlane->getContentSize().width / 2 && mBeganPos.x<mHeroPos.x + mHeroPlane->getContentSize().width / 2 &&mBeganPos.y>mHeroPos.y - mHeroPlane->getContentSize().height / 2 && mBeganPos.y < mHeroPos.y + mHeroPlane->getContentSize().height / 2){isHeroPlaneControl = true;//計算位移量mDeltaX = mBeganPos.x - mHeroPos.x;mDeltaY = mBeganPos.y - mHeroPos.y;}return true;}void GameMain::onTouchMoved(cocos2d::Touch *touch, cocos2d::Event *unused_event){if (isHeroPlaneControl){Point mMovedPos = touch->getLocationInView();mMovedPos = Director::getInstance()->convertToGL(mMovedPos);Size visibleSize = Director::getInstance()->getVisibleSize();Point origin = Director::getInstance()->getVisibleOrigin();float x = mMovedPos.x - mDeltaX;//記得減去位移量float y = mMovedPos.y - mDeltaY;if (x <= mHeroPlane->getContentSize().width / 2 + origin.x)//x到達螢幕左邊界x = mHeroPlane->getContentSize().width / 2 + origin.x;else if (x >= visibleSize.width - mHeroPlane->getContentSize().width / 2)//x到達螢幕右邊界x = visibleSize.width - mHeroPlane->getContentSize().width / 2;if (y <= mHeroPlane->getContentSize().height / 2 + origin.y)//y到達螢幕下邊界y = mHeroPlane->getContentSize().height / 2 + origin.y;else if (y >= visibleSize.height - mHeroPlane->getContentSize().height / 2)//x到達螢幕上邊界y = visibleSize.height - mHeroPlane->getContentSize().height/ 2;//飛機跟隨手指移動mHeroPlane->setPosition(Vec2(x,y));}}void GameMain::onTouchEened(cocos2d::Touch *touch, cocos2d::Event *unused_event){isHeroPlaneControl = false;}void GameMain::onTouchCancelled(cocos2d::Touch *touch, cocos2d::Event *unused_even){isHeroPlaneControl = false;}
這裡再說一寫主要函數:
標頭檔增加觸摸事件:
virtual bool onTouchBegan(cocos2d::Touch *touch, cocos2d::Event *unused_event);virtual void onTouchMoved(cocos2d::Touch *touch, cocos2d::Event *unused_event);virtual void onTouchEened(cocos2d::Touch *touch, cocos2d::Event *unused_event);virtual void onTouchCancelled(cocos2d::Touch *touch, cocos2d::Event *unused_even);
實現檔案開啟觸摸事件監聽:
//開啟觸摸,增加觸摸監聽事件this->setTouchEnabled(true);auto listen = EventListenerTouchOneByOne::create();listen->onTouchBegan = CC_CALLBACK_2( GameMain::onTouchBegan,this);listen->onTouchMoved = CC_CALLBACK_2(GameMain::onTouchMoved, this);listen->onTouchEnded = CC_CALLBACK_2(GameMain::onTouchEened, this);listen->onTouchCancelled = CC_CALLBACK_2(GameMain::onTouchCancelled, this);listen->setSwallowTouches(false);//不截取觸摸事件Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listen,this);
然後就是觸摸事件 的處理了:
bool GameMain::onTouchBegan(cocos2d::Touch *touch, cocos2d::Event *unused_event){Point mHeroPos = mHeroPlane->getPosition();Point mBeganPos = touch->getLocationInView();mBeganPos = Director::getInstance()->convertToGL(mBeganPos);//判斷當前手指按下地區是否是英雄飛機的地區,並且計算飛機要移動時的位移量if (mBeganPos.x > mHeroPos.x - mHeroPlane->getContentSize().width / 2 && mBeganPos.x<mHeroPos.x + mHeroPlane->getContentSize().width / 2 &&mBeganPos.y>mHeroPos.y - mHeroPlane->getContentSize().height / 2 && mBeganPos.y < mHeroPos.y + mHeroPlane->getContentSize().height / 2){isHeroPlaneControl = true;//計算位移量mDeltaX = mBeganPos.x - mHeroPos.x;mDeltaY = mBeganPos.y - mHeroPos.y;}return true;}void GameMain::onTouchMoved(cocos2d::Touch *touch, cocos2d::Event *unused_event){if (isHeroPlaneControl){Point mMovedPos = touch->getLocationInView();mMovedPos = Director::getInstance()->convertToGL(mMovedPos);Size visibleSize = Director::getInstance()->getVisibleSize();Point origin = Director::getInstance()->getVisibleOrigin();float x = mMovedPos.x - mDeltaX;//記得減去位移量float y = mMovedPos.y - mDeltaY;if (x <= mHeroPlane->getContentSize().width / 2 + origin.x)//x到達螢幕左邊界x = mHeroPlane->getContentSize().width / 2 + origin.x;else if (x >= visibleSize.width - mHeroPlane->getContentSize().width / 2)//x到達螢幕右邊界x = visibleSize.width - mHeroPlane->getContentSize().width / 2;if (y <= mHeroPlane->getContentSize().height / 2 + origin.y)//y到達螢幕下邊界y = mHeroPlane->getContentSize().height / 2 + origin.y;else if (y >= visibleSize.height - mHeroPlane->getContentSize().height / 2)//x到達螢幕上邊界y = visibleSize.height - mHeroPlane->getContentSize().height/ 2;//飛機跟隨手指移動mHeroPlane->setPosition(Vec2(x,y));}}void GameMain::onTouchEened(cocos2d::Touch *touch, cocos2d::Event *unused_event){isHeroPlaneControl = false;}void GameMain::onTouchCancelled(cocos2d::Touch *touch, cocos2d::Event *unused_even){isHeroPlaneControl = false;}
方法很簡單,代碼量也很少,有需要的把上面的自己拿過去,把圖片改改,把類名改改就可以了。
其實這裡應該把英雄和移動事件單獨寫一個類,然後在GameMain裡頭來調用,因為英雄這個類我還構思好,所以先這樣寫,後頭會把英雄飛機單獨提取出來成為一個類,就不會在GameMain裡頭寫這麼多了;
效果:
\
效果很好,飛機能跟隨移動並且不會跑出螢幕範圍
二、思路說明
1、首先在onTouchBegan判斷觸摸點是否在英雄飛機的圖片矩形內,若在這個範圍內,剛將布爾型的mHeroPlaneControl設定為true,並且計算觸摸點的橫縱座標與英雄飛機的錨點座標的差值。
2、因為要讓英雄飛機移動,要修改錨點位置,必須知道錨點位置與觸摸位置的位移量,之後才可以通過這個位移量設定主角的位置。
3、判斷英雄飛機是否跑出螢幕範圍了,如果是,就將它設定在邊界處,詳看上面的兩個if判斷。
4、在onTouchMoved中,若mHeroPlaneControl為true,說明可以移動英雄飛機。
林炳文Evankaka原創作品。轉載請註明出處http://blog.csdn.net/evankaka
若你覺得此文對你有用,那就幫我頂一下~~謝謝啦!
Cocos2d-x 《雷電大戰》-精靈隨手指移動,你點哪我走哪!