/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
language: "es"
});
/****
* Classes
****/
var GameButton = Container.expand(function (text, callback) {
var self = Container.call(this);
self.callback = callback;
self.isEnabled = true;
self.bg = self.attachAsset('button', {
anchorX: 0.5,
anchorY: 0.5
});
self.text = new Text2(text, {
size: 65,
fill: 0xFFFFFF
});
self.text.anchor.set(0.5, 0.5);
self.addChild(self.text);
self.setEnabled = function (enabled) {
self.isEnabled = enabled;
self.alpha = enabled ? 1.0 : 0.5;
};
self.down = function (x, y, obj) {
if (self.isEnabled && self.callback) {
self.callback();
}
};
return self;
});
var MenuBullet = Container.expand(function () {
var self = Container.call(this);
// Create bullet graphics
var bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
// Random initial properties
self.fallSpeed = 2 + Math.random() * 4; // Random fall speed between 2-6
self.rotationSpeed = (Math.random() - 0.5) * 0.2; // Random rotation speed
// Initialize position tracking
self.lastY = self.y;
self.update = function () {
// Move bullet down
self.y += self.fallSpeed;
// Rotate bullet
bulletGraphics.rotation += self.rotationSpeed;
// Check if bullet has gone off screen (transition from on-screen to off-screen)
if (self.lastY <= 2800 && self.y > 2800) {
// Reset position to top with new random x
self.y = -50;
self.x = Math.random() * 2048;
self.fallSpeed = 2 + Math.random() * 4;
self.rotationSpeed = (Math.random() - 0.5) * 0.2;
}
// Update last position
self.lastY = self.y;
};
return self;
});
var Player = Container.expand(function (playerNumber, color) {
var self = Container.call(this);
self.playerNumber = playerNumber;
self.maxHealth = 3;
self.health = self.maxHealth;
self.items = [];
self.isAlive = true;
var playerGraphics = self.attachAsset(playerNumber === 1 ? 'player1' : 'player2', {
anchorX: 0.5,
anchorY: 0.5
});
var healthBarBg = self.attachAsset('healthBar', {
anchorX: 0.5,
anchorY: 0.5,
y: -150,
tint: 0x660000
});
self.healthBar = self.attachAsset('healthBar', {
anchorX: 0.5,
anchorY: 0.5,
y: -150
});
self.nameText = new Text2('Jugador ' + playerNumber, {
size: 40,
fill: 0xFFFFFF
});
self.nameText.anchor.set(0.5, 0.5);
self.nameText.y = -200;
self.addChild(self.nameText);
self.healthText = new Text2(self.health + '/' + self.maxHealth, {
size: 30,
fill: 0xFFFFFF
});
self.healthText.anchor.set(0.5, 0.5);
self.healthText.y = -120;
self.addChild(self.healthText);
self.updateHealth = function () {
var healthPercent = self.health / self.maxHealth;
self.healthBar.scaleX = healthPercent;
self.healthText.setText(self.health + '/' + self.maxHealth);
if (self.health <= 0) {
self.isAlive = false;
self.alpha = 0.5;
}
};
self.takeDamage = function () {
self.health = Math.max(0, self.health - 1);
self.updateHealth();
// Fall animation - rotate and move down
tween(self, {
rotation: Math.PI / 6,
// Fall to the side
y: self.y + 50,
// Move down slightly
tint: 0xFF0000
}, {
duration: 400,
easing: tween.easeOut,
onFinish: function onFinish() {
// Get up animation - return to normal position
tween(self, {
rotation: 0,
// Return to upright
y: self.y - 50,
// Return to original position
tint: 0xFFFFFF
}, {
duration: 600,
easing: tween.easeInOut
});
}
});
};
self.heal = function () {
self.health = Math.min(self.maxHealth, self.health + 1);
self.updateHealth();
// Flash green
tween(self, {
tint: 0x00FF00
}, {
duration: 200,
onFinish: function onFinish() {
tween(self, {
tint: 0xFFFFFF
}, {
duration: 200
});
}
});
};
return self;
});
var Revolver = Container.expand(function () {
var self = Container.call(this);
self.chambers = [];
self.currentChamber = 0;
self.totalChambers = 6;
self.isRevealed = false;
var revolverGraphics = self.attachAsset('revolver', {
anchorX: 0.5,
anchorY: 0.5
});
self.chamberIndicators = [];
for (var i = 0; i < self.totalChambers; i++) {
var indicator = self.attachAsset('blank', {
anchorX: 0.5,
anchorY: 0.5,
x: (i - 2.5) * 50,
y: -120
});
self.chamberIndicators.push(indicator);
}
self.loadChambers = function (liveRounds, blanks) {
self.chambers = [];
self.currentChamber = 0;
// Add live rounds
for (var i = 0; i < liveRounds; i++) {
self.chambers.push(true);
}
// Add blanks
for (var i = 0; i < blanks; i++) {
self.chambers.push(false);
}
// Shuffle chambers
for (var i = self.chambers.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var temp = self.chambers[i];
self.chambers[i] = self.chambers[j];
self.chambers[j] = temp;
}
self.updateDisplay();
};
self.updateDisplay = function () {
for (var i = 0; i < self.totalChambers; i++) {
if (i < self.chambers.length) {
if (self.isRevealed || i < self.currentChamber) {
if (i < self.chambers.length && self.chambers[i]) {
self.chamberIndicators[i].tint = 0xFFD700; // Gold for live
} else {
self.chamberIndicators[i].tint = 0x888888; // Gray for blank
}
} else {
self.chamberIndicators[i].tint = 0x444444; // Dark for unknown
}
if (i === self.currentChamber) {
self.chamberIndicators[i].scaleX = 1.5;
self.chamberIndicators[i].scaleY = 1.5;
} else {
self.chamberIndicators[i].scaleX = 1;
self.chamberIndicators[i].scaleY = 1;
}
} else {
self.chamberIndicators[i].tint = 0x222222; // Very dark for empty
self.chamberIndicators[i].scaleX = 1;
self.chamberIndicators[i].scaleY = 1;
}
}
};
self.fire = function () {
if (self.currentChamber >= self.chambers.length) {
return null; // Empty chamber
}
var isLive = self.chambers[self.currentChamber];
self.currentChamber++;
self.updateDisplay();
// Animate rotation
tween(revolverGraphics, {
rotation: revolverGraphics.rotation + Math.PI / 3
}, {
duration: 300,
easing: tween.easeOut
});
return isLive;
};
self.peekNext = function () {
if (self.currentChamber >= self.chambers.length) {
return null;
}
return self.chambers[self.currentChamber];
};
self.getRemainingRounds = function () {
var live = 0;
var blank = 0;
for (var i = self.currentChamber; i < self.chambers.length; i++) {
if (self.chambers[i]) {
live++;
} else {
blank++;
}
}
return {
live: live,
blank: blank
};
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x1a1a1a
});
/****
* Game Code
****/
// Game state
var currentPlayer = 1;
var gamePhase = 'languageSelection'; // languageSelection, menu, setup, playing, gameover, difficulty
var gameMode = 'pvp'; // pvp, ai, 3vs
var aiDifficulty = 'medium'; // easy, medium, hard
var round = 1;
var player1, player2, player3, revolver;
var buttons = [];
var infoText, roundText, turnText;
var playButton, playAIButton;
var difficultyButtons = [];
var menuBullets = [];
var languageSelectionBullets = [];
var languageButtons = [];
var isLanguageSelectionOpen = true;
// Dialogue system variables
var dialogueBox = null;
var dialogueText = null;
var isDialogueActive = false;
var currentDialogueStep = 0;
var dialogueSequence = [];
// Language system
var currentLanguage = storage.language || 'es';
var currentSkin = storage.selectedSkin || 'revolver';
var skinButtons = [];
var isSkinsOpen = false;
var skinsPanel = null;
var availableSkins = ['shotgun', 'pistol', 'revolver'];
var skinNames = {
'revolver': 'Revólver Clásico',
'pistol': 'Pistola Moderna',
'shotgun': 'Escopeta'
};
var availableLanguages = ['es', 'en', 'it', 'pt', 'ru', 'ar', 'pe', 'ja', 'zh'];
var currentLanguageNames = {
'es': 'ESPAÑOL',
'en': 'ENGLISH',
'it': 'ITALIANO',
'pt': 'PORTUGUÊS',
'ru': 'РУССКИЙ',
'ar': 'ARGENTINO',
'pe': 'PERUANO',
'ja': '日本語',
'zh': '中文'
};
// IA Player sprite
var iaPlayerSprite = new Text2('IA PLAYER', {
size: 48,
fill: 0xFF6600
});
iaPlayerSprite.anchor.set(0.5, 0.5);
iaPlayerSprite.x = 1024;
iaPlayerSprite.y = 300;
iaPlayerSprite.visible = false;
game.addChild(iaPlayerSprite);
var texts = {
es: {
player: 'Jugador',
ai: 'IA',
round: 'Ronda',
turn: 'Turno del',
chooseAction: 'Elige tu acción',
playTwoPlayers: 'JUGAR (2 JUGADORES)',
playAgainstAI: 'JUGAR CONTRA IA',
settings: 'AJUSTES',
shootOpponent: 'Disparar al Oponente',
shootSelf: 'Dispararse a Sí Mismo',
welcome: '¡Bienvenido al Duelo de Ruleta Rusa!',
dialogueP1Start: '¡Es hora del duelo, Jugador 2!',
dialogueP2Start: '¡Estoy listo! ¡Que comience la batalla!',
dialogueP1Confident: '¡Esta vez voy a ganar!',
dialogueP2Determined: '¡Ya veremos quién es el mejor!',
aiWelcome: 'Bienvenido a la ruleta rusa, soy el jefe de la organización de dealers',
magnifyingGlass: 'Ver próxima bala',
handcuffs: 'Saltar turno del oponente',
cigarettes: 'Restaurar 1 de salud',
chamberEmpty: 'La recámara está vacía',
nextBullet: 'La próxima bala es:',
real: 'REAL',
blank: 'DE FOGUEO',
opponentSkip: 'El oponente saltará su próximo turno',
healthRestored: 'Salud restaurada',
bang: '¡BANG!',
opponentHit: '¡Oponente impactado!',
click: '*Clic*',
blankRound: 'Bala de fogueo',
emptyChamer: 'Recámara vacía',
shotSelf: '¡Te disparaste a ti mismo!',
blankContinue: '¡De fogueo! Continúa tu turno',
handcuffsUsed: 'Esposas usadas - el oponente salta su turno',
revolverEmpty: 'Revólver vacío - Nueva ronda comenzando...',
remaining: 'restantes',
aiShootSelf: 'IA decide dispararse a sí misma...',
aiShootOpponent: 'IA decide disparar al oponente...',
wins: 'Gana!',
gameOver: 'Juego Terminado',
sound: 'SONIDO',
music: 'MÚSICA',
close: 'CERRAR',
language: 'IDIOMA',
on: 'ON',
off: 'OFF',
spanish: 'ESPAÑOL',
english: 'INGLÉS',
italian: 'ITALIANO',
portuguese: 'PORTUGUÉS',
russian: 'RUSO',
argentine: 'ARGENTINO',
peruvian: 'PERUANO',
japanese: 'JAPONÉS',
chinese: 'CHINO',
instructions: 'INSTRUCCIONES',
howToPlay: 'CÓMO JUGAR:',
rule1: '1. Cada jugador tiene 3 puntos de vida',
rule2: '2. El revólver contiene balas reales y de fogueo',
rule3: '3. En tu turno puedes:',
rule4: ' - Disparar al oponente',
rule5: ' - Dispararte a ti mismo',
rule6: '4. Si te disparas con bala de fogueo, continúas',
rule7: '5. Si te disparas con bala real, pierdes vida',
rule8: '6. Usa objetos para obtener ventajas',
rule9: '7. Gana el último jugador vivo',
rule10: '8. Estrategia: La lupa revela la próxima bala',
rule11: '9. Las esposas hacen que el rival pierda un turno',
rule12: '10. Los cigarrillos restauran 1 punto de vida',
rule13: '11. Observa las balas disparadas para calcular odds',
rule14: '12. Cada ronda aumenta la dificultad',
exit: 'SALIR',
selectDifficulty: 'SELECCIONA DIFICULTAD',
easy: 'FÁCIL',
medium: 'MEDIO',
hard: 'DIFÍCIL',
skins: 'SKINS DE ESCOPETA',
back: 'VOLVER',
normalMode: 'MODO NORMAL'
},
en: {
player: 'Player',
ai: 'AI',
round: 'Round',
turn: 'Turn of',
chooseAction: 'Choose your action',
playTwoPlayers: 'PLAY (2 PLAYERS)',
playAgainstAI: 'PLAY AGAINST AI',
settings: 'SETTINGS',
shootOpponent: 'Shoot Opponent',
shootSelf: 'Shoot Self',
welcome: 'Welcome to Russian Roulette Duel!',
dialogueP1Start: 'It\'s time for the duel, Player 2!',
dialogueP2Start: 'I\'m ready! Let the battle begin!',
dialogueP1Confident: 'This time I\'m going to win!',
dialogueP2Determined: 'We\'ll see who\'s the best!',
aiWelcome: 'Welcome to Russian roulette, I am the head of the dealers organization',
magnifyingGlass: 'See next bullet',
handcuffs: 'Skip opponent turn',
cigarettes: 'Restore 1 health',
chamberEmpty: 'Chamber is empty',
nextBullet: 'Next bullet is:',
real: 'LIVE',
blank: 'BLANK',
opponentSkip: 'Opponent will skip their next turn',
healthRestored: 'Health restored',
bang: 'BANG!',
opponentHit: 'Opponent hit!',
click: '*Click*',
blankRound: 'Blank round',
emptyChamer: 'Empty chamber',
shotSelf: 'You shot yourself!',
blankContinue: 'Blank! Continue your turn',
handcuffsUsed: 'Handcuffs used - opponent skips turn',
revolverEmpty: 'Revolver empty - New round starting...',
remaining: 'remaining',
aiShootSelf: 'AI decides to shoot itself...',
aiShootOpponent: 'AI decides to shoot opponent...',
wins: 'Wins!',
gameOver: 'Game Over',
sound: 'SOUND',
music: 'MUSIC',
close: 'CLOSE',
language: 'LANGUAGE',
on: 'ON',
off: 'OFF',
spanish: 'SPANISH',
english: 'ENGLISH',
italian: 'ITALIAN',
portuguese: 'PORTUGUESE',
russian: 'RUSSIAN',
argentine: 'ARGENTINE',
peruvian: 'PERUVIAN',
japanese: 'JAPANESE',
chinese: 'CHINESE',
instructions: 'INSTRUCTIONS',
howToPlay: 'HOW TO PLAY:',
rule1: '1. Each player has 3 health points',
rule2: '2. The revolver contains live and blank rounds',
rule3: '3. On your turn you can:',
rule4: ' - Shoot the opponent',
rule5: ' - Shoot yourself',
rule6: '4. If you shoot yourself with blank, continue',
rule7: '5. If you shoot yourself with live, lose health',
rule8: '6. Use items to gain advantages',
rule9: '7. Last player alive wins',
rule10: '8. Strategy: Magnifying glass reveals next bullet',
rule11: '9. Handcuffs make opponent skip their turn',
rule12: '10. Cigarettes restore 1 health point',
rule13: '11. Track fired bullets to calculate odds',
rule14: '12. Each round increases difficulty',
exit: 'EXIT',
selectDifficulty: 'SELECT DIFFICULTY',
easy: 'EASY',
medium: 'MEDIUM',
hard: 'HARD',
skins: 'SHOTGUN SKINS',
back: 'BACK',
normalMode: 'NORMAL MODE'
},
it: {
player: 'Giocatore',
ai: 'IA',
round: 'Round',
turn: 'Turno di',
chooseAction: 'Scegli la tua azione',
playTwoPlayers: 'GIOCA (2 GIOCATORI)',
playAgainstAI: 'GIOCA CONTRO IA',
settings: 'IMPOSTAZIONI',
shootOpponent: 'Spara all\'Avversario',
shootSelf: 'Sparati',
welcome: 'Benvenuto al Duello di Roulette Russa!',
dialogueP1Start: 'È ora del duello, Giocatore 2!',
dialogueP2Start: 'Sono pronto! Che la battaglia abbia inizio!',
dialogueP1Confident: 'Questa volta vincerò io!',
dialogueP2Determined: 'Vedremo chi è il migliore!',
aiWelcome: 'Benvenuto alla roulette russa, sono il capo dell\'organizzazione dei dealers',
magnifyingGlass: 'Vedi prossimo proiettile',
handcuffs: 'Salta turno avversario',
cigarettes: 'Ripristina 1 salute',
chamberEmpty: 'La camera è vuota',
nextBullet: 'Il prossimo proiettile è:',
real: 'VERO',
blank: 'A SALVE',
opponentSkip: 'L\'avversario salterà il suo prossimo turno',
healthRestored: 'Salute ripristinata',
bang: 'BANG!',
opponentHit: 'Avversario colpito!',
click: '*Click*',
blankRound: 'Colpo a salve',
emptyChamer: 'Camera vuota',
shotSelf: 'Ti sei sparato!',
blankContinue: 'A salve! Continua il tuo turno',
handcuffsUsed: 'Manette usate - l\'avversario salta il turno',
revolverEmpty: 'Revolver vuoto - Inizia nuovo round...',
remaining: 'rimanenti',
aiShootSelf: 'IA decide di spararsi...',
aiShootOpponent: 'IA decide di sparare all\'avversario...',
wins: 'Vince!',
gameOver: 'Gioco Finito',
sound: 'SUONO',
music: 'MUSICA',
close: 'CHIUDI',
language: 'LINGUA',
on: 'ON',
off: 'OFF',
spanish: 'SPAGNOLO',
english: 'INGLESE',
italian: 'ITALIANO',
portuguese: 'PORTOGHESE',
russian: 'RUSSO',
argentine: 'ARGENTINO',
peruvian: 'PERUVIANO',
japanese: 'GIAPPONESE',
chinese: 'CINESE',
instructions: 'ISTRUZIONI',
howToPlay: 'COME GIOCARE:',
rule1: '1. Ogni giocatore ha 3 punti salute',
rule2: '2. Il revolver contiene proiettili veri e a salve',
rule3: '3. Nel tuo turno puoi:',
rule4: ' - Sparare all\'avversario',
rule5: ' - Spararti',
rule6: '4. Se ti spari con salve, continui',
rule7: '5. Se ti spari con vero, perdi salute',
rule8: '6. Usa oggetti per vantaggi',
rule9: '7. Vince l\'ultimo giocatore vivo',
rule10: '8. Strategia: La lente rivela il prossimo proiettile',
rule11: '9. Le manette fanno saltare il turno all\'avversario',
rule12: '10. Le sigarette ripristinano 1 punto salute',
rule13: '11. Tieni traccia dei proiettili sparati per calcolare le probabilità',
rule14: '12. Ogni round aumenta la difficoltà',
exit: 'ESCI',
selectDifficulty: 'SELEZIONA DIFFICOLTÀ',
easy: 'FACILE',
medium: 'MEDIO',
hard: 'DIFFICILE',
skins: 'SKIN FUCILE',
back: 'INDIETRO',
normalMode: 'MODALITÀ NORMALE'
},
pt: {
player: 'Jogador',
ai: 'IA',
round: 'Rodada',
turn: 'Turno do',
chooseAction: 'Escolha sua ação',
playTwoPlayers: 'JOGAR (2 JOGADORES)',
playAgainstAI: 'JOGAR CONTRA IA',
settings: 'CONFIGURAÇÕES',
shootOpponent: 'Atirar no Oponente',
shootSelf: 'Atirar em Si Mesmo',
welcome: 'Bem-vindo ao Duelo de Roleta Russa!',
dialogueP1Start: 'É hora do duelo, Jogador 2!',
dialogueP2Start: 'Estou pronto! Que a batalha comece!',
dialogueP1Confident: 'Desta vez eu vou ganhar!',
dialogueP2Determined: 'Vamos ver quem é o melhor!',
aiWelcome: 'Bem-vindo à roleta russa, sou o chefe da organização de dealers',
magnifyingGlass: 'Ver próxima bala',
handcuffs: 'Pular turno do oponente',
cigarettes: 'Restaurar 1 de saúde',
chamberEmpty: 'A câmara está vazia',
nextBullet: 'A próxima bala é:',
real: 'REAL',
blank: 'DE FESTIM',
opponentSkip: 'O oponente pulará seu próximo turno',
healthRestored: 'Saúde restaurada',
bang: 'BANG!',
opponentHit: 'Oponente atingido!',
click: '*Clique*',
blankRound: 'Tiro de festim',
emptyChamer: 'Câmara vazia',
shotSelf: 'Você atirou em si mesmo!',
blankContinue: 'De festim! Continue seu turno',
handcuffsUsed: 'Algemas usadas - oponente pula turno',
revolverEmpty: 'Revólver vazio - Nova rodada começando...',
remaining: 'restantes',
aiShootSelf: 'IA decide atirar em si mesma...',
aiShootOpponent: 'IA decide atirar no oponente...',
wins: 'Vence!',
gameOver: 'Fim de Jogo',
sound: 'SOM',
music: 'MÚSICA',
close: 'FECHAR',
language: 'IDIOMA',
on: 'LIGADO',
off: 'DESLIGADO',
spanish: 'ESPANHOL',
english: 'INGLÊS',
italian: 'ITALIANO',
portuguese: 'PORTUGUÊS',
russian: 'RUSSO',
argentine: 'ARGENTINO',
peruvian: 'PERUANO',
japanese: 'JAPONÊS',
chinese: 'CHINÊS',
instructions: 'INSTRUÇÕES',
howToPlay: 'COMO JOGAR:',
rule1: '1. Cada jogador tem 3 pontos de vida',
rule2: '2. O revólver contém balas reais e de festim',
rule3: '3. No seu turno você pode:',
rule4: ' - Atirar no oponente',
rule5: ' - Atirar em si mesmo',
rule6: '4. Se atirar em si com festim, continue',
rule7: '5. Se atirar em si com real, perde vida',
rule8: '6. Use itens para vantagens',
rule9: '7. Último jogador vivo ganha',
rule10: '8. Estratégia: A lupa revela a próxima bala',
rule11: '9. As algemas fazem o oponente pular o turno',
rule12: '10. Os cigarros restauram 1 ponto de vida',
rule13: '11. Acompanhe as balas disparadas para calcular probabilidades',
rule14: '12. Cada rodada aumenta a dificuldade',
exit: 'SAIR',
selectDifficulty: 'SELECIONAR DIFICULDADE',
easy: 'FÁCIL',
medium: 'MÉDIO',
hard: 'DIFÍCIL',
skins: 'SKINS ESPINGARDA',
back: 'VOLTAR',
normalMode: 'MODO NORMAL'
},
ru: {
player: 'Игрок',
ai: 'ИИ',
round: 'Раунд',
turn: 'Ход игрока',
chooseAction: 'Выберите действие',
playTwoPlayers: 'ИГРАТЬ (2 ИГРОКА)',
playAgainstAI: 'ИГРАТЬ ПРОТИВ ИИ',
settings: 'НАСТРОЙКИ',
shootOpponent: 'Стрелять в противника',
shootSelf: 'Стрелять в себя',
welcome: 'Добро пожаловать в дуэль русской рулетки!',
dialogueP1Start: 'Время дуэли, Игрок 2!',
dialogueP2Start: 'Я готов! Пусть битва начнется!',
dialogueP1Confident: 'На этот раз я выиграю!',
dialogueP2Determined: 'Посмотрим, кто лучший!',
aiWelcome: 'Добро пожаловать в русскую рулетку, я глава организации дилеров',
magnifyingGlass: 'Посмотреть следующую пулю',
handcuffs: 'Пропустить ход противника',
cigarettes: 'Восстановить 1 здоровье',
chamberEmpty: 'Камера пуста',
nextBullet: 'Следующая пуля:',
real: 'БОЕВАЯ',
blank: 'ХОЛОСТАЯ',
opponentSkip: 'Противник пропустит следующий ход',
healthRestored: 'Здоровье восстановлено',
bang: 'БАМ!',
opponentHit: 'Противник ранен!',
click: '*Щелчок*',
blankRound: 'Холостой патрон',
emptyChamer: 'Пустая камера',
shotSelf: 'Вы выстрелили в себя!',
blankContinue: 'Холостой! Продолжайте ход',
handcuffsUsed: 'Наручники использованы - противник пропускает ход',
revolverEmpty: 'Револьвер пуст - Начинается новый раунд...',
remaining: 'осталось',
aiShootSelf: 'ИИ решил выстрелить в себя...',
aiShootOpponent: 'ИИ решил выстрелить в противника...',
wins: 'Побеждает!',
gameOver: 'Игра окончена',
sound: 'ЗВУК',
music: 'МУЗЫКА',
close: 'ЗАКРЫТЬ',
language: 'ЯЗЫК',
on: 'ВКЛ',
off: 'ВЫКЛ',
spanish: 'ИСПАНСКИЙ',
english: 'АНГЛИЙСКИЙ',
italian: 'ИТАЛЬЯНСКИЙ',
portuguese: 'ПОРТУГАЛЬСКИЙ',
russian: 'РУССКИЙ',
argentine: 'АРГЕНТИНСКИЙ',
peruvian: 'ПЕРУАНСКИЙ',
japanese: 'ЯПОНСКИЙ',
chinese: 'КИТАЙСКИЙ',
instructions: 'ИНСТРУКЦИИ',
howToPlay: 'КАК ИГРАТЬ:',
rule1: '1. У каждого игрока 3 очка здоровья',
rule2: '2. Револьвер содержит боевые и холостые патроны',
rule3: '3. В свой ход вы можете:',
rule4: ' - Выстрелить в противника',
rule5: ' - Выстрелить в себя',
rule6: '4. Если стреляете в себя холостым, продолжайте',
rule7: '5. Если стреляете в себя боевым, теряете здоровье',
rule8: '6. Используйте предметы для преимуществ',
rule9: '7. Побеждает последний живой игрок',
rule10: '8. Стратегия: Лупа показывает следующую пулю',
rule11: '9. Наручники заставляют противника пропустить ход',
rule12: '10. Сигареты восстанавливают 1 очко здоровья',
rule13: '11. Отслеживайте выстреленные пули для расчета вероятности',
rule14: '12. Каждый раунд увеличивает сложность',
exit: 'ВЫХОД',
selectDifficulty: 'ВЫБЕРИТЕ СЛОЖНОСТЬ',
easy: 'ЛЕГКО',
medium: 'СРЕДНЕ',
hard: 'СЛОЖНО',
skins: 'СКИНЫ РУЖЬЯ',
back: 'НАЗАД',
normalMode: 'ОБЫЧНЫЙ РЕЖИМ'
},
ar: {
player: 'Jugador',
ai: 'IA',
round: 'Ronda',
turn: 'Turno del',
chooseAction: 'Elegí tu acción',
playTwoPlayers: 'JUGAR (2 JUGADORES)',
playAgainstAI: 'JUGAR CONTRA IA',
settings: 'CONFIGURACIÓN',
shootOpponent: 'Disparar al Rival',
shootSelf: 'Dispararte a Vos Mismo',
welcome: '¡Bienvenido al Duelo de Ruleta Rusa!',
dialogueP1Start: '¡Es hora del duelo, Jugador 2!',
dialogueP2Start: '¡Estoy listo! ¡Que arranque la batalla!',
dialogueP1Confident: '¡Esta vez la voy a ganar!',
dialogueP2Determined: '¡Ya vamos a ver quién es el mejor!',
aiWelcome: 'Bienvenido a la ruleta rusa, soy el jefe de la organización de dealers',
magnifyingGlass: 'Ver próxima bala',
handcuffs: 'Saltear turno del rival',
cigarettes: 'Restaurar 1 de salud',
chamberEmpty: 'La recámara está vacía',
nextBullet: 'La próxima bala es:',
real: 'REAL',
blank: 'DE FOGUEO',
opponentSkip: 'El rival va a saltear su próximo turno',
healthRestored: 'Salud restaurada',
bang: '¡BANG!',
opponentHit: '¡Rival impactado!',
click: '*Clic*',
blankRound: 'Bala de fogueo',
emptyChamer: 'Recámara vacía',
shotSelf: '¡Te disparaste a vos mismo!',
blankContinue: '¡De fogueo! Seguí tu turno',
handcuffsUsed: 'Esposas usadas - el rival saltea su turno',
revolverEmpty: 'Revólver vacío - Nueva ronda empezando...',
remaining: 'restantes',
aiShootSelf: 'IA decide dispararse a sí misma...',
aiShootOpponent: 'IA decide disparar al rival...',
wins: '¡Gana!',
gameOver: 'Juego Terminado',
sound: 'SONIDO',
music: 'MÚSICA',
close: 'CERRAR',
language: 'IDIOMA',
on: 'PRENDIDO',
off: 'APAGADO',
spanish: 'ESPAÑOL',
english: 'INGLÉS',
italian: 'ITALIANO',
portuguese: 'PORTUGUÉS',
russian: 'RUSO',
argentine: 'ARGENTINO',
peruvian: 'PERUANO',
japanese: 'JAPONÉS',
chinese: 'CHINO',
instructions: 'INSTRUCCIONES',
howToPlay: 'CÓMO JUGAR:',
rule1: '1. Cada jugador tiene 3 puntos de vida',
rule2: '2. El revólver contiene balas reales y de fogueo',
rule3: '3. En tu turno podés:',
rule4: ' - Disparar al rival',
rule5: ' - Dispararte a vos mismo',
rule6: '4. Si te disparás con bala de fogueo, seguís',
rule7: '5. Si te disparás con bala real, perdés vida',
rule8: '6. Usá objetos para obtener ventajas',
rule9: '7. Gana el último jugador vivo',
rule10: '8. Estrategia: La lupa revela la próxima bala',
rule11: '9. Las esposas hacen que el rival pierda un turno',
rule12: '10. Los cigarrillos restauran 1 punto de vida',
rule13: '11. Fijate en las balas disparadas para calcular chances',
rule14: '12. Cada ronda aumenta la dificultad',
exit: 'SALIR',
selectDifficulty: 'ELEGÍ DIFICULTAD',
easy: 'FÁCIL',
medium: 'MEDIO',
hard: 'DIFÍCIL',
skins: 'SKINS DE ESCOPETA',
back: 'VOLVER',
normalMode: 'MODO NORMAL'
},
pe: {
player: 'Jugador',
ai: 'IA',
round: 'Ronda',
turn: 'Turno del',
chooseAction: 'Elige tu acción pe',
playTwoPlayers: 'JUGAR (2 JUGADORES)',
playAgainstAI: 'JUGAR CONTRA IA',
settings: 'AJUSTES',
shootOpponent: 'Disparar al Rival',
shootSelf: 'Dispararte a Ti Mismo',
welcome: '¡Bienvenido al Duelo de Ruleta Rusa, causa!',
dialogueP1Start: '¡Es hora del duelo, Jugador 2, causa!',
dialogueP2Start: '¡Estoy listo, pe! ¡Que empiece la batalla!',
dialogueP1Confident: '¡Esta vez voy a ganar, causa!',
dialogueP2Determined: '¡Ya veremos quién es el mejor, pe!',
aiWelcome: 'Bienvenido a la ruleta rusa, causa, soy el jefe de la organización de dealers',
magnifyingGlass: 'Ver próxima bala',
handcuffs: 'Saltar turno del rival',
cigarettes: 'Restaurar 1 de salud',
chamberEmpty: 'La recámara está vacía',
nextBullet: 'La próxima bala es:',
real: 'REAL',
blank: 'DE FOGUEO',
opponentSkip: 'El rival saltará su próximo turno',
healthRestored: 'Salud restaurada',
bang: '¡BANG!',
opponentHit: '¡Rival impactado!',
click: '*Clic*',
blankRound: 'Bala de fogueo',
emptyChamer: 'Recámara vacía',
shotSelf: '¡Te disparaste a ti mismo, causa!',
blankContinue: '¡De fogueo! Continúa tu turno',
handcuffsUsed: 'Esposas usadas - el rival salta su turno',
revolverEmpty: 'Revólver vacío - Nueva ronda comenzando...',
remaining: 'restantes',
aiShootSelf: 'IA decide dispararse a sí misma...',
aiShootOpponent: 'IA decide disparar al rival...',
wins: '¡Gana!',
gameOver: 'Juego Terminado',
sound: 'SONIDO',
music: 'MÚSICA',
close: 'CERRAR',
language: 'IDIOMA',
on: 'PRENDIDO',
off: 'APAGADO',
spanish: 'ESPAÑOL',
english: 'INGLÉS',
italian: 'ITALIANO',
portuguese: 'PORTUGUÉS',
russian: 'RUSO',
argentine: 'ARGENTINO',
peruvian: 'PERUANO',
japanese: 'JAPONÉS',
chinese: 'CHINO',
instructions: 'INSTRUCCIONES',
howToPlay: 'CÓMO JUGAR:',
rule1: '1. Cada jugador tiene 3 puntos de vida',
rule2: '2. El revólver contiene balas reales y de fogueo',
rule3: '3. En tu turno puedes:',
rule4: ' - Disparar al rival',
rule5: ' - Dispararte a ti mismo',
rule6: '4. Si te disparas con bala de fogueo, continúas',
rule7: '5. Si te disparas con bala real, pierdes vida',
rule8: '6. Usa objetos para obtener ventajas, causa',
rule9: '7. Gana el último jugador vivo',
rule10: '8. Estrategia: La lupa revela la próxima bala, causa',
rule11: '9. Las esposas hacen que el rival pierda un turno',
rule12: '10. Los cigarrillos restauran 1 punto de vida',
rule13: '11. Observa las balas disparadas para calcular probabilidades',
rule14: '12. Cada ronda aumenta la dificultad, causa',
exit: 'SALIR',
selectDifficulty: 'ELIGE DIFICULTAD',
easy: 'FÁCIL',
medium: 'MEDIO',
hard: 'DIFÍCIL',
skins: 'SKINS DE ESCOPETA',
back: 'VOLVER',
normalMode: 'MODO NORMAL'
},
ja: {
player: 'プレイヤー',
ai: 'AI',
round: 'ラウンド',
turn: 'ターン',
chooseAction: 'アクションを選択してください',
playTwoPlayers: 'プレイ(2プレイヤー)',
playAgainstAI: 'AIと対戦',
settings: '設定',
shootOpponent: '相手を撃つ',
shootSelf: '自分を撃つ',
welcome: 'ロシアンルーレット決闘へようこそ!',
dialogueP1Start: '決闘の時間だ、プレイヤー2!',
dialogueP2Start: '準備はできた!戦いを始めよう!',
dialogueP1Confident: '今回は俺が勝つ!',
dialogueP2Determined: '誰が最強か見てやる!',
aiWelcome: 'ロシアンルーレットへようこそ、私はディーラー組織のボスです',
magnifyingGlass: '次の弾を見る',
handcuffs: '相手のターンをスキップ',
cigarettes: '体力を1回復',
chamberEmpty: 'チャンバーが空です',
nextBullet: '次の弾は:',
real: '実弾',
blank: '空砲',
opponentSkip: '相手は次のターンをスキップします',
healthRestored: '体力が回復しました',
bang: 'バン!',
opponentHit: '相手にヒット!',
click: '*カチッ*',
blankRound: '空砲',
emptyChamer: '空のチャンバー',
shotSelf: '自分を撃ちました!',
blankContinue: '空砲!ターンを続けてください',
handcuffsUsed: '手錠使用 - 相手はターンをスキップ',
revolverEmpty: 'リボルバーが空 - 新しいラウンドを開始...',
remaining: '残り',
aiShootSelf: 'AIは自分を撃つことを決定...',
aiShootOpponent: 'AIは相手を撃つことを決定...',
wins: '勝利!',
gameOver: 'ゲーム終了',
sound: 'サウンド',
music: '音楽',
close: '閉じる',
language: '言語',
on: 'オン',
off: 'オフ',
spanish: 'スペイン語',
english: '英語',
italian: 'イタリア語',
portuguese: 'ポルトガル語',
russian: 'ロシア語',
argentine: 'アルゼンチン語',
peruvian: 'ペルー語',
japanese: '日本語',
chinese: '中国語',
instructions: '説明書',
howToPlay: '遊び方:',
rule1: '1. 各プレイヤーは3つの体力ポイントを持っています',
rule2: '2. リボルバーには実弾と空砲が入っています',
rule3: '3. あなたのターンでできること:',
rule4: ' - 相手を撃つ',
rule5: ' - 自分を撃つ',
rule6: '4. 空砲で自分を撃った場合、続行',
rule7: '5. 実弾で自分を撃った場合、体力を失う',
rule8: '6. アイテムを使って有利になる',
rule9: '7. 最後に生き残ったプレイヤーが勝利',
rule10: '8. 戦略:虫眼鏡で次の弾を確認',
rule11: '9. 手錠で相手のターンをスキップ',
rule12: '10. タバコで体力を1回復',
rule13: '11. 発射された弾を追跡して確率を計算',
rule14: '12. 各ラウンドで難易度が上がります',
exit: '終了',
selectDifficulty: '難易度を選択',
easy: '簡単',
medium: '普通',
hard: '難しい',
skins: 'ショットガンスキン',
back: '戻る',
normalMode: '通常モード'
},
zh: {
player: '玩家',
ai: 'AI',
round: '回合',
turn: '轮到',
chooseAction: '选择你的行动',
playTwoPlayers: '开始游戏(2玩家)',
playAgainstAI: '对战AI',
settings: '设置',
shootOpponent: '射击对手',
shootSelf: '射击自己',
welcome: '欢迎来到俄罗斯轮盘决斗!',
dialogueP1Start: '决斗时间到了,玩家2!',
dialogueP2Start: '我准备好了!让战斗开始吧!',
dialogueP1Confident: '这次我要赢!',
dialogueP2Determined: '我们来看看谁是最强的!',
aiWelcome: '欢迎来到俄罗斯轮盘,我是庄家组织的头目',
magnifyingGlass: '查看下一发子弹',
handcuffs: '跳过对手回合',
cigarettes: '恢复1点生命',
chamberEmpty: '弹膛为空',
nextBullet: '下一发子弹是:',
real: '实弹',
blank: '空弹',
opponentSkip: '对手将跳过下一回合',
healthRestored: '生命已恢复',
bang: '砰!',
opponentHit: '击中对手!',
click: '*咔嗒*',
blankRound: '空弹',
emptyChamer: '空弹膛',
shotSelf: '你射击了自己!',
blankContinue: '空弹!继续你的回合',
handcuffsUsed: '手铐已使用 - 对手跳过回合',
revolverEmpty: '左轮手枪为空 - 开始新回合...',
remaining: '剩余',
aiShootSelf: 'AI决定射击自己...',
aiShootOpponent: 'AI决定射击对手...',
wins: '获胜!',
gameOver: '游戏结束',
sound: '声音',
music: '音乐',
close: '关闭',
language: '语言',
on: '开',
off: '关',
spanish: '西班牙语',
english: '英语',
italian: '意大利语',
portuguese: '葡萄牙语',
russian: '俄语',
argentine: '阿根廷语',
peruvian: '秘鲁语',
japanese: '日语',
chinese: '中文',
instructions: '说明',
howToPlay: '游戏玩法:',
rule1: '1. 每个玩家有3点生命值',
rule2: '2. 左轮手枪装有实弹和空弹',
rule3: '3. 在你的回合你可以:',
rule4: ' - 射击对手',
rule5: ' - 射击自己',
rule6: '4. 如果用空弹射击自己,继续游戏',
rule7: '5. 如果用实弹射击自己,失去生命',
rule8: '6. 使用道具获得优势',
rule9: '7. 最后存活的玩家获胜',
rule10: '8. 策略:放大镜显示下一发子弹',
rule11: '9. 手铐让对手跳过回合',
rule12: '10. 香烟恢复1点生命值',
rule13: '11. 追踪已射击的子弹来计算概率',
rule14: '12. 每轮难度递增',
exit: '退出',
selectDifficulty: '选择难度',
easy: '简单',
medium: '中等',
hard: '困难',
skins: '霰弹枪皮肤',
back: '返回',
normalMode: '普通模式'
}
};
function getText(key) {
return texts[currentLanguage][key] || key;
}
function changeLanguage(newLanguage) {
currentLanguage = newLanguage;
storage.language = newLanguage;
updateAllTexts();
}
function updateAllTexts() {
// Update UI texts
if (roundText) roundText.setText(getText('round') + ' ' + round);
if (turnText) {
var playerName = gameMode === 'ai' && currentPlayer === 2 ? getText('ai') : getText('player') + ' ' + currentPlayer;
turnText.setText(getText('turn') + ' ' + playerName);
}
if (infoText && gamePhase === 'menu') {
infoText.setText(getText('welcome'));
}
// Update player names
if (player1 && player1.nameText) {
player1.nameText.setText(getText('player') + ' 1');
}
if (player2 && player2.nameText) {
var p2Name = gameMode === 'ai' ? getText('ai') : getText('player') + ' 2';
player2.nameText.setText(p2Name);
}
// Update button texts
if (playButton && playButton.text) {
playButton.text.setText(getText('playTwoPlayers'));
}
if (playAIButton && playAIButton.text) {
playAIButton.text.setText(getText('playAgainstAI'));
}
if (shootOpponentButton && shootOpponentButton.text) {
shootOpponentButton.text.setText(getText('shootOpponent'));
}
if (shootSelfButton && shootSelfButton.text) {
shootSelfButton.text.setText(getText('shootSelf'));
}
// Update item descriptions
itemDescriptions = {
'magnifying_glass': getText('magnifyingGlass'),
'handcuffs': getText('handcuffs'),
'cigarettes': getText('cigarettes')
};
}
// Available items
var availableItems = ['magnifying_glass', 'handcuffs', 'cigarettes'];
var itemDescriptions = {
'magnifying_glass': 'Ver próxima bala',
'handcuffs': 'Saltar turno del oponente',
'cigarettes': 'Restaurar 1 de salud'
};
// Initialize players
player1 = game.addChild(new Player(1));
player1.x = 512;
player1.y = 1800;
player2 = game.addChild(new Player(2));
player2.x = 1536;
player2.y = 1800;
player3 = game.addChild(new Player(3));
player3.x = 1024;
player3.y = 2100;
// Initialize table for weapons
var weaponTable = game.addChild(LK.getAsset('table', {
anchorX: 0.5,
anchorY: 0.5,
tint: 0x654321
}));
weaponTable.x = 1024;
weaponTable.y = 1000;
weaponTable.visible = false;
// Initialize revolver
revolver = game.addChild(new Revolver());
revolver.x = 1024;
revolver.y = 1000;
// UI Text
roundText = new Text2(getText('round') + ' 1', {
size: 60,
fill: 0xFFFFFF
});
roundText.anchor.set(0.5, 0);
LK.gui.top.addChild(roundText);
roundText.y = 100;
turnText = new Text2(getText('turn') + ' ' + getText('player') + ' 1', {
size: 40,
fill: 0x00AAFF
});
turnText.anchor.set(0.5, 0.5);
game.addChild(turnText);
turnText.x = 1024;
turnText.y = 600;
infoText = new Text2(getText('chooseAction'), {
size: 36,
fill: 0xFFFFFF
});
infoText.anchor.set(0.5, 0.5);
game.addChild(infoText);
infoText.x = 1024;
infoText.y = 700;
// Play button
playButton = game.addChild(new GameButton(getText('playTwoPlayers'), function () {
gameMode = 'pvp';
startGame();
}));
playButton.x = 1024;
playButton.y = 1166;
// AI Play button
playAIButton = game.addChild(new GameButton(getText('playAgainstAI'), function () {
gameMode = 'ai';
showDifficultySelection();
}));
playAIButton.x = 1024;
playAIButton.y = 1366;
// 3vs Play button
var play3vsButton = game.addChild(new GameButton('JUGAR (3 JUGADORES)', function () {
gameMode = '3vs';
startGame();
}));
play3vsButton.x = 1024;
play3vsButton.y = 1566;
// Skins button
var skinsButton = game.addChild(new GameButton(getText('skins'), function () {
showSkins();
}));
skinsButton.x = 1024;
skinsButton.y = 1766;
// Action buttons
var shootOpponentButton = game.addChild(new GameButton(getText('shootOpponent'), function () {
shootOpponent();
}));
shootOpponentButton.x = 724;
shootOpponentButton.y = 1300;
shootOpponentButton.visible = false;
var shootSelfButton = game.addChild(new GameButton(getText('shootSelf'), function () {
shootSelf();
}));
shootSelfButton.x = 1324;
shootSelfButton.y = 1300;
shootSelfButton.visible = false;
buttons.push(shootOpponentButton, shootSelfButton);
// Item buttons (will be created dynamically)
var itemButtons = [];
function setupRound() {
gamePhase = 'setup';
// Calculate rounds for this round
var liveRounds = Math.min(2 + Math.floor(round / 2), 4);
var blanks = Math.max(4 - Math.floor(round / 3), 2);
// Load revolver
revolver.loadChambers(liveRounds, blanks);
// Play reload sound
LK.getSound('reload').play();
// Give items to players
giveRandomItems();
// Update display
var remaining = revolver.getRemainingRounds();
infoText.setText(getText('round') + ' ' + round + ': ' + remaining.live + ' reales, ' + remaining.blank + ' de fogueo');
roundText.setText(getText('round') + ' ' + round);
gamePhase = 'playing';
updateTurn();
}
function giveRandomItems() {
// Clear existing item buttons
for (var i = 0; i < itemButtons.length; i++) {
itemButtons[i].destroy();
}
itemButtons = [];
// Give 1-2 random items to each player
player1.items = [];
player2.items = [];
if (gameMode === '3vs') {
player3.items = [];
}
var maxPlayers = gameMode === '3vs' ? 3 : 2;
for (var p = 1; p <= maxPlayers; p++) {
var player = p === 1 ? player1 : p === 2 ? player2 : player3;
var numItems = 1 + Math.floor(Math.random() * 2);
for (var i = 0; i < numItems; i++) {
var randomItem = availableItems[Math.floor(Math.random() * availableItems.length)];
player.items.push(randomItem);
}
// Create item buttons for current player
if (p === currentPlayer) {
createItemButtons(player);
}
}
}
function createItemButtons(player) {
// Clear existing item buttons
for (var i = 0; i < itemButtons.length; i++) {
itemButtons[i].destroy();
}
itemButtons = [];
for (var i = 0; i < player.items.length; i++) {
var itemName = player.items[i];
var button = game.addChild(new GameButton(itemName.replace('_', ' '), createItemCallback(i)));
button.x = 400 + i * 250;
button.y = 1500;
button.scaleX = 1.0;
button.scaleY = 1.0;
itemButtons.push(button);
}
}
function createItemCallback(itemIndex) {
return function () {
useItem(itemIndex);
};
}
function useItem(itemIndex) {
var player = currentPlayer === 1 ? player1 : player2;
var itemName = player.items[itemIndex];
switch (itemName) {
case 'magnifying_glass':
var nextBullet = revolver.peekNext();
if (nextBullet === null) {
infoText.setText(getText('chamberEmpty'));
} else {
var bulletInfo = nextBullet ? getText('real') : getText('blank');
infoText.setText(getText('nextBullet') + ' ' + bulletInfo);
}
// Zoom animation towards the table
tween(game, {
scaleX: 2.0,
scaleY: 2.0,
x: -1024,
// Move camera towards table center (1024 - 1024*2.0)
y: -1000 // Move camera towards table center (1000 - 1000*2.0)
}, {
duration: 1000,
easing: tween.easeOut,
onFinish: function onFinish() {
// Hold zoom for a moment, then zoom back out
LK.setTimeout(function () {
tween(game, {
scaleX: 1.0,
scaleY: 1.0,
x: 0,
y: 0
}, {
duration: 800,
easing: tween.easeInOut
});
}, 500);
}
});
break;
case 'handcuffs':
infoText.setText('El oponente saltará su próximo turno');
// This will be handled in switchTurn
break;
case 'cigarettes':
player.heal();
infoText.setText('Salud restaurada');
// Cigarette relaxation animation
tween(player, {
rotation: -Math.PI / 12,
// Lean back slightly
scaleX: 1.1,
scaleY: 1.1,
tint: 0xAAFFAA // Light green tint for relaxation
}, {
duration: 800,
easing: tween.easeOut,
onFinish: function onFinish() {
// Return to normal position
tween(player, {
rotation: 0,
scaleX: 1.0,
scaleY: 1.0,
tint: 0xFFFFFF
}, {
duration: 600,
easing: tween.easeInOut
});
}
});
break;
}
// Remove used item
player.items.splice(itemIndex, 1);
createItemButtons(player);
LK.getSound('click').play();
// Don't end turn when using items
}
function shootOpponent() {
if (gamePhase !== 'playing') return;
if (gameMode === '3vs') {
// In 3vs mode, show target selection menu
showTargetSelection();
return;
}
var result = revolver.fire();
var opponent = currentPlayer === 1 ? player2 : player1;
// Zoom effect toward the opponent being shot
tween(game, {
scaleX: 1.3,
scaleY: 1.3,
x: -(opponent.x * 1.3 - 1024),
// Focus camera on opponent
y: -(opponent.y * 1.3 - 1366) // Focus camera on opponent
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
// Zoom back out
tween(game, {
scaleX: 1.0,
scaleY: 1.0,
x: 0,
y: 0
}, {
duration: 800,
easing: tween.easeInOut
});
}
});
if (result === true) {
// Live round - opponent takes damage
LK.getSound('gunshot').play();
opponent.takeDamage();
infoText.setText('¡BANG! ¡Oponente impactado!');
if (!opponent.isAlive) {
endGame(currentPlayer);
return;
}
} else if (result === false) {
// Blank round
LK.getSound('click').play();
infoText.setText('*Clic* - Bala de fogueo');
} else {
// Empty chamber
LK.getSound('empty_click').play();
infoText.setText('*Clic* - Recámara vacía');
}
// End turn
LK.setTimeout(function () {
switchTurn();
}, 1500);
}
function hideTargetSelection() {
if (!isTargetSelectionActive) return;
isTargetSelectionActive = false;
gamePhase = 'playing';
// Remove target selection buttons
for (var i = 0; i < targetSelectionButtons.length; i++) {
targetSelectionButtons[i].destroy();
}
targetSelectionButtons = [];
// Show action buttons again
shootOpponentButton.visible = true;
shootSelfButton.visible = true;
for (var i = 0; i < itemButtons.length; i++) {
itemButtons[i].visible = true;
}
// Update info text with remaining rounds
var remaining = revolver.getRemainingRounds();
infoText.setText(remaining.live + ' reales, ' + remaining.blank + ' de fogueo ' + getText('remaining'));
}
function shootSelf() {
if (gamePhase !== 'playing') return;
var result = revolver.fire();
var currentPlayerObj = currentPlayer === 1 ? player1 : currentPlayer === 2 ? player2 : player3;
// Zoom effect toward the current player being shot
tween(game, {
scaleX: 1.3,
scaleY: 1.3,
x: -(currentPlayerObj.x * 1.3 - 1024),
// Focus camera on current player
y: -(currentPlayerObj.y * 1.3 - 1366) // Focus camera on current player
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
// Zoom back out
tween(game, {
scaleX: 1.0,
scaleY: 1.0,
x: 0,
y: 0
}, {
duration: 800,
easing: tween.easeInOut
});
}
});
if (result === true) {
// Live round - current player takes damage
LK.getSound('gunshot').play();
currentPlayerObj.takeDamage();
infoText.setText('¡BANG! ¡Te disparaste a ti mismo!');
if (!currentPlayerObj.isAlive) {
endGame(currentPlayer === 1 ? 2 : 1);
return;
}
// End turn
LK.setTimeout(function () {
switchTurn();
}, 1500);
} else if (result === false) {
// Blank round - continue turn
LK.getSound('click').play();
infoText.setText('*Clic* - ¡De fogueo! Continúa tu turno');
// Don't switch turns
} else {
// Empty chamber
LK.getSound('empty_click').play();
infoText.setText('*Clic* - Recámara vacía');
// End turn
LK.setTimeout(function () {
switchTurn();
}, 1500);
}
}
function switchTurn() {
// Check if revolver is empty
var remaining = revolver.getRemainingRounds();
if (remaining.live === 0 && remaining.blank === 0) {
// Start new round
round++;
setupRound();
return;
}
// Check for handcuffs effect
var currentPlayerObj = currentPlayer === 1 ? player1 : player2;
var hasHandcuffs = false;
for (var i = 0; i < currentPlayerObj.items.length; i++) {
if (currentPlayerObj.items[i] === 'handcuffs') {
hasHandcuffs = true;
currentPlayerObj.items.splice(i, 1);
break;
}
}
if (hasHandcuffs) {
infoText.setText('Esposas usadas - el oponente salta su turno');
// Don't switch player
createItemButtons(currentPlayerObj);
updateTurn();
return;
}
// Normal turn switch
if (gameMode === '3vs') {
currentPlayer = currentPlayer === 1 ? 2 : currentPlayer === 2 ? 3 : 1;
} else {
currentPlayer = currentPlayer === 1 ? 2 : 1;
}
updateTurn();
}
function updateTurn() {
var currentPlayerObj = currentPlayer === 1 ? player1 : currentPlayer === 2 ? player2 : player3;
var playerName = gameMode === 'ai' && currentPlayer === 2 ? 'IA' : 'Jugador ' + currentPlayer;
turnText.setText('Turno del ' + playerName);
turnText.tint = currentPlayer === 1 ? 0x00aaff : currentPlayer === 2 ? 0xff00aa : 0x00ff00;
// Update player 2 name for AI mode
if (gameMode === 'ai') {
player2.nameText.setText('IA');
iaPlayerSprite.visible = true;
} else {
player2.nameText.setText('Jugador 2');
iaPlayerSprite.visible = false;
}
// Update item buttons
createItemButtons(currentPlayerObj);
// Show remaining rounds
var remaining = revolver.getRemainingRounds();
if (remaining.live === 0 && remaining.blank === 0) {
infoText.setText(getText('revolverEmpty'));
LK.setTimeout(function () {
round++;
setupRound();
}, 2000);
} else {
infoText.setText(remaining.live + ' reales, ' + remaining.blank + ' de fogueo ' + getText('remaining'));
}
// AI turn logic
if (gameMode === 'ai' && currentPlayer === 2) {
LK.setTimeout(function () {
makeAIMove();
}, 1500);
}
}
function showDifficultySelection() {
gamePhase = 'difficulty';
// Hide menu buttons
playButton.visible = false;
playAIButton.visible = false;
// Hide menu bullets
hideMenuBullets();
// Update info text
infoText.setText(getText('selectDifficulty'));
// Create difficulty buttons
var easyButton = game.addChild(new GameButton(getText('easy'), function () {
aiDifficulty = 'easy';
hideDifficultySelection();
startGame();
}));
easyButton.x = 1024;
easyButton.y = 1200;
difficultyButtons.push(easyButton);
var mediumButton = game.addChild(new GameButton(getText('medium'), function () {
aiDifficulty = 'medium';
hideDifficultySelection();
startGame();
}));
mediumButton.x = 1024;
mediumButton.y = 1400;
difficultyButtons.push(mediumButton);
var hardButton = game.addChild(new GameButton(getText('hard'), function () {
aiDifficulty = 'hard';
hideDifficultySelection();
startGame();
}));
hardButton.x = 1024;
hardButton.y = 1600;
difficultyButtons.push(hardButton);
var backButton = game.addChild(new GameButton(getText('back'), function () {
hideDifficultySelection();
showMainMenu();
}));
backButton.x = 1024;
backButton.y = 1800;
difficultyButtons.push(backButton);
}
function hideDifficultySelection() {
// Remove difficulty buttons
for (var i = 0; i < difficultyButtons.length; i++) {
difficultyButtons[i].destroy();
}
difficultyButtons = [];
}
function showMainMenu() {
gamePhase = 'menu';
// Show menu buttons
playButton.visible = true;
playAIButton.visible = true;
skinsButton.visible = true;
play3vsButton.visible = true;
// Hide IA Player sprite
iaPlayerSprite.visible = false;
// Hide game elements
weaponTable.visible = false;
// Update info text
infoText.setText(getText('welcome'));
// Show menu bullets again
for (var i = 0; i < menuBullets.length; i++) {
menuBullets[i].visible = true;
menuBullets[i].alpha = 1;
}
}
function makeAIMove() {
if (gamePhase !== 'playing' || currentPlayer !== 2) return;
var remaining = revolver.getRemainingRounds();
var aiPlayer = player2;
var playerHealth = player1.health;
var aiHealth = aiPlayer.health;
var totalRemaining = remaining.live + remaining.blank;
infoText.setText(remaining.live + ' reales, ' + remaining.blank + ' de fogueo restantes');
// AI uses items based on difficulty
for (var i = 0; i < aiPlayer.items.length; i++) {
var itemName = aiPlayer.items[i];
// Easy AI: Simple item usage
if (aiDifficulty === 'easy') {
if (itemName === 'cigarettes' && aiHealth < aiPlayer.maxHealth) {
useItem(i);
return;
}
}
// Medium AI: Strategic item usage
else if (aiDifficulty === 'medium') {
if (itemName === 'cigarettes' && aiHealth < aiPlayer.maxHealth) {
useItem(i);
return;
}
if (itemName === 'magnifying_glass' && remaining.live + remaining.blank > 2) {
useItem(i);
return;
}
}
// Hard AI: Advanced item usage
else if (aiDifficulty === 'hard') {
if (itemName === 'cigarettes' && aiHealth < aiPlayer.maxHealth && aiHealth <= playerHealth) {
useItem(i);
return;
}
if (itemName === 'magnifying_glass') {
useItem(i);
return;
}
if (itemName === 'handcuffs' && remaining.live > remaining.blank) {
useItem(i);
return;
}
}
}
// AI decision logic based on difficulty and odds
var totalRemaining = remaining.live + remaining.blank;
var liveRatio = totalRemaining > 0 ? remaining.live / totalRemaining : 0;
var shootSelfThreshold;
// Difficulty-based thresholds
if (aiDifficulty === 'easy') {
// Easy AI: Poor decision making, often makes risky moves
shootSelfThreshold = 0.6;
} else if (aiDifficulty === 'medium') {
// Medium AI: Balanced decision making
shootSelfThreshold = 0.4;
} else {
// Hard AI: Strategic decision making, considers health difference
shootSelfThreshold = 0.3;
// Hard AI considers health advantage
if (aiHealth > playerHealth) {
shootSelfThreshold = 0.35; // More aggressive when ahead
} else if (aiHealth < playerHealth) {
shootSelfThreshold = 0.25; // More conservative when behind
}
}
if (liveRatio < shootSelfThreshold) {
infoText.setText(getText('aiShootSelf'));
LK.setTimeout(function () {
shootSelf();
}, 1000);
} else {
infoText.setText(getText('aiShootOpponent'));
LK.setTimeout(function () {
shootOpponent();
}, 1000);
}
}
function endGame(winner) {
// In 3vs mode, check if there's only one survivor
if (gameMode === '3vs') {
var alivePlayers = [];
if (player1.isAlive) alivePlayers.push(1);
if (player2.isAlive) alivePlayers.push(2);
if (player3.isAlive) alivePlayers.push(3);
if (alivePlayers.length > 1) {
// Continue game if more than one player alive
return;
}
winner = alivePlayers[0];
}
gamePhase = 'gameover';
// Disable all buttons
for (var i = 0; i < buttons.length; i++) {
buttons[i].setEnabled(false);
}
for (var i = 0; i < itemButtons.length; i++) {
itemButtons[i].setEnabled(false);
}
var winnerName = gameMode === 'ai' && winner === 2 ? 'IA' : 'Jugador ' + winner;
infoText.setText('¡' + winnerName + ' Gana!');
turnText.setText('Juego Terminado');
LK.setScore(winner);
LK.setTimeout(function () {
LK.showYouWin();
}, 2000);
}
// Hide game elements initially
player1.visible = false;
player2.visible = false;
player3.visible = false;
revolver.visible = false;
turnText.visible = false;
playButton.visible = false;
playAIButton.visible = false;
skinsButton.visible = false;
infoText.setText('SELECCIONAR IDIOMA');
var isMusicOn = true;
// Create language selection bullets with animations
for (var i = 0; i < 20; i++) {
var bullet = new MenuBullet();
bullet.x = Math.random() * 2048;
bullet.y = Math.random() * 2732;
bullet.lastY = bullet.y;
// Make bullets larger
bullet.scaleX = 2.5;
bullet.scaleY = 2.5;
// Add rotation animation with tween
tween(bullet.children[0], {
rotation: Math.PI * 4
}, {
duration: 3000 + Math.random() * 2000,
easing: tween.linear,
onFinish: function onFinish() {
// Restart rotation animation
this.rotation = 0;
tween(this, {
rotation: Math.PI * 4
}, {
duration: 3000 + Math.random() * 2000,
easing: tween.linear
});
}
});
languageSelectionBullets.push(bullet);
game.addChild(bullet);
}
// Show language selection
showLanguageSelection();
function hideMenuBullets() {
// Hide menu bullets with tween animation
for (var i = 0; i < menuBullets.length; i++) {
tween(menuBullets[i], {
alpha: 0
}, {
duration: 300,
onFinish: function onFinish() {
this.visible = false;
}
});
}
}
function showSkins() {
if (isSkinsOpen) return;
isSkinsOpen = true;
gamePhase = 'skins';
// Hide menu buttons
playButton.visible = false;
playAIButton.visible = false;
skinsButton.visible = false;
play3vsButton.visible = false;
// Hide menu bullets
hideMenuBullets();
// Create skins panel background
skinsPanel = game.addChild(LK.getAsset('button', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 4,
scaleY: 6,
tint: 0x222222
}));
skinsPanel.x = 1024;
skinsPanel.y = 1366;
// Skins title
var skinsTitle = new Text2(getText('skins'), {
size: 50,
fill: 0xFFFFFF
});
skinsTitle.anchor.set(0.5, 0.5);
skinsPanel.addChild(skinsTitle);
skinsTitle.y = -200;
// Create skin selection buttons
for (var i = 0; i < availableSkins.length; i++) {
var skinId = availableSkins[i];
var skinButton = game.addChild(new GameButton(skinNames[skinId], createSkinCallback(skinId)));
skinButton.x = 1024;
skinButton.y = 1200 + i * 150;
// Add weapon icon to button
var weaponIcon = skinButton.attachAsset(skinId, {
anchorX: 0.5,
anchorY: 0.5,
x: -150,
y: 0,
scaleX: 0.6,
scaleY: 0.6
});
// Highlight current skin
if (skinId === currentSkin) {
skinButton.bg.tint = 0x004400;
}
skinButtons.push(skinButton);
}
// Back button
var backButton = game.addChild(new GameButton(getText('back'), function () {
closeSkins();
showMainMenu();
}));
backButton.x = 1024;
backButton.y = 1700;
skinButtons.push(backButton);
}
function createSkinCallback(skinId) {
return function () {
selectSkin(skinId);
};
}
function selectSkin(skinId) {
currentSkin = skinId;
storage.selectedSkin = skinId;
// Update visual feedback
for (var i = 0; i < skinButtons.length - 1; i++) {
// -1 to exclude back button
var button = skinButtons[i];
if (availableSkins[i] === skinId) {
button.bg.tint = 0x004400; // Green for selected
} else {
button.bg.tint = 0x333333; // Default color
}
}
// Update revolver asset to use selected skin
if (revolver && revolver.children[0]) {
var oldAsset = revolver.children[0];
revolver.removeChild(oldAsset);
var newAsset = revolver.attachAsset(currentSkin, {
anchorX: 0.5,
anchorY: 0.5
});
}
LK.getSound('click').play();
}
function closeSkins() {
if (!isSkinsOpen) return;
isSkinsOpen = false;
gamePhase = 'menu';
// Remove skins panel
if (skinsPanel) {
skinsPanel.destroy();
skinsPanel = null;
}
// Remove skin buttons
for (var i = 0; i < skinButtons.length; i++) {
skinButtons[i].destroy();
}
skinButtons = [];
}
function showDialogue(messages, callback) {
if (isDialogueActive) return;
isDialogueActive = true;
dialogueSequence = messages;
currentDialogueStep = 0;
gamePhase = 'dialogue';
// Create dialogue box background
dialogueBox = game.addChild(LK.getAsset('button', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 4.0,
scaleY: 1.8,
tint: 0x444444
}));
dialogueBox.x = 1024;
dialogueBox.y = 2200;
dialogueBox.alpha = 0;
// Create dialogue text
dialogueText = new Text2('', {
size: 32,
fill: 0xFFFFFF
});
dialogueText.anchor.set(0.5, 0.5);
dialogueBox.addChild(dialogueText);
// Animate dialogue box in
tween(dialogueBox, {
y: 2000,
alpha: 1
}, {
duration: 500,
easing: tween.easeOut,
onFinish: function onFinish() {
showNextDialogue(callback);
}
});
}
function showNextDialogue(callback) {
if (currentDialogueStep < dialogueSequence.length) {
var message = dialogueSequence[currentDialogueStep];
dialogueText.setText(message);
currentDialogueStep++;
// Auto advance after 2 seconds
LK.setTimeout(function () {
showNextDialogue(callback);
}, 2000);
} else {
hideDialogue(callback);
}
}
function hideDialogue(callback) {
if (!isDialogueActive) return;
// Animate dialogue box out
tween(dialogueBox, {
y: 2200,
alpha: 0
}, {
duration: 500,
easing: tween.easeIn,
onFinish: function onFinish() {
if (dialogueBox) {
dialogueBox.destroy();
dialogueBox = null;
dialogueText = null;
}
isDialogueActive = false;
gamePhase = 'playing';
if (callback) callback();
}
});
}
function startGame() {
gamePhase = 'setup';
// Hide 3vs play button when starting 3-player mode
if (gameMode === '3vs') {
play3vsButton.visible = false;
}
// Hide menu bullets
hideMenuBullets();
// Show different dialogue based on game mode
var dialogueMessages;
if (gameMode === 'ai') {
dialogueMessages = [getText('aiWelcome')];
} else {
dialogueMessages = [getText('dialogueP1Start'), getText('dialogueP2Start'), getText('dialogueP1Confident'), getText('dialogueP2Determined')];
}
showDialogue(dialogueMessages, function () {
continueGameStart();
});
}
function showLanguageSelection() {
if (!isLanguageSelectionOpen) return;
gamePhase = 'languageSelection';
// Hide 3vs play button in language selection
play3vsButton.visible = false;
// Create language buttons in a grid
var buttonsPerRow = 3;
var startY = 800;
var rowHeight = 200;
var buttonWidth = 600;
var spacing = (2048 - buttonsPerRow * buttonWidth) / (buttonsPerRow + 1);
for (var i = 0; i < availableLanguages.length; i++) {
var langCode = availableLanguages[i];
var langName = currentLanguageNames[langCode];
var row = Math.floor(i / buttonsPerRow);
var col = i % buttonsPerRow;
var x = spacing + col * (buttonWidth + spacing) + buttonWidth / 2;
var y = startY + row * rowHeight;
var langButton = game.addChild(new GameButton(langName, createLanguageCallback(langCode)));
langButton.x = x;
langButton.y = y;
langButton.scaleX = 0.75;
langButton.scaleY = 0.75;
languageButtons.push(langButton);
}
}
function createLanguageCallback(langCode) {
return function () {
selectLanguageAndContinue(langCode);
};
}
function selectLanguageAndContinue(langCode) {
changeLanguage(langCode);
hideLanguageSelection();
showMainMenu();
}
function hideLanguageSelection() {
if (!isLanguageSelectionOpen) return;
isLanguageSelectionOpen = false;
// Remove language buttons
for (var i = 0; i < languageButtons.length; i++) {
languageButtons[i].destroy();
}
languageButtons = [];
// Hide language selection bullets
for (var i = 0; i < languageSelectionBullets.length; i++) {
tween(languageSelectionBullets[i], {
alpha: 0
}, {
duration: 300,
onFinish: function onFinish() {
this.visible = false;
}
});
}
// Create menu bullets
for (var i = 0; i < 20; i++) {
var bullet = new MenuBullet();
bullet.x = Math.random() * 2048;
bullet.y = Math.random() * 2732;
bullet.lastY = bullet.y;
// Make bullets larger
bullet.scaleX = 2.5;
bullet.scaleY = 2.5;
// Add rotation animation with tween
tween(bullet.children[0], {
rotation: Math.PI * 4
}, {
duration: 3000 + Math.random() * 2000,
easing: tween.linear,
onFinish: function onFinish() {
// Restart rotation animation
this.rotation = 0;
tween(this, {
rotation: Math.PI * 4
}, {
duration: 3000 + Math.random() * 2000,
easing: tween.linear
});
}
});
menuBullets.push(bullet);
game.addChild(bullet);
}
}
// Target selection variables
var targetSelectionButtons = [];
var isTargetSelectionActive = false;
function showTargetSelection() {
if (isTargetSelectionActive) return;
isTargetSelectionActive = true;
gamePhase = 'targetSelection';
// Hide action buttons temporarily
shootOpponentButton.visible = false;
shootSelfButton.visible = false;
for (var i = 0; i < itemButtons.length; i++) {
itemButtons[i].visible = false;
}
// Show info about target selection
infoText.setText('Selecciona a qué jugador disparar');
// Get possible targets (alive players except current player)
var possibleTargets = [];
if (currentPlayer !== 1 && player1.isAlive) possibleTargets.push({
player: player1,
number: 1
});
if (currentPlayer !== 2 && player2.isAlive) possibleTargets.push({
player: player2,
number: 2
});
if (currentPlayer !== 3 && player3.isAlive) possibleTargets.push({
player: player3,
number: 3
});
// Create target selection buttons
for (var i = 0; i < possibleTargets.length; i++) {
var target = possibleTargets[i];
var targetButton = game.addChild(new GameButton('Jugador ' + target.number, createTargetCallback(target.player)));
targetButton.x = 800 + i * 250;
targetButton.y = 1200;
targetButton.scaleX = 0.8;
targetButton.scaleY = 0.8;
targetSelectionButtons.push(targetButton);
}
}
function createTargetCallback(targetPlayer) {
return function () {
selectTarget(targetPlayer);
};
}
function continueGameStart() {
// Show game elements
player1.visible = true;
player2.visible = true;
if (gameMode === '3vs') {
player3.visible = true;
}
revolver.visible = true;
weaponTable.visible = true;
turnText.visible = true;
// Hide menu buttons
playButton.visible = false;
playAIButton.visible = false;
skinsButton.visible = false;
// Apply selected skin to revolver
if (revolver && revolver.children[0]) {
var oldAsset = revolver.children[0];
revolver.removeChild(oldAsset);
var newAsset = revolver.attachAsset(currentSkin, {
anchorX: 0.5,
anchorY: 0.5
});
}
// Show action buttons (only for human player in AI mode)
shootOpponentButton.visible = true;
shootSelfButton.visible = true;
// Start the game
setupRound();
// Start music if enabled
if (isMusicOn) {
LK.playMusic('gameMusic');
}
}
function selectTarget(targetPlayer) {
hideTargetSelection();
// Fire at selected target
var result = revolver.fire();
var opponent = targetPlayer;
// Zoom effect toward the opponent being shot
tween(game, {
scaleX: 1.3,
scaleY: 1.3,
x: -(opponent.x * 1.3 - 1024),
// Focus camera on opponent
y: -(opponent.y * 1.3 - 1366) // Focus camera on opponent
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
// Zoom back out
tween(game, {
scaleX: 1.0,
scaleY: 1.0,
x: 0,
y: 0
}, {
duration: 800,
easing: tween.easeInOut
});
}
});
if (result === true) {
// Live round - opponent takes damage
LK.getSound('gunshot').play();
opponent.takeDamage();
infoText.setText('¡BANG! ¡Oponente impactado!');
if (!opponent.isAlive) {
endGame(currentPlayer);
return;
}
} else if (result === false) {
// Blank round
LK.getSound('click').play();
infoText.setText('*Clic* - Bala de fogueo');
} else {
// Empty chamber
LK.getSound('empty_click').play();
infoText.setText('*Clic* - Recámara vacía');
}
// End turn
LK.setTimeout(function () {
switchTurn();
}, 1500);
} /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
language: "es"
});
/****
* Classes
****/
var GameButton = Container.expand(function (text, callback) {
var self = Container.call(this);
self.callback = callback;
self.isEnabled = true;
self.bg = self.attachAsset('button', {
anchorX: 0.5,
anchorY: 0.5
});
self.text = new Text2(text, {
size: 65,
fill: 0xFFFFFF
});
self.text.anchor.set(0.5, 0.5);
self.addChild(self.text);
self.setEnabled = function (enabled) {
self.isEnabled = enabled;
self.alpha = enabled ? 1.0 : 0.5;
};
self.down = function (x, y, obj) {
if (self.isEnabled && self.callback) {
self.callback();
}
};
return self;
});
var MenuBullet = Container.expand(function () {
var self = Container.call(this);
// Create bullet graphics
var bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
// Random initial properties
self.fallSpeed = 2 + Math.random() * 4; // Random fall speed between 2-6
self.rotationSpeed = (Math.random() - 0.5) * 0.2; // Random rotation speed
// Initialize position tracking
self.lastY = self.y;
self.update = function () {
// Move bullet down
self.y += self.fallSpeed;
// Rotate bullet
bulletGraphics.rotation += self.rotationSpeed;
// Check if bullet has gone off screen (transition from on-screen to off-screen)
if (self.lastY <= 2800 && self.y > 2800) {
// Reset position to top with new random x
self.y = -50;
self.x = Math.random() * 2048;
self.fallSpeed = 2 + Math.random() * 4;
self.rotationSpeed = (Math.random() - 0.5) * 0.2;
}
// Update last position
self.lastY = self.y;
};
return self;
});
var Player = Container.expand(function (playerNumber, color) {
var self = Container.call(this);
self.playerNumber = playerNumber;
self.maxHealth = 3;
self.health = self.maxHealth;
self.items = [];
self.isAlive = true;
var playerGraphics = self.attachAsset(playerNumber === 1 ? 'player1' : 'player2', {
anchorX: 0.5,
anchorY: 0.5
});
var healthBarBg = self.attachAsset('healthBar', {
anchorX: 0.5,
anchorY: 0.5,
y: -150,
tint: 0x660000
});
self.healthBar = self.attachAsset('healthBar', {
anchorX: 0.5,
anchorY: 0.5,
y: -150
});
self.nameText = new Text2('Jugador ' + playerNumber, {
size: 40,
fill: 0xFFFFFF
});
self.nameText.anchor.set(0.5, 0.5);
self.nameText.y = -200;
self.addChild(self.nameText);
self.healthText = new Text2(self.health + '/' + self.maxHealth, {
size: 30,
fill: 0xFFFFFF
});
self.healthText.anchor.set(0.5, 0.5);
self.healthText.y = -120;
self.addChild(self.healthText);
self.updateHealth = function () {
var healthPercent = self.health / self.maxHealth;
self.healthBar.scaleX = healthPercent;
self.healthText.setText(self.health + '/' + self.maxHealth);
if (self.health <= 0) {
self.isAlive = false;
self.alpha = 0.5;
}
};
self.takeDamage = function () {
self.health = Math.max(0, self.health - 1);
self.updateHealth();
// Fall animation - rotate and move down
tween(self, {
rotation: Math.PI / 6,
// Fall to the side
y: self.y + 50,
// Move down slightly
tint: 0xFF0000
}, {
duration: 400,
easing: tween.easeOut,
onFinish: function onFinish() {
// Get up animation - return to normal position
tween(self, {
rotation: 0,
// Return to upright
y: self.y - 50,
// Return to original position
tint: 0xFFFFFF
}, {
duration: 600,
easing: tween.easeInOut
});
}
});
};
self.heal = function () {
self.health = Math.min(self.maxHealth, self.health + 1);
self.updateHealth();
// Flash green
tween(self, {
tint: 0x00FF00
}, {
duration: 200,
onFinish: function onFinish() {
tween(self, {
tint: 0xFFFFFF
}, {
duration: 200
});
}
});
};
return self;
});
var Revolver = Container.expand(function () {
var self = Container.call(this);
self.chambers = [];
self.currentChamber = 0;
self.totalChambers = 6;
self.isRevealed = false;
var revolverGraphics = self.attachAsset('revolver', {
anchorX: 0.5,
anchorY: 0.5
});
self.chamberIndicators = [];
for (var i = 0; i < self.totalChambers; i++) {
var indicator = self.attachAsset('blank', {
anchorX: 0.5,
anchorY: 0.5,
x: (i - 2.5) * 50,
y: -120
});
self.chamberIndicators.push(indicator);
}
self.loadChambers = function (liveRounds, blanks) {
self.chambers = [];
self.currentChamber = 0;
// Add live rounds
for (var i = 0; i < liveRounds; i++) {
self.chambers.push(true);
}
// Add blanks
for (var i = 0; i < blanks; i++) {
self.chambers.push(false);
}
// Shuffle chambers
for (var i = self.chambers.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var temp = self.chambers[i];
self.chambers[i] = self.chambers[j];
self.chambers[j] = temp;
}
self.updateDisplay();
};
self.updateDisplay = function () {
for (var i = 0; i < self.totalChambers; i++) {
if (i < self.chambers.length) {
if (self.isRevealed || i < self.currentChamber) {
if (i < self.chambers.length && self.chambers[i]) {
self.chamberIndicators[i].tint = 0xFFD700; // Gold for live
} else {
self.chamberIndicators[i].tint = 0x888888; // Gray for blank
}
} else {
self.chamberIndicators[i].tint = 0x444444; // Dark for unknown
}
if (i === self.currentChamber) {
self.chamberIndicators[i].scaleX = 1.5;
self.chamberIndicators[i].scaleY = 1.5;
} else {
self.chamberIndicators[i].scaleX = 1;
self.chamberIndicators[i].scaleY = 1;
}
} else {
self.chamberIndicators[i].tint = 0x222222; // Very dark for empty
self.chamberIndicators[i].scaleX = 1;
self.chamberIndicators[i].scaleY = 1;
}
}
};
self.fire = function () {
if (self.currentChamber >= self.chambers.length) {
return null; // Empty chamber
}
var isLive = self.chambers[self.currentChamber];
self.currentChamber++;
self.updateDisplay();
// Animate rotation
tween(revolverGraphics, {
rotation: revolverGraphics.rotation + Math.PI / 3
}, {
duration: 300,
easing: tween.easeOut
});
return isLive;
};
self.peekNext = function () {
if (self.currentChamber >= self.chambers.length) {
return null;
}
return self.chambers[self.currentChamber];
};
self.getRemainingRounds = function () {
var live = 0;
var blank = 0;
for (var i = self.currentChamber; i < self.chambers.length; i++) {
if (self.chambers[i]) {
live++;
} else {
blank++;
}
}
return {
live: live,
blank: blank
};
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x1a1a1a
});
/****
* Game Code
****/
// Game state
var currentPlayer = 1;
var gamePhase = 'languageSelection'; // languageSelection, menu, setup, playing, gameover, difficulty
var gameMode = 'pvp'; // pvp, ai, 3vs
var aiDifficulty = 'medium'; // easy, medium, hard
var round = 1;
var player1, player2, player3, revolver;
var buttons = [];
var infoText, roundText, turnText;
var playButton, playAIButton;
var difficultyButtons = [];
var menuBullets = [];
var languageSelectionBullets = [];
var languageButtons = [];
var isLanguageSelectionOpen = true;
// Dialogue system variables
var dialogueBox = null;
var dialogueText = null;
var isDialogueActive = false;
var currentDialogueStep = 0;
var dialogueSequence = [];
// Language system
var currentLanguage = storage.language || 'es';
var currentSkin = storage.selectedSkin || 'revolver';
var skinButtons = [];
var isSkinsOpen = false;
var skinsPanel = null;
var availableSkins = ['shotgun', 'pistol', 'revolver'];
var skinNames = {
'revolver': 'Revólver Clásico',
'pistol': 'Pistola Moderna',
'shotgun': 'Escopeta'
};
var availableLanguages = ['es', 'en', 'it', 'pt', 'ru', 'ar', 'pe', 'ja', 'zh'];
var currentLanguageNames = {
'es': 'ESPAÑOL',
'en': 'ENGLISH',
'it': 'ITALIANO',
'pt': 'PORTUGUÊS',
'ru': 'РУССКИЙ',
'ar': 'ARGENTINO',
'pe': 'PERUANO',
'ja': '日本語',
'zh': '中文'
};
// IA Player sprite
var iaPlayerSprite = new Text2('IA PLAYER', {
size: 48,
fill: 0xFF6600
});
iaPlayerSprite.anchor.set(0.5, 0.5);
iaPlayerSprite.x = 1024;
iaPlayerSprite.y = 300;
iaPlayerSprite.visible = false;
game.addChild(iaPlayerSprite);
var texts = {
es: {
player: 'Jugador',
ai: 'IA',
round: 'Ronda',
turn: 'Turno del',
chooseAction: 'Elige tu acción',
playTwoPlayers: 'JUGAR (2 JUGADORES)',
playAgainstAI: 'JUGAR CONTRA IA',
settings: 'AJUSTES',
shootOpponent: 'Disparar al Oponente',
shootSelf: 'Dispararse a Sí Mismo',
welcome: '¡Bienvenido al Duelo de Ruleta Rusa!',
dialogueP1Start: '¡Es hora del duelo, Jugador 2!',
dialogueP2Start: '¡Estoy listo! ¡Que comience la batalla!',
dialogueP1Confident: '¡Esta vez voy a ganar!',
dialogueP2Determined: '¡Ya veremos quién es el mejor!',
aiWelcome: 'Bienvenido a la ruleta rusa, soy el jefe de la organización de dealers',
magnifyingGlass: 'Ver próxima bala',
handcuffs: 'Saltar turno del oponente',
cigarettes: 'Restaurar 1 de salud',
chamberEmpty: 'La recámara está vacía',
nextBullet: 'La próxima bala es:',
real: 'REAL',
blank: 'DE FOGUEO',
opponentSkip: 'El oponente saltará su próximo turno',
healthRestored: 'Salud restaurada',
bang: '¡BANG!',
opponentHit: '¡Oponente impactado!',
click: '*Clic*',
blankRound: 'Bala de fogueo',
emptyChamer: 'Recámara vacía',
shotSelf: '¡Te disparaste a ti mismo!',
blankContinue: '¡De fogueo! Continúa tu turno',
handcuffsUsed: 'Esposas usadas - el oponente salta su turno',
revolverEmpty: 'Revólver vacío - Nueva ronda comenzando...',
remaining: 'restantes',
aiShootSelf: 'IA decide dispararse a sí misma...',
aiShootOpponent: 'IA decide disparar al oponente...',
wins: 'Gana!',
gameOver: 'Juego Terminado',
sound: 'SONIDO',
music: 'MÚSICA',
close: 'CERRAR',
language: 'IDIOMA',
on: 'ON',
off: 'OFF',
spanish: 'ESPAÑOL',
english: 'INGLÉS',
italian: 'ITALIANO',
portuguese: 'PORTUGUÉS',
russian: 'RUSO',
argentine: 'ARGENTINO',
peruvian: 'PERUANO',
japanese: 'JAPONÉS',
chinese: 'CHINO',
instructions: 'INSTRUCCIONES',
howToPlay: 'CÓMO JUGAR:',
rule1: '1. Cada jugador tiene 3 puntos de vida',
rule2: '2. El revólver contiene balas reales y de fogueo',
rule3: '3. En tu turno puedes:',
rule4: ' - Disparar al oponente',
rule5: ' - Dispararte a ti mismo',
rule6: '4. Si te disparas con bala de fogueo, continúas',
rule7: '5. Si te disparas con bala real, pierdes vida',
rule8: '6. Usa objetos para obtener ventajas',
rule9: '7. Gana el último jugador vivo',
rule10: '8. Estrategia: La lupa revela la próxima bala',
rule11: '9. Las esposas hacen que el rival pierda un turno',
rule12: '10. Los cigarrillos restauran 1 punto de vida',
rule13: '11. Observa las balas disparadas para calcular odds',
rule14: '12. Cada ronda aumenta la dificultad',
exit: 'SALIR',
selectDifficulty: 'SELECCIONA DIFICULTAD',
easy: 'FÁCIL',
medium: 'MEDIO',
hard: 'DIFÍCIL',
skins: 'SKINS DE ESCOPETA',
back: 'VOLVER',
normalMode: 'MODO NORMAL'
},
en: {
player: 'Player',
ai: 'AI',
round: 'Round',
turn: 'Turn of',
chooseAction: 'Choose your action',
playTwoPlayers: 'PLAY (2 PLAYERS)',
playAgainstAI: 'PLAY AGAINST AI',
settings: 'SETTINGS',
shootOpponent: 'Shoot Opponent',
shootSelf: 'Shoot Self',
welcome: 'Welcome to Russian Roulette Duel!',
dialogueP1Start: 'It\'s time for the duel, Player 2!',
dialogueP2Start: 'I\'m ready! Let the battle begin!',
dialogueP1Confident: 'This time I\'m going to win!',
dialogueP2Determined: 'We\'ll see who\'s the best!',
aiWelcome: 'Welcome to Russian roulette, I am the head of the dealers organization',
magnifyingGlass: 'See next bullet',
handcuffs: 'Skip opponent turn',
cigarettes: 'Restore 1 health',
chamberEmpty: 'Chamber is empty',
nextBullet: 'Next bullet is:',
real: 'LIVE',
blank: 'BLANK',
opponentSkip: 'Opponent will skip their next turn',
healthRestored: 'Health restored',
bang: 'BANG!',
opponentHit: 'Opponent hit!',
click: '*Click*',
blankRound: 'Blank round',
emptyChamer: 'Empty chamber',
shotSelf: 'You shot yourself!',
blankContinue: 'Blank! Continue your turn',
handcuffsUsed: 'Handcuffs used - opponent skips turn',
revolverEmpty: 'Revolver empty - New round starting...',
remaining: 'remaining',
aiShootSelf: 'AI decides to shoot itself...',
aiShootOpponent: 'AI decides to shoot opponent...',
wins: 'Wins!',
gameOver: 'Game Over',
sound: 'SOUND',
music: 'MUSIC',
close: 'CLOSE',
language: 'LANGUAGE',
on: 'ON',
off: 'OFF',
spanish: 'SPANISH',
english: 'ENGLISH',
italian: 'ITALIAN',
portuguese: 'PORTUGUESE',
russian: 'RUSSIAN',
argentine: 'ARGENTINE',
peruvian: 'PERUVIAN',
japanese: 'JAPANESE',
chinese: 'CHINESE',
instructions: 'INSTRUCTIONS',
howToPlay: 'HOW TO PLAY:',
rule1: '1. Each player has 3 health points',
rule2: '2. The revolver contains live and blank rounds',
rule3: '3. On your turn you can:',
rule4: ' - Shoot the opponent',
rule5: ' - Shoot yourself',
rule6: '4. If you shoot yourself with blank, continue',
rule7: '5. If you shoot yourself with live, lose health',
rule8: '6. Use items to gain advantages',
rule9: '7. Last player alive wins',
rule10: '8. Strategy: Magnifying glass reveals next bullet',
rule11: '9. Handcuffs make opponent skip their turn',
rule12: '10. Cigarettes restore 1 health point',
rule13: '11. Track fired bullets to calculate odds',
rule14: '12. Each round increases difficulty',
exit: 'EXIT',
selectDifficulty: 'SELECT DIFFICULTY',
easy: 'EASY',
medium: 'MEDIUM',
hard: 'HARD',
skins: 'SHOTGUN SKINS',
back: 'BACK',
normalMode: 'NORMAL MODE'
},
it: {
player: 'Giocatore',
ai: 'IA',
round: 'Round',
turn: 'Turno di',
chooseAction: 'Scegli la tua azione',
playTwoPlayers: 'GIOCA (2 GIOCATORI)',
playAgainstAI: 'GIOCA CONTRO IA',
settings: 'IMPOSTAZIONI',
shootOpponent: 'Spara all\'Avversario',
shootSelf: 'Sparati',
welcome: 'Benvenuto al Duello di Roulette Russa!',
dialogueP1Start: 'È ora del duello, Giocatore 2!',
dialogueP2Start: 'Sono pronto! Che la battaglia abbia inizio!',
dialogueP1Confident: 'Questa volta vincerò io!',
dialogueP2Determined: 'Vedremo chi è il migliore!',
aiWelcome: 'Benvenuto alla roulette russa, sono il capo dell\'organizzazione dei dealers',
magnifyingGlass: 'Vedi prossimo proiettile',
handcuffs: 'Salta turno avversario',
cigarettes: 'Ripristina 1 salute',
chamberEmpty: 'La camera è vuota',
nextBullet: 'Il prossimo proiettile è:',
real: 'VERO',
blank: 'A SALVE',
opponentSkip: 'L\'avversario salterà il suo prossimo turno',
healthRestored: 'Salute ripristinata',
bang: 'BANG!',
opponentHit: 'Avversario colpito!',
click: '*Click*',
blankRound: 'Colpo a salve',
emptyChamer: 'Camera vuota',
shotSelf: 'Ti sei sparato!',
blankContinue: 'A salve! Continua il tuo turno',
handcuffsUsed: 'Manette usate - l\'avversario salta il turno',
revolverEmpty: 'Revolver vuoto - Inizia nuovo round...',
remaining: 'rimanenti',
aiShootSelf: 'IA decide di spararsi...',
aiShootOpponent: 'IA decide di sparare all\'avversario...',
wins: 'Vince!',
gameOver: 'Gioco Finito',
sound: 'SUONO',
music: 'MUSICA',
close: 'CHIUDI',
language: 'LINGUA',
on: 'ON',
off: 'OFF',
spanish: 'SPAGNOLO',
english: 'INGLESE',
italian: 'ITALIANO',
portuguese: 'PORTOGHESE',
russian: 'RUSSO',
argentine: 'ARGENTINO',
peruvian: 'PERUVIANO',
japanese: 'GIAPPONESE',
chinese: 'CINESE',
instructions: 'ISTRUZIONI',
howToPlay: 'COME GIOCARE:',
rule1: '1. Ogni giocatore ha 3 punti salute',
rule2: '2. Il revolver contiene proiettili veri e a salve',
rule3: '3. Nel tuo turno puoi:',
rule4: ' - Sparare all\'avversario',
rule5: ' - Spararti',
rule6: '4. Se ti spari con salve, continui',
rule7: '5. Se ti spari con vero, perdi salute',
rule8: '6. Usa oggetti per vantaggi',
rule9: '7. Vince l\'ultimo giocatore vivo',
rule10: '8. Strategia: La lente rivela il prossimo proiettile',
rule11: '9. Le manette fanno saltare il turno all\'avversario',
rule12: '10. Le sigarette ripristinano 1 punto salute',
rule13: '11. Tieni traccia dei proiettili sparati per calcolare le probabilità',
rule14: '12. Ogni round aumenta la difficoltà',
exit: 'ESCI',
selectDifficulty: 'SELEZIONA DIFFICOLTÀ',
easy: 'FACILE',
medium: 'MEDIO',
hard: 'DIFFICILE',
skins: 'SKIN FUCILE',
back: 'INDIETRO',
normalMode: 'MODALITÀ NORMALE'
},
pt: {
player: 'Jogador',
ai: 'IA',
round: 'Rodada',
turn: 'Turno do',
chooseAction: 'Escolha sua ação',
playTwoPlayers: 'JOGAR (2 JOGADORES)',
playAgainstAI: 'JOGAR CONTRA IA',
settings: 'CONFIGURAÇÕES',
shootOpponent: 'Atirar no Oponente',
shootSelf: 'Atirar em Si Mesmo',
welcome: 'Bem-vindo ao Duelo de Roleta Russa!',
dialogueP1Start: 'É hora do duelo, Jogador 2!',
dialogueP2Start: 'Estou pronto! Que a batalha comece!',
dialogueP1Confident: 'Desta vez eu vou ganhar!',
dialogueP2Determined: 'Vamos ver quem é o melhor!',
aiWelcome: 'Bem-vindo à roleta russa, sou o chefe da organização de dealers',
magnifyingGlass: 'Ver próxima bala',
handcuffs: 'Pular turno do oponente',
cigarettes: 'Restaurar 1 de saúde',
chamberEmpty: 'A câmara está vazia',
nextBullet: 'A próxima bala é:',
real: 'REAL',
blank: 'DE FESTIM',
opponentSkip: 'O oponente pulará seu próximo turno',
healthRestored: 'Saúde restaurada',
bang: 'BANG!',
opponentHit: 'Oponente atingido!',
click: '*Clique*',
blankRound: 'Tiro de festim',
emptyChamer: 'Câmara vazia',
shotSelf: 'Você atirou em si mesmo!',
blankContinue: 'De festim! Continue seu turno',
handcuffsUsed: 'Algemas usadas - oponente pula turno',
revolverEmpty: 'Revólver vazio - Nova rodada começando...',
remaining: 'restantes',
aiShootSelf: 'IA decide atirar em si mesma...',
aiShootOpponent: 'IA decide atirar no oponente...',
wins: 'Vence!',
gameOver: 'Fim de Jogo',
sound: 'SOM',
music: 'MÚSICA',
close: 'FECHAR',
language: 'IDIOMA',
on: 'LIGADO',
off: 'DESLIGADO',
spanish: 'ESPANHOL',
english: 'INGLÊS',
italian: 'ITALIANO',
portuguese: 'PORTUGUÊS',
russian: 'RUSSO',
argentine: 'ARGENTINO',
peruvian: 'PERUANO',
japanese: 'JAPONÊS',
chinese: 'CHINÊS',
instructions: 'INSTRUÇÕES',
howToPlay: 'COMO JOGAR:',
rule1: '1. Cada jogador tem 3 pontos de vida',
rule2: '2. O revólver contém balas reais e de festim',
rule3: '3. No seu turno você pode:',
rule4: ' - Atirar no oponente',
rule5: ' - Atirar em si mesmo',
rule6: '4. Se atirar em si com festim, continue',
rule7: '5. Se atirar em si com real, perde vida',
rule8: '6. Use itens para vantagens',
rule9: '7. Último jogador vivo ganha',
rule10: '8. Estratégia: A lupa revela a próxima bala',
rule11: '9. As algemas fazem o oponente pular o turno',
rule12: '10. Os cigarros restauram 1 ponto de vida',
rule13: '11. Acompanhe as balas disparadas para calcular probabilidades',
rule14: '12. Cada rodada aumenta a dificuldade',
exit: 'SAIR',
selectDifficulty: 'SELECIONAR DIFICULDADE',
easy: 'FÁCIL',
medium: 'MÉDIO',
hard: 'DIFÍCIL',
skins: 'SKINS ESPINGARDA',
back: 'VOLTAR',
normalMode: 'MODO NORMAL'
},
ru: {
player: 'Игрок',
ai: 'ИИ',
round: 'Раунд',
turn: 'Ход игрока',
chooseAction: 'Выберите действие',
playTwoPlayers: 'ИГРАТЬ (2 ИГРОКА)',
playAgainstAI: 'ИГРАТЬ ПРОТИВ ИИ',
settings: 'НАСТРОЙКИ',
shootOpponent: 'Стрелять в противника',
shootSelf: 'Стрелять в себя',
welcome: 'Добро пожаловать в дуэль русской рулетки!',
dialogueP1Start: 'Время дуэли, Игрок 2!',
dialogueP2Start: 'Я готов! Пусть битва начнется!',
dialogueP1Confident: 'На этот раз я выиграю!',
dialogueP2Determined: 'Посмотрим, кто лучший!',
aiWelcome: 'Добро пожаловать в русскую рулетку, я глава организации дилеров',
magnifyingGlass: 'Посмотреть следующую пулю',
handcuffs: 'Пропустить ход противника',
cigarettes: 'Восстановить 1 здоровье',
chamberEmpty: 'Камера пуста',
nextBullet: 'Следующая пуля:',
real: 'БОЕВАЯ',
blank: 'ХОЛОСТАЯ',
opponentSkip: 'Противник пропустит следующий ход',
healthRestored: 'Здоровье восстановлено',
bang: 'БАМ!',
opponentHit: 'Противник ранен!',
click: '*Щелчок*',
blankRound: 'Холостой патрон',
emptyChamer: 'Пустая камера',
shotSelf: 'Вы выстрелили в себя!',
blankContinue: 'Холостой! Продолжайте ход',
handcuffsUsed: 'Наручники использованы - противник пропускает ход',
revolverEmpty: 'Револьвер пуст - Начинается новый раунд...',
remaining: 'осталось',
aiShootSelf: 'ИИ решил выстрелить в себя...',
aiShootOpponent: 'ИИ решил выстрелить в противника...',
wins: 'Побеждает!',
gameOver: 'Игра окончена',
sound: 'ЗВУК',
music: 'МУЗЫКА',
close: 'ЗАКРЫТЬ',
language: 'ЯЗЫК',
on: 'ВКЛ',
off: 'ВЫКЛ',
spanish: 'ИСПАНСКИЙ',
english: 'АНГЛИЙСКИЙ',
italian: 'ИТАЛЬЯНСКИЙ',
portuguese: 'ПОРТУГАЛЬСКИЙ',
russian: 'РУССКИЙ',
argentine: 'АРГЕНТИНСКИЙ',
peruvian: 'ПЕРУАНСКИЙ',
japanese: 'ЯПОНСКИЙ',
chinese: 'КИТАЙСКИЙ',
instructions: 'ИНСТРУКЦИИ',
howToPlay: 'КАК ИГРАТЬ:',
rule1: '1. У каждого игрока 3 очка здоровья',
rule2: '2. Револьвер содержит боевые и холостые патроны',
rule3: '3. В свой ход вы можете:',
rule4: ' - Выстрелить в противника',
rule5: ' - Выстрелить в себя',
rule6: '4. Если стреляете в себя холостым, продолжайте',
rule7: '5. Если стреляете в себя боевым, теряете здоровье',
rule8: '6. Используйте предметы для преимуществ',
rule9: '7. Побеждает последний живой игрок',
rule10: '8. Стратегия: Лупа показывает следующую пулю',
rule11: '9. Наручники заставляют противника пропустить ход',
rule12: '10. Сигареты восстанавливают 1 очко здоровья',
rule13: '11. Отслеживайте выстреленные пули для расчета вероятности',
rule14: '12. Каждый раунд увеличивает сложность',
exit: 'ВЫХОД',
selectDifficulty: 'ВЫБЕРИТЕ СЛОЖНОСТЬ',
easy: 'ЛЕГКО',
medium: 'СРЕДНЕ',
hard: 'СЛОЖНО',
skins: 'СКИНЫ РУЖЬЯ',
back: 'НАЗАД',
normalMode: 'ОБЫЧНЫЙ РЕЖИМ'
},
ar: {
player: 'Jugador',
ai: 'IA',
round: 'Ronda',
turn: 'Turno del',
chooseAction: 'Elegí tu acción',
playTwoPlayers: 'JUGAR (2 JUGADORES)',
playAgainstAI: 'JUGAR CONTRA IA',
settings: 'CONFIGURACIÓN',
shootOpponent: 'Disparar al Rival',
shootSelf: 'Dispararte a Vos Mismo',
welcome: '¡Bienvenido al Duelo de Ruleta Rusa!',
dialogueP1Start: '¡Es hora del duelo, Jugador 2!',
dialogueP2Start: '¡Estoy listo! ¡Que arranque la batalla!',
dialogueP1Confident: '¡Esta vez la voy a ganar!',
dialogueP2Determined: '¡Ya vamos a ver quién es el mejor!',
aiWelcome: 'Bienvenido a la ruleta rusa, soy el jefe de la organización de dealers',
magnifyingGlass: 'Ver próxima bala',
handcuffs: 'Saltear turno del rival',
cigarettes: 'Restaurar 1 de salud',
chamberEmpty: 'La recámara está vacía',
nextBullet: 'La próxima bala es:',
real: 'REAL',
blank: 'DE FOGUEO',
opponentSkip: 'El rival va a saltear su próximo turno',
healthRestored: 'Salud restaurada',
bang: '¡BANG!',
opponentHit: '¡Rival impactado!',
click: '*Clic*',
blankRound: 'Bala de fogueo',
emptyChamer: 'Recámara vacía',
shotSelf: '¡Te disparaste a vos mismo!',
blankContinue: '¡De fogueo! Seguí tu turno',
handcuffsUsed: 'Esposas usadas - el rival saltea su turno',
revolverEmpty: 'Revólver vacío - Nueva ronda empezando...',
remaining: 'restantes',
aiShootSelf: 'IA decide dispararse a sí misma...',
aiShootOpponent: 'IA decide disparar al rival...',
wins: '¡Gana!',
gameOver: 'Juego Terminado',
sound: 'SONIDO',
music: 'MÚSICA',
close: 'CERRAR',
language: 'IDIOMA',
on: 'PRENDIDO',
off: 'APAGADO',
spanish: 'ESPAÑOL',
english: 'INGLÉS',
italian: 'ITALIANO',
portuguese: 'PORTUGUÉS',
russian: 'RUSO',
argentine: 'ARGENTINO',
peruvian: 'PERUANO',
japanese: 'JAPONÉS',
chinese: 'CHINO',
instructions: 'INSTRUCCIONES',
howToPlay: 'CÓMO JUGAR:',
rule1: '1. Cada jugador tiene 3 puntos de vida',
rule2: '2. El revólver contiene balas reales y de fogueo',
rule3: '3. En tu turno podés:',
rule4: ' - Disparar al rival',
rule5: ' - Dispararte a vos mismo',
rule6: '4. Si te disparás con bala de fogueo, seguís',
rule7: '5. Si te disparás con bala real, perdés vida',
rule8: '6. Usá objetos para obtener ventajas',
rule9: '7. Gana el último jugador vivo',
rule10: '8. Estrategia: La lupa revela la próxima bala',
rule11: '9. Las esposas hacen que el rival pierda un turno',
rule12: '10. Los cigarrillos restauran 1 punto de vida',
rule13: '11. Fijate en las balas disparadas para calcular chances',
rule14: '12. Cada ronda aumenta la dificultad',
exit: 'SALIR',
selectDifficulty: 'ELEGÍ DIFICULTAD',
easy: 'FÁCIL',
medium: 'MEDIO',
hard: 'DIFÍCIL',
skins: 'SKINS DE ESCOPETA',
back: 'VOLVER',
normalMode: 'MODO NORMAL'
},
pe: {
player: 'Jugador',
ai: 'IA',
round: 'Ronda',
turn: 'Turno del',
chooseAction: 'Elige tu acción pe',
playTwoPlayers: 'JUGAR (2 JUGADORES)',
playAgainstAI: 'JUGAR CONTRA IA',
settings: 'AJUSTES',
shootOpponent: 'Disparar al Rival',
shootSelf: 'Dispararte a Ti Mismo',
welcome: '¡Bienvenido al Duelo de Ruleta Rusa, causa!',
dialogueP1Start: '¡Es hora del duelo, Jugador 2, causa!',
dialogueP2Start: '¡Estoy listo, pe! ¡Que empiece la batalla!',
dialogueP1Confident: '¡Esta vez voy a ganar, causa!',
dialogueP2Determined: '¡Ya veremos quién es el mejor, pe!',
aiWelcome: 'Bienvenido a la ruleta rusa, causa, soy el jefe de la organización de dealers',
magnifyingGlass: 'Ver próxima bala',
handcuffs: 'Saltar turno del rival',
cigarettes: 'Restaurar 1 de salud',
chamberEmpty: 'La recámara está vacía',
nextBullet: 'La próxima bala es:',
real: 'REAL',
blank: 'DE FOGUEO',
opponentSkip: 'El rival saltará su próximo turno',
healthRestored: 'Salud restaurada',
bang: '¡BANG!',
opponentHit: '¡Rival impactado!',
click: '*Clic*',
blankRound: 'Bala de fogueo',
emptyChamer: 'Recámara vacía',
shotSelf: '¡Te disparaste a ti mismo, causa!',
blankContinue: '¡De fogueo! Continúa tu turno',
handcuffsUsed: 'Esposas usadas - el rival salta su turno',
revolverEmpty: 'Revólver vacío - Nueva ronda comenzando...',
remaining: 'restantes',
aiShootSelf: 'IA decide dispararse a sí misma...',
aiShootOpponent: 'IA decide disparar al rival...',
wins: '¡Gana!',
gameOver: 'Juego Terminado',
sound: 'SONIDO',
music: 'MÚSICA',
close: 'CERRAR',
language: 'IDIOMA',
on: 'PRENDIDO',
off: 'APAGADO',
spanish: 'ESPAÑOL',
english: 'INGLÉS',
italian: 'ITALIANO',
portuguese: 'PORTUGUÉS',
russian: 'RUSO',
argentine: 'ARGENTINO',
peruvian: 'PERUANO',
japanese: 'JAPONÉS',
chinese: 'CHINO',
instructions: 'INSTRUCCIONES',
howToPlay: 'CÓMO JUGAR:',
rule1: '1. Cada jugador tiene 3 puntos de vida',
rule2: '2. El revólver contiene balas reales y de fogueo',
rule3: '3. En tu turno puedes:',
rule4: ' - Disparar al rival',
rule5: ' - Dispararte a ti mismo',
rule6: '4. Si te disparas con bala de fogueo, continúas',
rule7: '5. Si te disparas con bala real, pierdes vida',
rule8: '6. Usa objetos para obtener ventajas, causa',
rule9: '7. Gana el último jugador vivo',
rule10: '8. Estrategia: La lupa revela la próxima bala, causa',
rule11: '9. Las esposas hacen que el rival pierda un turno',
rule12: '10. Los cigarrillos restauran 1 punto de vida',
rule13: '11. Observa las balas disparadas para calcular probabilidades',
rule14: '12. Cada ronda aumenta la dificultad, causa',
exit: 'SALIR',
selectDifficulty: 'ELIGE DIFICULTAD',
easy: 'FÁCIL',
medium: 'MEDIO',
hard: 'DIFÍCIL',
skins: 'SKINS DE ESCOPETA',
back: 'VOLVER',
normalMode: 'MODO NORMAL'
},
ja: {
player: 'プレイヤー',
ai: 'AI',
round: 'ラウンド',
turn: 'ターン',
chooseAction: 'アクションを選択してください',
playTwoPlayers: 'プレイ(2プレイヤー)',
playAgainstAI: 'AIと対戦',
settings: '設定',
shootOpponent: '相手を撃つ',
shootSelf: '自分を撃つ',
welcome: 'ロシアンルーレット決闘へようこそ!',
dialogueP1Start: '決闘の時間だ、プレイヤー2!',
dialogueP2Start: '準備はできた!戦いを始めよう!',
dialogueP1Confident: '今回は俺が勝つ!',
dialogueP2Determined: '誰が最強か見てやる!',
aiWelcome: 'ロシアンルーレットへようこそ、私はディーラー組織のボスです',
magnifyingGlass: '次の弾を見る',
handcuffs: '相手のターンをスキップ',
cigarettes: '体力を1回復',
chamberEmpty: 'チャンバーが空です',
nextBullet: '次の弾は:',
real: '実弾',
blank: '空砲',
opponentSkip: '相手は次のターンをスキップします',
healthRestored: '体力が回復しました',
bang: 'バン!',
opponentHit: '相手にヒット!',
click: '*カチッ*',
blankRound: '空砲',
emptyChamer: '空のチャンバー',
shotSelf: '自分を撃ちました!',
blankContinue: '空砲!ターンを続けてください',
handcuffsUsed: '手錠使用 - 相手はターンをスキップ',
revolverEmpty: 'リボルバーが空 - 新しいラウンドを開始...',
remaining: '残り',
aiShootSelf: 'AIは自分を撃つことを決定...',
aiShootOpponent: 'AIは相手を撃つことを決定...',
wins: '勝利!',
gameOver: 'ゲーム終了',
sound: 'サウンド',
music: '音楽',
close: '閉じる',
language: '言語',
on: 'オン',
off: 'オフ',
spanish: 'スペイン語',
english: '英語',
italian: 'イタリア語',
portuguese: 'ポルトガル語',
russian: 'ロシア語',
argentine: 'アルゼンチン語',
peruvian: 'ペルー語',
japanese: '日本語',
chinese: '中国語',
instructions: '説明書',
howToPlay: '遊び方:',
rule1: '1. 各プレイヤーは3つの体力ポイントを持っています',
rule2: '2. リボルバーには実弾と空砲が入っています',
rule3: '3. あなたのターンでできること:',
rule4: ' - 相手を撃つ',
rule5: ' - 自分を撃つ',
rule6: '4. 空砲で自分を撃った場合、続行',
rule7: '5. 実弾で自分を撃った場合、体力を失う',
rule8: '6. アイテムを使って有利になる',
rule9: '7. 最後に生き残ったプレイヤーが勝利',
rule10: '8. 戦略:虫眼鏡で次の弾を確認',
rule11: '9. 手錠で相手のターンをスキップ',
rule12: '10. タバコで体力を1回復',
rule13: '11. 発射された弾を追跡して確率を計算',
rule14: '12. 各ラウンドで難易度が上がります',
exit: '終了',
selectDifficulty: '難易度を選択',
easy: '簡単',
medium: '普通',
hard: '難しい',
skins: 'ショットガンスキン',
back: '戻る',
normalMode: '通常モード'
},
zh: {
player: '玩家',
ai: 'AI',
round: '回合',
turn: '轮到',
chooseAction: '选择你的行动',
playTwoPlayers: '开始游戏(2玩家)',
playAgainstAI: '对战AI',
settings: '设置',
shootOpponent: '射击对手',
shootSelf: '射击自己',
welcome: '欢迎来到俄罗斯轮盘决斗!',
dialogueP1Start: '决斗时间到了,玩家2!',
dialogueP2Start: '我准备好了!让战斗开始吧!',
dialogueP1Confident: '这次我要赢!',
dialogueP2Determined: '我们来看看谁是最强的!',
aiWelcome: '欢迎来到俄罗斯轮盘,我是庄家组织的头目',
magnifyingGlass: '查看下一发子弹',
handcuffs: '跳过对手回合',
cigarettes: '恢复1点生命',
chamberEmpty: '弹膛为空',
nextBullet: '下一发子弹是:',
real: '实弹',
blank: '空弹',
opponentSkip: '对手将跳过下一回合',
healthRestored: '生命已恢复',
bang: '砰!',
opponentHit: '击中对手!',
click: '*咔嗒*',
blankRound: '空弹',
emptyChamer: '空弹膛',
shotSelf: '你射击了自己!',
blankContinue: '空弹!继续你的回合',
handcuffsUsed: '手铐已使用 - 对手跳过回合',
revolverEmpty: '左轮手枪为空 - 开始新回合...',
remaining: '剩余',
aiShootSelf: 'AI决定射击自己...',
aiShootOpponent: 'AI决定射击对手...',
wins: '获胜!',
gameOver: '游戏结束',
sound: '声音',
music: '音乐',
close: '关闭',
language: '语言',
on: '开',
off: '关',
spanish: '西班牙语',
english: '英语',
italian: '意大利语',
portuguese: '葡萄牙语',
russian: '俄语',
argentine: '阿根廷语',
peruvian: '秘鲁语',
japanese: '日语',
chinese: '中文',
instructions: '说明',
howToPlay: '游戏玩法:',
rule1: '1. 每个玩家有3点生命值',
rule2: '2. 左轮手枪装有实弹和空弹',
rule3: '3. 在你的回合你可以:',
rule4: ' - 射击对手',
rule5: ' - 射击自己',
rule6: '4. 如果用空弹射击自己,继续游戏',
rule7: '5. 如果用实弹射击自己,失去生命',
rule8: '6. 使用道具获得优势',
rule9: '7. 最后存活的玩家获胜',
rule10: '8. 策略:放大镜显示下一发子弹',
rule11: '9. 手铐让对手跳过回合',
rule12: '10. 香烟恢复1点生命值',
rule13: '11. 追踪已射击的子弹来计算概率',
rule14: '12. 每轮难度递增',
exit: '退出',
selectDifficulty: '选择难度',
easy: '简单',
medium: '中等',
hard: '困难',
skins: '霰弹枪皮肤',
back: '返回',
normalMode: '普通模式'
}
};
function getText(key) {
return texts[currentLanguage][key] || key;
}
function changeLanguage(newLanguage) {
currentLanguage = newLanguage;
storage.language = newLanguage;
updateAllTexts();
}
function updateAllTexts() {
// Update UI texts
if (roundText) roundText.setText(getText('round') + ' ' + round);
if (turnText) {
var playerName = gameMode === 'ai' && currentPlayer === 2 ? getText('ai') : getText('player') + ' ' + currentPlayer;
turnText.setText(getText('turn') + ' ' + playerName);
}
if (infoText && gamePhase === 'menu') {
infoText.setText(getText('welcome'));
}
// Update player names
if (player1 && player1.nameText) {
player1.nameText.setText(getText('player') + ' 1');
}
if (player2 && player2.nameText) {
var p2Name = gameMode === 'ai' ? getText('ai') : getText('player') + ' 2';
player2.nameText.setText(p2Name);
}
// Update button texts
if (playButton && playButton.text) {
playButton.text.setText(getText('playTwoPlayers'));
}
if (playAIButton && playAIButton.text) {
playAIButton.text.setText(getText('playAgainstAI'));
}
if (shootOpponentButton && shootOpponentButton.text) {
shootOpponentButton.text.setText(getText('shootOpponent'));
}
if (shootSelfButton && shootSelfButton.text) {
shootSelfButton.text.setText(getText('shootSelf'));
}
// Update item descriptions
itemDescriptions = {
'magnifying_glass': getText('magnifyingGlass'),
'handcuffs': getText('handcuffs'),
'cigarettes': getText('cigarettes')
};
}
// Available items
var availableItems = ['magnifying_glass', 'handcuffs', 'cigarettes'];
var itemDescriptions = {
'magnifying_glass': 'Ver próxima bala',
'handcuffs': 'Saltar turno del oponente',
'cigarettes': 'Restaurar 1 de salud'
};
// Initialize players
player1 = game.addChild(new Player(1));
player1.x = 512;
player1.y = 1800;
player2 = game.addChild(new Player(2));
player2.x = 1536;
player2.y = 1800;
player3 = game.addChild(new Player(3));
player3.x = 1024;
player3.y = 2100;
// Initialize table for weapons
var weaponTable = game.addChild(LK.getAsset('table', {
anchorX: 0.5,
anchorY: 0.5,
tint: 0x654321
}));
weaponTable.x = 1024;
weaponTable.y = 1000;
weaponTable.visible = false;
// Initialize revolver
revolver = game.addChild(new Revolver());
revolver.x = 1024;
revolver.y = 1000;
// UI Text
roundText = new Text2(getText('round') + ' 1', {
size: 60,
fill: 0xFFFFFF
});
roundText.anchor.set(0.5, 0);
LK.gui.top.addChild(roundText);
roundText.y = 100;
turnText = new Text2(getText('turn') + ' ' + getText('player') + ' 1', {
size: 40,
fill: 0x00AAFF
});
turnText.anchor.set(0.5, 0.5);
game.addChild(turnText);
turnText.x = 1024;
turnText.y = 600;
infoText = new Text2(getText('chooseAction'), {
size: 36,
fill: 0xFFFFFF
});
infoText.anchor.set(0.5, 0.5);
game.addChild(infoText);
infoText.x = 1024;
infoText.y = 700;
// Play button
playButton = game.addChild(new GameButton(getText('playTwoPlayers'), function () {
gameMode = 'pvp';
startGame();
}));
playButton.x = 1024;
playButton.y = 1166;
// AI Play button
playAIButton = game.addChild(new GameButton(getText('playAgainstAI'), function () {
gameMode = 'ai';
showDifficultySelection();
}));
playAIButton.x = 1024;
playAIButton.y = 1366;
// 3vs Play button
var play3vsButton = game.addChild(new GameButton('JUGAR (3 JUGADORES)', function () {
gameMode = '3vs';
startGame();
}));
play3vsButton.x = 1024;
play3vsButton.y = 1566;
// Skins button
var skinsButton = game.addChild(new GameButton(getText('skins'), function () {
showSkins();
}));
skinsButton.x = 1024;
skinsButton.y = 1766;
// Action buttons
var shootOpponentButton = game.addChild(new GameButton(getText('shootOpponent'), function () {
shootOpponent();
}));
shootOpponentButton.x = 724;
shootOpponentButton.y = 1300;
shootOpponentButton.visible = false;
var shootSelfButton = game.addChild(new GameButton(getText('shootSelf'), function () {
shootSelf();
}));
shootSelfButton.x = 1324;
shootSelfButton.y = 1300;
shootSelfButton.visible = false;
buttons.push(shootOpponentButton, shootSelfButton);
// Item buttons (will be created dynamically)
var itemButtons = [];
function setupRound() {
gamePhase = 'setup';
// Calculate rounds for this round
var liveRounds = Math.min(2 + Math.floor(round / 2), 4);
var blanks = Math.max(4 - Math.floor(round / 3), 2);
// Load revolver
revolver.loadChambers(liveRounds, blanks);
// Play reload sound
LK.getSound('reload').play();
// Give items to players
giveRandomItems();
// Update display
var remaining = revolver.getRemainingRounds();
infoText.setText(getText('round') + ' ' + round + ': ' + remaining.live + ' reales, ' + remaining.blank + ' de fogueo');
roundText.setText(getText('round') + ' ' + round);
gamePhase = 'playing';
updateTurn();
}
function giveRandomItems() {
// Clear existing item buttons
for (var i = 0; i < itemButtons.length; i++) {
itemButtons[i].destroy();
}
itemButtons = [];
// Give 1-2 random items to each player
player1.items = [];
player2.items = [];
if (gameMode === '3vs') {
player3.items = [];
}
var maxPlayers = gameMode === '3vs' ? 3 : 2;
for (var p = 1; p <= maxPlayers; p++) {
var player = p === 1 ? player1 : p === 2 ? player2 : player3;
var numItems = 1 + Math.floor(Math.random() * 2);
for (var i = 0; i < numItems; i++) {
var randomItem = availableItems[Math.floor(Math.random() * availableItems.length)];
player.items.push(randomItem);
}
// Create item buttons for current player
if (p === currentPlayer) {
createItemButtons(player);
}
}
}
function createItemButtons(player) {
// Clear existing item buttons
for (var i = 0; i < itemButtons.length; i++) {
itemButtons[i].destroy();
}
itemButtons = [];
for (var i = 0; i < player.items.length; i++) {
var itemName = player.items[i];
var button = game.addChild(new GameButton(itemName.replace('_', ' '), createItemCallback(i)));
button.x = 400 + i * 250;
button.y = 1500;
button.scaleX = 1.0;
button.scaleY = 1.0;
itemButtons.push(button);
}
}
function createItemCallback(itemIndex) {
return function () {
useItem(itemIndex);
};
}
function useItem(itemIndex) {
var player = currentPlayer === 1 ? player1 : player2;
var itemName = player.items[itemIndex];
switch (itemName) {
case 'magnifying_glass':
var nextBullet = revolver.peekNext();
if (nextBullet === null) {
infoText.setText(getText('chamberEmpty'));
} else {
var bulletInfo = nextBullet ? getText('real') : getText('blank');
infoText.setText(getText('nextBullet') + ' ' + bulletInfo);
}
// Zoom animation towards the table
tween(game, {
scaleX: 2.0,
scaleY: 2.0,
x: -1024,
// Move camera towards table center (1024 - 1024*2.0)
y: -1000 // Move camera towards table center (1000 - 1000*2.0)
}, {
duration: 1000,
easing: tween.easeOut,
onFinish: function onFinish() {
// Hold zoom for a moment, then zoom back out
LK.setTimeout(function () {
tween(game, {
scaleX: 1.0,
scaleY: 1.0,
x: 0,
y: 0
}, {
duration: 800,
easing: tween.easeInOut
});
}, 500);
}
});
break;
case 'handcuffs':
infoText.setText('El oponente saltará su próximo turno');
// This will be handled in switchTurn
break;
case 'cigarettes':
player.heal();
infoText.setText('Salud restaurada');
// Cigarette relaxation animation
tween(player, {
rotation: -Math.PI / 12,
// Lean back slightly
scaleX: 1.1,
scaleY: 1.1,
tint: 0xAAFFAA // Light green tint for relaxation
}, {
duration: 800,
easing: tween.easeOut,
onFinish: function onFinish() {
// Return to normal position
tween(player, {
rotation: 0,
scaleX: 1.0,
scaleY: 1.0,
tint: 0xFFFFFF
}, {
duration: 600,
easing: tween.easeInOut
});
}
});
break;
}
// Remove used item
player.items.splice(itemIndex, 1);
createItemButtons(player);
LK.getSound('click').play();
// Don't end turn when using items
}
function shootOpponent() {
if (gamePhase !== 'playing') return;
if (gameMode === '3vs') {
// In 3vs mode, show target selection menu
showTargetSelection();
return;
}
var result = revolver.fire();
var opponent = currentPlayer === 1 ? player2 : player1;
// Zoom effect toward the opponent being shot
tween(game, {
scaleX: 1.3,
scaleY: 1.3,
x: -(opponent.x * 1.3 - 1024),
// Focus camera on opponent
y: -(opponent.y * 1.3 - 1366) // Focus camera on opponent
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
// Zoom back out
tween(game, {
scaleX: 1.0,
scaleY: 1.0,
x: 0,
y: 0
}, {
duration: 800,
easing: tween.easeInOut
});
}
});
if (result === true) {
// Live round - opponent takes damage
LK.getSound('gunshot').play();
opponent.takeDamage();
infoText.setText('¡BANG! ¡Oponente impactado!');
if (!opponent.isAlive) {
endGame(currentPlayer);
return;
}
} else if (result === false) {
// Blank round
LK.getSound('click').play();
infoText.setText('*Clic* - Bala de fogueo');
} else {
// Empty chamber
LK.getSound('empty_click').play();
infoText.setText('*Clic* - Recámara vacía');
}
// End turn
LK.setTimeout(function () {
switchTurn();
}, 1500);
}
function hideTargetSelection() {
if (!isTargetSelectionActive) return;
isTargetSelectionActive = false;
gamePhase = 'playing';
// Remove target selection buttons
for (var i = 0; i < targetSelectionButtons.length; i++) {
targetSelectionButtons[i].destroy();
}
targetSelectionButtons = [];
// Show action buttons again
shootOpponentButton.visible = true;
shootSelfButton.visible = true;
for (var i = 0; i < itemButtons.length; i++) {
itemButtons[i].visible = true;
}
// Update info text with remaining rounds
var remaining = revolver.getRemainingRounds();
infoText.setText(remaining.live + ' reales, ' + remaining.blank + ' de fogueo ' + getText('remaining'));
}
function shootSelf() {
if (gamePhase !== 'playing') return;
var result = revolver.fire();
var currentPlayerObj = currentPlayer === 1 ? player1 : currentPlayer === 2 ? player2 : player3;
// Zoom effect toward the current player being shot
tween(game, {
scaleX: 1.3,
scaleY: 1.3,
x: -(currentPlayerObj.x * 1.3 - 1024),
// Focus camera on current player
y: -(currentPlayerObj.y * 1.3 - 1366) // Focus camera on current player
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
// Zoom back out
tween(game, {
scaleX: 1.0,
scaleY: 1.0,
x: 0,
y: 0
}, {
duration: 800,
easing: tween.easeInOut
});
}
});
if (result === true) {
// Live round - current player takes damage
LK.getSound('gunshot').play();
currentPlayerObj.takeDamage();
infoText.setText('¡BANG! ¡Te disparaste a ti mismo!');
if (!currentPlayerObj.isAlive) {
endGame(currentPlayer === 1 ? 2 : 1);
return;
}
// End turn
LK.setTimeout(function () {
switchTurn();
}, 1500);
} else if (result === false) {
// Blank round - continue turn
LK.getSound('click').play();
infoText.setText('*Clic* - ¡De fogueo! Continúa tu turno');
// Don't switch turns
} else {
// Empty chamber
LK.getSound('empty_click').play();
infoText.setText('*Clic* - Recámara vacía');
// End turn
LK.setTimeout(function () {
switchTurn();
}, 1500);
}
}
function switchTurn() {
// Check if revolver is empty
var remaining = revolver.getRemainingRounds();
if (remaining.live === 0 && remaining.blank === 0) {
// Start new round
round++;
setupRound();
return;
}
// Check for handcuffs effect
var currentPlayerObj = currentPlayer === 1 ? player1 : player2;
var hasHandcuffs = false;
for (var i = 0; i < currentPlayerObj.items.length; i++) {
if (currentPlayerObj.items[i] === 'handcuffs') {
hasHandcuffs = true;
currentPlayerObj.items.splice(i, 1);
break;
}
}
if (hasHandcuffs) {
infoText.setText('Esposas usadas - el oponente salta su turno');
// Don't switch player
createItemButtons(currentPlayerObj);
updateTurn();
return;
}
// Normal turn switch
if (gameMode === '3vs') {
currentPlayer = currentPlayer === 1 ? 2 : currentPlayer === 2 ? 3 : 1;
} else {
currentPlayer = currentPlayer === 1 ? 2 : 1;
}
updateTurn();
}
function updateTurn() {
var currentPlayerObj = currentPlayer === 1 ? player1 : currentPlayer === 2 ? player2 : player3;
var playerName = gameMode === 'ai' && currentPlayer === 2 ? 'IA' : 'Jugador ' + currentPlayer;
turnText.setText('Turno del ' + playerName);
turnText.tint = currentPlayer === 1 ? 0x00aaff : currentPlayer === 2 ? 0xff00aa : 0x00ff00;
// Update player 2 name for AI mode
if (gameMode === 'ai') {
player2.nameText.setText('IA');
iaPlayerSprite.visible = true;
} else {
player2.nameText.setText('Jugador 2');
iaPlayerSprite.visible = false;
}
// Update item buttons
createItemButtons(currentPlayerObj);
// Show remaining rounds
var remaining = revolver.getRemainingRounds();
if (remaining.live === 0 && remaining.blank === 0) {
infoText.setText(getText('revolverEmpty'));
LK.setTimeout(function () {
round++;
setupRound();
}, 2000);
} else {
infoText.setText(remaining.live + ' reales, ' + remaining.blank + ' de fogueo ' + getText('remaining'));
}
// AI turn logic
if (gameMode === 'ai' && currentPlayer === 2) {
LK.setTimeout(function () {
makeAIMove();
}, 1500);
}
}
function showDifficultySelection() {
gamePhase = 'difficulty';
// Hide menu buttons
playButton.visible = false;
playAIButton.visible = false;
// Hide menu bullets
hideMenuBullets();
// Update info text
infoText.setText(getText('selectDifficulty'));
// Create difficulty buttons
var easyButton = game.addChild(new GameButton(getText('easy'), function () {
aiDifficulty = 'easy';
hideDifficultySelection();
startGame();
}));
easyButton.x = 1024;
easyButton.y = 1200;
difficultyButtons.push(easyButton);
var mediumButton = game.addChild(new GameButton(getText('medium'), function () {
aiDifficulty = 'medium';
hideDifficultySelection();
startGame();
}));
mediumButton.x = 1024;
mediumButton.y = 1400;
difficultyButtons.push(mediumButton);
var hardButton = game.addChild(new GameButton(getText('hard'), function () {
aiDifficulty = 'hard';
hideDifficultySelection();
startGame();
}));
hardButton.x = 1024;
hardButton.y = 1600;
difficultyButtons.push(hardButton);
var backButton = game.addChild(new GameButton(getText('back'), function () {
hideDifficultySelection();
showMainMenu();
}));
backButton.x = 1024;
backButton.y = 1800;
difficultyButtons.push(backButton);
}
function hideDifficultySelection() {
// Remove difficulty buttons
for (var i = 0; i < difficultyButtons.length; i++) {
difficultyButtons[i].destroy();
}
difficultyButtons = [];
}
function showMainMenu() {
gamePhase = 'menu';
// Show menu buttons
playButton.visible = true;
playAIButton.visible = true;
skinsButton.visible = true;
play3vsButton.visible = true;
// Hide IA Player sprite
iaPlayerSprite.visible = false;
// Hide game elements
weaponTable.visible = false;
// Update info text
infoText.setText(getText('welcome'));
// Show menu bullets again
for (var i = 0; i < menuBullets.length; i++) {
menuBullets[i].visible = true;
menuBullets[i].alpha = 1;
}
}
function makeAIMove() {
if (gamePhase !== 'playing' || currentPlayer !== 2) return;
var remaining = revolver.getRemainingRounds();
var aiPlayer = player2;
var playerHealth = player1.health;
var aiHealth = aiPlayer.health;
var totalRemaining = remaining.live + remaining.blank;
infoText.setText(remaining.live + ' reales, ' + remaining.blank + ' de fogueo restantes');
// AI uses items based on difficulty
for (var i = 0; i < aiPlayer.items.length; i++) {
var itemName = aiPlayer.items[i];
// Easy AI: Simple item usage
if (aiDifficulty === 'easy') {
if (itemName === 'cigarettes' && aiHealth < aiPlayer.maxHealth) {
useItem(i);
return;
}
}
// Medium AI: Strategic item usage
else if (aiDifficulty === 'medium') {
if (itemName === 'cigarettes' && aiHealth < aiPlayer.maxHealth) {
useItem(i);
return;
}
if (itemName === 'magnifying_glass' && remaining.live + remaining.blank > 2) {
useItem(i);
return;
}
}
// Hard AI: Advanced item usage
else if (aiDifficulty === 'hard') {
if (itemName === 'cigarettes' && aiHealth < aiPlayer.maxHealth && aiHealth <= playerHealth) {
useItem(i);
return;
}
if (itemName === 'magnifying_glass') {
useItem(i);
return;
}
if (itemName === 'handcuffs' && remaining.live > remaining.blank) {
useItem(i);
return;
}
}
}
// AI decision logic based on difficulty and odds
var totalRemaining = remaining.live + remaining.blank;
var liveRatio = totalRemaining > 0 ? remaining.live / totalRemaining : 0;
var shootSelfThreshold;
// Difficulty-based thresholds
if (aiDifficulty === 'easy') {
// Easy AI: Poor decision making, often makes risky moves
shootSelfThreshold = 0.6;
} else if (aiDifficulty === 'medium') {
// Medium AI: Balanced decision making
shootSelfThreshold = 0.4;
} else {
// Hard AI: Strategic decision making, considers health difference
shootSelfThreshold = 0.3;
// Hard AI considers health advantage
if (aiHealth > playerHealth) {
shootSelfThreshold = 0.35; // More aggressive when ahead
} else if (aiHealth < playerHealth) {
shootSelfThreshold = 0.25; // More conservative when behind
}
}
if (liveRatio < shootSelfThreshold) {
infoText.setText(getText('aiShootSelf'));
LK.setTimeout(function () {
shootSelf();
}, 1000);
} else {
infoText.setText(getText('aiShootOpponent'));
LK.setTimeout(function () {
shootOpponent();
}, 1000);
}
}
function endGame(winner) {
// In 3vs mode, check if there's only one survivor
if (gameMode === '3vs') {
var alivePlayers = [];
if (player1.isAlive) alivePlayers.push(1);
if (player2.isAlive) alivePlayers.push(2);
if (player3.isAlive) alivePlayers.push(3);
if (alivePlayers.length > 1) {
// Continue game if more than one player alive
return;
}
winner = alivePlayers[0];
}
gamePhase = 'gameover';
// Disable all buttons
for (var i = 0; i < buttons.length; i++) {
buttons[i].setEnabled(false);
}
for (var i = 0; i < itemButtons.length; i++) {
itemButtons[i].setEnabled(false);
}
var winnerName = gameMode === 'ai' && winner === 2 ? 'IA' : 'Jugador ' + winner;
infoText.setText('¡' + winnerName + ' Gana!');
turnText.setText('Juego Terminado');
LK.setScore(winner);
LK.setTimeout(function () {
LK.showYouWin();
}, 2000);
}
// Hide game elements initially
player1.visible = false;
player2.visible = false;
player3.visible = false;
revolver.visible = false;
turnText.visible = false;
playButton.visible = false;
playAIButton.visible = false;
skinsButton.visible = false;
infoText.setText('SELECCIONAR IDIOMA');
var isMusicOn = true;
// Create language selection bullets with animations
for (var i = 0; i < 20; i++) {
var bullet = new MenuBullet();
bullet.x = Math.random() * 2048;
bullet.y = Math.random() * 2732;
bullet.lastY = bullet.y;
// Make bullets larger
bullet.scaleX = 2.5;
bullet.scaleY = 2.5;
// Add rotation animation with tween
tween(bullet.children[0], {
rotation: Math.PI * 4
}, {
duration: 3000 + Math.random() * 2000,
easing: tween.linear,
onFinish: function onFinish() {
// Restart rotation animation
this.rotation = 0;
tween(this, {
rotation: Math.PI * 4
}, {
duration: 3000 + Math.random() * 2000,
easing: tween.linear
});
}
});
languageSelectionBullets.push(bullet);
game.addChild(bullet);
}
// Show language selection
showLanguageSelection();
function hideMenuBullets() {
// Hide menu bullets with tween animation
for (var i = 0; i < menuBullets.length; i++) {
tween(menuBullets[i], {
alpha: 0
}, {
duration: 300,
onFinish: function onFinish() {
this.visible = false;
}
});
}
}
function showSkins() {
if (isSkinsOpen) return;
isSkinsOpen = true;
gamePhase = 'skins';
// Hide menu buttons
playButton.visible = false;
playAIButton.visible = false;
skinsButton.visible = false;
play3vsButton.visible = false;
// Hide menu bullets
hideMenuBullets();
// Create skins panel background
skinsPanel = game.addChild(LK.getAsset('button', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 4,
scaleY: 6,
tint: 0x222222
}));
skinsPanel.x = 1024;
skinsPanel.y = 1366;
// Skins title
var skinsTitle = new Text2(getText('skins'), {
size: 50,
fill: 0xFFFFFF
});
skinsTitle.anchor.set(0.5, 0.5);
skinsPanel.addChild(skinsTitle);
skinsTitle.y = -200;
// Create skin selection buttons
for (var i = 0; i < availableSkins.length; i++) {
var skinId = availableSkins[i];
var skinButton = game.addChild(new GameButton(skinNames[skinId], createSkinCallback(skinId)));
skinButton.x = 1024;
skinButton.y = 1200 + i * 150;
// Add weapon icon to button
var weaponIcon = skinButton.attachAsset(skinId, {
anchorX: 0.5,
anchorY: 0.5,
x: -150,
y: 0,
scaleX: 0.6,
scaleY: 0.6
});
// Highlight current skin
if (skinId === currentSkin) {
skinButton.bg.tint = 0x004400;
}
skinButtons.push(skinButton);
}
// Back button
var backButton = game.addChild(new GameButton(getText('back'), function () {
closeSkins();
showMainMenu();
}));
backButton.x = 1024;
backButton.y = 1700;
skinButtons.push(backButton);
}
function createSkinCallback(skinId) {
return function () {
selectSkin(skinId);
};
}
function selectSkin(skinId) {
currentSkin = skinId;
storage.selectedSkin = skinId;
// Update visual feedback
for (var i = 0; i < skinButtons.length - 1; i++) {
// -1 to exclude back button
var button = skinButtons[i];
if (availableSkins[i] === skinId) {
button.bg.tint = 0x004400; // Green for selected
} else {
button.bg.tint = 0x333333; // Default color
}
}
// Update revolver asset to use selected skin
if (revolver && revolver.children[0]) {
var oldAsset = revolver.children[0];
revolver.removeChild(oldAsset);
var newAsset = revolver.attachAsset(currentSkin, {
anchorX: 0.5,
anchorY: 0.5
});
}
LK.getSound('click').play();
}
function closeSkins() {
if (!isSkinsOpen) return;
isSkinsOpen = false;
gamePhase = 'menu';
// Remove skins panel
if (skinsPanel) {
skinsPanel.destroy();
skinsPanel = null;
}
// Remove skin buttons
for (var i = 0; i < skinButtons.length; i++) {
skinButtons[i].destroy();
}
skinButtons = [];
}
function showDialogue(messages, callback) {
if (isDialogueActive) return;
isDialogueActive = true;
dialogueSequence = messages;
currentDialogueStep = 0;
gamePhase = 'dialogue';
// Create dialogue box background
dialogueBox = game.addChild(LK.getAsset('button', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 4.0,
scaleY: 1.8,
tint: 0x444444
}));
dialogueBox.x = 1024;
dialogueBox.y = 2200;
dialogueBox.alpha = 0;
// Create dialogue text
dialogueText = new Text2('', {
size: 32,
fill: 0xFFFFFF
});
dialogueText.anchor.set(0.5, 0.5);
dialogueBox.addChild(dialogueText);
// Animate dialogue box in
tween(dialogueBox, {
y: 2000,
alpha: 1
}, {
duration: 500,
easing: tween.easeOut,
onFinish: function onFinish() {
showNextDialogue(callback);
}
});
}
function showNextDialogue(callback) {
if (currentDialogueStep < dialogueSequence.length) {
var message = dialogueSequence[currentDialogueStep];
dialogueText.setText(message);
currentDialogueStep++;
// Auto advance after 2 seconds
LK.setTimeout(function () {
showNextDialogue(callback);
}, 2000);
} else {
hideDialogue(callback);
}
}
function hideDialogue(callback) {
if (!isDialogueActive) return;
// Animate dialogue box out
tween(dialogueBox, {
y: 2200,
alpha: 0
}, {
duration: 500,
easing: tween.easeIn,
onFinish: function onFinish() {
if (dialogueBox) {
dialogueBox.destroy();
dialogueBox = null;
dialogueText = null;
}
isDialogueActive = false;
gamePhase = 'playing';
if (callback) callback();
}
});
}
function startGame() {
gamePhase = 'setup';
// Hide 3vs play button when starting 3-player mode
if (gameMode === '3vs') {
play3vsButton.visible = false;
}
// Hide menu bullets
hideMenuBullets();
// Show different dialogue based on game mode
var dialogueMessages;
if (gameMode === 'ai') {
dialogueMessages = [getText('aiWelcome')];
} else {
dialogueMessages = [getText('dialogueP1Start'), getText('dialogueP2Start'), getText('dialogueP1Confident'), getText('dialogueP2Determined')];
}
showDialogue(dialogueMessages, function () {
continueGameStart();
});
}
function showLanguageSelection() {
if (!isLanguageSelectionOpen) return;
gamePhase = 'languageSelection';
// Hide 3vs play button in language selection
play3vsButton.visible = false;
// Create language buttons in a grid
var buttonsPerRow = 3;
var startY = 800;
var rowHeight = 200;
var buttonWidth = 600;
var spacing = (2048 - buttonsPerRow * buttonWidth) / (buttonsPerRow + 1);
for (var i = 0; i < availableLanguages.length; i++) {
var langCode = availableLanguages[i];
var langName = currentLanguageNames[langCode];
var row = Math.floor(i / buttonsPerRow);
var col = i % buttonsPerRow;
var x = spacing + col * (buttonWidth + spacing) + buttonWidth / 2;
var y = startY + row * rowHeight;
var langButton = game.addChild(new GameButton(langName, createLanguageCallback(langCode)));
langButton.x = x;
langButton.y = y;
langButton.scaleX = 0.75;
langButton.scaleY = 0.75;
languageButtons.push(langButton);
}
}
function createLanguageCallback(langCode) {
return function () {
selectLanguageAndContinue(langCode);
};
}
function selectLanguageAndContinue(langCode) {
changeLanguage(langCode);
hideLanguageSelection();
showMainMenu();
}
function hideLanguageSelection() {
if (!isLanguageSelectionOpen) return;
isLanguageSelectionOpen = false;
// Remove language buttons
for (var i = 0; i < languageButtons.length; i++) {
languageButtons[i].destroy();
}
languageButtons = [];
// Hide language selection bullets
for (var i = 0; i < languageSelectionBullets.length; i++) {
tween(languageSelectionBullets[i], {
alpha: 0
}, {
duration: 300,
onFinish: function onFinish() {
this.visible = false;
}
});
}
// Create menu bullets
for (var i = 0; i < 20; i++) {
var bullet = new MenuBullet();
bullet.x = Math.random() * 2048;
bullet.y = Math.random() * 2732;
bullet.lastY = bullet.y;
// Make bullets larger
bullet.scaleX = 2.5;
bullet.scaleY = 2.5;
// Add rotation animation with tween
tween(bullet.children[0], {
rotation: Math.PI * 4
}, {
duration: 3000 + Math.random() * 2000,
easing: tween.linear,
onFinish: function onFinish() {
// Restart rotation animation
this.rotation = 0;
tween(this, {
rotation: Math.PI * 4
}, {
duration: 3000 + Math.random() * 2000,
easing: tween.linear
});
}
});
menuBullets.push(bullet);
game.addChild(bullet);
}
}
// Target selection variables
var targetSelectionButtons = [];
var isTargetSelectionActive = false;
function showTargetSelection() {
if (isTargetSelectionActive) return;
isTargetSelectionActive = true;
gamePhase = 'targetSelection';
// Hide action buttons temporarily
shootOpponentButton.visible = false;
shootSelfButton.visible = false;
for (var i = 0; i < itemButtons.length; i++) {
itemButtons[i].visible = false;
}
// Show info about target selection
infoText.setText('Selecciona a qué jugador disparar');
// Get possible targets (alive players except current player)
var possibleTargets = [];
if (currentPlayer !== 1 && player1.isAlive) possibleTargets.push({
player: player1,
number: 1
});
if (currentPlayer !== 2 && player2.isAlive) possibleTargets.push({
player: player2,
number: 2
});
if (currentPlayer !== 3 && player3.isAlive) possibleTargets.push({
player: player3,
number: 3
});
// Create target selection buttons
for (var i = 0; i < possibleTargets.length; i++) {
var target = possibleTargets[i];
var targetButton = game.addChild(new GameButton('Jugador ' + target.number, createTargetCallback(target.player)));
targetButton.x = 800 + i * 250;
targetButton.y = 1200;
targetButton.scaleX = 0.8;
targetButton.scaleY = 0.8;
targetSelectionButtons.push(targetButton);
}
}
function createTargetCallback(targetPlayer) {
return function () {
selectTarget(targetPlayer);
};
}
function continueGameStart() {
// Show game elements
player1.visible = true;
player2.visible = true;
if (gameMode === '3vs') {
player3.visible = true;
}
revolver.visible = true;
weaponTable.visible = true;
turnText.visible = true;
// Hide menu buttons
playButton.visible = false;
playAIButton.visible = false;
skinsButton.visible = false;
// Apply selected skin to revolver
if (revolver && revolver.children[0]) {
var oldAsset = revolver.children[0];
revolver.removeChild(oldAsset);
var newAsset = revolver.attachAsset(currentSkin, {
anchorX: 0.5,
anchorY: 0.5
});
}
// Show action buttons (only for human player in AI mode)
shootOpponentButton.visible = true;
shootSelfButton.visible = true;
// Start the game
setupRound();
// Start music if enabled
if (isMusicOn) {
LK.playMusic('gameMusic');
}
}
function selectTarget(targetPlayer) {
hideTargetSelection();
// Fire at selected target
var result = revolver.fire();
var opponent = targetPlayer;
// Zoom effect toward the opponent being shot
tween(game, {
scaleX: 1.3,
scaleY: 1.3,
x: -(opponent.x * 1.3 - 1024),
// Focus camera on opponent
y: -(opponent.y * 1.3 - 1366) // Focus camera on opponent
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
// Zoom back out
tween(game, {
scaleX: 1.0,
scaleY: 1.0,
x: 0,
y: 0
}, {
duration: 800,
easing: tween.easeInOut
});
}
});
if (result === true) {
// Live round - opponent takes damage
LK.getSound('gunshot').play();
opponent.takeDamage();
infoText.setText('¡BANG! ¡Oponente impactado!');
if (!opponent.isAlive) {
endGame(currentPlayer);
return;
}
} else if (result === false) {
// Blank round
LK.getSound('click').play();
infoText.setText('*Clic* - Bala de fogueo');
} else {
// Empty chamber
LK.getSound('empty_click').play();
infoText.setText('*Clic* - Recámara vacía');
}
// End turn
LK.setTimeout(function () {
switchTurn();
}, 1500);
}
Haceme un humano desde arriba sentado realista. con camisa amarilla
Haceme un humano desde arriba sentado realista. con camisa roja
Escopeta realista. In-Game asset. 2d. High contrast. No shadows
Pistola realista. In-Game asset. 2d. High contrast. No shadows
Revolver realista. In-Game asset. 2d. High contrast. No shadows
Bala realista. In-Game asset. 2d. High contrast. No shadows
Papel realista. In-Game asset. 2d. High contrast. No shadows
Mesa desde arriba Realista. In-Game asset. 2d. High contrast. No shadows
Barra de salud verde. In-Game asset. 2d. High contrast. No shadows