41003帶你走進游戲開發(fā)的世界之主菜單與進度條
本例中出現(xiàn)的資源圖片全部源于互聯(lián)網,本文僅供個人學習。
由于Android開發(fā) 橫豎屏的切換會給游戲開發(fā)造成非常麻煩的事情 所以在游戲的制作當中會強制手機屏幕橫屏或者豎屏避免橫豎屏切換造成的數(shù)據(jù)重置 即使讓程序不在切換屏幕后調用onCreat()方法 也會帶來屏幕自適應的麻煩 所以Android的游戲一般都會強制橫屏或者強制豎屏。
強制橫屏的方法 - //強制為橫屏
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
復制代碼 強制豎屏的方法 - //強制豎屏
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
復制代碼 后期的博文我會詳細介紹 可以切換屏幕的情況下開發(fā)游戲和軟件,廢話不多說了。
1.游戲主菜單
游戲中的菜單在游戲開發(fā)中雖然在程序員的眼力不是最難的開發(fā)難點但是它在玩家眼力確實很重要的一部分,因為任何一款游戲第一個進入玩家眼簾的就是游戲的主菜單,制作一個漂亮的界面對于游戲品質來說會提高很多?,F(xiàn)在主流的游戲主菜單都是使用漂亮的背景加上一些動畫效果而構成,今天雨松MOMO用自己寫的一個Demo向大家介紹如何制作一個漂亮的游戲菜單。
Demo中這個游戲界面一共是又3個部件組成的
1.游戲背景圖
2. 圖片按鈕 教學 與 設置, 在程序中須要對點擊圖片按鈕進行事件的處理
3.動畫效果 紅框中的小魚是一組游戲動畫 ,從一進游戲菜單界面開始小魚就從屏幕的右邊向左邊游讓界面動了起來, 游戲菜單中可以多加一些這樣的動畫效果會使游戲界面活靈活現(xiàn)起來,給玩家一種視覺的沖擊,游戲動畫繪制的方法我已經在前幾篇博客詳細的說明 如果看到這里你還是不太清楚動畫如何來繪制請閱讀我前幾篇帖子。
為了方便使用圖片按鈕 所以我寫了一個ImageButton類 專門來處理圖片按鈕的繪制以及監(jiān)聽,這個類是非常有存在必要的 用對象去處理 會比在代碼中寫死坐標點來處理方便很多可以更好地管理這些圖片按鈕。用戶點擊屏幕后程序只需要調用ImageButton成員方法IsClick() 根據(jù)返回值 就可以確定用戶點擊的范圍是否在這個圖片按鈕中。 - public class ImageButton {
/**按鈕圖片**/
private Bitmap mBitButton = null;
/**圖片繪制的XY坐標**/
private int mPosX =0;
private int mPosY =0;
/**圖片繪制的寬高**/
private int mWidth =0;
private int mHeight =0;
public ImageButton(Context context, int frameBitmapID, int x, int y) {
mBitButton = ReadBitMap(context,frameBitmapID);
mPosX = x;
mPosY = y;
mWidth = mBitButton.getWidth();
mHeight = mBitButton.getHeight();
}
/**
* 繪制圖片按鈕
* @param canvas
* @param paint
*/
public void DrawImageButton(Canvas canvas, Paint paint) {
canvas.drawBitmap(mBitButton, mPosX, mPosY, paint);
}
/**
* 判斷是否點中圖片按鈕
* @param x
* @param y
*/
public boolean IsClick(int x, int y) {
boolean isClick = false;
if (x >= mPosX && x <= mPosX + mWidth && y >= mPosY
&& y <= mPosY + mHeight) {
isClick = true;
}
return isClick;
}
/**
* 讀取圖片資源
* @param context
* @param resId
* @return
*/
public Bitmap ReadBitMap(Context context, int resId) {
BitmapFactory.Options opt = new BitmapFactory.Options();
opt.inPreferredConfig = Bitmap.Config.RGB_565;
opt.inPurgeable = true;
opt.inInputShareable = true;
// 獲取資源圖片
InputStream is = context.getResources().openRawResource(resId);
return BitmapFactory.decodeStream(is, null, opt);
}
}
復制代碼 2.游戲進度條的實現(xiàn)
我相信讀我博文的朋友 應該都玩過游戲吧, 進度條機制基本上是個游戲都有,要想做一個完全百分百以按讀取進度比例的進度條就需要使用線程檢測文件的讀取進度來確定當前的進度信息,我覺得這么做完全沒必要,純屬多余,而且基本上沒有游戲公司這么做,為什么呢?我相信大家玩游戲的時候都會發(fā)現(xiàn)有時候進度條讀取的很不均勻 比如說進度條從左邊給右邊走 在中間某一個點卡住了一小會兒,這就表明游戲的進度是通過讀取文件結束以后才計算出來的,卡住的時候剛好是在讀較多文件的時候。下面我向大家分享一下我在游戲開發(fā)中如何來計算進度信息。
在讀取進度的界面我會調用Loading()這個方法,每次調用mProgress 就會++ ,在switch 中就可以分布式讀取資源,每個case中會加載 不同的資源 所以讀取的時間是不一樣的,讀取的總數(shù) 和 當前讀取mProgress的值 就 可以計算出進度的百分比值,最后根據(jù)計算出來的百分比在屏幕中顯示進度信息。
我在強調一下下面代碼中的sleep(200)須要替換成真正需要加載的資源,由于本例中沒有大量的資源 所以我臨時寫成Sleep去等待 將進度顯示在UI中。 VRt"> - public void Loading() {
// 這里應該是去讀取資源, 由于沒有大量的資源 這里我暫時只用線程去等待
try {
switch (mProgress) {
case 0:
Thread.sleep(200);
break;
case 1:
Thread.sleep(200);
break;
case 2:
Thread.sleep(200);
break;
case 3:
Thread.sleep(200);
break;
case 4:
Thread.sleep(200);
break;
case 5:
Thread.sleep(200);
break;
case 6:
Thread.sleep(200);
break;
case 7:
Thread.sleep(200);
break;
case 8:
Thread.sleep(200);
break;
case 9:
Thread.sleep(200);
break;
case 10:
Thread.sleep(200);
break;
case 11:
Thread.sleep(200);
break;
}
mProgressBar = (100 / 12) * mProgress;
mProgress++;
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
復制代碼 在Loading狀態(tài)中實時監(jiān)測mProgress的值, 未讀取到100在UI中繪制進度信息,讀取到100則修改游戲狀態(tài)機狀態(tài) 轉跳讀取成功界面。 - /** 這里表示進度加載完成 **/
if (mProgressBar >= 100) {
setGameState(GAME_TEACH);
}
復制代碼
3.游戲狀態(tài)機
游戲狀態(tài)機的實現(xiàn)方式的是通過變量來控制當前游戲狀態(tài),在游戲主線程中只更新繪制當前游戲狀態(tài)下的內容,這就是游戲狀態(tài)機的原理。
下面的代碼中一共有4個游戲狀態(tài) 分別是 游戲菜單狀態(tài),讀取進度狀態(tài),讀取成功教學狀態(tài) ,游戲設置狀態(tài)。在程序執(zhí)行的過程中根據(jù)須要的時候去更改游戲狀態(tài)。 - protected void Draw() {
switch (mState) {
case GAME_MENU:
/**計算魚動畫的X坐標向左超出屏幕后在還原保持一直在屏幕上游動**/
mMenuAnimPosX-= 5;
if(mMenuAnimPosX + MENU_ANIM_WIDTH <= 0) {
mMenuAnimPosX = mScreenWidth;
}
/**繪制背景**/
mCanvas.drawBitmap(mBitMenuBG, 0, 0, mPaint);
mCanvas.drawBitmap(mBitMenuTitle, (mScreenWidth - mBitMenuTitle.getWidth()) >> 1,0, mPaint);
mMenuAnim.DrawAnimation(mCanvas, mPaint, mMenuAnimPosX , 100);
/**繪制按鈕**/
mButtonTeach.DrawImageButton(mCanvas, mPaint);
mButtonOption.DrawImageButton(mCanvas, mPaint);
break;
case GAME_LOAD:
mCanvas.drawBitmap(mBitMenuBG, 0, 0, mPaint);
mCanvas.drawBitmap(mBitMenuTitle, (mScreenWidth - mBitMenuTitle.getWidth()) >> 1,0, mPaint);
mButtonTeach.DrawImageButton(mCanvas, mPaint);
mButtonOption.DrawImageButton(mCanvas, mPaint);
mCanvas.drawBitmap(mLoadBack, (mScreenWidth - mLoadBack.getWidth()) >> 1, mScreenHeight >> 1, mPaint);
//這里計算進度條進度
Loading();
break;
case GAME_TEACH:
mCanvas.drawBitmap(mBitTeach, 0, 0, mPaint);
mCanvas.drawBitmap(mMomo, (mScreenWidth >> 1) - (mMomo.getWidth()>> 1), 20, mPaint);
String str1 = "歡迎光臨雨松MOMO的博客 資源已經全部加載完成";
drawRimString(mCanvas,str1,Color.BLACK,(mScreenWidth >> 1) - (((int)mPaint.measureText(str1)) >> 1), mScreenHeight >> 1);
break;
case GAME_OPTION:
mCanvas.drawBitmap(mBitTeach, 0, 0, mPaint);
mCanvas.drawBitmap(mMomo, (mScreenWidth >> 1) - (mMomo.getWidth()>> 1), 20, mPaint);
String str2 = "設置界面暫未 開放 雨松MOMO:xuanyusong@gmail.com";
drawRimString(mCanvas,str2,Color.BLACK,(mScreenWidth >> 1) - (((int)mPaint.measureText(str2)) >> 1), mScreenHeight >> 1);
break;
}
}
復制代碼 如圖:我們實現(xiàn)點擊設置按鈕 游戲狀態(tài)機跳轉到 游戲狀態(tài)頁面
在拿到玩家觸摸屏幕后的的X Y坐標 判斷是否在游戲主菜單界面 點擊設置按鈕 狀態(tài)機切換到GAME_OPTION 游戲設置界面。 - public void UpdateTouchEvent(int x, int y) {
switch(mState) {
case GAME_MENU:
if(mButtonTeach.IsClick(x, y)) {
//教學圖片按鈕被按下
setGameState(GAME_LOAD);
}else if(mButtonOption.IsClick(x, y)) {
//設置圖片按鈕被按下
setGameState(GAME_OPTION);
}
break;
}
}
復制代碼 后期我還會詳細介紹游戲狀態(tài)機,今天只是先簡單給大家介紹一下,希望孩童們快速跟進
老規(guī)矩每一篇博文都會附帶我寫的源代碼,下面給出Demo源碼的下載地
第六講游戲菜單進度條.rar(1.74 MB, 下載次數(shù): 1259)[/I]2011-9-2 23:42 上傳點擊文件名 下載積分: 下載豆 -2 |