Skip to content

Commit 45f3c6c

Browse files
committed
Initial commit
1 parent 77304e4 commit 45f3c6c

File tree

6 files changed

+220
-4
lines changed

6 files changed

+220
-4
lines changed

app/src/main/java/tech/torque/popper/MainActivity.java

Lines changed: 70 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import android.view.View;
88
import android.view.ViewGroup;
99
import android.view.ViewTreeObserver;
10+
import android.widget.Button;
1011
import android.widget.ImageView;
1112
import android.widget.TextView;
1213
import android.widget.Toast;
@@ -16,13 +17,18 @@
1617
import java.util.List;
1718
import java.util.Random;
1819

20+
import tech.torque.popper.utils.HighScoreHelper;
21+
import tech.torque.popper.utils.SimpleAlertDialog;
22+
import tech.torque.popper.utils.SoundHelper;
23+
1924
public class MainActivity extends AppCompatActivity implements Balloon.BalloonListener {
2025

2126
public static final int MIN_ANIMATION_DELAY = 500;
2227
public static final int MAX_ANIMATION_DELAY = 1500;
2328
public static final int MIN_ANIMATION_DURATION = 1000;
2429
public static final int MAX_ANIMATION_DURATION = 8000;
2530
public static final int NUMBER_OF_PINS = 5;
31+
private static final int BALLOONS_PER_LEVEL = 10;
2632

2733
private ViewGroup mContentView;
2834
private int[] mBalloonColors = new int[3];
@@ -32,6 +38,10 @@ public class MainActivity extends AppCompatActivity implements Balloon.BalloonLi
3238
TextView mScoreDisplay, mLevelDisplay;
3339
private List<ImageView> mPinImages = new ArrayList<>();
3440
private List<Balloon> mBalloons = new ArrayList<>();
41+
private Button mGoButton;
42+
private boolean mPlaying, mGameStopped = true;
43+
private int mBalloonsPopped;
44+
private SoundHelper mSoundHelper;
3545

3646

3747
@Override
@@ -65,25 +75,64 @@ public void onGlobalLayout() {
6575
mPinImages.add((ImageView) findViewById(R.id.pushpin4));
6676
mPinImages.add((ImageView) findViewById(R.id.pushpin5));
6777

78+
mGoButton = (Button) findViewById(R.id.go_button);
79+
80+
6881
mScoreDisplay = (TextView) findViewById(R.id.score_display);
6982
mLevelDisplay = (TextView) findViewById(R.id.level_display);
7083

7184
updateDisplay();
85+
86+
mSoundHelper = new SoundHelper(this);
87+
mSoundHelper.prepareMusicPlayer(this);
88+
}
89+
90+
private void startGame() {
91+
mScore = 0;
92+
mLevel = 0;
93+
mPinsUsed = 0;
94+
for (ImageView pin: mPinImages
95+
) {
96+
pin.setImageResource(R.drawable.pin);
97+
98+
}
99+
mGameStopped = false;
100+
startLevel();
101+
mSoundHelper.playMusic();
72102
}
73103

74104
private void startLevel() {
75105
mLevel++;
76106
updateDisplay();
77107
BalloonLauncher launcher = new BalloonLauncher();
78108
launcher.execute(mLevel);
109+
mPlaying = true;
110+
mBalloonsPopped = 0;
111+
mGoButton.setText("Stop game");
112+
}
113+
114+
private void finishLevel() {
115+
Toast.makeText(this, String.format("You finished level %d", mLevel), Toast.LENGTH_SHORT).show();
116+
mPlaying = false;
117+
mGoButton.setText(String.format("Start level %d", mLevel + 1));
79118
}
80119

81120
public void goButtonClickHandler(View view) {
82-
startLevel();
121+
if(mPlaying) {
122+
gameOver(false);
123+
} else if(mGameStopped) {
124+
startGame();
125+
} else {
126+
startLevel();
127+
}
83128
}
84129

85130
@Override
86131
public void popBalloon(Balloon balloon, boolean userTouch) {
132+
133+
mBalloonsPopped++;
134+
mSoundHelper.playSound();
135+
87136
mContentView.removeView(balloon);
88137
mBalloons.remove(balloon);
89138

@@ -103,18 +152,36 @@ public void popBalloon(Balloon balloon, boolean userTouch) {
103152
Toast.makeText(this, "Missed that one!", Toast.LENGTH_SHORT).show();
104153
}
105154
}
155+
156+
if(mBalloonsPopped == BALLOONS_PER_LEVEL) {
157+
finishLevel();
158+
}
159+
106160
updateDisplay();
107161
}
108162

