20 freely moving balls on the android platform

Source: Internet
Author: User

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 (); // reclaim the image

}

Private class PaintThread extends Thread

{

Private SurfaceHolder holder; // drawing control class

Private Paint paint; // Paint brush

Private float [] [] bils = new float [20] [2]; // used to save the coordinates of 20 balls

Private int [] direction = new int [20]; // used to save the direction of each ball

Private int radius = 20; // the radius of the ball

Public boolean isRun = true; // whether the program is running

Private int ballStep = 20; // The length of each ball.

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 ++) // initialize the direction of each ball

{

Direction [I] = random. nextInt (4 );

}

Music = new MediaPlayer ();

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

Try {

Music. reset ();

Music. setDataSource (file. getAbsolutePath ());

Music. prepare ();

Music. setLooping (true); // loop playback

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 ()

{

Initbils (); // initialize the position of each ball

While (isRun)

{

Draw (); // draw each ball

Logic (); // calculate the position of each ball

}

}

Private void initbils (){

// TODO Auto-generated method stub

Random random = new Random ();

For (int I = 0; I <bils. length; I ++) // initialize the position of each ball

{

Boolean order = true; // cyclically generates the Coordinate Position of a ball until the position is reasonable.

While (order)

{

// Pay attention to the position of the ball

Bils [I] [0] = radius + (float) random. nextInt (BallsView. this. getWidth ()-2 * radius); // abscissa

Bils [I] [1] = radius + (float) random. nextInt (BallsView. this. getHeight ()-2 * radius); // y coordinate

Boolean isCollapse = isCollapse (I, bils [I] [0], bils [I] [1]); // determines whether the ball will collide with other balls

// Here it should be compared with the produced ball, but it is unreasonable to compare it with all the balls.

If (isCollapse = false)

Order = false; // The initial position is reasonable and no random position of the ball is generated.

}

}

}

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); // draw the background to overwrite the original interface.

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

For (int I = 0; I <20; I ++)

{

Canvas. drawCircle (bils [I] [0], bils [I] [1], radius, paint); // display the position of each ball

}

Holder. unlockCanvasAndPost (canvas );

}

}

/**

* Logic of every ball walk

*/

Public void logic ()

{

Random random = new Random ();

// I indicates the first few balls

For (int I = 0; I <bils. length; I ++)

{

// Random direction of each ball. // 0 indicates left. // 1 indicates right. // 2 indicates top. // 3 indicates bottom.

// Determine the direction of the ball

Boolean isSuccess = false;

Switch (direction [I])

{

Case 0: // left

IsSuccess = goLeft (I );

If (isSuccess = false) // An error occurred while leaving

{

IsSuccess = goRight (I); // right

If (isSuccess)

{Direction [I] = 1 ;}// the operation is successful. Modify the direction.

Else {direction [I] = random. nextInt (2) + 2;} // both the left and right sides fail, changing the upper and lower directions

}

Break;

Case 1: // right

IsSuccess = goRight (I );

If (isSuccess = false) // The right side fails.

{

IsSuccess = goLeft (I); // left

If (isSuccess)

{Direction [I] = 0;} // The operation is successful. Modify the direction.

Else {direction [I] = random. nextInt (2) + 2;} // both the left and right sides fail, changing the upper and lower directions

}

Break;

Case 2: // go up

IsSuccess = goUp (I );

If (isSuccess = false) // failed to go up,

{

IsSuccess = goDown (I); // go down

If (isSuccess)

{Direction [I] = 3;} // The operation is successful. Modify the direction.

Else {direction [I] = random. nextInt (2);} // both upper and lower failed, change direction

}

Break;

Case 3: // go down

IsSuccess = goDown (I );

If (isSuccess = false) // failed to go down,

{

IsSuccess = goUp (I); // go up

If (isSuccess)

{Direction [I] = 2;} // The operation is successful. Modify the direction.

Else {direction [I] = random. nextInt (2);} // both upper and lower failed, change direction

}

Break;

}

}

}

/**

* Logic of the I-th ball going up

* @ Param I the number of the ball

* @ Return false indicates that the walking fails, including hitting the wall and hitting the ball. true indicates that the walking is successful.

*/

Private boolean goUp (int I)

{

// TODO Auto-generated method stub

If (bils [I] [1]-radius <= 0) // the top is the upper boundary.

{Return false ;}

Else

{

Boolean isBallUp = isCollapse (I, bils [I] [0], bils [I] [1]-ballStep); // determines whether the ball will collide with other balls

If (isBallUp = false) // no collision

{

Bils [I] [1]-= ballStep;

Return true;

}

Return false;

}

}

/**

* Logic of the I-th ball going down

* @ Param I the number of the ball

* @ Return false indicates that the walking fails, including hitting the wall and hitting the ball. true indicates that the walking is successful.

*/

Private boolean goDown (int I)

{

If (bils [I] [1]> = BallsView. this. getHeight ()-radius) // The bottom of the border is

Return false;

Else

{

Boolean isBallDown = isCollapse (I, bils [I] [0], bils [I] [1] + ballStep); // determines whether the ball will collide with other balls

If (isBallDown = false) // The result does not hit the ball.

{

Bils [I] [1] + = ballStep;

Return true;

}

Return false;

}

}

/**

* Logic of the I-th ball to the right

* @ Param I the number of the ball

* @ Return false indicates that the walking fails, including hitting the wall and hitting the ball. true indicates that the walking is successful.

*/

Private boolean goRight (int I)

{

If (bils [I] [0]> = BallsView. this. getWidth ()-radius) // right side of the border

Return false; // a boundary collision occurs.

Else

{

Boolean isBallRight = isCollapse (I, bils [I] [0] + ballStep, bils [I] [1]); // determines whether the ball will collide with other balls

If (isBallRight = false) // The result is not hitting the ball.

{

Bils [I] [0] + = ballStep;

Return true;

}

Return false; // collision

}

}

/**

* Logic of the I-th ball to the left

* @ Param I the number of the ball

* @ Return false indicates that the walking fails, including hitting the wall and hitting the ball. true indicates that the walking is successful.

*/

Private boolean goLeft (int I)

{

If (bils [I] [0]-radius <0) // The left side is the border.

Return false;

Else

{// Go to the left

Boolean isBallLeft = isCollapse (I, bils [I] [0]-ballStep, bils [I] [1]); // determines whether the ball will collide with other balls

If (isBallLeft = false) // The result does not hit the ball.

{

Bils [I] [0]-= ballStep;

Return true;

}

Return false;

}

}

/**

* Determine if the I-th ball will collide with other balls

* @ Param I the number of the ball

* @ Param x horizontal coordinates of the ball

* @ Param y the ordinate of the ball

* @ Return returns true to indicate that a collision will occur, and returns false to indicate that a collision will not occur.

*/

Private boolean isCollapse (int I, float x, float y ){

// TODO Auto-generated method stub

For (int j = 0; j <bils. length; j ++) // determines whether a ball exists on the top.

{

If (I! = J)

{

Boolean result = this. isCollapsing (bils [j] [0], x, bils [j] [1], y); // determines whether the two balls are in conflict.

If (result = true) // The result hits the ball.

{

Return true;

}

}

}

Return false;

}

/**

* Determine whether two balls will collide

* @ Param x1 the abscissa of the first ball

* @ Param x2 the abscissa of the second ball

* @ Param y1 the ordinate of the first ball

* @ Param y2 the ordinate of the second ball

* @ 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;

}

}

}


This article from "android games" blog, please be sure to keep this source http://chenshuidewoniu.blog.51cto.com/3622711/1299851

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.