不多说 上码
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;
}
}