Android 球碰撞反弹 (1)

不多说 上码


1. Ball Class:

public class LeBall {

	private float xAxis ;
	private float yAxis ;
	private float radius;
	private int angle;
	private int order;

	private Bitmap bitmap;

	public LeBall(float x, float y, float r, int o, Bitmap bitmap) {
		// TODO Auto-generated constructor stub
		this.xAxis = x;
		this.yAxis = y;
		this.radius = r;
		this.order = o;
		this.bitmap = bitmap;
		this.angle = new Random().nextInt(LeCrashValues.degree);
	}

	public void draw(Canvas canvas) {
		// TODO Auto-generated method stub
		canvas.drawBitmap(this.bitmap, xAxis, yAxis, null);
	}

	
	public float getxAxis() {
		return xAxis;
	}

	
	public void setxAxis(float xAxis) {
		this.xAxis = xAxis;
	}

	
	public float getyAxis() {
		return yAxis;
	}

	
	public void setyAxis(float yAxis) {
		this.yAxis = yAxis;
	}

	
	public float getRadius() {
		return radius;
	}

	
	public void setRadius(float radius) {
		this.radius = radius;
	}

	
	public int getAngle() {
		return angle;
	}

	
	public void setAngle(int angle) {
		this.angle = angle;
	}

	
	public int getOrder() {
		return order;
	}

	
	public void setOrder(int order) {
		this.order = order;
	}

}

2. SurfaceView Class:


public class LeBallSurfaceView extends SurfaceView implements SurfaceHolder.Callback {

	private LeDrawThread drawThread;
	private LeBallThread ballThread;

	private Bitmap bg;
	private Bitmap[] bitmaps;

	private LeBall moveBall;
	private int mapCount = 0;
	private int ballCount = 0;
	private int currentCount = 0;

	public static List<LeBall> ballList = new Vector<LeBall>();

	public LeBallSurfaceView(Context context) {
		super(context);
		// TODO Auto-generated constructor stub
		getHolder().addCallback(this);
		initBitmaps(getResources());
		addMoveBall(20, 20);
		drawThread = new LeDrawThread(this, getHolder());
		ballThread = new LeBallThread();
	}
        
        @Override
	public void surfaceCreated(SurfaceHolder holder) {
		// TODO Auto-generated method stub
		if (!drawThread.isAlive()) {
			drawThread.start();
		}
		if (!ballThread.isAlive()) {
			ballThread.start();
		}
	}

	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width,
			int height) {
		// TODO Auto-generated method stub

	}

	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {
		
		ballList.clear();
		ballList = null;
		drawThread.setRunning(false);
		drawThread = null;
		ballThread.setRunning(false);
		ballThread = null;
	}

	public void doDraw(Canvas canvas) {
		canvas.drawBitmap(bg, 0, 0, null);
		if (null == ballList)
			return;
		for (LeBall mb : ballList) {
			mb.draw(canvas);
		}
	}

	private void initBitmaps(Resources r) {
		// TODO Auto-generated method stub
		bg = BitmapFactory.decodeResource(r, R.drawable.bg);
		bitmaps = new Bitmap[] {
				BitmapFactory.decodeResource(r, R.drawable.red),
				BitmapFactory.decodeResource(r, R.drawable.green),
				BitmapFactory.decodeResource(r, R.drawable.base),
				BitmapFactory.decodeResource(r, R.drawable.next),
				BitmapFactory.decodeResource(r, R.drawable.heaven)};
		mapCount = bitmaps.length;
	}

	public void addMoveBall(float x, float y) {
		if (null == ballList)
			ballList = new Vector<LeBall>();
		moveBall = new LeBall(x, y, LeCrashValues.ballSize / 2, ballCount, bitmaps[new Random().nextInt(mapCount)]);
		ballList.add(moveBall);
		ballCount ++;
		currentCount ++;
		Log.v(this.getClass().getName(), "current ball count="+currentCount);
	}

	public void removeMoveBall(LeBall mb) {
		ballList.remove(mb);
		mb = null;
		currentCount --;
		Log.v(this.getClass().getName(), "current ball count="+currentCount);
	}
}
3. two Thread:



public class LeBallThread extends Thread {

	private boolean running = true;

	public LeBallThread() {
		super.setName("##-LeBall-");
	}

	public void run() {
		while (running) {
			moveBall();
			LeCrashValues.sleep();
		}
	}

