模拟平抛运动(二)

2014-11-24 02:08:46 · 作者: · 浏览: 1
向的速度 float startVY = 0f; // 初始竖直方向的速度 float v_x = 0f; // 实时水平方向速度 float v_y = 0f; // 实时竖直方向速度 int r; // 小球半径 double timeX; // X方向上的运动时间 double timeY; // Y方向上的运动时间 Bitmap bitmap = null; // 小球图片 BallThread bt = null; // 负责小球移动时的处理线程 boolean bFall = false;// 小球是否已经从木板上下落 float impactFactor = 0.25f; // 小球撞地后速度的损失系数 public Movable(int x, int y, int r, Bitmap bitmap) { this.startX = x; this.x = x; this.startY = y; this.y = y; this.r = r; this.bitmap = bitmap; timeX = System.nanoTime(); // 获取系统时间初始化 // 随机获取小球初始时水平方向的速度(介于最大值和最小值之间) this.v_x = BallView.V_MIN + (int) ((BallView.V_MAX - BallView.V_MIN) * Math.random()); bt = new BallThread(this);// 创建并启动BallThread bt.start(); } /** * 把自己绘制在屏幕上 * * @param canvas */ public void drawSelf(Canvas canvas) { canvas.drawBitmap(bitmap, x, y, null); } }

BallThread:

package com.home.simulationthrow;


/**
 * 负责修改小球位置坐标的线程
 * @author Administrator
 *
 */
public class BallThread extends Thread{	
	private Movable movable;		//Movable对象
	private boolean flag = false;	//线程执行标志位
	private int sleepSpan = 30;		//休眠时间
	private float g = 200;		//球下落的加速度
	private double current;	//记录当前时间
	//构造器:初始化Movable对象引用及线程执行标志位
	public BallThread(Movable movable){
		this.movable = movable;
		this.flag = true;		//设置线程执行的标志位为true
	}
	//方法:负责根据物理公式修改小球位置
	public void run(){
		while(flag){
			current = System.nanoTime();//获取当前时间,单位为纳秒
			double timeSpanX = (double)((current-movable.timeX)/1000/1000/1000);//获取从玩家开始到现在水平方向走过的时间
			//处理水平方向上的运动(获得实时x坐标)
			movable.x = (int)(movable.startX + movable.v_x * timeSpanX);
			//处理竖直方向上的运动			
			if(movable.bFall){//判断球是否已经移出挡板
				double timeSpanY = (double)((current - movable.timeY)/1000/1000/1000);//Y方向上走过的时间	
				//获得实时y坐标
				movable.y = (int)(movable.startY + movable.startVY * timeSpanY + timeSpanY*timeSpanY*g/2);
				//获得实时Y方向上的速度
				movable.v_y = (float)(movable.startVY + g*timeSpanY);				
				//判断小球是否到达最高点(速度方向向上,并且小于了某个阀值,则认为达到了最高点)
				if(movable.startVY < 0 && Math.abs(movable.v_y) <= BallView.UP_ZERO){
					movable.timeY = System.nanoTime();			//设置新的运动阶段竖直方向上的开始时间
					movable.v_y = 0;								//设置新的运动阶段竖直方向上的实时速度
					movable.startVY = 0;							//设置新的运动阶段竖直方向上的初始速度
					movable.startY = movable.y;					//设置新的运动阶段竖直方向上的初始位置
				}
				//判断小球是否撞地
				if(movable.y + movable.r*2 >
= BallView.GROUND_LING && movable.v_y >0){//判断撞地条件 //改变水平方向的速度 movable.v_x = movable.v_x * (1-movable.impactFactor); //衰减水平方向上的速度 //改变竖直方向的速度 movable.v_y = 0 - movable.v_y * (1-movable.impactFactor); //衰减竖直方向上的速度并改变方向 if(Math.abs(movable.v_y) < BallView.DOWN_ZERO){ //判断撞地后的速度,太小就停止 this.flag = false; }else{ //撞地后的速度还可以弹起继续下一阶段的运动 //撞地之后水平方向的变化 movable.startX = movable.x; //设置新的运动阶段的水平方向的起始位置 movable.timeX = System.nanoTime(); //设置新的运动阶段的水平方向的开始时间 //撞地之后竖直方向的变化 movable.startY = movable.y; //设置新的运动阶段竖直方向上的起始位置 movable.timeY = System.nanoTime(); //设置新的运动阶段竖直方向开始运动的时间 movable.startVY = movable.v_y; //设置新的运动阶段竖直方向上的初速度 } } } else if(movable.x + movable.r/2 >= BallView.WOOD_EDGE){//判断球是否移出了挡板 movable.timeY = System.nanoTime(); //记录球竖直方向上的开始运动时间 movable.bFall = true; //设置表示是否开始下落标志位 } try{ Thread.sleep(sleepSpan); //休眠一段时间 } catch(Exception e){ e.printStackTrace(); } } } }

DrawThread:

package com.home.simulationthrow;

import android.graphics.Canvas;
import android.view.SurfaceHolder;

public class DrawThread extends Thread {
	BallView bv; // BallView对象引用
	SurfaceHolder surfaceHolder;// SurfaceHolder对象引用
	boolean flag = false; // 线程执行标志位
	int sleepSpan = 30; // 休眠时间
	long start = System.nanoTime(); // 记录起始时间,该变量用于计算帧速率
	int count = 0; // 记录帧数,该变量用于计算帧速率

	// 构造器
	public DrawThread(BallView bv, SurfaceHolder surfaceHolder) {
		this.bv = bv; 
		this.surfaceHolder = surfaceHolder; 
		this.flag = true; 
	}

	// 方法:线程的执行方法,用于绘制屏幕和计算帧速率
	public void run() {
		Canvas canvas = null;// 声明一个Canvas对象
		while (flag) {
			try {
				canvas = surfaceHolder.lockCanvas(null);// 获取BallView