本博文适合刚刚学完android基础准备做做项目实战一下的人看,在我的博文中,我会将这个游戏的开发过程讲得非常详细,所以非常容易理解,植物大战僵尸这个游戏我会出一系列的博文详细解释,所以有兴趣的人可以持续跟进哦!

             一:制作游戏必备的三个API

(1)SurfaceView:类似于于展示电影的屏幕,这个API是一个非常强大的API,它的内部是一个双缓冲机制,显示界面的效率非常快。那么什么

是双缓冲机制呢?

例如有一个A和一个B两个线程,

A:如果A先加载数据,加载数据完成之后显示界面

B:同时B先显示界面,显示完成时候B再加载数据

这个双缓冲机制的意思就是这两个线程可以同时存在,一个加载数据,另一个显示界面,这样的交叉加载显示会是游戏的运行效率非常快。

SurfaceView有两个主要的功能:

①提供一个可以绘制的surface

②可以在多个线程同时修改界面,如果想要在多个线程中修改界面,就要注意两个前提条件:

1.将所有的surface在主线程中被调用

2..将所有的surfaceHolder.callback在主线程中被调用

                    (2)surfaceHolder:类似于展示电影的内容,
                    (3)Thread:类似于工作人员,
                 
                 二:多线程同时修改界面UI的前提:
                            (1)实现调用SurfaceView API的两个前提: 
                           第一步就是创建一个GameUI类,用于进行游戏界面的更新,那么要实现在多个线程中同时修改界面,我们必须要保证surface和
         surfaceHolder.callback在主线程中被调用,要实现这个前提,我们可以将GameUI 继承surface类,并实现surfaceHolder.callback,然后我们
         再在主函数中调用GameUI,然而要想要surfaceHolder.callback生效,我们必须要调用一下surfaceHolder.addcallback方法,所以我们在刚刚
         的构造方法中使用getHolder()方法得到一个surfaceHolder对象,然后我们再用这个对象调用。
             注意:当软件运行起来,我们的界面是一片黑色,现在我们看日志,当软件运行起来的时候我们的LogCat中打印出了surfaceCreated,             surfaceChanged的日志,当我们点击返回键的时候会调用销毁的那个方法,但是当我们点击Home键的时候,日志中同样会打印销毁的方法,然
后重新进入软件的时候又会重新打印一次创建和改变的方法,这是因为surface对我们的CPU和内存消耗非常大,所以我们的google工程师为了节
约资源,就设置了这样一个机制,每次重新进入的时候都要重新加载。
      
                          (2)创建线程的两个条件:  
            (1)我们必须要保证线程是有效的,怎么保证线程是有效的呢?
      就是我们必须保证我们的线程在  surfaceHolder.callback.surfaceCreated()surfaceHolder.callback.surfaceDestroyed()方法之间,意思就是
      我们必须保证我们的线程必须在 surfaceHolder.callback.surfaceCreated()之后创建,在surfaceHolder.callback.surfaceDestroyed()之前停止,
      就相当于我们的线程作用范围在这两个方法之间,这样才是一个有效的线程,这样才能够去修改界面。
          
           (2)这样我们再去新建一个RenderThread内部类,实现Thread,这样我们就创建了一个新的线程,然后我们在surfaceCreated()方法中新建
一个 RenderThread对象,再开启线程,在surfaceDestroyed中销毁,由于stop方法存在一些安全隐患,所以google工程师已经不在建议我们使用
stop方法去停止线程了,现在我们可以通过一个线程循环来停止线程,通过循环停止线程很简单,我们现在RenderThread的run方法中新建一个while(true),然后在新建一个flag标记,这个标记代表一个线程运行的标记,然后在开启线程的时候将标记变成true,然后在关闭线程的时候直接将
标记变成false就关闭线程了。
  
        GameUI类:
package game.qiu.com.game;import android.content.Context;
import android.os.Handler;
import android.util.AttributeSet;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;/*** 这是游戏的UI类* 如果想让SurfaceHolder.Callback生效,我们必须要去调用* SurfaceHolder.addCallback(SurfaceHolder.Callback)* 这样的一个方法,这样就可以保证实现SurfaceHolder.Callback的这* 三个方法能够生效*/
public  class GameUI extends SurfaceView implements SurfaceHolder.Callback{private RenderThread renderThread;private boolean flag;// 线程运行的一个标记public GameUI(Context context) {super(context);SurfaceHolder holder = getHolder();holder.addCallback(this);//保证surfaceCreated,surfaceChanged,surfaceDestroyed能够生效}private class RenderThread extends Thread{@Overridepublic void run() {while(flag){}}}//当surface创建的时候调用@Overridepublic void surfaceCreated(SurfaceHolder holder) {Log.d("surfaceCreated----->","surface创建的时候调用");renderThread = new RenderThread();flag=true;renderThread.start();//开启线程.....}//当surface的大小改变的时候调用,一般的改变是当前显示的界面的改变@Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {Log.d("surfaceCreated----->","surface大小改变的时候调用");}//当surface销毁的时候调用@Overridepublic void surfaceDestroyed(SurfaceHolder holder) {Log.d("surfaceCreated----->","surface销毁的时候调用");//renderThread.stop();//停止线程,因为这个方法有一些安全隐患,所以java工程师//已经不建议我们通过这个方法去停止线程了,所以我们停止线程都是通过线程的一个循环,让线程自动停止flag=false;//停止一个线程只要直接将标记定义为false就行了}
}

MainActivity类:

