利用接口只暴露出两个函数出来,内部实现其功能.
1.接口
public interface Walker {
//显示人物
void show(Canvas canvas);
//目标坐标
void targetPostion(float x, float y);
}
2. 计算位置
/**
* 计算坐标位置, 方向.
* @author Administrator
*
*/
public class CalcWalk {
private boolean isFinish;
/**
*
* @param x 贴图位置x
* @param y 贴图位置y
* @param step 步长
*/
public CalcWalk(int x, int y, int step ) {
this.x = x;
this.y = y;
this.step = step;
direction = Direction.DOWN;
stepX = stepY = 0;
xTarget = yTarget= 0;
isFinish = true;
}
/**
* 得到目标位置坐标()
* @param f
* @param g
*/
public void targetXY(float f, float g) {
this.xTarget = f;
this.yTarget = g;
isFinish = false;
initData();
}
//得到下一步贴图位置
public void nextPostion() {
// System.out.println("dx="+(xTarget - x) +" sx="+stepX+ " dy="+(yTarget - y)+" sy"+stepY);
float tmX = x, tmY = y;
x = Math.abs(xTarget - x) > Math.abs(stepX) ? x+stepX : x;
y = Math.abs(yTarget - y) > Math.abs(stepY) ? y+stepY : y;
if (tmX == x && tmY == y) {
isFinish = true;
}
}
/**
* 初始化数据,对穿进来的目标位置进行处理.
* 得到偏移量,确定贴图行走的方向
* @param xTarget 目标坐标
* @param yTarget
*/
private void initData() {
float dx = xTarget - x;
float dy = yTarget - y;
float move;
if (Math.abs(dx) > Math.abs(dy)) {
stepX = Math.abs(dx) > step ? dx > 0 ? step : -step : 0;
direction = dx < 0 ? Direction.LEFT :Direction.RIGHT;
move = Math.abs(dy*step/dx);
stepY = Math.abs(dy) > step ? dy > 0 ? move : -move : 0;
} else if (Math.abs(dx) < Math.abs(dy)){
stepY = Math.abs(dy) > step ? dy > 0 ? step : -step : 0;
direction = dy < 0 ? Direction.UP :Direction.DOWN;
move = Math.abs(dx*step/dy);
stepX = Math.abs(dx) > step ? dx > 0 ? move : -move : 0;
}
// System.out.println("dx="+dx+" dy="+dy+" stepx="+stepX+" stepY="+stepY +" "+ direction);
}
public float getX() {
return x;
}
public float getY() {
return y;
}
public Direction getDirection() {
return direction;
}
public boolean getIsFinish() {
return isFinish;
}
private float xTarget, yTarget;
private float x, y; //贴图位置
private float stepX, stepY; //x, y 方向步长
private int step; //步长(人物方向的步长)
private Direction direction; //人物方向.
}
3. 人物与行走具体实现
public class PersonWalk extends CalcWalk implements Walker{
public PersonWalk(Bitmap bitmap, int nState,int x,int y,int step) {
super(x, y, step);
this.bitmap = bitmap;
this.nState = nState;
width = bitmap.getWidth()/nState;
height = bitmap.getHeight()/4;
int left = iframe*width;
int top = 0;//getDirection().ordinal()*height;
src = new Rect(left, top, left+width, top+height);
dst = new Rect(src);
iframe = 0;
time = 100;
}
@Override
public void show(Canvas canvas) {
// long start = System.currentTimeMillis();
if (time > 2) {
time = 0;
//得到下一步坐标
nextPostion();
//算出矩阵
calcRect();
}
canvas.drawBitmap(bitmap, src, dst, null);
Rect r2 = new Rect(100,100,200,200);
Paint paint =new Paint();
paint.setColor(Color.RED);
paint.setStrokeWidth(4);
canvas.drawRect(r2, paint);
if (RectCollision.isCollision(dst, r2))
canvas.drawText("碰撞碰撞!!",22, 22, paint );
// System.out.println(time);
time ++;
}
@Override
public void targetPostion(float x, float y) {
targetXY(x-width/2, y-height/2);
}
/**
* 计算绘图的矩形Rect
*/
private void calcRect() {
if (getIsFinish()) return;
iframe = iframe > nState-2 ? 0 : iframe+1;
src.left = iframe*width;
int dir=0;
switch (getDirection()) {
case DOWN:
dir = 0;
break;
case LEFT:
dir = 1;
break;
case RIGHT:
dir = 2;
break;
case UP:
dir = 3;
break;
default:
break;
}
src.top = dir*height;
src.right = src.left + width;
src.bottom = src.top + height;
dst.left = (int) getX();
dst.top = (int) getY();
dst.right = dst.left + width;
dst.bottom = dst.top + height;
}
private Bitmap bitmap;
private int width, height;
private int nState; //有几个动作
private int iframe;
private Rect src;
private Rect dst;
private long time; //画图间隔
}
4. SurfaceView 显示
public class MySurfaceView extends SurfaceView implements Callback, Runnable {
private SurfaceHolder sfh;
private Thread th;
private Canvas canvas;
public static int screenW, screenH;
private Walker perosn;
private boolean flag;
/**
* SurfaceView初始化函数
*/
public MySurfaceView(Context context) {
super(context);
sfh = this.getHolder();
sfh.addCallback(this);
setFocusable(true);
//位图加载
Bitmap walkBitmap = BitmapFactory.decodeResource(getResources(),
R.drawable.walk);
perosn = new PersonWalk(walkBitmap, 4, 0, 0, 5);
System.out.println("MySurfaceView");
}
/**
* SurfaceView视图创建,响应此函数
*/
public void surfaceCreated(SurfaceHolder holder) {
//屏幕尺寸
screenW = this.getWidth();
screenH = this.getHeight();
flag = true;
// 实例线程
th = new Thread(this);
// 启动线程
th.start();
// -----------以上是SurfaceView游戏框架
System.out.println("surfaceCreated");
}
/**
* 帧动画, 人物行走
*/
private void frameDraw() {
try {
canvas = sfh.lockCanvas();
if (canvas != null) {
canvas.drawRGB(0, 128, 128);
perosn.show(canvas);
}
} catch (Exception e) {
// TODO: handle exception
} finally {
if (canvas != null)
sfh.unlockCanvasAndPost(canvas);
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
float xTarget = event.getX();
float yTarget = event.getY();
perosn.targetPostion(xTarget, yTarget);
return super.onTouchEvent(event);
}
public void run() {
while (flag) {
long start = System.currentTimeMillis();
frameDraw();
long end = System.currentTimeMillis();
try { //50毫秒调用一次
if (end - start < 200) {
Thread.sleep(200 - (end - start));
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
/**
* SurfaceView视图状态发生改变,响应此函数
*/
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
System.out.println("surfaceChanged");
}
/**
* SurfaceView视图消亡时,响应此函数
*/
public void surfaceDestroyed(SurfaceHolder holder) {
flag = false;
System.out.println("surfaceDestroyed");
}
}
5. MainActivity
public class MainActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
//隐去电池等图标和一切修饰部分(状态栏部分)
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
this.setContentView(new MySurfaceView(this));
}
}
6. 程序效果图
7.附件人物图: