Code edit (3 edits merged)
Please save this source code
Code edit (1 edits merged)
Please save this source code
User prompt
Permite que la muΜsica suene desde el menuΜ
User prompt
Aumenta el tamanΜo de la fuente del tiΜtulo un 25% y dale una fuente que se asocie con lo maΜgico
User prompt
Sube el tiΜtulo Elemental Battle
User prompt
Baja un poco maΜs el botoΜn de play
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot set properties of null (setting 'visible')' in or related to this line: 'statusText.visible = true;' Line Number: 560
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot set properties of null (setting 'visible')' in or related to this line: 'statusText.visible = true;' Line Number: 560
User prompt
Has que cuando el jugador pierda o gane, regrese al menuΜ principal y baja un poco maΜs el botoΜn de play
User prompt
Crea un pequenΜo menuΜ, manteΜn el circulo girando en su posicioΜn y debajo de eΜl un botoΜn de play
User prompt
Ya existe el sonido cardWin para cuando el jugador gana el turno, crea un asset para cuando pierde
User prompt
Cuando se usa una carta, si no fue empate, se descarta, no importa si el jugador o enemigo gano o perdioΜ, ambas se descartan
User prompt
Agrega nuevos assets para estas 4 cartas
User prompt
Agrega otras 4 cartas: Tierra: Gaia (atk 100, def 100) Agua: Moon(atk 100, def 100) Fuego: Sun(atk 100, def 100) Aire: Ether(atk 100, def 100)
Code edit (1 edits merged)
Please save this source code
User prompt
Correcto, cambia la condicioΜn de victoria a ganar 5 combates en lugar de 3
User prompt
Ya funciona pero hay un error, cuando se selecciona el botoΜn attack o defense, la previsualizacioΜn de la carta en grande se queda hasta que se elige otra
User prompt
Cuando el usuario tiene ventaja de tipo no se muestra sobre la carta del jugador el +10, cuando el enemigo tiene ventaja siΜ funciona
User prompt
Ahora, has que una vez descartada una carta, el jugador o el enemigo obtenga otra que no se haya jugado por ninguni
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'indexOf')' in or related to this line: 'if (child.text.indexOf('ATK:') !== -1) {' Line Number: 615
User prompt
Has que cuando sale el texto de bonus dure medio segundo maΜs para que el usuario pueda leer βͺπ‘ Consider importing and using the following plugins: @upit/tween.v1
User prompt
Has que cuando tengas ventaja o desventaja, la carda con el bonus tenga escrito "+ 10" en grande sobre las estadiΜsticas βͺπ‘ Consider importing and using the following plugins: @upit/tween.v1
User prompt
Agrega unas reglas al momento de entrar en batalla para dar bonificaciones por tipo: Fuego > Aire > Agua > Tierra > Fuego Cuando se enfrentan, la carta que tiene ventaja gana un +10 en sus estadiΜsticas en ese combate. El cambio debe verse reflejado al revelar las cartas con un Atk: 80 + 10 y Def: 80 + 10 por ejemplo βͺπ‘ Consider importing and using the following plugins: @upit/tween.v1
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
/**** * Classes
****/
var Card = Container.expand(function (cardData) {
var self = Container.call(this);
self.cardData = cardData;
self.isSelected = false;
var cardBg = self.attachAsset(cardData.element.toLowerCase() + 'CardBase', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.2,
scaleY: 1.15
});
var elementGraphic = self.attachAsset(cardData.name.toLowerCase() + 'Card', {
anchorX: 0.5,
anchorY: 0.5,
y: -20
});
var textBg = self.attachAsset('textBackground', {
anchorX: 0.5,
anchorY: 0.5,
y: 95,
alpha: 0.7
});
var nameText = new Text2(cardData.name, {
size: 24,
fill: 0x000000
});
nameText.anchor.set(0.5, 0.5);
nameText.x = 0;
nameText.y = 70;
self.addChild(nameText);
var attackText = new Text2('ATK: ' + cardData.attack, {
size: 20,
fill: 0xcc1010,
stroke: 0xFFFFFF,
strokeThickness: 2
});
attackText.anchor.set(0.5, 0.5);
attackText.y = 95;
self.addChild(attackText);
var defenseText = new Text2('DEF: ' + cardData.defense, {
size: 20,
fill: 0x2795c4,
stroke: 0xFFFFFF,
strokeThickness: 2
});
defenseText.anchor.set(0.5, 0.5);
defenseText.y = 120;
self.addChild(defenseText);
self.setSelected = function (selected) {
self.isSelected = selected;
self.scaleX = selected ? 1.65 : 1.5;
self.scaleY = selected ? 1.65 : 1.5;
};
self.down = function (x, y, obj) {
if (gameState === GAME_STATE.SELECT_CARD && !self.isSelected || gameState === GAME_STATE.SELECT_MODE && !self.isSelected) {
selectCard(self);
LK.getSound('cardSelect').play();
}
};
return self;
});
var ModeButton = Container.expand(function (mode, color) {
var self = Container.call(this);
self.mode = mode;
var buttonBg = self.attachAsset(mode.toLowerCase() + 'Button', {
anchorX: 0.5,
anchorY: 0.5
});
var buttonText = new Text2(mode.toUpperCase(), {
size: 45,
fill: 0xFFFFFF
});
buttonText.anchor.set(0.5, 0.5);
self.addChild(buttonText);
self.down = function (x, y, obj) {
if (gameState === GAME_STATE.SELECT_MODE && selectedCard) {
playerMode = mode.toLowerCase();
startBattle();
}
};
return self;
});
var PlayButton = Container.expand(function () {
var self = Container.call(this);
var buttonBg = self.attachAsset('playButton', {
anchorX: 0.5,
anchorY: 0.5
});
var buttonText = new Text2('PLAY', {
size: 50,
fill: 0xFFFFFF
});
buttonText.anchor.set(0.5, 0.5);
self.addChild(buttonText);
self.down = function (x, y, obj) {
if (gameState === GAME_STATE.MENU) {
startGame();
}
};
return self;
});
/****
* Initialize Game
****/
/**** * Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x0f1419
});
/****
* Game Code
****/
/**** * Constants & Configurations (Arquitectura mejorada)
****/
/**** * Plugins
****/
/**** * Game State Variables
****/
var GAME_STATE = {
MENU: 'menu',
SELECT_CARD: 'selectCard',
SELECT_MODE: 'selectMode',
BATTLE: 'battle',
RESULT: 'result'
};
var COMBAT_MODE = {
ATTACK: 'attack',
DEFENSE: 'defense'
};
var BATTLE_RESULT = {
PLAYER_WIN: 'playerWin',
ENEMY_WIN: 'enemyWin',
TIE: 'tie'
};
var SCREEN = {
CENTER_X: 1024,
CENTER_Y: 1200
};
// Ventaja de tipos (Sacado de la lΓ³gica para optimizar memoria)
var ELEMENT_ADVANTAGES = {
'Fire': 'Air',
'Air': 'Water',
'Water': 'Earth',
'Earth': 'Fire'
};
// Base de datos de cartas
var cardDatabase = [{
name: 'Sea',
element: 'Water',
attack: 100,
defense: 90
}, {
name: 'Rain',
element: 'Water',
attack: 80,
defense: 90
}, {
name: 'Tsunami',
element: 'Water',
attack: 90,
defense: 100
}, {
name: 'River',
element: 'Water',
attack: 90,
defense: 80
}, {
name: 'Ice',
element: 'Water',
attack: 90,
defense: 90
}, {
name: 'Inferno',
element: 'Fire',
attack: 100,
defense: 90
}, {
name: 'Ember',
element: 'Fire',
attack: 90,
defense: 80
}, {
name: 'Lightning',
element: 'Fire',
attack: 90,
defense: 100
}, {
name: 'Flame',
element: 'Fire',
attack: 90,
defense: 90
}, {
name: 'Spark',
element: 'Fire',
attack: 80,
defense: 90
}, {
name: 'Mountain',
element: 'Earth',
attack: 100,
defense: 90
}, {
name: 'Stone',
element: 'Earth',
attack: 90,
defense: 80
}, {
name: 'Boulder',
element: 'Earth',
attack: 90,
defense: 100
}, {
name: 'Sand',
element: 'Earth',
attack: 80,
defense: 90
}, {
name: 'Crystal',
element: 'Earth',
attack: 90,
defense: 90
}, {
name: 'Tornado',
element: 'Air',
attack: 100,
defense: 90
}, {
name: 'Breeze',
element: 'Air',
attack: 80,
defense: 90
}, {
name: 'Gale',
element: 'Air',
attack: 90,
defense: 90
}, {
name: 'Wind',
element: 'Air',
attack: 90,
defense: 80
}, {
name: 'Storm',
element: 'Air',
attack: 90,
defense: 100
}, {
name: 'Metal',
element: 'Earth',
attack: 100,
defense: 80
}, {
name: 'Cave',
element: 'Earth',
attack: 80,
defense: 100
}, {
name: 'Glacier',
element: 'Water',
attack: 100,
defense: 80
}, {
name: 'Mist',
element: 'Water',
attack: 80,
defense: 100
}, {
name: 'Volcano',
element: 'Fire',
attack: 100,
defense: 80
}, {
name: 'Ashes',
element: 'Fire',
attack: 80,
defense: 100
}, {
name: 'Cloud',
element: 'Air',
attack: 80,
defense: 100
}, {
name: 'Whirlwind',
element: 'Air',
attack: 100,
defense: 80
}, {
name: 'Gaia',
element: 'Earth',
attack: 100,
defense: 100
}, {
name: 'Moon',
element: 'Water',
attack: 100,
defense: 100
}, {
name: 'Sun',
element: 'Fire',
attack: 100,
defense: 100
}, {
name: 'Ether',
element: 'Air',
attack: 100,
defense: 100
}];
var gameState = GAME_STATE.MENU;
var playerHand = [];
var enemyHand = [];
var usedCards = [];
var selectedCard = null;
var enemySelectedCard = null;
var playerMode = null;
var enemyMode = null;
var battleResult = null;
var playerWins = 0;
var enemyWins = 0;
// UI elements
var handContainer = new Container();
var modeButtons = new Container();
var battleSquareContainer = new Container();
var battleSquares = [];
var statusText = null;
var playerModeText = null;
var enemyModeText = null;
var enlargedCardContainer = new Container();
var enlargedCard = null;
var enemyCardContainer = new Container();
var enemyCard = null;
var playerWinsText = null;
var enemyWinsText = null;
var enemyHandContainer = new Container();
var enemyCardBacks = [];
var menuContainer = new Container();
var playButton = null;
var titleText = null;
/**** * Core Functions
****/
function initializeGame() {
usedCards = [];
var shuffledDeck = shuffleArray([].concat(cardDatabase));
for (var i = 0; i < 5; i++) {
playerHand.push(shuffledDeck[i]);
enemyHand.push(shuffledDeck[i + 5]);
usedCards.push(shuffledDeck[i], shuffledDeck[i + 5]);
}
setupUI();
displayPlayerHand();
displayEnemyHand();
LK.playMusic('backgroundMusic');
}
function shuffleArray(array) {
for (var i = array.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
// Destructuring swap
var _ref = [array[j], array[i]];
array[i] = _ref[0];
array[j] = _ref[1];
}
return array;
}
function getUnusedCards() {
return cardDatabase.filter(function (card) {
return !usedCards.some(function (used) {
return used.name === card.name;
});
});
}
function drawNewCard() {
var unusedCards = getUnusedCards();
if (unusedCards.length > 0) {
var randomIndex = Math.floor(Math.random() * unusedCards.length);
var newCard = unusedCards[randomIndex];
usedCards.push(newCard);
return newCard;
}
return null;
}
function replaceCardInHand(hand, cardToReplace, index) {
var newCard = drawNewCard();
if (newCard) {
hand[index] = newCard;
} else {
hand.splice(index, 1);
}
}
function setupMenu() {
var centerBackground = LK.getAsset('centerCircle', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.5
});
centerBackground.x = SCREEN.CENTER_X;
centerBackground.y = SCREEN.CENTER_Y;
game.addChild(centerBackground);
var radius = 200;
var squareAssets = ['battleSquare1', 'battleSquare2', 'battleSquare3', 'battleSquare4'];
for (var i = 0; i < 4; i++) {
var square = LK.getAsset(squareAssets[i], {
anchorX: 0.5,
anchorY: 0.5
});
var angle = i * Math.PI * 2 / 4;
square.x = SCREEN.CENTER_X + Math.cos(angle) * radius;
square.y = SCREEN.CENTER_Y + Math.sin(angle) * radius;
square.startAngle = angle;
game.addChild(square);
battleSquares.push(square);
}
titleText = new Text2('ELEMENTAL BATTLE', {
size: 150,
fill: 0xFFFFFF,
stroke: 0x000000,
strokeThickness: 4,
font: "serif"
});
titleText.anchor.set(0.5, 0.5);
titleText.x = SCREEN.CENTER_X;
titleText.y = 600;
menuContainer.addChild(titleText);
playButton = new PlayButton();
playButton.x = SCREEN.CENTER_X;
playButton.y = 1600;
menuContainer.addChild(playButton);
game.addChild(menuContainer);
}
function setupUI() {
handContainer.x = SCREEN.CENTER_X;
handContainer.y = 2400;
game.addChild(handContainer);
var attackButton = new ModeButton('Attack', 0xFF4444);
attackButton.x = 800;
attackButton.y = 1800;
var defenseButton = new ModeButton('Defense', 0x4444FF);
defenseButton.x = 1250;
defenseButton.y = 1800;
modeButtons.addChild(attackButton);
modeButtons.addChild(defenseButton);
game.addChild(modeButtons);
modeButtons.visible = false;
battleSquareContainer.x = SCREEN.CENTER_X;
battleSquareContainer.y = SCREEN.CENTER_Y;
game.addChild(battleSquareContainer);
statusText = new Text2('Select a card from your hand', {
size: 100,
fill: 0xFFFFFF
});
statusText.anchor.set(0.5, 0.5);
statusText.x = SCREEN.CENTER_X;
statusText.y = 2100;
game.addChild(statusText);
playerModeText = new Text2('', {
size: 72,
fill: 0xFFFF00
});
playerModeText.anchor.set(0.5, 0.5);
playerModeText.x = 800;
playerModeText.y = 1700;
game.addChild(playerModeText);
enemyModeText = new Text2('', {
size: 72,
fill: 0xFF8800
});
enemyModeText.anchor.set(0.5, 0.5);
enemyModeText.x = 1248;
enemyModeText.y = 700;
game.addChild(enemyModeText);
enlargedCardContainer.x = 350;
enlargedCardContainer.y = SCREEN.CENTER_Y;
game.addChild(enlargedCardContainer);
enemyCardContainer.x = 1700;
enemyCardContainer.y = SCREEN.CENTER_Y;
game.addChild(enemyCardContainer);
playerWinsText = new Text2('Player Wins: 0', {
size: 60,
fill: 0x00FF00
});
playerWinsText.anchor.set(0.5, 0.5);
playerWinsText.x = 400;
playerWinsText.y = 150;
game.addChild(playerWinsText);
enemyWinsText = new Text2('Enemy Wins: 0', {
size: 60,
fill: 0xFF0000
});
enemyWinsText.anchor.set(0.5, 0.5);
enemyWinsText.x = 1648;
enemyWinsText.y = 150;
game.addChild(enemyWinsText);
enemyHandContainer.x = SCREEN.CENTER_X;
enemyHandContainer.y = 400;
game.addChild(enemyHandContainer);
}
function startGame() {
gameState = GAME_STATE.SELECT_CARD;
menuContainer.visible = false;
initializeGame();
[handContainer, enemyHandContainer, statusText, playerModeText, enemyModeText, enlargedCardContainer, enemyCardContainer, playerWinsText, enemyWinsText].forEach(function (el) {
if (el) el.visible = true;
});
}
function displayPlayerHand() {
while (handContainer.children.length > 0) handContainer.removeChild(handContainer.children[0]);
for (var i = 0; i < playerHand.length; i++) {
var card = new Card(playerHand[i]);
card.scaleX = 1.5;
card.scaleY = 1.5;
card.x = (i - 2) * 350;
card.handIndex = i;
handContainer.addChild(card);
}
}
function displayEnemyHand() {
while (enemyHandContainer.children.length > 0) enemyHandContainer.removeChild(enemyHandContainer.children[0]);
enemyCardBacks = [];
for (var i = 0; i < enemyHand.length; i++) {
var cardBack = LK.getAsset(enemyHand[i].element.toLowerCase() + 'CardBack', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
cardBack.x = (i - 2) * 280;
cardBack.element = enemyHand[i].element;
enemyHandContainer.addChild(cardBack);
enemyCardBacks.push(cardBack);
}
}
function selectCard(cardObj) {
if (selectedCard === cardObj && gameState === GAME_STATE.SELECT_MODE) return;
for (var i = 0; i < handContainer.children.length; i++) {
handContainer.children[i].setSelected(false);
}
cardObj.setSelected(true);
selectedCard = cardObj;
if (enlargedCard) {
tween.stop(enlargedCard);
tween(enlargedCard, {
alpha: 0,
scaleX: 0.5,
scaleY: 0.5
}, {
duration: 150,
easing: tween.easeIn,
onFinish: function onFinish() {
enlargedCardContainer.removeChild(enlargedCard);
enlargedCard = null;
createEnlargedCard(cardObj);
}
});
} else {
createEnlargedCard(cardObj);
}
if (gameState !== GAME_STATE.SELECT_MODE) {
gameState = GAME_STATE.SELECT_MODE;
statusText.setText('Choose Attack or Defense mode');
modeButtons.visible = true;
}
}
function createEnlargedCard(cardObj) {
enlargedCard = new Card(cardObj.cardData);
if (gameState === GAME_STATE.BATTLE && enemySelectedCard) {
if (hasTypeAdvantage(cardObj.cardData.element, enemySelectedCard.element)) {
applyBonusVisuals(enlargedCard, cardObj.cardData);
}
}
setupCardAnimation(enlargedCard, enlargedCardContainer);
}
function createEnemyCardPreview(cardData) {
if (enemyCard) {
tween.stop(enemyCard);
tween(enemyCard, {
alpha: 0,
scaleX: 0.5,
scaleY: 0.5
}, {
duration: 150,
easing: tween.easeIn,
onFinish: function onFinish() {
enemyCardContainer.removeChild(enemyCard);
enemyCard = null;
createNewEnemyCard(cardData);
}
});
} else {
createNewEnemyCard(cardData);
}
}
function createNewEnemyCard(cardData) {
enemyCard = new Card(cardData);
if (gameState === GAME_STATE.BATTLE && selectedCard) {
if (hasTypeAdvantage(cardData.element, selectedCard.cardData.element)) {
applyBonusVisuals(enemyCard, cardData);
}
}
setupCardAnimation(enemyCard, enemyCardContainer);
}
function applyBonusVisuals(cardUI, cardData) {
for (var i = 0; i < cardUI.children.length; i++) {
var child = cardUI.children[i];
if (child instanceof Text2) {
if (child.text && child.text.indexOf('ATK:') !== -1) {
child.setText('ATK: ' + cardData.attack + ' + 10');
} else if (child.text && child.text.indexOf('DEF:') !== -1) {
child.setText('DEF: ' + cardData.defense + ' + 10');
}
}
}
var bonusText = new Text2('+ 10', {
size: 80,
fill: 0x00FF00,
stroke: 0xFFFFFF,
strokeThickness: 3
});
bonusText.anchor.set(0.5, 0.5);
bonusText.x = 0;
bonusText.y = -80;
cardUI.addChild(bonusText);
}
function setupCardAnimation(cardUI, container) {
cardUI.scaleX = 0.5;
cardUI.scaleY = 0.5;
cardUI.x = 0;
cardUI.y = 0;
cardUI.alpha = 0;
container.addChild(cardUI);
tween(cardUI, {
alpha: 1,
scaleX: 2.75,
scaleY: 2.75
}, {
duration: 300,
easing: tween.easeOut
});
}
function startBattle() {
gameState = GAME_STATE.BATTLE;
modeButtons.visible = false;
if (enlargedCard) {
tween(enlargedCard, {
alpha: 0,
scaleX: 0.5,
scaleY: 0.5
}, {
duration: 200,
easing: tween.easeIn,
onFinish: function onFinish() {
enlargedCardContainer.removeChild(enlargedCard);
enlargedCard = null;
}
});
}
var enemyCardIndex = Math.floor(Math.random() * enemyHand.length);
enemySelectedCard = enemyHand[enemyCardIndex];
enemyMode = Math.random() < 0.5 ? COMBAT_MODE.ATTACK : COMBAT_MODE.DEFENSE;
statusText.setText('Battle in progress...');
playerModeText.setText('Player: ' + playerMode.toUpperCase());
enemyModeText.setText('Enemy: ' + enemyMode.toUpperCase());
LK.setTimeout(function () {
if (selectedCard) createEnlargedCard(selectedCard);
createEnemyCardPreview(enemySelectedCard);
}, 300);
LK.setTimeout(resolveBattle, 2500);
LK.getSound('cardBattle').play();
}
function hasTypeAdvantage(attacker, defender) {
return ELEMENT_ADVANTAGES[attacker] === defender;
}
function resolveBattle() {
var playerCard = selectedCard.cardData;
var enemyData = enemySelectedCard;
var playerValue = playerMode === COMBAT_MODE.ATTACK ? playerCard.attack : playerCard.defense;
var enemyValue = enemyMode === COMBAT_MODE.ATTACK ? enemyData.attack : enemyData.defense;
if (hasTypeAdvantage(playerCard.element, enemyData.element)) playerValue += 10;
if (hasTypeAdvantage(enemyData.element, playerCard.element)) enemyValue += 10;
var resultText = '';
if (playerMode === COMBAT_MODE.DEFENSE && enemyMode === COMBAT_MODE.DEFENSE) {
resultText = 'Both defended - cards returned to hand';
battleResult = BATTLE_RESULT.TIE;
} else if (playerValue > enemyValue) {
resultText = 'You win this round!';
battleResult = BATTLE_RESULT.PLAYER_WIN;
playerWins++;
playerWinsText.setText('Player Wins: ' + playerWins);
usedCards.push(enemyData, playerCard);
replaceCardInHand(enemyHand, enemySelectedCard, enemyHand.indexOf(enemySelectedCard));
replaceCardInHand(playerHand, playerCard, selectedCard.handIndex);
displayEnemyHand();
LK.getSound('cardWin').play();
} else if (enemyValue > playerValue) {
resultText = 'Enemy wins this round!';
battleResult = BATTLE_RESULT.ENEMY_WIN;
enemyWins++;
enemyWinsText.setText('Enemy Wins: ' + enemyWins);
usedCards.push(playerCard, enemyData);
replaceCardInHand(playerHand, playerCard, selectedCard.handIndex);
replaceCardInHand(enemyHand, enemySelectedCard, enemyHand.indexOf(enemySelectedCard));
displayEnemyHand();
LK.getSound('cardLose').play();
} else {
resultText = 'Tie - both cards returned to hand';
battleResult = BATTLE_RESULT.TIE;
}
statusText.setText(resultText);
LK.setTimeout(checkWinCondition, 2500);
}
function checkWinCondition() {
if (playerWins >= 5) {
statusText.setText('Victory - You won 5 rounds!');
LK.setScore(playerWins * 100);
LK.setTimeout(resetGameToMenu, 2000);
} else if (enemyWins >= 5) {
statusText.setText('Game Over - Enemy won 5 rounds!');
LK.setTimeout(resetGameToMenu, 2000);
} else {
resetForNextRound();
}
}
function resetForNextRound() {
selectedCard = null;
enemySelectedCard = null;
playerMode = null;
enemyMode = null;
battleResult = null;
playerModeText.setText('');
enemyModeText.setText('');
gameState = GAME_STATE.SELECT_CARD;
statusText.setText('Select a card from your hand');
if (enlargedCard) {
tween(enlargedCard, {
alpha: 0,
scaleX: 0.5,
scaleY: 0.5
}, {
duration: 200,
easing: tween.easeIn,
onFinish: function onFinish() {
enlargedCardContainer.removeChild(enlargedCard);
enlargedCard = null;
}
});
}
if (enemyCard) {
tween(enemyCard, {
alpha: 0,
scaleX: 0.5,
scaleY: 0.5
}, {
duration: 200,
easing: tween.easeIn,
onFinish: function onFinish() {
enemyCardContainer.removeChild(enemyCard);
enemyCard = null;
}
});
}
displayPlayerHand();
}
// Initialize the menu
setupMenu();
LK.playMusic('backgroundMusic');
game.update = function () {
var time = LK.ticks * 0.02;
var radius = 200;
for (var i = 0; i < battleSquares.length; i++) {
var square = battleSquares[i];
if (square && square.startAngle !== undefined) {
var angle = square.startAngle + time;
square.x = SCREEN.CENTER_X + radius * Math.cos(angle);
square.y = SCREEN.CENTER_Y + radius * Math.sin(angle);
}
}
};
function resetGameToMenu() {
gameState = GAME_STATE.MENU;
playerHand = [];
enemyHand = [];
usedCards = [];
selectedCard = null;
enemySelectedCard = null;
playerMode = null;
enemyMode = null;
battleResult = null;
playerWins = 0;
enemyWins = 0;
while (handContainer.children.length > 0) handContainer.removeChild(handContainer.children[0]);
while (enemyHandContainer.children.length > 0) enemyHandContainer.removeChild(enemyHandContainer.children[0]);
if (enlargedCard) {
enlargedCardContainer.removeChild(enlargedCard);
enlargedCard = null;
}
if (enemyCard) {
enemyCardContainer.removeChild(enemyCard);
enemyCard = null;
}
[statusText, playerModeText, enemyModeText, playerWinsText, enemyWinsText, modeButtons, handContainer, enemyHandContainer, enlargedCardContainer, enemyCardContainer].forEach(function (el) {
if (el) {
el.visible = false;
if (el.setText) el.setText('');
}
});
if (playerWinsText) playerWinsText.setText('Player Wins: 0');
if (enemyWinsText) enemyWinsText.setText('Enemy Wins: 0');
menuContainer.visible = true;
} ===================================================================
--- original.js
+++ change.js
@@ -5,8 +5,10 @@
/****
* Classes
****/
+/**** * Classes
+****/
var Card = Container.expand(function (cardData) {
var self = Container.call(this);
self.cardData = cardData;
self.isSelected = false;
@@ -54,18 +56,13 @@
defenseText.y = 120;
self.addChild(defenseText);
self.setSelected = function (selected) {
self.isSelected = selected;
- if (selected) {
- self.scaleX = 1.65; // 1.5 * 1.1 to maintain size increase with selection effect
- self.scaleY = 1.65; // 1.5 * 1.1 to maintain size increase with selection effect
- } else {
- self.scaleX = 1.5; // Return to the 50% increased base size to match enemy cards
- self.scaleY = 1.5; // Return to the 50% increased base size to match enemy cards
- }
+ self.scaleX = selected ? 1.65 : 1.5;
+ self.scaleY = selected ? 1.65 : 1.5;
};
self.down = function (x, y, obj) {
- if (gameState === 'selectCard' && !self.isSelected || gameState === 'selectMode' && !self.isSelected) {
+ if (gameState === GAME_STATE.SELECT_CARD && !self.isSelected || gameState === GAME_STATE.SELECT_MODE && !self.isSelected) {
selectCard(self);
LK.getSound('cardSelect').play();
}
};
@@ -84,9 +81,9 @@
});
buttonText.anchor.set(0.5, 0.5);
self.addChild(buttonText);
self.down = function (x, y, obj) {
- if (gameState === 'selectMode' && selectedCard) {
+ if (gameState === GAME_STATE.SELECT_MODE && selectedCard) {
playerMode = mode.toLowerCase();
startBattle();
}
};
@@ -104,9 +101,9 @@
});
buttonText.anchor.set(0.5, 0.5);
self.addChild(buttonText);
self.down = function (x, y, obj) {
- if (gameState === 'menu') {
+ if (gameState === GAME_STATE.MENU) {
startGame();
}
};
return self;
@@ -114,18 +111,51 @@
/****
* Initialize Game
****/
+/**** * Initialize Game
+****/
var game = new LK.Game({
backgroundColor: 0x0f1419
});
/****
* Game Code
****/
-// Card database
-// Individual card base assets
-// Individual card element graphics
+/**** * Constants & Configurations (Arquitectura mejorada)
+****/
+/**** * Plugins
+****/
+/**** * Game State Variables
+****/
+var GAME_STATE = {
+ MENU: 'menu',
+ SELECT_CARD: 'selectCard',
+ SELECT_MODE: 'selectMode',
+ BATTLE: 'battle',
+ RESULT: 'result'
+};
+var COMBAT_MODE = {
+ ATTACK: 'attack',
+ DEFENSE: 'defense'
+};
+var BATTLE_RESULT = {
+ PLAYER_WIN: 'playerWin',
+ ENEMY_WIN: 'enemyWin',
+ TIE: 'tie'
+};
+var SCREEN = {
+ CENTER_X: 1024,
+ CENTER_Y: 1200
+};
+// Ventaja de tipos (Sacado de la lΓ³gica para optimizar memoria)
+var ELEMENT_ADVANTAGES = {
+ 'Fire': 'Air',
+ 'Air': 'Water',
+ 'Water': 'Earth',
+ 'Earth': 'Fire'
+};
+// Base de datos de cartas
var cardDatabase = [{
name: 'Sea',
element: 'Water',
attack: 100,
@@ -285,13 +315,12 @@
element: 'Air',
attack: 100,
defense: 100
}];
-// Game state variables
-var gameState = 'menu'; // 'menu', 'selectCard', 'selectMode', 'battle', 'result'
+var gameState = GAME_STATE.MENU;
var playerHand = [];
var enemyHand = [];
-var usedCards = []; // Track cards that have been used by both players
+var usedCards = [];
var selectedCard = null;
var enemySelectedCard = null;
var playerMode = null;
var enemyMode = null;
@@ -300,11 +329,10 @@
var enemyWins = 0;
// UI elements
var handContainer = new Container();
var modeButtons = new Container();
-var battleArea = null;
-var battleSquares = [];
var battleSquareContainer = new Container();
+var battleSquares = [];
var statusText = null;
var playerModeText = null;
var enemyModeText = null;
var enlargedCardContainer = new Container();
@@ -314,24 +342,20 @@
var playerWinsText = null;
var enemyWinsText = null;
var enemyHandContainer = new Container();
var enemyCardBacks = [];
-// Menu UI elements
var menuContainer = new Container();
var playButton = null;
var titleText = null;
-// Initialize game
+/**** * Core Functions
+****/
function initializeGame() {
- // Reset used cards list
usedCards = [];
- // Deal 5 random cards to each player
var shuffledDeck = shuffleArray([].concat(cardDatabase));
for (var i = 0; i < 5; i++) {
playerHand.push(shuffledDeck[i]);
enemyHand.push(shuffledDeck[i + 5]);
- // Mark initial cards as used
- usedCards.push(shuffledDeck[i]);
- usedCards.push(shuffledDeck[i + 5]);
+ usedCards.push(shuffledDeck[i], shuffledDeck[i + 5]);
}
setupUI();
displayPlayerHand();
displayEnemyHand();
@@ -339,29 +363,21 @@
}
function shuffleArray(array) {
for (var i = array.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
- var temp = array[i];
- array[i] = array[j];
- array[j] = temp;
+ // Destructuring swap
+ var _ref = [array[j], array[i]];
+ array[i] = _ref[0];
+ array[j] = _ref[1];
}
return array;
}
function getUnusedCards() {
- var unused = [];
- for (var i = 0; i < cardDatabase.length; i++) {
- var isUsed = false;
- for (var j = 0; j < usedCards.length; j++) {
- if (cardDatabase[i].name === usedCards[j].name) {
- isUsed = true;
- break;
- }
- }
- if (!isUsed) {
- unused.push(cardDatabase[i]);
- }
- }
- return unused;
+ return cardDatabase.filter(function (card) {
+ return !usedCards.some(function (used) {
+ return used.name === card.name;
+ });
+ });
}
function drawNewCard() {
var unusedCards = getUnusedCards();
if (unusedCards.length > 0) {
@@ -369,61 +385,62 @@
var newCard = unusedCards[randomIndex];
usedCards.push(newCard);
return newCard;
}
- return null; // No more unused cards available
+ return null;
}
+function replaceCardInHand(hand, cardToReplace, index) {
+ var newCard = drawNewCard();
+ if (newCard) {
+ hand[index] = newCard;
+ } else {
+ hand.splice(index, 1);
+ }
+}
function setupMenu() {
- // Add center background circle behind battle squares
var centerBackground = LK.getAsset('centerCircle', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.5
});
- centerBackground.x = 1024;
- centerBackground.y = 1200;
+ centerBackground.x = SCREEN.CENTER_X;
+ centerBackground.y = SCREEN.CENTER_Y;
game.addChild(centerBackground);
- // Create 4 squares in circular formation around screen center
var radius = 200;
var squareAssets = ['battleSquare1', 'battleSquare2', 'battleSquare3', 'battleSquare4'];
for (var i = 0; i < 4; i++) {
var square = LK.getAsset(squareAssets[i], {
anchorX: 0.5,
anchorY: 0.5
});
- // Initial position in circle around screen center (1024, 1200)
- var angle = i * Math.PI * 2 / 4; // 90 degrees apart
- square.x = 1024 + Math.cos(angle) * radius;
- square.y = 1200 + Math.sin(angle) * radius;
- square.startAngle = angle; // Store initial angle for parametric motion
+ var angle = i * Math.PI * 2 / 4;
+ square.x = SCREEN.CENTER_X + Math.cos(angle) * radius;
+ square.y = SCREEN.CENTER_Y + Math.sin(angle) * radius;
+ square.startAngle = angle;
game.addChild(square);
battleSquares.push(square);
}
- // Title text
titleText = new Text2('ELEMENTAL BATTLE', {
size: 150,
fill: 0xFFFFFF,
stroke: 0x000000,
strokeThickness: 4,
font: "serif"
});
titleText.anchor.set(0.5, 0.5);
- titleText.x = 1024;
+ titleText.x = SCREEN.CENTER_X;
titleText.y = 600;
menuContainer.addChild(titleText);
- // Play button
playButton = new PlayButton();
- playButton.x = 1024;
+ playButton.x = SCREEN.CENTER_X;
playButton.y = 1600;
menuContainer.addChild(playButton);
game.addChild(menuContainer);
}
function setupUI() {
- // Hand container for player cards
- handContainer.x = 1024;
+ handContainer.x = SCREEN.CENTER_X;
handContainer.y = 2400;
game.addChild(handContainer);
- // Mode selection buttons
var attackButton = new ModeButton('Attack', 0xFF4444);
attackButton.x = 800;
attackButton.y = 1800;
var defenseButton = new ModeButton('Defense', 0x4444FF);
@@ -432,22 +449,19 @@
modeButtons.addChild(attackButton);
modeButtons.addChild(defenseButton);
game.addChild(modeButtons);
modeButtons.visible = false;
- // Battle area with 4 rotating squares
- battleSquareContainer.x = 1024;
- battleSquareContainer.y = 1200;
+ battleSquareContainer.x = SCREEN.CENTER_X;
+ battleSquareContainer.y = SCREEN.CENTER_Y;
game.addChild(battleSquareContainer);
- // Status text
statusText = new Text2('Select a card from your hand', {
size: 100,
fill: 0xFFFFFF
});
statusText.anchor.set(0.5, 0.5);
- statusText.x = 1024;
+ statusText.x = SCREEN.CENTER_X;
statusText.y = 2100;
game.addChild(statusText);
- // Mode display texts
playerModeText = new Text2('', {
size: 72,
fill: 0xFFFF00
});
@@ -462,121 +476,76 @@
enemyModeText.anchor.set(0.5, 0.5);
enemyModeText.x = 1248;
enemyModeText.y = 700;
game.addChild(enemyModeText);
- // Enlarged card display area
enlargedCardContainer.x = 350;
- enlargedCardContainer.y = 1200;
+ enlargedCardContainer.y = SCREEN.CENTER_Y;
game.addChild(enlargedCardContainer);
- // Enemy card display area
enemyCardContainer.x = 1700;
- enemyCardContainer.y = 1200;
+ enemyCardContainer.y = SCREEN.CENTER_Y;
game.addChild(enemyCardContainer);
- // Player wins counter
playerWinsText = new Text2('Player Wins: 0', {
size: 60,
fill: 0x00FF00
});
playerWinsText.anchor.set(0.5, 0.5);
playerWinsText.x = 400;
playerWinsText.y = 150;
game.addChild(playerWinsText);
- // Enemy wins counter
enemyWinsText = new Text2('Enemy Wins: 0', {
size: 60,
fill: 0xFF0000
});
enemyWinsText.anchor.set(0.5, 0.5);
enemyWinsText.x = 1648;
enemyWinsText.y = 150;
game.addChild(enemyWinsText);
- // Enemy hand container for card backs
- enemyHandContainer.x = 1024;
+ enemyHandContainer.x = SCREEN.CENTER_X;
enemyHandContainer.y = 400;
game.addChild(enemyHandContainer);
}
function startGame() {
- gameState = 'selectCard';
+ gameState = GAME_STATE.SELECT_CARD;
menuContainer.visible = false;
- // Initialize game first to ensure UI elements exist
initializeGame();
- // Show all game UI elements (only if they exist)
- if (handContainer) {
- handContainer.visible = true;
- }
- if (enemyHandContainer) {
- enemyHandContainer.visible = true;
- }
- if (statusText) {
- statusText.visible = true;
- }
- if (playerModeText) {
- playerModeText.visible = true;
- }
- if (enemyModeText) {
- enemyModeText.visible = true;
- }
- if (enlargedCardContainer) {
- enlargedCardContainer.visible = true;
- }
- if (enemyCardContainer) {
- enemyCardContainer.visible = true;
- }
- if (playerWinsText) {
- playerWinsText.visible = true;
- }
- if (enemyWinsText) {
- enemyWinsText.visible = true;
- }
+ [handContainer, enemyHandContainer, statusText, playerModeText, enemyModeText, enlargedCardContainer, enemyCardContainer, playerWinsText, enemyWinsText].forEach(function (el) {
+ if (el) el.visible = true;
+ });
}
function displayPlayerHand() {
- // Clear existing cards
- for (var i = handContainer.children.length - 1; i >= 0; i--) {
- handContainer.removeChild(handContainer.children[i]);
- }
- // Display current hand
+ while (handContainer.children.length > 0) handContainer.removeChild(handContainer.children[0]);
for (var i = 0; i < playerHand.length; i++) {
var card = new Card(playerHand[i]);
- card.scaleX = 1.5; // Match enemy card size
- card.scaleY = 1.5; // Match enemy card size
- card.x = (i - 2) * 350; // Increase spacing to 350 to prevent overlap with 1.5 scale
+ card.scaleX = 1.5;
+ card.scaleY = 1.5;
+ card.x = (i - 2) * 350;
card.handIndex = i;
handContainer.addChild(card);
}
}
function displayEnemyHand() {
- // Clear existing card backs
- for (var i = enemyHandContainer.children.length - 1; i >= 0; i--) {
- enemyHandContainer.removeChild(enemyHandContainer.children[i]);
- }
+ while (enemyHandContainer.children.length > 0) enemyHandContainer.removeChild(enemyHandContainer.children[0]);
enemyCardBacks = [];
- // Display individual card backs for each card in enemy hand
for (var i = 0; i < enemyHand.length; i++) {
var cardBack = LK.getAsset(enemyHand[i].element.toLowerCase() + 'CardBack', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
- cardBack.x = (i - 2) * 280; // Same spacing as player cards
+ cardBack.x = (i - 2) * 280;
cardBack.element = enemyHand[i].element;
enemyHandContainer.addChild(cardBack);
enemyCardBacks.push(cardBack);
}
}
function selectCard(cardObj) {
- // If this card is already selected and we're in selectMode, don't do anything
- if (selectedCard === cardObj && gameState === 'selectMode') {
- return;
- }
- // Deselect all cards
+ if (selectedCard === cardObj && gameState === GAME_STATE.SELECT_MODE) return;
for (var i = 0; i < handContainer.children.length; i++) {
handContainer.children[i].setSelected(false);
}
- // Select this card
cardObj.setSelected(true);
selectedCard = cardObj;
- // Clear previous enlarged card with animation if it exists
if (enlargedCard) {
tween.stop(enlargedCard);
tween(enlargedCard, {
alpha: 0,
@@ -587,77 +556,30 @@
easing: tween.easeIn,
onFinish: function onFinish() {
enlargedCardContainer.removeChild(enlargedCard);
enlargedCard = null;
- // Create new enlarged card after old one is removed
createEnlargedCard(cardObj);
}
});
} else {
- // No previous enlarged card, create new one immediately
createEnlargedCard(cardObj);
}
- // Move to mode selection only if not already there
- if (gameState !== 'selectMode') {
- gameState = 'selectMode';
+ if (gameState !== GAME_STATE.SELECT_MODE) {
+ gameState = GAME_STATE.SELECT_MODE;
statusText.setText('Choose Attack or Defense mode');
modeButtons.visible = true;
}
}
function createEnlargedCard(cardObj) {
- // Create enlarged version of selected card
enlargedCard = new Card(cardObj.cardData);
- // If in battle, show bonus stats
- if (gameState === 'battle' && enemySelectedCard) {
- var hasAdvantage = hasTypeAdvantage(cardObj.cardData.element, enemySelectedCard.element);
- if (hasAdvantage) {
- // Update the card's display to show bonus stats
- for (var i = 0; i < enlargedCard.children.length; i++) {
- var child = enlargedCard.children[i];
- if (child instanceof Text2) {
- if (child.text && child.text.indexOf('ATK:') !== -1) {
- var baseAttack = cardObj.cardData.attack;
- child.setText('ATK: ' + baseAttack + ' + 10');
- } else if (child.text && child.text.indexOf('DEF:') !== -1) {
- var baseDefense = cardObj.cardData.defense;
- child.setText('DEF: ' + baseDefense + ' + 10');
- }
- }
- }
- // Add large "+10" bonus text
- var bonusText = new Text2('+ 10', {
- size: 80,
- fill: 0x00FF00,
- stroke: 0xFFFFFF,
- strokeThickness: 3
- });
- bonusText.anchor.set(0.5, 0.5);
- bonusText.x = 0;
- bonusText.y = -80;
- enlargedCard.addChild(bonusText);
+ if (gameState === GAME_STATE.BATTLE && enemySelectedCard) {
+ if (hasTypeAdvantage(cardObj.cardData.element, enemySelectedCard.element)) {
+ applyBonusVisuals(enlargedCard, cardObj.cardData);
}
}
- enlargedCard.scaleX = 2.75;
- enlargedCard.scaleY = 2.75;
- enlargedCard.x = 0;
- enlargedCard.y = 0;
- // Start with enlarged card invisible and tween it in
- enlargedCard.alpha = 0;
- enlargedCard.scaleX = 0.5;
- enlargedCard.scaleY = 0.5;
- enlargedCardContainer.addChild(enlargedCard);
- // Animate enlarged card appearing
- tween(enlargedCard, {
- alpha: 1,
- scaleX: 2.75,
- scaleY: 2.75
- }, {
- duration: 300,
- easing: tween.easeOut
- });
+ setupCardAnimation(enlargedCard, enlargedCardContainer);
}
function createEnemyCardPreview(cardData) {
- // Clear previous enemy card if it exists
if (enemyCard) {
tween.stop(enemyCard);
tween(enemyCard, {
alpha: 0,
@@ -668,61 +590,54 @@
easing: tween.easeIn,
onFinish: function onFinish() {
enemyCardContainer.removeChild(enemyCard);
enemyCard = null;
- // Create new enemy card after old one is removed
createNewEnemyCard(cardData);
}
});
} else {
- // No previous enemy card, create new one immediately
createNewEnemyCard(cardData);
}
}
function createNewEnemyCard(cardData) {
- // Create enlarged version of enemy's selected card
enemyCard = new Card(cardData);
- // If in battle, show bonus stats
- if (gameState === 'battle' && selectedCard) {
- var hasAdvantage = hasTypeAdvantage(cardData.element, selectedCard.cardData.element);
- if (hasAdvantage) {
- // Update the card's display to show bonus stats
- for (var i = 0; i < enemyCard.children.length; i++) {
- var child = enemyCard.children[i];
- if (child instanceof Text2) {
- if (child.text && child.text.indexOf('ATK:') !== -1) {
- var baseAttack = cardData.attack;
- child.setText('ATK: ' + baseAttack + ' + 10');
- } else if (child.text && child.text.indexOf('DEF:') !== -1) {
- var baseDefense = cardData.defense;
- child.setText('DEF: ' + baseDefense + ' + 10');
- }
- }
+ if (gameState === GAME_STATE.BATTLE && selectedCard) {
+ if (hasTypeAdvantage(cardData.element, selectedCard.cardData.element)) {
+ applyBonusVisuals(enemyCard, cardData);
+ }
+ }
+ setupCardAnimation(enemyCard, enemyCardContainer);
+}
+function applyBonusVisuals(cardUI, cardData) {
+ for (var i = 0; i < cardUI.children.length; i++) {
+ var child = cardUI.children[i];
+ if (child instanceof Text2) {
+ if (child.text && child.text.indexOf('ATK:') !== -1) {
+ child.setText('ATK: ' + cardData.attack + ' + 10');
+ } else if (child.text && child.text.indexOf('DEF:') !== -1) {
+ child.setText('DEF: ' + cardData.defense + ' + 10');
}
- // Add large "+10" bonus text
- var bonusText = new Text2('+ 10', {
- size: 80,
- fill: 0x00FF00,
- stroke: 0xFFFFFF,
- strokeThickness: 3
- });
- bonusText.anchor.set(0.5, 0.5);
- bonusText.x = 0;
- bonusText.y = -80;
- enemyCard.addChild(bonusText);
}
}
- enemyCard.scaleX = 2.75;
- enemyCard.scaleY = 2.75;
- enemyCard.x = 0;
- enemyCard.y = 0;
- // Start with enemy card invisible and tween it in
- enemyCard.alpha = 0;
- enemyCard.scaleX = 0.5;
- enemyCard.scaleY = 0.5;
- enemyCardContainer.addChild(enemyCard);
- // Animate enemy card appearing
- tween(enemyCard, {
+ var bonusText = new Text2('+ 10', {
+ size: 80,
+ fill: 0x00FF00,
+ stroke: 0xFFFFFF,
+ strokeThickness: 3
+ });
+ bonusText.anchor.set(0.5, 0.5);
+ bonusText.x = 0;
+ bonusText.y = -80;
+ cardUI.addChild(bonusText);
+}
+function setupCardAnimation(cardUI, container) {
+ cardUI.scaleX = 0.5;
+ cardUI.scaleY = 0.5;
+ cardUI.x = 0;
+ cardUI.y = 0;
+ cardUI.alpha = 0;
+ container.addChild(cardUI);
+ tween(cardUI, {
alpha: 1,
scaleX: 2.75,
scaleY: 2.75
}, {
@@ -730,11 +645,10 @@
easing: tween.easeOut
});
}
function startBattle() {
- gameState = 'battle';
+ gameState = GAME_STATE.BATTLE;
modeButtons.visible = false;
- // Clear enlarged card display before battle starts
if (enlargedCard) {
tween(enlargedCard, {
alpha: 0,
scaleX: 0.5,
@@ -747,156 +661,73 @@
enlargedCard = null;
}
});
}
- // Enemy AI selects card and mode
var enemyCardIndex = Math.floor(Math.random() * enemyHand.length);
enemySelectedCard = enemyHand[enemyCardIndex];
- enemyMode = Math.random() < 0.5 ? 'attack' : 'defense';
- // Display selected cards and modes
+ enemyMode = Math.random() < 0.5 ? COMBAT_MODE.ATTACK : COMBAT_MODE.DEFENSE;
statusText.setText('Battle in progress...');
playerModeText.setText('Player: ' + playerMode.toUpperCase());
enemyModeText.setText('Enemy: ' + enemyMode.toUpperCase());
- // Show enlarged cards with battle stats after a brief delay
LK.setTimeout(function () {
- // Update player enlarged card to show bonus stats if applicable
- if (selectedCard) {
- createEnlargedCard(selectedCard);
- }
- // Show enemy card preview
+ if (selectedCard) createEnlargedCard(selectedCard);
createEnemyCardPreview(enemySelectedCard);
}, 300);
- // Resolve battle after a delay
- LK.setTimeout(function () {
- resolveBattle();
- }, 2500);
+ LK.setTimeout(resolveBattle, 2500);
LK.getSound('cardBattle').play();
}
+function hasTypeAdvantage(attacker, defender) {
+ return ELEMENT_ADVANTAGES[attacker] === defender;
+}
function resolveBattle() {
- var playerValue, enemyValue;
var playerCard = selectedCard.cardData;
- var enemyCard = enemySelectedCard;
- // Check type advantages: Fire > Air > Water > Earth > Fire
- var playerAdvantage = hasTypeAdvantage(playerCard.element, enemyCard.element);
- var enemyAdvantage = hasTypeAdvantage(enemyCard.element, playerCard.element);
- // Determine values based on modes
- if (playerMode === 'attack') {
- playerValue = playerCard.attack;
- } else {
- playerValue = playerCard.defense;
- }
- if (enemyMode === 'attack') {
- enemyValue = enemyCard.attack;
- } else {
- enemyValue = enemyCard.defense;
- }
- // Apply type advantage bonuses
- if (playerAdvantage) {
- playerValue += 10;
- }
- if (enemyAdvantage) {
- enemyValue += 10;
- }
- // Resolve battle outcome
+ var enemyData = enemySelectedCard;
+ var playerValue = playerMode === COMBAT_MODE.ATTACK ? playerCard.attack : playerCard.defense;
+ var enemyValue = enemyMode === COMBAT_MODE.ATTACK ? enemyData.attack : enemyData.defense;
+ if (hasTypeAdvantage(playerCard.element, enemyData.element)) playerValue += 10;
+ if (hasTypeAdvantage(enemyData.element, playerCard.element)) enemyValue += 10;
var resultText = '';
- if (playerMode === 'defense' && enemyMode === 'defense') {
- // Both defense - both cards return to hand
+ if (playerMode === COMBAT_MODE.DEFENSE && enemyMode === COMBAT_MODE.DEFENSE) {
resultText = 'Both defended - cards returned to hand';
- battleResult = 'tie';
+ battleResult = BATTLE_RESULT.TIE;
} else if (playerValue > enemyValue) {
- // Player wins
resultText = 'You win this round!';
- battleResult = 'playerWin';
+ battleResult = BATTLE_RESULT.PLAYER_WIN;
playerWins++;
playerWinsText.setText('Player Wins: ' + playerWins);
- // Discard both cards - add both to used cards and replace with new ones
- usedCards.push(enemySelectedCard);
- usedCards.push(selectedCard.cardData);
- // Replace enemy card
- var enemyIndex = enemyHand.indexOf(enemySelectedCard);
- var newEnemyCard = drawNewCard();
- if (newEnemyCard) {
- enemyHand[enemyIndex] = newEnemyCard;
- } else {
- enemyHand.splice(enemyIndex, 1);
- }
- // Replace player card
- var playerIndex = selectedCard.handIndex;
- var newPlayerCard = drawNewCard();
- if (newPlayerCard) {
- playerHand[playerIndex] = newPlayerCard;
- } else {
- playerHand.splice(playerIndex, 1);
- }
+ usedCards.push(enemyData, playerCard);
+ replaceCardInHand(enemyHand, enemySelectedCard, enemyHand.indexOf(enemySelectedCard));
+ replaceCardInHand(playerHand, playerCard, selectedCard.handIndex);
displayEnemyHand();
LK.getSound('cardWin').play();
} else if (enemyValue > playerValue) {
- // Enemy wins
resultText = 'Enemy wins this round!';
- battleResult = 'enemyWin';
+ battleResult = BATTLE_RESULT.ENEMY_WIN;
enemyWins++;
enemyWinsText.setText('Enemy Wins: ' + enemyWins);
- // Discard both cards - add both to used cards and replace with new ones
- usedCards.push(selectedCard.cardData);
- usedCards.push(enemySelectedCard);
- // Replace player card
- var playerIndex = selectedCard.handIndex;
- var newPlayerCard = drawNewCard();
- if (newPlayerCard) {
- playerHand[playerIndex] = newPlayerCard;
- } else {
- playerHand.splice(playerIndex, 1);
- }
- // Replace enemy card
- var enemyIndex = enemyHand.indexOf(enemySelectedCard);
- var newEnemyCard = drawNewCard();
- if (newEnemyCard) {
- enemyHand[enemyIndex] = newEnemyCard;
- } else {
- enemyHand.splice(enemyIndex, 1);
- }
+ usedCards.push(playerCard, enemyData);
+ replaceCardInHand(playerHand, playerCard, selectedCard.handIndex);
+ replaceCardInHand(enemyHand, enemySelectedCard, enemyHand.indexOf(enemySelectedCard));
displayEnemyHand();
LK.getSound('cardLose').play();
} else {
- // Tie - both cards return to hand
resultText = 'Tie - both cards returned to hand';
- battleResult = 'tie';
+ battleResult = BATTLE_RESULT.TIE;
}
statusText.setText(resultText);
- // Check win conditions
- LK.setTimeout(function () {
- checkWinCondition();
- }, 2500);
+ LK.setTimeout(checkWinCondition, 2500);
}
-function hasTypeAdvantage(attacker, defender) {
- // Fire > Air > Water > Earth > Fire
- var advantages = {
- 'Fire': 'Air',
- 'Air': 'Water',
- 'Water': 'Earth',
- 'Earth': 'Fire'
- };
- return advantages[attacker] === defender;
-}
function checkWinCondition() {
if (playerWins >= 5) {
statusText.setText('Victory - You won 5 rounds!');
LK.setScore(playerWins * 100);
- // Reset game state and return to menu
- LK.setTimeout(function () {
- resetGameToMenu();
- }, 2000);
- return;
+ LK.setTimeout(resetGameToMenu, 2000);
} else if (enemyWins >= 5) {
statusText.setText('Game Over - Enemy won 5 rounds!');
- // Reset game state and return to menu
- LK.setTimeout(function () {
- resetGameToMenu();
- }, 2000);
- return;
+ LK.setTimeout(resetGameToMenu, 2000);
+ } else {
+ resetForNextRound();
}
- // Continue to next round
- resetForNextRound();
}
function resetForNextRound() {
selectedCard = null;
enemySelectedCard = null;
@@ -904,11 +735,10 @@
enemyMode = null;
battleResult = null;
playerModeText.setText('');
enemyModeText.setText('');
- gameState = 'selectCard';
+ gameState = GAME_STATE.SELECT_CARD;
statusText.setText('Select a card from your hand');
- // Clear enlarged card display
if (enlargedCard) {
tween(enlargedCard, {
alpha: 0,
scaleX: 0.5,
@@ -921,9 +751,8 @@
enlargedCard = null;
}
});
}
- // Clear enemy card display
if (enemyCard) {
tween(enemyCard, {
alpha: 0,
scaleX: 0.5,
@@ -942,27 +771,21 @@
// Initialize the menu
setupMenu();
LK.playMusic('backgroundMusic');
game.update = function () {
- // Update battle squares using parametric circle equations (they rotate even in menu)
- var time = LK.ticks * 0.02; // Control animation speed
+ var time = LK.ticks * 0.02;
var radius = 200;
- var centerX = 1024;
- var centerY = 1200;
for (var i = 0; i < battleSquares.length; i++) {
var square = battleSquares[i];
if (square && square.startAngle !== undefined) {
- // Parametric circle: x = centerX + radius * cos(angle + time), y = centerY + radius * sin(angle + time)
var angle = square.startAngle + time;
- square.x = centerX + radius * Math.cos(angle);
- square.y = centerY + radius * Math.sin(angle);
+ square.x = SCREEN.CENTER_X + radius * Math.cos(angle);
+ square.y = SCREEN.CENTER_Y + radius * Math.sin(angle);
}
}
- // Update game logic if needed
};
function resetGameToMenu() {
- // Reset all game state variables
- gameState = 'menu';
+ gameState = GAME_STATE.MENU;
playerHand = [];
enemyHand = [];
usedCards = [];
selectedCard = null;
@@ -971,59 +794,24 @@
enemyMode = null;
battleResult = null;
playerWins = 0;
enemyWins = 0;
- // Clear all UI containers
- for (var i = handContainer.children.length - 1; i >= 0; i--) {
- handContainer.removeChild(handContainer.children[i]);
- }
- for (var i = enemyHandContainer.children.length - 1; i >= 0; i--) {
- enemyHandContainer.removeChild(enemyHandContainer.children[i]);
- }
+ while (handContainer.children.length > 0) handContainer.removeChild(handContainer.children[0]);
+ while (enemyHandContainer.children.length > 0) enemyHandContainer.removeChild(enemyHandContainer.children[0]);
if (enlargedCard) {
enlargedCardContainer.removeChild(enlargedCard);
enlargedCard = null;
}
if (enemyCard) {
enemyCardContainer.removeChild(enemyCard);
enemyCard = null;
}
- // Reset UI text (only if elements exist)
- if (statusText) {
- statusText.setText('');
- statusText.visible = false;
- }
- if (playerModeText) {
- playerModeText.setText('');
- playerModeText.visible = false;
- }
- if (enemyModeText) {
- enemyModeText.setText('');
- enemyModeText.visible = false;
- }
- if (playerWinsText) {
- playerWinsText.setText('Player Wins: 0');
- playerWinsText.visible = false;
- }
- if (enemyWinsText) {
- enemyWinsText.setText('Enemy Wins: 0');
- enemyWinsText.visible = false;
- }
- // Hide game UI elements (only if they exist)
- if (modeButtons) {
- modeButtons.visible = false;
- }
- if (handContainer) {
- handContainer.visible = false;
- }
- if (enemyHandContainer) {
- enemyHandContainer.visible = false;
- }
- if (enlargedCardContainer) {
- enlargedCardContainer.visible = false;
- }
- if (enemyCardContainer) {
- enemyCardContainer.visible = false;
- }
- // Show menu
+ [statusText, playerModeText, enemyModeText, playerWinsText, enemyWinsText, modeButtons, handContainer, enemyHandContainer, enlargedCardContainer, enemyCardContainer].forEach(function (el) {
+ if (el) {
+ el.visible = false;
+ if (el.setText) el.setText('');
+ }
+ });
+ if (playerWinsText) playerWinsText.setText('Player Wins: 0');
+ if (enemyWinsText) enemyWinsText.setText('Enemy Wins: 0');
menuContainer.visible = true;
}
\ No newline at end of file
Un tsunami
A Stone
A boulder
An ember
A spark
Three small ember
A river
A wind symbol
Ice floe
A purple cristal rock
Columnas de fuego rojo y azul
Big storm
A cold gale
El margen para una carta que representa el tipo tierra
Un marco para una carta que represente al tipo aire
Un marco para una carta que represente al tipo agua
The rain
A big mountain
Pile of yellow sand
El margen para una carta que representa el tipo fuego
A tornado
The sea
El margen de un botoΜn que indica ataque de un juego de mesa, color rojo sin texto
Crea una versioΜn de este marco en color azul
Marco cuadrado, delgado color dorado con un fondo blanco. In-Game asset. 2d. High contrast. No shadows. card
SiΜmbolo del elemento aire
SiΜmbolo de la tierra color verde
SiΜmbolo del fuego color rojo
SiΜmbolo del agua color azul
A lightning
Crea la parte inversa de una carta que representa el elemento agua, no debe tener texto ni espacio vaciΜo, deben ser corrientes de agua y rocas en la parte inferior
Crea la parte inversa de una carta que representa el elemento fuego, no debe tener texto ni espacio vaciΜo, deben ser flamas y montiΜculos rojos en la parte inferior
Crea la parte inversa de una carta que representa el elemento tierra, no debe tener texto ni espacio vaciΜo, deben ser montiΜculos de tierra y algunas hierbas verdes repartidas
A whirlwind
A cloud
A volcano with lava
Un cubo de hielo
Una niebla densa
an ashes
A brown cave
Una pieza en forma de prisma hexagonal de metal
4 segmentos de flecha que forman un circulo en sentido horario, color morado
The ether
The moon
El siΜmbolo de Gaia, sin texto, color verde y cafeΜ
The sun