package game.qiu.com.game;import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);//因为当前的gameUI是继承了surfacevuew,实现了SurfaceHolder.Callback,// 所以我们认为这行代码在//主线程中调用了surfaceview,同时也是调用了SurfaceHolder.Callback,// 这样就可以在多个线程中同时修改界面GameUI gameUI = new GameUI(getApplicationContext());setContentView(gameUI);}
}
       这样我们就将开发游戏的前提全部写完了,然后我们运行软件,出现的界面是一片全黑,如图:
                                              
         然后我们看到LogCat看到有日志打印,到这里准备工作就全部做完了,自己回去试一试吧!!!
                                        
           
                                     

植物大战僵尸一:多线程修改UI界面,游戏必备API相关推荐

  1. C#-WinForm跨线程修改UI界面

    背景 在我做WinForm开发的过程中,经常会遇到耗时操作或阻塞操作.他们会引发软件的卡顿甚至假死,严重影响软件的使用.因此,这类耗时或阻塞的操作一般都会使用异步的方式去执行,不影响主线程(UI线程) ...

  2. 植物大战僵尸用户存档修改(CSDN任务1,20210418)

    植物大战僵尸用户存档修改 任务目标 目标1:修改<植物⼤战僵⼫>的存档⽂件,能跳到指定关卡,例如「5-1」 目标2:修改<植物⼤战僵⼫>的存档⽂件,让游戏账户有指定数量的⾦币 ...

  3. c语言游戏call调用,C语言-植物大战僵尸-刷僵尸call;fps游戏CS-方框透视(矩阵+传统)...

    C语言-植物大战僵尸-刷僵尸call:fps游戏CS-方框透视(矩阵+传统)前言:大家好,我是向上先生,嘿嘿~最近在学习逆向.反汇编等等,首先我在非常感谢52pojie这个平台,差不多很多学习资源都是 ...

  4. 对植物大战僵尸的数据修改

    植物大战僵尸是许多人的回忆. 在学习相关知识后我决定修改其中的数据. 有三个任务点 1.修改关卡到5-1 2.修改金币为10000 3.开启迷你游戏和生存模式 需要的是一个二进制编辑器 通过网络查找我 ...

  5. 单机版植物大战僵尸部分内容修改

    植物大战僵尸 游戏下载 工具下载 游戏配置文件路径 修改游戏关卡 修改商城金币 解锁迷你游戏和生存模式 游戏下载 植物大战僵尸 提取码: 71ki 工具下载 010编辑器. 游戏配置文件路径 一般默认 ...

  6. 植物大战僵尸原版--简单修改攻略

    1.下载 植物大战僵尸下载地址----提取码------20he https://pan.baidu.com/s/1SX4Up78jx8-qZTYlLZGhrA 2.安装(安装) 将两个压缩包解压缩到 ...

  7. 植物大战僵尸 “Hex editor” 修改关卡进度和金币数量攻略

    一. 任务/目的: 通过修改十六进制控制关卡的地址上的数据,进行修改植物大战僵尸游戏的关卡--(例如. 关卡:8-8) 通过修改十六进制控制金币的地址上的数据,进行修改植物大战僵尸游戏的金币数量--( ...

  8. C# Wpf异步修改UI,多线程修改UI(二)

    1.使用定时器异步修改 这是相对比较简单的方法 在Wpf中定时器使用DiapatcherTimer,不使用Timer原因: 在一个应用程序中,Timer会重复生成time事件,而DispatcherT ...

  9. QT Creator 使用 design 修改 ui界面编译后界面未更新代码提示

    我的开发环境: 1,VS2008 2,qt-win-opensource-4.7.4-vs2008 3,qt-vs-addin-1.1.9 为了开发方便,我也安装了qt-creator-win-ope ...

最新文章

  1. 我的家庭私有云计划-13
  2. 网络营销立足于网站自身的优化与运营
  3. hdu 2191 悼念512汶川大地震遇难同胞 【多重背包】(模板题)
  4. SpringBoot的优势
  5. 安卓入门系列-01开发工具Android Studio的安装
  6. Android安全与逆向之Java虚拟机和Dalvik虚拟机的区别
  7. php yaf框架和icon,php中Yaf框架是什么?
  8. 求锤得锤,你要的一致性 hash 来了! | 附代码
  9. JavaScript 进阶问题列表
  10. 有关 strongSwan 的英文文档
  11. 【编程开发】 C与C++中的关于函数指针的强制类型转换与指针函数的关系
  12. application.properties和bootstrap.yml到底先读哪个文件
  13. 在网页中显示某个目录文件(未成功)
  14. #2991. kiki君的护盾 (shield)
  15. Java如何进行Base64的编码(Encode)与解码(Decode)?
  16. 无情刀永不知错,无缘分只叹奈何
  17. Suzy想吃烤蛋挞了Day35 | 贪心算法进行时:860. 柠檬水找零,406. 根据身高重建队列,452. 用最少数量的箭引爆气球
  18. iphone微信下无法播放音乐
  19. 【整理】SSD的TRIM指令作用与GC关系
  20. 图像视频大数据产业技术创新联盟成立

热门文章

  1. 小程序原生swiper中bindtransition监听滑动效果
  2. xp计算机用户名在哪里设置路由器,XP系统如何连接无线路由器?XP电脑安装路由器和猫的操作步骤...
  3. win10桌面图标字体看不清楚
  4. 监控与性能分析系列:2)netstat、ss对比使用
  5. hardhat开发dapp初始化操作
  6. html中a标签如何进行锚点,a标签中的锚点使用方法
  7. pdf文件怎么压缩得更小?如何改变pdf文件的大小?
  8. Android知识点总结
  9. CSS:标准文档流、浮动、绝对定位—(解决有时候父元素不能自动扩展)
  10. 使用一维数组输出最小值及其最大下标