6 Commits

71 changed files with 692 additions and 363 deletions

3
.gitignore vendored
View File

@@ -36,3 +36,6 @@ google-services.json
# Claude # Claude
.claude/ .claude/
.settings/ .settings/
skills-lock.json
.agents

View File

@@ -34,20 +34,6 @@ El APK se generará en: `app/build/outputs/apk/release/app-release.apk`
adb install -r app/build/outputs/apk/release/app-release.apk adb install -r app/build/outputs/apk/release/app-release.apk
``` ```
## Pipeline CI/CD
El proyecto incluye pipeline automático para Gitea que compila releases al crear tags:
```bash
git tag v1.0.0
git push origin v1.0.0
```
- **Trigger**: Tags con formato `v*`
- **JDK**: 21
- **Android SDK**: API 34, build-tools 34.0.0
- **Salida**: APK en artifacts
## Estructura del Proyecto ## Estructura del Proyecto
``` ```
@@ -69,19 +55,19 @@ Helldivers/
├── settings.gradle ├── settings.gradle
├── gradle.properties ├── gradle.properties
├── gradlew / gradlew.bat ├── gradlew / gradlew.bat
└── .gitea/workflows/android.yml # Pipeline CI/CD └── .gitea/workflows/android.yml
``` ```
## Configuración Técnica ## Configuración Técnica
|属性|Valor| | Atributo | Valor |
|---|---| |---|---|
|minSdk|18 (Android 4.3)| | minSdk | 18 (Android 4.3) |
|targetSdk|21 (Android 5.0)| | targetSdk | 21 (Android 5.0) |
|compileSdk|34| | compileSdk | 34 |
|Java|21 con desugaring| | Java | 21 con desugaring |
|AGP|8.3.0| | AGP | 8.3.0 |
|Resolución|720x1280 xhdpi (landscape)| | Resolución | 720x1280 xhdpi (landscape) |
## Contribución ## Contribución

View File

