1. 程式人生 > >Cocos2d-X 瓦片地圖使用的例項專案(包含碰撞檢測,移動)

Cocos2d-X 瓦片地圖使用的例項專案(包含碰撞檢測,移動)

(1)標頭檔案中

#include <iostream>

#include "cocos2d.h"

usingnamespacecocos2d;

class AA:publicCCLayer

{

public:

    virtual bool init();

    static CCScene *scene();

CREATE_FUNC(AA);

     CCSprite *_player;

    int count;

    bool mode;

    CCArray *bulletArray;

    CCArray *enemyArray;

    CCTMXTiledMap

*_tileMap;

    CCTMXTiledMap *_titleMap;

    CCTMXLayer *wall,*foreground;

    CCPoint mapPoint,heroPoint,beginPoint;

     CCLabelTTF *label;

//碰撞檢測

    void detection();

    bool iscallision(CCSprite *mysprite,CCSprite *testsprite);

    CCRect getRect(CCSprite *sprite);

//觸控事件

    virtual bool ccTouchBegan(CCTouch

*pTouch, CCEvent *pEvent);

    virtual void ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent);

    virtual void ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent);

    virtual void ccTouchCancelled(CCTouch *pTouch, CCEvent *pEvent);

    void goon(CCNode *pSender);

    void toggleGame(CCObject *pSender);

    void targetFinish(CCNode *pSender);

};

(2)實現檔案中

//

//  AA.cpp

//  date10

//

//  Created by Student on 14-9-22.

//

//

#include "AA.h"

CCScene *AA::scene()

{

    CCScene *s=CCScene::create();

    AA *layer=AA::create();

    s->addChild(layer);

    return s;

}

bool AA::init()

{

    if(!CCLayer::init())

    {

returnfalse;

    }

    mode=true;

//初始化陣列

    bulletArray = CCArray::create();

bulletArray->retain();

    enemyArray = CCArray::create();

enemyArray->retain();

//載入瓦片地圖

_tileMap=CCTMXTiledMap::create("ThefirstTiled1.tmx");

_tileMap->setPosition(mapPoint);

addChild(_tileMap);

//讀取瓦片地圖中的層和物件

wall=_tileMap->layerNamed("wall");

foreground=_tileMap->layerNamed("water");

    CCTMXObjectGroup *objects=_tileMap->objectGroupNamed("hero");

    CCDictionary  *spawnPoint=objects->objectNamed("pa");

    heroPoint.x=spawnPoint->valueForKey("x")->floatValue();

    heroPoint.y=spawnPoint->valueForKey("y")->floatValue();

CCLog("x=%f,y=%f",heroPoint.x,heroPoint.y);

//載入英雄到介面

    _player=CCSprite::create("www.png");

_player->setAnchorPoint(CCPoint(0,0));

_player->setPosition(heroPoint);

_tileMap->addChild(_player,0);

//載入敵人到介面

    for(int i=0;i<int(objects->getObjects()->count());i++) //得到敵人的數量

    {

        CCDictionary *enemy=(CCDictionary *)objects->getObjects()->objectAtIndex(i);

        if(enemy->valueForKey("n")->intValue()==1)

        {

            CCSprite *s=CCSprite::create("enemy1.png");

            float x=enemy->valueForKey("x")->floatValue();

            float y=enemy->valueForKey("y")->floatValue();

            s->setPosition(ccp(x,y));

            s->setAnchorPoint(CCPoint(0,0));

            _tileMap->addChild(s,4);

            enemyArray->addObject(s);

            CCActionInterval *move=CCMoveBy::create(0.5,CCPoint(_player->getPosition().x-s->getPosition().x>0?10:-10,_player->getPosition().y-s->getPosition().y>0?10:-10));

//goon 表示不斷的移動

CCFiniteTimeAction *func=CCCallFuncN::create(this,callfuncN_selector(AA::goon));

            s->runAction(CCSequence::create(move,func,NULL));

        }

    }

//載入開關選項

    CCMenuItem *oon,*ooff;

    oon=CCMenuItemImage::create("projectile-button-on.png","projectile-button-on.png");

    ooff=CCMenuItemImage::create("projectile-button-off.png","projectile-button-off.png");

CCMenuItemToggle *toggle=CCMenuItemToggle::createWithTarget(this,

                                                                menu_selector(AA::toggleGame),

                                                                ooff,oon,NULL);

    CCMenu *menu=CCMenu::create(toggle,NULL);

    menu->setPosition(ccp(oon->getContentSize().width/2,oon->getContentSize().height/2));

    addChild(menu);

//加入觸控的單例

CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, 1, true);

