/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Landmark = Container.expand(function (type) {
var self = Container.call(this);
var landmarkGraphics = self.attachAsset(type, {
anchorX: 0.5,
anchorY: 0.5
});
self.type = type;
self.passed = false;
return self;
});
var Obstacle = Container.expand(function () {
var self = Container.call(this);
var obstacleGraphics = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
var PowerpuffGirl = Container.expand(function (characterType) {
var self = Container.call(this);
var characterGraphics = self.attachAsset(characterType, {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 2;
self.sidewaysSpeed = 0;
self.acceleration = 0.1;
self.isAccelerating = false;
self.characterType = characterType;
self.update = function () {
// Move down the mountain
self.y += self.speed;
// Handle sideways movement
if (self.sidewaysSpeed > 0) {
self.x += self.sidewaysSpeed;
self.sidewaysSpeed *= 0.95; // Gradual slowdown
} else if (self.sidewaysSpeed < 0) {
self.x += self.sidewaysSpeed;
self.sidewaysSpeed *= 0.95;
}
// Handle acceleration
if (self.isAccelerating) {
self.speed += self.acceleration;
if (self.speed > 8) self.speed = 8; // Max speed
} else {
if (self.speed > 2) {
self.speed -= 0.05; // Gradual slowdown
}
}
// Keep character within screen bounds
if (self.x < 50) self.x = 50;
if (self.x > 1998) self.x = 1998;
};
self.moveLeft = function () {
self.sidewaysSpeed = -8;
LK.getSound('swoosh').play();
};
self.moveRight = function () {
self.sidewaysSpeed = 8;
LK.getSound('swoosh').play();
};
self.accelerate = function () {
self.isAccelerating = true;
};
self.stopAccelerate = function () {
self.isAccelerating = false;
};
self.down = function (x, y, obj) {
if (x < self.width / 2) {
self.moveLeft();
} else {
self.moveRight();
}
};
return self;
});
var Snowflake = Container.expand(function () {
var self = Container.call(this);
var snowflakeGraphics = self.attachAsset('snowflake', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = Math.random() * 2 + 1;
self.drift = (Math.random() - 0.5) * 2;
self.update = function () {
self.y += self.speed;
self.x += self.drift;
if (self.y > 2800) {
self.y = -50;
self.x = Math.random() * 2048;
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB
});
/****
* Game Code
****/
// Game variables
var powerpuffGirls = [];
var snowflakes = [];
var obstacles = [];
var landmarks = [];
var gameStarted = false;
var allGirlsFinished = false;
var cameraY = 0;
var mountainLength = 4000;
// UI elements
var scoreTxt = new Text2('Distance: 0m', {
size: 60,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
var instructionTxt = new Text2('Tap girls to move sideways, tap and hold to accelerate!', {
size: 40,
fill: 0xFFFFFF
});
instructionTxt.anchor.set(0.5, 0);
instructionTxt.x = LK.gui.center.x;
instructionTxt.y = 100;
LK.gui.center.addChild(instructionTxt);
// Create Powerpuff Girls
var blossom = game.addChild(new PowerpuffGirl('blossom'));
blossom.x = 500;
blossom.y = 200;
powerpuffGirls.push(blossom);
var bubbles = game.addChild(new PowerpuffGirl('bubbles'));
bubbles.x = 1024;
bubbles.y = 200;
powerpuffGirls.push(bubbles);
var buttercup = game.addChild(new PowerpuffGirl('buttercup'));
buttercup.x = 1500;
buttercup.y = 200;
powerpuffGirls.push(buttercup);
// Create snowflakes
for (var i = 0; i < 30; i++) {
var snowflake = game.addChild(new Snowflake());
snowflake.x = Math.random() * 2048;
snowflake.y = Math.random() * 2732;
snowflakes.push(snowflake);
}
// Create landmarks along the mountain
var landmarkPositions = [{
type: 'hill',
x: 300,
y: 800
}, {
type: 'shop',
x: 1200,
y: 1200
}, {
type: 'hill',
x: 800,
y: 1600
}, {
type: 'house',
x: 1600,
y: 2000
}, {
type: 'hill',
x: 400,
y: 2400
}, {
type: 'shop',
x: 1000,
y: 2800
}, {
type: 'playgroup',
x: 1024,
y: 3600
}];
for (var i = 0; i < landmarkPositions.length; i++) {
var landmark = game.addChild(new Landmark(landmarkPositions[i].type));
landmark.x = landmarkPositions[i].x;
landmark.y = landmarkPositions[i].y;
landmarks.push(landmark);
}
// Create obstacles
var obstaclePositions = [{
x: 600,
y: 1000
}, {
x: 1400,
y: 1400
}, {
x: 200,
y: 1800
}, {
x: 1800,
y: 2200
}, {
x: 700,
y: 2600
}, {
x: 1300,
y: 3000
}];
for (var i = 0; i < obstaclePositions.length; i++) {
var obstacle = game.addChild(new Obstacle());
obstacle.x = obstaclePositions[i].x;
obstacle.y = obstaclePositions[i].y;
obstacles.push(obstacle);
}
// Game input handling
var acceleratingGirls = [];
game.down = function (x, y, obj) {
// Check if tapping on a girl for acceleration
for (var i = 0; i < powerpuffGirls.length; i++) {
var girl = powerpuffGirls[i];
var localPos = girl.toLocal({
x: x,
y: y
});
if (Math.abs(localPos.x) < 40 && Math.abs(localPos.y) < 40) {
girl.accelerate();
if (acceleratingGirls.indexOf(girl) === -1) {
acceleratingGirls.push(girl);
}
return;
}
}
};
game.up = function (x, y, obj) {
// Stop acceleration for all girls
for (var i = 0; i < acceleratingGirls.length; i++) {
acceleratingGirls[i].stopAccelerate();
}
acceleratingGirls = [];
};
// Main game loop
game.update = function () {
if (!gameStarted) {
gameStarted = true;
// Hide instruction after 3 seconds
LK.setTimeout(function () {
if (instructionTxt.parent) {
instructionTxt.parent.removeChild(instructionTxt);
}
}, 3000);
}
// Calculate camera position based on the leading girl
var leadingY = Math.max(blossom.y, bubbles.y, buttercup.y);
cameraY = leadingY - 400;
// Update camera position
game.y = -cameraY;
// Update distance score
var distance = Math.floor(leadingY / 10);
scoreTxt.setText('Distance: ' + distance + 'm');
// Check collisions with obstacles
for (var i = 0; i < powerpuffGirls.length; i++) {
var girl = powerpuffGirls[i];
for (var j = 0; j < obstacles.length; j++) {
var obstacle = obstacles[j];
if (girl.intersects(obstacle)) {
// Slow down the girl when hitting obstacle
girl.speed = Math.max(1, girl.speed - 1);
LK.effects.flashObject(girl, 0xFF0000, 500);
}
}
}
// Check if girls reached landmarks
for (var i = 0; i < landmarks.length; i++) {
var landmark = landmarks[i];
if (!landmark.passed) {
for (var j = 0; j < powerpuffGirls.length; j++) {
var girl = powerpuffGirls[j];
if (girl.intersects(landmark)) {
landmark.passed = true;
LK.setScore(LK.getScore() + 10);
LK.getSound('collect').play();
if (landmark.type === 'playgroup') {
// Check if all girls reached the playgroup
var allReached = true;
for (var k = 0; k < powerpuffGirls.length; k++) {
if (!powerpuffGirls[k].intersects(landmark)) {
allReached = false;
break;
}
}
if (allReached && !allGirlsFinished) {
allGirlsFinished = true;
LK.setTimeout(function () {
LK.showYouWin();
}, 1000);
}
}
break;
}
}
}
}
// Check if any girl went too far off course
for (var i = 0; i < powerpuffGirls.length; i++) {
var girl = powerpuffGirls[i];
if (girl.y > mountainLength + 500) {
LK.showGameOver();
return;
}
}
}; /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Landmark = Container.expand(function (type) {
var self = Container.call(this);
var landmarkGraphics = self.attachAsset(type, {
anchorX: 0.5,
anchorY: 0.5
});
self.type = type;
self.passed = false;
return self;
});
var Obstacle = Container.expand(function () {
var self = Container.call(this);
var obstacleGraphics = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
var PowerpuffGirl = Container.expand(function (characterType) {
var self = Container.call(this);
var characterGraphics = self.attachAsset(characterType, {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 2;
self.sidewaysSpeed = 0;
self.acceleration = 0.1;
self.isAccelerating = false;
self.characterType = characterType;
self.update = function () {
// Move down the mountain
self.y += self.speed;
// Handle sideways movement
if (self.sidewaysSpeed > 0) {
self.x += self.sidewaysSpeed;
self.sidewaysSpeed *= 0.95; // Gradual slowdown
} else if (self.sidewaysSpeed < 0) {
self.x += self.sidewaysSpeed;
self.sidewaysSpeed *= 0.95;
}
// Handle acceleration
if (self.isAccelerating) {
self.speed += self.acceleration;
if (self.speed > 8) self.speed = 8; // Max speed
} else {
if (self.speed > 2) {
self.speed -= 0.05; // Gradual slowdown
}
}
// Keep character within screen bounds
if (self.x < 50) self.x = 50;
if (self.x > 1998) self.x = 1998;
};
self.moveLeft = function () {
self.sidewaysSpeed = -8;
LK.getSound('swoosh').play();
};
self.moveRight = function () {
self.sidewaysSpeed = 8;
LK.getSound('swoosh').play();
};
self.accelerate = function () {
self.isAccelerating = true;
};
self.stopAccelerate = function () {
self.isAccelerating = false;
};
self.down = function (x, y, obj) {
if (x < self.width / 2) {
self.moveLeft();
} else {
self.moveRight();
}
};
return self;
});
var Snowflake = Container.expand(function () {
var self = Container.call(this);
var snowflakeGraphics = self.attachAsset('snowflake', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = Math.random() * 2 + 1;
self.drift = (Math.random() - 0.5) * 2;
self.update = function () {
self.y += self.speed;
self.x += self.drift;
if (self.y > 2800) {
self.y = -50;
self.x = Math.random() * 2048;
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB
});
/****
* Game Code
****/
// Game variables
var powerpuffGirls = [];
var snowflakes = [];
var obstacles = [];
var landmarks = [];
var gameStarted = false;
var allGirlsFinished = false;
var cameraY = 0;
var mountainLength = 4000;
// UI elements
var scoreTxt = new Text2('Distance: 0m', {
size: 60,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
var instructionTxt = new Text2('Tap girls to move sideways, tap and hold to accelerate!', {
size: 40,
fill: 0xFFFFFF
});
instructionTxt.anchor.set(0.5, 0);
instructionTxt.x = LK.gui.center.x;
instructionTxt.y = 100;
LK.gui.center.addChild(instructionTxt);
// Create Powerpuff Girls
var blossom = game.addChild(new PowerpuffGirl('blossom'));
blossom.x = 500;
blossom.y = 200;
powerpuffGirls.push(blossom);
var bubbles = game.addChild(new PowerpuffGirl('bubbles'));
bubbles.x = 1024;
bubbles.y = 200;
powerpuffGirls.push(bubbles);
var buttercup = game.addChild(new PowerpuffGirl('buttercup'));
buttercup.x = 1500;
buttercup.y = 200;
powerpuffGirls.push(buttercup);
// Create snowflakes
for (var i = 0; i < 30; i++) {
var snowflake = game.addChild(new Snowflake());
snowflake.x = Math.random() * 2048;
snowflake.y = Math.random() * 2732;
snowflakes.push(snowflake);
}
// Create landmarks along the mountain
var landmarkPositions = [{
type: 'hill',
x: 300,
y: 800
}, {
type: 'shop',
x: 1200,
y: 1200
}, {
type: 'hill',
x: 800,
y: 1600
}, {
type: 'house',
x: 1600,
y: 2000
}, {
type: 'hill',
x: 400,
y: 2400
}, {
type: 'shop',
x: 1000,
y: 2800
}, {
type: 'playgroup',
x: 1024,
y: 3600
}];
for (var i = 0; i < landmarkPositions.length; i++) {
var landmark = game.addChild(new Landmark(landmarkPositions[i].type));
landmark.x = landmarkPositions[i].x;
landmark.y = landmarkPositions[i].y;
landmarks.push(landmark);
}
// Create obstacles
var obstaclePositions = [{
x: 600,
y: 1000
}, {
x: 1400,
y: 1400
}, {
x: 200,
y: 1800
}, {
x: 1800,
y: 2200
}, {
x: 700,
y: 2600
}, {
x: 1300,
y: 3000
}];
for (var i = 0; i < obstaclePositions.length; i++) {
var obstacle = game.addChild(new Obstacle());
obstacle.x = obstaclePositions[i].x;
obstacle.y = obstaclePositions[i].y;
obstacles.push(obstacle);
}
// Game input handling
var acceleratingGirls = [];
game.down = function (x, y, obj) {
// Check if tapping on a girl for acceleration
for (var i = 0; i < powerpuffGirls.length; i++) {
var girl = powerpuffGirls[i];
var localPos = girl.toLocal({
x: x,
y: y
});
if (Math.abs(localPos.x) < 40 && Math.abs(localPos.y) < 40) {
girl.accelerate();
if (acceleratingGirls.indexOf(girl) === -1) {
acceleratingGirls.push(girl);
}
return;
}
}
};
game.up = function (x, y, obj) {
// Stop acceleration for all girls
for (var i = 0; i < acceleratingGirls.length; i++) {
acceleratingGirls[i].stopAccelerate();
}
acceleratingGirls = [];
};
// Main game loop
game.update = function () {
if (!gameStarted) {
gameStarted = true;
// Hide instruction after 3 seconds
LK.setTimeout(function () {
if (instructionTxt.parent) {
instructionTxt.parent.removeChild(instructionTxt);
}
}, 3000);
}
// Calculate camera position based on the leading girl
var leadingY = Math.max(blossom.y, bubbles.y, buttercup.y);
cameraY = leadingY - 400;
// Update camera position
game.y = -cameraY;
// Update distance score
var distance = Math.floor(leadingY / 10);
scoreTxt.setText('Distance: ' + distance + 'm');
// Check collisions with obstacles
for (var i = 0; i < powerpuffGirls.length; i++) {
var girl = powerpuffGirls[i];
for (var j = 0; j < obstacles.length; j++) {
var obstacle = obstacles[j];
if (girl.intersects(obstacle)) {
// Slow down the girl when hitting obstacle
girl.speed = Math.max(1, girl.speed - 1);
LK.effects.flashObject(girl, 0xFF0000, 500);
}
}
}
// Check if girls reached landmarks
for (var i = 0; i < landmarks.length; i++) {
var landmark = landmarks[i];
if (!landmark.passed) {
for (var j = 0; j < powerpuffGirls.length; j++) {
var girl = powerpuffGirls[j];
if (girl.intersects(landmark)) {
landmark.passed = true;
LK.setScore(LK.getScore() + 10);
LK.getSound('collect').play();
if (landmark.type === 'playgroup') {
// Check if all girls reached the playgroup
var allReached = true;
for (var k = 0; k < powerpuffGirls.length; k++) {
if (!powerpuffGirls[k].intersects(landmark)) {
allReached = false;
break;
}
}
if (allReached && !allGirlsFinished) {
allGirlsFinished = true;
LK.setTimeout(function () {
LK.showYouWin();
}, 1000);
}
}
break;
}
}
}
}
// Check if any girl went too far off course
for (var i = 0; i < powerpuffGirls.length; i++) {
var girl = powerpuffGirls[i];
if (girl.y > mountainLength + 500) {
LK.showGameOver();
return;
}
}
};