山寨騰訊“愛消除”遊戲7日教程--DAY5

【課程內容】

今天我們將介紹用戶交互技術--屏幕拾取技術,並設計控制中心類,實現更復雜的控制邏輯。

【源代碼下載地址】http://download.csdn.net/detail/elong_2009/6455097

前面幾天的課程,我們實驗了幾種渲染的技術,這些技術是後續開發的基礎。今天我們將研究用戶交互的技術,以實現與用戶的互動。

 

1、屏幕拾取技術

OpenGL ES的開發環境下,可以利用的屏幕拾取技術有很多種,如顏色拾取、射線相交等。但是這些技術對於我們正在山寨的應用來說,顯得過於複雜了。基於應用特定的需求,我們不需要使用複雜的技術就能夠完成屏幕拾取。

從技術角度來說,簡單就是美,能夠滿足需求就是好的。對於基於棋盤佈局的消除遊戲,每個可觸碰對象的座標範圍是可以預測的,因此我們決定採用最簡單的屏幕座標定位技術。

對於更復雜的場景,如對象座標是隨時改變或不能簡單預測的,或者對象表面是不規則形狀的,需要採用其它更復雜的屏幕拾取技術。如果有緣,你們會在筆者另外一個作品《教你玩魔方》中看到這種技術的介紹,合適的時候,我會向大家詳細介紹這種技術。目前這種技術在網絡上可參考的示例還不是太多。

 

2、ScreenTouch 類

我們設計了屏幕拾取ScreenTouch 類來獲取用戶正在操作的對象,如果用戶的操作是有效的,將通過RaiseTouchEvent 方法產生一個事件,用消息的方式通知控制中心ControlCenter處理該動作。

 

//產生有效的觸摸事件,發消息給mHandler統一處理

void RaiseTouchEvent()

{

if(!isValidTouch()) //校驗動作是否合法

return;

Toast.makeText(mContext"Direction:" + getDirection() + " (" + getGridX() + " ," + getGridY() + ")",

     Toast.LENGTH_SHORT).show();

Bundle b = new Bundle();

b.putInt("col1", getGridX());

b.putInt("row1", getGridY());

b.putInt("col2", getNeighborX());

b.putInt("row2", getNeighborY());

Message msg = new Message();

    msg.what = ControlCenter.EXCHANGE_START;

msg.setData(b);

    ControlCenter.mHandler.sendMessage(msg);

}

 

每個touch事件必定會觸發一個交換動作,因此我們向mHandler發送的消息類型定義爲EXCHANGE_START

 

ScreenTouch 類提供了一個公有的方法供CrazyLinkGLSurfaceView.onTouchEvent()方法調用

public boolean Touch(MotionEvent e);

 

3、控制中心ControlCenter 類設計

到目前爲止,我們已經有了若干個渲染類DrawXxx,渲染動態控制效果類CtlXxx以及用戶交互類ScreenTouch。現在,需要把這些獨立的功能組合起來。

從本節開始,我們開始設計遊戲的邏輯算法類ControlCenter ,該類包含在 package elong.CrazyLink.Core中,後續各種遊戲邏輯控制算法,都會放在這個包下面。

我們將前面課程的代碼進行了少量的修改,以便適合新邏輯。

(1)將紋理操作、渲染對象、渲染動態控制對象等從CrazyLinkGLSurfaceView 移除,取而代之是一個static ControlCenter controlCenter;對象

(2)將紋理操作、渲染對象、渲染動態控制對象等移到ControlCenter 類中。

(3)DrawLoadingDrawExchang 對象根據特定事件動作來創建,不需要在初始化時就創建好。

(4)增加了消息處理的機制。mHandler.handleMessage負責處理各種消息類型。

 

下面給出了消息處理的代碼,後續更負責的處理邏輯,大都是通過增加對應的消息處理來實現的:

//消息處理

    public static Handler mHandler = new Handler(){   

        @Override  

public void handleMessage(Message msg) 

{

    // process incoming messages here

switch(msg.what)

{

case EXCHANGE_START: //交換特效開始

{

Bundle b = msg.getData();

int col1 = b.getInt("col1");

int col2 = b.getInt("col2");

int row1 = b.getInt("row1");

int row2 = b.getInt("row2");

     mInExchange[col1][row1] = true; //處於交換狀態

     mInExchange[col2][row2] = true;

     drawExchange = new DrawExchange(drawAnimalmPic[col1][row1], col1, row1, mPic[col2][row2], col2, row2);     

     control.exchange = drawExchange.control;

break;

}

case EXCHANGE_END: //交換特效結束

{

Bundle b = msg.getData();

int col1 = b.getInt("col1");

int col2 = b.getInt("col2");

int row1 = b.getInt("row1");

int row2 = b.getInt("row2");

int picId = mPic[col1][row1];

mPic[col1][row1] = mPic[col2][row2];

mPic[col2][row2] = picId;

     mInExchange[col1][row1] = false; //交換狀態解除

     mInExchange[col2][row2] = false;

control.exchange = null;

drawExchange = null;

break;

}

case LOADING_START: //加載動作開始

     drawLoading = new DrawLoading(loadingTextureId); //創建加載動畫素材

     control.loading = drawLoading.control;

case LOADING_END: //加載動作結束

control.loading = null;

drawLoading = null;

break;

}

}

    };

 

 

最後的效果如下,瘋狂消除的雛形已經初現了!


用手指在屏幕上滑動,已經可以實現交換的效果了。在下節,我們將完整實現一個遊戲用到的全部基本特效。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章