//碰撞檢測的呼叫

this->schedule(schedule_selector(AA::detection), 0.2);

    label=CCLabelTTF::create("0","Arial",20);

label->setPosition(ccp(CCDirector::sharedDirector()->getWinSize().width-label->getContentSize().width/2,label->getContentSize().height/2));

    addChild(label,10);

returntrue;

}

//表示敵人不斷移動的距離

void AA::goon(CCNode *pSender)

{

    CCLOG("goon");

CCSprite *s=(CCSprite *)pSender;

    CCActionInterval *move=CCMoveBy::create(0.5,CCPoint(_player->getPosition().x-s->getPosition().x>0?10:-10,_player->getPosition().y-s->getPosition().y>0?10:-10));

CCFiniteTimeAction *func=CCCallFuncN::create(this,callfuncN_selector(AA::goon));

    s->runAction(CCSequence::create(move,func,NULL));

}

void AA::toggleGame(CCObject *pSender)

{

mode=mode?false:true;

}

bool AA::ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent)

{

    beginPoint=pTouch->getLocation();

returntrue;

}

void AA::ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent)

{

    /*

    if(mode)

    {

        //得到先前的座標(0,0)

        CCPoint PP=pTouch->getPreviousLocation();

        //得到當前的座標

        CCPoint np=pTouch->getLocation();

        //兩座標相減

        CCPoint dp=ccpSub(np, PP);

        //向左為負 右側為正

        if(_titleMap->getPosition().x+dp.x>-480 &&  _titleMap->getPosition().x+dp.x<0)

        {

            mapPoint=ccp(_titleMap->getPosition().x+dp.x,0);

            _titleMap->setPosition(mapPoint);

        }

    }

     */

    if(mode)

{

        CCPoint pp=pTouch->getPreviousLocation();

        CCPoint np=pTouch->getLocation();

        CCPoint dp=ccpSub(np,pp);

        if(_tileMap->getPosition().x+dp.x>-480&&_tileMap->getPosition().x+dp.x<0)

        {

            mapPoint=ccp(_tileMap->getPosition().x+dp.x,0);

            _tileMap->setPosition(mapPoint);

        }

}

}

void AA::ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent)

