Skip to content
Snippets Groups Projects
Commit 8864ee16 authored by Andrej Rasevic's avatar Andrej Rasevic
Browse files

added student-distribution Lab8GraphicsLab

parent c1d7b0b6
No related branches found
No related tags found
No related merge requests found
Showing
with 681 additions and 0 deletions
# built application files
*.apk
*.ap_
# files for the dex VM
*.dex
# Java class files
*.class
# generated files
bin/
gen/
# Local configuration file (sdk path, etc)
local.properties
# Eclipse project files
.classpath
.settings
# Proguard folder generated by Eclipse
proguard/
# Intellij project files
*.iml
*.ipr
*.iws
.idea
.idea/workspace.xml
.gradle
build/
captures/
# Mac files
.DS_Store
# Windows thumbnail db
Thumbs.db
File added
File added
apply plugin: 'com.android.application'
android {
compileSdkVersion 26
buildToolsVersion "26.0.1"
defaultConfig {
applicationId "course.labs.graphicslab"
minSdkVersion 21
targetSdkVersion 26
testApplicationId "course.labs.graphicslab.tests"
testInstrumentationRunner "android.test.InstrumentationTestRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
}
}
}
dependencies {
androidTestCompile 'com.jayway.android.robotium:robotium-solo:5.6.3'
}
package course.labs.graphicslab.tests;
import course.labs.graphicslab.BubbleActivity;
import com.robotium.solo.*;
import android.test.ActivityInstrumentationTestCase2;
public class BubbleActivityFloatOffScreen extends
ActivityInstrumentationTestCase2<BubbleActivity> {
private Solo solo;
public BubbleActivityFloatOffScreen() {
super(BubbleActivity.class);
}
public void setUp() throws Exception {
solo = new Solo(getInstrumentation(), getActivity());
}
@Override
public void tearDown() throws Exception {
solo.finishOpenedActivities();
}
public void testRun() {
int shortDelay = 250, delay = 2000;
// Wait for activity: 'course.labs.TouchLab.BubbleActivity'
solo.waitForActivity(course.labs.graphicslab.BubbleActivity.class,
delay);
// Click on action bar item
solo.clickOnMenuItem("Single Speed Mode");
// Click on action bar item
solo.clickOnMenuItem("Add a Bubble");
// Check whether bubble appears
boolean bubbleAppeared = solo.getCurrentViews(
course.labs.graphicslab.BubbleActivity.BubbleView.class).size() > 0;
for (int i = 0; i < 8 && !bubbleAppeared; i++) {
solo.sleep(shortDelay);
bubbleAppeared = solo.getCurrentViews(
course.labs.graphicslab.BubbleActivity.BubbleView.class)
.size() > 0;
}
// Assert that a bubble was displayed
assertTrue("Bubble hasn't appeared", bubbleAppeared);
solo.sleep(delay);
// Assert that the bubble has left the screen
assertEquals(
"Bubble hasn't left the screen",
0,
solo.getCurrentViews(
course.labs.graphicslab.BubbleActivity.BubbleView.class)
.size());
}
}
package course.labs.graphicslab.tests;
import course.labs.graphicslab.BubbleActivity;
import com.robotium.solo.*;
import android.test.ActivityInstrumentationTestCase2;
public class BubbleActivityMultiple extends
ActivityInstrumentationTestCase2<BubbleActivity> {
private Solo solo;
public BubbleActivityMultiple() {
super(BubbleActivity.class);
}
public void setUp() throws Exception {
solo = new Solo(getInstrumentation(), getActivity());
}
@Override
public void tearDown() throws Exception {
solo.finishOpenedActivities();
}
public void testRun() {
int delay = 2000;
// Wait for activity: 'course.labs.TouchLab.BubbleActivity'
solo.waitForActivity(course.labs.graphicslab.BubbleActivity.class, delay);
// Set Still Mode
solo.clickOnMenuItem("Still Mode");
// Click on action bar item
solo.clickOnMenuItem("Add a Bubble");
solo.sleep(delay);
// Assert that a bubble was displayed
assertEquals("Bubble hasn't appeared", 1, solo.getCurrentViews(course.labs.graphicslab.BubbleActivity.BubbleView.class).size());
// Click on action bar item
solo.clickOnMenuItem("Add a Bubble");
solo.sleep(delay);
// Assert that a bubble was displayed
assertEquals("Second bubble hasn't appeared", 2, solo.getCurrentViews(course.labs.graphicslab.BubbleActivity.BubbleView.class).size());
solo.sleep(delay);
// Give misbehaving bubbles a chance to move off screen
// Assert that there are two bubbles on the screen
assertEquals(
"There should be two bubbles on the screen",
2,
solo.getCurrentViews(
course.labs.graphicslab.BubbleActivity.BubbleView.class)
.size());
}
}
package course.labs.graphicslab.tests;
import course.labs.graphicslab.BubbleActivity;
import com.robotium.solo.*;
import android.test.ActivityInstrumentationTestCase2;
public class BubbleActivityPop extends
ActivityInstrumentationTestCase2<BubbleActivity> {
private Solo solo;
public BubbleActivityPop() {
super(BubbleActivity.class);
}
public void setUp() throws Exception {
solo = new Solo(getInstrumentation(), getActivity());
}
@Override
public void tearDown() throws Exception {
solo.finishOpenedActivities();
}
public void testRun() {
int delay = 2000;
// Wait for activity: 'course.labs.TouchLab.BubbleActivity'
solo.waitForActivity(course.labs.graphicslab.BubbleActivity.class,
delay);
// Set Still Mode
solo.clickOnMenuItem("Still Mode");
// Click on action bar item
solo.clickOnMenuItem("Add a Bubble");
solo.sleep(delay);
// Assert that a bubble was displayed
assertEquals(
"Bubble hasn't appeared",
1,
solo.getCurrentViews(
course.labs.graphicslab.BubbleActivity.BubbleView.class)
.size());
// Click on action bar item
solo.clickOnMenuItem("Delete a Bubble");
solo.sleep(delay);
// Assert that there are no more bubbles
assertEquals(
"The bubble was not popped",
0,
solo.getCurrentViews(
course.labs.graphicslab.BubbleActivity.BubbleView.class)
.size());
}
}
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="course.labs.graphicslab"
android:versionCode="1"
android:versionName="1.0" >
<application
android:allowBackup="false"
android:icon="@mipmap/icon"
android:label="@string/app_name" >
<activity
android:name=".BubbleActivity"
android:label="@string/app_name"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
\ No newline at end of file
package course.labs.graphicslab;
import java.util.Random;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
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;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.widget.RelativeLayout;
public class BubbleActivity extends Activity {
// These variables are for testing purposes, do not modify
private final static int RANDOM = 0;
private final static int SINGLE = 1;
private final static int STILL = 2;
private static int speedMode = RANDOM;
private static final String TAG = "Lab-Graphics";
// The Main view
private RelativeLayout mFrame;
// Bubble image's bitmap
private Bitmap mBitmap;
// Display dimensions
private int mDisplayWidth, mDisplayHeight;
// Sound variables
// AudioManager
private AudioManager mAudioManager;
// SoundPool
private SoundPool mSoundPool;
// ID for the bubble popping sound
private int mSoundID;
// Audio volume
private float mStreamVolume;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Set up user interface
mFrame = (RelativeLayout) findViewById(R.id.frame);
// Load basic bubble Bitmap
mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.b64);
}
@Override
protected void onResume() {
super.onResume();
// Manage bubble popping sound
// Use AudioManager.STREAM_MUSIC as stream type
mAudioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
mStreamVolume = (float) mAudioManager
.getStreamVolume(AudioManager.STREAM_MUSIC)
/ mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
// TODO - make a new SoundPool, allowing up to 10 streams
// TODO - load the sound from res/raw/bubble_pop.wav
}
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus) {
// Get the size of the display so this View knows where borders are
mDisplayWidth = mFrame.getWidth();
mDisplayHeight = mFrame.getHeight();
}
}
@Override
protected void onPause() {
// TODO - unload the sound resource and release the sound pool
//TODO - set the sound pool to null
super.onPause();
}
// BubbleView is a View that displays a bubble.
// This class handles animating, drawing, and popping amongst other actions.
// A new BubbleView is created for each bubble on the display
public class BubbleView extends View {
private static final int BITMAP_SIZE = 64;
private static final int REFRESH_RATE = 40;
private final Paint mPainter = new Paint();
private ScheduledFuture<?> mMoverFuture;
private int mScaledBitmapWidth;
private Bitmap mScaledBitmap;
// location, speed and direction of the bubble
private float mXPos, mYPos, mDx, mDy, mRadius, mRadiusSquared;
private long mRotate, mDRotate;
BubbleView(Context context, float x, float y) {
super(context);
Log.i(TAG, "Creating Bubble at: x:" + x + " y:" + y);
// Create a new random number generator to
// randomize size, rotation, speed and direction
Random r = new Random();
// Creates the bubble bitmap for this BubbleView
createScaledBitmap(r);
// Radius of the Bitmap
mRadius = mScaledBitmapWidth / 2;
mRadiusSquared = mRadius * mRadius;
// Adjust position to center the bubble under user's finger
mXPos = x - mRadius;
mYPos = y - mRadius;
// Set the BubbleView's speed and direction
setSpeedAndDirection(r);
// Set the BubbleView's rotation
setRotation(r);
mPainter.setAntiAlias(true);
}
private void setRotation(Random r) {
if (speedMode == RANDOM) {
// TODO - set rotation in range [1..3]
mDRotate = 0;
} else {
mDRotate = 0;
}
}
private void setSpeedAndDirection(Random r) {
// Used by test cases
switch (speedMode) {
case SINGLE:
mDx = 40;
mDy = 40;
break;
case STILL:
// No speed
mDx = 0;
mDy = 0;
break;
default:
// TODO - Set movement direction and speed
// Limit movement speed in the x and y
// direction to [-3..3] pixels per movement.
}
}
private void createScaledBitmap(Random r) {
if (speedMode != RANDOM) {
mScaledBitmapWidth = BITMAP_SIZE * 3;
} else {
// TODO - set scaled bitmap size in range [1..3] * BITMAP_SIZE
}
// TODO - create the scaled bitmap using size set above
}
// Start moving the BubbleView & updating the display
private void start() {
// Creates a WorkerThread
ScheduledExecutorService executor = Executors
.newScheduledThreadPool(1);
// Execute the run() in Worker Thread every REFRESH_RATE
// milliseconds
// Save reference to this job in mMoverFuture
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.
}
}, 0, REFRESH_RATE, TimeUnit.MILLISECONDS);
}
// Cancel the Bubble's movement
// Remove Bubble from mFrame
// Play pop sound if the BubbleView was popped
private void stop(final boolean wasPopped) {
if (null != mMoverFuture) {
if (!mMoverFuture.isDone()) {
mMoverFuture.cancel(true);
}
// This work will be performed on the UI Thread
mFrame.post(new Runnable() {
@Override
public void run() {
// TODO - Remove the BubbleView from mFrame
// TODO - If the bubble was popped by user,
// play the popping sound
Log.i(TAG, "Bubble removed from view!");
}
});
}
}
// 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
// Hint - Rotate around the bubble's center, not its position
// TODO - draw the bitmap at it's new location
// TODO - restore the canvas
}
// Returns true if the BubbleView is still on the screen after the move
// operation
private synchronized boolean moveWhileOnScreen() {
// TODO - Move the BubbleView
return isOutOfView();
}
// Return true if the BubbleView is still on the screen after the move
// operation
private boolean isOutOfView() {
// TODO - Return true if the BubbleView is still on the screen after
// the move operation
return false;
}
}
@Override
public void onBackPressed() {
openOptionsMenu();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
getMenuInflater().inflate(R.menu.menu, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// TODO- Handle addition and deletion of bubbles from options menu
// Added bubbles should be given random locations.
// The bubble to delete is the most recently added bubble
// that is still in the frame.
// Hint: You can get all Views in mFrame using the
// ViewGroup.getChildCount() method
switch (item.getItemId()) {
case R.id.menu_add_bubble:
return true;
case R.id.menu_delete_bubble:
return true;
case R.id.menu_still_mode:
speedMode = STILL;
return true;
case R.id.menu_single_speed:
speedMode = SINGLE;
return true;
case R.id.menu_random_mode:
speedMode = RANDOM;
return true;
case R.id.quit:
exitRequested();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
private void exitRequested() {
super.onBackPressed();
}
}
\ No newline at end of file
Lab8_GraphicsLab/app/src/main/res/drawable/b128.png

24.9 KiB

Lab8_GraphicsLab/app/src/main/res/drawable/b64.png

7.99 KiB

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#FF444444"
android:id="@+id/frame">
</RelativeLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:id="@+id/menu_add_bubble" android:title="@string/add_bubble_string"></item>
<item android:id="@+id/menu_delete_bubble" android:title="@string/delete_bubble_string"></item>
<item android:id="@+id/menu_still_mode" android:title="@string/still_mode_string"></item>
<item android:id="@+id/menu_single_speed" android:title="@string/single_speed_mode_string"></item>
<item android:id="@+id/menu_random_mode" android:title="@string/random_speed_mode_string"></item>
<item android:id="@+id/quit" android:title="@string/quit_string"></item>
</menu>
Lab8_GraphicsLab/app/src/main/res/mipmap-hdpi/icon.png

4.05 KiB

Lab8_GraphicsLab/app/src/main/res/mipmap-ldpi/icon.png

1.68 KiB

Lab8_GraphicsLab/app/src/main/res/mipmap-mdpi/icon.png

2.51 KiB

File added
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">GraphicsLab</string>
<string name="still_mode_string">Still Mode</string>
<string name="single_speed_mode_string">Single Speed Mode</string>
<string name="random_speed_mode_string">Random Speed Mode</string>
<string name="quit_string">Quit</string>
<string name="add_bubble_string">Add a Bubble</string>
<string name="delete_bubble_string">Delete a Bubble</string>
</resources>
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.3.3'
}
}
allprojects {
repositories {
jcenter()
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment