1. 程式人生 > >cocos2d-x 旅程開始--(實現瓦片地圖中的碰撞檢測)

cocos2d-x 旅程開始--(實現瓦片地圖中的碰撞檢測)


       轉眼隔了一天了,昨天搞了整整一下午加一晚上,楞是沒搞定小坦克跟磚頭的碰撞檢測,帶著個問題睡覺甚是難受啊!還好今天弄成功了,不過感覺程式不怎麼穩定啊。而且發現自己寫的東西讓我重寫一遍的話我肯定寫不出來,還要繼續學習啊!

上次的進度

           實現了坦克的移動,昨天把程式優化了一下,能整合在一起的就整合在一個函式裡了。而且對碰到螢幕邊緣的情況進行了檢測。之前的程式碼都是部分程式碼,今天試試把程式碼整個貼上去。

這兩天的進度

           打這麼多漢字,自個都看不進去,直接上程式碼:

/////////////////////實現移動///////////////////////
void HelloWorld::moveTank()
{
	//初始化所需資料
	origPo = player_1->getPosition();       //先得到主角player_1的初始座標備用
	newPo = ccp(0, 0);                //初始化目標座標,主角移動的新座標就是它
	xPo = newPo;                  //主角的錨點為(0.5f,0.5f),xPo是真正的檢測位置,真正的檢測位置應該在坦克外面

	if (boolleft==true)           //向左移動的話
	{
		player_1->setRotation(-90);          //坦克轉向左側
		newPo = origPo - ccp(10, 0);         //設定坦克移動的目的座標
		newPo.x = newPo.x > 30 ? newPo.x : 30;      //越界判斷

		xPo = newPo + ccp(-30, 0);           //設定檢測位置
		xPo.x = xPo.x < 30 ? 30 : xPo.x;    //越界判斷
	}
	else if (boolright==true)
	{
		player_1->setRotation(90);
		newPo = origPo + ccp(10, 0);
		newPo.x = newPo.x < MAP_WIDTH - 30 ? newPo.x : MAP_WIDTH - 30;      //MAP_WIDTH為定義的巨集,地圖寬度

		xPo = newPo + ccp(22, 0);
		xPo.x = xPo.x > MAP_WIDTH - 30 ? MAP_WIDTH - 30 : xPo.x;
	}
	else if (boolup==true)
	{
		player_1->setRotation(0);
		newPo = origPo + ccp(0, 10);
		newPo.y = newPo.y < MAP_HEIGHT - 30 ? newPo.y : MAP_HEIGHT - 30;

		xPo = newPo + ccp(0, 30);
		xPo.y = xPo.y > MAP_HEIGHT - 30 ? MAP_HEIGHT - 30 : xPo.y;
	}
	else if (booldown==true)
	{
		player_1->setRotation(180);
		newPo = origPo - ccp(0, 10);
		newPo.y = newPo.y >30 ? newPo.y : 30;

		xPo = newPo + ccp(0, -22);
		xPo.y = xPo.y < 30 ? 30 : xPo.y;
	}
        //實現碰撞檢測
	this->collide("layer_1");                        //檢測layer_1圖層,這層只有磚塊     
	float distancePo = origPo.getDistance(player_1->getPosition());    //計算前後是否移動,得出移動距離           
	if (!distancePo == 0)             //如果移動了,就說明這時候磚塊層沒有碰撞,而且已經設定了新的position                                            
	{                                                                                
		player_1->setPosition(origPo);             //把position改回來,不讓它移動
                collide("layer_2");           //檢測layer_2層這層只有鐵塊               
	}
}
collide函式實現碰撞檢測:
void HelloWorld::collide(CCString stringx)
{
	const char *str = "";                      //定義一個char用來改變檢測的圖層
	if (stringx.compare("layer_1")==0)           //判斷是哪個圖層
	{
		str = "layer_1";
	}
	else if (stringx.compare("layer_2")==0)
	{
		str = "layer_2";
	}
		
	CCPoint xPo_1; CCPoint xPo_2;            //初始化兩個新的檢測位置

	if (boolleft)
	{
		xPo_1 = xPo + ccp(0, -25);       //向左移動的話分別檢測原檢測位置上下兩個新的位置
		xPo_2 = xPo + ccp(0, 25);
	}
	else if (boolright)
	{
		xPo_1 = xPo + ccp(0, -25);
		xPo_2 = xPo + ccp(0, 25);
	}
	else if (booldown)
	{
		xPo_1 = xPo + ccp(-25, 0);
		xPo_2 = xPo + ccp(25, 0);
	}
	else if (boolup)
	{
		xPo_1 = xPo + ccp(-25, 0);
		xPo_2 = xPo + ccp(25, 0);
	}
	CCTMXLayer* wallLayer = tank_war->layerNamed(str);            //得到需要檢測的圖層

	CCPoint m_1 = this->changePositionToMap(xPo_1);
	int tag_1 = wallLayer->tileGIDAt(m_1);

	CCPoint m_2 = this->changePositionToMap(xPo_2);
	int tag_2 = wallLayer->tileGIDAt(m_2);

	CCPoint m = this->changePositionToMap(xPo);                  //將浮點位置座標轉化為TileMap特有的塊座標系統
	int wallTag = wallLayer->tileGIDAt(m);                       //獲得地圖塊上的ID

	if (wallTag == 0)                                            
	{
		if (tag_1 == 0)
		{
			if (tag_2 == 0)           //只有三個檢測位置都沒有阻擋才能移動
			{
				player_1->setPosition(newPo);
			}
		}
		return;
	}
}
需要把浮點型的檢測位置座標轉換為TileMap特有的地圖塊座標系統,轉換座標的函式:
CCPoint HelloWorld::changePositionToMap(CCPoint po)
{
	CCPoint mapPosition;
	mapPosition.x = (int)(po.x / 30);
	mapPosition.y = (int)((MAP_HEIGHT - po.y) / 30);
	return mapPosition;
}
說明:由於前面設定的移動距離為10,就會出現這種情況,檢測點xPo沒有磚塊,可以向前移動,而磚塊在左側卻與坦克出現碰撞,這時候就會出現部分的穿牆現象,所以需要設定兩個新的檢測點xPo_1與xPo_2用來檢測是否發生了這種狀況。

