原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://chenshuidewoniu.blog.51cto.com/3622711/1299851

package com.junling.surfaceView;

 

import java.io.File;

import java.io.IOException;

import java.util.Random;

 

import android.content.Context;

import android.graphics.Bitmap;

import android.graphics.BitmapFactory;

import android.graphics.Canvas;

import android.graphics.Color;

import android.graphics.Paint;

import android.media.MediaPlayer;

import android.media.MediaPlayer.OnPreparedListener;

import android.os.Environment;

import android.view.SurfaceHolder;

import android.view.SurfaceHolder.Callback;

import android.view.SurfaceView;

 

public class BallsView extends SurfaceView implements Callback{

private SurfaceHolder holder;

private PaintThread thread;

private Context context;

 

public BallsView(Context context) {

super(context);

// TODO Auto-generated constructor stub

this.holder=this.getHolder();

holder.addCallback(this);

thread=new PaintThread(holder,context);

this.context=context;

 

//this.setBackgroundDrawable(this.getResources().getDrawable(R.drawable.e));

 

}

 

@Override

public void surfaceChanged(SurfaceHolder holder, int format, int width,

int height) {

// TODO Auto-generated method stub

 

 

}

 

@Override

public void surfaceCreated(SurfaceHolder holder) {

// TODO Auto-generated method stub

thread.start();

}

 

@Override

public void surfaceDestroyed(SurfaceHolder holder) {

// TODO Auto-generated method stub

thread.isRun=false;

thread.music.release();

thread.music=null;

thread.bitmap.recycle();//回收图片

}

private class PaintThread extends Thread

{

private SurfaceHolder holder;//绘图控制类

private Paint paint;//画笔

private float[][] balls=new float[20][2];//用于保存20个小球的坐标

private int [] direction=new int[20];//用于保存每个球的方向

private int radius=20;//小球的半径

public boolean isRun=true;//程序是否运行

private int ballStep=20;//每个小球走的步伐长度

public MediaPlayer music;

public Bitmap bitmap=BitmapFactory.decodeResource(getResources(), R.drawable.bg);

public PaintThread(SurfaceHolder holder,Context context) {

this.holder=holder;

paint=new Paint();

Random random=new Random();

for(int i=0;i<20;i++)//为每个小球初始化方向

{

direction[i]=random.nextInt(4);

}

music=new MediaPlayer();

File file=new File(Environment.getExternalStorageDirectory(),"flower.mp3");

try {

music.reset();

music.setDataSource(file.getAbsolutePath());

 

music.prepare();

music.setLooping(true);//循环播放

music.setOnPreparedListener(new OnPreparedListener(){

 

@Override

public void onPrepared(MediaPlayer mp) {

// TODO Auto-generated method stub

music.start();

}

 

});

} catch (IllegalArgumentException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (IllegalStateException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

 

 

}

public void run()

{

initBalls(); //初始化每个小球的位置

while(isRun)

{

draw();//绘出每个小球

logic();//计算每个小球的位置

 

}

}

private void initBalls() {

// TODO Auto-generated method stub

Random random=new Random();

for(int i=0;i<balls.length;i++)//初始化每个小球的位置

{

boolean order=true;//循环产生一个小球的坐标位置,直到该位置合理位置

while(order)

{

//注意小球的位置

balls[i][0]=radius+(float)random.nextInt(BallsView.this.getWidth()-2*radius);//横坐标

balls[i][1]=radius+(float)random.nextInt(BallsView.this.getHeight()-2*radius);//纵坐标

boolean isCollapse=isCollapse(i,balls[i][0],balls[i][1]);//判断该球是否会和其他球相撞

//,这里应该是让它和已经产生的小球进行比较,但是此处是和所有的小球比较有些不合理

if(isCollapse==false)

order=false;//该初始位置是合理的,不用再产生该小球的随机位置

}

}

}

private void draw() {

Canvas canvas=null;

paint.setColor(Color.RED);

if(holder!=null)

{

// TODO Auto-generated method stub

canvas=holder.lockCanvas();

 

canvas.drawColor(Color.BLACK);//画出背景覆盖原来的界面

 

canvas.drawBitmap(bitmap, 0, 0, paint);

for(int i=0;i<20;i++)

{

canvas.drawCircle(balls[i][0], balls[i][1], radius, paint);//显示每个小球 的位置

}

holder.unlockCanvasAndPost(canvas);

}

 

}

/**

* 每个球行走的逻辑

*/

public void logic()

{

Random random=new Random();

//i代表第几个小球

for(int i=0;i<balls.length;i++)

{

//随机每个小球走的方向//0代表左//1代表右//2代表上//3代表下

//判断小球的走向

boolean isSuccess=false;

switch(direction[i])

{

case 0://左走

isSuccess=goLeft(i);

if(isSuccess==false)//左走失败

{

isSuccess=goRight(i);//向右走

if(isSuccess)

{ direction[i]=1;}//走动成功,修改方向

else {direction[i]=random.nextInt(2)+2;}//左右均失败,换上下方向

}

 

break;

case 1://右走

isSuccess=goRight(i);

if(isSuccess==false)//右走失败

{

isSuccess=goLeft(i);//向左走

if(isSuccess)

{direction[i]=0;}//走动成功,修改方向

else{direction[i]=random.nextInt(2)+2;}//左右均失败,换上下方向

}

break;

case 2://上走

isSuccess=goUp(i);

if(isSuccess==false)//上走失败,

{

isSuccess=goDown(i);//向下走

if(isSuccess)

{direction[i]=3;}//走动成功,修改方向

else{direction[i]=random.nextInt(2);}//上下均失败,换方向

}

break;

case 3://下走

isSuccess=goDown(i);

if(isSuccess==false)//下走失败,

{

isSuccess=goUp(i);//向上走

if(isSuccess)

{direction[i]=2;}//走动成功,修改方向

else{direction[i]=random.nextInt(2);}//上下均失败,换方向

}

 

break;

}

}

}

/**

* 第i个球向上走的逻辑

* @param i 球的编号

* @return 返回false代表行走失败(包括撞壁和撞球),true代表行走成功

*/

private boolean goUp(int i)

{

// TODO Auto-generated method stub

if(balls[i][1]-radius<=0)//上边是上边界

{ return false;}

else

{

boolean isBallUp=isCollapse(i,balls[i][0],balls[i][1]-ballStep);//判断该球是否会和其他球相撞

if(isBallUp==false)//没有相撞

{

balls[i][1]-=ballStep;

return true;

}

return false;

}

}

/**

* 第i个球向下走的逻辑

* @param i 球的编号

* @return 返回false代表行走失败(包括撞壁和撞球),true代表行走成功

*/

private boolean goDown(int i)

{

if(balls[i][1]>=BallsView.this.getHeight()-radius)//下边是下边界

return false;

else

{

boolean isBallDown=isCollapse(i,balls[i][0],balls[i][1]+ballStep);//判断该球是否会和其他球相撞

 

if(isBallDown==false)//结果没有撞球

{

balls[i][1]+=ballStep;

return true;

}

return false;

}

}

/**

* 第i个球向右走的逻辑

* @param i 球的编号

* @return 返回false代表行走失败(包括撞壁和撞球),true代表行走成功

*/

private boolean goRight(int i)

{

if(balls[i][0]>=BallsView.this.getWidth()-radius)//右边是右边界

return false;//发生边界碰撞

else

{

boolean isBallRight=isCollapse(i,balls[i][0]+ballStep,balls[i][1]);//判断该球是否会和其他球相撞

if(isBallRight==false)//结果没有撞球

{

balls[i][0]+=ballStep;

return true;

}

return false;//发生碰撞

}

}

/**

* 第i个球向左走的逻辑

* @param i 球的编号

* @return 返回false代表行走失败(包括撞壁和撞球),true代表行走成功

*/

private boolean goLeft(int i)

{

if(balls[i][0]-radius<0)//左边是边界

return false;

else

{ //左边可以走

boolean isBallLeft=isCollapse(i,balls[i][0]-ballStep,balls[i][1]);//判断该球是否会和其他球相撞

if(isBallLeft==false)//结果没有撞球

{

balls[i][0]-=ballStep;

return true;

}

return false;

}

}

/**

* 判断第i个球是否会和其余的球相撞

* @param i 球的编号

* @param x 球的横坐标

* @param y 球的纵坐标

* @return 返回true代表会相撞,返回false代表不会相撞

*/

private boolean isCollapse(int i,float x, float y) {

// TODO Auto-generated method stub

for(int j=0;j<balls.length;j++)//判断上边是否有小球

{

if(i!=j)

{

boolean result=this.isCollapsing(balls[j][0], x, balls[j][1], y);//判断两球是否相撞

if(result==true)//结果撞球

{

return true;

}

}

}

return false;

}

/**

* 判断两个小球是否会相撞

* @param x1 第一个小球的横坐标

* @param x2 第二个小球的横坐标

* @param y1 第一个小球的纵坐标

* @param y2 第二个小球的纵坐标

* @return

*/

private boolean isCollapsing(float x1,float x2,float y1,float y2)

{

if((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)<=(2*radius)*(2*radius))

return true;

return false;

}

}

}

 

本文出自 “android小游戏” 博客,请务必保留此出处http://chenshuidewoniu.blog.51cto.com/3622711/1299851

創作者介紹
創作者 shadow 的頭像
shadow

資訊園

shadow 發表在 痞客邦 留言(0) 人氣()