您的位置:首页 > 产品设计 > UI/UE

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

2015-09-21 23:36 716 查看
本博文适合刚刚学完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{
@Override
public void run() {
while(flag){

}
}
}
//当surface创建的时候调用
@Override
public void surfaceCreated(SurfaceHolder holder) {
Log.d("surfaceCreated----->","surface创建的时候调用");
renderThread = new RenderThread();
flag=true;
renderThread.start();//开启线程.....
}

//当surface的大小改变的时候调用,一般的改变是当前显示的界面的改变
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
Log.d("surfaceCreated----->","surface大小改变的时候调用");
}

//当surface销毁的时候调用
@Override
public 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 {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//因为当前的gameUI是继承了surfacevuew,实现了SurfaceHolder.Callback,
// 所以我们认为这行代码在
//主线程中调用了surfaceview,同时也是调用了SurfaceHolder.Callback,
// 这样就可以在多个线程中同时修改界面
GameUI gameUI = new GameUI(getApplicationContext());
setContentView(gameUI);
}
}


这样我们就将开发游戏的前提全部写完了,然后我们运行软件,出现的界面是一片全黑,如图:



然后我们看到LogCat看到有日志打印,到这里准备工作就全部做完了,自己回去试一试吧!!!



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: