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