Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 1089|回复: 0

Android游戏开发之绘制游戏主菜单与进度条加载进度(十三

[复制链接]

该用户从未签到

发表于 2011-10-25 08:59:01 | 显示全部楼层 |阅读模式
带你走进游戏开发的世界之主菜单与进度条
本例中出现的资源图片全部源于互联网,本文仅供个人学习。


        由于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, 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;

            }

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


      在拿到玩家触摸屏幕后的的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;

            }

        }
复制代码后期我还会详细介绍游戏状态机,今天只是先简单给大家介绍一下,希望孩童们快速跟进
老规矩每一篇博文都会附带我写的源代码,下面给出Demo源码的下载地
第六讲游戏菜单进度条.rar (1.74 MB, 下载次数: 72)
回复

使用道具 举报

该用户从未签到

发表于 2011-10-25 08:59:04 | 显示全部楼层

Re:Android游戏开发之绘制游戏主菜单与进度条加载进度(十

学习了~!
回复 支持 反对

使用道具 举报

该用户从未签到

发表于 2011-10-25 08:59:06 | 显示全部楼层

Re:Android游戏开发之绘制游戏主菜单与进度条加载进度(十

Android游戏开发之绘制游戏主菜单与进度条加载进度(十三)
回复 支持 反对

使用道具 举报

该用户从未签到

发表于 2011-10-25 08:59:09 | 显示全部楼层

Re:Android游戏开发之绘制游戏主菜单与进度条加载进度(十

写的很好。不错。受教了了。呵呵
回复 支持 反对

使用道具 举报

该用户从未签到

发表于 2011-10-25 08:59:12 | 显示全部楼层

Re:Android游戏开发之绘制游戏主菜单与进度条加载进度(十

写的很好,受益匪浅。
回复 支持 反对

使用道具 举报

该用户从未签到

发表于 2011-10-25 08:59:15 | 显示全部楼层

Re:Android游戏开发之绘制游戏主菜单与进度条加载进度(十

谢谢楼主分享
回复 支持 反对

使用道具 举报

该用户从未签到

发表于 2011-10-25 08:59:20 | 显示全部楼层

Re:Android游戏开发之绘制游戏主菜单与进度条加载进度(十

very good thank you
回复 支持 反对

使用道具 举报

该用户从未签到

发表于 2011-10-25 08:59:25 | 显示全部楼层

Re:Android游戏开发之绘制游戏主菜单与进度条加载进度(十

感谢lz
回复 支持 反对

使用道具 举报

该用户从未签到

发表于 2011-10-25 08:59:28 | 显示全部楼层

Re:Android游戏开发之绘制游戏主菜单与进度条加载进度(十

新手学习学习~
回复 支持 反对

使用道具 举报

该用户从未签到

发表于 2012-5-22 16:03:42 | 显示全部楼层
好!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

GMT+8, 2025-1-12 02:55 , Processed in 0.354826 second(s), 34 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表