@@ -3,100 +3,208 @@ package com.helldivers.app;
import android.graphics.Color; import android.graphics.Color;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.widget.Button; import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView; import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
public class ActivityGame extends AppCompatActivity { public class ActivityGame extends AppCompatActivity {
private static final String[] ARROWS = new String[]{"\u2191", "\u2193", "\u2190", "\u2192"};
private static final int UP = 0, DOWN = 1, LEFT = 2, RIGHT = 3; private static final int UP = 0, DOWN = 1, LEFT = 2, RIGHT = 3;
private static final int[][] STRATAGEMS = new int[][]{ private static final int[][] STRATAGEMS = {
new int[]{UP, DOWN, RIGHT, LEFT, UP}, // SUPPORT WEAPONS (12 items) - from wiki
new int[]{DOWN, DOWN, UP, RIGHT}, new int[]{DOWN, LEFT, DOWN, UP, RIGHT}, // MG-43 Machine Gun
new int[]{UP, DOWN, RIGHT, UP}, new int[]{DOWN, DOWN, LEFT, UP, RIGHT}, // EAT-17 Expendable Anti-Tank
new int[]{RIGHT, UP, UP, DOWN}, new int[]{DOWN, LEFT, DOWN, UP, UP, LEFT}, // M-105 Stalwart
new int[]{DOWN, UP, LEFT, DOWN, UP, RIGHT, DOWN, UP}, new int[]{DOWN, LEFT, DOWN, UP, LEFT}, // LAS-98 Laser Cannon
new int[]{DOWN, UP, DOWN, UP}, new int[]{DOWN, LEFT, RIGHT, UP, DOWN}, // APW-1 Anti-Materiel Rifle
new int[]{DOWN, LEFT, DOWN, UP, RIGHT}, new int[]{DOWN, LEFT, RIGHT, RIGHT, LEFT}, // GR-8 Recoilless Rifle
new int[]{DOWN, LEFT, RIGHT, UP, DOWN}, new int[]{DOWN, LEFT, UP, LEFT, DOWN}, // GL-21 Grenade Launcher
new int[]{DOWN, LEFT, DOWN, UP, UP, LEFT}, new int[]{DOWN, LEFT, UP, DOWN, UP}, // FLAM-40 Flamethrower
new int[]{DOWN, DOWN, LEFT, UP, RIGHT}, new int[]{DOWN, LEFT, DOWN, UP, UP, RIGHT}, // AC-8 Autocannon
new int[]{DOWN, LEFT, RIGHT, RIGHT, LEFT}, new int[]{DOWN, RIGHT, DOWN, UP, LEFT, LEFT}, // ARC-3 Arc Thrower
new int[]{DOWN, LEFT, UP, DOWN, UP}, new int[]{DOWN, RIGHT, DOWN, UP, LEFT, RIGHT},// RS-422 Railgun
new int[]{DOWN, LEFT, DOWN, UP, UP, RIGHT}, new int[]{DOWN, DOWN, UP, DOWN, DOWN}, // FAF-14 Spear
new int[]{DOWN, RIGHT, DOWN, UP, LEFT, RIGHT},
new int[]{DOWN, DOWN, UP, DOWN, DOWN}, // ORBITAL (11 items)
new int[]{RIGHT, DOWN, LEFT, UP, UP}, new int[]{RIGHT, RIGHT, UP}, // Orbital Precision Strike
new int[]{RIGHT, RIGHT, RIGHT}, new int[]{RIGHT, DOWN, LEFT, UP, UP}, // Orbital Gatling Barrage
new int[]{RIGHT, RIGHT, DOWN, LEFT, RIGHT, DOWN}, new int[]{RIGHT, RIGHT, RIGHT}, // Orbital Airburst Strike
new int[]{RIGHT, DOWN, UP, UP, LEFT, DOWN, DOWN}, new int[]{RIGHT, RIGHT, DOWN, LEFT, RIGHT, DOWN}, // Orbital 120MM HE Barrage
new int[]{RIGHT, DOWN, RIGHT, DOWN, RIGHT, DOWN}, new int[]{RIGHT, RIGHT, DOWN, UP}, // Orbital Smoke Strike
new int[]{RIGHT, DOWN, UP, RIGHT, DOWN}, new int[]{RIGHT, RIGHT, LEFT, DOWN}, // Orbital EMS Strike
new int[]{RIGHT, UP, DOWN, DOWN, RIGHT}, new int[]{RIGHT, DOWN, UP, UP, LEFT, DOWN, DOWN}, // Orbital 380MM HE Barrage
new int[]{UP, RIGHT, RIGHT}, new int[]{RIGHT, DOWN, RIGHT, DOWN, RIGHT, DOWN}, // Orbital Walking Barrage
new int[]{UP, RIGHT, DOWN, RIGHT}, new int[]{RIGHT, DOWN, UP, RIGHT, DOWN}, // Orbital Laser
new int[]{UP, RIGHT, DOWN, DOWN, RIGHT}, new int[]{RIGHT, UP, DOWN, DOWN, RIGHT}, // Orbital Railcannon Strike
new int[]{UP, RIGHT, DOWN, UP}, new int[]{RIGHT, RIGHT, DOWN, RIGHT}, // Orbital Gas Strike
new int[]{DOWN, UP, UP, DOWN, UP},
new int[]{UP, RIGHT, DOWN, UP}, // EAGLE (7 items)
new int[]{UP, RIGHT, UP, LEFT}, new int[]{UP, RIGHT, RIGHT}, // Eagle Strafing Run
new int[]{UP, RIGHT, DOWN, DOWN, DOWN}, new int[]{UP, RIGHT, DOWN, RIGHT}, // Eagle Airstrike
new int[]{UP, UP, LEFT, UP, RIGHT}, new int[]{UP, RIGHT, DOWN, DOWN, RIGHT}, // Eagle Cluster Bomb
new int[]{RIGHT, RIGHT, UP}, new int[]{UP, RIGHT, UP, DOWN}, // Eagle Smoke Strike
new int[]{RIGHT, RIGHT, DOWN, RIGHT}, new int[]{UP, RIGHT, DOWN, UP}, // Eagle Napalm Airstrike
new int[]{RIGHT, RIGHT, LEFT, DOWN}, new int[]{UP, RIGHT, UP, LEFT}, // Eagle 110MM Rocket Pods
new int[]{RIGHT, RIGHT, DOWN, UP}, new int[]{UP, RIGHT, DOWN, DOWN, DOWN}, // Eagle 500kg Bomb
new int[]{DOWN, UP, LEFT, RIGHT, RIGHT, LEFT},
new int[]{DOWN, DOWN, LEFT, RIGHT, LEFT, RIGHT}, // BACKPACKS (4 items)
new int[]{DOWN, UP, RIGHT, UP, LEFT, RIGHT}, new int[]{DOWN, LEFT, DOWN, UP, UP, DOWN}, // B-1 Supply Pack
new int[]{DOWN, LEFT, UP, RIGHT}, new int[]{DOWN, UP, UP, DOWN, UP}, // LIFT-850 Jump Pack
new int[]{DOWN, LEFT, DOWN, UP, UP, DOWN}, new int[]{DOWN, LEFT, DOWN, DOWN, UP, LEFT}, // SH-20 Ballistic Shield Backpack
new int[]{DOWN, LEFT, UP, LEFT, DOWN}, new int[]{DOWN, UP, LEFT, RIGHT, LEFT, RIGHT},// SH-32 Shield Generator Pack
new int[]{DOWN, LEFT, DOWN, UP, LEFT},
new int[]{DOWN, LEFT, LEFT, DOWN}, // MINES (2 items)
new int[]{UP, DOWN, LEFT, UP, RIGHT, RIGHT}, new int[]{DOWN, LEFT, UP, RIGHT}, // MD-6 Anti-Personnel Minefield
new int[]{DOWN, LEFT, DOWN, DOWN, UP, LEFT}, new int[]{DOWN, LEFT, LEFT, DOWN}, // MD-I4 Incendiary Mines
new int[]{DOWN, RIGHT, DOWN, UP, LEFT, LEFT},
new int[]{DOWN, UP, LEFT, RIGHT, LEFT, RIGHT}, // EMPLACEMENTS (3 items)
new int[]{DOWN, UP, RIGHT, RIGHT, UP}, new int[]{DOWN, DOWN, LEFT, RIGHT,LEFT, RIGHT}, // FX-12 Shield Generator Relay
new int[]{DOWN, UP, RIGHT, LEFT}, new int[]{DOWN, UP, LEFT, RIGHT, RIGHT, LEFT}, // EMG-101 HMG Emplacement
new int[]{DOWN, UP, RIGHT, RIGHT, DOWN}, new int[]{DOWN, UP, RIGHT, UP, LEFT, RIGHT}, // AARC-3 Tesla Tower
new int[]{DOWN, UP, LEFT, UP, RIGHT, DOWN},
new int[]{DOWN, UP, RIGHT, UP, LEFT, UP}, // SENTRIES (6 items)
new int[]{DOWN, UP, RIGHT, RIGHT, LEFT}, new int[]{DOWN, UP, RIGHT, LEFT}, // AG-16 Gatling Sentry
new int[]{DOWN, UP, RIGHT, DOWN, RIGHT} new int[]{DOWN, UP, RIGHT, RIGHT, UP}, // AMG-43 Machine Gun Sentry
new int[]{DOWN, UP, RIGHT, UP, LEFT, UP}, // AAC-8 Autocannon Sentry
new int[]{DOWN, UP, RIGHT, DOWN, UP, UP}, // AMLS-4X Rocket Sentry
new int[]{DOWN, UP, RIGHT, RIGHT, DOWN}, // AM-12 Mortar Sentry
new int[]{DOWN, UP, RIGHT, DOWN, RIGHT}, // AM-23 EMS Mortar Sentry
// MISSION (12 items)
new int[]{UP, DOWN, RIGHT, LEFT, UP}, // Reinforce
new int[]{DOWN, DOWN, UP, RIGHT}, // Resupply
new int[]{UP, DOWN, RIGHT, UP}, // SOS Beacon
new int[]{DOWN, UP, LEFT, DOWN, UP, RIGHT, DOWN, UP}, // NUX-223 Hellbomb
new int[]{DOWN, DOWN, DOWN, UP, UP}, // SSSD Delivery
new int[]{UP, UP, LEFT, RIGHT, DOWN, DOWN}, // Seismic Probe
new int[]{UP, UP, LEFT, UP, RIGHT}, // Eagle Rearm
new int[]{DOWN, UP, DOWN, UP}, // Super Earth Flag
new int[]{LEFT, RIGHT, UP, UP, UP}, // Upload Data
new int[]{RIGHT, UP, UP, DOWN},// SEAF Artillery
new int[]{LEFT, UP, DOWN, RIGHT, DOWN, DOWN} // Hive Breaker Drill
}; };
private static final String[] NAMES = new String[]{ private static final String[] NAMES = {
"Reforzamiento", "Reabastecimiento", "Baliza SOS", "Artilleria", "Bomba Infernal", // SUPPORT WEAPONS (0-11)
"Bandera", "Ametralladora", "Rifle material", "Leal", "Antitanque", "MG-43 Machine Gun", "EAT-17", "M-105 Stalwart", "LAS-98 Laser Cannon", "APW-1 Anti-Materiel Rifle",
"Rifle retroceso", "Echador llama", "Canon auto", "Canon riel", "Lanza", "GR-8 Recoilless Rifle", "GL-21 Grenade Launcher", "FLAM-40 Flamethrower", "AC-8 Autocannon",
"Bombardeo", "Ataque aereo", "HE 120mm", "HE 380mm", "Aluvion", "ARC-3 Arc Thrower", "RS-422 Railgun", "FAF-14 Spear",
"Laser orbital", "Riel orbital", "Carrera", "Ataque", "Racimo", // ORBITAL (12-22)
"Napalm", "Salto", "Humo", "Cohetes", "Bomba 500kg", "Orbital Precision", "Orbital Gatling", "Orbital Airburst", "Orbital 120mm", "Orbital Smoke",
"Rearme", "Precision", "Gas", "EMS", "Humo2", "Orbital EMS", "Orbital 380mm", "Orbital Walking", "Orbital Laser", "Orbital Railcannon", "Orbital Gas",
"HMG", "Escudo", "Tesla", "Minas", "Suministros", // EAGLE (23-29)
"Granadas", "Laser", "Incendiarias", "Rover", "Balistico", "Eagle Strafing", "Eagle Airstrike", "Eagle Cluster", "Eagle Smoke", "Eagle Napalm",
"Arco", "Escudo2", "Centinela1", "Centinela2", "Centinela3", "Eagle Rocket Pods", "Eagle 500kg",
"Guardian", "Centinela4", "Centinela5", "Centinela6", "Centinela7" // BACKPACKS (30-33)
"Supply Pack", "Jump Pack", "Ballistic Shield", "Shield Generator",
// MINES (34-35)
"Anti-Personnel Mines", "Incendiary Mines",
// EMPLACEMENTS (36-38)
"Shield Relay", "HMG Emplacement", "Tesla Tower",
// SENTRIES (39-44)
"Gatling Sentry", "MG Sentry", "Autocannon Sentry", "Rocket Sentry", "Mortar Sentry", "EMS Mortar Sentry",
// MISSION (45-56)
"Reinforce", "Resupply", "SOS Beacon", "Hellbomb", "SSSD", "Seismic Probe", "Eagle Rearm",
"Super Earth Flag", "Upload Data", "SEAF Artillery", "Hive Breaker"
};
private static final int[] ICONS = new int[]{
// SUPPORT WEAPONS (0-11)
R.drawable.mg_43_machine_gun,
R.drawable.eat_17_expendable_anti_tank,
R.drawable.m_105_stalwart,
R.drawable.las_98_laser_cannon,
R.drawable.apw_1_anti_materiel_rifle,
R.drawable.gr_8_recoilless_rifle,
R.drawable.gl_21_grenade_launcher,
R.drawable.flam_40_flamethrower,
R.drawable.ac_8_autocannon,
R.drawable.arc_3_arc_thrower,
R.drawable.rs_422_railgun,
R.drawable.faf_14_spear_launcher,
// ORBITAL (12-22)
R.drawable.orbital_precision_strike,
R.drawable.orbital_gatling_barrage,
R.drawable.orbital_airburst_strike,
R.drawable.orbital_120mm_he_barrage,
R.drawable.orbital_smoke_strike,
R.drawable.orbital_ems_strike,
R.drawable.orbital_380mm_he_barrage,
R.drawable.orbital_walking_barrage,
R.drawable.orbital_laser,
R.drawable.orbital_railcannon_strike,
R.drawable.orbital_gas_strike,
// EAGLE (23-29)
R.drawable.eagle_strafing_run,
R.drawable.eagle_airstrike,
R.drawable.eagle_cluster_bomb,
R.drawable.eagle_smoke_strike,
R.drawable.eagle_napalm_airstrike,
R.drawable.eagle_110mm_rocket_pods,
R.drawable.eagle_500kg_bomb,
// BACKPACKS (30-33)
R.drawable.b_1_supply_pack,
R.drawable.lift_850_jump_pack,
R.drawable.sh_20_ballistic_shield_backpack,
R.drawable.sh_32_shield_generator_pack,
// MINES (34-35)
R.drawable.md_6_anti_personnel,
R.drawable.md_i4_incendiary_mines,
// EMPLACEMENTS (36-38)
R.drawable.fx_12_shield_generator_relay,
R.drawable.emg_101_hmg_emplacem_nt,
R.drawable.aarc_3_tesla_tower,
// SENTRIES (39-44)
R.drawable.ag_16_gatling_sentry,
R.drawable.amg_43_machine_gun_sentry,
R.drawable.aac_8_autocannon_sentry,
R.drawable.amls_4x_rocket_sentry,
R.drawable.am_12_mortar_sentry,
R.drawable.am_23_ems_mortar_sentry,
// MISSION (45-56)
R.drawable.reinforce,
R.drawable.resupply,
R.drawable.sos_beacon,
R.drawable.nux_223_hellbomb,
R.drawable.sssd_delivery,
R.drawable.seismic_probe,
R.drawable.eagle_rearm,
R.drawable.super_earth_flag,
R.drawable.nux_223_hellbomb,
R.drawable.sssd_delivery,
R.drawable.hive_breaker_drill
};
private static final int[] ARROW_ICONS = new int[]{
R.drawable.stepforward, R.drawable.stepforward, R.drawable.stepforward, R.drawable.stepforward
}; };
private SoundManager soundManager; private SoundManager soundManager;
private Handler handler = new Handler(); private Handler handler = new Handler();
private TextView tvSequence;
private TextView tvCounter; private TextView tvCounter;
private Button btnUp, btnDown, btnLeft, btnRight; private ImageView ivStratagemIcon;
private Button btnVolver; private LinearLayout sequenceContainer;
private ImageButton btnUp, btnDown, btnLeft, btnRight;
private android.widget.Button btnVolver;
private ProgressBar progressBar;
private ImageView ivFailure;
private int[] sequence; private int[] sequence;
private int playerIndex = 0; private int playerIndex = 0;
private int completadas = 0; private int completadas = 0;
private boolean esperando = false; private boolean esperando = false;
private boolean juegoActivo = true; private boolean juegoActivo = true;
private String[] ultimosArrows; private int currentStratagemIndex = 0;
private boolean bloqueado = false;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
@@ -106,13 +214,16 @@ public class ActivityGame extends AppCompatActivity {
try { soundManager = new SoundManager(this); } try { soundManager = new SoundManager(this); }
catch (Exception e) { soundManager = null; } catch (Exception e) { soundManager = null; }
tvSequence = findViewById(R.id.tv_sequence);
tvCounter = findViewById(R.id.tv_counter); tvCounter = findViewById(R.id.tv_counter);
ivStratagemIcon = findViewById(R.id.iv_stratagem_icon);
sequenceContainer = findViewById(R.id.sequence_container);
btnUp = findViewById(R.id.btn_up); btnUp = findViewById(R.id.btn_up);
btnDown = findViewById(R.id.btn_down); btnDown = findViewById(R.id.btn_down);
btnLeft = findViewById(R.id.btn_left); btnLeft = findViewById(R.id.btn_left);
btnRight = findViewById(R.id.btn_right); btnRight = findViewById(R.id.btn_right);
btnVolver = findViewById(R.id.btn_volver); btnVolver = findViewById(R.id.btn_volver);
progressBar = findViewById(R.id.progress_bar);
ivFailure = findViewById(R.id.iv_failure);
btnVolver.setOnClickListener(v -> finish()); btnVolver.setOnClickListener(v -> finish());
@@ -124,26 +235,64 @@ public class ActivityGame extends AppCompatActivity {
nuevaRonda(); nuevaRonda();
} }
private int getArrowRotation(int dir) {
switch(dir) {
case UP: return 0;
case DOWN: return 180;
case LEFT: return -90;
case RIGHT: return 90;
default: return 0;
}
}
private void nuevaRonda() { private void nuevaRonda() {
int idx = (int)(Math.random() * STRATAGEMS.length); int idx = (int)(Math.random() * STRATAGEMS.length);
sequence = STRATAGEMS[idx]; sequence = STRATAGEMS[idx];
currentStratagemIndex = idx;
playerIndex = 0; playerIndex = 0;
juegoActivo = true; juegoActivo = true;
ultimosArrows = new String[sequence.length]; bloqueado = false;
StringBuilder sb = new StringBuilder(); if (progressBar != null) progressBar.setVisibility(View.GONE);
for (int i = 0; i < sequence.length; i++) { if (ivFailure != null) ivFailure.setVisibility(View.GONE);
int dir = sequence[i];
ultimosArrows[i] = ARROWS[dir]; if (ivStratagemIcon != null) {
sb.append(ultimosArrows[i]).append(" "); try {
} int iconIndex = idx % ICONS.length;
if (tvSequence != null) { ivStratagemIcon.setImageResource(ICONS[iconIndex]);
tvSequence.setText(sb.toString().trim()); } catch (Exception e) {
tvSequence.setTextColor(Color.parseColor("#FFD700")); ivStratagemIcon.setImageResource(R.drawable.stratagemas_icon);
}
} }
secuenciaMostrar();
handler.removeCallbacksAndMessages(null); handler.removeCallbacksAndMessages(null);
handler.postDelayed(() -> { esperando = true; }, 1200); esperando = true;
}
private static final String ARROW_CHARS = "\u2191\u2193\u2190\u2192";
private void secuenciaMostrar() {
if (sequenceContainer == null) return;
sequenceContainer.removeAllViews();
for (int i = 0; i < sequence.length; i++) {
TextView arrowView = new TextView(this);
int size = (int)(56 * getResources().getDisplayMetrics().density);
int margin = (int)(4 * getResources().getDisplayMetrics().density);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(size, size);
params.setMargins(margin, margin, margin, margin);
arrowView.setLayoutParams(params);
arrowView.setText(String.valueOf(ARROW_CHARS.charAt(sequence[i])));
arrowView.setTextSize(36);
arrowView.setTextColor(Color.parseColor("#FFD700"));
arrowView.setGravity(Gravity.CENTER);
arrowView.setBackgroundResource(R.drawable.arrow_white);
sequenceContainer.addView(arrowView);
}
} }
private void onInputWithSound(int dir) { private void onInputWithSound(int dir) {
@@ -154,24 +303,17 @@ public class ActivityGame extends AppCompatActivity {
} }
private void onInput(int dir) { private void onInput(int dir) {
if (!juegoActivo || !esperando) return; if (!juegoActivo || !esperando || bloqueado) return;
bloqueado = true;
if (dir == sequence[playerIndex]) { if (dir == sequence[playerIndex]) {
playerIndex++; playerIndex++;
if (tvSequence != null) { if (sequenceContainer != null && playerIndex <= sequence.length) {
StringBuilder sb = new StringBuilder(); View child = sequenceContainer.getChildAt(playerIndex - 1);
for (int i = 0; i < sequence.length; i++) { if (child instanceof TextView) {
if (i < playerIndex) { TextView arrowView = (TextView) child;
sb.append("<font color='#00FF00'>").append(ultimosArrows[i]).append("</font> "); arrowView.setTextColor(Color.parseColor("#00FF00"));
} else {
sb.append(ultimosArrows[i]).append(" ");
}
}
try {
tvSequence.setText(android.text.Html.fromHtml(sb.toString()));
} catch (Exception e) {
tvSequence.setText(sb.toString().replaceAll("<[^>]*>", ""));
} }
} }
@@ -181,22 +323,23 @@ public class ActivityGame extends AppCompatActivity {
} }
completadas++; completadas++;
if (tvCounter != null) tvCounter.setText(String.valueOf(completadas)); if (tvCounter != null) tvCounter.setText(String.valueOf(completadas));
if (tvSequence != null) {
tvSequence.setText("OK!");
tvSequence.setTextColor(Color.parseColor("#00FF00"));
}
esperando = false; esperando = false;
handler.postDelayed(this::nuevaRonda, 1200); if (progressBar != null) {
progressBar.setVisibility(View.VISIBLE);
handler.postDelayed(() -> {
if (progressBar != null) progressBar.setVisibility(View.GONE);
}, 300);
}
handler.postDelayed(this::nuevaRonda, 300);
} else {
bloqueado = false;
} }
} else { } else {
if (soundManager != null) { if (soundManager != null) {
try { soundManager.playFailure(); } catch (Exception e) {} try { soundManager.playFailure(); } catch (Exception e) {}
} }
if (tvSequence != null) {
tvSequence.setText("X");
tvSequence.setTextColor(Color.parseColor("#FF0000"));
}
juegoActivo = false; juegoActivo = false;
if (ivFailure != null) ivFailure.setVisibility(View.VISIBLE);
handler.postDelayed(this::nuevaRonda, 1500); handler.postDelayed(this::nuevaRonda, 1500);
} }
} }

