Added rudimentary "Bust" Animation
This commit is contained in:
@@ -33,6 +33,10 @@ android {
|
||||
}
|
||||
}
|
||||
|
||||
base {
|
||||
archivesName.set("OcheCompanion")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(libs.appcompat)
|
||||
implementation(libs.material)
|
||||
|
||||
@@ -123,6 +123,12 @@ public class GameActivity extends BaseActivity {
|
||||
*/
|
||||
private boolean mIsTurnOver = false;
|
||||
|
||||
/**
|
||||
* Flag indicating the current turn resulted in a bust.
|
||||
* Used to prevent UI from subtracting bust darts from the score display.
|
||||
*/
|
||||
private boolean mIsBustedTurn = false;
|
||||
|
||||
/**
|
||||
* Helper class to track dart hit details for statistics.
|
||||
*/
|
||||
@@ -183,6 +189,11 @@ public class GameActivity extends BaseActivity {
|
||||
* Visible when score ≤170 and route is available.
|
||||
*/
|
||||
private LinearLayout layoutCheckoutSuggestion;
|
||||
|
||||
/**
|
||||
* The Container for displaying the current score.
|
||||
*/
|
||||
private LinearLayout mScoreContainer;
|
||||
|
||||
/**
|
||||
* Button for selecting single (1×) multiplier.
|
||||
@@ -199,6 +210,16 @@ public class GameActivity extends BaseActivity {
|
||||
*/
|
||||
private View btnTriple;
|
||||
|
||||
/**
|
||||
* Overlay to be shown when the player busted.
|
||||
*/
|
||||
private View mBustOverlay;
|
||||
|
||||
/**
|
||||
* The Button to submit a turn.
|
||||
*/
|
||||
private MaterialButton mSubmitTurnBtn;
|
||||
|
||||
/**
|
||||
* The Button to open the stats view.
|
||||
*/
|
||||
@@ -329,6 +350,7 @@ public class GameActivity extends BaseActivity {
|
||||
outState.putInt("startingScore", mStartingScore);
|
||||
outState.putString("matchUuid", mMatchUuid);
|
||||
outState.putBoolean("isTurnOver", mIsTurnOver);
|
||||
outState.putBoolean("isBustedTurn", mIsBustedTurn);
|
||||
|
||||
// Save current turn darts
|
||||
int[] dartsArray = new int[mCurrentTurnDarts.size()];
|
||||
@@ -382,6 +404,7 @@ public class GameActivity extends BaseActivity {
|
||||
mStartingScore = savedInstanceState.getInt("startingScore", DartsConstants.DEFAULT_GAME_SCORE);
|
||||
mMatchUuid = savedInstanceState.getString("matchUuid");
|
||||
mIsTurnOver = savedInstanceState.getBoolean("isTurnOver", false);
|
||||
mIsBustedTurn = savedInstanceState.getBoolean("isBustedTurn", false);
|
||||
|
||||
// Restore current turn darts
|
||||
mCurrentTurnDarts.clear();
|
||||
@@ -443,6 +466,9 @@ public class GameActivity extends BaseActivity {
|
||||
tvDartPills[0] = findViewById(R.id.tvDart1);
|
||||
tvDartPills[1] = findViewById(R.id.tvDart2);
|
||||
tvDartPills[2] = findViewById(R.id.tvDart3);
|
||||
mBustOverlay = findViewById(R.id.bust_pulse_overlay);
|
||||
mSubmitTurnBtn = findViewById(R.id.btnSubmitTurn);
|
||||
mScoreContainer = findViewById(R.id.scoreContainer);
|
||||
|
||||
glKeyboard = findViewById(R.id.glKeyboard);
|
||||
|
||||
@@ -458,7 +484,7 @@ public class GameActivity extends BaseActivity {
|
||||
});
|
||||
|
||||
|
||||
findViewById(R.id.btnSubmitTurn).setOnClickListener(v -> submitTurn());
|
||||
mSubmitTurnBtn.setOnClickListener(v -> submitTurn());
|
||||
findViewById(R.id.btnUndoDart).setOnClickListener(v -> undoLastDart());
|
||||
}
|
||||
|
||||
@@ -540,10 +566,11 @@ public class GameActivity extends BaseActivity {
|
||||
|
||||
updateTurnIndicators();
|
||||
mIsTurnOver = true;
|
||||
mIsBustedTurn = true;
|
||||
if (mIsAudioEnabled) {
|
||||
mSoundEngine.playBustedSound();
|
||||
}
|
||||
Toast.makeText(this, "BUST!", Toast.LENGTH_SHORT).show();
|
||||
triggerBustSequence();
|
||||
// In a pro interface, we usually wait for "Submit" or auto-submit after a short delay
|
||||
} else if (scoreAfterDart == 0 && isDouble) {
|
||||
// VICTORY CONDITION
|
||||
@@ -571,6 +598,39 @@ public class GameActivity extends BaseActivity {
|
||||
setMultiplier(DartsConstants.MULTIPLIER_SINGLE);
|
||||
}
|
||||
|
||||
private void triggerBustSequence() {
|
||||
mIsTurnOver = true;
|
||||
mIsBustedTurn = true;
|
||||
|
||||
// Visual feedback: Shake scoreboard
|
||||
Animation shake = AnimationUtils.loadAnimation(this, R.anim.shake);
|
||||
mScoreContainer.startAnimation(shake);
|
||||
|
||||
// Change scoreboard to Red
|
||||
mScoreContainer.setBackgroundColor(Color.parseColor("#33FF3B30"));
|
||||
tvScorePrimary.setTextColor(ContextCompat.getColor(this, R.color.double_red));
|
||||
|
||||
// Pulsing red overlay on input
|
||||
mBustOverlay.setVisibility(View.VISIBLE);
|
||||
Animation pulse = new AlphaAnimation(0.2f, 0.5f);
|
||||
pulse.setDuration(500);
|
||||
pulse.setRepeatMode(Animation.REVERSE);
|
||||
pulse.setRepeatCount(Animation.INFINITE);
|
||||
mBustOverlay.startAnimation(pulse);
|
||||
|
||||
mSubmitTurnBtn.setText("NEXT PLAYER (BUST)");
|
||||
updateTurnIndicators();
|
||||
}
|
||||
|
||||
private void resetVisuals() {
|
||||
mScoreContainer.setBackgroundColor(ContextCompat.getColor(this, R.color.surface_primary));
|
||||
tvScorePrimary.setTextColor(ContextCompat.getColor(this, R.color.volt_green));
|
||||
mBustOverlay.clearAnimation();
|
||||
mBustOverlay.setVisibility(View.GONE);
|
||||
mSubmitTurnBtn.setText(R.string.txt_game_btn_submit);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handler for Bull button tap. Delegates to onNumberTap with base value 25.
|
||||
*
|
||||
@@ -659,6 +719,7 @@ public class GameActivity extends BaseActivity {
|
||||
* Updates player score (unless bust), rotates to next player, resets turn state.
|
||||
*/
|
||||
private void submitTurn() {
|
||||
resetVisuals();
|
||||
// Don't submit if no darts thrown
|
||||
if (mCurrentTurnDarts.isEmpty()) return;
|
||||
|
||||
@@ -694,10 +755,9 @@ public class GameActivity extends BaseActivity {
|
||||
}
|
||||
}
|
||||
|
||||
// Re-check logic for non-double finish or score of 1
|
||||
int lastDartValue = mCurrentTurnDarts.get(mCurrentTurnDarts.size() - 1);
|
||||
// Note: this check is redundant but safe for manual "Submit" actions
|
||||
boolean isBust = (finalScore < 0 || finalScore == 1 || (finalScore == 0 && !isFinishDart(mCurrentTurnDarts.size() - 1)));
|
||||
// Use the mIsBustedTurn flag that was set in onNumberTap when the bust was detected
|
||||
// This is more reliable than recalculating since it tracks the actual multiplier used
|
||||
boolean isBust = mIsBustedTurn;
|
||||
|
||||
// Update score only if not bust
|
||||
if (!isBust) {
|
||||
@@ -717,6 +777,7 @@ public class GameActivity extends BaseActivity {
|
||||
mCurrentTurnDarts.clear();
|
||||
mCurrentTurnDartHits.clear();
|
||||
mIsTurnOver = false;
|
||||
mIsBustedTurn = false;
|
||||
|
||||
// Update UI for next player
|
||||
updateUI();
|
||||
@@ -756,10 +817,12 @@ public class GameActivity extends BaseActivity {
|
||||
|
||||
// Allow turn to continue
|
||||
mIsTurnOver = false;
|
||||
mIsBustedTurn = false;
|
||||
|
||||
// Update displays
|
||||
updateTurnIndicators();
|
||||
updateUI();
|
||||
resetVisuals();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -782,8 +845,11 @@ public class GameActivity extends BaseActivity {
|
||||
tvLegAvg.setText(String.format("AVG: %.1f", avg));
|
||||
|
||||
// Calculate current target (remaining score minus current turn darts)
|
||||
// If it's a busted turn, don't subtract the bust darts from the display
|
||||
int turnPointsSoFar = 0;
|
||||
for (int d : mCurrentTurnDarts) turnPointsSoFar += d;
|
||||
if (!mIsBustedTurn) {
|
||||
for (int d : mCurrentTurnDarts) turnPointsSoFar += d;
|
||||
}
|
||||
int currentTarget = active.remainingScore - turnPointsSoFar;
|
||||
int dartsRemaining = 3 - mCurrentTurnDarts.size();
|
||||
|
||||
|
||||
@@ -157,6 +157,15 @@
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:id="@+id/bust_pulse_overlay"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:background="#4DFF3B30"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintTop_toBottomOf="@id/trackerBar"
|
||||
app:layout_constraintBottom_toBottomOf="parent" />
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/dimmer"
|
||||
android:layout_width="match_parent"
|
||||
@@ -185,6 +194,7 @@
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/winner_text"
|
||||
android:layout_marginTop="15dp"
|
||||
style="@style/Widget.Oche_Button_Primary"
|
||||
android:visibility="gone"/>
|
||||
|
||||
@@ -198,7 +208,6 @@
|
||||
android:id="@+id/player_stats_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="15dp"
|
||||
android:visibility="gone"/>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
Reference in New Issue
Block a user