// MovingBallsWithPointerActivity.java Copyright (c) Kari Laitinen // http://www.naturalprogramming.com/ // 2012-01-25 File created. // 2015-03-14 Last modification. /* This is the main and only .java file of an Android app called MovingBallsWithPointer. This program displays three balls which can be moved by touching them with a finger (pointer). The balls are objects of class Ball. To run this program in Android studio, you have to set up a project named MovingBallsWithPointer and use the package name that is given below. This program does not need any .xml files. So you can accept the .xml files generated by Android Studio. After you have created the project, you can overwrite the created .java file with this file. */ // http://developer.android.com/reference/android/view/MotionEvent.html package moving.balls.with.pointer ; import android.app.Activity ; import android.os.Bundle ; import android.graphics.* ; // Classes Canvas, Color, Paint, RectF, etc. import android.view.View ; import android.view.MotionEvent ; import android.content.Context ; class Ball { int ball_center_point_x = 0 ; int ball_center_point_y = 0 ; int ball_color = Color.RED ; int ball_diameter = 128 ; boolean this_ball_is_activated = false ; public Ball( int given_center_point_x, int given_center_point_y, int given_color ) { ball_center_point_x = given_center_point_x ; ball_center_point_y = given_center_point_y ; ball_color = given_color ; } public void activate_ball() { this_ball_is_activated = true ; } public void deactivate_ball() { this_ball_is_activated = false ; } public int get_ball_center_point_x() { return ball_center_point_x ; } public int get_ball_center_point_y() { return ball_center_point_y ; } public int get_ball_diameter() { return ball_diameter ; } public void move_right() { ball_center_point_x += 3 ; } public void move_left() { ball_center_point_x -= 3 ; } public void move_up() { ball_center_point_y -= 3 ; } public void move_down() { ball_center_point_y += 3 ; } public void move_this_ball( int movement_in_direction_x, int movement_in_direction_y ) { ball_center_point_x = ball_center_point_x + movement_in_direction_x ; ball_center_point_y = ball_center_point_y + movement_in_direction_y ; } public void move_to_position( int new_center_point_x, int new_center_point_y ) { ball_center_point_x = new_center_point_x ; ball_center_point_y = new_center_point_y ; } public void shrink() { // The if-construct ensures that the ball does not become // too small. if ( ball_diameter > 10 ) { ball_diameter -= 6 ; } } public void enlarge() { ball_diameter += 6 ; } public void set_diameter( int new_diameter ) { if ( new_diameter > 5 ) { ball_diameter = new_diameter ; } } public void set_color( int new_color ) { ball_color = new_color ; } public boolean contains_point( Point given_point ) { int ball_radius = ball_diameter / 2 ; // Here we use the Pythagorean theorem to calculate the distance // from the given point to the center point of the ball. // See the note at the end of this file. int distance_from_given_point_to_ball_center = (int) Math.sqrt( Math.pow( ball_center_point_x - given_point.x, 2 ) + Math.pow( ball_center_point_y - given_point.y, 2 ) ) ; return ( distance_from_given_point_to_ball_center <= ball_radius ) ; } public void draw( Canvas canvas ) { Paint filling_paint = new Paint() ; filling_paint.setStyle( Paint.Style.FILL ) ; filling_paint.setColor( ball_color ) ; Paint outline_paint = new Paint() ; outline_paint.setStyle( Paint.Style.STROKE ) ; // Default color for a Paint is black. canvas.drawCircle( ball_center_point_x, ball_center_point_y, ball_diameter / 2, filling_paint ) ; // If this ball is activated, it will have a thick black edge if ( this_ball_is_activated == true ) { outline_paint.setStrokeWidth( 3 ) ; } canvas.drawCircle( ball_center_point_x, ball_center_point_y, ball_diameter / 2, outline_paint ) ; } } final class MovingBallsWithPointerView extends View { int view_width, view_height ; Ball first_ball, second_ball, third_ball ; Ball ball_being_moved = null ; Point previous_pointer_position ; public MovingBallsWithPointerView( Context context ) { super( context ) ; setBackgroundColor( 0xFFFFFFE0 ) ; // Light Yellow } public void onSizeChanged( int current_width_of_this_view, int current_height_of_this_view, int old_width_of_this_view, int old_height_of_this_view ) { view_width = current_width_of_this_view ; view_height = current_height_of_this_view ; // We create new balls always when the size of this view // is changed. This seems to happen before the balls are // drawn for the first time. first_ball = new Ball( view_width / 2, view_height / 2 - 150, Color.RED ) ; second_ball = new Ball( view_width / 2, view_height / 2, Color.GREEN ) ; third_ball = new Ball( view_width / 2, view_height / 2 + 150, Color.BLUE ) ; } public boolean onTouchEvent ( MotionEvent motion_event ) { if ( motion_event.getAction() == MotionEvent.ACTION_DOWN ) { Point pointer_position = new Point( (int) motion_event.getX(), (int) motion_event.getY() ) ; if ( first_ball.contains_point( pointer_position ) ) { ball_being_moved = first_ball ; ball_being_moved.activate_ball() ; } else if ( second_ball.contains_point( pointer_position ) ) { ball_being_moved = second_ball ; ball_being_moved.activate_ball() ; } else if ( third_ball.contains_point( pointer_position ) ) { ball_being_moved = third_ball ; ball_being_moved.activate_ball() ; } previous_pointer_position = pointer_position ; } else if ( motion_event.getAction() == MotionEvent.ACTION_MOVE ) { if ( ball_being_moved != null ) { Point new_pointer_position = new Point( (int) motion_event.getX(), (int) motion_event.getY() ) ; int pointer_movement_x = new_pointer_position.x - previous_pointer_position.x ; int pointer_movement_y = new_pointer_position.y - previous_pointer_position.y ; previous_pointer_position = new_pointer_position ; ball_being_moved.move_this_ball( pointer_movement_x, pointer_movement_y ) ; } } else if ( motion_event.getAction() == MotionEvent.ACTION_UP ) { if ( ball_being_moved != null ) { ball_being_moved.deactivate_ball() ; ball_being_moved = null ; } } invalidate() ; return true ; } @Override protected void onDraw( Canvas canvas ) { first_ball.draw( canvas ) ; second_ball.draw( canvas ) ; third_ball.draw( canvas ) ; } } public class MovingBallsWithPointerActivity extends Activity { /** Called when the activity is first created. */ @Override public void onCreate( Bundle savedInstanceState ) { super.onCreate( savedInstanceState ) ; setContentView( new MovingBallsWithPointerView( this ) ) ; } }