View File

@@ -4,75 +4,80 @@ import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.view.View; import android.view.View;
import android.widget.Button; import android.widget.Button;
import android.widget.ImageButton;
import android.widget.ImageView;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
/**
* Main Activity - Menu principal con tematica Helldivers 2
* Optimizado para Samsung Galaxy S3 (720x1280 xhdpi, landscape)
*/
public class MainActivity extends AppCompatActivity { public class MainActivity extends AppCompatActivity {
private SoundManager soundManager; private SoundManager soundManager;
private Button btnQrInstagram; private Button btnQrInstagram;
private Button btnMinijuego; private Button btnMinijuego;
private ImageButton btnUp, btnDown, btnLeft, btnRight;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); setContentView(R.layout.activity_main);
// Inicializar SoundManager try {
soundManager = new SoundManager(this); soundManager = new SoundManager(this);
} catch (Exception e) {
// Referencias UI soundManager = null;
btnQrInstagram = findViewById(R.id.btn_qr_instagram);
btnMinijuego = findViewById(R.id.btn_minijuego);
if (btnQrInstagram == null || btnMinijuego == null) {
throw new RuntimeException("Button not found in layout");
} }
// Configurar listeners btnQrInstagram = findViewById(R.id.btn_qr_instagram);
btnQrInstagram.setOnClickListener(new View.OnClickListener() { btnMinijuego = findViewById(R.id.btn_minijuego);
@Override btnUp = findViewById(R.id.btn_up);
public void onClick(View v) { btnDown = findViewById(R.id.btn_down);
soundManager.playButtonClick(); btnLeft = findViewById(R.id.btn_left);
Intent intent = new Intent(MainActivity.this, ActivityQR.class); btnRight = findViewById(R.id.btn_right);
startActivity(intent);
}
});
btnMinijuego.setOnClickListener(new View.OnClickListener() { if (btnQrInstagram != null) {
@Override btnQrInstagram.setOnClickListener(v -> {
public void onClick(View v) { if (soundManager != null) {
soundManager.playButtonClick(); try { soundManager.playButtonClick(); } catch (Exception e) {}
Intent intent = new Intent(MainActivity.this, ActivityGame.class); }
startActivity(intent); startActivity(new Intent(this, ActivityQR.class));
});
}
if (btnMinijuego != null) {
btnMinijuego.setOnClickListener(v -> {
if (soundManager != null) {
try { soundManager.playButtonClick(); } catch (Exception e) {}
}
startActivity(new Intent(this, ActivityGame.class));
});
}
View.OnClickListener arrowSoundListener = v -> {
if (soundManager != null) {
try { soundManager.playButtonClick(); } catch (Exception e) {}
} }
}); };
if (btnUp != null) btnUp.setOnClickListener(arrowSoundListener);
if (btnDown != null) btnDown.setOnClickListener(arrowSoundListener);
if (btnLeft != null) btnLeft.setOnClickListener(arrowSoundListener);
if (btnRight != null) btnRight.setOnClickListener(arrowSoundListener);
} }
@Override @Override
protected void onResume() { protected void onResume() {
super.onResume(); super.onResume();
if (soundManager != null) { if (soundManager != null) soundManager.resume();
soundManager.resume();
}
} }
@Override @Override
protected void onPause() { protected void onPause() {
super.onPause(); super.onPause();
if (soundManager != null) { if (soundManager != null) soundManager.pause();
soundManager.pause();
}
} }
@Override @Override
protected void onDestroy() { protected void onDestroy() {
super.onDestroy(); super.onDestroy();
if (soundManager != null) { if (soundManager != null) soundManager.release();
soundManager.release();
}
} }
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<solid android:color="#232830" />
<corners android:radius="6dp" />
<stroke android:width="2dp" android:color="#FFD700" />
</shape>
</item>
<item android:top="4dp" android:bottom="4dp" android:left="4dp" android:right="4dp">
<shape android:shape="rectangle">
<solid android:color="#1B1F25" />
<corners android:radius="4dp" />
</shape>
</item>
</layer-list>

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

View File

@@ -1,7 +1,22 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!-- Centro del D-Pad decorativo --> <!-- Centro del D-Pad decorativo con efecto de luz -->
<shape xmlns:android="http://schemas.android.com/apk/res/android" <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
android:shape="oval"> <item>
<solid android:color="#2C3138" /> <shape android:shape="oval">
<stroke android:width="2dp" android:color="#FFD700" /> <solid android:color="#1A1D24" />
</shape> <size android:width="420dp" android:height="420dp" />
</shape>
</item>
<item android:top="2dp" android:bottom="2dp" android:left="2dp" android:right="2dp">
<shape android:shape="oval">
<solid android:color="#232830" />
<stroke android:width="1dp" android:color="#3D4350" />
</shape>
</item>
<item android:top="4dp" android:bottom="4dp" android:left="4dp" android:right="4dp">
<shape android:shape="oval">
<solid android:color="#2C3138" />
<stroke android:width="1dp" android:color="#FFD700" android:alpha="0.3" />
</shape>
</item>
</layer-list>

View File

@@ -1,27 +1,56 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!-- Boton de direccion para D-Pad del juego --> <!-- Boton de direccion para D-Pad del juego con efecto neon -->
<selector xmlns:android="http://schemas.android.com/apk/res/android"> <selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"> <item android:state_pressed="true">
<shape android:shape="rectangle"> <layer-list>
<solid android:color="#FFD700" /> <item>
<corners android:radius="4dp" /> <shape android:shape="rectangle">
<stroke android:width="2dp" android:color="#FFFFFF" /> <solid android:color="#FFD700" />
</shape> <corners android:radius="8dp" />
</shape>
</item>
<item android:top="2dp" android:left="2dp" android:right="2dp" android:bottom="2dp">
<shape android:shape="rectangle">
<solid android:color="#1B1F25" />
<corners android:radius="6dp" />
</shape>
</item>
</layer-list>
</item> </item>
<item android:state_focused="true"> <item android:state_focused="true">
<shape android:shape="rectangle"> <layer-list>
<solid android:color="#00BFFF" /> <item>
<corners android:radius="4dp" /> <shape android:shape="rectangle">
<stroke android:width="2dp" android:color="#1E90FF" /> <solid android:color="#1B1F25" />
</shape> <corners android:radius="8dp" />
<stroke android:width="3dp" android:color="#00BFFF" />
</shape>
</item>
<item android:top="3dp" android:left="3dp" android:right="3dp" android:bottom="3dp">
<shape android:shape="rectangle">
<solid android:color="#232830" />
<corners android:radius="6dp" />
</shape>
</item>
</layer-list>
</item> </item>
<item> <item>
<shape android:shape="rectangle"> <layer-list>
<solid android:color="#1B1F25" /> <item>
<corners android:radius="4dp" /> <shape android:shape="rectangle">
<stroke android:width="2dp" android:color="#FFD700" /> <solid android:color="#1B1F25" />
</shape> <corners android:radius="8dp" />
<stroke android:width="2dp" android:color="#FFD700" />
</shape>
</item>
<item android:top="2dp" android:left="2dp" android:right="2dp" android:bottom="2dp">
<shape android:shape="rectangle">
<solid android:color="#232830" />
<corners android:radius="6dp" />
</shape>
</item>
</layer-list>
</item> </item>
</selector> </selector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="150dp"
android:height="150dp"
android:viewportWidth="150"
android:viewportHeight="150">
<!-- Red circle background -->
<path
android:fillColor="#CC0000"
android:pathData="M75,75m-60,0a60,60 0,1 1,120 0a60,60 0,1 1,-120 0"/>
<!-- X mark -->
<path
android:strokeWidth="10"
android:strokeColor="#FFFFFF"
android:pathData="M45,45L105,105"/>
<path
android:strokeWidth="10"
android:strokeColor="#FFFFFF"
android:pathData="M105,45L45,105"/>
</vector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

