本文要實現飛機遊戲中,人的手指按着飛機,就能拖着飛機走動,這裏實現了當你手指按在手機的圖片上,手指一直按着屏幕,飛機就會跟着你走。同時,還加入了邊界判斷條件,讓飛機在你的視野內移動,實現的效果完全和我們手機上的飛機遊戲一樣。
效果:
Cocos2d-x版本:3.4
工程環境:VS30213
一、代碼編寫
1、頭文件GameMain.h
/** *@作者 林炳文(郵箱:[email protected]) *@博客 http://linbingwen.blog.51cto.com/ *@時間 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__
#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,說明可以移動英雄飛機。
若你覺得此文對你有用,那就幫我贊一下~~謝謝啦