{

    /*

     //地圖裡的座標(0,0)是從左上角開始的

    步驟:

    1、判斷是否點選

    2、判斷點選的位置與英雄的位置的X,Y的差值     比較DX與DY的大小

    3、判斷英雄的X做標要大於點選的X座標  才能向左

    4、判斷移動時是否撞擊牆和移出地圖外

     */

//獲得點選的位置

////////////////////////////////////////////////////////

    /*

    CCPoint pp=pTouch->getLocation();

    if(mode)

    {

         //是點選不是滑動  在原地點選下又點選離開

        if(beginPoint.x==pp.x && beginPoint.y==pp.y)//beginPoint是開始觸控的位置

        {

            //—player的位置

            CCPoint pt=_player->getPosition();

           //判斷是否 x>y

            if(fabs(pt.x-(pp.x-mapPoint.x))>=fabs( pt.y-(pp.y-mapPoint.y))    )

            {

               ////////點選點向左移動   英雄的X做標要大於點選的X座標  才能向左

                if(pt.x>=pp.x-mapPoint.x)

                {

                    if(9-_player->getPosition().y/32<10 && 9-_player->getPosition().y/32>=0&&

                       _player->getPosition().x/32-1<50&&_player->getPosition().x/32-1>=0&&

                       !(wall->tileGIDAt(ccp(_player->getPosition().x/32-1,9-_player->getPosition().y/32))))//判斷是否是地圖外面,或者是不是牆

                    {

                        _player->setPosition(ccp(_player->getPosition().x-32,_player->getPosition().y));

                        if(foreground->tileGIDAt(ccp(_player->getPosition().x/32,9-_player->getPosition().y/32)))

                        {

                            foreground->removeTileAt(ccp(_player->getPosition().x/32,9-_player->getPosition().y/32));

                            count++;

                            CCString *temp=CCString::createWithFormat("%d",count);

                            label->setString(temp->getCString());

                        }

                    }

                }

                else

                {

                    if(9-_player->getPosition().y/32<10&&9-_player->getPosition().y/32>=0&&_player->getPosition().x/32+1<50&&_player->getPosition().x/32+1>=0&&!(wall->tileGIDAt(ccp(_player->getPosition().x/32+1,9-_player->getPosition().y/32))))

                    {

                        _player->setPosition(ccp(_player->getPosition().x+32,_player->getPosition().y));

                        if(foreground->tileGIDAt(ccp(_player->getPosition().x/32,9-_player->getPosition().y/32)))

                        {

                            foreground->removeTileAt(ccp(_player->getPosition().x/32,9-_player->getPosition().y/32));

count++;

                            CCString *temp=CCString::createWithFormat("%d",count);

                            label->setString(temp->getCString());

                        }

                    }

                }

            }

            else

            {

                if(pt.y>=pp.y-mapPoint.y)

                {

                    if(9-_player->getPosition().y/32+1<10&&9-_player->getPosition().y/32+1>=0&&_player->getPosition().x/32<50&&_player->getPosition().x/32>=0&&!(wall->tileGIDAt(ccp(_player->getPosition().x/32,9-_player->getPosition().y/32+1))))

                    {

                        _player->setPosition(ccp(_player->getPosition().x,_player->getPosition().y-32));

                        if(foreground->tileGIDAt(ccp(_player->getPosition().x/32,9-_player->getPosition().y/32)))

                        {

                            foreground->removeTileAt(ccp(_player->getPosition().x/32,9-_player->getPosition().y/32));

count++;

                            CCString *temp=CCString::createWithFormat("%d",count);

                            label->setString(temp->getCString());

                        }

                    }

                }

                else

                {

                    if(9-_player->getPosition().y/32-1<10&&9-_player->getPosition().y/32-1>=0&&_player->getPosition().x/32<50&&_player->getPosition().x/32>=0&&!(wall->tileGIDAt(ccp(_player->getPosition().x/32,9-_player->getPosition().y/32-1))))

                    {

                        _player->setPosition(ccp(_player->getPosition().x,_player->getPosition().y+32));

                        if(foreground->tileGIDAt(ccp(_player->getPosition().x/32,9-_player->getPosition().y/32)))

                        {

                            foreground->removeTileAt(ccp(_player->getPosition().x/32,9-_player->getPosition().y/32));

count++;

                            CCString *temp=CCString::createWithFormat("%d",count);

                            label->setString(temp->getCString());

                        }

                    }

                }

            }

        }

}

    else

{

CCSprite *s=CCSprite::create("Projectile.png");

s->setPosition(_player->getPosition());

_tileMap->addChild(s,4);

        bulletArray->addObject(s);

float dx=pp.x-_player->getPosition().x;

float dy=pp.y-_player->getPosition().y;

if(dx>0)

{

float lx=32*30-_player->getPosition().x;

float ly=dy/dx*lx;

CCActionInterval *move=CCMoveBy::create(3,ccp(lx+s->getContentSize().width,ly));

CCFiniteTimeAction *ff=CCCallFuncN::create(this,callfuncN_selector(AA::targetFinish));

s->runAction(CCSequence::create(move,ff,NULL));

}

else

{

float lx=0-_player->getPosition().x;

float ly=dy/dx*lx;

CCActionInterval *move=CCMoveBy::create(3,ccp(lx-s->getContentSize().width,ly));

CCFiniteTimeAction *ff=CCCallFuncN::create(this,callfuncN_selector(AA::targetFinish));

s->runAction(CCSequence::create(move,ff,NULL));

}

}

    */

   CCPoint pp=pTouch->getLocation();

if(mode)//移動

{

        if(beginPoint.x==pp.x&&beginPoint.y==pp.y)

        {

            cocos2d::CCPoint pt=_player->getPosition();

            //dx>dy

            if(fabs(pt.x-(pp.x-mapPoint.x))>=fabs(pt.y-(pp.y-mapPoint.y)))

            {

                //左移

                if(pt.x>=pp.x-mapPoint.x)

                {

                    if(9-_player->getPosition().y/32<10&&9-_player->getPosition().y/32>=0&&

                       _player->getPosition().x/32-1<50&&_player->getPosition().x/32-1>=0&&

                       !(wall->tileGIDAt(ccp(_player->getPosition().x/32-1,9-_player->getPosition().y/32))))//判斷是否是地圖外面,或者是不是牆  //tileGIDAt表示有沒有的意思

                    {

                        //32表示32個畫素  表示向左挪動了1個單位

                        _player->setPosition(ccp(_player->getPosition().x-32,_player->getPosition().y));

                         //判斷西瓜的和_player相撞

                        if(foreground->tileGIDAt(ccp(_player->getPosition().x/32,9-_player->getPosition().y/32)))

                        {

                            //西瓜的位置消失

                            foreground->removeTileAt(ccp(_player->getPosition().x/32,9-_player->getPosition().y/32));

                            count++;

                            CCString *temp=CCString::createWithFormat("%d",count);

                            label->setString(temp->getCString());

                        }

                    }

                }

                //右移

                else

                {

                    if(9-_player->getPosition().y/32<10&&9-_player->getPosition().y/32>=0&&_player->getPosition().x/32+1<50&&_player->getPosition().x/32+1>=0&&!(wall->tileGIDAt(ccp(_player->getPosition().x/32+1,9-_player->getPosition().y/32))))

                    {

                        _player->setPosition(ccp(_player->getPosition().x+32,_player->getPosition().y));

                        if(foreground->tileGIDAt(ccp(_player->getPosition().x/32,9-_player->getPosition().y/32)))

                        {

                            foreground->removeTileAt(ccp(_player->getPosition().x/32,9-_player->getPosition().y/32));

count++;

                            CCString *temp=CCString::createWithFormat("%d",count);

                            label->setString(temp->getCString());

                        }

                    }

                }

            }

             //dx<dy

            else

            {

                //下移

                if(pt.y>=pp.y-mapPoint.y)

                {

                    if(9-_player->getPosition().y/32+1<10&&9-_player->getPosition().y/32+1>=0&&_player->getPosition().x/32<50&&_player->getPosition().x/32>=0&&!(wall->tileGIDAt(ccp(_player->getPosition().x/32,9-_player->getPosition().y/32+1))))

                    {

                        _player->setPosition(ccp(_player->getPosition().x,_player->getPosition().y-32));

                        if(foreground->tileGIDAt(ccp(_player->getPosition().x/32,9-_player->getPosition().y/32)))

                        {

                            foreground->removeTileAt(ccp(_player->getPosition().x/32,9-_player->getPosition().y/32));

count++;

                            CCString *temp=CCString::createWithFormat("%d",count);

                            label->setString(temp->getCString());

                        }

                    }

                }

                 //上移

                else

                {

                    if(9-_player->getPosition().y/32-1<10&&9-_player->getPosition().y/32-1>=0&&_player->getPosition().x/32<50&&_player->getPosition().x/32>=0&&!(wall->tileGIDAt(ccp(_player->getPosition().x/32,9-_player->getPosition().y/32-1))))

                    {

                        _player->setPosition(ccp(_player->getPosition().x,_player->getPosition().y+32));

                        if(foreground->tileGIDAt(ccp(_player->getPosition().x/32,9-_player->getPosition().y/32)))

                        {

                            foreground->removeTileAt(ccp(_player->getPosition().x/32,9-_player->getPosition().y/32));

count++;

                            CCString *temp=CCString::createWithFormat("%d",count);

                            label->setString(temp->getCString());

                        }

                    }

                }

            }

        }

}

//英雄發射子彈

else

{

CCSprite *s=CCSprite::create("Projectile.png");

s->setPosition(_player->getPosition());

_tileMap->addChild(s,4);

        bulletArray->addObject(s);

float dx=pp.x-_player->getPosition().x;

float dy=pp.y-_player->getPosition().y;

if(dx>0)

{

float lx=32*30-_player->getPosition().x;

float ly=dy/dx*lx;

CCActionInterval *move=CCMoveBy::create(3,ccp(lx+s->getContentSize().width,ly));

CCFiniteTimeAction *ff=CCCallFuncN::create(this,callfuncN_selector(AA::targetFinish));

s->runAction(CCSequence::create(move,ff,NULL));

}

else

{

float lx=0-_player->getPosition().x;

float ly=dy/dx*lx;

CCActionInterval *move=CCMoveBy::create(3,ccp(lx-s->getContentSize().width,ly));

CCFiniteTimeAction *ff=CCCallFuncN::create(this,callfuncN_selector(AA::targetFinish));

s->runAction(CCSequence::create(move,ff,NULL));

}

}

}