109-
private void gameOver(boolean b) {
163+
private void gameOver(boolean allPinsUsed) {
110164
Toast.makeText(this, "Game Over!", Toast.LENGTH_SHORT).show();
165+
mSoundHelper.pauseMusic();
166+
111167
for (Balloon balloon: mBalloons
112168
) {
113169
mContentView.removeView(balloon);
114170
balloon.setPopped(true);
115171

116172
}
117173
mBalloons.clear();
174+
mPlaying = false;
175+
mGameStopped = true;
176+
mGoButton.setText("Start game");
177+
178+
if(allPinsUsed) {
179+
if(HighScoreHelper.isTopScore(this, mScore)) {
180+
HighScoreHelper.setTopScore(this, mScore);
181+
SimpleAlertDialog dialog = SimpleAlertDialog.newInstance("New High Score!", String.format("Your new high score is %d", mScore));
182+
dialog.show(getSupportFragmentManager(), null);
183+
}
184+
}
118185
}
119186

120187
private void updateDisplay() {
@@ -138,7 +205,7 @@ protected Void doInBackground(Integer... params) {
138205
int minDelay = maxDelay / 2;
139206

140207
int balloonsLaunched = 0;
141-
while (balloonsLaunched < 3) {
208+
while (mPlaying && balloonsLaunched < BALLOONS_PER_LEVEL) {
142209

143210
// Get a random horizontal position for the next balloon
144211
Random random = new Random(new Date().getTime());
Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,32 @@
11
package tech.torque.popper.utils;
22

3+
import android.content.Context;
4+
import android.content.SharedPreferences;
35

46
public class HighScoreHelper {
57

6-
}
8+
private static final String PREFS_GLOBAL = "prefs_global";
9+
private static final String PREF_TOP_SCORE = "pref_top_score";
10+
11+
private static SharedPreferences getPreferences(Context context) {
12+
return context.getSharedPreferences(
13+
PREFS_GLOBAL, Context.MODE_PRIVATE);
14+
}
15+
16+
// Setters and getters for global preferences
17+
public static boolean isTopScore(Context context, int newScore) {
18+
int topScore = getPreferences(context).getInt(PREF_TOP_SCORE, 0);
19+
return newScore > topScore;
20+
}
21+
22+
public static int getTopScore(Context context) {
23+
return getPreferences(context).getInt(PREF_TOP_SCORE, 0);
24+
}
25+
26+
public static void setTopScore(Context context, int score) {
27+
SharedPreferences.Editor editor = getPreferences(context).edit();
28+
editor.putInt(PREF_TOP_SCORE, score);
29+
editor.apply();
30+
}
31+
32+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package tech.torque.popper.utils;
2+
3+
import android.app.Dialog;
4+
import android.os.Bundle;
5+
import android.support.annotation.NonNull;
6+
import android.support.v4.app.DialogFragment;
7+
import android.support.v7.app.AlertDialog;
8+
9+
public class SimpleAlertDialog extends DialogFragment {
10+
11+
private static final String TITLE_KEY = "title_key";
12+
private static final String MESSAGE_KEY = "message_key";
13+
14+
public SimpleAlertDialog() {
15+
}
16+
17+
public static SimpleAlertDialog newInstance(String title, String message) {
18+
19+
Bundle args = new Bundle();
20+
args.putString(TITLE_KEY, title);
21+
args.putString(MESSAGE_KEY, message);
22+
23+
SimpleAlertDialog fragment = new SimpleAlertDialog();
24+
fragment.setArguments(args);
25+
return fragment;
26+
}
27+
28+
@NonNull
29+
@Override
30+
public Dialog onCreateDialog(Bundle savedInstanceState) {
31+
32+
Bundle args = getArguments();
33+
if (args == null) throw new AssertionError();
34+
35+
String title = args.getString(TITLE_KEY);
36+
String prompt = args.getString(MESSAGE_KEY);
37+
38+
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity())
39+
.setTitle(title)
40+
.setMessage(prompt)
41+
.setCancelable(false);
42+
43+
builder.setPositiveButton(android.R.string.ok, null);
44+
return builder.create();
45+
46+
}
47+
48+
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package tech.torque.popper.utils;
2+
3+
4+
import android.app.Activity;
5+
import android.content.Context;
6+
import android.media.AudioAttributes;
7+
import android.media.AudioManager;
8+
import android.media.MediaPlayer;
9+
import android.media.SoundPool;
10+
import android.view.View;
11+
12+
import tech.torque.popper.R;
13+
14+
public class SoundHelper {
15+
16+
private MediaPlayer mMusicPlayer;
17+
18+
private SoundPool mSoundPool;
19+
private int mSoundID;
20+
private boolean mLoaded;
21+
private float mVolume;
22+
23+
public SoundHelper(Activity activity) {
24+
25+
AudioManager audioManager = (AudioManager) activity.getSystemService(Context.AUDIO_SERVICE);
26+
float actVolume = (float) audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
27+
float maxVolume = (float) audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
28+
mVolume = actVolume / maxVolume;
29+
30+
activity.setVolumeControlStream(AudioManager.STREAM_MUSIC);
31+
32+
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
33+
AudioAttributes audioAttrib = new AudioAttributes.Builder()
34+
.setUsage(AudioAttributes.USAGE_GAME)
35+
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
36+
.build();
37+
mSoundPool = new SoundPool.Builder().setAudioAttributes(audioAttrib).setMaxStreams(6).build();
38+
} else {
39+
//noinspection deprecation
40+
mSoundPool = new SoundPool(6, AudioManager.STREAM_MUSIC, 0);
41+
}
42+
43+
mSoundPool.setOnLoadCompleteListener(new SoundPool.OnLoadCompleteListener() {
44+
@Override
45+
public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {
46+
mLoaded = true;
47+
}
48+
});
49+
mSoundID = mSoundPool.load(activity, R.raw.balloon_pop, 1);
50+
}
51+
52+
public void playSound() {
53+
if (mLoaded) {
54+
mSoundPool.play(mSoundID, mVolume, mVolume, 1, 0, 1f);
55+
}
56+
}
57+
58+
public void prepareMusicPlayer(Context context) {
59+
mMusicPlayer = MediaPlayer.create(context.getApplicationContext(), R.raw.pleasant_music);
60+
mMusicPlayer.setVolume(.5f, .5f);
61+
mMusicPlayer.setLooping(true);
62+
}
63+
64+
public void playMusic() {
65+
if(mMusicPlayer != null) {
66+
mMusicPlayer.start();
67+
}
68+
}
69+
70+
public void pauseMusic() {
71+
if(mMusicPlayer != null && mMusicPlayer.isPlaying()) {
72+
mMusicPlayer.pause();
73+
}
74+
}
75+
}

app/src/main/res/raw/balloon_pop.wav

54.6 KB
Binary file not shown.
5.07 MB
Binary file not shown.

0 commit comments

Comments
 (0)