package com.peiandsky;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnTouchListener;
/*开发游戏的时候必定有一个'画板',在上面不断的画图和更新,达到游戏场面
* 这里的'画板',我们采用了继承surfaceView,来实现*/
public class MenuView extends SurfaceView implements SurfaceHolder.Callback,
OnTouchListener {
private DDZ ddz;
SurfaceHolder holder;
Canvas canvas;
boolean threadFlag = true;
Bitmap back;
private int x = 270;
private int y = 50;
private Bitmap[] menuItems;
/*提供一个构造函数,new的时候产生的实例就会具有参数列表的属性
* 参数:context 这里解释一下,这个参数表示context(上下文)调用MenuView的实例,
* 比如我们常看到Toast(this)之类的。这里其实是用this(当前activity)代替了context
* ddz这个参数是为了getResource()。貌似是因为activity下的次方法返回的才是资源
* */
public MenuView(Context context, DDZ ddz) {
super(context);
this.ddz = ddz;
//new一个位图的数组
menuItems = new Bitmap[5];
holder = getHolder();
/*将图片分解成位图,这应该是计算机可识别的二进制数据吧
* 从descode的字面上看应该是反编码*/
back = BitmapFactory
.decodeResource(ddz.getResources(), R.drawable.menu);
menuItems[0] = BitmapFactory.decodeResource(ddz.getResources(),
R.drawable.menu1);
menuItems[1] = BitmapFactory.decodeResource(ddz.getResources(),
R.drawable.menu2);
menuItems[2] = BitmapFactory.decodeResource(ddz.getResources(),
R.drawable.menu3);
menuItems[3] = BitmapFactory.decodeResource(ddz.getResources(),
R.drawable.menu4);
menuItems[4] = BitmapFactory.decodeResource(ddz.getResources(),
R.drawable.menu5);
// for(int i=0;i<menuItems.length;i++)
// {
// menuItems[0]=BitmapFactory.decodeFile("menu"+(i+1)+".png");
// }
/*
*每个surfaceView当中都有一个surface,surfaceView提供精细绘制surface的方法,可以通过它来改变surface的大小,格式等
*surfaceHolder是为surfaceView提供的一个接口类, 方便实现对surface的控制
*给Holder加一个回调接口,这个'回调接口应该就是指SurfaceHolder.Callback'
*依照我的理解,就是给holder实现了callback的以下三个方法*/
this.getHolder().addCallback(this);
//监听触摸事件
this.setOnTouchListener(this);
}
/*
* 因为存在主线程UI线程,又另起一个线程来实现绘画,所以势必会两个线程同时共享一块surface内存
* 为了避免UI线程在绘图期间对surface的操作,我们通过lockCanvas对绘图的画布来加锁,直到解锁之后
* 才让出线程*/
@SuppressLint("WrongCall")
Thread menuThread = new Thread() {
@Override
public void run() {
while (threadFlag) {
try {
//给画布加锁
canvas = holder.lockCanvas();
//给onDraw方法加锁,在解锁之前其它线程不能修改此处内存
synchronized (this) {
onDraw(canvas);
}
// System.out.println("menuThread");
} finally {
//给画布解锁
holder.unlockCanvasAndPost(canvas);
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
/*绘图方法,在这里实现画布上的图像
* 绘制*/
@Override
protected void onDraw(Canvas canvas) {
//画笔
Paint paint = new Paint();
//先画个背景
canvas.drawBitmap(back, 0, 0, paint);
//利用循环递加的方式,绘制出其它按钮的图像
for (int i = 0; i < menuItems.length; i++) {
canvas.drawBitmap(menuItems[i], x, y + i * 43, paint);
}
// paint.setColor(Color.WHITE);
// paint.setTextSize(32);
// canvas.drawText("开始游戏", 158, 91, paint);
// canvas.drawText("游戏帮助", 158, 121, paint);
// canvas.drawText("关于游戏", 158, 151, paint);
}
/*关于callBack中方法触发的时机
* surfaceChange在surface大小等的改变时触发*/
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
}
@Override
/*在surface创建时激发,一般在这里调用过绘图的线程
* 这里用到标志位threadFlag*/
public void surfaceCreated(SurfaceHolder holder) {
threadFlag = true;
menuThread.start();
System.out.println("surfaceCreated");
}
/*销毁时激发,一般在这里对绘图线程停止,释放*/
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
threadFlag = false;
boolean retry = true;
while (retry) {// 循环
try {
menuThread.join();// 等待线程结束
retry = false;// 停止循环
} catch (InterruptedException e) {
}// 不断地循环,直到刷帧线程结束
}
}
/*监听触摸事件*/
@Override
public boolean onTouch(View v, MotionEvent event) {
//获取触摸的坐标
int ex = (int) event.getX();
int ey = (int) event.getY();
System.out.println(event.getX() + "," + event.getY());
int selectIndex = -1;
for (int i = 0; i < menuItems.length; i++) {
System.out.println(x+" "+(y+i*43));
if (Poke.inRect(ex, ey, x, y + i * 43, 125, 33)) {
selectIndex = i;
break;
}
}
System.out.println(selectIndex);
switch (selectIndex) {
case 0:
ddz.handler.sendEmptyMessage(DDZ.GAME);
break;
case 1:
break;
case 2:
break;
case 3:
break;
case 4:
ddz.finish();
break;
}
return super.onTouchEvent(event);
}
}