From 73a946cebcb55619758fd9c0dddb31ff63c8498b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Zurcher?= Date: Sun, 16 Mar 2014 18:16:39 +0100 Subject: Android : 07-Graphics: implement --- .../course/labs/GraphicsLab/BubbleActivity.java | 117 +++++++++++++-------- 1 file changed, 75 insertions(+), 42 deletions(-) diff --git a/Android/07-Graphics/GraphicsLab/src/course/labs/GraphicsLab/BubbleActivity.java b/Android/07-Graphics/GraphicsLab/src/course/labs/GraphicsLab/BubbleActivity.java index fed77d7..e93eba3 100644 --- a/Android/07-Graphics/GraphicsLab/src/course/labs/GraphicsLab/BubbleActivity.java +++ b/Android/07-Graphics/GraphicsLab/src/course/labs/GraphicsLab/BubbleActivity.java @@ -14,6 +14,7 @@ import android.graphics.Canvas; import android.graphics.Paint; import android.media.AudioManager; import android.media.SoundPool; +import android.media.SoundPool.OnLoadCompleteListener; import android.os.Bundle; import android.util.Log; import android.view.GestureDetector; @@ -83,12 +84,20 @@ public class BubbleActivity extends Activity { mStreamVolume = (float) mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC) / mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC); - // TODO - make a new SoundPool, allowing up to 10 streams - mSoundPool = null; + mSoundPool = new SoundPool(10, AudioManager.STREAM_MUSIC, 0); - // TODO - set a SoundPool OnLoadCompletedListener that calls setupGestureDetector() - // TODO - load the sound from res/raw/bubble_pop.wav - mSoundID = 0; + mSoundPool.setOnLoadCompleteListener(new OnLoadCompleteListener() { + @Override + public void onLoadComplete(SoundPool soundPool, int sampleId, int status) { + if (0 == status) { + setupGestureDetector(); + } + } + }); + + mSoundID = mSoundPool.load(this, R.raw.bubble_pop, 1); + mAudioManager.setSpeakerphoneOn(true); + mAudioManager.loadSoundEffects(); } @Override @@ -125,23 +134,44 @@ public class BubbleActivity extends Activity { // it to mFrame. You can get all views from mFrame with ViewGroup.getChildAt() @Override public boolean onSingleTapConfirmed(MotionEvent event) { - // TODO - Implement onSingleTapConfirmed actions. - // You can get all Views in mFrame using the - // ViewGroup.getChildCount() method - return false; + int pointerIndex = event.getActionIndex(); + int pointerID = event.getPointerId(pointerIndex); + + float x = event.getX(pointerID); + float y = event.getY(pointerID); + + int numberChilds = mFrame.getChildCount(); + for (int i = 0; i < numberChilds; i++) { + final BubbleView bubble = (BubbleView) mFrame.getChildAt(i); + + if (bubble.intersects(x, y)) { + bubble.stop(true); + return true; + } + } + + BubbleView child = new BubbleView(getApplicationContext(), x, y); + mFrame.addView(child); + child.start(); + return true; } }); } @Override public boolean onTouchEvent(MotionEvent event) { - // TODO - delegate the touch to the gestureDetector - return false; + return mGestureDetector.onTouchEvent(event); } @Override protected void onPause() { - // TODO - Release all SoundPool resources + if (mSoundPool != null) { + mSoundPool.unload(mSoundID); + mSoundPool.release(); + mSoundPool = null; + } + mAudioManager.setSpeakerphoneOn(false); + mAudioManager.unloadSoundEffects(); super.onPause(); } @@ -187,8 +217,7 @@ public class BubbleActivity extends Activity { private void setRotation(Random r) { if (speedMode == RANDOM) { - // TODO - set rotation in range [1..3] - mDRotate = 0; + mDRotate = (r.nextInt(3) + 1); } else { mDRotate = 0; } @@ -209,9 +238,8 @@ public class BubbleActivity extends Activity { mDy = 0; break; default: - // TODO - Set movement direction and speed - // Limit movement speed in the x and y - // direction to [-3..3]. + mDx = r.nextInt(7) - 3; + mDy = r.nextInt(7) - 3; } } @@ -219,11 +247,9 @@ public class BubbleActivity extends Activity { if (speedMode != RANDOM) { mScaledBitmapWidth = BITMAP_SIZE * 3; } else { - //TODO - set scaled bitmap size in range [1..3] * BITMAP_SIZE - mScaledBitmapWidth = 0; + mScaledBitmapWidth = (r.nextInt(3) + 1) * BITMAP_SIZE; } - // TODO - create the scaled bitmap using size set above - mScaledBitmap = null; + mScaledBitmap = Bitmap.createScaledBitmap(mBitmap, mScaledBitmapWidth, mScaledBitmapWidth, false); } // Start moving the BubbleView & updating the display @@ -238,17 +264,22 @@ public class BubbleActivity extends Activity { mMoverFuture = executor.scheduleWithFixedDelay(new Runnable() { @Override public void run() { - // TODO - implement movement logic. - // Each time this method is run the BubbleView should - // move one step. If the BubbleView exits the display, - // stop the BubbleView's Worker Thread. - // Otherwise, request that the BubbleView be redrawn. + boolean outOfView = moveWhileOnScreen(); + if (outOfView) { + stop(false); + } else { + postInvalidate(); + } } }, 0, REFRESH_RATE, TimeUnit.MILLISECONDS); } private synchronized boolean intersects(float x, float y) { - // TODO - Return true if the BubbleView intersects position (x,y) + if (mXPos <= x && x <= mXPos + mScaledBitmapWidth) { + if (mYPos <= y && y <= mYPos + mScaledBitmapWidth) { + return true; + } + } return false; } @@ -261,11 +292,10 @@ public class BubbleActivity extends Activity { mFrame.post(new Runnable() { @Override public void run() { - // TODO - Remove the BubbleView from mFrame + mFrame.removeView(BubbleView.this); if (popped) { log("Pop!"); - // TODO - If the bubble was popped by user, - // play the popping sound + mSoundPool.play(mSoundID, mStreamVolume, mStreamVolume, 1, 0, 1f); } log("Bubble removed from view!"); } @@ -276,31 +306,34 @@ public class BubbleActivity extends Activity { // Change the Bubble's speed and direction private synchronized void deflect(float velocityX, float velocityY) { log("velocity X:" + velocityX + " velocity Y:" + velocityY); - //TODO - set mDx and mDy to be the new velocities divided by the REFRESH_RATE - mDx = 0; - mDy = 0; + mDx = velocityX / (REFRESH_RATE * 10); + mDy = velocityY / (REFRESH_RATE * 10); } // Draw the Bubble at its current location @Override protected synchronized void onDraw(Canvas canvas) { - // TODO - save the canvas - // TODO - increase the rotation of the original image by mDRotate - // TODO Rotate the canvas by current rotation - // TODO - draw the bitmap at it's new location - // TODO - restore the canvas + canvas.save(); + mRotate = mRotate + mDRotate; + canvas.rotate(mRotate, mXPos + mScaledBitmapWidth / 2, mYPos + mScaledBitmapWidth / 2); + canvas.drawBitmap(mScaledBitmap, this.mXPos, this.mYPos, null); + canvas.restore(); } private synchronized boolean moveWhileOnScreen() { - // TODO - Move the BubbleView - // Returns true if the BubbleView has exited the screen - return false; + this.mXPos = mXPos + mDx; + this.mYPos = mYPos + mDy; + return isOutOfView(); } private boolean isOutOfView() { - // TODO - Return true if the BubbleView has exited the screen + if (mXPos + mDisplayWidth < 0 || mYPos + mDisplayHeight < 0) + return true; + if (mXPos > mDisplayWidth || mYPos > mDisplayHeight) + return true; + return false; } } -- cgit v1.1-2-g2b99