今天就先這樣吧,接下來要實現坦克開炮,加上敵人,開始介面等等,還有好多沒實現的,一步一步來!休息休息,去跑步,洗澡,睡覺...哦,祝老爸父親節快樂...

相關推薦

cocos2d-x 旅程開始--實現瓦片地圖碰撞檢測

       轉眼隔了一天了,昨天搞了整整一下午加一晚上,楞是沒搞定小坦克跟磚頭的碰撞檢測,帶著個問題睡覺甚是難受啊!還好今天弄成功了,不過感覺程式不怎麼穩定啊。而且發現自己寫的東西讓我重寫一遍的話我肯定寫不出來,還要繼續學習啊! 上次的進度:            實現

cocos2d-x 旅程開始--實現單擊與長按

    if (turnLeftx->boundingBox().containsPoint(pTouch->getLocation()))   //點選處座標在左轉按鈕區域中(這裡末尾加分號的話,會導致點哪裡都左移的情況)     {         turnLeft->setVisibl

struts框架實現國際化實現登入頁面英互換

新建一個Web工程,並且搭好框架 以上已經介紹了Struts2框架的搭建,在這裡就不在介紹了。下面是例項化的一個例子,有需要的可以參考一下。 首先,先寫jsp頁面,在這個jsp上測試中英文切換效果,程式碼如下: 登入頁面:index.jsp <%@ pag

Cocos2d-x教程(33)-三維物體AABB碰撞檢測演算法

#include "3d/CCAABB.h" NS_CC_BEGIN //建構函式 AABB::AABB() { reset(); //初始化最大頂點與最小頂點 } AABB::AABB(const Vec3& min, const Vec3& max) { set(mi

cocos2d-x學習筆記c++與lua交互回調函數的處理

回調函數 tolua++ cocos2dx lua 本文假設讀者已經會使用tolua++進行C++與lua之間的通訊1、在頭文件中定義註冊回調函數,定義在MyClass類中void register(unsigned short cmdID, LUA_FUNCTION func);//LUA_

Cocos2d-x學習筆記 布景層的加入移除

dcl from position 顏色 顯示地圖 idt col 分享 學習 布景層類也就是CCLayer類,每一個遊戲場景中都能夠有非常多層,每一層負責各自的任務。顯示地圖、顯示人物等。同一時候層還是一個容器,能夠放入文本、圖片和菜單。構成遊戲中一個個UI。這次

cocos2d-x學習筆記十二cocos2dx 3.10添加lua LuaFileSystem庫遍歷文件

luafilesystem庫;lfs;遍歷文件在lua中遍歷目錄文件需要用到lfs庫,而所用的cocos2dx 3.10沒用lfs,需要自己添加1、下載lfs.c和lfs.hhttps://github.com/keplerproject/luafilesystem 從github獲取源碼,在src目錄拷貝l

Cocos2d-x學習筆記例項——記住帳號密碼功能

【關於記住賬號/密碼】 在很多需要賬號、密碼驗證的應用程式,“記住密碼”是非常常見的,那麼如何用cocos2d-x來實現呢?這裡用選單來實現“記住密碼”的功能。 【記住賬號/密碼的實現】 (1)首先準備兩張圖片,即選單項兩種狀態(正常和點選)下顯示的的圖片背景,以便在使用者多次

Cocos2d-x學習筆記例項——場景自動切換

【關於場景自動切換】 如何實現場景的自動切換?我嘗試過很多種方法,比如在AppDelegate.cpp檔案中的applicationDidFinishLaunching()函式中, 想在pDirector->runWithScene(pLandlords);中直接使用replace

Cocos2d-x學習筆記例項——精靈Action

【關於精靈Action】 精靈的動作分為瞬時動作和延時動作,瞬時動作中間不產生任何動畫效果,而延時動作則會產生很多的動畫效果。動畫效果主要還是要靠延時動作類CCActionInterval的子類來實現,其應用例項在TestCpp裡面有很多的例子。 單純的實現一個精靈動作很簡單,只要

Cocos2d-x學習筆記例項——繪製圖形

【關於draw函式】 在節點類CCNode中,可以重寫draw函式並在其中繪製圖形。Draw是一個虛擬函式,只要繼承CCNode的子類都可使用,只要在其函式內部新增繪圖操作即可在場景中顯示繪製的圖形。 【1】為了使繪製的圖形更清晰,將init()裡所有關於佈景的資源(

Cocos2d-x學習筆記例項——多層佈景

【關於多層佈景】 在遊戲開發中,一般會把遊戲分為兩部分:一部分是遊戲介面部分,也就是常說得UI部分;另一部分就是遊戲本身部分。有時UI有很多頁面,在頁面中用的圖也不是很多,不需要進行場景切換,只需把不同頁面做成不同的佈景,然後切換佈景層。那麼就需要一個“管理者”來管理這些介面,這時

Cocos2d-x學習筆記例項——場景切換

【1】首先設計場景需要許多的圖片資源,往resource資料夾裡新增資原始檔: 【2】新建Cocos2d-x工程時預設的是HelloWord場景,在此只做先顯示佈景層中相關精靈圖片以及選單圖片的修改: 【3】在剛剛的init()函式中有兩個選單回撥函式,主要

Cocos2d-x學習筆記淺析動作類CCAction(3)

【1】動作管理類CCActionManager: 動作管理類CCActionManager是一個管理所有動作的單例,可以對動作進行一系列的操作,如:新增動作、刪除動作、暫停動作、重啟動作,這個單例可以通過CCDirector::sharedDirector()->getActionMa

Cocos2d-x學習筆記淺析動作類CCAction(2)

有關CCAction其它動作類簡介: (1)攝像機動作類CCOrbitCamera:  攝像機動作是環繞中心螢幕旋轉所形成的動作,其旋轉座標採用球座標描述。  Create()函式原型CCOrbitCamera* create(fl

Cocos2d-x學習筆記淺析動作類CCAction(1)

Cocos2d-x的動作類CCAction並不是一個在螢幕中顯示的物件,動作必須要依託於CCNode類及其子類的例項才能發揮作用。CCAction繼承於物件類CCObject,有三個子類:有限時間動作、跟隨、移動速度,其中有限時間動作子類CCActionInterVal會形成動畫過程。

Cocos2d-x學習筆記HelloCpp的來龍去脈

【1】首先分析HelloCpp專案的檔案結構,分為Classes、win32、外部檔案依賴三個資料夾,其中外部依賴資料夾暫且不用理會。 Classes主要包含像導演、場景、佈景、攝像機、精靈、App相關類的申明和定義; Win32主要是應用程式框架的WinMain函式入口(包

cocos2d-x學習筆記10重複動作RepeatForever和Repeat 以及動作組合Sequence和Spawn

Repeat和RepeatForever Sprite* sprite=Sprite::create("sprite.png"); sprite->setPosition(Point(visibleSize.width/2,visibleSize.height/

cocos2D-X原始碼分析之從cocos2D-X學習OpenGL20----模型,網格和材質

       openGL在cocos2d-x中的應用點,呼叫的api基本已經介紹的差不多了,這一篇介紹一些3d遊戲中的概念,它們也和底層有一些關係,也是遊戲中常用的一些封裝。       當我們要在螢幕上繪製簡單的圖形時,我們直接計算點的座標就可以,但是遊戲世界中經常有些複

cocos2d-x面試題

(一)執行順序相關: 執行順序: 我們知道Cocos2d-x程式的執行順序是從AppDelegate這個類開始,在其中做一些必要的初始化並建立執行第一個場景,之後有一個主迴圈來維持遊戲每一幀的迴圈,並在此期間執行遊戲的相關邏輯。當遊戲結束時,會呼叫導演類的e