	private void moveBall() {
		try {
			for (LeBall mb : LeBallSurfaceView.ballList) {
				moveBall(mb);
				checkCrash(mb);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private void moveBall(LeBall mb){
		mb.setxAxis(mb.getxAxis() + (float)(LeCrashValues.velocity * LeTrigonometricFunction.cos(mb.getAngle())));
		mb.setyAxis(mb.getyAxis() + (float)(LeCrashValues.velocity * LeTrigonometricFunction.sin(mb.getAngle())));
	}

	private void checkCrash(LeBall mb) {
		if (checkForEdge(mb))
			return;
		checkForCrash(mb);
	}

	private boolean checkForEdge(LeBall mb) {
		if (mb.getxAxis() <= LeCrashValues.fieldLeft) {
			if (mb.getAngle() > 90 && mb.getAngle() <= 180) {
				mb.setAngle(180 - mb.getAngle());
			} else if (mb.getAngle() > 180 && mb.getAngle() < 270) {
				mb.setAngle(540 - mb.getAngle());
			}
			return true;
		} else if (mb.getxAxis() >= LeCrashValues.fieldRight - LeCrashValues.ballSize) {
			if (mb.getAngle() >= 0 && mb.getAngle() < 90) {
				mb.setAngle(180 - mb.getAngle());
			} else if (mb.getAngle() > 270 && mb.getAngle() < 360) {
				mb.setAngle(540 - mb.getAngle());
			}
			return true;
		} else if (mb.getyAxis() <= LeCrashValues.fieldTop) {
			if (mb.getAngle() > 180 && mb.getAngle() < 360) {
				mb.setAngle(360 - mb.getAngle());
			}
			return true;
		} else if (mb.getyAxis() >= LeCrashValues.fieldBottom - LeCrashValues.ballSize) {
			if (mb.getAngle() > 0 && mb.getAngle() < 180) {
				mb.setAngle(360 - mb.getAngle());
			}
			return true;
		}
		return false;
	}

	private void checkForCrash(LeBall moveBall) {
		if (null == LeBallSurfaceView.ballList)
			return;
		try {
			for (LeBall mb : LeBallSurfaceView.ballList) {
				if (mb.getOrder() > moveBall.getOrder()) {
					if (isCrash(moveBall.getxAxis() - mb.getxAxis(), moveBall.getyAxis() - mb.getyAxis(), LeCrashValues.diameter)) {
						handleCrash(moveBall, mb);
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private void handleCrash(LeBall b1, LeBall b2) {
		Log.v(this.getClass().getName(), this.getName() + b1.getOrder() + "--------angle="+b1.getAngle());
		int angle = b2.getAngle();
		b2.setAngle(b1.getAngle());
		b1.setAngle(angle);

		moveBall(b1);

		while (!isSeperated(b1, b2)) {
			moveBall(b1);
		}

	}

	private boolean isSeperated(LeBall b1, LeBall b2) {
		if (isCrash(b1.getxAxis() - b2.getxAxis(), b1.getyAxis() - b2.getyAxis(), LeCrashValues.diameter))
			return false;
		return true;
	}

	private boolean isCrash(float x, float y, float d) {
		if (pow(x) + pow(y) <= pow(d))
			return true;
		return false;
	}

	private float pow(float x) {
		return x * x;
	}

	public boolean isRunning() {
		return running;
	}

	public void setRunning(boolean running) {
		this.running = running;
	}
}
public class LeDrawThread extends Thread {

	private boolean running = true;
	private LeBallSurfaceView view;
	private SurfaceHolder holder;

	public LeDrawThread(LeBallSurfaceView view, SurfaceHolder holder) {
		// TODO Auto-generated constructor stub
		this.view = view;
		this.holder = holder;
		this.running = true;
	}

	public void run() {
		Canvas canvas = null;
		while (running) {
			try {
				canvas = holder.lockCanvas(null);
				synchronized (holder) {
					view.doDraw(canvas);
				}
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				if (canvas != null) {
					holder.unlockCanvasAndPost(canvas);
				}
			}
			LeCrashValues.sleep();
		}
	}


	public boolean isRunning() {
		return running;
	}

	public void setRunning(boolean running) {
		this.running = running;
	}

}


转载于:https://my.oschina.net/huasolna/blog/83452

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值