今天在学习Android游戏开发中的crazy football中遇到了一些问题。首先碰到的就是surfaceview相关的知识,由于之前没有接触过图像渲染方面的东西,觉得理解起来不太容易。因此专门将这个知识点拿出来学习一下。
学习surfaceview之前,肯定有必要先了解一下view的基本知识。其实简单理解view就是每个activity界面的显示效果。系统自带了很多种效果,例如各种各样的布局文件,就是其中的很多种效果。我们也可以自己定义自己的效果。最简单的就是我们新建一个画布,在画布上绘制我们自己想要看的东西。这也是一种显示效果。不过自己定义的view有一个致命的缺点,它的参数更改只能在UI线程中进行。若要执行的任务比较消耗时间,就会导致UI线程长期的等待,从而程序死掉。下面是一个简单的自定义view代码:
- package com.example.test;
- import android.app.Activity;
- import android.content.Context;
- import android.graphics.Canvas;
- import android.graphics.Color;
- import android.graphics.Paint;
- import android.os.Bundle;
- import android.view.View;
- public class AnimateViewActivity extends Activity {
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(new AnimateView(this));//這邊傳入的this代表這個對象,
- // setContentView(new DemoSurfaceView(this));//這邊傳入的this代表這個對象,
- // 因 為Activity是繼承自Content類的,因此該對象也
- // 可向上轉型為Content類型作為
- // AnimateView的構造方法的參數
- }
- class AnimateView extends View{
- float radius = 10;
- Canvas canvas=new Canvas();
- Paint paint=new Paint(); ;
- public AnimateView(Context context) {
- super(context);
- paint.setColor(Color.RED);
- paint.setStyle(Paint.Style.FILL_AND_STROKE);
- //onDraw(canvas);
- }
- @Override
- protected void onDraw(Canvas canvas) {
- canvas.translate(200, 200);
- canvas.drawCircle(80, 80, radius++, paint);
- if(radius > 100){
- radius = 10;
- }
- invalidate();//通过调用这个方法让系统自动刷新视图
- }
- }
- }
这段
代码实现了不断更新圆圈半径的显示。改变的过程是通过ondraw方法中的invalidate()方法实现的。
下面来看看surfaceview的使用方法:
讲到surfaceVIEW,就得先提到与其相关联的其他几个名词:1,surface,2,surfaceholder,3 callback()
首先
来解释一下,surface其实就是一块内存区域,代表了一块显存。surfaceholder可以管理控制surfaceview,比如说控制画布canvas等
callback()函数管理了surface生命周期的三个主要函数,oncreat,onchange,ondestroy.
使用的基本方法:
1,创建类继承surfaceview 并实现callback接口
2,初始化init,包括得到surfaceholder,(getholder()方法得到),利用holder来添加回调函数callback()
3, 新建一个线程,来处理生命周期中所需要处理的动作(可选)
4, 在生命周期函数中,不断结束线程和开始线程,具体由动作决定(停止线程join()).
下面是一段实例代码:(只需要在上一段代码中添加这一句,并注释上一句就行// setContentView(new DemoSurfaceView(this));//這邊傳入的this代表這個對象,)
- package com.example.test;
- import android.content.Context;
- import android.graphics.Canvas;
- import android.graphics.Color;
- import android.graphics.Paint;
- import android.view.SurfaceHolder;
- import android.view.SurfaceHolder.Callback;
- import android.view.SurfaceView;
- public class DemoSurfaceView extends SurfaceView implements Callback{
- LoopThread thread;
- public DemoSurfaceView(Context context) {
- super(context);
- init(); //初始化,设置生命周期回调方法
- }
- private void init(){
- SurfaceHolder holder = getHolder();
- holder.addCallback(this); //设置Surface生命周期回调
- thread = new LoopThread(holder, getContext());
- }
- @Override
- public void surfaceChanged(SurfaceHolder holder, int format, int width,
- int height) {
- }
- @Override
- public void surfaceCreated(SurfaceHolder holder) {
- thread.isRunning = true;
- thread.start();
- }
- @Override
- public void surfaceDestroyed(SurfaceHolder holder) {
- thread.isRunning = false;
- try {
- thread.join();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- /**
- * 执行绘制的绘制线程
- * @author Administrator
- *
- */
- class LoopThread extends Thread{
- SurfaceHolder surfaceHolder;
- Context context;
- boolean isRunning;
- float radius = 10f;
- Paint paint;
- public LoopThread(SurfaceHolder surfaceHolder,Context context){
- this.surfaceHolder = surfaceHolder;
- this.context = context;
- isRunning = false;
- paint = new Paint();
- paint.setColor(Color.YELLOW);
- paint.setTextSize(100);
- paint.setStyle(Paint.Style.STROKE);
- }
- @Override
- public void run() {
- Canvas c = null;
- while(isRunning){
- try{
- synchronized (surfaceHolder) {
- c = surfaceHolder.lockCanvas(null);
- doDraw(c);
- //通过它来控制帧数执行一次绘制后休息50ms
- Thread.sleep(50);
- }
- } catch (InterruptedException e) {
- e.printStackTrace();
- } finally {
- surfaceHolder.unlockCanvasAndPost(c);
- }
- }
- }
- public void doDraw(Canvas c){
- //这个很重要,清屏操作,清楚掉上次绘制的残留图像
- c.drawColor(Color.BLACK);
- c.translate(200, 200);
- c.rotate(30);
- // c.drawCircle(200,200, radius++, paint);
- c.drawText("hello"+radius++, 50, 50, paint);
- if(radius > 100){
- radius = 10f;
- }
- }
- }
- }