void AA::targetFinish(CCNode *pSender)

{

    pSender->removeFromParent();

}

void AA::ccTouchCancelled(CCTouch *pTouch, CCEvent *pEvent)

{

}

//碰撞檢測

void AA::detection()

{

    /*

     1、英雄與敵人碰撞

     2、子彈與敵人碰撞

     */

//遍歷敵人

    for(int i=0;i<enemyArray->count();i++)

    {

        CCSprite *s=(CCSprite *)enemyArray->objectAtIndex(i);

//判斷英雄是否和敵人碰撞

        if(iscallision(_player, s))

        {

CCLog("--------aaaaaaaa-------------");

        }

    }

//建立臨時的陣列

    CCArray *bulletA=CCArray::create();

    CCArray *enemyA=CCArray::create();

//遍歷子彈

    for(int i=0;i<bulletArray->count();i++)

    {

        CCSprite *bullet=(CCSprite *)bulletArray->objectAtIndex(i);

        //遍歷敵人

        for(int j=0;j<enemyArray->count();j++)

        {

            CCSprite *enemy=(CCSprite *)enemyArray->objectAtIndex(i);

//判斷子彈是否和敵人相撞

            if(iscallision(bullet, enemy))

            {

//這裡移除後應該加入陣列  否則會崩潰

                enemy->removeFromParent();

                bullet->removeFromParent();

                bulletA->addObject(bullet);

                enemyA->addObject(enemy);

            }

        }

    }

//從陣列中移除子彈

    for(int i=0;i<bulletA->count();i++)

    {

        CCSprite *bullet = (CCSprite *) bulletA->objectAtIndex(i);

        bulletArray->removeObject(bullet);

    }

//從陣列中移除敵人

    for(int i=0;i<enemyA->count();i++)

    {

        CCSprite *enemy = (CCSprite *) enemyA->objectAtIndex(i);

        enemyArray->removeObject(enemy);

    }

}

//碰撞檢測

bool AA::iscallision(CCSprite *mysprite,CCSprite *testsprite)

{

    CCRect myrect=mysprite->boundingBox();

    CCRect testrect=testsprite->boundingBox();

    return myrect.intersectsRect(testrect);

}