/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { highScore: 0, gamesPlayed: 0, wavesCompleted: 0, bestWave: 0, playerName: "Player", topPlayers: {} }); /**** * Classes ****/ var ActionButton = Container.expand(function (text, callback) { var self = Container.call(this); var buttonBg = self.attachAsset('actionButton', { anchorX: 0.5, anchorY: 0.5 }); var buttonText = new Text2(text, { size: 40, fill: 0xFFFFFF }); buttonText.anchor.set(0.5, 0.5); self.addChild(buttonText); self.setText = function (newText) { buttonText.setText(newText); }; self.setEnabled = function (enabled) { buttonBg.alpha = enabled ? 1 : 0.5; self.interactive = enabled; }; self.down = function (x, y, obj) { if (callback) callback(); }; return self; }); var Hand = Container.expand(function (isPlayer) { var self = Container.call(this); self.isPlayer = isPlayer; self.health = 100; self.maxHealth = 100; self.isCharging = false; self.chargeAmount = 0; self.isDodging = false; self.isAttacking = false; var handGraphics = self.attachAsset(isPlayer ? 'playerHand' : 'aiHand', { anchorX: 0.5, anchorY: 0.5 }); self.resetPosition = function () { if (self.isPlayer) { self.x = 1024; self.y = 1800; } else { self.x = 1024; self.y = 932; } self.isDodging = false; self.isAttacking = false; handGraphics.alpha = 1; handGraphics.rotation = 0; }; self.startCharge = function () { self.isCharging = true; self.chargeAmount = 0; }; self.stopCharge = function () { self.isCharging = false; return self.chargeAmount; }; self.attack = function (power) { self.isAttacking = true; var targetY = self.isPlayer ? 1200 : 1532; tween(self, { y: targetY }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { tween(self, { y: self.isPlayer ? 1800 : 932 }, { duration: 300, easing: tween.easeIn, onFinish: function onFinish() { self.isAttacking = false; } }); } }); return power; }; self.dodge = function () { self.isDodging = true; var dodgeX = self.x + (Math.random() > 0.5 ? 200 : -200); handGraphics.alpha = 0.7; tween(self, { x: dodgeX }, { duration: 150, easing: tween.easeOut, onFinish: function onFinish() { tween(self, { x: 1024 }, { duration: 200, easing: tween.easeIn, onFinish: function onFinish() { self.isDodging = false; handGraphics.alpha = 1; } }); } }); }; self.takeDamage = function (damage) { self.health -= damage; if (self.health < 0) self.health = 0; LK.effects.flashObject(self, 0xFF0000, 500); tween(handGraphics, { rotation: 0.3 }, { duration: 100, onFinish: function onFinish() { tween(handGraphics, { rotation: 0 }, { duration: 100 }); } }); }; self.update = function () { if (self.isCharging && self.chargeAmount < 100) { self.chargeAmount += 2; if (self.chargeAmount > 100) self.chargeAmount = 100; } }; return self; }); var NameInput = Container.expand(function () { var self = Container.call(this); self.playerName = storage.playerName || 'Player'; self.isEditing = false; self.cursorVisible = true; self.cursorTimer = null; var background = LK.getAsset('chargeBar', { anchorX: 0.5, anchorY: 0.5, width: 800, height: 600, color: 0x222222 }); self.addChild(background); var titleText = new Text2('Enter Your Name', { size: 40, fill: 0xFFFFFF }); titleText.anchor.set(0.5, 0.5); titleText.y = -120; self.addChild(titleText); var nameText = new Text2(self.playerName, { size: 50, fill: 0xFFFF00 }); nameText.anchor.set(0.5, 0.5); nameText.y = 0; self.addChild(nameText); // Add instructions text var instructionText = new Text2('Use buttons below to enter name', { size: 25, fill: 0xAAAAAA }); instructionText.anchor.set(0.5, 0.5); instructionText.y = 50; self.addChild(instructionText); // Create invisible text input field for name editing var inputField = LK.getAsset('chargeBar', { anchorX: 0.5, anchorY: 0.5, width: 400, height: 60, alpha: 0.3, y: 0 }); self.addChild(inputField); // Clear button var clearButton = new ActionButton('Clear', function () { self.playerName = ''; self.updateDisplay(); }); clearButton.x = -150; clearButton.y = 120; clearButton.scaleX = 0.7; clearButton.scaleY = 0.7; self.addChild(clearButton); var confirmButton = new ActionButton('Confirm', function () { if (self.playerName.length > 0) { storage.playerName = self.playerName; self.visible = false; if (self.onConfirm) self.onConfirm(); } }); confirmButton.x = 0; confirmButton.y = 120; self.addChild(confirmButton); // Preset name buttons var presetNames = ['Player', 'Hero', 'Champion', 'Warrior']; var presetContainer = new Container(); presetContainer.y = -60; for (var i = 0; i < presetNames.length; i++) { var presetButton = new ActionButton(presetNames[i], function (name) { return function () { self.playerName = name; self.updateDisplay(); }; }(presetNames[i])); presetButton.x = (i - 1.5) * 150; presetButton.scaleX = 0.6; presetButton.scaleY = 0.6; presetContainer.addChild(presetButton); } self.addChild(presetContainer); // Character buttons for typing var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; var charContainer = new Container(); charContainer.y = -20; // Create character buttons in rows for (var i = 0; i < chars.length; i++) { var row = Math.floor(i / 9); var col = i % 9; var charButton = new ActionButton(chars[i], function (_char) { return function () { if (self.playerName.length < 12) { self.playerName += _char; self.updateDisplay(); } }; }(chars[i])); charButton.x = (col - 4) * 65; charButton.y = row * 70 + 200; charButton.scaleX = 0.5; charButton.scaleY = 0.5; charContainer.addChild(charButton); } // Add space button var spaceButton = new ActionButton('Space', function () { if (self.playerName.length < 12 && self.playerName.length > 0 && self.playerName[self.playerName.length - 1] !== ' ') { self.playerName += ' '; self.updateDisplay(); } }); spaceButton.x = 0; spaceButton.y = 340; spaceButton.scaleX = 0.7; spaceButton.scaleY = 0.5; charContainer.addChild(spaceButton); // Backspace button var backspaceButton = new ActionButton('←', function () { if (self.playerName.length > 0) { self.playerName = self.playerName.slice(0, -1); self.updateDisplay(); } }); backspaceButton.x = 260; backspaceButton.y = 270; backspaceButton.scaleX = 0.5; backspaceButton.scaleY = 0.5; charContainer.addChild(backspaceButton); self.addChild(charContainer); self.updateDisplay = function () { var displayText = self.playerName; if (self.isEditing && self.cursorVisible) { displayText += '|'; } nameText.setText(displayText || '|'); }; self.updateName = function (newName) { self.playerName = newName; self.updateDisplay(); }; // Start cursor blinking self.cursorTimer = LK.setInterval(function () { if (self.visible) { self.cursorVisible = !self.cursorVisible; self.updateDisplay(); } }, 500); return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x2E7D32 }); /**** * Game Code ****/ var playerHand = new Hand(true); var aiHand = new Hand(false); var gameState = 'waiting'; // waiting, playerTurn, aiTurn, gameOver var currentTurn = 'player'; // player or ai var isPlayerAttacker = true; var aiDifficulty = 0.5; var aiReactionTime = 200; var currentWave = 1; var totalWaves = 4; // UI Elements var table = LK.getAsset('table', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 1366 }); game.addChild(table); var chargeBarBg = LK.getAsset('chargeBar', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 2500 }); game.addChild(chargeBarBg); var chargeFill = LK.getAsset('chargeFill', { anchorX: 0, anchorY: 0.5, x: 824, y: 2500 }); game.addChild(chargeFill); var actionButton = new ActionButton('Start Turn', function () { if (gameState === 'waiting') { startPlayerTurn(); } else if (gameState === 'playerTurn' && isPlayerAttacker) { if (playerHand.isCharging) { executePlayerAttack(); } else { startPlayerCharge(); } } else if (gameState === 'playerTurn' && !isPlayerAttacker) { executePlayerDodge(); } }); actionButton.x = 1024; actionButton.y = 2600; game.addChild(actionButton); // Health bars var playerHealthBg = LK.getAsset('chargeBar', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 2100, width: 400, height: 20, color: 0x333333 }); game.addChild(playerHealthBg); var playerHealthFill = LK.getAsset('chargeFill', { anchorX: 0, anchorY: 0.5, x: 824, y: 2100, width: 400, height: 16, color: 0x4CAF50 }); game.addChild(playerHealthFill); var aiHealthBg = LK.getAsset('chargeBar', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 632, width: 400, height: 20, color: 0x333333 }); game.addChild(aiHealthBg); var aiHealthFill = LK.getAsset('chargeFill', { anchorX: 0, anchorY: 0.5, x: 824, y: 632, width: 400, height: 16, color: 0x4CAF50 }); game.addChild(aiHealthFill); // Status text var statusText = new Text2('Tap "Start Turn" to begin!', { size: 50, fill: 0xFFFFFF }); statusText.anchor.set(0.5, 0.5); statusText.x = 1024; statusText.y = 300; game.addChild(statusText); // Turn indicator var turnText = new Text2('Your Turn - Attack', { size: 40, fill: 0xFFFF00 }); turnText.anchor.set(0.5, 0.5); turnText.x = 1024; turnText.y = 400; game.addChild(turnText); // Wave indicator var waveText = new Text2('Wave 1 of 4', { size: 35, fill: 0xFFFFFF }); waveText.anchor.set(0.5, 0.5); waveText.x = 1024; waveText.y = 200; game.addChild(waveText); // Leaderboard display var leaderboardText = new Text2('High Score: ' + storage.highScore, { size: 30, fill: 0xFFD700 }); leaderboardText.anchor.set(0.5, 0.5); leaderboardText.x = 1024; leaderboardText.y = 150; game.addChild(leaderboardText); var statsText = new Text2('Games: ' + storage.gamesPlayed + ' | Best Wave: ' + storage.bestWave, { size: 25, fill: 0xCCCCCC }); statsText.anchor.set(0.5, 0.5); statsText.x = 1024; statsText.y = 100; game.addChild(statsText); // Player name display var playerNameText = new Text2(storage.playerName + ' - Total Played: ' + storage.gamesPlayed, { size: 28, fill: 0x00FF00 }); playerNameText.anchor.set(0.5, 0.5); playerNameText.x = 1024; playerNameText.y = 50; game.addChild(playerNameText); // Name input system var nameInput = new NameInput(); nameInput.x = 1024; nameInput.y = 1366; nameInput.visible = false; game.addChild(nameInput); // Show name input on first play if (!storage.playerName || storage.playerName === 'Player' || storage.gamesPlayed === 0) { nameInput.visible = true; gameState = 'nameInput'; actionButton.setEnabled(false); statusText.setText('Please enter your name'); } nameInput.onConfirm = function () { if (nameInput.cursorTimer) { LK.clearInterval(nameInput.cursorTimer); } gameState = 'waiting'; actionButton.setEnabled(true); playerNameText.setText(storage.playerName + ' - Total Played: ' + storage.gamesPlayed); }; // Add hands to game game.addChild(playerHand); game.addChild(aiHand); // Initialize positions playerHand.resetPosition(); aiHand.resetPosition(); // Start background music LK.playMusic('bgmusic'); // AI variables var aiActionTimer = 0; var aiDecisionMade = false; var aiWillDodge = false; function startPlayerTurn() { gameState = 'playerTurn'; actionButton.setEnabled(true); if (isPlayerAttacker) { statusText.setText('Hold to charge, release to attack!'); turnText.setText('Your Turn - Attack'); actionButton.setText('Charge Attack'); // Reset AI decision for this turn aiDecisionMade = false; // Wave 4 has more aggressive AI dodge behavior if (currentWave === 4) { aiWillDodge = Math.random() < 0.7; // 70% dodge chance in wave 4 } else { aiWillDodge = Math.random() < 0.4 + aiDifficulty * 0.15; } } else { statusText.setText('Get ready to dodge!'); turnText.setText('Your Turn - Defend'); actionButton.setText('Ready'); } } function startPlayerCharge() { if (!playerHand.isCharging) { playerHand.startCharge(); actionButton.setText('Release to Attack'); statusText.setText('Charging... Release to attack!'); } } function executePlayerAttack() { var power = playerHand.stopCharge(); var damage = Math.floor(power * 0.5) + 10; playerHand.attack(power); // AI dodge decision was made at turn start if (aiWillDodge) { aiHand.dodge(); statusText.setText('AI dodged your attack!'); LK.getSound('dodge').play(); } else { aiHand.takeDamage(damage); statusText.setText('Hit! Dealt ' + damage + ' damage!'); LK.getSound('hit').play(); } LK.setTimeout(function () { if (aiHand.health <= 0) { endGame(true); } else { switchTurns(); } }, 100); } function executePlayerDodge() { playerHand.dodge(); statusText.setText('You dodged!'); actionButton.setEnabled(false); LK.getSound('dodge').play(); LK.setTimeout(function () { switchTurns(); }, 100); } function executeAIAttack() { // Wave 4 has much stronger AI attacks var aiPower, damage, dodgeChance; if (currentWave === 4) { aiPower = 60 + Math.random() * 60; // Much higher base power damage = Math.floor(aiPower * 0.6) + 15; // Higher damage multiplier dodgeChance = 0.1; // Very low dodge chance (10%) } else { aiPower = 30 + Math.random() * 40 * aiDifficulty; damage = Math.floor(aiPower * 0.4) + 8; dodgeChance = Math.max(0.2, 0.5 - aiDifficulty * 0.1); } aiHand.attack(aiPower); // Player has a chance to dodge if they're quick enough if (Math.random() < dodgeChance) { playerHand.dodge(); statusText.setText('You dodged the AI attack!'); LK.getSound('dodge').play(); } else { playerHand.takeDamage(damage); statusText.setText('AI hit you for ' + damage + ' damage!'); LK.getSound('hit').play(); } LK.setTimeout(function () { if (playerHand.health <= 0) { endGame(false); } else { switchTurns(); } }, 100); } function switchTurns() { isPlayerAttacker = !isPlayerAttacker; currentTurn = currentTurn === 'player' ? 'ai' : 'player'; if (currentTurn === 'player') { startPlayerTurn(); } else { startAITurn(); } } function startAITurn() { gameState = 'aiTurn'; actionButton.setEnabled(false); if (!isPlayerAttacker) { // AI is attacking statusText.setText('AI attacks!'); turnText.setText('AI Turn - Attack'); // AI attacks with slight delay for normal mode LK.setTimeout(function () { executeAIAttack(); }, aiReactionTime); } else { // AI is defending, player should attack statusText.setText('Attack the AI!'); turnText.setText('Your Turn - Attack'); actionButton.setText('Charge Attack'); actionButton.setEnabled(true); gameState = 'playerTurn'; } } function endGame(playerWon) { gameState = 'gameOver'; actionButton.setEnabled(false); if (playerWon) { if (currentWave < totalWaves) { // Advance to next wave currentWave++; // Special hard mode for wave 4 if (currentWave === 4) { aiDifficulty = 0.95; // Very high difficulty for final wave aiReactionTime = 50; // Very fast reaction time } else { aiDifficulty = 0.5 + (currentWave - 1) * 0.3; aiReactionTime = Math.max(100, 200 - currentWave * 20); } // Reset health for next wave playerHand.health = playerHand.maxHealth; aiHand.health = aiHand.maxHealth; playerHand.resetPosition(); aiHand.resetPosition(); // Update wave text waveText.setText('Wave ' + currentWave + ' of ' + totalWaves); // Start next wave statusText.setText('Wave ' + currentWave + ' - Get ready!'); gameState = 'waiting'; isPlayerAttacker = true; currentTurn = 'player'; actionButton.setText('Start Turn'); actionButton.setEnabled(true); } else { // Player won all waves - record final score and stats var finalScore = LK.getScore(); updateLeaderboard(finalScore, totalWaves, true); statusText.setText('You Win All Waves! High Score: ' + storage.highScore); LK.showYouWin(); } } else { // Player lost - record current progress var finalScore = LK.getScore(); var wavesCompleted = currentWave - 1; updateLeaderboard(finalScore, wavesCompleted, false); statusText.setText('AI Wins! High Score: ' + storage.highScore); LK.showGameOver(); } } function updateLeaderboard(finalScore, wavesCompleted, gameWon) { // Update games played storage.gamesPlayed++; // Update best wave reached if (currentWave > storage.bestWave) { storage.bestWave = currentWave; } // Update waves completed total storage.wavesCompleted += wavesCompleted; // Update high score if (finalScore > storage.highScore) { storage.highScore = finalScore; } // Track top players - use separate storage keys to avoid nested objects var playerGamesKey = storage.playerName + '_games'; var playerScoreKey = storage.playerName + '_score'; if (!storage[playerGamesKey]) { storage[playerGamesKey] = 0; } if (!storage[playerScoreKey]) { storage[playerScoreKey] = 0; } storage[playerGamesKey]++; if (finalScore > storage[playerScoreKey]) { storage[playerScoreKey] = finalScore; } // Update display leaderboardText.setText('High Score: ' + storage.highScore); statsText.setText('Games: ' + storage.gamesPlayed + ' | Best Wave: ' + storage.bestWave); playerNameText.setText(storage.playerName + ' - Total Played: ' + storage.gamesPlayed); } function updateUI() { // Update charge bar var chargePercent = playerHand.chargeAmount / 100; chargeFill.width = 400 * chargePercent; // Update health bars var playerHealthPercent = playerHand.health / playerHand.maxHealth; var aiHealthPercent = aiHand.health / aiHand.maxHealth; playerHealthFill.width = 400 * playerHealthPercent; aiHealthFill.width = 400 * aiHealthPercent; // Update score based on waves completed and current progress var baseScore = (currentWave - 1) * 100; var currentWaveScore = Math.max(0, 100 - aiHand.health); LK.setScore(baseScore + currentWaveScore); // Update leaderboard display in real-time leaderboardText.setText('High Score: ' + storage.highScore); playerNameText.setText(storage.playerName + ' - Total Played: ' + storage.gamesPlayed); } game.update = function () { updateUI(); };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
highScore: 0,
gamesPlayed: 0,
wavesCompleted: 0,
bestWave: 0,
playerName: "Player",
topPlayers: {}
});
/****
* Classes
****/
var ActionButton = Container.expand(function (text, callback) {
var self = Container.call(this);
var buttonBg = self.attachAsset('actionButton', {
anchorX: 0.5,
anchorY: 0.5
});
var buttonText = new Text2(text, {
size: 40,
fill: 0xFFFFFF
});
buttonText.anchor.set(0.5, 0.5);
self.addChild(buttonText);
self.setText = function (newText) {
buttonText.setText(newText);
};
self.setEnabled = function (enabled) {
buttonBg.alpha = enabled ? 1 : 0.5;
self.interactive = enabled;
};
self.down = function (x, y, obj) {
if (callback) callback();
};
return self;
});
var Hand = Container.expand(function (isPlayer) {
var self = Container.call(this);
self.isPlayer = isPlayer;
self.health = 100;
self.maxHealth = 100;
self.isCharging = false;
self.chargeAmount = 0;
self.isDodging = false;
self.isAttacking = false;
var handGraphics = self.attachAsset(isPlayer ? 'playerHand' : 'aiHand', {
anchorX: 0.5,
anchorY: 0.5
});
self.resetPosition = function () {
if (self.isPlayer) {
self.x = 1024;
self.y = 1800;
} else {
self.x = 1024;
self.y = 932;
}
self.isDodging = false;
self.isAttacking = false;
handGraphics.alpha = 1;
handGraphics.rotation = 0;
};
self.startCharge = function () {
self.isCharging = true;
self.chargeAmount = 0;
};
self.stopCharge = function () {
self.isCharging = false;
return self.chargeAmount;
};
self.attack = function (power) {
self.isAttacking = true;
var targetY = self.isPlayer ? 1200 : 1532;
tween(self, {
y: targetY
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(self, {
y: self.isPlayer ? 1800 : 932
}, {
duration: 300,
easing: tween.easeIn,
onFinish: function onFinish() {
self.isAttacking = false;
}
});
}
});
return power;
};
self.dodge = function () {
self.isDodging = true;
var dodgeX = self.x + (Math.random() > 0.5 ? 200 : -200);
handGraphics.alpha = 0.7;
tween(self, {
x: dodgeX
}, {
duration: 150,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(self, {
x: 1024
}, {
duration: 200,
easing: tween.easeIn,
onFinish: function onFinish() {
self.isDodging = false;
handGraphics.alpha = 1;
}
});
}
});
};
self.takeDamage = function (damage) {
self.health -= damage;
if (self.health < 0) self.health = 0;
LK.effects.flashObject(self, 0xFF0000, 500);
tween(handGraphics, {
rotation: 0.3
}, {
duration: 100,
onFinish: function onFinish() {
tween(handGraphics, {
rotation: 0
}, {
duration: 100
});
}
});
};
self.update = function () {
if (self.isCharging && self.chargeAmount < 100) {
self.chargeAmount += 2;
if (self.chargeAmount > 100) self.chargeAmount = 100;
}
};
return self;
});
var NameInput = Container.expand(function () {
var self = Container.call(this);
self.playerName = storage.playerName || 'Player';
self.isEditing = false;
self.cursorVisible = true;
self.cursorTimer = null;
var background = LK.getAsset('chargeBar', {
anchorX: 0.5,
anchorY: 0.5,
width: 800,
height: 600,
color: 0x222222
});
self.addChild(background);
var titleText = new Text2('Enter Your Name', {
size: 40,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0.5);
titleText.y = -120;
self.addChild(titleText);
var nameText = new Text2(self.playerName, {
size: 50,
fill: 0xFFFF00
});
nameText.anchor.set(0.5, 0.5);
nameText.y = 0;
self.addChild(nameText);
// Add instructions text
var instructionText = new Text2('Use buttons below to enter name', {
size: 25,
fill: 0xAAAAAA
});
instructionText.anchor.set(0.5, 0.5);
instructionText.y = 50;
self.addChild(instructionText);
// Create invisible text input field for name editing
var inputField = LK.getAsset('chargeBar', {
anchorX: 0.5,
anchorY: 0.5,
width: 400,
height: 60,
alpha: 0.3,
y: 0
});
self.addChild(inputField);
// Clear button
var clearButton = new ActionButton('Clear', function () {
self.playerName = '';
self.updateDisplay();
});
clearButton.x = -150;
clearButton.y = 120;
clearButton.scaleX = 0.7;
clearButton.scaleY = 0.7;
self.addChild(clearButton);
var confirmButton = new ActionButton('Confirm', function () {
if (self.playerName.length > 0) {
storage.playerName = self.playerName;
self.visible = false;
if (self.onConfirm) self.onConfirm();
}
});
confirmButton.x = 0;
confirmButton.y = 120;
self.addChild(confirmButton);
// Preset name buttons
var presetNames = ['Player', 'Hero', 'Champion', 'Warrior'];
var presetContainer = new Container();
presetContainer.y = -60;
for (var i = 0; i < presetNames.length; i++) {
var presetButton = new ActionButton(presetNames[i], function (name) {
return function () {
self.playerName = name;
self.updateDisplay();
};
}(presetNames[i]));
presetButton.x = (i - 1.5) * 150;
presetButton.scaleX = 0.6;
presetButton.scaleY = 0.6;
presetContainer.addChild(presetButton);
}
self.addChild(presetContainer);
// Character buttons for typing
var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
var charContainer = new Container();
charContainer.y = -20;
// Create character buttons in rows
for (var i = 0; i < chars.length; i++) {
var row = Math.floor(i / 9);
var col = i % 9;
var charButton = new ActionButton(chars[i], function (_char) {
return function () {
if (self.playerName.length < 12) {
self.playerName += _char;
self.updateDisplay();
}
};
}(chars[i]));
charButton.x = (col - 4) * 65;
charButton.y = row * 70 + 200;
charButton.scaleX = 0.5;
charButton.scaleY = 0.5;
charContainer.addChild(charButton);
}
// Add space button
var spaceButton = new ActionButton('Space', function () {
if (self.playerName.length < 12 && self.playerName.length > 0 && self.playerName[self.playerName.length - 1] !== ' ') {
self.playerName += ' ';
self.updateDisplay();
}
});
spaceButton.x = 0;
spaceButton.y = 340;
spaceButton.scaleX = 0.7;
spaceButton.scaleY = 0.5;
charContainer.addChild(spaceButton);
// Backspace button
var backspaceButton = new ActionButton('←', function () {
if (self.playerName.length > 0) {
self.playerName = self.playerName.slice(0, -1);
self.updateDisplay();
}
});
backspaceButton.x = 260;
backspaceButton.y = 270;
backspaceButton.scaleX = 0.5;
backspaceButton.scaleY = 0.5;
charContainer.addChild(backspaceButton);
self.addChild(charContainer);
self.updateDisplay = function () {
var displayText = self.playerName;
if (self.isEditing && self.cursorVisible) {
displayText += '|';
}
nameText.setText(displayText || '|');
};
self.updateName = function (newName) {
self.playerName = newName;
self.updateDisplay();
};
// Start cursor blinking
self.cursorTimer = LK.setInterval(function () {
if (self.visible) {
self.cursorVisible = !self.cursorVisible;
self.updateDisplay();
}
}, 500);
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2E7D32
});
/****
* Game Code
****/
var playerHand = new Hand(true);
var aiHand = new Hand(false);
var gameState = 'waiting'; // waiting, playerTurn, aiTurn, gameOver
var currentTurn = 'player'; // player or ai
var isPlayerAttacker = true;
var aiDifficulty = 0.5;
var aiReactionTime = 200;
var currentWave = 1;
var totalWaves = 4;
// UI Elements
var table = LK.getAsset('table', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1366
});
game.addChild(table);
var chargeBarBg = LK.getAsset('chargeBar', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 2500
});
game.addChild(chargeBarBg);
var chargeFill = LK.getAsset('chargeFill', {
anchorX: 0,
anchorY: 0.5,
x: 824,
y: 2500
});
game.addChild(chargeFill);
var actionButton = new ActionButton('Start Turn', function () {
if (gameState === 'waiting') {
startPlayerTurn();
} else if (gameState === 'playerTurn' && isPlayerAttacker) {
if (playerHand.isCharging) {
executePlayerAttack();
} else {
startPlayerCharge();
}
} else if (gameState === 'playerTurn' && !isPlayerAttacker) {
executePlayerDodge();
}
});
actionButton.x = 1024;
actionButton.y = 2600;
game.addChild(actionButton);
// Health bars
var playerHealthBg = LK.getAsset('chargeBar', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 2100,
width: 400,
height: 20,
color: 0x333333
});
game.addChild(playerHealthBg);
var playerHealthFill = LK.getAsset('chargeFill', {
anchorX: 0,
anchorY: 0.5,
x: 824,
y: 2100,
width: 400,
height: 16,
color: 0x4CAF50
});
game.addChild(playerHealthFill);
var aiHealthBg = LK.getAsset('chargeBar', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 632,
width: 400,
height: 20,
color: 0x333333
});
game.addChild(aiHealthBg);
var aiHealthFill = LK.getAsset('chargeFill', {
anchorX: 0,
anchorY: 0.5,
x: 824,
y: 632,
width: 400,
height: 16,
color: 0x4CAF50
});
game.addChild(aiHealthFill);
// Status text
var statusText = new Text2('Tap "Start Turn" to begin!', {
size: 50,
fill: 0xFFFFFF
});
statusText.anchor.set(0.5, 0.5);
statusText.x = 1024;
statusText.y = 300;
game.addChild(statusText);
// Turn indicator
var turnText = new Text2('Your Turn - Attack', {
size: 40,
fill: 0xFFFF00
});
turnText.anchor.set(0.5, 0.5);
turnText.x = 1024;
turnText.y = 400;
game.addChild(turnText);
// Wave indicator
var waveText = new Text2('Wave 1 of 4', {
size: 35,
fill: 0xFFFFFF
});
waveText.anchor.set(0.5, 0.5);
waveText.x = 1024;
waveText.y = 200;
game.addChild(waveText);
// Leaderboard display
var leaderboardText = new Text2('High Score: ' + storage.highScore, {
size: 30,
fill: 0xFFD700
});
leaderboardText.anchor.set(0.5, 0.5);
leaderboardText.x = 1024;
leaderboardText.y = 150;
game.addChild(leaderboardText);
var statsText = new Text2('Games: ' + storage.gamesPlayed + ' | Best Wave: ' + storage.bestWave, {
size: 25,
fill: 0xCCCCCC
});
statsText.anchor.set(0.5, 0.5);
statsText.x = 1024;
statsText.y = 100;
game.addChild(statsText);
// Player name display
var playerNameText = new Text2(storage.playerName + ' - Total Played: ' + storage.gamesPlayed, {
size: 28,
fill: 0x00FF00
});
playerNameText.anchor.set(0.5, 0.5);
playerNameText.x = 1024;
playerNameText.y = 50;
game.addChild(playerNameText);
// Name input system
var nameInput = new NameInput();
nameInput.x = 1024;
nameInput.y = 1366;
nameInput.visible = false;
game.addChild(nameInput);
// Show name input on first play
if (!storage.playerName || storage.playerName === 'Player' || storage.gamesPlayed === 0) {
nameInput.visible = true;
gameState = 'nameInput';
actionButton.setEnabled(false);
statusText.setText('Please enter your name');
}
nameInput.onConfirm = function () {
if (nameInput.cursorTimer) {
LK.clearInterval(nameInput.cursorTimer);
}
gameState = 'waiting';
actionButton.setEnabled(true);
playerNameText.setText(storage.playerName + ' - Total Played: ' + storage.gamesPlayed);
};
// Add hands to game
game.addChild(playerHand);
game.addChild(aiHand);
// Initialize positions
playerHand.resetPosition();
aiHand.resetPosition();
// Start background music
LK.playMusic('bgmusic');
// AI variables
var aiActionTimer = 0;
var aiDecisionMade = false;
var aiWillDodge = false;
function startPlayerTurn() {
gameState = 'playerTurn';
actionButton.setEnabled(true);
if (isPlayerAttacker) {
statusText.setText('Hold to charge, release to attack!');
turnText.setText('Your Turn - Attack');
actionButton.setText('Charge Attack');
// Reset AI decision for this turn
aiDecisionMade = false;
// Wave 4 has more aggressive AI dodge behavior
if (currentWave === 4) {
aiWillDodge = Math.random() < 0.7; // 70% dodge chance in wave 4
} else {
aiWillDodge = Math.random() < 0.4 + aiDifficulty * 0.15;
}
} else {
statusText.setText('Get ready to dodge!');
turnText.setText('Your Turn - Defend');
actionButton.setText('Ready');
}
}
function startPlayerCharge() {
if (!playerHand.isCharging) {
playerHand.startCharge();
actionButton.setText('Release to Attack');
statusText.setText('Charging... Release to attack!');
}
}
function executePlayerAttack() {
var power = playerHand.stopCharge();
var damage = Math.floor(power * 0.5) + 10;
playerHand.attack(power);
// AI dodge decision was made at turn start
if (aiWillDodge) {
aiHand.dodge();
statusText.setText('AI dodged your attack!');
LK.getSound('dodge').play();
} else {
aiHand.takeDamage(damage);
statusText.setText('Hit! Dealt ' + damage + ' damage!');
LK.getSound('hit').play();
}
LK.setTimeout(function () {
if (aiHand.health <= 0) {
endGame(true);
} else {
switchTurns();
}
}, 100);
}
function executePlayerDodge() {
playerHand.dodge();
statusText.setText('You dodged!');
actionButton.setEnabled(false);
LK.getSound('dodge').play();
LK.setTimeout(function () {
switchTurns();
}, 100);
}
function executeAIAttack() {
// Wave 4 has much stronger AI attacks
var aiPower, damage, dodgeChance;
if (currentWave === 4) {
aiPower = 60 + Math.random() * 60; // Much higher base power
damage = Math.floor(aiPower * 0.6) + 15; // Higher damage multiplier
dodgeChance = 0.1; // Very low dodge chance (10%)
} else {
aiPower = 30 + Math.random() * 40 * aiDifficulty;
damage = Math.floor(aiPower * 0.4) + 8;
dodgeChance = Math.max(0.2, 0.5 - aiDifficulty * 0.1);
}
aiHand.attack(aiPower);
// Player has a chance to dodge if they're quick enough
if (Math.random() < dodgeChance) {
playerHand.dodge();
statusText.setText('You dodged the AI attack!');
LK.getSound('dodge').play();
} else {
playerHand.takeDamage(damage);
statusText.setText('AI hit you for ' + damage + ' damage!');
LK.getSound('hit').play();
}
LK.setTimeout(function () {
if (playerHand.health <= 0) {
endGame(false);
} else {
switchTurns();
}
}, 100);
}
function switchTurns() {
isPlayerAttacker = !isPlayerAttacker;
currentTurn = currentTurn === 'player' ? 'ai' : 'player';
if (currentTurn === 'player') {
startPlayerTurn();
} else {
startAITurn();
}
}
function startAITurn() {
gameState = 'aiTurn';
actionButton.setEnabled(false);
if (!isPlayerAttacker) {
// AI is attacking
statusText.setText('AI attacks!');
turnText.setText('AI Turn - Attack');
// AI attacks with slight delay for normal mode
LK.setTimeout(function () {
executeAIAttack();
}, aiReactionTime);
} else {
// AI is defending, player should attack
statusText.setText('Attack the AI!');
turnText.setText('Your Turn - Attack');
actionButton.setText('Charge Attack');
actionButton.setEnabled(true);
gameState = 'playerTurn';
}
}
function endGame(playerWon) {
gameState = 'gameOver';
actionButton.setEnabled(false);
if (playerWon) {
if (currentWave < totalWaves) {
// Advance to next wave
currentWave++;
// Special hard mode for wave 4
if (currentWave === 4) {
aiDifficulty = 0.95; // Very high difficulty for final wave
aiReactionTime = 50; // Very fast reaction time
} else {
aiDifficulty = 0.5 + (currentWave - 1) * 0.3;
aiReactionTime = Math.max(100, 200 - currentWave * 20);
}
// Reset health for next wave
playerHand.health = playerHand.maxHealth;
aiHand.health = aiHand.maxHealth;
playerHand.resetPosition();
aiHand.resetPosition();
// Update wave text
waveText.setText('Wave ' + currentWave + ' of ' + totalWaves);
// Start next wave
statusText.setText('Wave ' + currentWave + ' - Get ready!');
gameState = 'waiting';
isPlayerAttacker = true;
currentTurn = 'player';
actionButton.setText('Start Turn');
actionButton.setEnabled(true);
} else {
// Player won all waves - record final score and stats
var finalScore = LK.getScore();
updateLeaderboard(finalScore, totalWaves, true);
statusText.setText('You Win All Waves! High Score: ' + storage.highScore);
LK.showYouWin();
}
} else {
// Player lost - record current progress
var finalScore = LK.getScore();
var wavesCompleted = currentWave - 1;
updateLeaderboard(finalScore, wavesCompleted, false);
statusText.setText('AI Wins! High Score: ' + storage.highScore);
LK.showGameOver();
}
}
function updateLeaderboard(finalScore, wavesCompleted, gameWon) {
// Update games played
storage.gamesPlayed++;
// Update best wave reached
if (currentWave > storage.bestWave) {
storage.bestWave = currentWave;
}
// Update waves completed total
storage.wavesCompleted += wavesCompleted;
// Update high score
if (finalScore > storage.highScore) {
storage.highScore = finalScore;
}
// Track top players - use separate storage keys to avoid nested objects
var playerGamesKey = storage.playerName + '_games';
var playerScoreKey = storage.playerName + '_score';
if (!storage[playerGamesKey]) {
storage[playerGamesKey] = 0;
}
if (!storage[playerScoreKey]) {
storage[playerScoreKey] = 0;
}
storage[playerGamesKey]++;
if (finalScore > storage[playerScoreKey]) {
storage[playerScoreKey] = finalScore;
}
// Update display
leaderboardText.setText('High Score: ' + storage.highScore);
statsText.setText('Games: ' + storage.gamesPlayed + ' | Best Wave: ' + storage.bestWave);
playerNameText.setText(storage.playerName + ' - Total Played: ' + storage.gamesPlayed);
}
function updateUI() {
// Update charge bar
var chargePercent = playerHand.chargeAmount / 100;
chargeFill.width = 400 * chargePercent;
// Update health bars
var playerHealthPercent = playerHand.health / playerHand.maxHealth;
var aiHealthPercent = aiHand.health / aiHand.maxHealth;
playerHealthFill.width = 400 * playerHealthPercent;
aiHealthFill.width = 400 * aiHealthPercent;
// Update score based on waves completed and current progress
var baseScore = (currentWave - 1) * 100;
var currentWaveScore = Math.max(0, 100 - aiHand.health);
LK.setScore(baseScore + currentWaveScore);
// Update leaderboard display in real-time
leaderboardText.setText('High Score: ' + storage.highScore);
playerNameText.setText(storage.playerName + ' - Total Played: ' + storage.gamesPlayed);
}
game.update = function () {
updateUI();
};