/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
// Cat player class
var Cat = Container.expand(function () {
var self = Container.call(this);
var catSprite = self.attachAsset('cat', {
anchorX: 0.5,
anchorY: 0.5
});
self.lane = 1; // Start in center lane
self.y = 2200; // Near bottom of screen
self.x = laneX[self.lane];
self.width = catSprite.width;
self.height = catSprite.height;
self.magnetActive = false;
self.speedBoostActive = false;
self.doubleActive = false;
self.powerupTimer = 0;
self.moveToLane = function (targetLane) {
if (targetLane < 0 || targetLane > 2) return;
self.lane = targetLane;
// Animate to new lane
tween(self, {
x: laneX[self.lane]
}, {
duration: 120,
easing: tween.cubicOut
});
};
self.activatePowerup = function (type, duration) {
if (type === 'magnet') {
self.magnetActive = true;
} else if (type === 'speed') {
self.speedBoostActive = true;
} else if (type === 'double') {
self.doubleActive = true;
}
self.powerupTimer = LK.ticks + Math.floor(duration * 60 / 1000); // duration in ms
};
self.update = function () {
// Powerup timer
if (self.powerupTimer && LK.ticks > self.powerupTimer) {
self.magnetActive = false;
self.speedBoostActive = false;
self.doubleActive = false;
self.powerupTimer = 0;
}
};
return self;
});
// Fish collectible
var Fish = Container.expand(function () {
var self = Container.call(this);
var fishSprite = self.attachAsset('fish', {
anchorX: 0.5,
anchorY: 0.5
});
self.lane = 1;
self.x = laneX[self.lane];
self.y = -100;
self.width = fishSprite.width;
self.height = fishSprite.height;
self.collected = false;
self.update = function () {
// Movement handled in game.update
};
return self;
});
// Obstacle base class
var Obstacle = Container.expand(function () {
var self = Container.call(this);
self.lane = 1;
self.x = laneX[self.lane];
self.y = -200;
self.width = 100;
self.height = 100;
self.type = 'obstacle';
self.update = function () {};
return self;
});
// Trashcan obstacle
var Trashcan = Obstacle.expand(function () {
var self = Obstacle.call(this);
var trashSprite = self.attachAsset('trashcan', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = trashSprite.width;
self.height = trashSprite.height;
self.type = 'trashcan';
return self;
});
// Puddle obstacle
var Puddle = Obstacle.expand(function () {
var self = Obstacle.call(this);
var puddleSprite = self.attachAsset('puddle', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = puddleSprite.width;
self.height = puddleSprite.height;
self.type = 'puddle';
return self;
});
// Dog obstacle
var Dog = Obstacle.expand(function () {
var self = Obstacle.call(this);
var dogSprite = self.attachAsset('dog', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = dogSprite.width;
self.height = dogSprite.height;
self.type = 'dog';
return self;
});
// Powerup base class
var Powerup = Container.expand(function () {
var self = Container.call(this);
self.lane = 1;
self.x = laneX[self.lane];
self.y = -100;
self.width = 80;
self.height = 80;
self.kind = '';
self.update = function () {};
return self;
});
// Speed boost powerup
var Speed = Powerup.expand(function () {
var self = Powerup.call(this);
var spdSprite = self.attachAsset('speed', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = spdSprite.width;
self.height = spdSprite.height;
self.kind = 'speed';
return self;
});
// Magnet powerup
var Magnet = Powerup.expand(function () {
var self = Powerup.call(this);
var magSprite = self.attachAsset('magnet', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = magSprite.width;
self.height = magSprite.height;
self.kind = 'magnet';
return self;
});
// Double points powerup
var Double = Powerup.expand(function () {
var self = Powerup.call(this);
var dblSprite = self.attachAsset('double', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = dblSprite.width;
self.height = dblSprite.height;
self.kind = 'double';
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87ceeb // Light blue sky
});
/****
* Game Code
****/
// Game state variables
// Cat character (main player)
// Fish collectible
// Trash can obstacle
// Water puddle obstacle
// Dog obstacle
// Magnet powerup
// Speed boost powerup
// Double points powerup
// Lane positions (3 lanes: left, center, right)
var laneX = [512, 1024, 1536];
var cat;
var obstacles = [];
var fishes = [];
var powerups = [];
var score = 0;
var speed = 18; // Initial speed (pixels per frame)
var gameTick = 0;
var lastSwipeX = null;
var dragStartX = null;
var dragStartY = null;
var dragActive = false;
var swipeThreshold = 80; // Minimum px for swipe
var lastLane = 1;
var lastScore = 0;
var powerupDuration = 4000; // ms
var spawnTimer = 0;
var powerupSpawnTimer = 0;
var fishSpawnTimer = 0;
var gameOver = false;
// Score text
var scoreTxt = new Text2('0', {
size: 120,
fill: "#fff"
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Powerup indicator
var powerupTxt = new Text2('', {
size: 70,
fill: "#fff"
});
powerupTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(powerupTxt);
powerupTxt.y = 130;
// Daily reward (placeholder, not implemented in MVP)
var dailyRewardTxt = new Text2('', {
size: 60,
fill: "#fff"
});
dailyRewardTxt.anchor.set(0.5, 0);
LK.gui.bottom.addChild(dailyRewardTxt);
dailyRewardTxt.visible = false;
// Initialize cat
cat = new Cat();
cat.x = laneX[1];
cat.y = 2200;
game.addChild(cat);
// Helper: spawn obstacle
function spawnObstacle() {
var lane = Math.floor(Math.random() * 3);
var typeRand = Math.random();
var obs;
if (typeRand < 0.5) {
obs = new Trashcan();
} else if (typeRand < 0.8) {
obs = new Puddle();
} else {
obs = new Dog();
}
obs.lane = lane;
obs.x = laneX[lane];
obs.y = -200;
obstacles.push(obs);
game.addChild(obs);
}
// Helper: spawn fish
function spawnFish() {
var lane = Math.floor(Math.random() * 3);
var fish = new Fish();
fish.lane = lane;
fish.x = laneX[lane];
fish.y = -100;
fishes.push(fish);
game.addChild(fish);
}
// Helper: spawn powerup
function spawnPowerup() {
var lane = Math.floor(Math.random() * 3);
var kindRand = Math.random();
var pwr;
if (kindRand < 0.34) {
pwr = new Magnet();
} else if (kindRand < 0.67) {
pwr = new Speed();
} else {
pwr = new Double();
}
pwr.lane = lane;
pwr.x = laneX[lane];
pwr.y = -100;
powerups.push(pwr);
game.addChild(pwr);
}
// Helper: reset game state
function resetGame() {
// Remove all obstacles, fishes, powerups
for (var i = 0; i < obstacles.length; i++) obstacles[i].destroy();
for (var i = 0; i < fishes.length; i++) fishes[i].destroy();
for (var i = 0; i < powerups.length; i++) powerups[i].destroy();
obstacles = [];
fishes = [];
powerups = [];
score = 0;
speed = 18;
gameTick = 0;
cat.lane = 1;
cat.x = laneX[1];
cat.y = 2200;
cat.magnetActive = false;
cat.speedBoostActive = false;
cat.doubleActive = false;
cat.powerupTimer = 0;
scoreTxt.setText('0');
powerupTxt.setText('');
gameOver = false;
}
// Touch/move/swipe controls
game.down = function (x, y, obj) {
dragStartX = x;
dragStartY = y;
dragActive = true;
lastSwipeX = x;
};
game.move = function (x, y, obj) {
if (!dragActive) return;
var dx = x - dragStartX;
if (Math.abs(dx) > swipeThreshold) {
if (dx > 0 && cat.lane < 2) {
cat.moveToLane(cat.lane + 1);
dragActive = false;
} else if (dx < 0 && cat.lane > 0) {
cat.moveToLane(cat.lane - 1);
dragActive = false;
}
}
};
game.up = function (x, y, obj) {
dragActive = false;
};
// Main game update loop
// Random meow timer
var meowTimer = 0;
game.update = function () {
if (gameOver) return;
gameTick++;
// Increase speed over time
if (gameTick % 180 === 0 && speed < 40) {
speed += 1;
}
// If speed boost active
var moveSpeed = cat.speedBoostActive ? speed * 1.7 : speed;
// Spawn obstacles
spawnTimer--;
if (spawnTimer <= 0) {
spawnObstacle();
spawnTimer = 60 + Math.floor(Math.random() * 40); // 1-1.5s
}
// Spawn fish
fishSpawnTimer--;
if (fishSpawnTimer <= 0) {
spawnFish();
fishSpawnTimer = 40 + Math.floor(Math.random() * 40); // 0.7-1.3s
}
// Spawn powerup
powerupSpawnTimer--;
if (powerupSpawnTimer <= 0) {
spawnPowerup();
powerupSpawnTimer = 400 + Math.floor(Math.random() * 200); // 7-10s
}
// Update cat
cat.update();
// Move obstacles
for (var i = obstacles.length - 1; i >= 0; i--) {
var obs = obstacles[i];
obs.y += moveSpeed;
// Remove if off screen
if (obs.y > 2900) {
obs.destroy();
obstacles.splice(i, 1);
continue;
}
// Collision with cat
if (obs.lane === cat.lane && Math.abs(obs.y - cat.y) < (obs.height + cat.height) / 2 - 20) {
// Play trash impact sound if trashcan, otherwise cat meow
if (obs.type === 'trashcan') {
LK.getSound('TrashImpactSound').play();
} else {
LK.getSound('cat').play();
}
// Game over
LK.effects.flashScreen(0xff0000, 800);
gameOver = true;
LK.showGameOver();
return;
}
}
// Move fishes
for (var i = fishes.length - 1; i >= 0; i--) {
var fish = fishes[i];
fish.y += moveSpeed;
// Magnet effect
if (cat.magnetActive && Math.abs(fish.y - cat.y) < 500 && Math.abs(fish.x - cat.x) < 400) {
// Move fish toward cat
var dx = cat.x - fish.x;
var dy = cat.y - fish.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist > 1) {
fish.x += dx / dist * 22;
fish.y += dy / dist * 22;
}
}
// Remove if off screen
if (fish.y > 2900) {
fish.destroy();
fishes.splice(i, 1);
continue;
}
// Collect fish
if (!fish.collected && fish.lane === cat.lane && Math.abs(fish.y - cat.y) < (fish.height + cat.height) / 2 - 20) {
fish.collected = true;
var points = cat.doubleActive ? 2 : 1;
score += points;
LK.setScore(score);
scoreTxt.setText(score + '');
// Play cat meow sound only when cat eats 5 fish
if (typeof fishEatCount === "undefined") {
fishEatCount = 0;
}
fishEatCount += 1;
if (fishEatCount % 5 === 0) {
LK.getSound('cat').play();
}
// Animate fish
tween(fish, {
alpha: 0,
y: cat.y - 80
}, {
duration: 200,
onFinish: function onFinish() {
fish.destroy();
}
});
fishes.splice(i, 1);
continue;
}
}
// Move powerups
for (var i = powerups.length - 1; i >= 0; i--) {
var pwr = powerups[i];
pwr.y += moveSpeed;
// Remove if off screen
if (pwr.y > 2900) {
pwr.destroy();
powerups.splice(i, 1);
continue;
}
// Collect powerup
if (pwr.lane === cat.lane && Math.abs(pwr.y - cat.y) < (pwr.height + cat.height) / 2 - 20) {
// Activate powerup
cat.activatePowerup(pwr.kind, powerupDuration);
// Play speed sound only when picking up speed powerup
if (pwr.kind === 'speed') {
LK.getSound('speed').play();
}
// Show indicator
if (pwr.kind === 'magnet') {
powerupTxt.setText('Magnet!');
} else if (pwr.kind === 'speed') {
powerupTxt.setText('Speed!');
} else if (pwr.kind === 'double') {
powerupTxt.setText('Double Points!');
}
// Animate
tween(pwr, {
alpha: 0,
y: cat.y - 80
}, {
duration: 200,
onFinish: function onFinish() {
pwr.destroy();
}
});
powerups.splice(i, 1);
continue;
}
}
// Powerup indicator clear
if (!cat.magnetActive && !cat.speedBoostActive && !cat.doubleActive) {
powerupTxt.setText('');
}
};
// Reset game state on game over
LK.on('gameover', function () {
resetGame();
});
// Reset game state on you win (not used in endless runner, but for completeness)
LK.on('youwin', function () {
resetGame();
}); /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
// Cat player class
var Cat = Container.expand(function () {
var self = Container.call(this);
var catSprite = self.attachAsset('cat', {
anchorX: 0.5,
anchorY: 0.5
});
self.lane = 1; // Start in center lane
self.y = 2200; // Near bottom of screen
self.x = laneX[self.lane];
self.width = catSprite.width;
self.height = catSprite.height;
self.magnetActive = false;
self.speedBoostActive = false;
self.doubleActive = false;
self.powerupTimer = 0;
self.moveToLane = function (targetLane) {
if (targetLane < 0 || targetLane > 2) return;
self.lane = targetLane;
// Animate to new lane
tween(self, {
x: laneX[self.lane]
}, {
duration: 120,
easing: tween.cubicOut
});
};
self.activatePowerup = function (type, duration) {
if (type === 'magnet') {
self.magnetActive = true;
} else if (type === 'speed') {
self.speedBoostActive = true;
} else if (type === 'double') {
self.doubleActive = true;
}
self.powerupTimer = LK.ticks + Math.floor(duration * 60 / 1000); // duration in ms
};
self.update = function () {
// Powerup timer
if (self.powerupTimer && LK.ticks > self.powerupTimer) {
self.magnetActive = false;
self.speedBoostActive = false;
self.doubleActive = false;
self.powerupTimer = 0;
}
};
return self;
});
// Fish collectible
var Fish = Container.expand(function () {
var self = Container.call(this);
var fishSprite = self.attachAsset('fish', {
anchorX: 0.5,
anchorY: 0.5
});
self.lane = 1;
self.x = laneX[self.lane];
self.y = -100;
self.width = fishSprite.width;
self.height = fishSprite.height;
self.collected = false;
self.update = function () {
// Movement handled in game.update
};
return self;
});
// Obstacle base class
var Obstacle = Container.expand(function () {
var self = Container.call(this);
self.lane = 1;
self.x = laneX[self.lane];
self.y = -200;
self.width = 100;
self.height = 100;
self.type = 'obstacle';
self.update = function () {};
return self;
});
// Trashcan obstacle
var Trashcan = Obstacle.expand(function () {
var self = Obstacle.call(this);
var trashSprite = self.attachAsset('trashcan', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = trashSprite.width;
self.height = trashSprite.height;
self.type = 'trashcan';
return self;
});
// Puddle obstacle
var Puddle = Obstacle.expand(function () {
var self = Obstacle.call(this);
var puddleSprite = self.attachAsset('puddle', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = puddleSprite.width;
self.height = puddleSprite.height;
self.type = 'puddle';
return self;
});
// Dog obstacle
var Dog = Obstacle.expand(function () {
var self = Obstacle.call(this);
var dogSprite = self.attachAsset('dog', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = dogSprite.width;
self.height = dogSprite.height;
self.type = 'dog';
return self;
});
// Powerup base class
var Powerup = Container.expand(function () {
var self = Container.call(this);
self.lane = 1;
self.x = laneX[self.lane];
self.y = -100;
self.width = 80;
self.height = 80;
self.kind = '';
self.update = function () {};
return self;
});
// Speed boost powerup
var Speed = Powerup.expand(function () {
var self = Powerup.call(this);
var spdSprite = self.attachAsset('speed', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = spdSprite.width;
self.height = spdSprite.height;
self.kind = 'speed';
return self;
});
// Magnet powerup
var Magnet = Powerup.expand(function () {
var self = Powerup.call(this);
var magSprite = self.attachAsset('magnet', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = magSprite.width;
self.height = magSprite.height;
self.kind = 'magnet';
return self;
});
// Double points powerup
var Double = Powerup.expand(function () {
var self = Powerup.call(this);
var dblSprite = self.attachAsset('double', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = dblSprite.width;
self.height = dblSprite.height;
self.kind = 'double';
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87ceeb // Light blue sky
});
/****
* Game Code
****/
// Game state variables
// Cat character (main player)
// Fish collectible
// Trash can obstacle
// Water puddle obstacle
// Dog obstacle
// Magnet powerup
// Speed boost powerup
// Double points powerup
// Lane positions (3 lanes: left, center, right)
var laneX = [512, 1024, 1536];
var cat;
var obstacles = [];
var fishes = [];
var powerups = [];
var score = 0;
var speed = 18; // Initial speed (pixels per frame)
var gameTick = 0;
var lastSwipeX = null;
var dragStartX = null;
var dragStartY = null;
var dragActive = false;
var swipeThreshold = 80; // Minimum px for swipe
var lastLane = 1;
var lastScore = 0;
var powerupDuration = 4000; // ms
var spawnTimer = 0;
var powerupSpawnTimer = 0;
var fishSpawnTimer = 0;
var gameOver = false;
// Score text
var scoreTxt = new Text2('0', {
size: 120,
fill: "#fff"
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Powerup indicator
var powerupTxt = new Text2('', {
size: 70,
fill: "#fff"
});
powerupTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(powerupTxt);
powerupTxt.y = 130;
// Daily reward (placeholder, not implemented in MVP)
var dailyRewardTxt = new Text2('', {
size: 60,
fill: "#fff"
});
dailyRewardTxt.anchor.set(0.5, 0);
LK.gui.bottom.addChild(dailyRewardTxt);
dailyRewardTxt.visible = false;
// Initialize cat
cat = new Cat();
cat.x = laneX[1];
cat.y = 2200;
game.addChild(cat);
// Helper: spawn obstacle
function spawnObstacle() {
var lane = Math.floor(Math.random() * 3);
var typeRand = Math.random();
var obs;
if (typeRand < 0.5) {
obs = new Trashcan();
} else if (typeRand < 0.8) {
obs = new Puddle();
} else {
obs = new Dog();
}
obs.lane = lane;
obs.x = laneX[lane];
obs.y = -200;
obstacles.push(obs);
game.addChild(obs);
}
// Helper: spawn fish
function spawnFish() {
var lane = Math.floor(Math.random() * 3);
var fish = new Fish();
fish.lane = lane;
fish.x = laneX[lane];
fish.y = -100;
fishes.push(fish);
game.addChild(fish);
}
// Helper: spawn powerup
function spawnPowerup() {
var lane = Math.floor(Math.random() * 3);
var kindRand = Math.random();
var pwr;
if (kindRand < 0.34) {
pwr = new Magnet();
} else if (kindRand < 0.67) {
pwr = new Speed();
} else {
pwr = new Double();
}
pwr.lane = lane;
pwr.x = laneX[lane];
pwr.y = -100;
powerups.push(pwr);
game.addChild(pwr);
}
// Helper: reset game state
function resetGame() {
// Remove all obstacles, fishes, powerups
for (var i = 0; i < obstacles.length; i++) obstacles[i].destroy();
for (var i = 0; i < fishes.length; i++) fishes[i].destroy();
for (var i = 0; i < powerups.length; i++) powerups[i].destroy();
obstacles = [];
fishes = [];
powerups = [];
score = 0;
speed = 18;
gameTick = 0;
cat.lane = 1;
cat.x = laneX[1];
cat.y = 2200;
cat.magnetActive = false;
cat.speedBoostActive = false;
cat.doubleActive = false;
cat.powerupTimer = 0;
scoreTxt.setText('0');
powerupTxt.setText('');
gameOver = false;
}
// Touch/move/swipe controls
game.down = function (x, y, obj) {
dragStartX = x;
dragStartY = y;
dragActive = true;
lastSwipeX = x;
};
game.move = function (x, y, obj) {
if (!dragActive) return;
var dx = x - dragStartX;
if (Math.abs(dx) > swipeThreshold) {
if (dx > 0 && cat.lane < 2) {
cat.moveToLane(cat.lane + 1);
dragActive = false;
} else if (dx < 0 && cat.lane > 0) {
cat.moveToLane(cat.lane - 1);
dragActive = false;
}
}
};
game.up = function (x, y, obj) {
dragActive = false;
};
// Main game update loop
// Random meow timer
var meowTimer = 0;
game.update = function () {
if (gameOver) return;
gameTick++;
// Increase speed over time
if (gameTick % 180 === 0 && speed < 40) {
speed += 1;
}
// If speed boost active
var moveSpeed = cat.speedBoostActive ? speed * 1.7 : speed;
// Spawn obstacles
spawnTimer--;
if (spawnTimer <= 0) {
spawnObstacle();
spawnTimer = 60 + Math.floor(Math.random() * 40); // 1-1.5s
}
// Spawn fish
fishSpawnTimer--;
if (fishSpawnTimer <= 0) {
spawnFish();
fishSpawnTimer = 40 + Math.floor(Math.random() * 40); // 0.7-1.3s
}
// Spawn powerup
powerupSpawnTimer--;
if (powerupSpawnTimer <= 0) {
spawnPowerup();
powerupSpawnTimer = 400 + Math.floor(Math.random() * 200); // 7-10s
}
// Update cat
cat.update();
// Move obstacles
for (var i = obstacles.length - 1; i >= 0; i--) {
var obs = obstacles[i];
obs.y += moveSpeed;
// Remove if off screen
if (obs.y > 2900) {
obs.destroy();
obstacles.splice(i, 1);
continue;
}
// Collision with cat
if (obs.lane === cat.lane && Math.abs(obs.y - cat.y) < (obs.height + cat.height) / 2 - 20) {
// Play trash impact sound if trashcan, otherwise cat meow
if (obs.type === 'trashcan') {
LK.getSound('TrashImpactSound').play();
} else {
LK.getSound('cat').play();
}
// Game over
LK.effects.flashScreen(0xff0000, 800);
gameOver = true;
LK.showGameOver();
return;
}
}
// Move fishes
for (var i = fishes.length - 1; i >= 0; i--) {
var fish = fishes[i];
fish.y += moveSpeed;
// Magnet effect
if (cat.magnetActive && Math.abs(fish.y - cat.y) < 500 && Math.abs(fish.x - cat.x) < 400) {
// Move fish toward cat
var dx = cat.x - fish.x;
var dy = cat.y - fish.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist > 1) {
fish.x += dx / dist * 22;
fish.y += dy / dist * 22;
}
}
// Remove if off screen
if (fish.y > 2900) {
fish.destroy();
fishes.splice(i, 1);
continue;
}
// Collect fish
if (!fish.collected && fish.lane === cat.lane && Math.abs(fish.y - cat.y) < (fish.height + cat.height) / 2 - 20) {
fish.collected = true;
var points = cat.doubleActive ? 2 : 1;
score += points;
LK.setScore(score);
scoreTxt.setText(score + '');
// Play cat meow sound only when cat eats 5 fish
if (typeof fishEatCount === "undefined") {
fishEatCount = 0;
}
fishEatCount += 1;
if (fishEatCount % 5 === 0) {
LK.getSound('cat').play();
}
// Animate fish
tween(fish, {
alpha: 0,
y: cat.y - 80
}, {
duration: 200,
onFinish: function onFinish() {
fish.destroy();
}
});
fishes.splice(i, 1);
continue;
}
}
// Move powerups
for (var i = powerups.length - 1; i >= 0; i--) {
var pwr = powerups[i];
pwr.y += moveSpeed;
// Remove if off screen
if (pwr.y > 2900) {
pwr.destroy();
powerups.splice(i, 1);
continue;
}
// Collect powerup
if (pwr.lane === cat.lane && Math.abs(pwr.y - cat.y) < (pwr.height + cat.height) / 2 - 20) {
// Activate powerup
cat.activatePowerup(pwr.kind, powerupDuration);
// Play speed sound only when picking up speed powerup
if (pwr.kind === 'speed') {
LK.getSound('speed').play();
}
// Show indicator
if (pwr.kind === 'magnet') {
powerupTxt.setText('Magnet!');
} else if (pwr.kind === 'speed') {
powerupTxt.setText('Speed!');
} else if (pwr.kind === 'double') {
powerupTxt.setText('Double Points!');
}
// Animate
tween(pwr, {
alpha: 0,
y: cat.y - 80
}, {
duration: 200,
onFinish: function onFinish() {
pwr.destroy();
}
});
powerups.splice(i, 1);
continue;
}
}
// Powerup indicator clear
if (!cat.magnetActive && !cat.speedBoostActive && !cat.doubleActive) {
powerupTxt.setText('');
}
};
// Reset game state on game over
LK.on('gameover', function () {
resetGame();
});
// Reset game state on you win (not used in endless runner, but for completeness)
LK.on('youwin', function () {
resetGame();
});
pixel art 2D cat head. In-Game asset. 2d. High contrast. No shadows
pixel art 2D dog head. In-Game asset. 2d. High contrast. No shadows
pixel art 2D trash can. In-Game asset. 2d. High contrast. No shadows
pixel art 2D fish. In-Game asset. 2d. High contrast. No shadows
pixel art 2D magnet. In-Game asset. 2d. High contrast. No shadows
pixel art 2D puddle. In-Game asset. 2d. High contrast. No shadows
pixel art 2D speed drink. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
pixel art 2D x2. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat