/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { highScore: 0, coins: 0 }); /**** * Classes ****/ var Coin = Container.expand(function () { var self = Container.call(this); self.lane = Math.floor(Math.random() * 3); self.speed = 0; self.collected = false; var coinGraphics = self.attachAsset('coin', { anchorX: 0.5, anchorY: 0.5 }); self.update = function () { self.y += self.speed; // Spinning animation coinGraphics.scaleX = Math.abs(Math.sin(LK.ticks * 0.05)) * 0.5 + 0.5; }; self.collect = function () { if (self.collected) { return; } self.collected = true; LK.getSound('collect').play(); // Animate collection tween(self, { alpha: 0, scaleX: 1.5, scaleY: 1.5 }, { duration: 300, easing: tween.easeOut }); }; self.getCollisionBox = function () { var box = { x: self.x - coinGraphics.width * 0.5 * 0.8, y: self.y - coinGraphics.height * 0.5 * 0.8, width: coinGraphics.width * 0.8, height: coinGraphics.height * 0.8 }; return box; }; return self; }); var Obstacle = Container.expand(function (type) { var self = Container.call(this); self.type = type || 'regular'; // regular, low, high self.lane = Math.floor(Math.random() * 3); self.speed = 0; var obstacleGraphics = self.attachAsset('obstacle', { anchorX: 0.5, anchorY: 0.5 }); // Adjust obstacle appearance based on type if (self.type === 'low') { obstacleGraphics.scaleY = 0.5; obstacleGraphics.y = obstacleGraphics.height * 0.25; } else if (self.type === 'high') { obstacleGraphics.scaleY = 0.5; obstacleGraphics.y = -obstacleGraphics.height * 0.25; } self.update = function () { self.y += self.speed; }; self.getCollisionBox = function () { var box = { x: self.x - obstacleGraphics.width * 0.5 * 0.9, y: self.y - obstacleGraphics.height * 0.5 * 0.9 + (self.type === 'low' ? obstacleGraphics.height * 0.25 : self.type === 'high' ? -obstacleGraphics.height * 0.25 : 0), width: obstacleGraphics.width * 0.9, height: obstacleGraphics.height * 0.9 * (self.type === 'low' || self.type === 'high' ? 0.5 : 1) }; return box; }; return self; }); var Player = Container.expand(function () { var self = Container.call(this); // Player states self.isJumping = false; self.isSliding = false; self.lane = 1; // 0: left, 1: center, 2: right self.speed = 10; self.jumpHeight = 200; self.jumpDuration = 500; self.slideDuration = 600; self.powerupActive = false; self.powerupType = null; self.powerupDuration = 0; // Player graphics var playerGraphics = self.attachAsset('player', { anchorX: 0.5, anchorY: 0.5 }); // Methods for player actions self.switchLane = function (targetLane) { if (targetLane < 0 || targetLane > 2 || self.lane === targetLane) { return; } var targetX = LANE_POSITIONS[targetLane]; tween.stop(self, { x: true }); tween(self, { x: targetX }, { duration: 200, easing: tween.easeOut }); self.lane = targetLane; }; self.jump = function () { if (self.isJumping || self.isSliding) { return; } self.isJumping = true; LK.getSound('jump').play(); var initialY = self.y; // Jump up tween(self, { y: initialY - self.jumpHeight }, { duration: self.jumpDuration / 2, easing: tween.easeOut, onFinish: function onFinish() { // Fall down tween(self, { y: initialY }, { duration: self.jumpDuration / 2, easing: tween.easeIn, onFinish: function onFinish() { self.isJumping = false; } }); } }); }; self.slide = function () { if (self.isJumping || self.isSliding) { return; } self.isSliding = true; LK.getSound('slide').play(); // Shrink player height for sliding tween(playerGraphics, { scaleY: 0.5 }, { duration: 200, easing: tween.linear }); // Return to normal after slide duration LK.setTimeout(function () { tween(playerGraphics, { scaleY: 1 }, { duration: 200, easing: tween.linear, onFinish: function onFinish() { self.isSliding = false; } }); }, self.slideDuration); }; self.activatePowerup = function (type) { self.powerupActive = true; self.powerupType = type; switch (type) { case 'magnet': self.powerupDuration = 5000; break; case 'multiplier': self.powerupDuration = 8000; break; case 'invincibility': self.powerupDuration = 4000; playerGraphics.alpha = 0.7; break; } LK.getSound('powerup').play(); }; self.updatePowerup = function () { if (!self.powerupActive) { return; } self.powerupDuration -= 16.67; // Approximate ms per frame at 60fps if (self.powerupDuration <= 0) { self.powerupActive = false; self.powerupType = null; playerGraphics.alpha = 1; } }; // Collision detection utility self.getCollisionBox = function () { var box = { x: self.x - playerGraphics.width * 0.5 * 0.8, y: self.y - playerGraphics.height * 0.5 * (self.isSliding ? 0.5 : 0.9), width: playerGraphics.width * 0.8, height: playerGraphics.height * (self.isSliding ? 0.5 : 0.9) }; return box; }; return self; }); var Powerup = Container.expand(function () { var self = Container.call(this); self.lane = Math.floor(Math.random() * 3); self.speed = 0; self.collected = false; // Random powerup type var types = ['magnet', 'multiplier', 'invincibility']; self.type = types[Math.floor(Math.random() * types.length)]; var powerupGraphics = self.attachAsset('powerup', { anchorX: 0.5, anchorY: 0.5 }); // Different colors for different powerups if (self.type === 'magnet') { powerupGraphics.tint = 0x0088ff; } else if (self.type === 'multiplier') { powerupGraphics.tint = 0xff8800; } else if (self.type === 'invincibility') { powerupGraphics.tint = 0xff00ff; } self.update = function () { self.y += self.speed; // Pulsing animation var pulse = Math.sin(LK.ticks * 0.1) * 0.1 + 1; powerupGraphics.scale.set(pulse, pulse); }; self.collect = function () { if (self.collected) { return; } self.collected = true; LK.getSound('powerup').play(); // Animate collection tween(self, { alpha: 0, scaleX: 2, scaleY: 2 }, { duration: 300, easing: tween.easeOut }); }; self.getCollisionBox = function () { var box = { x: self.x - powerupGraphics.width * 0.5 * 0.8, y: self.y - powerupGraphics.height * 0.5 * 0.8, width: powerupGraphics.width * 0.8, height: powerupGraphics.height * 0.8 }; return box; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x202020 }); /**** * Game Code ****/ // Game constants var GAME_WIDTH = 2048; var GAME_HEIGHT = 2732; var PLAYER_START_Y = GAME_HEIGHT - 400; var LANE_WIDTH = 200; var LANE_POSITIONS = [GAME_WIDTH / 2 - LANE_WIDTH, GAME_WIDTH / 2, GAME_WIDTH / 2 + LANE_WIDTH]; var SPAWN_Y = -200; var DESPAWN_Y = GAME_HEIGHT + 200; // Game variables var gameStarted = false; var gameSpeed = 10; var score = 0; var distance = 0; var coins = 0; var multiplier = 1; var lastObstacleSpawn = 0; var lastCoinSpawn = 0; var lastPowerupSpawn = 0; var obstacleSpawnRate = 1500; // ms var coinSpawnRate = 1000; // ms var powerupSpawnRate = 10000; // ms var playerSwipeStartY = 0; var playerSwipeStartX = 0; var MIN_SWIPE_DISTANCE = 50; // Game elements var player; var obstacles = []; var coinsArray = []; var powerups = []; var swipeDirection = null; // Create lanes and background var background = LK.getAsset('ground', { anchorX: 0, anchorY: 0 }); game.addChild(background); for (var i = 0; i < 3; i++) { var lane = LK.getAsset('lane', { anchorX: 0.5, anchorY: 0, alpha: 0.3 }); lane.x = LANE_POSITIONS[i]; lane.y = 0; game.addChild(lane); } // Create UI elements var scoreText = new Text2('SCORE: 0', { size: 80, fill: 0xFFFFFF }); scoreText.anchor.set(0.5, 0); scoreText.x = GAME_WIDTH / 2; scoreText.y = 50; LK.gui.top.addChild(scoreText); var coinText = new Text2('COINS: 0', { size: 80, fill: 0xFFD700 }); coinText.anchor.set(0, 0); coinText.x = 150; coinText.y = 50; LK.gui.top.addChild(coinText); var highScoreText = new Text2('HIGH SCORE: ' + storage.highScore, { size: 60, fill: 0xFFAA00 }); highScoreText.anchor.set(1, 0); highScoreText.x = GAME_WIDTH - 150; highScoreText.y = 50; LK.gui.top.addChild(highScoreText); var powerupText = new Text2('', { size: 70, fill: 0x83DE44 }); powerupText.anchor.set(0.5, 0); powerupText.x = GAME_WIDTH / 2; powerupText.y = 150; powerupText.alpha = 0; LK.gui.top.addChild(powerupText); var tapToStartText = new Text2('TAP TO START', { size: 120, fill: 0xFFFFFF }); tapToStartText.anchor.set(0.5, 0.5); tapToStartText.x = GAME_WIDTH / 2; tapToStartText.y = GAME_HEIGHT / 2; LK.gui.center.addChild(tapToStartText); // Initialize player function initPlayer() { player = new Player(); player.x = LANE_POSITIONS[1]; // Start in center lane player.y = PLAYER_START_Y; game.addChild(player); } // Spawn obstacle function spawnObstacle() { var now = Date.now(); if (now - lastObstacleSpawn < obstacleSpawnRate) { return; } lastObstacleSpawn = now; // Determine obstacle type var types = ['regular', 'low', 'high']; var type = types[Math.floor(Math.random() * types.length)]; var obstacle = new Obstacle(type); obstacle.x = LANE_POSITIONS[obstacle.lane]; obstacle.y = SPAWN_Y; obstacle.speed = gameSpeed; obstacles.push(obstacle); game.addChild(obstacle); // Gradually increase spawn rate obstacleSpawnRate = Math.max(800, obstacleSpawnRate - 5); } // Spawn coin function spawnCoin() { var now = Date.now(); if (now - lastCoinSpawn < coinSpawnRate) { return; } lastCoinSpawn = now; // Spawn 1-3 coins in a row or pattern var coinCount = Math.floor(Math.random() * 3) + 1; var lane = Math.floor(Math.random() * 3); for (var i = 0; i < coinCount; i++) { var coin = new Coin(); // Determine pattern type var patternType = Math.floor(Math.random() * 3); if (patternType === 0) { // Straight line in same lane coin.lane = lane; } else if (patternType === 1) { // Diagonal pattern coin.lane = (lane + i) % 3; } else { // Random lanes coin.lane = Math.floor(Math.random() * 3); } coin.x = LANE_POSITIONS[coin.lane]; coin.y = SPAWN_Y - i * 120; // Spaced out vertically coin.speed = gameSpeed; coinsArray.push(coin); game.addChild(coin); } } // Spawn powerup function spawnPowerup() { var now = Date.now(); if (now - lastPowerupSpawn < powerupSpawnRate) { return; } lastPowerupSpawn = now; var powerup = new Powerup(); powerup.x = LANE_POSITIONS[powerup.lane]; powerup.y = SPAWN_Y; powerup.speed = gameSpeed; powerups.push(powerup); game.addChild(powerup); } // Check collision between two objects using their collision boxes function checkCollision(obj1, obj2) { var box1 = obj1.getCollisionBox(); var box2 = obj2.getCollisionBox(); return box1.x < box2.x + box2.width && box1.x + box1.width > box2.x && box1.y < box2.y + box2.height && box1.y + box1.height > box2.y; } // Handle collisions function handleCollisions() { if (!player) { return; } // Check obstacle collisions for (var i = obstacles.length - 1; i >= 0; i--) { var obstacle = obstacles[i]; if (checkCollision(player, obstacle)) { if (player.powerupActive && player.powerupType === 'invincibility') { // Destroy obstacle if player is invincible obstacle.destroy(); obstacles.splice(i, 1); // Add points for destroying obstacle addScore(50); } else { // Game over on collision LK.getSound('crash').play(); LK.effects.flashScreen(0xff0000, 500); // Update high score if (score > storage.highScore) { storage.highScore = score; highScoreText.setText('HIGH SCORE: ' + storage.highScore); } // Update total coins storage.coins += coins; LK.showGameOver(); return; } } } // Check coin collisions for (var j = coinsArray.length - 1; j >= 0; j--) { var coin = coinsArray[j]; // For magnet powerup, attract nearby coins if (player.powerupActive && player.powerupType === 'magnet') { var dx = player.x - coin.x; var dy = player.y - coin.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < 400) { // Move coin towards player var speed = 0.1; coin.x += dx * speed; coin.y += dy * speed; } } if (checkCollision(player, coin)) { coin.collect(); coinsArray.splice(j, 1); // Add coin and points coins++; coinText.setText('COINS: ' + coins); addScore(10); } } // Check powerup collisions for (var k = powerups.length - 1; k >= 0; k--) { var powerup = powerups[k]; if (checkCollision(player, powerup)) { powerup.collect(); player.activatePowerup(powerup.type); powerups.splice(k, 1); // Show powerup text var powerupName = powerup.type.charAt(0).toUpperCase() + powerup.type.slice(1); powerupText.setText(powerupName + ' ACTIVATED!'); powerupText.alpha = 1; // Fade out powerup text tween(powerupText, { alpha: 0 }, { duration: 2000, easing: tween.linear }); // Set multiplier if applicable if (powerup.type === 'multiplier') { multiplier = 2; } } } } // Add to score function addScore(points) { score += points * multiplier; scoreText.setText('SCORE: ' + score); } // Handle touch/mouse events game.down = function (x, y, obj) { if (!gameStarted) { startGame(); return; } playerSwipeStartX = x; playerSwipeStartY = y; swipeDirection = null; }; game.move = function (x, y, obj) { if (!gameStarted || !player) { return; } // Make player follow mouse/touch position horizontally // Find the closest lane based on x position var closestLane = 0; var closestDist = Math.abs(x - LANE_POSITIONS[0]); for (var i = 1; i < LANE_POSITIONS.length; i++) { var dist = Math.abs(x - LANE_POSITIONS[i]); if (dist < closestDist) { closestDist = dist; closestLane = i; } } // Only change lane if needed if (player.lane !== closestLane) { player.switchLane(closestLane); } }; game.up = function (x, y, obj) { // Reset swipe state swipeDirection = null; }; // Start the game function startGame() { if (gameStarted) { return; } gameStarted = true; // Hide start text tween(tapToStartText, { alpha: 0 }, { duration: 500, easing: tween.easeOut }); // Initialize game variables score = 0; distance = 0; coins = 0; multiplier = 1; gameSpeed = 10; // Update UI scoreText.setText('SCORE: 0'); coinText.setText('COINS: 0'); highScoreText.setText('HIGH SCORE: ' + storage.highScore); // Initialize player initPlayer(); // Play music LK.playMusic('gameMusic'); } // Game update function game.update = function () { if (!gameStarted) { return; } // Increase distance and score distance += gameSpeed; if (LK.ticks % 10 === 0) { addScore(1); } // Gradually increase game speed if (LK.ticks % 300 === 0) { gameSpeed += 0.2; } // Spawn game elements spawnObstacle(); spawnCoin(); spawnPowerup(); // Update powerup status if (player) { player.updatePowerup(); // Reset multiplier when powerup ends if (!player.powerupActive && player.powerupType === 'multiplier') { multiplier = 1; } } // Update and clean up obstacles for (var i = obstacles.length - 1; i >= 0; i--) { var obstacle = obstacles[i]; if (obstacle.y > DESPAWN_Y) { obstacle.destroy(); obstacles.splice(i, 1); } } // Update and clean up coins for (var j = coinsArray.length - 1; j >= 0; j--) { var coin = coinsArray[j]; if (coin.y > DESPAWN_Y || coin.collected) { coin.destroy(); coinsArray.splice(j, 1); } } // Update and clean up powerups for (var k = powerups.length - 1; k >= 0; k--) { var powerup = powerups[k]; if (powerup.y > DESPAWN_Y || powerup.collected) { powerup.destroy(); powerups.splice(k, 1); } } // Check for collisions handleCollisions(); };
===================================================================
--- original.js
+++ change.js
@@ -537,32 +537,23 @@
game.move = function (x, y, obj) {
if (!gameStarted || !player) {
return;
}
- // Calculate swipe distance
- var dx = x - playerSwipeStartX;
- var dy = y - playerSwipeStartY;
- var absDx = Math.abs(dx);
- var absDy = Math.abs(dy);
- // Only register swipe if it's long enough and we haven't already processed this swipe
- if (swipeDirection === null && (absDx > MIN_SWIPE_DISTANCE || absDy > MIN_SWIPE_DISTANCE)) {
- if (absDx > absDy) {
- // Horizontal swipe (lane change)
- swipeDirection = dx > 0 ? 'right' : 'left';
- var newLane = player.lane + (dx > 0 ? 1 : -1);
- if (newLane >= 0 && newLane <= 2) {
- player.switchLane(newLane);
- }
- } else {
- // Vertical swipe (jump or slide)
- swipeDirection = dy > 0 ? 'down' : 'up';
- if (dy < 0) {
- player.jump();
- } else {
- player.slide();
- }
+ // Make player follow mouse/touch position horizontally
+ // Find the closest lane based on x position
+ var closestLane = 0;
+ var closestDist = Math.abs(x - LANE_POSITIONS[0]);
+ for (var i = 1; i < LANE_POSITIONS.length; i++) {
+ var dist = Math.abs(x - LANE_POSITIONS[i]);
+ if (dist < closestDist) {
+ closestDist = dist;
+ closestLane = i;
}
}
+ // Only change lane if needed
+ if (player.lane !== closestLane) {
+ player.switchLane(closestLane);
+ }
};
game.up = function (x, y, obj) {
// Reset swipe state
swipeDirection = null;