求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Modeler   Code  
会员   
 
  
 
 
     
   
分享到
Android游戏开发之绘制游戏主菜单与进度条加载进度(六)
 

发布于 2011-10-21

 

由于Android开发 横竖屏的切换会给游戏开发造成非常麻烦的事情 所以在游戏的制作当中会强制手机屏幕横屏或者竖屏避免横竖屏切换造成的数据重置 即使让程序不在切换屏幕后调用onCreat()方法 也会带来屏幕自适应的麻烦 所以Android的游戏一般都会强制横屏或者强制竖屏。

强制横屏的方法

//强制为横屏

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

强制竖屏的方法

//强制竖屏

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

后期的博文我会详细介绍 可以切换屏幕的情况下开发游戏和软件,废话不多说了。

1.游戏主菜单

游戏中的菜单在游戏开发中虽然在程序员的眼力不是最难的开发难点但是它在玩家眼力确实很重要的一部分,因为任何一款游戏第一个进入玩家眼帘的就是游戏的主菜单,制作一个漂亮的界面对于游戏品质来说会提高很多。现在主流的游戏主菜单都是使用漂亮的背景加上一些动画效果而构成,今天雨松MOMO用自己写的一个Demo向大家介绍如何制作一个漂亮的游戏菜单。

Demo中这个游戏界面一共是又3个部件组成的

1.游戏背景图

2. 图片按钮 教学 与 设置, 在程序中须要对点击图片按钮进行事件的处理

3.动画效果 红框中的小鱼是一组游戏动画 ,从一进游戏菜单界面开始小鱼就从屏幕的右边向左边游让界面动了起来, 游戏菜单中可以多加一些这样的动画效果会使游戏界面活灵活现起来,给玩家一种视觉的冲击,游戏动画绘制的方法我已经在前几篇博客详细的说明 如果看到这里你还是不太清楚动画如何来绘制请阅读我前几篇博客。

为了方便使用图片按钮 所以我写了一个ImageButton类 专门来处理图片按钮的绘制以及监听,这个类是非常有存在必要的 用对象去处理 会比在代码中写死坐标点来处理方便很多可以更好地管理这些图片按钮。用户点击屏幕后程序只需要调用ImageButton成员方法IsClick() 根据返回值 就可以确定用户点击的范围是否在这个图片按钮中。

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.游戏进度条的实现

我相信读我博文的朋友 应该都玩过游戏吧, 进度条机制基本上是个游戏都有,要想做一个完全百分百以按读取进度比例的进度条就需要使用线程检测文件的读取进度来确定当前的进度信息,我觉得这么做完全没必要,纯属多余,而且基本上没有游戏公司这么做,为什么呢?我相信大家玩游戏的时候都会发现有时候进度条读取的很不均匀 比如说进度条从左边给右边走 在中间某一个点卡住了一小会儿,这就表明游戏的进度是通过读取文件结束以后才计算出来的,卡住的时候刚好是在读较多文件的时候。下面我向大家分享一下我在游戏开发中如何来计算进度信息。

在读取进度的界面我会调用Loading()这个方法,每次调用mProgress 就会++ ,在switch 中就可以分布式读取资源,每个case中会加载 不同的资源 所以读取的时间是不一样的,读取的总数 和 当前读取mProgress的值 就 可以计算出进度的百分比值,最后根据计算出来的百分比在屏幕中显示进度信息。

我在强调一下下面代码中的sleep(200)须要替换成真正需要加载的资源,由于本例中没有大量的资源 所以我临时写成Sleep去等待 将进度显示在UI中。

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状态中实时监测mProgress的值, 未读取到100在UI中绘制进度信息,读取到100则修改游戏状态机状态 转跳读取成功界面。

/** 这里表示进度加载完成 **/  

   if (mProgressBar >= 100) {  

setGameState(GAME_TEACH);  

   }  

3.游戏状态机

游戏状态机的实现方式的是通过变量来控制当前游戏状态,在游戏主线程中只更新绘制当前游戏状态下的内容,这就是游戏状态机的原理。

下面的代码中一共有4个游戏状态 分别是 游戏菜单状态,读取进度状态,读取成功教学状态 ,游戏设置状态。在程序执行的过程中根据须要的时候去更改游戏状态。

protected void Draw() {  

    switch (mState) {  

    case GAME_MENU:  

    /**计算鱼动画的X坐标向左超出屏幕后在还原保持一直在屏幕上游动**/  

    mMenuAnimPosX-= 5;  

    if(mMenuAnimPosX + MENU_ANIM_WIDTH <= 0) {  

        mMenuAnimPosX = mScreenWidth;  

    }  

    /**绘制背景**/  

    mCanvas.drawBitmap(mBitMenuBG, 00, 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, 00, 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, 00, 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, 00, 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;  

    }  

如图:我们实现点击设置按钮 游戏状态机跳转到 游戏状态页面

在拿到玩家触摸屏幕后的的X Y坐标 判断是否在游戏主菜单界面 点击设置按钮 状态机切换到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;  

    }  

}  


相关文章

深度解析:清理烂代码
如何编写出拥抱变化的代码
重构-使代码更简洁优美
团队项目开发"编码规范"系列文章
相关文档

重构-改善既有代码的设计
软件重构v2
代码整洁之道
高质量编程规范
相关课程

基于HTML5客户端、Web端的应用开发
HTML 5+CSS 开发
嵌入式C高质量编程
C++高级编程

 
分享到
 
 
     


android人机界面指南
Android手机开发(一)
Android手机开发(二)
Android手机开发(三)
Android手机开发(四)
iPhone消息推送机制实现探讨
手机软件测试用例设计实践
手机客户端UI测试分析
手机软件自动化测试研究报告
更多...   


Android高级移动应用程序
Android应用开发
Android系统开发
手机软件测试
嵌入式软件测试
Android软、硬、云整合


领先IT公司 android开发平台最佳实践
北京 Android开发技术进阶
某新能源领域企业 Android开发技术
某航天公司 Android、IOS应用软件开发
阿尔卡特 Linux内核驱动
艾默生 嵌入式软件架构设计
西门子 嵌入式架构设计
更多...