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