View File

@@ -5,19 +5,8 @@
android:background="@drawable/bg_helldivers_gradient"> android:background="@drawable/bg_helldivers_gradient">
<!-- Contador --> <!-- Contador -->
<TextView
android:id="@+id/tv_counter"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
android:layout_margin="8dp"
android:text="0"
android:textSize="24sp"
android:textStyle="bold"
android:textColor="#00FF00" />
<!-- Secuencia - arriba --> <!-- Nombre de la estratagema -->
<TextView <TextView
android:id="@+id/tv_counter_label" android:id="@+id/tv_counter_label"
@@ -25,115 +14,170 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignTop="@id/tv_counter" android:layout_alignTop="@id/tv_counter"
android:layout_marginTop="5dp" android:layout_marginTop="5dp"
android:layout_marginEnd="26dp" android:layout_marginEnd="24dp"
android:layout_toStartOf="@id/tv_counter" android:layout_toStartOf="@id/tv_counter"
android:text="ESTRATAGEMAS: " android:text="ESTRATAGEMAS: "
android:textColor="#00FF00" android:textColor="#00FF00"
android:textSize="16sp" /> android:textSize="16sp" />
<TextView <TextView
android:id="@+id/tv_sequence" android:id="@+id/tv_counter"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentBottom="true"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="15dp"
android:layout_marginBottom="207dp"
android:text="0"
android:textColor="#00FF00"
android:textSize="24sp"
android:textStyle="bold" />
<TextView
android:id="@+id/tv_stratagem_name"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_centerHorizontal="true" android:layout_centerHorizontal="true"
android:layout_above="@id/buttons_grid" android:layout_alignParentTop="true"
android:layout_marginBottom="8dp" android:layout_marginTop="8dp"
android:text="" android:text=""
android:textSize="36sp" android:textSize="20sp"
android:textStyle="bold" android:textStyle="bold"
android:textColor="#FFD700" /> android:textColor="#FFD700" />
<!-- Botones - mas separadas --> <!-- Contenedor principal: Icono + Secuencia + Grid flechas -->
<GridLayout <LinearLayout
android:id="@+id/buttons_grid" android:id="@+id/linearLayout"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentBottom="true" android:layout_centerInParent="true"
android:layout_centerHorizontal="true" android:gravity="center_vertical"
android:layout_marginBottom="48dp" android:orientation="horizontal">
android:rowCount="3"
android:columnCount="3"
android:padding="16dp">
<Space <!-- Icono de la estratagema - Izquierda -->
android:layout_width="80dp" <LinearLayout
android:layout_height="80dp" android:layout_width="wrap_content"
android:layout_row="0" android:layout_height="wrap_content"
android:layout_column="0" /> android:layout_marginEnd="24dp"
android:gravity="center"
android:orientation="vertical">
<Button </LinearLayout>
android:id="@+id/btn_up"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_row="0"
android:layout_column="1"
android:background="@drawable/btn_direction"
android:text="↑"
android:textColor="#FFD700"
android:textSize="36sp"
android:layout_margin="6dp" />
<Space <!-- Centro: Secuencia de flechas -->
android:layout_width="80dp" <LinearLayout
android:layout_height="80dp" android:layout_width="wrap_content"
android:layout_row="0" android:layout_height="wrap_content"
android:layout_column="2" /> android:gravity="center"
android:orientation="vertical">
<Button
android:id="@+id/btn_left"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_row="1"
android:layout_column="0"
android:background="@drawable/btn_direction"
android:text="←"
android:textColor="#FFD700"
android:textSize="36sp"
android:layout_margin="6dp" />
<Button <LinearLayout
android:id="@+id/btn_down" android:id="@+id/sequence_container"
android:layout_width="80dp" android:layout_width="wrap_content"
android:layout_height="80dp" android:layout_height="wrap_content"
android:layout_row="1" android:layout_marginBottom="12dp"
android:layout_column="1" android:gravity="center"
android:background="@drawable/btn_direction" android:orientation="horizontal" />
android:text="↓"
android:textColor="#FFD700"
android:textSize="36sp"
android:layout_margin="6dp" />
<Button <!-- Grid de Flechas - Input -->
android:id="@+id/btn_right" <GridLayout
android:layout_width="80dp" android:id="@+id/buttons_grid"
android:layout_height="80dp" android:layout_width="wrap_content"
android:layout_row="1" android:layout_height="wrap_content"
android:layout_column="2" android:columnCount="3"
android:background="@drawable/btn_direction" android:padding="8dp"
android:text="→" android:rowCount="3">
android:textColor="#FFD700"
android:textSize="36sp"
android:layout_margin="6dp" />
<Space <Space
android:layout_width="80dp" android:layout_width="80dp"
android:layout_height="10dp" android:layout_height="80dp"
android:layout_row="2" android:layout_row="0"
android:layout_column="0" /> android:layout_column="0" />
<Space <ImageButton
android:layout_width="80dp" android:id="@+id/btn_up"
android:layout_height="10dp" android:layout_width="80dp"
android:layout_row="2" android:layout_height="80dp"
android:layout_column="1" /> android:layout_row="0"
android:layout_column="1"
android:layout_margin="4dp"
android:background="@drawable/btn_direction"
android:contentDescription="Up"
android:rotation="-90"
android:scaleType="centerInside"
android:src="@drawable/stepforward" />
<Space <Space
android:layout_width="80dp" android:layout_width="80dp"
android:layout_height="10dp" android:layout_height="80dp"
android:layout_row="2" android:layout_row="0"
android:layout_column="2" /> android:layout_column="2" />
</GridLayout> <ImageButton
android:id="@+id/btn_left"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_row="1"
android:layout_column="0"
android:layout_margin="4dp"
android:background="@drawable/btn_direction"
android:contentDescription="Left"
android:rotation="180"
android:scaleType="centerInside"
android:src="@drawable/stepforward" />
<ImageButton
android:id="@+id/btn_down"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_row="1"
android:layout_column="1"
android:layout_margin="4dp"
android:background="@drawable/btn_direction"
android:contentDescription="Down"
android:rotation="90"
android:scaleType="centerInside"
android:src="@drawable/stepforward" />
<ImageButton
android:id="@+id/btn_right"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_row="1"
android:layout_column="2"
android:layout_margin="4dp"
android:background="@drawable/btn_direction"
android:contentDescription="Right"
android:rotation="0"
android:scaleType="centerInside"
android:src="@drawable/stepforward" />
<Space
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_row="2"
android:layout_column="0" />
<Space
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_row="2"
android:layout_column="1" />
<Space
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_row="2"
android:layout_column="2" />
</GridLayout>
</LinearLayout>
</LinearLayout>
<!-- Volver --> <!-- Volver -->
<Button <Button
@@ -150,4 +194,33 @@
android:paddingHorizontal="24dp" android:paddingHorizontal="24dp"
android:paddingVertical="8dp" /> android:paddingVertical="8dp" />
<ImageView
android:id="@+id/iv_stratagem_icon"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_marginStart="53dp"
android:layout_marginTop="93dp"
android:scaleType="fitCenter"
android:src="@drawable/stratagemas_icon" />
<!-- Loading Spinner -->
<ProgressBar
android:id="@+id/progress_bar"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_centerInParent="true"
android:indeterminateTint="#FFD700"
android:visibility="gone" />
<!-- Failure Indicator (X) -->
<ImageView
android:id="@+id/iv_failure"
android:layout_width="150dp"
android:layout_height="150dp"
android:layout_centerInParent="true"
android:src="@drawable/ic_failure"
android:visibility="gone" />
</RelativeLayout> </RelativeLayout>

