/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var Broom = Container.expand(function () { var self = Container.call(this); var broomGraphics = self.attachAsset('broom', { anchorX: 0.5, anchorY: 0.8, // Anchor at bottom for sweeping feel rotation: Math.PI / 4 // 45-degree angle }); // Trail to make the broom more visible self.lastPositions = []; self.maxTrailLength = 5; // Sweeping animation self.isSweeping = false; self.sweepAngle = Math.PI / 4; self.sweepDirection = 1; self.sweepSpeed = 0.1; self.startSweeping = function () { self.isSweeping = true; }; self.stopSweeping = function () { self.isSweeping = false; // Reset broom rotation tween(broomGraphics, { rotation: Math.PI / 4 }, { duration: 300, easing: tween.easeOut }); }; self.update = function () { // Update trail if (self.lastPositions.length >= self.maxTrailLength) { self.lastPositions.shift(); } self.lastPositions.push({ x: self.x, y: self.y }); // Update sweeping animation if (self.isSweeping) { broomGraphics.rotation += self.sweepDirection * self.sweepSpeed; if (broomGraphics.rotation > Math.PI / 3 || broomGraphics.rotation < Math.PI / 6) { self.sweepDirection *= -1; } } }; return self; }); var Ghost = Container.expand(function () { var self = Container.call(this); var ghostGraphics = self.attachAsset('ghost', { anchorX: 0.5, anchorY: 0.5, alpha: 0.8 }); // Ghost properties self.speed = 3; self.targetX = 0; self.targetY = 0; self.setTarget = function (x, y) { self.targetX = x; self.targetY = y; }; // Movement behavior self.moveRandomly = function () { if (Math.random() < 0.02 || Math.abs(self.x - self.targetX) < 10 && Math.abs(self.y - self.targetY) < 10) { self.setTarget(Math.random() * 1948 + 50, // Keep away from edges Math.random() * 2532 + 100 // Keep away from top ); } }; // Update every frame self.update = function () { // Move toward target var dx = self.targetX - self.x; var dy = self.targetY - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > 0) { self.x += dx / dist * self.speed; self.y += dy / dist * self.speed; } // Bobbing animation self.y += Math.sin(LK.ticks / 20) * 0.5; // Fading in and out slightly ghostGraphics.alpha = 0.7 + Math.sin(LK.ticks / 30) * 0.3; }; // Flash and disappear when captured self.capture = function () { var captureEffect = LK.getAsset('captureEffect', { anchorX: 0.5, anchorY: 0.5, alpha: 0.7 }); self.addChild(captureEffect); // Capture animation tween(captureEffect, { alpha: 0, scaleX: 2, scaleY: 2 }, { duration: 500, easing: tween.easeOut, onFinish: function onFinish() { captureEffect.destroy(); } }); // Ghost disappearing animation tween(ghostGraphics, { alpha: 0, scaleX: 0.1, scaleY: 0.1 }, { duration: 500, easing: tween.easeIn }); // Play capture sound LK.getSound('ghostCapture').play(); return true; }; return self; }); var HUD = Container.expand(function () { var self = Container.call(this); // Score display self.scoreText = new Text2('0', { size: 120, fill: 0xFFFFFF }); self.scoreText.anchor.set(0.5, 0); // Level display self.levelText = new Text2('Level: 1', { size: 80, fill: 0xFFFFFF }); self.levelText.anchor.set(0, 0); // Lives display self.livesText = new Text2('Lives: 3', { size: 80, fill: 0xFFFFFF }); self.livesText.anchor.set(1, 0); // Update HUD self.updateScore = function (score) { self.scoreText.setText(score.toString()); }; self.updateLevel = function (level) { self.levelText.setText('Level: ' + level); }; self.updateLives = function (lives) { self.livesText.setText('Lives: ' + lives); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000000 }); /**** * Game Code ****/ // Game state variables var score = 0; var level = 1; var lives = 3; var ghostCaptureRadius = 100; // How close broom needs to be to ghost to capture it var ghostCount = 0; var maxGhosts = 5; // Starting max ghosts var ghostSpawnInterval = 3000; // ms between ghost spawns var lastGhostSpawnTime = 0; var isGameActive = true; // Set up background var houseBackground = LK.getAsset('house', { anchorX: 0, anchorY: 0 }); game.addChild(houseBackground); // Create player's broom var broom = new Broom(); game.addChild(broom); broom.x = 2048 / 2; broom.y = 2732 / 2; // Create ghosts array var ghosts = []; // Create HUD var hud = new HUD(); LK.gui.top.addChild(hud.scoreText); LK.gui.topLeft.addChild(hud.levelText); LK.gui.topRight.addChild(hud.livesText); // Position HUD elements hud.scoreText.x = 2048 / 2; hud.scoreText.y = 20; hud.levelText.x = 120; // Keep away from top-left menu icon hud.levelText.y = 20; hud.livesText.x = 2048 - 20; hud.livesText.y = 20; // Update HUD with initial values hud.updateScore(score); hud.updateLevel(level); hud.updateLives(lives); // Play background music LK.playMusic('hauntedMusic'); // Spawn a new ghost function spawnGhost() { if (ghosts.length >= maxGhosts || !isGameActive) return; var ghost = new Ghost(); // Decide spawn location (from edge of screen) var side = Math.floor(Math.random() * 4); switch (side) { case 0: // Top ghost.x = Math.random() * 2048; ghost.y = -100; break; case 1: // Right ghost.x = 2048 + 100; ghost.y = Math.random() * 2732; break; case 2: // Bottom ghost.x = Math.random() * 2048; ghost.y = 2732 + 100; break; case 3: // Left ghost.x = -100; ghost.y = Math.random() * 2732; break; } // Initial target is center of screen ghost.setTarget(Math.random() * 1948 + 50, Math.random() * 2532 + 100); // Speed increases with level ghost.speed = 3 + level * 0.5; ghosts.push(ghost); game.addChild(ghost); ghostCount++; // Play ghost appear sound LK.getSound('ghostAppear').play(); // Ghost fades in ghost.alpha = 0; tween(ghost, { alpha: 1 }, { duration: 500, easing: tween.easeIn }); } // Handle input for broom movement var isDragging = false; game.down = function (x, y) { isDragging = true; broom.x = x; broom.y = y; broom.startSweeping(); }; game.move = function (x, y) { if (isDragging) { broom.x = x; broom.y = y; } }; game.up = function () { isDragging = false; broom.stopSweeping(); }; // Check if player captured a ghost function checkGhostCapture() { for (var i = ghosts.length - 1; i >= 0; i--) { var ghost = ghosts[i]; var distance = Math.sqrt(Math.pow(ghost.x - broom.x, 2) + Math.pow(ghost.y - broom.y, 2)); if (distance < ghostCaptureRadius && isDragging) { // Capture the ghost if (ghost.capture()) { score += 10 * level; hud.updateScore(score); // Remove the ghost after capture animation LK.setTimeout(function () { game.removeChild(ghost); ghosts.splice(i, 1); ghostCount--; // Check for level completion if (ghostCount === 0 && isGameActive) { levelUp(); } }, 500); } } } } // Check if ghost hit the player function checkPlayerCollision() { if (!isDragging) return; // Only check collisions when player is active for (var i = 0; i < ghosts.length; i++) { var ghost = ghosts[i]; var distance = Math.sqrt(Math.pow(ghost.x - broom.x, 2) + Math.pow(ghost.y - broom.y, 2)); if (distance < 40 && !ghost.isBeingCaptured) { // Player hit by ghost LK.getSound('playerHit').play(); LK.effects.flashScreen(0xFF0000, 500); lives--; hud.updateLives(lives); // Check game over if (lives <= 0) { isGameActive = false; LK.setScore(score); LK.showGameOver(); } // Temporary invulnerability break; } } } // Level up function function levelUp() { level++; hud.updateLevel(level); // Increase difficulty maxGhosts = 5 + level; ghostSpawnInterval = Math.max(500, 3000 - level * 200); // Visual feedback for level up LK.effects.flashScreen(0x00FF00, 500); // Reset ghost counter ghostCount = 0; } // Main game update loop game.update = function () { // Update broom broom.update(); // Update all ghosts for (var i = 0; i < ghosts.length; i++) { var ghost = ghosts[i]; ghost.moveRandomly(); ghost.update(); } // Spawn ghosts on interval var currentTime = Date.now(); if (currentTime - lastGhostSpawnTime > ghostSpawnInterval && isGameActive) { spawnGhost(); lastGhostSpawnTime = currentTime; } // Check for ghost captures checkGhostCapture(); // Check for player collisions checkPlayerCollision(); }; // Initialize by spawning first ghost lastGhostSpawnTime = Date.now(); spawnGhost();
===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,362 @@
-/****
+/****
+* Plugins
+****/
+var tween = LK.import("@upit/tween.v1");
+var storage = LK.import("@upit/storage.v1");
+
+/****
+* Classes
+****/
+var Broom = Container.expand(function () {
+ var self = Container.call(this);
+ var broomGraphics = self.attachAsset('broom', {
+ anchorX: 0.5,
+ anchorY: 0.8,
+ // Anchor at bottom for sweeping feel
+ rotation: Math.PI / 4 // 45-degree angle
+ });
+ // Trail to make the broom more visible
+ self.lastPositions = [];
+ self.maxTrailLength = 5;
+ // Sweeping animation
+ self.isSweeping = false;
+ self.sweepAngle = Math.PI / 4;
+ self.sweepDirection = 1;
+ self.sweepSpeed = 0.1;
+ self.startSweeping = function () {
+ self.isSweeping = true;
+ };
+ self.stopSweeping = function () {
+ self.isSweeping = false;
+ // Reset broom rotation
+ tween(broomGraphics, {
+ rotation: Math.PI / 4
+ }, {
+ duration: 300,
+ easing: tween.easeOut
+ });
+ };
+ self.update = function () {
+ // Update trail
+ if (self.lastPositions.length >= self.maxTrailLength) {
+ self.lastPositions.shift();
+ }
+ self.lastPositions.push({
+ x: self.x,
+ y: self.y
+ });
+ // Update sweeping animation
+ if (self.isSweeping) {
+ broomGraphics.rotation += self.sweepDirection * self.sweepSpeed;
+ if (broomGraphics.rotation > Math.PI / 3 || broomGraphics.rotation < Math.PI / 6) {
+ self.sweepDirection *= -1;
+ }
+ }
+ };
+ return self;
+});
+var Ghost = Container.expand(function () {
+ var self = Container.call(this);
+ var ghostGraphics = self.attachAsset('ghost', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ alpha: 0.8
+ });
+ // Ghost properties
+ self.speed = 3;
+ self.targetX = 0;
+ self.targetY = 0;
+ self.setTarget = function (x, y) {
+ self.targetX = x;
+ self.targetY = y;
+ };
+ // Movement behavior
+ self.moveRandomly = function () {
+ if (Math.random() < 0.02 || Math.abs(self.x - self.targetX) < 10 && Math.abs(self.y - self.targetY) < 10) {
+ self.setTarget(Math.random() * 1948 + 50,
+ // Keep away from edges
+ Math.random() * 2532 + 100 // Keep away from top
+ );
+ }
+ };
+ // Update every frame
+ self.update = function () {
+ // Move toward target
+ var dx = self.targetX - self.x;
+ var dy = self.targetY - self.y;
+ var dist = Math.sqrt(dx * dx + dy * dy);
+ if (dist > 0) {
+ self.x += dx / dist * self.speed;
+ self.y += dy / dist * self.speed;
+ }
+ // Bobbing animation
+ self.y += Math.sin(LK.ticks / 20) * 0.5;
+ // Fading in and out slightly
+ ghostGraphics.alpha = 0.7 + Math.sin(LK.ticks / 30) * 0.3;
+ };
+ // Flash and disappear when captured
+ self.capture = function () {
+ var captureEffect = LK.getAsset('captureEffect', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ alpha: 0.7
+ });
+ self.addChild(captureEffect);
+ // Capture animation
+ tween(captureEffect, {
+ alpha: 0,
+ scaleX: 2,
+ scaleY: 2
+ }, {
+ duration: 500,
+ easing: tween.easeOut,
+ onFinish: function onFinish() {
+ captureEffect.destroy();
+ }
+ });
+ // Ghost disappearing animation
+ tween(ghostGraphics, {
+ alpha: 0,
+ scaleX: 0.1,
+ scaleY: 0.1
+ }, {
+ duration: 500,
+ easing: tween.easeIn
+ });
+ // Play capture sound
+ LK.getSound('ghostCapture').play();
+ return true;
+ };
+ return self;
+});
+var HUD = Container.expand(function () {
+ var self = Container.call(this);
+ // Score display
+ self.scoreText = new Text2('0', {
+ size: 120,
+ fill: 0xFFFFFF
+ });
+ self.scoreText.anchor.set(0.5, 0);
+ // Level display
+ self.levelText = new Text2('Level: 1', {
+ size: 80,
+ fill: 0xFFFFFF
+ });
+ self.levelText.anchor.set(0, 0);
+ // Lives display
+ self.livesText = new Text2('Lives: 3', {
+ size: 80,
+ fill: 0xFFFFFF
+ });
+ self.livesText.anchor.set(1, 0);
+ // Update HUD
+ self.updateScore = function (score) {
+ self.scoreText.setText(score.toString());
+ };
+ self.updateLevel = function (level) {
+ self.levelText.setText('Level: ' + level);
+ };
+ self.updateLives = function (lives) {
+ self.livesText.setText('Lives: ' + lives);
+ };
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
var game = new LK.Game({
backgroundColor: 0x000000
-});
\ No newline at end of file
+});
+
+/****
+* Game Code
+****/
+// Game state variables
+var score = 0;
+var level = 1;
+var lives = 3;
+var ghostCaptureRadius = 100; // How close broom needs to be to ghost to capture it
+var ghostCount = 0;
+var maxGhosts = 5; // Starting max ghosts
+var ghostSpawnInterval = 3000; // ms between ghost spawns
+var lastGhostSpawnTime = 0;
+var isGameActive = true;
+// Set up background
+var houseBackground = LK.getAsset('house', {
+ anchorX: 0,
+ anchorY: 0
+});
+game.addChild(houseBackground);
+// Create player's broom
+var broom = new Broom();
+game.addChild(broom);
+broom.x = 2048 / 2;
+broom.y = 2732 / 2;
+// Create ghosts array
+var ghosts = [];
+// Create HUD
+var hud = new HUD();
+LK.gui.top.addChild(hud.scoreText);
+LK.gui.topLeft.addChild(hud.levelText);
+LK.gui.topRight.addChild(hud.livesText);
+// Position HUD elements
+hud.scoreText.x = 2048 / 2;
+hud.scoreText.y = 20;
+hud.levelText.x = 120; // Keep away from top-left menu icon
+hud.levelText.y = 20;
+hud.livesText.x = 2048 - 20;
+hud.livesText.y = 20;
+// Update HUD with initial values
+hud.updateScore(score);
+hud.updateLevel(level);
+hud.updateLives(lives);
+// Play background music
+LK.playMusic('hauntedMusic');
+// Spawn a new ghost
+function spawnGhost() {
+ if (ghosts.length >= maxGhosts || !isGameActive) return;
+ var ghost = new Ghost();
+ // Decide spawn location (from edge of screen)
+ var side = Math.floor(Math.random() * 4);
+ switch (side) {
+ case 0:
+ // Top
+ ghost.x = Math.random() * 2048;
+ ghost.y = -100;
+ break;
+ case 1:
+ // Right
+ ghost.x = 2048 + 100;
+ ghost.y = Math.random() * 2732;
+ break;
+ case 2:
+ // Bottom
+ ghost.x = Math.random() * 2048;
+ ghost.y = 2732 + 100;
+ break;
+ case 3:
+ // Left
+ ghost.x = -100;
+ ghost.y = Math.random() * 2732;
+ break;
+ }
+ // Initial target is center of screen
+ ghost.setTarget(Math.random() * 1948 + 50, Math.random() * 2532 + 100);
+ // Speed increases with level
+ ghost.speed = 3 + level * 0.5;
+ ghosts.push(ghost);
+ game.addChild(ghost);
+ ghostCount++;
+ // Play ghost appear sound
+ LK.getSound('ghostAppear').play();
+ // Ghost fades in
+ ghost.alpha = 0;
+ tween(ghost, {
+ alpha: 1
+ }, {
+ duration: 500,
+ easing: tween.easeIn
+ });
+}
+// Handle input for broom movement
+var isDragging = false;
+game.down = function (x, y) {
+ isDragging = true;
+ broom.x = x;
+ broom.y = y;
+ broom.startSweeping();
+};
+game.move = function (x, y) {
+ if (isDragging) {
+ broom.x = x;
+ broom.y = y;
+ }
+};
+game.up = function () {
+ isDragging = false;
+ broom.stopSweeping();
+};
+// Check if player captured a ghost
+function checkGhostCapture() {
+ for (var i = ghosts.length - 1; i >= 0; i--) {
+ var ghost = ghosts[i];
+ var distance = Math.sqrt(Math.pow(ghost.x - broom.x, 2) + Math.pow(ghost.y - broom.y, 2));
+ if (distance < ghostCaptureRadius && isDragging) {
+ // Capture the ghost
+ if (ghost.capture()) {
+ score += 10 * level;
+ hud.updateScore(score);
+ // Remove the ghost after capture animation
+ LK.setTimeout(function () {
+ game.removeChild(ghost);
+ ghosts.splice(i, 1);
+ ghostCount--;
+ // Check for level completion
+ if (ghostCount === 0 && isGameActive) {
+ levelUp();
+ }
+ }, 500);
+ }
+ }
+ }
+}
+// Check if ghost hit the player
+function checkPlayerCollision() {
+ if (!isDragging) return; // Only check collisions when player is active
+ for (var i = 0; i < ghosts.length; i++) {
+ var ghost = ghosts[i];
+ var distance = Math.sqrt(Math.pow(ghost.x - broom.x, 2) + Math.pow(ghost.y - broom.y, 2));
+ if (distance < 40 && !ghost.isBeingCaptured) {
+ // Player hit by ghost
+ LK.getSound('playerHit').play();
+ LK.effects.flashScreen(0xFF0000, 500);
+ lives--;
+ hud.updateLives(lives);
+ // Check game over
+ if (lives <= 0) {
+ isGameActive = false;
+ LK.setScore(score);
+ LK.showGameOver();
+ }
+ // Temporary invulnerability
+ break;
+ }
+ }
+}
+// Level up function
+function levelUp() {
+ level++;
+ hud.updateLevel(level);
+ // Increase difficulty
+ maxGhosts = 5 + level;
+ ghostSpawnInterval = Math.max(500, 3000 - level * 200);
+ // Visual feedback for level up
+ LK.effects.flashScreen(0x00FF00, 500);
+ // Reset ghost counter
+ ghostCount = 0;
+}
+// Main game update loop
+game.update = function () {
+ // Update broom
+ broom.update();
+ // Update all ghosts
+ for (var i = 0; i < ghosts.length; i++) {
+ var ghost = ghosts[i];
+ ghost.moveRandomly();
+ ghost.update();
+ }
+ // Spawn ghosts on interval
+ var currentTime = Date.now();
+ if (currentTime - lastGhostSpawnTime > ghostSpawnInterval && isGameActive) {
+ spawnGhost();
+ lastGhostSpawnTime = currentTime;
+ }
+ // Check for ghost captures
+ checkGhostCapture();
+ // Check for player collisions
+ checkPlayerCollision();
+};
+// Initialize by spawning first ghost
+lastGhostSpawnTime = Date.now();
+spawnGhost();
\ No newline at end of file