/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { highScore: 0 }); /**** * Classes ****/ var GameObject = Container.expand(function () { var self = Container.call(this); self.speed = 0; self.active = true; return self; }); var PowerUp = GameObject.expand(function () { var self = GameObject.call(this); var powerup = self.attachAsset('powerup', { anchorX: 0.5, anchorY: 0.5 }); self.type = "speedBoost"; // Default type self.update = function () { GameObject.prototype.update.call(this); // Add a pulsing effect to make it more noticeable var scale = 1 + Math.sin(LK.ticks * 0.1) * 0.1; powerup.scale.set(scale, scale); }; self.checkCollision = function (player) { if (!self.active) return false; return player.intersects(self); }; return self; }); var Police = GameObject.expand(function () { var self = GameObject.call(this); var police = self.attachAsset('police', { anchorX: 0.5, anchorY: 0.5 }); self.targetLane = 1; // Middle lane by default self.movementSpeed = 0.1; self.xPositions = [624, 1024, 1424]; // Lane positions self.update = function () { GameObject.prototype.update.call(this); // Gradually move towards target lane var targetX = self.xPositions[self.targetLane]; self.x += (targetX - self.x) * self.movementSpeed; // Change lane randomly if far from player if (self.y < 500 && Math.random() < 0.01) { self.targetLane = Math.floor(Math.random() * 3); } }; self.checkCollision = function (player) { if (!self.active) return false; return player.intersects(self); }; return self; }); var Obstacle = GameObject.expand(function () { var self = GameObject.call(this); var obstacle = self.attachAsset('obstacle', { anchorX: 0.5, anchorY: 0.5 }); self.checkCollision = function (player) { if (!self.active) return false; return player.intersects(self); }; return self; }); var Collectible = GameObject.expand(function () { var self = GameObject.call(this); var collectible = self.attachAsset('collectible', { anchorX: 0.5, anchorY: 0.5 }); self.value = 10; self.update = function () { GameObject.prototype.update.call(this); // Add a slight rotation to make it more eye-catching collectible.rotation += 0.03; }; self.checkCollision = function (player) { if (!self.active) return false; return player.intersects(self); }; return self; }); var Player = Container.expand(function () { var self = Container.call(this); var thief = self.attachAsset('thief', { anchorX: 0.5, anchorY: 0.5 }); self.lane = 1; // Start in middle lane (0, 1, 2) self.xPositions = [624, 1024, 1424]; // Lane positions self.isJumping = false; self.hasPowerUp = false; self.powerUpType = ""; self.powerUpTimeLeft = 0; self.moveTo = function (lane) { if (lane < 0) lane = 0; if (lane > 2) lane = 2; self.lane = lane; tween(self, { x: self.xPositions[lane] }, { duration: 200, easing: tween.easeOut }); }; self.jump = function () { if (self.isJumping) return; self.isJumping = true; LK.getSound('jump').play(); // Jump animation with tweens tween(self, { y: self.y - 150 }, { duration: 400, easing: tween.easeOut, onFinish: function onFinish() { tween(self, { y: self.y + 150 }, { duration: 400, easing: tween.easeIn, onFinish: function onFinish() { self.isJumping = false; } }); } }); }; self.activatePowerUp = function (type) { self.hasPowerUp = true; self.powerUpType = type; self.powerUpTimeLeft = 300; // 5 seconds (60fps) // Visual feedback tween(thief, { tint: 0x00FFFF }, { duration: 300 }); }; self.updatePowerUp = function () { if (!self.hasPowerUp) return; self.powerUpTimeLeft--; if (self.powerUpTimeLeft <= 0) { self.hasPowerUp = false; self.powerUpType = ""; tween(thief, { tint: 0xFFFFFF }, { duration: 300 }); } }; return self; }); var RoadLine = Container.expand(function () { var self = Container.call(this); var line = self.attachAsset('roadLine', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 10; self.update = function () { self.y += self.speed; if (self.y > 2732 + line.height / 2) { self.y = -line.height / 2; } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x222222 }); /**** * Game Code ****/ // Game variables // Character assets // Environment assets // Game effect sounds // Game background music GameObject.prototype.update = function () { this.y += gameSpeed; if (this.y > 2732 + 100) { this.active = false; } }; var gameSpeed = 10; var score = 0; var distance = 0; var difficulty = 1; var gameRunning = false; var roadLines = []; var obstacles = []; var collectibles = []; var powerups = []; var policeOfficers = []; var spawnTimer = 0; var roadWidth = 1200; // Initialize player var player = new Player(); player.x = 1024; // Middle of screen player.y = 2200; // Near bottom of screen // Create road var road = LK.getAsset('road', { anchorX: 0.5, anchorY: 0.5, x: 1024, // Center of screen y: 1366 // Center of screen }); game.addChild(road); // Create road lines for (var i = 0; i < 20; i++) { var roadLine = new RoadLine(); roadLine.x = 1024; // Center of screen roadLine.y = i * 150 - 150; // Spaced evenly roadLines.push(roadLine); game.addChild(roadLine); } // Add player to game game.addChild(player); // Setup GUI var scoreTxt = new Text2('Score: 0', { size: 70, fill: 0xFFFFFF }); scoreTxt.anchor.set(0, 0); // Top left LK.gui.topRight.addChild(scoreTxt); // Add high score display var highScoreTxt = new Text2('High Score: 0', { size: 70, fill: 0xFFD700 // Gold color }); highScoreTxt.anchor.set(0, 0); // Top left highScoreTxt.y = 80; // Position below score LK.gui.topRight.addChild(highScoreTxt); // Setup control for player movement var touchStartX = 0; var swipeThreshold = 100; // Play background music LK.playMusic('gameMusic'); // Start the game startGame(); function startGame() { // Reset variables gameSpeed = 10; score = 0; distance = 0; difficulty = 1; gameRunning = true; // Reset player player.lane = 1; player.x = 1024; player.moveTo(1); // Clear existing game objects clearGameObjects(); // Update score display updateScoreDisplay(); } function updateScoreDisplay() { scoreTxt.setText('Score: ' + score); highScoreTxt.setText('High Score: ' + storage.highScore); } function clearGameObjects() { // Remove all obstacles, collectibles, etc. for (var i = obstacles.length - 1; i >= 0; i--) { obstacles[i].destroy(); } obstacles = []; for (var i = collectibles.length - 1; i >= 0; i--) { collectibles[i].destroy(); } collectibles = []; for (var i = powerups.length - 1; i >= 0; i--) { powerups[i].destroy(); } powerups = []; for (var i = policeOfficers.length - 1; i >= 0; i--) { policeOfficers[i].destroy(); } policeOfficers = []; } function spawnObstacle() { var obstacle = new Obstacle(); var lane = Math.floor(Math.random() * 3); obstacle.x = player.xPositions[lane]; obstacle.y = -100; // Off-screen obstacles.push(obstacle); game.addChild(obstacle); } function spawnCollectible() { var collectible = new Collectible(); var lane = Math.floor(Math.random() * 3); collectible.x = player.xPositions[lane]; collectible.y = -100; // Off-screen collectibles.push(collectible); game.addChild(collectible); } function spawnPowerUp() { var powerup = new PowerUp(); var lane = Math.floor(Math.random() * 3); powerup.x = player.xPositions[lane]; powerup.y = -100; // Off-screen // Random power-up type var types = ["speedBoost", "invincibility", "magneticPull"]; powerup.type = types[Math.floor(Math.random() * types.length)]; powerups.push(powerup); game.addChild(powerup); } function spawnPolice() { var police = new Police(); // Police starts at random lane var lane = Math.floor(Math.random() * 3); police.x = player.xPositions[lane]; police.y = -100; // Off-screen // Higher difficulty makes police faster and more accurate police.movementSpeed = 0.1 + difficulty * 0.02; policeOfficers.push(police); game.addChild(police); } function checkCollisions() { // Check obstacle collisions for (var i = obstacles.length - 1; i >= 0; i--) { if (obstacles[i].checkCollision(player) && !player.isJumping) { if (!player.hasPowerUp || player.powerUpType !== "invincibility") { gameOver(); LK.getSound('crash').play(); return; } } if (!obstacles[i].active) { obstacles[i].destroy(); obstacles.splice(i, 1); } } // Check police collisions for (var i = policeOfficers.length - 1; i >= 0; i--) { if (policeOfficers[i].checkCollision(player) && !player.isJumping) { if (!player.hasPowerUp || player.powerUpType !== "invincibility") { gameOver(); LK.getSound('crash').play(); return; } } if (!policeOfficers[i].active) { policeOfficers[i].destroy(); policeOfficers.splice(i, 1); } } // Check collectible collisions for (var i = collectibles.length - 1; i >= 0; i--) { if (collectibles[i].checkCollision(player)) { // Collect the item score += collectibles[i].value; updateScoreDisplay(); LK.getSound('coin').play(); collectibles[i].destroy(); collectibles.splice(i, 1); } else if (!collectibles[i].active) { collectibles[i].destroy(); collectibles.splice(i, 1); } } // Check power-up collisions for (var i = powerups.length - 1; i >= 0; i--) { if (powerups[i].checkCollision(player)) { // Activate the power-up player.activatePowerUp(powerups[i].type); LK.getSound('powerup').play(); powerups[i].destroy(); powerups.splice(i, 1); } else if (!powerups[i].active) { powerups[i].destroy(); powerups.splice(i, 1); } } } function gameOver() { gameRunning = false; // Check if this is a high score if (score > storage.highScore) { storage.highScore = score; } // Show the game over screen LK.showGameOver(); } // Touch input handlers game.down = function (x, y) { touchStartX = x; }; game.move = function (x, y) { // Only handle horizontal swipes while the game is running if (!gameRunning) return; // Check for swipe var swipeDist = x - touchStartX; if (Math.abs(swipeDist) >= swipeThreshold) { if (swipeDist > 0) { // Swipe right player.moveTo(player.lane + 1); } else { // Swipe left player.moveTo(player.lane - 1); } // Reset touch start to prevent multiple swipes touchStartX = x; } }; game.up = function (x, y) { // Check if it was a tap (not a swipe) if (Math.abs(x - touchStartX) < swipeThreshold) { // Tap to jump player.jump(); } }; // Game update logic game.update = function () { if (!gameRunning) return; // Update road lines for (var i = 0; i < roadLines.length; i++) { roadLines[i].update(); } // Update player player.updatePowerUp(); // Update all game objects for (var i = 0; i < obstacles.length; i++) { obstacles[i].update(); } for (var i = 0; i < collectibles.length; i++) { collectibles[i].update(); } for (var i = 0; i < powerups.length; i++) { powerups[i].update(); } for (var i = 0; i < policeOfficers.length; i++) { policeOfficers[i].update(); // Make police follow player's lane more aggressively as difficulty increases if (Math.random() < 0.02 * difficulty) { policeOfficers[i].targetLane = player.lane; } } // Spawn game elements spawnTimer++; if (spawnTimer % 60 === 0) { // Spawn obstacles more frequently as difficulty increases if (Math.random() < 0.3 + difficulty * 0.1) { spawnObstacle(); } // Spawn collectibles if (Math.random() < 0.4) { spawnCollectible(); } // Spawn power-ups rarely if (Math.random() < 0.05) { spawnPowerUp(); } // Spawn police based on difficulty if (Math.random() < 0.2 + difficulty * 0.1) { spawnPolice(); } } // Increase distance and score distance += gameSpeed; if (distance % 1000 === 0) { score += 5; updateScoreDisplay(); } // Increase difficulty over time if (distance % 5000 === 0) { difficulty += 0.2; gameSpeed += 0.5; } // Check for collisions checkCollisions(); // Apply power-up effects if (player.hasPowerUp) { if (player.powerUpType === "speedBoost") { // Temporary speed boost distance += gameSpeed; } else if (player.powerUpType === "magneticPull") { // Pull collectibles towards player for (var i = 0; i < collectibles.length; i++) { var dx = player.x - collectibles[i].x; var dy = player.y - collectibles[i].y; collectibles[i].x += dx * 0.05; collectibles[i].y += dy * 0.05; } } } };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
highScore: 0
});
/****
* Classes
****/
var GameObject = Container.expand(function () {
var self = Container.call(this);
self.speed = 0;
self.active = true;
return self;
});
var PowerUp = GameObject.expand(function () {
var self = GameObject.call(this);
var powerup = self.attachAsset('powerup', {
anchorX: 0.5,
anchorY: 0.5
});
self.type = "speedBoost"; // Default type
self.update = function () {
GameObject.prototype.update.call(this);
// Add a pulsing effect to make it more noticeable
var scale = 1 + Math.sin(LK.ticks * 0.1) * 0.1;
powerup.scale.set(scale, scale);
};
self.checkCollision = function (player) {
if (!self.active) return false;
return player.intersects(self);
};
return self;
});
var Police = GameObject.expand(function () {
var self = GameObject.call(this);
var police = self.attachAsset('police', {
anchorX: 0.5,
anchorY: 0.5
});
self.targetLane = 1; // Middle lane by default
self.movementSpeed = 0.1;
self.xPositions = [624, 1024, 1424]; // Lane positions
self.update = function () {
GameObject.prototype.update.call(this);
// Gradually move towards target lane
var targetX = self.xPositions[self.targetLane];
self.x += (targetX - self.x) * self.movementSpeed;
// Change lane randomly if far from player
if (self.y < 500 && Math.random() < 0.01) {
self.targetLane = Math.floor(Math.random() * 3);
}
};
self.checkCollision = function (player) {
if (!self.active) return false;
return player.intersects(self);
};
return self;
});
var Obstacle = GameObject.expand(function () {
var self = GameObject.call(this);
var obstacle = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 0.5
});
self.checkCollision = function (player) {
if (!self.active) return false;
return player.intersects(self);
};
return self;
});
var Collectible = GameObject.expand(function () {
var self = GameObject.call(this);
var collectible = self.attachAsset('collectible', {
anchorX: 0.5,
anchorY: 0.5
});
self.value = 10;
self.update = function () {
GameObject.prototype.update.call(this);
// Add a slight rotation to make it more eye-catching
collectible.rotation += 0.03;
};
self.checkCollision = function (player) {
if (!self.active) return false;
return player.intersects(self);
};
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
var thief = self.attachAsset('thief', {
anchorX: 0.5,
anchorY: 0.5
});
self.lane = 1; // Start in middle lane (0, 1, 2)
self.xPositions = [624, 1024, 1424]; // Lane positions
self.isJumping = false;
self.hasPowerUp = false;
self.powerUpType = "";
self.powerUpTimeLeft = 0;
self.moveTo = function (lane) {
if (lane < 0) lane = 0;
if (lane > 2) lane = 2;
self.lane = lane;
tween(self, {
x: self.xPositions[lane]
}, {
duration: 200,
easing: tween.easeOut
});
};
self.jump = function () {
if (self.isJumping) return;
self.isJumping = true;
LK.getSound('jump').play();
// Jump animation with tweens
tween(self, {
y: self.y - 150
}, {
duration: 400,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(self, {
y: self.y + 150
}, {
duration: 400,
easing: tween.easeIn,
onFinish: function onFinish() {
self.isJumping = false;
}
});
}
});
};
self.activatePowerUp = function (type) {
self.hasPowerUp = true;
self.powerUpType = type;
self.powerUpTimeLeft = 300; // 5 seconds (60fps)
// Visual feedback
tween(thief, {
tint: 0x00FFFF
}, {
duration: 300
});
};
self.updatePowerUp = function () {
if (!self.hasPowerUp) return;
self.powerUpTimeLeft--;
if (self.powerUpTimeLeft <= 0) {
self.hasPowerUp = false;
self.powerUpType = "";
tween(thief, {
tint: 0xFFFFFF
}, {
duration: 300
});
}
};
return self;
});
var RoadLine = Container.expand(function () {
var self = Container.call(this);
var line = self.attachAsset('roadLine', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 10;
self.update = function () {
self.y += self.speed;
if (self.y > 2732 + line.height / 2) {
self.y = -line.height / 2;
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x222222
});
/****
* Game Code
****/
// Game variables
// Character assets
// Environment assets
// Game effect sounds
// Game background music
GameObject.prototype.update = function () {
this.y += gameSpeed;
if (this.y > 2732 + 100) {
this.active = false;
}
};
var gameSpeed = 10;
var score = 0;
var distance = 0;
var difficulty = 1;
var gameRunning = false;
var roadLines = [];
var obstacles = [];
var collectibles = [];
var powerups = [];
var policeOfficers = [];
var spawnTimer = 0;
var roadWidth = 1200;
// Initialize player
var player = new Player();
player.x = 1024; // Middle of screen
player.y = 2200; // Near bottom of screen
// Create road
var road = LK.getAsset('road', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
// Center of screen
y: 1366 // Center of screen
});
game.addChild(road);
// Create road lines
for (var i = 0; i < 20; i++) {
var roadLine = new RoadLine();
roadLine.x = 1024; // Center of screen
roadLine.y = i * 150 - 150; // Spaced evenly
roadLines.push(roadLine);
game.addChild(roadLine);
}
// Add player to game
game.addChild(player);
// Setup GUI
var scoreTxt = new Text2('Score: 0', {
size: 70,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0, 0); // Top left
LK.gui.topRight.addChild(scoreTxt);
// Add high score display
var highScoreTxt = new Text2('High Score: 0', {
size: 70,
fill: 0xFFD700 // Gold color
});
highScoreTxt.anchor.set(0, 0); // Top left
highScoreTxt.y = 80; // Position below score
LK.gui.topRight.addChild(highScoreTxt);
// Setup control for player movement
var touchStartX = 0;
var swipeThreshold = 100;
// Play background music
LK.playMusic('gameMusic');
// Start the game
startGame();
function startGame() {
// Reset variables
gameSpeed = 10;
score = 0;
distance = 0;
difficulty = 1;
gameRunning = true;
// Reset player
player.lane = 1;
player.x = 1024;
player.moveTo(1);
// Clear existing game objects
clearGameObjects();
// Update score display
updateScoreDisplay();
}
function updateScoreDisplay() {
scoreTxt.setText('Score: ' + score);
highScoreTxt.setText('High Score: ' + storage.highScore);
}
function clearGameObjects() {
// Remove all obstacles, collectibles, etc.
for (var i = obstacles.length - 1; i >= 0; i--) {
obstacles[i].destroy();
}
obstacles = [];
for (var i = collectibles.length - 1; i >= 0; i--) {
collectibles[i].destroy();
}
collectibles = [];
for (var i = powerups.length - 1; i >= 0; i--) {
powerups[i].destroy();
}
powerups = [];
for (var i = policeOfficers.length - 1; i >= 0; i--) {
policeOfficers[i].destroy();
}
policeOfficers = [];
}
function spawnObstacle() {
var obstacle = new Obstacle();
var lane = Math.floor(Math.random() * 3);
obstacle.x = player.xPositions[lane];
obstacle.y = -100; // Off-screen
obstacles.push(obstacle);
game.addChild(obstacle);
}
function spawnCollectible() {
var collectible = new Collectible();
var lane = Math.floor(Math.random() * 3);
collectible.x = player.xPositions[lane];
collectible.y = -100; // Off-screen
collectibles.push(collectible);
game.addChild(collectible);
}
function spawnPowerUp() {
var powerup = new PowerUp();
var lane = Math.floor(Math.random() * 3);
powerup.x = player.xPositions[lane];
powerup.y = -100; // Off-screen
// Random power-up type
var types = ["speedBoost", "invincibility", "magneticPull"];
powerup.type = types[Math.floor(Math.random() * types.length)];
powerups.push(powerup);
game.addChild(powerup);
}
function spawnPolice() {
var police = new Police();
// Police starts at random lane
var lane = Math.floor(Math.random() * 3);
police.x = player.xPositions[lane];
police.y = -100; // Off-screen
// Higher difficulty makes police faster and more accurate
police.movementSpeed = 0.1 + difficulty * 0.02;
policeOfficers.push(police);
game.addChild(police);
}
function checkCollisions() {
// Check obstacle collisions
for (var i = obstacles.length - 1; i >= 0; i--) {
if (obstacles[i].checkCollision(player) && !player.isJumping) {
if (!player.hasPowerUp || player.powerUpType !== "invincibility") {
gameOver();
LK.getSound('crash').play();
return;
}
}
if (!obstacles[i].active) {
obstacles[i].destroy();
obstacles.splice(i, 1);
}
}
// Check police collisions
for (var i = policeOfficers.length - 1; i >= 0; i--) {
if (policeOfficers[i].checkCollision(player) && !player.isJumping) {
if (!player.hasPowerUp || player.powerUpType !== "invincibility") {
gameOver();
LK.getSound('crash').play();
return;
}
}
if (!policeOfficers[i].active) {
policeOfficers[i].destroy();
policeOfficers.splice(i, 1);
}
}
// Check collectible collisions
for (var i = collectibles.length - 1; i >= 0; i--) {
if (collectibles[i].checkCollision(player)) {
// Collect the item
score += collectibles[i].value;
updateScoreDisplay();
LK.getSound('coin').play();
collectibles[i].destroy();
collectibles.splice(i, 1);
} else if (!collectibles[i].active) {
collectibles[i].destroy();
collectibles.splice(i, 1);
}
}
// Check power-up collisions
for (var i = powerups.length - 1; i >= 0; i--) {
if (powerups[i].checkCollision(player)) {
// Activate the power-up
player.activatePowerUp(powerups[i].type);
LK.getSound('powerup').play();
powerups[i].destroy();
powerups.splice(i, 1);
} else if (!powerups[i].active) {
powerups[i].destroy();
powerups.splice(i, 1);
}
}
}
function gameOver() {
gameRunning = false;
// Check if this is a high score
if (score > storage.highScore) {
storage.highScore = score;
}
// Show the game over screen
LK.showGameOver();
}
// Touch input handlers
game.down = function (x, y) {
touchStartX = x;
};
game.move = function (x, y) {
// Only handle horizontal swipes while the game is running
if (!gameRunning) return;
// Check for swipe
var swipeDist = x - touchStartX;
if (Math.abs(swipeDist) >= swipeThreshold) {
if (swipeDist > 0) {
// Swipe right
player.moveTo(player.lane + 1);
} else {
// Swipe left
player.moveTo(player.lane - 1);
}
// Reset touch start to prevent multiple swipes
touchStartX = x;
}
};
game.up = function (x, y) {
// Check if it was a tap (not a swipe)
if (Math.abs(x - touchStartX) < swipeThreshold) {
// Tap to jump
player.jump();
}
};
// Game update logic
game.update = function () {
if (!gameRunning) return;
// Update road lines
for (var i = 0; i < roadLines.length; i++) {
roadLines[i].update();
}
// Update player
player.updatePowerUp();
// Update all game objects
for (var i = 0; i < obstacles.length; i++) {
obstacles[i].update();
}
for (var i = 0; i < collectibles.length; i++) {
collectibles[i].update();
}
for (var i = 0; i < powerups.length; i++) {
powerups[i].update();
}
for (var i = 0; i < policeOfficers.length; i++) {
policeOfficers[i].update();
// Make police follow player's lane more aggressively as difficulty increases
if (Math.random() < 0.02 * difficulty) {
policeOfficers[i].targetLane = player.lane;
}
}
// Spawn game elements
spawnTimer++;
if (spawnTimer % 60 === 0) {
// Spawn obstacles more frequently as difficulty increases
if (Math.random() < 0.3 + difficulty * 0.1) {
spawnObstacle();
}
// Spawn collectibles
if (Math.random() < 0.4) {
spawnCollectible();
}
// Spawn power-ups rarely
if (Math.random() < 0.05) {
spawnPowerUp();
}
// Spawn police based on difficulty
if (Math.random() < 0.2 + difficulty * 0.1) {
spawnPolice();
}
}
// Increase distance and score
distance += gameSpeed;
if (distance % 1000 === 0) {
score += 5;
updateScoreDisplay();
}
// Increase difficulty over time
if (distance % 5000 === 0) {
difficulty += 0.2;
gameSpeed += 0.5;
}
// Check for collisions
checkCollisions();
// Apply power-up effects
if (player.hasPowerUp) {
if (player.powerUpType === "speedBoost") {
// Temporary speed boost
distance += gameSpeed;
} else if (player.powerUpType === "magneticPull") {
// Pull collectibles towards player
for (var i = 0; i < collectibles.length; i++) {
var dx = player.x - collectibles[i].x;
var dy = player.y - collectibles[i].y;
collectibles[i].x += dx * 0.05;
collectibles[i].y += dy * 0.05;
}
}
}
};