android 学习: 人物行走

利用接口只暴露出两个函数出来,内部实现其功能.

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.附件人物图:

     


  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值