/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var EnemySpell = Container.expand(function () { var self = Container.call(this); var spellGraphics = self.attachAsset('spell', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 6; self.rotationSpeed = -0.1; self.update = function () { // Move straight toward player wizard (to the left) self.x -= self.speed; // Add rotation (opposite direction) spellGraphics.rotation += self.rotationSpeed; // Remove spell if it goes off screen if (self.x < -200 || self.y < -200 || self.y > 2900) { self.destroy(); } }; return self; }); var PlayerSpell = Container.expand(function () { var self = Container.call(this); var spellGraphics = self.attachAsset('spell', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 6; self.rotationSpeed = 0.1; self.update = function () { // Move straight toward enemy wizard (to the right) self.x += self.speed; // Add rotation spellGraphics.rotation += self.rotationSpeed; // Remove spell if it goes off screen if (self.x > 2248 || self.y < -200 || self.y > 2900) { self.destroy(); } }; return self; }); var RhythmButton = Container.expand(function (buttonType) { var self = Container.call(this); // Choose different note asset based on button type var noteAsset = 'note'; if (buttonType === 'A' || buttonType === 'S') { noteAsset = 'note2'; } else if (buttonType === 'D') { noteAsset = 'note3'; } var buttonGraphics = self.attachAsset(noteAsset, { anchorX: 0.5, anchorY: 0.5 }); self.buttonType = buttonType; self.isActive = false; self.originalScale = 1; self.activate = function () { self.isActive = true; // Move button from right side to left side of screen tween(self, { x: -200 // Move to left side and exit screen }, { duration: beatInterval * 4 // Much slower movement - increased from 2.5 to 4 }); tween(buttonGraphics, { scaleX: 1.2, scaleY: 1.2 }, { duration: 100 }); tween(buttonGraphics, { alpha: 1 }, { duration: 100 }); }; self.deactivate = function () { self.isActive = false; // Reset button position back to right side self.x = 2100; tween(buttonGraphics, { scaleX: 1, scaleY: 1 }, { duration: 200 }); tween(buttonGraphics, { alpha: 0.6 }, { duration: 200 }); }; self.hit = function () { // Play different note sound based on button type var noteSound = 'note' + self.buttonType; LK.getSound(noteSound).play(); tween(buttonGraphics, { scaleX: 0.8, scaleY: 0.8 }, { duration: 50, onFinish: function onFinish() { tween(buttonGraphics, { scaleX: 1, scaleY: 1 }, { duration: 50 }); } }); }; // Set initial alpha buttonGraphics.alpha = 0.6; self.down = function (x, y, obj) { if (self.isActive) { self.hit(); return true; } return false; }; return self; }); var Wizard = Container.expand(function (isPlayer) { var self = Container.call(this); var wizardAsset = isPlayer ? 'wizard' : 'enemyWizard'; var wizardGraphics = self.attachAsset(wizardAsset, { anchorX: 0.5, anchorY: 1 }); self.isPlayer = isPlayer; self.maxHealth = 100; self.health = self.maxHealth; self.isDancing = false; self.dance = function () { if (self.isDancing) return; self.isDancing = true; var originalY = self.y; tween(self, { y: originalY - 30 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { tween(self, { y: originalY }, { duration: 200, easing: tween.easeIn, onFinish: function onFinish() { self.isDancing = false; } }); } }); tween(wizardGraphics, { rotation: 0.2 }, { duration: 100, onFinish: function onFinish() { tween(wizardGraphics, { rotation: -0.2 }, { duration: 200, onFinish: function onFinish() { tween(wizardGraphics, { rotation: 0 }, { duration: 100 }); } }); } }); }; self.castSpell = function () { var spell; if (self.isPlayer) { spell = new PlayerSpell(); spell.x = self.x; spell.y = self.y - 100; // Start from player position } else { spell = new EnemySpell(); spell.x = self.x; spell.y = self.y - 400; // Start from enemy position } game.addChild(spell); spells.push(spell); LK.getSound('spellCast').play(); LK.effects.flashObject(self, 0xffd700, 300); }; self.takeDamage = function (damage) { self.health = Math.max(0, self.health - damage); LK.getSound('wizardHit').play(); LK.effects.flashObject(self, 0xff0000, 500); if (self.health <= 0) { self.die(); } }; self.die = function () { tween(wizardGraphics, { alpha: 0.3, scaleX: 0.8, scaleY: 0.8 }, { duration: 1000 }); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x2c3e50 }); /**** * Game Code ****/ // Game variables var playerWizard; var enemyWizard; var rhythmButtons = []; var spells = []; var currentBeat = 0; var beatInterval = 600; // milliseconds between beats var lastBeatTime = 0; var gameActive = true; var playerHealth; var enemyHealth; var playerHealthBar; var enemyHealthBar; var score = 0; var combo = 0; var currentLevel = 1; // Beat pattern for the song var beatPattern = ['W', 'A', 'S', 'D', 'W', 'S', 'A', 'D']; var patternIndex = 0; // Create wizards playerWizard = game.addChild(new Wizard(true)); playerWizard.x = 400; playerWizard.y = 2200; enemyWizard = game.addChild(new Wizard(false)); enemyWizard.x = 1648; enemyWizard.y = 2200; // Create health bars var playerHealthBg = LK.getAsset('healthBarBg', { anchorX: 0, anchorY: 0.5 }); playerHealthBg.x = 50; playerHealthBg.y = 150; game.addChild(playerHealthBg); playerHealthBar = LK.getAsset('healthBar', { anchorX: 0, anchorY: 0.5 }); playerHealthBar.x = 55; playerHealthBar.y = 150; game.addChild(playerHealthBar); var enemyHealthBg = LK.getAsset('healthBarBg', { anchorX: 1, anchorY: 0.5 }); enemyHealthBg.x = 1998; enemyHealthBg.y = 150; game.addChild(enemyHealthBg); enemyHealthBar = LK.getAsset('healthBar', { anchorX: 1, anchorY: 0.5 }); enemyHealthBar.x = 1993; enemyHealthBar.y = 150; game.addChild(enemyHealthBar); // Create rhythm buttons positioned from the right between enemy wizard head and health bar var buttonTypes = ['W', 'A', 'S', 'D']; var buttonStartX = 2100; // Start from right side of screen var buttonY = 400; // Between enemy wizard head and health bar var buttonSpacing = 100; // Vertical spacing between buttons for (var i = 0; i < buttonTypes.length; i++) { var button = new RhythmButton(buttonTypes[i]); button.x = buttonStartX; button.y = buttonY + i * buttonSpacing; // Stack vertically, one under the other rhythmButtons.push(button); game.addChild(button); } ; // Show level completion screen function showLevelComplete() { // Create level complete text var levelCompleteText = new Text2('Level ' + currentLevel + ' completed!', { size: 120, fill: 0xFFD700 }); levelCompleteText.anchor.set(0.5, 0.5); levelCompleteText.x = 1024; levelCompleteText.y = 1366; game.addChild(levelCompleteText); // Flash screen green for success LK.effects.flashScreen(0x27ae60, 1000); // Remove text and start next level after 2 seconds LK.setTimeout(function () { levelCompleteText.destroy(); currentLevel++; startNextLevel(); }, 2000); } // Level progression function function startNextLevel() { // Increase difficulty beatInterval = Math.max(300, beatInterval - 50); // Faster beats, minimum 300ms // Reset wizards' health playerWizard.health = playerWizard.maxHealth; enemyWizard.health = enemyWizard.maxHealth; // Clear existing spells for (var i = spells.length - 1; i >= 0; i--) { spells[i].destroy(); spells.splice(i, 1); } // Reset wizard graphics var playerGraphics = playerWizard.children[0]; var enemyGraphics = enemyWizard.children[0]; playerGraphics.alpha = 1; playerGraphics.scaleX = 1; playerGraphics.scaleY = 1; enemyGraphics.alpha = 1; enemyGraphics.scaleX = 1; enemyGraphics.scaleY = 1; // Deactivate all buttons for (var i = 0; i < rhythmButtons.length; i++) { rhythmButtons[i].deactivate(); } // Reset beat variables currentBeat = 0; patternIndex = 0; lastBeatTime = LK.ticks; // Clear existing beat timer LK.clearInterval(beatTimer); // Start new beat timer with faster interval beatTimer = LK.setInterval(function () { if (!gameActive) return; currentBeat++; var currentButton = beatPattern[patternIndex % beatPattern.length]; patternIndex++; // Deactivate all buttons for (var i = 0; i < rhythmButtons.length; i++) { rhythmButtons[i].deactivate(); } // Activate current button for (var i = 0; i < rhythmButtons.length; i++) { if (rhythmButtons[i].buttonType === currentButton) { rhythmButtons[i].activate(); break; } } // Enemy AI - increase difficulty by making enemy hit more often based on current level var enemyHitChance = Math.min(0.9, 0.4 + (currentLevel - 1) * 0.1); // Increase by 10% each level, max 90% if (Math.random() < enemyHitChance) { LK.setTimeout(function () { enemyWizard.dance(); enemyWizard.castSpell(); }, beatInterval * 0.3); } lastBeatTime = LK.ticks; }, beatInterval); // Re-enable game gameActive = true; // Flash screen to indicate level start LK.effects.flashScreen(0xffd700, 500); } // Score display var scoreText = new Text2('Score: 0', { size: 80, fill: 0xFFFFFF }); scoreText.anchor.set(0.5, 0); LK.gui.top.addChild(scoreText); // Combo display var comboText = new Text2('Combo: 0', { size: 60, fill: 0xFFD700 }); comboText.anchor.set(0.5, 0); comboText.y = 100; LK.gui.top.addChild(comboText); // Start music LK.playMusic('battleMusic'); // Beat timer var beatTimer = LK.setInterval(function () { if (!gameActive) return; currentBeat++; var currentButton = beatPattern[patternIndex % beatPattern.length]; patternIndex++; // Deactivate all buttons for (var i = 0; i < rhythmButtons.length; i++) { rhythmButtons[i].deactivate(); } // Activate current button for (var i = 0; i < rhythmButtons.length; i++) { if (rhythmButtons[i].buttonType === currentButton) { rhythmButtons[i].activate(); break; } } // Enemy AI - sometimes hits the beat if (Math.random() < 0.4) { // 40% chance enemy hits (reduced from 70%) LK.setTimeout(function () { enemyWizard.dance(); enemyWizard.castSpell(); }, beatInterval * 0.3); } lastBeatTime = LK.ticks; }, beatInterval); // Handle button presses var buttonPressed = false; game.down = function (x, y, obj) { if (!gameActive) return; buttonPressed = false; // Check if any active button was pressed for (var i = 0; i < rhythmButtons.length; i++) { if (rhythmButtons[i].isActive) { var hit = rhythmButtons[i].down(x, y, obj); if (hit) { buttonPressed = true; // Calculate timing accuracy var timeSinceBeat = (LK.ticks - lastBeatTime) * (1000 / 60); // Convert to ms var accuracy = 1 - Math.min(timeSinceBeat / (beatInterval * 0.5), 1); if (accuracy > 0.3) { // Good timing playerWizard.dance(); playerWizard.castSpell(); var points = Math.floor(accuracy * 100); score += points * (combo + 1); combo++; LK.setScore(score); scoreText.setText('Score: ' + score); comboText.setText('Combo: ' + combo); } else { combo = 0; comboText.setText('Combo: 0'); } break; } } } if (!buttonPressed) { combo = 0; comboText.setText('Combo: 0'); } }; // Game update loop game.update = function () { if (!gameActive) return; // Update spells for (var i = spells.length - 1; i >= 0; i--) { var spell = spells[i]; // Check spell collision with wizards if (spell instanceof PlayerSpell && spell.intersects(enemyWizard)) { enemyWizard.takeDamage(10); spell.destroy(); spells.splice(i, 1); continue; } else if (spell instanceof EnemySpell && spell.intersects(playerWizard)) { playerWizard.takeDamage(10); spell.destroy(); spells.splice(i, 1); continue; } // Remove spells that are off screen (now checking X coordinates for horizontal movement) if (spell.x < -200 || spell.x > 2248) { spell.destroy(); spells.splice(i, 1); } } // Update health bars var playerHealthPercent = playerWizard.health / playerWizard.maxHealth; var enemyHealthPercent = enemyWizard.health / enemyWizard.maxHealth; playerHealthBar.scaleX = playerHealthPercent; enemyHealthBar.scaleX = enemyHealthPercent; // Check win/lose conditions if (playerWizard.health <= 0 && gameActive) { gameActive = false; LK.clearInterval(beatTimer); LK.setTimeout(function () { LK.showGameOver(); }, 1000); } else if (enemyWizard.health <= 0 && gameActive) { gameActive = false; LK.clearInterval(beatTimer); LK.setTimeout(function () { showLevelComplete(); }, 1000); } // Auto-deactivate buttons if timing window passed (adjusted for slower movement) var timeSinceBeat = (LK.ticks - lastBeatTime) * (1000 / 60); if (timeSinceBeat > beatInterval * 4.2) { // Increased timing window to match slower movement for (var i = 0; i < rhythmButtons.length; i++) { if (rhythmButtons[i].isActive) { rhythmButtons[i].deactivate(); } } } };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var EnemySpell = Container.expand(function () {
var self = Container.call(this);
var spellGraphics = self.attachAsset('spell', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 6;
self.rotationSpeed = -0.1;
self.update = function () {
// Move straight toward player wizard (to the left)
self.x -= self.speed;
// Add rotation (opposite direction)
spellGraphics.rotation += self.rotationSpeed;
// Remove spell if it goes off screen
if (self.x < -200 || self.y < -200 || self.y > 2900) {
self.destroy();
}
};
return self;
});
var PlayerSpell = Container.expand(function () {
var self = Container.call(this);
var spellGraphics = self.attachAsset('spell', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 6;
self.rotationSpeed = 0.1;
self.update = function () {
// Move straight toward enemy wizard (to the right)
self.x += self.speed;
// Add rotation
spellGraphics.rotation += self.rotationSpeed;
// Remove spell if it goes off screen
if (self.x > 2248 || self.y < -200 || self.y > 2900) {
self.destroy();
}
};
return self;
});
var RhythmButton = Container.expand(function (buttonType) {
var self = Container.call(this);
// Choose different note asset based on button type
var noteAsset = 'note';
if (buttonType === 'A' || buttonType === 'S') {
noteAsset = 'note2';
} else if (buttonType === 'D') {
noteAsset = 'note3';
}
var buttonGraphics = self.attachAsset(noteAsset, {
anchorX: 0.5,
anchorY: 0.5
});
self.buttonType = buttonType;
self.isActive = false;
self.originalScale = 1;
self.activate = function () {
self.isActive = true;
// Move button from right side to left side of screen
tween(self, {
x: -200 // Move to left side and exit screen
}, {
duration: beatInterval * 4 // Much slower movement - increased from 2.5 to 4
});
tween(buttonGraphics, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 100
});
tween(buttonGraphics, {
alpha: 1
}, {
duration: 100
});
};
self.deactivate = function () {
self.isActive = false;
// Reset button position back to right side
self.x = 2100;
tween(buttonGraphics, {
scaleX: 1,
scaleY: 1
}, {
duration: 200
});
tween(buttonGraphics, {
alpha: 0.6
}, {
duration: 200
});
};
self.hit = function () {
// Play different note sound based on button type
var noteSound = 'note' + self.buttonType;
LK.getSound(noteSound).play();
tween(buttonGraphics, {
scaleX: 0.8,
scaleY: 0.8
}, {
duration: 50,
onFinish: function onFinish() {
tween(buttonGraphics, {
scaleX: 1,
scaleY: 1
}, {
duration: 50
});
}
});
};
// Set initial alpha
buttonGraphics.alpha = 0.6;
self.down = function (x, y, obj) {
if (self.isActive) {
self.hit();
return true;
}
return false;
};
return self;
});
var Wizard = Container.expand(function (isPlayer) {
var self = Container.call(this);
var wizardAsset = isPlayer ? 'wizard' : 'enemyWizard';
var wizardGraphics = self.attachAsset(wizardAsset, {
anchorX: 0.5,
anchorY: 1
});
self.isPlayer = isPlayer;
self.maxHealth = 100;
self.health = self.maxHealth;
self.isDancing = false;
self.dance = function () {
if (self.isDancing) return;
self.isDancing = true;
var originalY = self.y;
tween(self, {
y: originalY - 30
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(self, {
y: originalY
}, {
duration: 200,
easing: tween.easeIn,
onFinish: function onFinish() {
self.isDancing = false;
}
});
}
});
tween(wizardGraphics, {
rotation: 0.2
}, {
duration: 100,
onFinish: function onFinish() {
tween(wizardGraphics, {
rotation: -0.2
}, {
duration: 200,
onFinish: function onFinish() {
tween(wizardGraphics, {
rotation: 0
}, {
duration: 100
});
}
});
}
});
};
self.castSpell = function () {
var spell;
if (self.isPlayer) {
spell = new PlayerSpell();
spell.x = self.x;
spell.y = self.y - 100; // Start from player position
} else {
spell = new EnemySpell();
spell.x = self.x;
spell.y = self.y - 400; // Start from enemy position
}
game.addChild(spell);
spells.push(spell);
LK.getSound('spellCast').play();
LK.effects.flashObject(self, 0xffd700, 300);
};
self.takeDamage = function (damage) {
self.health = Math.max(0, self.health - damage);
LK.getSound('wizardHit').play();
LK.effects.flashObject(self, 0xff0000, 500);
if (self.health <= 0) {
self.die();
}
};
self.die = function () {
tween(wizardGraphics, {
alpha: 0.3,
scaleX: 0.8,
scaleY: 0.8
}, {
duration: 1000
});
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2c3e50
});
/****
* Game Code
****/
// Game variables
var playerWizard;
var enemyWizard;
var rhythmButtons = [];
var spells = [];
var currentBeat = 0;
var beatInterval = 600; // milliseconds between beats
var lastBeatTime = 0;
var gameActive = true;
var playerHealth;
var enemyHealth;
var playerHealthBar;
var enemyHealthBar;
var score = 0;
var combo = 0;
var currentLevel = 1;
// Beat pattern for the song
var beatPattern = ['W', 'A', 'S', 'D', 'W', 'S', 'A', 'D'];
var patternIndex = 0;
// Create wizards
playerWizard = game.addChild(new Wizard(true));
playerWizard.x = 400;
playerWizard.y = 2200;
enemyWizard = game.addChild(new Wizard(false));
enemyWizard.x = 1648;
enemyWizard.y = 2200;
// Create health bars
var playerHealthBg = LK.getAsset('healthBarBg', {
anchorX: 0,
anchorY: 0.5
});
playerHealthBg.x = 50;
playerHealthBg.y = 150;
game.addChild(playerHealthBg);
playerHealthBar = LK.getAsset('healthBar', {
anchorX: 0,
anchorY: 0.5
});
playerHealthBar.x = 55;
playerHealthBar.y = 150;
game.addChild(playerHealthBar);
var enemyHealthBg = LK.getAsset('healthBarBg', {
anchorX: 1,
anchorY: 0.5
});
enemyHealthBg.x = 1998;
enemyHealthBg.y = 150;
game.addChild(enemyHealthBg);
enemyHealthBar = LK.getAsset('healthBar', {
anchorX: 1,
anchorY: 0.5
});
enemyHealthBar.x = 1993;
enemyHealthBar.y = 150;
game.addChild(enemyHealthBar);
// Create rhythm buttons positioned from the right between enemy wizard head and health bar
var buttonTypes = ['W', 'A', 'S', 'D'];
var buttonStartX = 2100; // Start from right side of screen
var buttonY = 400; // Between enemy wizard head and health bar
var buttonSpacing = 100; // Vertical spacing between buttons
for (var i = 0; i < buttonTypes.length; i++) {
var button = new RhythmButton(buttonTypes[i]);
button.x = buttonStartX;
button.y = buttonY + i * buttonSpacing; // Stack vertically, one under the other
rhythmButtons.push(button);
game.addChild(button);
}
;
// Show level completion screen
function showLevelComplete() {
// Create level complete text
var levelCompleteText = new Text2('Level ' + currentLevel + ' completed!', {
size: 120,
fill: 0xFFD700
});
levelCompleteText.anchor.set(0.5, 0.5);
levelCompleteText.x = 1024;
levelCompleteText.y = 1366;
game.addChild(levelCompleteText);
// Flash screen green for success
LK.effects.flashScreen(0x27ae60, 1000);
// Remove text and start next level after 2 seconds
LK.setTimeout(function () {
levelCompleteText.destroy();
currentLevel++;
startNextLevel();
}, 2000);
}
// Level progression function
function startNextLevel() {
// Increase difficulty
beatInterval = Math.max(300, beatInterval - 50); // Faster beats, minimum 300ms
// Reset wizards' health
playerWizard.health = playerWizard.maxHealth;
enemyWizard.health = enemyWizard.maxHealth;
// Clear existing spells
for (var i = spells.length - 1; i >= 0; i--) {
spells[i].destroy();
spells.splice(i, 1);
}
// Reset wizard graphics
var playerGraphics = playerWizard.children[0];
var enemyGraphics = enemyWizard.children[0];
playerGraphics.alpha = 1;
playerGraphics.scaleX = 1;
playerGraphics.scaleY = 1;
enemyGraphics.alpha = 1;
enemyGraphics.scaleX = 1;
enemyGraphics.scaleY = 1;
// Deactivate all buttons
for (var i = 0; i < rhythmButtons.length; i++) {
rhythmButtons[i].deactivate();
}
// Reset beat variables
currentBeat = 0;
patternIndex = 0;
lastBeatTime = LK.ticks;
// Clear existing beat timer
LK.clearInterval(beatTimer);
// Start new beat timer with faster interval
beatTimer = LK.setInterval(function () {
if (!gameActive) return;
currentBeat++;
var currentButton = beatPattern[patternIndex % beatPattern.length];
patternIndex++;
// Deactivate all buttons
for (var i = 0; i < rhythmButtons.length; i++) {
rhythmButtons[i].deactivate();
}
// Activate current button
for (var i = 0; i < rhythmButtons.length; i++) {
if (rhythmButtons[i].buttonType === currentButton) {
rhythmButtons[i].activate();
break;
}
}
// Enemy AI - increase difficulty by making enemy hit more often based on current level
var enemyHitChance = Math.min(0.9, 0.4 + (currentLevel - 1) * 0.1); // Increase by 10% each level, max 90%
if (Math.random() < enemyHitChance) {
LK.setTimeout(function () {
enemyWizard.dance();
enemyWizard.castSpell();
}, beatInterval * 0.3);
}
lastBeatTime = LK.ticks;
}, beatInterval);
// Re-enable game
gameActive = true;
// Flash screen to indicate level start
LK.effects.flashScreen(0xffd700, 500);
}
// Score display
var scoreText = new Text2('Score: 0', {
size: 80,
fill: 0xFFFFFF
});
scoreText.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreText);
// Combo display
var comboText = new Text2('Combo: 0', {
size: 60,
fill: 0xFFD700
});
comboText.anchor.set(0.5, 0);
comboText.y = 100;
LK.gui.top.addChild(comboText);
// Start music
LK.playMusic('battleMusic');
// Beat timer
var beatTimer = LK.setInterval(function () {
if (!gameActive) return;
currentBeat++;
var currentButton = beatPattern[patternIndex % beatPattern.length];
patternIndex++;
// Deactivate all buttons
for (var i = 0; i < rhythmButtons.length; i++) {
rhythmButtons[i].deactivate();
}
// Activate current button
for (var i = 0; i < rhythmButtons.length; i++) {
if (rhythmButtons[i].buttonType === currentButton) {
rhythmButtons[i].activate();
break;
}
}
// Enemy AI - sometimes hits the beat
if (Math.random() < 0.4) {
// 40% chance enemy hits (reduced from 70%)
LK.setTimeout(function () {
enemyWizard.dance();
enemyWizard.castSpell();
}, beatInterval * 0.3);
}
lastBeatTime = LK.ticks;
}, beatInterval);
// Handle button presses
var buttonPressed = false;
game.down = function (x, y, obj) {
if (!gameActive) return;
buttonPressed = false;
// Check if any active button was pressed
for (var i = 0; i < rhythmButtons.length; i++) {
if (rhythmButtons[i].isActive) {
var hit = rhythmButtons[i].down(x, y, obj);
if (hit) {
buttonPressed = true;
// Calculate timing accuracy
var timeSinceBeat = (LK.ticks - lastBeatTime) * (1000 / 60); // Convert to ms
var accuracy = 1 - Math.min(timeSinceBeat / (beatInterval * 0.5), 1);
if (accuracy > 0.3) {
// Good timing
playerWizard.dance();
playerWizard.castSpell();
var points = Math.floor(accuracy * 100);
score += points * (combo + 1);
combo++;
LK.setScore(score);
scoreText.setText('Score: ' + score);
comboText.setText('Combo: ' + combo);
} else {
combo = 0;
comboText.setText('Combo: 0');
}
break;
}
}
}
if (!buttonPressed) {
combo = 0;
comboText.setText('Combo: 0');
}
};
// Game update loop
game.update = function () {
if (!gameActive) return;
// Update spells
for (var i = spells.length - 1; i >= 0; i--) {
var spell = spells[i];
// Check spell collision with wizards
if (spell instanceof PlayerSpell && spell.intersects(enemyWizard)) {
enemyWizard.takeDamage(10);
spell.destroy();
spells.splice(i, 1);
continue;
} else if (spell instanceof EnemySpell && spell.intersects(playerWizard)) {
playerWizard.takeDamage(10);
spell.destroy();
spells.splice(i, 1);
continue;
}
// Remove spells that are off screen (now checking X coordinates for horizontal movement)
if (spell.x < -200 || spell.x > 2248) {
spell.destroy();
spells.splice(i, 1);
}
}
// Update health bars
var playerHealthPercent = playerWizard.health / playerWizard.maxHealth;
var enemyHealthPercent = enemyWizard.health / enemyWizard.maxHealth;
playerHealthBar.scaleX = playerHealthPercent;
enemyHealthBar.scaleX = enemyHealthPercent;
// Check win/lose conditions
if (playerWizard.health <= 0 && gameActive) {
gameActive = false;
LK.clearInterval(beatTimer);
LK.setTimeout(function () {
LK.showGameOver();
}, 1000);
} else if (enemyWizard.health <= 0 && gameActive) {
gameActive = false;
LK.clearInterval(beatTimer);
LK.setTimeout(function () {
showLevelComplete();
}, 1000);
}
// Auto-deactivate buttons if timing window passed (adjusted for slower movement)
var timeSinceBeat = (LK.ticks - lastBeatTime) * (1000 / 60);
if (timeSinceBeat > beatInterval * 4.2) {
// Increased timing window to match slower movement
for (var i = 0; i < rhythmButtons.length; i++) {
if (rhythmButtons[i].isActive) {
rhythmButtons[i].deactivate();
}
}
}
};
a wizard with a red dress, a hat, a long white beard and his whole body. In-Game asset. 2d. High contrast. No shadows
A wizard with a blue dress (like a coat) holding a stick touching the ground and a colored stone on the end of the stick, a wizard with a white beard and a hat on his head, and his whole body and right arm should not be visible from the frame (screen). In-Game asset. 2d. High contrast. No shadows
Musical note. In-Game asset. 2d. High contrast. No shadows
a prismatic rotating cube with notes inside. In-Game asset. 2d. High contrast. No shadows