View File

@@ -1,87 +1,126 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:orientation="vertical" android:background="@drawable/bg_helldivers_gradient">
android:background="@drawable/bg_helldivers_gradient"
android:gravity="center_horizontal"
android:padding="16dp">
<!-- Logo Helldivers 2 - Area superior --> <!-- Logo Super Tierra - Arriba centro -->
<TextView <ImageView
android:id="@+id/logo_helldivers" android:id="@+id/logo_super_tierra"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_alignParentTop="true"
android:layout_marginTop="12dp"
android:src="@drawable/hd_logo"
android:contentDescription="Super Tierra"
android:adjustViewBounds="true"
android:maxWidth="280dp"
android:tint="#FFD700" />
<!-- Botón Estratagemas - Esquina izquierda -->
<Button
android:id="@+id/btn_minijuego"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/logo_super_tierra"
android:layout_alignParentStart="true"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp" android:layout_marginTop="16dp"
android:layout_marginBottom="24dp" android:background="@drawable/btn_helldivers_primary"
android:text="HELLDIVERS" android:paddingHorizontal="20dp"
android:textSize="36sp" android:paddingVertical="10dp"
android:textStyle="bold" android:text="ESTRATAGEMAS"
android:textAllCaps="true"
android:textColor="#FFD700" android:textColor="#FFD700"
android:fontFamily="monospace" android:textSize="14sp" />
android:shadowColor="#FF6B00"
android:shadowDx="2"
android:shadowDy="2"
android:shadowRadius="4" />
<!-- Contenedor principal de botones --> <!-- Botón QR Instagram - Esquina derecha -->
<LinearLayout <Button
android:layout_width="match_parent" android:id="@+id/btn_qr_instagram"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="horizontal"
android:gravity="center"
android:paddingHorizontal="48dp">
<!-- Boton QR Instagram -->
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btn_qr_instagram"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginEnd="32dp"
android:minHeight="72dp"
android:text="@string/btn_qr_instagram"
android:textColor="@color/helldivers_yellow"
android:textSize="18sp"
android:textAllCaps="true"
android:fontFamily="sans-serif-medium"
android:background="@drawable/btn_helldivers_primary"
android:drawableTop="@drawable/ic_qr_code"
android:paddingTop="12dp"
android:paddingBottom="12dp"
android:gravity="center" />
<!-- Boton Minijuego -->
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btn_minijuego"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginStart="32dp"
android:minHeight="72dp"
android:text="@string/btn_minijuego"
android:textColor="@color/helldivers_yellow"
android:textSize="18sp"
android:textAllCaps="true"
android:fontFamily="sans-serif-medium"
android:background="@drawable/btn_helldivers_primary"
android:drawableTop="@drawable/ic_gamepad"
android:paddingTop="12dp"
android:paddingBottom="12dp"
android:gravity="center" />
</LinearLayout>
<!-- Footer con version -->
<TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="16dp" android:layout_below="@id/logo_super_tierra"
android:text="@string/app_version" android:layout_alignParentEnd="true"
android:textColor="@color/helldivers_gray" android:layout_marginEnd="16dp"
android:textSize="12sp" android:layout_marginTop="16dp"
android:fontFamily="sans-serif-condensed" /> android:background="@drawable/btn_helldivers_primary"
android:paddingHorizontal="20dp"
android:paddingVertical="10dp"
android:text="@string/btn_qr_instagram"
android:textAllCaps="true"
android:textColor="#FFD700"
android:textSize="14sp" />
</LinearLayout> <!-- Grid de Flechas - Centro -->
<GridLayout
android:id="@+id/buttons_grid"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_marginTop="40dp"
android:rowCount="3"
android:columnCount="3"
android:padding="8dp">
<Space android:layout_width="100dp" android:layout_height="100dp" android:layout_row="0" android:layout_column="0" />
<ImageButton
android:id="@+id/btn_up"
android:layout_width="95dp"
android:layout_height="95dp"
android:layout_row="0"
android:layout_column="1"
android:background="@drawable/btn_direction"
android:contentDescription="Up"
android:rotation="-90"
android:scaleType="centerInside"
android:src="@drawable/stepforward" />
<Space android:layout_width="100dp" android:layout_height="100dp" android:layout_row="0" android:layout_column="2" />
<ImageButton
android:id="@+id/btn_left"
android:layout_width="95dp"
android:layout_height="95dp"
android:layout_row="1"
android:layout_column="0"
android:background="@drawable/btn_direction"
android:contentDescription="Left"
android:rotation="180"
android:scaleType="centerInside"
android:src="@drawable/stepforward" />
<ImageButton
android:id="@+id/btn_down"
android:layout_width="95dp"
android:layout_height="95dp"
android:layout_row="1"
android:layout_column="1"
android:background="@drawable/btn_direction"
android:contentDescription="Down"
android:rotation="90"
android:scaleType="centerInside"
android:src="@drawable/stepforward" />
<ImageButton
android:id="@+id/btn_right"
android:layout_width="95dp"
android:layout_height="95dp"
android:layout_row="1"
android:layout_column="2"
android:background="@drawable/btn_direction"
android:contentDescription="Right"
android:rotation="0"
android:scaleType="centerInside"
android:src="@drawable/stepforward" />
<Space android:layout_width="100dp" android:layout_height="20dp" android:layout_row="2" android:layout_column="0" />
<Space android:layout_width="100dp" android:layout_height="20dp" android:layout_row="2" android:layout_column="1" />
<Space android:layout_width="100dp" android:layout_height="20dp" android:layout_row="2" android:layout_column="2" />
</GridLayout>
<!-- Footer - Versión abajo centro -->
</RelativeLayout>