Advertisement
tafazzi87

Untitled

Mar 4th, 2014
1,183
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 12.11 KB | None | 0 0
  1. package course.labs.GraphicsLab;
  2.  
  3. import java.util.Random;
  4. import java.util.concurrent.Executors;
  5. import java.util.concurrent.ScheduledExecutorService;
  6. import java.util.concurrent.ScheduledFuture;
  7. import java.util.concurrent.TimeUnit;
  8.  
  9. import android.app.Activity;
  10. import android.content.Context;
  11. import android.graphics.Bitmap;
  12. import android.graphics.BitmapFactory;
  13. import android.graphics.Canvas;
  14. import android.graphics.Paint;
  15. import android.media.AudioManager;
  16. import android.media.SoundPool;
  17. import android.media.SoundPool.OnLoadCompleteListener;
  18. import android.os.Bundle;
  19. import android.util.Log;
  20. import android.view.GestureDetector;
  21. import android.view.Menu;
  22. import android.view.MenuItem;
  23. import android.view.MotionEvent;
  24. import android.view.View;
  25. import android.widget.RelativeLayout;
  26.  
  27. public class BubbleActivity extends Activity {
  28.  
  29.     // These variables are for testing purposes, do not modify
  30.     private final static int RANDOM = 0;
  31.     private final static int SINGLE = 1;
  32.     private final static int STILL = 2;
  33.     private static int speedMode = RANDOM;
  34.  
  35.     private static final int MENU_STILL = Menu.FIRST;
  36.     private static final int MENU_SINGLE_SPEED = Menu.FIRST + 1;
  37.     private static final int MENU_RANDOM_SPEED = Menu.FIRST + 2;
  38.  
  39.     private static final String TAG = "Lab-Graphics";
  40.  
  41.     // Main view
  42.     private RelativeLayout mFrame;
  43.  
  44.     // Bubble image
  45.     private Bitmap mBitmap;
  46.  
  47.     // Display dimensions
  48.     private int mDisplayWidth, mDisplayHeight;
  49.  
  50.     // Sound variables
  51.  
  52.     // AudioManager
  53.     private AudioManager mAudioManager;
  54.     // SoundPool
  55.     private SoundPool mSoundPool;
  56.     // ID for the bubble popping sound
  57.     private int mSoundID;
  58.     // Audio volume
  59.     private float mStreamVolume;
  60.  
  61.     // Gesture Detector
  62.     private GestureDetector mGestureDetector;
  63.  
  64.     @Override
  65.     public void onCreate(Bundle savedInstanceState) {
  66.         super.onCreate(savedInstanceState);
  67.  
  68.         setContentView(R.layout.main);
  69.  
  70.         // Set up user interface
  71.         mFrame = (RelativeLayout) findViewById(R.id.frame);
  72.  
  73.         // Load basic bubble Bitmap
  74.         mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.b64);
  75.  
  76.     }
  77.  
  78.     @Override
  79.     protected void onResume() {
  80.         super.onResume();
  81.  
  82.         // Manage bubble popping sound
  83.         // Use AudioManager.STREAM_MUSIC as stream type
  84.  
  85.         mAudioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
  86.  
  87.         mStreamVolume = (float) mAudioManager
  88.                 .getStreamVolume(AudioManager.STREAM_MUSIC)
  89.                 / mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
  90.  
  91.         // TODO - make a new SoundPool, allowing up to 10 streams
  92.         mSoundPool = new SoundPool(10, AudioManager.STREAM_MUSIC, 0);
  93.  
  94.         // TODO - set a SoundPool OnLoadCompletedListener that calls setupGestureDetector()
  95.         mSoundPool.setOnLoadCompleteListener(new OnLoadCompleteListener() {
  96.            
  97.             @Override
  98.             public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {
  99.                 // TODO Auto-generated method stub
  100.                 setupGestureDetector();
  101.             }
  102.         });
  103.        
  104.         // TODO - load the sound from res/raw/bubble_pop.wav
  105.         mSoundID = mSoundPool.load(this, R.raw.bubble_pop, 1);
  106.     }
  107.  
  108.     @Override
  109.     public void onWindowFocusChanged(boolean hasFocus) {
  110.         super.onWindowFocusChanged(hasFocus);
  111.         if (hasFocus) {
  112.  
  113.             // Get the size of the display so this view knows where borders are
  114.             mDisplayWidth = mFrame.getWidth();
  115.             mDisplayHeight = mFrame.getHeight();
  116.  
  117.         }
  118.     }
  119.  
  120.     // Set up GestureDetector
  121.     private void setupGestureDetector() {
  122.  
  123.         mGestureDetector = new GestureDetector(this,
  124.  
  125.         new GestureDetector.SimpleOnGestureListener() {
  126.  
  127.             // If a fling gesture starts on a BubbleView then change the
  128.             // BubbleView's velocity
  129.  
  130.             @Override
  131.             public boolean onFling(MotionEvent event1, MotionEvent event2,
  132.                     float velocityX, float velocityY) {
  133.  
  134.                 // TODO - Implement onFling actions.
  135.                 // You can get all Views in mFrame using the
  136.                 // ViewGroup.getChildCount() method
  137.                 for(int i=0;i<mFrame.getChildCount();i++){
  138.                     BubbleView bubble= (BubbleView) mFrame.getChildAt(i);
  139.                     if (bubble.intersects(event1.getX(),event1.getY())){
  140.                         bubble.deflect(velocityX, velocityY);
  141.                         return true;
  142.                        }
  143.                     }
  144.                 return false;
  145.                
  146.             }
  147.  
  148.             // If a single tap intersects a BubbleView, then pop the BubbleView
  149.             // Otherwise, create a new BubbleView at the tap's location and add
  150.             // it to mFrame. You can get all views from mFrame with ViewGroup.getChildAt()
  151.  
  152.             @Override
  153.             public boolean onSingleTapConfirmed(MotionEvent event) {
  154.  
  155.                 // TODO - Implement onSingleTapConfirmed actions.
  156.                 // You can get all Views in mFrame using the
  157.                 // ViewGroup.getChildCount() method
  158.                 for(int i=0;i<mFrame.getChildCount();i++)
  159.                 {
  160.                         BubbleView bubbleView= (BubbleView) mFrame.getChildAt(i);
  161.                         if (((BubbleView)mFrame.getChildAt(i)).intersects(event.getRawX(),event.getRawY()))
  162.                                 {
  163.                                     bubbleView.stop(true);
  164.                                     return true;
  165.                                 }
  166.                             }
  167.                     BubbleView bubble=new BubbleView(mFrame.getContext(),event.getX(),event.getY());
  168.                     mFrame.addView(bubble);
  169.                     bubble.start();
  170.                     return false;
  171.             }
  172.         });
  173.     }
  174.  
  175.     @Override
  176.     public boolean onTouchEvent(MotionEvent event) {
  177.  
  178.         // TODO - delegate the touch to the gestureDetector
  179.         return mGestureDetector.onTouchEvent(event);
  180.    
  181.     }
  182.  
  183.     @Override
  184.     protected void onPause() {
  185.        
  186.         // TODO - Release all SoundPool resources
  187.        
  188.         mSoundPool.unload(mSoundID);
  189.         mSoundPool.release();
  190.         super.onPause();
  191.     }
  192.  
  193.     // BubbleView is a View that displays a bubble.
  194.     // This class handles animating, drawing, popping amongst other actions.
  195.     // A new BubbleView is created for each bubble on the display
  196.  
  197.     private class BubbleView extends View {
  198.  
  199.         private static final int BITMAP_SIZE = 64;
  200.         private static final int REFRESH_RATE = 40;
  201.         private final Paint mPainter = new Paint();
  202.         private ScheduledFuture<?> mMoverFuture;
  203.         private int mScaledBitmapWidth;
  204.         private Bitmap mScaledBitmap;
  205.  
  206.         // location, speed and direction of the bubble
  207.         private float mXPos, mYPos, mDx, mDy;
  208.         private long mRotate, mDRotate;
  209.  
  210.         public BubbleView(Context context, float x, float y) {
  211.             super(context);
  212.             log("Creating Bubble at: x:" + x + " y:" + y);
  213.  
  214.             // Create a new random number generator to
  215.             // randomize size, rotation, speed and direction
  216.             Random r = new Random();
  217.  
  218.             // Creates the bubble bitmap for this BubbleView
  219.             createScaledBitmap(r);
  220.  
  221.             // Adjust position to center the bubble under user's finger
  222.             mXPos = x - mScaledBitmapWidth / 2;
  223.             mYPos = y - mScaledBitmapWidth / 2;
  224.  
  225.             // Set the BubbleView's speed and direction
  226.             setSpeedAndDirection(r);
  227.            
  228.             // Set the BubbleView's rotation
  229.             setRotation(r);
  230.  
  231.             mPainter.setAntiAlias(true);
  232.  
  233.         }
  234.  
  235.         private void setRotation(Random r) {
  236.  
  237.             if (speedMode == RANDOM) {
  238.                
  239.                 // TODO - set rotation in range [1..3]
  240.                 mDRotate = r.nextInt(3)+1;
  241.  
  242.                
  243.             } else {
  244.            
  245.                 mDRotate = 0;
  246.            
  247.             }
  248.         }
  249.  
  250.         private void setSpeedAndDirection(Random r) {
  251.  
  252.             // Used by test cases
  253.             switch (speedMode) {
  254.  
  255.             case SINGLE:
  256.  
  257.                 // Fixed speed
  258.                 mDx = 10;
  259.                 mDy = 10;
  260.                 break;
  261.  
  262.             case STILL:
  263.  
  264.                 // No speed
  265.                 mDx = 0;
  266.                 mDy = 0;
  267.                 break;
  268.  
  269.             default:
  270.  
  271.                 // TODO - Set movement direction and speed
  272.                 // Limit movement speed in the x and y
  273.                 // direction to [-3..3].
  274.                 mDx=r.nextInt(7)+1;
  275.                 mDy=r.nextInt(7)+1;
  276.                 break;
  277.             }
  278.         }
  279.  
  280.         private void createScaledBitmap(Random r) {
  281.  
  282.             if (speedMode != RANDOM) {
  283.  
  284.                 mScaledBitmapWidth = BITMAP_SIZE * 3;
  285.            
  286.             } else {
  287.            
  288.                 //TODO - set scaled bitmap size in range [1..3] * BITMAP_SIZE
  289.                 mScaledBitmapWidth = (r.nextInt(3)+1)*BITMAP_SIZE;
  290.            
  291.             }
  292.  
  293.             // TODO - create the scaled bitmap using size set above
  294.             mScaledBitmap = Bitmap.createScaledBitmap(mBitmap, mScaledBitmapWidth, mScaledBitmapWidth, false);
  295.         }
  296.  
  297.         // Start moving the BubbleView & updating the display
  298.         private void start() {
  299.  
  300.             // Creates a WorkerThread
  301.             ScheduledExecutorService executor = Executors
  302.                     .newScheduledThreadPool(1);
  303.  
  304.             // Execute the run() in Worker Thread every REFRESH_RATE
  305.             // milliseconds
  306.             // Save reference to this job in mMoverFuture
  307.             mMoverFuture = executor.scheduleWithFixedDelay(new Runnable() {
  308.                 @Override
  309.                 public void run() {
  310.                     // TODO - implement movement logic.
  311.                     // Each time this method is run the BubbleView should
  312.                     // move one step. If the BubbleView exits the display,
  313.                     // stop the BubbleView's Worker Thread.
  314.                     // Otherwise, request that the BubbleView be redrawn.
  315.                     if(BubbleView.this.moveWhileOnScreen()){
  316.                          BubbleView.this.stop(true);
  317.                        }else{
  318.                            BubbleView.this.postInvalidate();
  319.                        }   
  320.                 }
  321.             }, 0, REFRESH_RATE, TimeUnit.MILLISECONDS);
  322.         }
  323.  
  324.         private synchronized boolean intersects(float x, float y) {
  325.  
  326.             // TODO - Return true if the BubbleView intersects position (x,y)
  327.             if((x>mXPos && x<mXPos + mScaledBitmapWidth) && (y>mYPos && y<mYPos + mScaledBitmapWidth)){
  328.                 return true;
  329.                 }
  330.             return false;
  331.         }
  332.  
  333.         // Cancel the Bubble's movement
  334.         // Remove Bubble from mFrame
  335.         // Play pop sound if the BubbleView was popped
  336.        
  337.         private void stop(final boolean popped) {
  338.  
  339.             if (null != mMoverFuture && mMoverFuture.cancel(true)) {
  340.  
  341.                 // This work will be performed on the UI Thread
  342.                
  343.                 mFrame.post(new Runnable() {
  344.                     @Override
  345.                     public void run() {
  346.                        
  347.                         // TODO - Remove the BubbleView from mFrame
  348.                         mFrame.removeView(BubbleView.this);
  349.  
  350.                        
  351.                        
  352.                         if (popped) {
  353.                             log("Pop!");
  354.  
  355.                             // TODO - If the bubble was popped by user,
  356.                             // play the popping sound
  357.                             mSoundPool.play(mSoundID, mStreamVolume, mStreamVolume, 1, 0, 1f);
  358.  
  359.                        
  360.                         }
  361.  
  362.                         log("Bubble removed from view!");
  363.                    
  364.                     }
  365.                 });
  366.             }
  367.         }
  368.  
  369.         // Change the Bubble's speed and direction
  370.         private synchronized void deflect(float velocityX, float velocityY) {
  371.             log("velocity X:" + velocityX + " velocity Y:" + velocityY);
  372.  
  373.             //TODO - set mDx and mDy to be the new velocities divided by the REFRESH_RATE
  374.            
  375.             mDx = velocityX/REFRESH_RATE;
  376.             mDy = velocityY/REFRESH_RATE;
  377.  
  378.         }
  379.  
  380.         // Draw the Bubble at its current location
  381.         @Override
  382.         protected synchronized void onDraw(Canvas canvas) {
  383.  
  384.             // TODO - save the canvas
  385.             canvas.save();
  386.  
  387.             // TODO - increase the rotation of the original image by mDRotate
  388.             mRotate=mRotate+mDRotate;
  389.  
  390.            
  391.             // TODO Rotate the canvas by current rotation
  392.             canvas.rotate(mRotate, mXPos + mScaledBitmapWidth/2, mYPos + mScaledBitmapWidth/2);
  393.            
  394.            
  395.             // TODO - draw the bitmap at it's new location
  396.             canvas.drawBitmap(mScaledBitmap, mDx, mDy, mPainter);
  397.  
  398.            
  399.             // TODO - restore the canvas
  400.             canvas.restore();
  401.  
  402.            
  403.         }
  404.  
  405.  
  406.         private synchronized boolean moveWhileOnScreen() {
  407.  
  408.             // TODO - Move the BubbleView
  409.             // Returns true if the BubbleView has exited the screen
  410.             if (isOutOfView()==true) {
  411.                 mXPos = mXPos+mDx;
  412.                 mYPos = mYPos+mDy;
  413.                 return true;
  414.             } else {
  415.                 return false;
  416.             }
  417.  
  418.  
  419.         }
  420.  
  421.         private boolean isOutOfView() {
  422.  
  423.             // TODO - Return true if the BubbleView has exited the screen
  424.             if (mXPos < 0 || mXPos + mScaledBitmapWidth > mDisplayWidth || mYPos < 0 || mYPos + mScaledBitmapWidth > mDisplayHeight){
  425.                 return true;
  426.             } else {
  427.                 return false;
  428.             }
  429.  
  430.         }
  431.     }
  432.  
  433.     // Do not modify below here
  434.     @Override
  435.     public boolean onCreateOptionsMenu(Menu menu) {
  436.         super.onCreateOptionsMenu(menu);
  437.  
  438.         menu.add(Menu.NONE, MENU_STILL, Menu.NONE, "Still Mode");
  439.         menu.add(Menu.NONE, MENU_SINGLE_SPEED, Menu.NONE, "Single Speed Mode");
  440.         menu.add(Menu.NONE, MENU_RANDOM_SPEED, Menu.NONE, "Random Speed Mode");
  441.  
  442.         return true;
  443.     }
  444.  
  445.     @Override
  446.     public boolean onOptionsItemSelected(MenuItem item) {
  447.         switch (item.getItemId()) {
  448.         case MENU_STILL:
  449.             speedMode = STILL;
  450.             return true;
  451.         case MENU_SINGLE_SPEED:
  452.             speedMode = SINGLE;
  453.             return true;
  454.         case MENU_RANDOM_SPEED:
  455.             speedMode = RANDOM;
  456.             return true;
  457.  
  458.         default:
  459.             return super.onOptionsItemSelected(item);
  460.         }
  461.     }
  462.    
  463.     private static void log (String message) {
  464.         try {
  465.             Thread.sleep(500);
  466.         } catch (InterruptedException e) {
  467.             e.printStackTrace();
  468.         }
  469.         Log.i(TAG,message);
  470.     }
  471. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement