Code edit (1 edits merged)
Please save this source code
User prompt
El color de ataque debe ser de un color vino intenso y defensa de un color azul marino
User prompt
Baja un poco el texto de ataque y defensa en la carta
User prompt
Sube un poco el texto Has que el marco de las cartas sea un poco maĢs ancho un poco maĢs alto
User prompt
Es decir, centra el texto en X y en Y
User prompt
Centra los textos de "Sand", "Wind", etc. respecto al eje X
User prompt
Aumenta un 50% maĢs el tamanĢo del texto de los botones
User prompt
Ahora sepaĢralos un poco, es decir, mueve un poco a la izquierda el botoĢn attack y un poco a la derecha defense
User prompt
AumeĢntalos un 50% maĢs y tambieĢn sus textos
User prompt
Aumenta el tamanĢo de los botones attack y defense
User prompt
Baja un poco maĢs el texto de Ataque y defensa
User prompt
Aumenta el tamanĢo de la previsualizacioĢn un 25% āŖš” Consider importing and using the following plugins: @upit/tween.v1
User prompt
Baja ese texto de descripcioĢn maĢs
User prompt
Mejor devuelve esa descripcioĢn a donde estaba
User prompt
El texto de descripcioĢn ceĢntralo en la carta respecto al eje Y āŖš” Consider importing and using the following plugins: @upit/tween.v1
User prompt
Baja un poco el texto de ataque y de defensa y pon el texto de la carta "Sand", "Wind", etc, en color negro
User prompt
Has que todas las cartas de un tipo usen el mismo asset, es decir, todas las de agua usaran la misma, fuego el mismo y asiĢ con los otros
User prompt
Crea un asset comuĢn para todas las cartas y otro para cada una que representa lo que dice su texto
User prompt
Has que se pueda cambiar la eleccioĢn de carta al momento de la previsualizacioĢn con simplemente seleccionar otra āŖš” Consider importing and using the following plugins: @upit/tween.v1
User prompt
Has que al seleccionar una carta aparezca en grande a la izquierda, en la zona vaciĢa para apreciarla mejor, asiĢ como su texto āŖš” Consider importing and using the following plugins: @upit/tween.v1
Code edit (1 edits merged)
Please save this source code
User prompt
Elemental Card Battle
Initial prompt
Hola, quiero crear un juego de cartas, donde su contenido representa a los elementos: Agua, Fuego, Tierra, Aire. Las cartas tienen ataque y defensa, son distintos es decir, puede existir una carta agua Mar con 100 atq y 90 def, todas las cartas Mar son iguales, pero puede existir una carta Lluvia con 50 atq y 70 def, todas las cartas Lluvia son iguales, ambas son tipo Agua. A los jugadores se les reparten 5 cartas. Cada jugador elige una carta suya para jugar, antes de revelarla al oponente cada jugador decide si ponerla en modo ataque o defensa, puede suceder lo siguiente: 1. Si ambos jugadores juegan ataque se comparan las cantidades, la maĢs alta gana. 2. Si ambos jugadores juegan defensa las cartas regresa a su mano. 3. Si uno juega ataque y otro defensa se comparan las cantidades, la maĢs alta gana. 4. En cualquier punto, si hay un empate de poder ambas cartas regresan a la mano.
/****
* 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;
self.attachAsset(cardData.element.toLowerCase() + 'CardBase', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.2,
scaleY: 1.15
});
self.attachAsset(cardData.name.toLowerCase() + 'Card', {
anchorX: 0.5,
anchorY: 0.5,
y: -20
});
self.attachAsset('textBackground', {
anchorX: 0.5,
anchorY: 0.5,
y: 95,
alpha: 0.7
});
self.nameText = new Text2(cardData.name, {
size: 24,
fill: 0x000000
});
self.nameText.anchor.set(0.5, 0.5);
self.nameText.y = 70;
self.addChild(self.nameText);
// Referencias directas para facilitar la actualización segura de stats
self.attackText = new Text2('ATK: ' + cardData.attack, {
size: 20,
fill: 0xcc1010,
stroke: 0xFFFFFF,
strokeThickness: 2
});
self.attackText.anchor.set(0.5, 0.5);
self.attackText.y = 95;
self.addChild(self.attackText);
self.defenseText = new Text2('DEF: ' + cardData.defense, {
size: 20,
fill: 0x2795c4,
stroke: 0xFFFFFF,
strokeThickness: 2
});
self.defenseText.anchor.set(0.5, 0.5);
self.defenseText.y = 120;
self.addChild(self.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 () {
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) {
var self = Container.call(this);
self.mode = mode;
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 () {
if (gameState === GAME_STATE.SELECT_MODE && selectedCard) {
playerMode = mode.toLowerCase();
startBattle();
}
};
return self;
});
var PlayButton = Container.expand(function () {
var self = Container.call(this);
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 () {
if (gameState === GAME_STATE.MENU) {
startGame();
}
};
return self;
});
/****
* Initialize Game
****/
/**** * Main Game Object ****/
var game = new LK.Game({
backgroundColor: 0x0f1419
});
/****
* Game Code
****/
/**** * Constants & Configurations ****/
/**** * Plugins ****/
/**** * 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
};
var GAME_RULES = {
MAX_HP: 250,
BASE_DAMAGE_MIN: 10,
ADVANTAGE_BONUS: 20
};
var ELEMENT_ADVANTAGES = {
'Fire': 'Air',
'Air': 'Water',
'Water': 'Earth',
'Earth': 'Fire'
};
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 = [],
enemyHand = [],
usedCards = [];
var selectedCard = null,
enemySelectedCard = null;
var playerMode = null,
enemyMode = null;
var playerHP = GAME_RULES.MAX_HP,
enemyHP = GAME_RULES.MAX_HP;
// UI Containers
var handContainer = new Container(),
modeButtons = new Container(),
battleSquareContainer = new Container();
var battleSquares = [],
statusText = null,
playerModeText = null,
enemyModeText = null;
var enlargedCardContainer = new Container(),
enemyCardContainer = new Container();
var enlargedCard = null,
enemyCard = null;
var playerHPText = null,
enemyHPText = null;
var enemyHandContainer = new Container(),
menuContainer = new Container();
/**** * Core Systems ****/
function initializeGame() {
usedCards = [];
playerHP = GAME_RULES.MAX_HP;
enemyHP = GAME_RULES.MAX_HP;
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();
updateHPDisplays();
LK.playMusic('backgroundMusic');
}
function shuffleArray(array) {
for (var i = array.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
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 unused = getUnusedCards();
// Lógica de reciclaje del mazo cuando nos quedamos sin cartas
if (unused.length === 0) {
usedCards = [];
// Mantenemos registradas únicamente las cartas que actualmente estÔn en juego en las manos
playerHand.forEach(function (c) {
if (c) {
usedCards.push(c);
}
});
enemyHand.forEach(function (c) {
if (c) {
usedCards.push(c);
}
});
unused = getUnusedCards(); // Recalculamos con el descarte devuelto al mazo
}
if (unused.length > 0) {
var newCard = unused[Math.floor(Math.random() * unused.length)];
usedCards.push(newCard);
return newCard;
}
return null;
}
function replaceCardInHand(hand, index) {
var newCard = drawNewCard();
if (newCard) {
hand[index] = newCard;
} else {
hand.splice(index, 1);
}
}
/**** * VFX / Game Feel Functions ****/
function showFloatingText(x, y, text, color) {
var floatingObj = new Text2(text, {
size: 100,
fill: color,
stroke: 0xFFFFFF,
strokeThickness: 5
});
floatingObj.anchor.set(0.5, 0.5);
floatingObj.x = x;
floatingObj.y = y;
game.addChild(floatingObj);
tween(floatingObj, {
y: y - 200,
alpha: 0
}, {
duration: 1800,
easing: tween.easeOut,
onFinish: function onFinish() {
return game.removeChild(floatingObj);
}
});
}
function shakeScreen() {
var shakeAmount = 20;
var originalX = game.x;
var originalY = game.y;
var shakes = 0;
var shakeInterval = LK.setInterval(function () {
game.x = originalX + (Math.random() * shakeAmount - shakeAmount / 2);
game.y = originalY + (Math.random() * shakeAmount - shakeAmount / 2);
shakes++;
if (shakes > 10) {
LK.clearInterval(shakeInterval);
game.x = originalX;
game.y = originalY;
}
}, 20);
}
/**** * UI Setup ****/
function setupMenu() {
var centerBg = LK.getAsset('centerCircle', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.5
});
centerBg.x = SCREEN.CENTER_X;
centerBg.y = SCREEN.CENTER_Y;
game.addChild(centerBg);
for (var i = 0; i < 4; i++) {
var square = LK.getAsset("battleSquare".concat(i + 1), {
anchorX: 0.5,
anchorY: 0.5
});
var angle = i * Math.PI * 2 / 4;
square.x = SCREEN.CENTER_X + Math.cos(angle) * 200;
square.y = SCREEN.CENTER_Y + Math.sin(angle) * 200;
square.startAngle = angle;
game.addChild(square);
battleSquares.push(square);
}
var 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);
var 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 btnAtk = new ModeButton('Attack');
btnAtk.x = 800;
btnAtk.y = 1800;
var btnDef = new ModeButton('Defense');
btnDef.x = 1250;
btnDef.y = 1800;
modeButtons.addChild(btnAtk);
modeButtons.addChild(btnDef);
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);
playerHPText = new Text2('HP: ' + GAME_RULES.MAX_HP, {
size: 80,
fill: 0x00FF00,
stroke: 0x000000,
strokeThickness: 4
});
playerHPText.anchor.set(0.5, 0.5);
playerHPText.x = 400;
playerHPText.y = 150;
game.addChild(playerHPText);
enemyHPText = new Text2('HP: ' + GAME_RULES.MAX_HP, {
size: 80,
fill: 0xFF0000,
stroke: 0x000000,
strokeThickness: 4
});
enemyHPText.anchor.set(0.5, 0.5);
enemyHPText.x = 1648;
enemyHPText.y = 150;
game.addChild(enemyHPText);
enemyHandContainer.x = SCREEN.CENTER_X;
enemyHandContainer.y = 400;
game.addChild(enemyHandContainer);
}
function updateHPDisplays() {
if (playerHPText) {
playerHPText.setText('HP: ' + Math.max(0, playerHP));
}
if (enemyHPText) {
enemyHPText.setText('HP: ' + Math.max(0, enemyHP));
}
}
function startGame() {
gameState = GAME_STATE.SELECT_CARD;
menuContainer.visible = false;
initializeGame();
[handContainer, enemyHandContainer, statusText, playerModeText, enemyModeText, enlargedCardContainer, enemyCardContainer, playerHPText, enemyHPText].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]);
}
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;
enemyHandContainer.addChild(cardBack);
}
}
/**** * Battle Flow ****/
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,
onFinish: function onFinish() {
enlargedCardContainer.removeChild(enlargedCard);
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 && 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,
onFinish: function onFinish() {
enemyCardContainer.removeChild(enemyCard);
enemyCard = new Card(cardData);
if (gameState === GAME_STATE.BATTLE && selectedCard && hasTypeAdvantage(cardData.element, selectedCard.cardData.element)) {
applyBonusVisuals(enemyCard, cardData);
}
setupCardAnimation(enemyCard, enemyCardContainer);
}
});
} else {
enemyCard = new Card(cardData);
if (gameState === GAME_STATE.BATTLE && selectedCard && hasTypeAdvantage(cardData.element, selectedCard.cardData.element)) {
applyBonusVisuals(enemyCard, cardData);
}
setupCardAnimation(enemyCard, enemyCardContainer);
}
}
function applyBonusVisuals(cardUI, cardData) {
// Actualización segura utilizando las referencias guardadas
cardUI.attackText.setText('ATK: ' + cardData.attack + " + ".concat(GAME_RULES.ADVANTAGE_BONUS));
cardUI.defenseText.setText('DEF: ' + cardData.defense + " + ".concat(GAME_RULES.ADVANTAGE_BONUS));
var bonus = new Text2("+ ".concat(GAME_RULES.ADVANTAGE_BONUS), {
size: 80,
fill: 0x00FF00,
stroke: 0xFFFFFF,
strokeThickness: 3
});
bonus.anchor.set(0.5, 0.5);
bonus.y = -80;
cardUI.addChild(bonus);
}
function setupCardAnimation(cardUI, container) {
cardUI.scaleX = 0.5;
cardUI.scaleY = 0.5;
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,
onFinish: function onFinish() {
return enlargedCardContainer.removeChild(enlargedCard);
}
});
}
enemySelectedCard = enemyHand[Math.floor(Math.random() * enemyHand.length)];
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,
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 += GAME_RULES.ADVANTAGE_BONUS;
}
if (hasTypeAdvantage(enemyData.element, playerCard.element)) {
enemyValue += GAME_RULES.ADVANTAGE_BONUS;
}
var resultText = '';
if (playerMode === COMBAT_MODE.DEFENSE && enemyMode === COMBAT_MODE.DEFENSE) {
resultText = 'Both defended - no damage taken';
} else if (playerValue > enemyValue) {
var damage = Math.max(GAME_RULES.BASE_DAMAGE_MIN, playerValue - enemyValue);
enemyHP -= damage;
updateHPDisplays();
showFloatingText(1648, 250, '-' + damage, 0xFF0000);
shakeScreen();
resultText = "You strike for ".concat(damage, " damage!");
usedCards.push(enemyData, playerCard);
replaceCardInHand(enemyHand, enemyHand.indexOf(enemySelectedCard));
replaceCardInHand(playerHand, selectedCard.handIndex);
displayEnemyHand();
LK.getSound('cardWin').play();
} else if (enemyValue > playerValue) {
var damage = Math.max(GAME_RULES.BASE_DAMAGE_MIN, enemyValue - playerValue);
playerHP -= damage;
updateHPDisplays();
showFloatingText(400, 250, '-' + damage, 0xFF0000);
shakeScreen();
resultText = "Enemy hits you for ".concat(damage, " damage!");
usedCards.push(playerCard, enemyData);
replaceCardInHand(playerHand, selectedCard.handIndex);
replaceCardInHand(enemyHand, enemyHand.indexOf(enemySelectedCard));
displayEnemyHand();
LK.getSound('cardLose').play();
} else {
resultText = 'Clash tied - no damage taken';
}
statusText.setText(resultText);
LK.setTimeout(checkWinCondition, 2500);
}
function checkWinCondition() {
if (enemyHP <= 0) {
statusText.setText('Victory - The enemy has fallen!');
LK.setTimeout(resetGameToMenu, 3000);
} else if (playerHP <= 0) {
statusText.setText('Game Over - Your HP reached 0!');
LK.setTimeout(resetGameToMenu, 3000);
} else {
resetForNextRound();
}
}
function resetForNextRound() {
selectedCard = null;
enemySelectedCard = null;
playerMode = null;
enemyMode = 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,
onFinish: function onFinish() {
return enlargedCardContainer.removeChild(enlargedCard);
}
});
}
if (enemyCard) {
tween(enemyCard, {
alpha: 0,
scaleX: 0.5,
scaleY: 0.5
}, {
duration: 200,
onFinish: function onFinish() {
return enemyCardContainer.removeChild(enemyCard);
}
});
}
displayPlayerHand();
}
// Init
setupMenu();
LK.playMusic('backgroundMusic');
game.update = function () {
var time = LK.ticks * 0.02;
for (var i = 0; i < battleSquares.length; i++) {
var square = battleSquares[i];
if (square && square.startAngle !== undefined) {
square.x = SCREEN.CENTER_X + 200 * Math.cos(square.startAngle + time);
square.y = SCREEN.CENTER_Y + 200 * Math.sin(square.startAngle + time);
}
}
};
function resetGameToMenu() {
gameState = GAME_STATE.MENU;
playerHand = [];
enemyHand = [];
usedCards = [];
selectedCard = null;
enemySelectedCard = null;
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);
}
if (enemyCard) {
enemyCardContainer.removeChild(enemyCard);
}
[statusText, playerModeText, enemyModeText, playerHPText, enemyHPText, modeButtons, handContainer, enemyHandContainer, enlargedCardContainer, enemyCardContainer].forEach(function (el) {
if (el) {
el.visible = false;
}
});
menuContainer.visible = true;
} /****
* 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;
self.attachAsset(cardData.element.toLowerCase() + 'CardBase', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.2,
scaleY: 1.15
});
self.attachAsset(cardData.name.toLowerCase() + 'Card', {
anchorX: 0.5,
anchorY: 0.5,
y: -20
});
self.attachAsset('textBackground', {
anchorX: 0.5,
anchorY: 0.5,
y: 95,
alpha: 0.7
});
self.nameText = new Text2(cardData.name, {
size: 24,
fill: 0x000000
});
self.nameText.anchor.set(0.5, 0.5);
self.nameText.y = 70;
self.addChild(self.nameText);
// Referencias directas para facilitar la actualización segura de stats
self.attackText = new Text2('ATK: ' + cardData.attack, {
size: 20,
fill: 0xcc1010,
stroke: 0xFFFFFF,
strokeThickness: 2
});
self.attackText.anchor.set(0.5, 0.5);
self.attackText.y = 95;
self.addChild(self.attackText);
self.defenseText = new Text2('DEF: ' + cardData.defense, {
size: 20,
fill: 0x2795c4,
stroke: 0xFFFFFF,
strokeThickness: 2
});
self.defenseText.anchor.set(0.5, 0.5);
self.defenseText.y = 120;
self.addChild(self.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 () {
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) {
var self = Container.call(this);
self.mode = mode;
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 () {
if (gameState === GAME_STATE.SELECT_MODE && selectedCard) {
playerMode = mode.toLowerCase();
startBattle();
}
};
return self;
});
var PlayButton = Container.expand(function () {
var self = Container.call(this);
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 () {
if (gameState === GAME_STATE.MENU) {
startGame();
}
};
return self;
});
/****
* Initialize Game
****/
/**** * Main Game Object ****/
var game = new LK.Game({
backgroundColor: 0x0f1419
});
/****
* Game Code
****/
/**** * Constants & Configurations ****/
/**** * Plugins ****/
/**** * 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
};
var GAME_RULES = {
MAX_HP: 250,
BASE_DAMAGE_MIN: 10,
ADVANTAGE_BONUS: 20
};
var ELEMENT_ADVANTAGES = {
'Fire': 'Air',
'Air': 'Water',
'Water': 'Earth',
'Earth': 'Fire'
};
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 = [],
enemyHand = [],
usedCards = [];
var selectedCard = null,
enemySelectedCard = null;
var playerMode = null,
enemyMode = null;
var playerHP = GAME_RULES.MAX_HP,
enemyHP = GAME_RULES.MAX_HP;
// UI Containers
var handContainer = new Container(),
modeButtons = new Container(),
battleSquareContainer = new Container();
var battleSquares = [],
statusText = null,
playerModeText = null,
enemyModeText = null;
var enlargedCardContainer = new Container(),
enemyCardContainer = new Container();
var enlargedCard = null,
enemyCard = null;
var playerHPText = null,
enemyHPText = null;
var enemyHandContainer = new Container(),
menuContainer = new Container();
/**** * Core Systems ****/
function initializeGame() {
usedCards = [];
playerHP = GAME_RULES.MAX_HP;
enemyHP = GAME_RULES.MAX_HP;
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();
updateHPDisplays();
LK.playMusic('backgroundMusic');
}
function shuffleArray(array) {
for (var i = array.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
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 unused = getUnusedCards();
// Lógica de reciclaje del mazo cuando nos quedamos sin cartas
if (unused.length === 0) {
usedCards = [];
// Mantenemos registradas únicamente las cartas que actualmente estÔn en juego en las manos
playerHand.forEach(function (c) {
if (c) {
usedCards.push(c);
}
});
enemyHand.forEach(function (c) {
if (c) {
usedCards.push(c);
}
});
unused = getUnusedCards(); // Recalculamos con el descarte devuelto al mazo
}
if (unused.length > 0) {
var newCard = unused[Math.floor(Math.random() * unused.length)];
usedCards.push(newCard);
return newCard;
}
return null;
}
function replaceCardInHand(hand, index) {
var newCard = drawNewCard();
if (newCard) {
hand[index] = newCard;
} else {
hand.splice(index, 1);
}
}
/**** * VFX / Game Feel Functions ****/
function showFloatingText(x, y, text, color) {
var floatingObj = new Text2(text, {
size: 100,
fill: color,
stroke: 0xFFFFFF,
strokeThickness: 5
});
floatingObj.anchor.set(0.5, 0.5);
floatingObj.x = x;
floatingObj.y = y;
game.addChild(floatingObj);
tween(floatingObj, {
y: y - 200,
alpha: 0
}, {
duration: 1800,
easing: tween.easeOut,
onFinish: function onFinish() {
return game.removeChild(floatingObj);
}
});
}
function shakeScreen() {
var shakeAmount = 20;
var originalX = game.x;
var originalY = game.y;
var shakes = 0;
var shakeInterval = LK.setInterval(function () {
game.x = originalX + (Math.random() * shakeAmount - shakeAmount / 2);
game.y = originalY + (Math.random() * shakeAmount - shakeAmount / 2);
shakes++;
if (shakes > 10) {
LK.clearInterval(shakeInterval);
game.x = originalX;
game.y = originalY;
}
}, 20);
}
/**** * UI Setup ****/
function setupMenu() {
var centerBg = LK.getAsset('centerCircle', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.5
});
centerBg.x = SCREEN.CENTER_X;
centerBg.y = SCREEN.CENTER_Y;
game.addChild(centerBg);
for (var i = 0; i < 4; i++) {
var square = LK.getAsset("battleSquare".concat(i + 1), {
anchorX: 0.5,
anchorY: 0.5
});
var angle = i * Math.PI * 2 / 4;
square.x = SCREEN.CENTER_X + Math.cos(angle) * 200;
square.y = SCREEN.CENTER_Y + Math.sin(angle) * 200;
square.startAngle = angle;
game.addChild(square);
battleSquares.push(square);
}
var 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);
var 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 btnAtk = new ModeButton('Attack');
btnAtk.x = 800;
btnAtk.y = 1800;
var btnDef = new ModeButton('Defense');
btnDef.x = 1250;
btnDef.y = 1800;
modeButtons.addChild(btnAtk);
modeButtons.addChild(btnDef);
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);
playerHPText = new Text2('HP: ' + GAME_RULES.MAX_HP, {
size: 80,
fill: 0x00FF00,
stroke: 0x000000,
strokeThickness: 4
});
playerHPText.anchor.set(0.5, 0.5);
playerHPText.x = 400;
playerHPText.y = 150;
game.addChild(playerHPText);
enemyHPText = new Text2('HP: ' + GAME_RULES.MAX_HP, {
size: 80,
fill: 0xFF0000,
stroke: 0x000000,
strokeThickness: 4
});
enemyHPText.anchor.set(0.5, 0.5);
enemyHPText.x = 1648;
enemyHPText.y = 150;
game.addChild(enemyHPText);
enemyHandContainer.x = SCREEN.CENTER_X;
enemyHandContainer.y = 400;
game.addChild(enemyHandContainer);
}
function updateHPDisplays() {
if (playerHPText) {
playerHPText.setText('HP: ' + Math.max(0, playerHP));
}
if (enemyHPText) {
enemyHPText.setText('HP: ' + Math.max(0, enemyHP));
}
}
function startGame() {
gameState = GAME_STATE.SELECT_CARD;
menuContainer.visible = false;
initializeGame();
[handContainer, enemyHandContainer, statusText, playerModeText, enemyModeText, enlargedCardContainer, enemyCardContainer, playerHPText, enemyHPText].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]);
}
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;
enemyHandContainer.addChild(cardBack);
}
}
/**** * Battle Flow ****/
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,
onFinish: function onFinish() {
enlargedCardContainer.removeChild(enlargedCard);
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 && 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,
onFinish: function onFinish() {
enemyCardContainer.removeChild(enemyCard);
enemyCard = new Card(cardData);
if (gameState === GAME_STATE.BATTLE && selectedCard && hasTypeAdvantage(cardData.element, selectedCard.cardData.element)) {
applyBonusVisuals(enemyCard, cardData);
}
setupCardAnimation(enemyCard, enemyCardContainer);
}
});
} else {
enemyCard = new Card(cardData);
if (gameState === GAME_STATE.BATTLE && selectedCard && hasTypeAdvantage(cardData.element, selectedCard.cardData.element)) {
applyBonusVisuals(enemyCard, cardData);
}
setupCardAnimation(enemyCard, enemyCardContainer);
}
}
function applyBonusVisuals(cardUI, cardData) {
// Actualización segura utilizando las referencias guardadas
cardUI.attackText.setText('ATK: ' + cardData.attack + " + ".concat(GAME_RULES.ADVANTAGE_BONUS));
cardUI.defenseText.setText('DEF: ' + cardData.defense + " + ".concat(GAME_RULES.ADVANTAGE_BONUS));
var bonus = new Text2("+ ".concat(GAME_RULES.ADVANTAGE_BONUS), {
size: 80,
fill: 0x00FF00,
stroke: 0xFFFFFF,
strokeThickness: 3
});
bonus.anchor.set(0.5, 0.5);
bonus.y = -80;
cardUI.addChild(bonus);
}
function setupCardAnimation(cardUI, container) {
cardUI.scaleX = 0.5;
cardUI.scaleY = 0.5;
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,
onFinish: function onFinish() {
return enlargedCardContainer.removeChild(enlargedCard);
}
});
}
enemySelectedCard = enemyHand[Math.floor(Math.random() * enemyHand.length)];
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,
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 += GAME_RULES.ADVANTAGE_BONUS;
}
if (hasTypeAdvantage(enemyData.element, playerCard.element)) {
enemyValue += GAME_RULES.ADVANTAGE_BONUS;
}
var resultText = '';
if (playerMode === COMBAT_MODE.DEFENSE && enemyMode === COMBAT_MODE.DEFENSE) {
resultText = 'Both defended - no damage taken';
} else if (playerValue > enemyValue) {
var damage = Math.max(GAME_RULES.BASE_DAMAGE_MIN, playerValue - enemyValue);
enemyHP -= damage;
updateHPDisplays();
showFloatingText(1648, 250, '-' + damage, 0xFF0000);
shakeScreen();
resultText = "You strike for ".concat(damage, " damage!");
usedCards.push(enemyData, playerCard);
replaceCardInHand(enemyHand, enemyHand.indexOf(enemySelectedCard));
replaceCardInHand(playerHand, selectedCard.handIndex);
displayEnemyHand();
LK.getSound('cardWin').play();
} else if (enemyValue > playerValue) {
var damage = Math.max(GAME_RULES.BASE_DAMAGE_MIN, enemyValue - playerValue);
playerHP -= damage;
updateHPDisplays();
showFloatingText(400, 250, '-' + damage, 0xFF0000);
shakeScreen();
resultText = "Enemy hits you for ".concat(damage, " damage!");
usedCards.push(playerCard, enemyData);
replaceCardInHand(playerHand, selectedCard.handIndex);
replaceCardInHand(enemyHand, enemyHand.indexOf(enemySelectedCard));
displayEnemyHand();
LK.getSound('cardLose').play();
} else {
resultText = 'Clash tied - no damage taken';
}
statusText.setText(resultText);
LK.setTimeout(checkWinCondition, 2500);
}
function checkWinCondition() {
if (enemyHP <= 0) {
statusText.setText('Victory - The enemy has fallen!');
LK.setTimeout(resetGameToMenu, 3000);
} else if (playerHP <= 0) {
statusText.setText('Game Over - Your HP reached 0!');
LK.setTimeout(resetGameToMenu, 3000);
} else {
resetForNextRound();
}
}
function resetForNextRound() {
selectedCard = null;
enemySelectedCard = null;
playerMode = null;
enemyMode = 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,
onFinish: function onFinish() {
return enlargedCardContainer.removeChild(enlargedCard);
}
});
}
if (enemyCard) {
tween(enemyCard, {
alpha: 0,
scaleX: 0.5,
scaleY: 0.5
}, {
duration: 200,
onFinish: function onFinish() {
return enemyCardContainer.removeChild(enemyCard);
}
});
}
displayPlayerHand();
}
// Init
setupMenu();
LK.playMusic('backgroundMusic');
game.update = function () {
var time = LK.ticks * 0.02;
for (var i = 0; i < battleSquares.length; i++) {
var square = battleSquares[i];
if (square && square.startAngle !== undefined) {
square.x = SCREEN.CENTER_X + 200 * Math.cos(square.startAngle + time);
square.y = SCREEN.CENTER_Y + 200 * Math.sin(square.startAngle + time);
}
}
};
function resetGameToMenu() {
gameState = GAME_STATE.MENU;
playerHand = [];
enemyHand = [];
usedCards = [];
selectedCard = null;
enemySelectedCard = null;
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);
}
if (enemyCard) {
enemyCardContainer.removeChild(enemyCard);
}
[statusText, playerModeText, enemyModeText, playerHPText, enemyHPText, modeButtons, handContainer, enemyHandContainer, enlargedCardContainer, enemyCardContainer].forEach(function (el) {
if (el) {
el.visible = false;
}
});
menuContainer.visible = true;
}
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