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里面写。自定义View的XML文件里面不能添加任何控件。自定义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();