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 música suene desde el menú
User prompt
Aumenta el tamaño de la fuente del título un 25% y dale una fuente que se asocie con lo mágico
User prompt
Sube el título Elemental Battle
User prompt
Baja un poco más el botó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 menú principal y baja un poco más el botón de play
User prompt
Crea un pequeño menú, mantén el circulo girando en su posición y debajo de él un botó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 perdió, 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 condición de victoria a ganar 5 combates en lugar de 3
User prompt
Ya funciona pero hay un error, cuando se selecciona el botón attack o defense, la previsualizació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 sí 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 má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 estadí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 estadí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;
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;
} ===================================================================
--- original.js
+++ change.js
@@ -5,74 +5,73 @@
/****
* Classes
****/
-/**** * 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', {
+ 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', {
+ self.attachAsset(cardData.name.toLowerCase() + 'Card', {
anchorX: 0.5,
anchorY: 0.5,
y: -20
});
- var textBg = self.attachAsset('textBackground', {
+ self.attachAsset('textBackground', {
anchorX: 0.5,
anchorY: 0.5,
y: 95,
alpha: 0.7
});
- var nameText = new Text2(cardData.name, {
+ self.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, {
+ 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
});
- attackText.anchor.set(0.5, 0.5);
- attackText.y = 95;
- self.addChild(attackText);
- var defenseText = new Text2('DEF: ' + cardData.defense, {
+ 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
});
- defenseText.anchor.set(0.5, 0.5);
- defenseText.y = 120;
- self.addChild(defenseText);
+ 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 (x, y, obj) {
+ 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, color) {
+var ModeButton = Container.expand(function (mode) {
var self = Container.call(this);
self.mode = mode;
- var buttonBg = self.attachAsset(mode.toLowerCase() + 'Button', {
+ self.attachAsset(mode.toLowerCase() + 'Button', {
anchorX: 0.5,
anchorY: 0.5
});
var buttonText = new Text2(mode.toUpperCase(), {
@@ -80,9 +79,9 @@
fill: 0xFFFFFF
});
buttonText.anchor.set(0.5, 0.5);
self.addChild(buttonText);
- self.down = function (x, y, obj) {
+ self.down = function () {
if (gameState === GAME_STATE.SELECT_MODE && selectedCard) {
playerMode = mode.toLowerCase();
startBattle();
}
@@ -90,9 +89,9 @@
return self;
});
var PlayButton = Container.expand(function () {
var self = Container.call(this);
- var buttonBg = self.attachAsset('playButton', {
+ self.attachAsset('playButton', {
anchorX: 0.5,
anchorY: 0.5
});
var buttonText = new Text2('PLAY', {
@@ -100,9 +99,9 @@
fill: 0xFFFFFF
});
buttonText.anchor.set(0.5, 0.5);
self.addChild(buttonText);
- self.down = function (x, y, obj) {
+ self.down = function () {
if (gameState === GAME_STATE.MENU) {
startGame();
}
};
@@ -111,23 +110,19 @@
/****
* Initialize Game
****/
-/**** * Initialize Game
-****/
+/**** * Main Game Object ****/
var game = new LK.Game({
backgroundColor: 0x0f1419
});
/****
* Game Code
****/
-/**** * Constants & Configurations (Arquitectura mejorada)
-****/
-/**** * Plugins
-****/
-/**** * Game State Variables
-****/
+/**** * Constants & Configurations ****/
+/**** * Plugins ****/
+/**** * State Variables ****/
var GAME_STATE = {
MENU: 'menu',
SELECT_CARD: 'selectCard',
SELECT_MODE: 'selectMode',
@@ -146,16 +141,19 @@
var SCREEN = {
CENTER_X: 1024,
CENTER_Y: 1200
};
-// Ventaja de tipos (Sacado de la lógica para optimizar memoria)
+var GAME_RULES = {
+ MAX_HP: 250,
+ BASE_DAMAGE_MIN: 10,
+ ADVANTAGE_BONUS: 20
+};
var ELEMENT_ADVANTAGES = {
'Fire': 'Air',
'Air': 'Water',
'Water': 'Earth',
'Earth': 'Fire'
};
-// Base de datos de cartas
var cardDatabase = [{
name: 'Sea',
element: 'Water',
attack: 100,
@@ -316,41 +314,38 @@
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
-****/
+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]);
@@ -358,14 +353,14 @@
}
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));
- // Destructuring swap
var _ref = [array[j], array[i]];
array[i] = _ref[0];
array[j] = _ref[1];
}
@@ -378,49 +373,102 @@
});
});
}
function drawNewCard() {
- var unusedCards = getUnusedCards();
- if (unusedCards.length > 0) {
- var randomIndex = Math.floor(Math.random() * unusedCards.length);
- var newCard = unusedCards[randomIndex];
+ 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, cardToReplace, index) {
+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 centerBackground = LK.getAsset('centerCircle', {
+ var centerBg = 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'];
+ centerBg.x = SCREEN.CENTER_X;
+ centerBg.y = SCREEN.CENTER_Y;
+ game.addChild(centerBg);
for (var i = 0; i < 4; i++) {
- var square = LK.getAsset(squareAssets[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) * radius;
- square.y = SCREEN.CENTER_Y + Math.sin(angle) * radius;
+ 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);
}
- titleText = new Text2('ELEMENTAL BATTLE', {
+ var titleText = new Text2('ELEMENTAL BATTLE', {
size: 150,
fill: 0xFFFFFF,
stroke: 0x000000,
strokeThickness: 4,
@@ -429,9 +477,9 @@
titleText.anchor.set(0.5, 0.5);
titleText.x = SCREEN.CENTER_X;
titleText.y = 600;
menuContainer.addChild(titleText);
- playButton = new PlayButton();
+ var playButton = new PlayButton();
playButton.x = SCREEN.CENTER_X;
playButton.y = 1600;
menuContainer.addChild(playButton);
game.addChild(menuContainer);
@@ -439,16 +487,16 @@
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);
+ 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;
@@ -482,38 +530,54 @@
game.addChild(enlargedCardContainer);
enemyCardContainer.x = 1700;
enemyCardContainer.y = SCREEN.CENTER_Y;
game.addChild(enemyCardContainer);
- playerWinsText = new Text2('Player Wins: 0', {
- size: 60,
- fill: 0x00FF00
+ playerHPText = new Text2('HP: ' + GAME_RULES.MAX_HP, {
+ size: 80,
+ fill: 0x00FF00,
+ stroke: 0x000000,
+ strokeThickness: 4
});
- 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
+ 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
});
- enemyWinsText.anchor.set(0.5, 0.5);
- enemyWinsText.x = 1648;
- enemyWinsText.y = 150;
- game.addChild(enemyWinsText);
+ 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, playerWinsText, enemyWinsText].forEach(function (el) {
- if (el) el.visible = true;
+ [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]);
+ 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;
@@ -522,25 +586,27 @@
handContainer.addChild(card);
}
}
function displayEnemyHand() {
- while (enemyHandContainer.children.length > 0) enemyHandContainer.removeChild(enemyHandContainer.children[0]);
- enemyCardBacks = [];
+ 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;
- cardBack.element = enemyHand[i].element;
enemyHandContainer.addChild(cardBack);
- enemyCardBacks.push(cardBack);
}
}
+/**** * Battle Flow ****/
function selectCard(cardObj) {
- if (selectedCard === cardObj && gameState === GAME_STATE.SELECT_MODE) return;
+ 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);
@@ -552,12 +618,10 @@
scaleX: 0.5,
scaleY: 0.5
}, {
duration: 150,
- easing: tween.easeIn,
onFinish: function onFinish() {
enlargedCardContainer.removeChild(enlargedCard);
- enlargedCard = null;
createEnlargedCard(cardObj);
}
});
} else {
@@ -570,12 +634,10 @@
}
}
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);
- }
+ if (gameState === GAME_STATE.BATTLE && enemySelectedCard && hasTypeAdvantage(cardObj.cardData.element, enemySelectedCard.element)) {
+ applyBonusVisuals(enlargedCard, cardObj.cardData);
}
setupCardAnimation(enlargedCard, enlargedCardContainer);
}
function createEnemyCardPreview(cardData) {
@@ -586,55 +648,42 @@
scaleX: 0.5,
scaleY: 0.5
}, {
duration: 150,
- easing: tween.easeIn,
onFinish: function onFinish() {
enemyCardContainer.removeChild(enemyCard);
- enemyCard = null;
- createNewEnemyCard(cardData);
+ enemyCard = new Card(cardData);
+ if (gameState === GAME_STATE.BATTLE && selectedCard && hasTypeAdvantage(cardData.element, selectedCard.cardData.element)) {
+ applyBonusVisuals(enemyCard, cardData);
+ }
+ setupCardAnimation(enemyCard, enemyCardContainer);
}
});
} else {
- createNewEnemyCard(cardData);
- }
-}
-function createNewEnemyCard(cardData) {
- enemyCard = new Card(cardData);
- if (gameState === GAME_STATE.BATTLE && selectedCard) {
- if (hasTypeAdvantage(cardData.element, selectedCard.cardData.element)) {
+ enemyCard = new Card(cardData);
+ if (gameState === GAME_STATE.BATTLE && selectedCard && hasTypeAdvantage(cardData.element, selectedCard.cardData.element)) {
applyBonusVisuals(enemyCard, cardData);
}
+ setupCardAnimation(enemyCard, enemyCardContainer);
}
- 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', {
+ // 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
});
- bonusText.anchor.set(0.5, 0.5);
- bonusText.x = 0;
- bonusText.y = -80;
- cardUI.addChild(bonusText);
+ 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.x = 0;
- cardUI.y = 0;
cardUI.alpha = 0;
container.addChild(cardUI);
tween(cardUI, {
alpha: 1,
@@ -654,23 +703,22 @@
scaleX: 0.5,
scaleY: 0.5
}, {
duration: 200,
- easing: tween.easeIn,
onFinish: function onFinish() {
- enlargedCardContainer.removeChild(enlargedCard);
- enlargedCard = null;
+ return enlargedCardContainer.removeChild(enlargedCard);
}
});
}
- var enemyCardIndex = Math.floor(Math.random() * enemyHand.length);
- enemySelectedCard = enemyHand[enemyCardIndex];
+ 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);
+ if (selectedCard) {
+ createEnlargedCard(selectedCard);
+ }
createEnemyCardPreview(enemySelectedCard);
}, 300);
LK.setTimeout(resolveBattle, 2500);
LK.getSound('cardBattle').play();
@@ -678,53 +726,58 @@
function hasTypeAdvantage(attacker, defender) {
return ELEMENT_ADVANTAGES[attacker] === defender;
}
function resolveBattle() {
- var playerCard = selectedCard.cardData;
- var enemyData = enemySelectedCard;
+ 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 += 10;
- if (hasTypeAdvantage(enemyData.element, playerCard.element)) enemyValue += 10;
+ 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 - cards returned to hand';
- battleResult = BATTLE_RESULT.TIE;
+ resultText = 'Both defended - no damage taken';
} else if (playerValue > enemyValue) {
- resultText = 'You win this round!';
- battleResult = BATTLE_RESULT.PLAYER_WIN;
- playerWins++;
- playerWinsText.setText('Player Wins: ' + playerWins);
+ 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, enemySelectedCard, enemyHand.indexOf(enemySelectedCard));
- replaceCardInHand(playerHand, playerCard, selectedCard.handIndex);
+ replaceCardInHand(enemyHand, enemyHand.indexOf(enemySelectedCard));
+ replaceCardInHand(playerHand, 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);
+ 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, playerCard, selectedCard.handIndex);
- replaceCardInHand(enemyHand, enemySelectedCard, enemyHand.indexOf(enemySelectedCard));
+ replaceCardInHand(playerHand, selectedCard.handIndex);
+ replaceCardInHand(enemyHand, enemyHand.indexOf(enemySelectedCard));
displayEnemyHand();
LK.getSound('cardLose').play();
} else {
- resultText = 'Tie - both cards returned to hand';
- battleResult = BATTLE_RESULT.TIE;
+ resultText = 'Clash tied - no damage taken';
}
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);
+ 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();
}
}
@@ -732,9 +785,8 @@
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');
@@ -744,12 +796,10 @@
scaleX: 0.5,
scaleY: 0.5
}, {
duration: 200,
- easing: tween.easeIn,
onFinish: function onFinish() {
- enlargedCardContainer.removeChild(enlargedCard);
- enlargedCard = null;
+ return enlargedCardContainer.removeChild(enlargedCard);
}
});
}
if (enemyCard) {
@@ -758,29 +808,25 @@
scaleX: 0.5,
scaleY: 0.5
}, {
duration: 200,
- easing: tween.easeIn,
onFinish: function onFinish() {
- enemyCardContainer.removeChild(enemyCard);
- enemyCard = null;
+ return enemyCardContainer.removeChild(enemyCard);
}
});
}
displayPlayerHand();
}
-// Initialize the menu
+// Init
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);
+ square.x = SCREEN.CENTER_X + 200 * Math.cos(square.startAngle + time);
+ square.y = SCREEN.CENTER_Y + 200 * Math.sin(square.startAngle + time);
}
}
};
function resetGameToMenu() {
@@ -789,29 +835,23 @@
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]);
+ 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) {
+ [statusText, playerModeText, enemyModeText, playerHPText, enemyHPText, 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 botón que indica ataque de un juego de mesa, color rojo sin texto
Crea una versió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
Símbolo del elemento aire
Símbolo de la tierra color verde
Símbolo del fuego color rojo
Sí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 vací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 vacío, deben ser flamas y montículos rojos en la parte inferior
Crea la parte inversa de una carta que representa el elemento tierra, no debe tener texto ni espacio vacío, deben ser montí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 símbolo de Gaia, sin texto, color verde y café
The sun