View、Bitmap游戏常用

Android中经常用到重写View类,用来定义自己的View界面,过程如下:

常见的办法是先定义一个类继承自View

注意:

 

public MyView1(Context context, AttributeSet attrs, int defStyle) {

super(context, attrs, defStyle);

this.setClickable(true);

this.setFocusable(true);

}

 

public MyView1(Context context, AttributeSet attrs) {

super(context, attrs);

this.setClickable(true);

this.setFocusable(true);

}

 

public MyView1(Context context) {

super(context);

this.setClickable(true);

this.setFocusable(true);

}

//这三个构造函数都得重写一遍,因为有些是在new对象时用到的,有些是在从XML文件获取对象的时候用到的。

 

‚在Activity类的XML文件里面将自定义的View类型引用进去(必须是包+类全名),还有一种方式是new一个自定义View对象然后把这个View添加到指定界面。

 

View界面的重绘是重载一个OnDraw()函数,通常在涉及游戏编程这一类的界面重绘刷新要求很高的情况下,先把内容绘制到一个BitMap上面,然后再将这个Bitmap画到View界面,这样就避免了重复的操作界面,提高速度:

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

if (bufferBmp == null) {

//自己创建一张空的位图,而不是加载一张位图图片进来

bufferBmp = Bitmap.createBitmap(this.getWidth(), this.getHeight(),

Config.ARGB_8888);

//new一张画布

bufferCv = new Canvas();

//设置画布的Bitmap,这样画在这张画布上的东西就画在Bitmap上了

bufferCv.setBitmap(bufferBmp);

bt1.draw(bufferCv, paint);

bt2.draw(bufferCv, paint);

bt3.draw(bufferCv, paint);

postInvalidate();

} else {

canvas.drawBitmap(bufferBmp, 0, 0, paint);

}

}

 

    View类里面的事件响应,在View.JAVA里面写。自定义ViewXML文件里面不能添加任何控件。自定义View类里面的好处就是能更加利用一个画布(Canvas)和一支笔(Paint)来控制整个界面的布局。要向自定义View里面添加一个可以容纳其他控件的自定义View可以让自定义View继承自布局类,此时添加的控件会覆盖在ondrwa()函数绘制出来的图像的上面(布局类其实也是继承于View

 

其它自定义类型控件的用法和View类差不多

 

用工厂类获取一张位图:

Bitmap bmp = BitmapFactory.decodeResource(context.getResources(),

R.drawable.aaa);

 

SurfaceView同时实现了双缓冲,SurfaceView标签先在XML文件中定义:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:orientation="vertical" >

 

    <SurfaceView

        android:id="@+id/activity2_sv_1"

        android:layout_width="fill_parent"

        android:layout_height="fill_parent" />

 

    <Button

        android:id="@+id/activity2_bt_1"

        android:layout_width="fill_parent"

        android:layout_height="wrap_content"

        android:layout_alignParentTop="true"

        android:text="去下一个activity" />

 

</RelativeLayout>

然后根据ID获取这个控件,对SurfaceView操作的过程如下:

首先利用这个SurfaceView获取一个SurfaceHolder对象

SurfaceHolder sh=sv.getHolder();

 

‚实现其Callback接口:

sh.addCallback(new Callback() {

 

@Override

public void surfaceDestroyed(SurfaceHolder holder) {

System.out.println("===surfaceDestroyed");

isStop = true;

}

 

@Override

public void surfaceCreated(SurfaceHolder holder) {

rd = new Random();

// Canvas canvas = holder.lockCanvas();

paint.setColor(0xffff0000);

// canvas.drawRect(100, 100, 200, 200, paint);

// holder.unlockCanvasAndPost(canvas);

System.out.println("===surfaceCreated");

isStop = false;

thread = new Thread(new Runnable() {

 

@Override

public void run() {

for (int i = 0; i < 100; i++) {

if (isStop) {

break;

}

try {

Thread.sleep(300);

} catch (InterruptedException e) {

e.printStackTrace();

}

//在操作surface之前要先锁定显卡的一块内存区域

Canvas canvas = sh.lockCanvas();

if (canvas != null) {

canvas.drawColor(Color.BLACK);

canvas.drawCircle(rd.nextInt(320),

rd.nextInt(480), 20 + rd.nextInt(40),

paint);

//使用完后要解锁这边内存区域

sh.unlockCanvasAndPost(canvas);

}

}

}

});

//SurfaceView可以直接用多线程进行操作,而不用借助于Handler

thread.start();

posted @ 2012-09-17 23:01  乌托邦.  阅读(398)  评论(0编辑  收藏  举报