溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Cocos2d-x 《雷電大戰(zhàn)》-精靈隨手指移動(dòng),你點(diǎn)哪我走哪!

發(fā)布時(shí)間:2020-07-01 17:19:35 來源:網(wǎng)絡(luò) 閱讀:912 作者:林炳文 欄目:游戲開發(fā)

    本文要實(shí)現(xiàn)飛機(jī)游戲中,人的手指按著飛機(jī),就能拖著飛機(jī)走動(dòng),這里實(shí)現(xiàn)了當(dāng)你手指按在手機(jī)的圖片上,手指一直按著屏幕,飛機(jī)就會(huì)跟著你走。同時(shí),還加入了邊界判斷條件,讓飛機(jī)在你的視野內(nèi)移動(dòng),實(shí)現(xiàn)的效果完全和我們手機(jī)上的飛機(jī)游戲一樣。

效果:

 Cocos2d-x 《雷電大戰(zhàn)》-精靈隨手指移動(dòng),你點(diǎn)哪我走哪!

Cocos2d-x版本:3.4

工程環(huán)境:VS30213

一、代碼編寫

1、頭文件GameMain.h

/**
*@作者 林炳文(郵箱:ling20081005@126.com)
*@博客 http://linbingwen.blog.51cto.com/
*@時(shí)間 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;//飛機(jī)是否被控制著
    float mDeltaX;//英雄飛機(jī)隨手指移動(dòng)時(shí)的X偏移量
    float mDeltaY;//英雄飛機(jī)隨手指移動(dòng)時(shí)的Y偏移量
    Sprite *mHeroPlane;//英雄飛機(jī)
};

#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());

    //加個(gè)飛機(jī)
    mHeroPlane = Sprite::create("air1.png");
    mHeroPlane->setPosition(Vec2(visibleSize.width / 2, visibleSize.height / 5));
    this->addChild(mHeroPlane, 1, 100);
    isHeroPlaneControl = false;

    //打開觸摸,增加觸摸監(jiān)聽事件
    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);

    //判斷當(dāng)前手指按下區(qū)域是否是英雄飛機(jī)的區(qū)域,并且計(jì)算飛機(jī)要移動(dòng)時(shí)的偏移量
    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;
        //計(jì)算偏移量
        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到達(dá)屏幕左邊界
            x = mHeroPlane->getContentSize().width / 2 + origin.x;
        else if (x >= visibleSize.width - mHeroPlane->getContentSize().width / 2)//x到達(dá)屏幕右邊界
            x = visibleSize.width - mHeroPlane->getContentSize().width / 2;

        if (y <= mHeroPlane->getContentSize().height / 2 + origin.y)//y到達(dá)屏幕下邊界
            y = mHeroPlane->getContentSize().height / 2 + origin.y;
        else if (y >= visibleSize.height - mHeroPlane->getContentSize().height / 2)//x到達(dá)屏幕上邊界
            y = visibleSize.height - mHeroPlane->getContentSize().height/ 2;

        //飛機(jī)跟隨手指移動(dòng)
        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;
}

這里再說一寫主要函數(shù):

頭文件增加觸摸事件:

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);

實(shí)現(xiàn)文件開啟觸摸事件監(jiān)聽:

//打開觸摸,增加觸摸監(jiān)聽事件
    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);

    //判斷當(dāng)前手指按下區(qū)域是否是英雄飛機(jī)的區(qū)域,并且計(jì)算飛機(jī)要移動(dòng)時(shí)的偏移量
    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;
        //計(jì)算偏移量
        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到達(dá)屏幕左邊界
            x = mHeroPlane->getContentSize().width / 2 + origin.x;
        else if (x >= visibleSize.width - mHeroPlane->getContentSize().width / 2)//x到達(dá)屏幕右邊界
            x = visibleSize.width - mHeroPlane->getContentSize().width / 2;

        if (y <= mHeroPlane->getContentSize().height / 2 + origin.y)//y到達(dá)屏幕下邊界
            y = mHeroPlane->getContentSize().height / 2 + origin.y;
        else if (y >= visibleSize.height - mHeroPlane->getContentSize().height / 2)//x到達(dá)屏幕上邊界
            y = visibleSize.height - mHeroPlane->getContentSize().height/ 2;

        //飛機(jī)跟隨手指移動(dòng)
        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;
}

   方法很簡單,代碼量也很少,有需要的把上面的自己拿過去,把圖片改改,把類名改改就可以了。

   其實(shí)這里應(yīng)該把英雄和移動(dòng)事件單獨(dú)寫一個(gè)類,然后在GameMain里頭來調(diào)用,因?yàn)橛⑿圻@個(gè)類我還構(gòu)思好,所以先這樣寫,后頭會(huì)把英雄飛機(jī)單獨(dú)提取出來成為一個(gè)類,就不會(huì)在GameMain里頭寫這么多了;

效果:

 Cocos2d-x 《雷電大戰(zhàn)》-精靈隨手指移動(dòng),你點(diǎn)哪我走哪!

 Cocos2d-x 《雷電大戰(zhàn)》-精靈隨手指移動(dòng),你點(diǎn)哪我走哪!

 Cocos2d-x 《雷電大戰(zhàn)》-精靈隨手指移動(dòng),你點(diǎn)哪我走哪!



效果很好,飛機(jī)能跟隨移動(dòng)并且不會(huì)跑出屏幕范圍

二、思路說明

1、首先在onTouchBegan判斷觸摸點(diǎn)是否在英雄飛機(jī)的圖片矩形內(nèi),若在這個(gè)范圍內(nèi),剛將布爾型的mHeroPlaneControl設(shè)置為true,并且計(jì)算觸摸點(diǎn)的橫縱坐標(biāo)與英雄飛機(jī)的錨點(diǎn)坐標(biāo)的差值。

2、因?yàn)橐層⑿埏w機(jī)移動(dòng),要修改錨點(diǎn)位置,必須知道錨點(diǎn)位置與觸摸位置的偏移量,之后才可以通過這個(gè)偏移量設(shè)置主角的位置。

3、判斷英雄飛機(jī)是否跑出屏幕范圍了,如果是,就將它設(shè)置在邊界處,詳看上面的兩個(gè)if判斷。

4、在onTouchMoved中,若mHeroPlaneControl為true,說明可以移動(dòng)英雄飛機(jī)。

  

                若你覺得此文對你有用,那就幫我贊一下~~謝謝啦


向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI