zoukankan      html  css  js  c++  java
  • 团队项目代码分析

    代码组成部分

    本项目代码共有17个类,主要可以分为活动类、视图类、游戏处理类、辅助功能类4种

    • 活动类
      活动类包含一个类:MagicTower,类此类继承了Activity类,是本项目的主活动。
    • 视图类
      视图类实现了游戏的界面显示,包含了八个类:GameView类、GameScreen类、MainMenu类、SplashScreen类、HelpScreen类、AboutScreen类、FightScreen类、ThreadCanvas类
      其中GameView类继承了View类,是概念层类;GameScreen类继承了GameView类,是游戏的游戏运行视图;MainMenu类继承了GameView类,是游戏的主菜单视图;SplashScreen类继承了GameView类,是游戏的音效选择视图;HelpScreen类继承了GameView类,是游戏的帮助视图;AboutScreen类继承了GameView类,是游戏的关于信息视图;FightScreen类是游戏的战斗视图,由于该视图显示与游戏运行视图之上,调用该类需要传入GameScreen类;ThreadCanvas类是游戏的操作控制类,作为独立线程独立与其他视图之外,用于接收用户的触屏或按键等操作。
    • 游戏处理类
      游戏处理类实现了游戏的后台处理,包括六个类:MainGame类、GameMap类、HeroSprite类、FightCalc类、Task类、MySet类
      其中MainGame类是游戏的运行本体,负责在各个视图间的调度;GameMap类负责处理游戏的地图信息;HeroSprite类负责游戏的主角(即用户操作的角色)数据以及对主角的操作处理;FightCalc类责游戏的战斗处理;Task类负责处理游戏的npc事件以及游戏关键道具;MySet类负责处理游戏的基本数据信息设定,如界面长宽、字体大小、基本文字图像显示等。
    • 辅助功能类
      辅助功能类添加了一些游戏的辅助功能,包括了两个类:CMIDIPlayer类和TextUtil类
      其中CMIDIPlayer类是游戏的音乐播放器,负责播放游戏背景音乐;TextUtil类负责对游戏的一些文本文字进行处理和显示输出。

    代码调用关系

    各个类之间的代码调用关系如下图所示:

    代码分析

    游戏运行会首先打开MagicTower,随后会调用SplashScreen进行音效设置,设置完成调用MainMenu进入主界面,主界面有多个选项,点击相应的选项按“确定”会调用相应的程序,进入相应界面。点击新游戏会调用GameScreen,在GameScreen实例化过程中会调用Gamemap、HeroSprite、task,显示在界面上。
    我在该项目中主要负责 SplashScreen类、HelpScreen类、AboutScreen类、MainMenu类、CMIDIPlayer类和TextUtil类的功能实现。
    SplashScreen类主要代码如下:

        protected void onDraw(Canvas canvas)
        {
            tick++;
            paint.setColor(Color.BLACK);
            MySet.fillRect(canvas, 0, 0, MySet.SCREENW, MySet.SCREENH, paint);
    
            paint.setColor(Color.WHITE);
            String string = "是否开启音效?";
            MySet.drawString(canvas, string, (MySet.SCREENW - paint.measureText(string)) / 2, (MySet.SCREENH - paint.getTextSize()) / 2, paint);
            string = "是";
            MySet.drawString(canvas, string, 350, MySet.SCREENH - paint.getTextSize() - 550, paint);
            string = "否";
            MySet.drawString(canvas, string, MySet.SCREENW - paint.measureText(string) - 350, MySet.SCREENH - paint.getTextSize() - 550, paint);
        }
    
    
        public boolean onTouchEvent(MotionEvent event)
        {
            int x = (int) event.getX();
            int y = (int) event.getY();
            int type = 0;
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    // 记录触摸点坐标
                    if (MySet.touchYes(x,y) )
                    {
                        mMainGame.mbMusic = 1;;
                    }
    
                    else if (MySet.touchNo(x,y))
                    {
                        mMainGame.mbMusic = 0;
                    }
                    mMainGame.controlView(MySet.GAME_MENU);
                    if (mMainGame.mbMusic == 1)
                    {
                        mMainGame.mCMIDIPlayer.PlayMusic(1);
                    }
                    break;
                case MotionEvent.ACTION_UP:
                    break;
            }
            return true;
        }
        public void refurbish()
        {
            // if (tick > 10)
            // {
            // mMainGame.controlView(MySet.GAME_MENU);
            // }
        }
    
    
        public void reCycle()
        {
            paint = null;
            System.gc();
        }
    }
    

    这部分代码主要实现了音效的开启和关闭选择。

    AboutScreen类主要代码:

    
        public AboutScreen(Context context, MainGame mainGame)
        {
            super(context);
            mMainGame = mainGame;
            paint = new Paint();
            tu = new TextUtil();
            title = new TextUtil();
            Resources r = this.getContext().getResources();
            title.InitText((r.getString(R.string.t_about)), (int)(MySet.SCREENW - paint.measureText((r.getString(R.string.t_about)))) / 2, 0, MySet.SCREENW, MySet.SCREENH, 0x0, 0xff0000, 255, MySet.TextSize);
            tu.InitText(((String) r.getString(R.string.about)), 0, 0, MySet.SCREENW, MySet.SCREENH, 0x0, 0xff0000, 255, MySet.TextSize);
        }
    
    
        protected void onDraw(Canvas canvas)
        {
            paint.setColor(Color.BLACK);
            MySet.fillRect(canvas, 0, 0, MySet.SCREENW, MySet.SCREENH, paint);
            drawCont(canvas);
            title.SetTextColor(0xffff00);
            title.DrawText(canvas);
            tu.SetTextColor(0xffff00);
            tu.DrawText(canvas);
        }
    
        private void drawCont(Canvas canvas) //操作栏
        {
            MySet.drawImage(canvas, getImage(GameScreen.IMAGE_WHEEL), 160, 1350, 400, 400, 0, 0);
            MySet.drawImage(canvas, getImage(GameScreen.IMAGE_BTNA), 600, 1380, 240, 240, 0, 0);
            MySet.drawImage(canvas, getImage(GameScreen.IMAGE_BTNB), 800, 1520, 240, 240, 0, 0);
        }
    
        public Bitmap getImage(int type)
        {
            Bitmap result = null;
            switch (type)
            {
                case  GameScreen.IMAGE_WHEEL:
                    result = BitmapFactory.decodeResource(this.getResources(), R.mipmap.wheel_1);
                    break;
                case  GameScreen.IMAGE_BTNA:
                    result = BitmapFactory.decodeResource(this.getResources(), R.mipmap.btna_1);
                    break;
                case  GameScreen.IMAGE_BTNB:
                    result = BitmapFactory.decodeResource(this.getResources(), R.mipmap.btnb_1);
                    break;
            }
            return result;
        }
    
        public boolean onTouchEvent(MotionEvent event)
        {
            int x = (int) event.getX();
            int y = (int) event.getY();
            int type = 0;
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    // 记录触摸点坐标
                    if (MySet.touchUp(x,y) )
                    {
                        tu.Key(MySet.KEY_DPAD_UP);
                    }
                    else if (MySet.touchDown(x,y))
                    {
                        tu.Key(MySet.KEY_DPAD_DOWN);
                    }
                    else
                    {
                        mMainGame.controlView(MySet.GAME_MENU);
                    }
                    break;
                case MotionEvent.ACTION_UP:
                    break;
            }
            return true;
        }
    
    
        public void refurbish()
        {
    
        }
    
    
        public void reCycle()
        {
            paint = null;
            title = null;
            tu = null;
            System.gc();
        }
    }
    

    主要实现了关于界面的绘制,点击任意位置返回主界面。

    HelpScreen类主要代码如下:

    
    
        public HelpScreen(Context context, MainGame mainGame)
        {
            super(context);
            mMainGame = mainGame;
            paint = new Paint();
            title = new TextUtil();
            tu = new TextUtil();
            Resources r = this.getContext().getResources();
            title.InitText((r.getString(R.string.t_help)), (int)(MySet.SCREENW - paint.measureText((r.getString(R.string.t_about)))) / 2, 0, MySet.SCREENW, MySet.SCREENH, 0x0, 0xff0000, 255, MySet.TextSize);
            tu.InitText(((String) r.getString(R.string.help)), 0, 0, MySet.SCREENW, MySet.SCREENH, 0x0, 0xff0000, 255, MySet.TextSize);
        }
    
    
        protected void onDraw(Canvas canvas)
        {
            paint.setColor(Color.BLACK);
            MySet.fillRect(canvas, 0, 0, MySet.SCREENW, MySet.SCREENH, paint);
            drawCont(canvas);
            title.SetTextColor(0xffff00);
            tu.SetTextColor(0xffff00);
            title.DrawText(canvas);
            tu.DrawText(canvas);
        }
    
        private void drawCont(Canvas canvas) //操作栏
        {
            MySet.drawImage(canvas, getImage(GameScreen.IMAGE_WHEEL), 160, 1350, 400, 400, 0, 0);
            MySet.drawImage(canvas, getImage(GameScreen.IMAGE_BTNA), 600, 1380, 240, 240, 0, 0);
            MySet.drawImage(canvas, getImage(GameScreen.IMAGE_BTNB), 800, 1520, 240, 240, 0, 0);
        }
    
        public Bitmap getImage(int type)
        {
            Bitmap result = null;
            switch (type)
            {
                case  GameScreen.IMAGE_WHEEL:
                    result = BitmapFactory.decodeResource(this.getResources(), R.mipmap.wheel_1);
                    break;
                case  GameScreen.IMAGE_BTNA:
                    result = BitmapFactory.decodeResource(this.getResources(), R.mipmap.btna_1);
                    break;
                case  GameScreen.IMAGE_BTNB:
                    result = BitmapFactory.decodeResource(this.getResources(), R.mipmap.btnb_1);
                    break;
            }
            return result;
        }
    
        public boolean onTouchEvent(MotionEvent event)
        {
            int x = (int) event.getX();
            int y = (int) event.getY();
            int type = 0;
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    // 记录触摸点坐标
                    if (MySet.touchUp(x,y) )
                    {
                        tu.Key(MySet.KEY_DPAD_UP);
                    }
                    else if (MySet.touchDown(x,y))
                    {
                        tu.Key(MySet.KEY_DPAD_DOWN);
                    }
                    else
                    {
                        mMainGame.controlView(MySet.GAME_MENU);
                    }
                    break;
                case MotionEvent.ACTION_UP:
                    break;
            }
            return true;
        }
    
        public void refurbish()
        {
    
        }
    
    
        public void reCycle()
        {
            paint = null;
            title = null;
            tu = null;
            System.gc();
        }
    }
    

    实现了帮助界面的绘制,点击任意位置返回主界面。

    MainMenu类主要代码如下:

    public class MainMenu extends GameView
    {
        private String[]	menu		= { "新游戏", "读取上次游戏", "帮助", "关于", "退出" };
        private int			itemNum		= menu.length;
        private int			curItem;
        private boolean		isFirstPlay	= false;
        public int			borderX, borderY;
        private Bitmap		mImgMenuBG	= null;
    
        private MainGame	mMainGame	= null;
    
        private int			split		= MySet.TextSize + 5;
    
        private int			y;
        private Paint		paint		= null;
    
    
        public MainMenu(Context context, MainGame mainGame)
        {
            super(context);
            borderX = 0;
            borderY = 0;
    
            paint = new Paint();
            paint.setTextSize(MySet.TextSize);
            paint.setFlags(Paint.ANTI_ALIAS_FLAG);
            mMainGame = mainGame;
    
            mImgMenuBG = BitmapFactory.decodeResource(this.getResources(), R.mipmap.menu_1);
        }
    
    
        private void next()
        {
            if ((curItem + 1) < itemNum)
                curItem++;
            else
                curItem = 0;
            if ((curItem == 1) && (isFirstPlay))
            {
                curItem++;
            }
        }
    
    
        private void pre()
        {
            if ((curItem - 1) >= 0)
                curItem--;
            else
                curItem = itemNum - 1;
            if ((curItem == 1) && (isFirstPlay))
            {
                curItem--;
            }
        }
    
    
        protected void onDraw(Canvas canvas)
        {
            paint.setColor(Color.BLACK);
            MySet.fillRect(canvas, 0, 0, MySet.SCREENW, MySet.SCREENH, paint);
            drawCont(canvas);
            MySet.drawImage(canvas, mImgMenuBG, (MySet.SCREENW - mImgMenuBG.getWidth()) / 2, 60);
            drawItem(canvas);
            y = (curItem + 1) * split + borderY + 600;
    
            paint.setARGB(255, 255, 0, 0);
    
            MySet.drawString(canvas, menu[curItem], borderX + (MySet.BORDERW - paint.measureText(menu[curItem])) / 2, y, paint);
        }
    
        private void drawCont(Canvas canvas) //操作栏
        {
            MySet.drawImage(canvas, getImage(GameScreen.IMAGE_WHEEL), 160, 1350, 400, 400, 0, 0);
            MySet.drawImage(canvas, getImage(GameScreen.IMAGE_BTNA), 600, 1380, 240, 240, 0, 0);
            MySet.drawImage(canvas, getImage(GameScreen.IMAGE_BTNB), 800, 1520, 240, 240, 0, 0);
        }
    
        public Bitmap getImage(int type)
        {
            Bitmap result = null;
            switch (type)
            {
                case  GameScreen.IMAGE_WHEEL:
                    result = BitmapFactory.decodeResource(this.getResources(), R.mipmap.wheel_1);
                    break;
                case  GameScreen.IMAGE_BTNA:
                    result = BitmapFactory.decodeResource(this.getResources(), R.mipmap.btna_1);
                    break;
                case  GameScreen.IMAGE_BTNB:
                    result = BitmapFactory.decodeResource(this.getResources(), R.mipmap.btnb_1);
                    break;
            }
            return result;
        }
    
        public boolean onTouchEvent(MotionEvent event)
        {
            int x = (int) event.getX();
            int y = (int) event.getY();
            int type = 0;
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    // 记录触摸点坐标
                    if (MySet.touchUp(x,y) )
                    {
                        pre();
                    }
                    else if (MySet.touchDown(x,y))
                    {
                        next();
                    }
                    else if (MySet.touchOK(x,y))
                    {
                        dealItem();
                    }
                    break;
                case MotionEvent.ACTION_UP:
                    break;
            }
            return true;
        }
    
    
        private void drawItem(Canvas canvas)
        {
            paint.setColor(Color.WHITE);
            for (int i = 0; i < itemNum; i++)
            {
                y = (i + 1) * split + borderY + 600;
    
                MySet.drawString(canvas, menu[i], borderX + (MySet.BORDERW - paint.measureText(menu[i])) / 2, y, paint);
            }
        }
    
    
        private void dealItem()
        {
            switch (curItem)
            {
                case 0:
                    mMainGame.controlView(MySet.GAME_RUN);
                    if (mMainGame.mbMusic == 1)
                    {
                        mMainGame.mCMIDIPlayer.PlayMusic(2);
                    }
                    break;
                case 1:
                    mMainGame.controlView(MySet.GAME_CONTINUE);
                    if (mMainGame.mbMusic == 1)
                    {
                        mMainGame.mCMIDIPlayer.PlayMusic(2);
                    }
                    break;
                case 2:
                    mMainGame.controlView(MySet.GAME_HELP);
                    break;
                case 3:
                    mMainGame.controlView(MySet.GAME_ABOUT);
                    break;
                case 4:
                    if (mMainGame.mCMIDIPlayer != null)
                    {
                        mMainGame.mCMIDIPlayer.FreeMusic();
                        mMainGame.mCMIDIPlayer = null;
                    }
                    System.gc();
                    mMainGame.getMagicTower().finish();
                    break;
            }
        }
    
    
        public void refurbish()
        {
    
        }
    
    
        public void reCycle()
        {
            mImgMenuBG = null;
            paint = null;
            System.gc();
        }
    }
    

    该部分实现了主界面的功能,可以选择查看关于、帮助界面,可以选择进入新游戏、退出、继续游戏。

    CMIDIPlayer类主要代码如下:

    public class CMIDIPlayer
    {
        public MediaPlayer	playerMusic;
    
        public MagicTower	magicTower	= null;
    
    
        public CMIDIPlayer(MagicTower magicTower)
        {
            this.magicTower = magicTower;
    
        }
    
    
        // 播放音乐
        public void PlayMusic(int ID)
        {
            FreeMusic();
            switch (ID)
            {
                case 1:
                    //装载音乐
                    playerMusic = MediaPlayer.create(magicTower, R.raw.menu);
                    //设置循环
                    playerMusic.setLooping(true);
                    try
                    {
                        //准备
                        playerMusic.prepare();
                    }
                    catch (IllegalStateException e)
                    {
                        e.printStackTrace();
                    }
                    catch (IOException e)
                    {
                        e.printStackTrace();
                    }
                    //开始
                    playerMusic.start();
                    break;
                case 2:
                    playerMusic = MediaPlayer.create(magicTower, R.raw.run);
                    playerMusic.setLooping(true);
                    try
                    {
                        playerMusic.prepare();
                    }
                    catch (IllegalStateException e)
                    {
                        e.printStackTrace();
                    }
                    catch (IOException e)
                    {
                        e.printStackTrace();
                    }
                    playerMusic.start();
                    break;
            }
        }
    
    
        // 退出释放资源
        public void FreeMusic()
        {
            if (playerMusic != null)
            {
                playerMusic.stop();
                playerMusic.release();
            }
        }
    
    
        // 停止播放
        public void StopMusic()
        {
            if (playerMusic != null)
            {
                playerMusic.stop();
            }
        }
    }
    

    该部分主要实现了音乐的播放和关闭功能。
    TextUtil类主要代码如下:

    public class TextUtil
    {
        int				m_iTextPosX;
        int				m_iTextPosY;
        int				m_iTextWidth;
        int				m_iTextHeight;
    
        int				m_iFontHeight;
    
        int				m_ipageLineNum;
    
        int				m_iTextBGColor; // 背景颜色
        int				m_iTextColor;	// 字体颜色
        int				m_iAlpha;
    
        int				m_iRealLine;	// 字符串真实的行数
        int				m_iCurLine;
    
        String			m_strText;
    
        Vector<String>	m_String;
    
        Paint			m_paint;
    
        int				m_iTextSize;
    
    
        public TextUtil()
        {
            m_paint = new Paint();
            m_String = new Vector<String>();
        }
    
    
        public TextUtil(String strText, int x, int y, int w, int h, int bgcolor, int txetcolor, int a, int iTextSize)
        {
            m_paint = new Paint();
            m_String = new Vector<String>();
    
            m_strText = strText;
    
            m_iTextPosX = x;
            m_iTextPosY = y;
            m_iTextWidth = w;
            m_iTextHeight = h;
    
            m_iTextBGColor = bgcolor;
            m_iTextColor = txetcolor;
    
            m_iTextSize = iTextSize;
    
            m_iAlpha = a;
    
        }
    
    
        public void  InitText(String strText, int x, int y, int w, int h, int bgcolor, int txetcolor, int a, int iTextSize) //设置文本
        {
            m_iCurLine = 0;
            m_ipageLineNum = 0;
            m_iRealLine = 0;
            m_strText = "";
            m_iTextPosX = 0;
            m_iTextPosY = 0;
            m_iTextWidth = 0;
            m_iTextHeight = 0;
            m_iTextBGColor = 0;
            m_iTextColor = 0;
            m_iTextSize = 0;
            m_iAlpha = 0;
    
            m_String.clear();
    
            SetText(strText);
            SetRect(x, y, w, h);
            SetBGColor(bgcolor);
            SetTextColor(txetcolor);
            SetFontSize(iTextSize);
            SetAlpha(a);
    
            SetPaint();
    
            GetTextIfon();
        }
    
    
        public void SetAlpha(int a)
        {
            m_iAlpha = a;
        }
    
    
        public void SetPaint()
        {
            m_paint.setARGB(m_iAlpha, Color.red(m_iTextColor), Color.green(m_iTextColor), Color.blue(m_iTextColor));
            m_paint.setTextSize(m_iTextSize);
        }
    
    
        public void SetFontSize(int iTextSize)
        {
            m_iTextSize = iTextSize;
        }
    
    
        public void SetRect(int x, int y, int w, int h)
        {
            m_iTextPosX = x;
            m_iTextPosY = y;
            m_iTextWidth = w;
            m_iTextHeight = h;
        }
    
    
        public void SetBGColor(int bgcolor)
        {
            m_iTextBGColor = bgcolor;
        }
    
    
        public void SetTextColor(int txetcolor)
        {
            m_iTextColor = txetcolor;
        }
    
    
        public void SetText(String strText)
        {
            m_strText = strText;
        }
    
    
        public void GetTextIfon()
        {
            char ch;
            int w = 0;
            int istart = 0;
            FontMetrics fm = m_paint.getFontMetrics();
    
            m_iFontHeight = (int) Math.ceil(fm.descent - fm.top) + 2;
    
            m_ipageLineNum = (m_iTextHeight-m_iTextSize) / m_iFontHeight;
    
            for (int i = 0; i < m_strText.length(); i++)
            {
                ch = m_strText.charAt(i);
                float[] widths = new float[1];
                String srt = String.valueOf(ch);
                m_paint.getTextWidths(srt, widths);
    
                if (ch == '
    ')
                {
                    m_iRealLine++;
                    m_String.addElement(m_strText.substring(istart, i));
                    istart = i + 1;
                    w = 0;
                }
                else
                {
                    w += (int) (Math.ceil(widths[0]));
                    if (w > m_iTextWidth)
                    {
                        m_iRealLine++;
                        m_String.addElement(m_strText.substring(istart, i));
                        istart = i;
                        i--;
                        w = 0;
                    }
                    else
                    {
                        if (i == (m_strText.length() - 1))
                        {
                            m_iRealLine++;
                            m_String.addElement(m_strText.substring(istart, m_strText.length()));
                        }
                    }
                }
            }
        }
    
    
        public void DrawText(Canvas canvas)
        {
            m_paint.setFlags(Paint.ANTI_ALIAS_FLAG);
            for (int i = m_iCurLine, j = 0; i < m_iRealLine; i++, j++)
            {
                if (j > m_ipageLineNum)
                {
                    break;
                }
                canvas.drawText((String) (m_String.elementAt(i)), m_iTextPosX, m_iTextPosY + m_iFontHeight * j + m_paint.getTextSize() + 3, m_paint);
            }
        }
    
    
        public boolean Key(int keyCode)
        {
            if (keyCode == KeyEvent.KEYCODE_DPAD_UP)
            {
                if (m_iCurLine > 0)
                {
                    m_iCurLine--;
                    return true;
                }
            }
            else if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN)
            {
                if ((m_iCurLine + m_ipageLineNum) < (m_iRealLine - 1))
                {
                    m_iCurLine++;
                    return true;
                }
            }
            return false;
        }
    }
    

    该部分实现了文本的处理和显示。

  • 相关阅读:
    python集成开发环境Anaconda的安装
    hasMap2
    WireShark:TCP三次握手 抓包
    CCF 201409-4 最优配餐
    201403-4 无线网络
    java IO的字节流和字符流及其区别
    平衡二叉树DSW算法
    警惕Java编译器中那些“蜜糖”陷阱
    laravel 学习笔记 —— 神奇的服务容器
    LNMP下安装phpmyadmin的一个小错误解决办法
  • 原文地址:https://www.cnblogs.com/23du/p/10890015.html
Copyright © 2011-2022 走看看