Code edit (1 edits merged)
Please save this source code
User prompt
Stepping Stones Challenge
Initial prompt
Toca stepping stones (2014). The aim of this game is to make it across the rock pool before time runs out. Tap on the powerpuff girls to jump to the next stone but be careful not all the stone are what you seen before you fall into the sea. Tap on level 1 white, level 2 blue, level 3 red, level 4 purple, or level 5 green to get started.
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var LevelButton = Container.expand(function (levelNumber, color, x, y) {
var self = Container.call(this);
self.levelNumber = levelNumber;
self.x = x;
self.y = y;
var buttonGraphics = self.attachAsset('stableStone', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5,
tint: color
});
var levelText = new Text2(levelNumber.toString(), {
size: 60,
fill: 0xFFFFFF
});
levelText.anchor.set(0.5, 0.5);
self.addChild(levelText);
self.down = function (x, y, obj) {
if (gameState === 'levelSelect') {
startLevel(self.levelNumber);
}
};
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
var playerGraphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
self.jumpTo = function (targetX, targetY, onComplete) {
playerMoving = true;
// Jump animation
tween(self, {
x: targetX,
y: targetY - 30
}, {
duration: 300,
easing: tween.easeOut
});
tween(self, {
x: targetX,
y: targetY
}, {
duration: 300,
easing: tween.easeIn,
onFinish: function onFinish() {
playerMoving = false;
if (onComplete) onComplete();
}
});
};
return self;
});
var Stone = Container.expand(function (isStable, level) {
var self = Container.call(this);
self.isStable = isStable;
self.level = level;
self.hasBeenStepped = false;
var stoneGraphics = self.attachAsset(isStable ? 'stableStone' : 'unstableStone', {
anchorX: 0.5,
anchorY: 0.5
});
// Add subtle visual hints for stability
if (!isStable) {
stoneGraphics.alpha = 0.9;
}
self.stepOn = function () {
if (self.hasBeenStepped) return false;
self.hasBeenStepped = true;
if (self.isStable) {
// Stable stone - slight wobble
tween(stoneGraphics, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 100
});
tween(stoneGraphics, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 100
});
return true;
} else {
// Unstable stone - crumble effect
tween(stoneGraphics, {
alpha: 0.3,
scaleX: 0.8,
scaleY: 0.8
}, {
duration: 200
});
return false;
}
};
self.down = function (x, y, obj) {
if (gameState === 'playing' && !playerMoving) {
targetStone = self;
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x4A90E2
});
/****
* Game Code
****/
// Game state variables
var gameState = 'levelSelect'; // 'levelSelect', 'playing', 'gameOver'
var currentLevel = 1;
var timeLeft = 60;
var gameTimer;
var playerMoving = false;
var targetStone = null;
// Game objects
var player;
var stones = [];
var startPlatform;
var endPlatform;
var levelButtons = [];
// UI elements
var timerText;
var levelText;
var instructionText;
// Level configurations
var levelConfigs = {
1: {
color: 0xFFFFFF,
timeLimit: 60,
stableStones: 8,
unstableStones: 4
},
2: {
color: 0x4A90E2,
timeLimit: 50,
stableStones: 7,
unstableStones: 5
},
3: {
color: 0xFF6B35,
timeLimit: 40,
stableStones: 6,
unstableStones: 6
},
4: {
color: 0x8E44AD,
timeLimit: 35,
stableStones: 5,
unstableStones: 7
},
5: {
color: 0x27AE60,
timeLimit: 30,
stableStones: 4,
unstableStones: 8
}
};
// Initialize UI
function initUI() {
timerText = new Text2('Time: 60', {
size: 80,
fill: 0xFFFFFF
});
timerText.anchor.set(0.5, 0);
LK.gui.top.addChild(timerText);
levelText = new Text2('Level 1', {
size: 60,
fill: 0xFFFFFF
});
levelText.anchor.set(0, 0);
levelText.x = 150;
levelText.y = 50;
LK.gui.topLeft.addChild(levelText);
instructionText = new Text2('Tap stones to jump!', {
size: 50,
fill: 0xFFFFFF
});
instructionText.anchor.set(0.5, 1);
LK.gui.bottom.addChild(instructionText);
}
// Create level selection screen
function createLevelSelect() {
gameState = 'levelSelect';
clearGame();
// Title
var titleText = new Text2('Stepping Stones Challenge', {
size: 80,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 1024;
titleText.y = 400;
game.addChild(titleText);
// Level buttons
var colors = [0xFFFFFF, 0x4A90E2, 0xFF6B35, 0x8E44AD, 0x27AE60];
var positions = [{
x: 512,
y: 800
}, {
x: 1024,
y: 800
}, {
x: 1536,
y: 800
}, {
x: 768,
y: 1000
}, {
x: 1280,
y: 1000
}];
for (var i = 0; i < 5; i++) {
var levelButton = new LevelButton(i + 1, colors[i], positions[i].x, positions[i].y);
levelButtons.push(levelButton);
game.addChild(levelButton);
}
instructionText.setText('Choose your level!');
}
// Start a specific level
function startLevel(level) {
currentLevel = level;
gameState = 'playing';
var config = levelConfigs[level];
timeLeft = config.timeLimit;
clearGame();
createLevel();
// Start timer
gameTimer = LK.setInterval(function () {
timeLeft--;
timerText.setText('Time: ' + timeLeft);
if (timeLeft <= 0) {
gameOver(false);
}
}, 1000);
levelText.setText('Level ' + level);
instructionText.setText('Tap stones to jump!');
}
// Create level layout
function createLevel() {
var config = levelConfigs[currentLevel];
// Create start platform
startPlatform = game.addChild(LK.getAsset('startPlatform', {
anchorX: 0.5,
anchorY: 0.5,
x: 200,
y: 2000
}));
// Create end platform
endPlatform = game.addChild(LK.getAsset('endPlatform', {
anchorX: 0.5,
anchorY: 0.5,
x: 1848,
y: 2000
}));
// Create player
player = game.addChild(new Player());
player.x = 200;
player.y = 1950;
// Generate stone positions
var totalStones = config.stableStones + config.unstableStones;
var stonePositions = [];
// Create a path of stones
for (var i = 0; i < totalStones; i++) {
var x = 400 + i * 150 + (Math.random() * 100 - 50);
var y = 1800 + (Math.random() * 400 - 200);
stonePositions.push({
x: x,
y: y
});
}
// Randomly assign stability
var stableCount = config.stableStones;
for (var i = 0; i < stonePositions.length; i++) {
var isStable = stableCount > 0 && (Math.random() < 0.6 || stableCount >= stonePositions.length - i);
if (isStable) stableCount--;
var stone = new Stone(isStable, currentLevel);
stone.x = stonePositions[i].x;
stone.y = stonePositions[i].y;
stones.push(stone);
game.addChild(stone);
}
}
// Clear game objects
function clearGame() {
// Clear stones
for (var i = 0; i < stones.length; i++) {
stones[i].destroy();
}
stones = [];
// Clear level buttons
for (var i = 0; i < levelButtons.length; i++) {
levelButtons[i].destroy();
}
levelButtons = [];
// Clear platforms and player
if (startPlatform) {
startPlatform.destroy();
startPlatform = null;
}
if (endPlatform) {
endPlatform.destroy();
endPlatform = null;
}
if (player) {
player.destroy();
player = null;
}
// Clear timer
if (gameTimer) {
LK.clearInterval(gameTimer);
gameTimer = null;
}
// Clear any remaining children
while (game.children.length > 0) {
game.children[0].destroy();
}
}
// Game over handling
function gameOver(success) {
gameState = 'gameOver';
if (gameTimer) {
LK.clearInterval(gameTimer);
gameTimer = null;
}
if (success) {
LK.getSound('success').play();
LK.setScore(LK.getScore() + timeLeft + currentLevel * 10);
if (currentLevel >= 5) {
LK.showYouWin();
} else {
// Show success message and move to next level
LK.setTimeout(function () {
startLevel(currentLevel + 1);
}, 2000);
}
} else {
LK.getSound('fall').play();
LK.showGameOver();
}
}
// Initialize game
initUI();
createLevelSelect();
// Game update loop
game.update = function () {
if (gameState === 'playing') {
// Handle stone tapping
if (targetStone && !playerMoving) {
var distance = Math.sqrt(Math.pow(targetStone.x - player.x, 2) + Math.pow(targetStone.y - player.y, 2));
if (distance < 200) {
// Within jumping range
LK.getSound('jump').play();
player.jumpTo(targetStone.x, targetStone.y, function () {
var success = targetStone.stepOn();
if (!success) {
gameOver(false);
} else {
// Check if reached end platform
var endDistance = Math.sqrt(Math.pow(endPlatform.x - player.x, 2) + Math.pow(endPlatform.y - player.y, 2));
if (endDistance < 150) {
gameOver(true);
}
}
});
}
targetStone = null;
}
// Check if player can reach end platform directly
if (!playerMoving && endPlatform) {
var endDistance = Math.sqrt(Math.pow(endPlatform.x - player.x, 2) + Math.pow(endPlatform.y - player.y, 2));
if (endDistance < 200) {
// Allow direct jump to end platform
if (LK.ticks % 10 === 0) {
instructionText.setText('Tap end platform to finish!');
}
}
}
}
};
// Handle direct clicks on end platform
game.down = function (x, y, obj) {
if (gameState === 'playing' && !playerMoving && endPlatform) {
var endDistance = Math.sqrt(Math.pow(endPlatform.x - player.x, 2) + Math.pow(endPlatform.y - player.y, 2));
if (endDistance < 200) {
// Check if click is on end platform
var localPos = endPlatform.toLocal({
x: x,
y: y
});
if (Math.abs(localPos.x) < 100 && Math.abs(localPos.y) < 50) {
LK.getSound('jump').play();
player.jumpTo(endPlatform.x, endPlatform.y - 50, function () {
gameOver(true);
});
}
}
}
}; /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var LevelButton = Container.expand(function (levelNumber, color, x, y) {
var self = Container.call(this);
self.levelNumber = levelNumber;
self.x = x;
self.y = y;
var buttonGraphics = self.attachAsset('stableStone', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5,
tint: color
});
var levelText = new Text2(levelNumber.toString(), {
size: 60,
fill: 0xFFFFFF
});
levelText.anchor.set(0.5, 0.5);
self.addChild(levelText);
self.down = function (x, y, obj) {
if (gameState === 'levelSelect') {
startLevel(self.levelNumber);
}
};
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
var playerGraphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
self.jumpTo = function (targetX, targetY, onComplete) {
playerMoving = true;
// Jump animation
tween(self, {
x: targetX,
y: targetY - 30
}, {
duration: 300,
easing: tween.easeOut
});
tween(self, {
x: targetX,
y: targetY
}, {
duration: 300,
easing: tween.easeIn,
onFinish: function onFinish() {
playerMoving = false;
if (onComplete) onComplete();
}
});
};
return self;
});
var Stone = Container.expand(function (isStable, level) {
var self = Container.call(this);
self.isStable = isStable;
self.level = level;
self.hasBeenStepped = false;
var stoneGraphics = self.attachAsset(isStable ? 'stableStone' : 'unstableStone', {
anchorX: 0.5,
anchorY: 0.5
});
// Add subtle visual hints for stability
if (!isStable) {
stoneGraphics.alpha = 0.9;
}
self.stepOn = function () {
if (self.hasBeenStepped) return false;
self.hasBeenStepped = true;
if (self.isStable) {
// Stable stone - slight wobble
tween(stoneGraphics, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 100
});
tween(stoneGraphics, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 100
});
return true;
} else {
// Unstable stone - crumble effect
tween(stoneGraphics, {
alpha: 0.3,
scaleX: 0.8,
scaleY: 0.8
}, {
duration: 200
});
return false;
}
};
self.down = function (x, y, obj) {
if (gameState === 'playing' && !playerMoving) {
targetStone = self;
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x4A90E2
});
/****
* Game Code
****/
// Game state variables
var gameState = 'levelSelect'; // 'levelSelect', 'playing', 'gameOver'
var currentLevel = 1;
var timeLeft = 60;
var gameTimer;
var playerMoving = false;
var targetStone = null;
// Game objects
var player;
var stones = [];
var startPlatform;
var endPlatform;
var levelButtons = [];
// UI elements
var timerText;
var levelText;
var instructionText;
// Level configurations
var levelConfigs = {
1: {
color: 0xFFFFFF,
timeLimit: 60,
stableStones: 8,
unstableStones: 4
},
2: {
color: 0x4A90E2,
timeLimit: 50,
stableStones: 7,
unstableStones: 5
},
3: {
color: 0xFF6B35,
timeLimit: 40,
stableStones: 6,
unstableStones: 6
},
4: {
color: 0x8E44AD,
timeLimit: 35,
stableStones: 5,
unstableStones: 7
},
5: {
color: 0x27AE60,
timeLimit: 30,
stableStones: 4,
unstableStones: 8
}
};
// Initialize UI
function initUI() {
timerText = new Text2('Time: 60', {
size: 80,
fill: 0xFFFFFF
});
timerText.anchor.set(0.5, 0);
LK.gui.top.addChild(timerText);
levelText = new Text2('Level 1', {
size: 60,
fill: 0xFFFFFF
});
levelText.anchor.set(0, 0);
levelText.x = 150;
levelText.y = 50;
LK.gui.topLeft.addChild(levelText);
instructionText = new Text2('Tap stones to jump!', {
size: 50,
fill: 0xFFFFFF
});
instructionText.anchor.set(0.5, 1);
LK.gui.bottom.addChild(instructionText);
}
// Create level selection screen
function createLevelSelect() {
gameState = 'levelSelect';
clearGame();
// Title
var titleText = new Text2('Stepping Stones Challenge', {
size: 80,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 1024;
titleText.y = 400;
game.addChild(titleText);
// Level buttons
var colors = [0xFFFFFF, 0x4A90E2, 0xFF6B35, 0x8E44AD, 0x27AE60];
var positions = [{
x: 512,
y: 800
}, {
x: 1024,
y: 800
}, {
x: 1536,
y: 800
}, {
x: 768,
y: 1000
}, {
x: 1280,
y: 1000
}];
for (var i = 0; i < 5; i++) {
var levelButton = new LevelButton(i + 1, colors[i], positions[i].x, positions[i].y);
levelButtons.push(levelButton);
game.addChild(levelButton);
}
instructionText.setText('Choose your level!');
}
// Start a specific level
function startLevel(level) {
currentLevel = level;
gameState = 'playing';
var config = levelConfigs[level];
timeLeft = config.timeLimit;
clearGame();
createLevel();
// Start timer
gameTimer = LK.setInterval(function () {
timeLeft--;
timerText.setText('Time: ' + timeLeft);
if (timeLeft <= 0) {
gameOver(false);
}
}, 1000);
levelText.setText('Level ' + level);
instructionText.setText('Tap stones to jump!');
}
// Create level layout
function createLevel() {
var config = levelConfigs[currentLevel];
// Create start platform
startPlatform = game.addChild(LK.getAsset('startPlatform', {
anchorX: 0.5,
anchorY: 0.5,
x: 200,
y: 2000
}));
// Create end platform
endPlatform = game.addChild(LK.getAsset('endPlatform', {
anchorX: 0.5,
anchorY: 0.5,
x: 1848,
y: 2000
}));
// Create player
player = game.addChild(new Player());
player.x = 200;
player.y = 1950;
// Generate stone positions
var totalStones = config.stableStones + config.unstableStones;
var stonePositions = [];
// Create a path of stones
for (var i = 0; i < totalStones; i++) {
var x = 400 + i * 150 + (Math.random() * 100 - 50);
var y = 1800 + (Math.random() * 400 - 200);
stonePositions.push({
x: x,
y: y
});
}
// Randomly assign stability
var stableCount = config.stableStones;
for (var i = 0; i < stonePositions.length; i++) {
var isStable = stableCount > 0 && (Math.random() < 0.6 || stableCount >= stonePositions.length - i);
if (isStable) stableCount--;
var stone = new Stone(isStable, currentLevel);
stone.x = stonePositions[i].x;
stone.y = stonePositions[i].y;
stones.push(stone);
game.addChild(stone);
}
}
// Clear game objects
function clearGame() {
// Clear stones
for (var i = 0; i < stones.length; i++) {
stones[i].destroy();
}
stones = [];
// Clear level buttons
for (var i = 0; i < levelButtons.length; i++) {
levelButtons[i].destroy();
}
levelButtons = [];
// Clear platforms and player
if (startPlatform) {
startPlatform.destroy();
startPlatform = null;
}
if (endPlatform) {
endPlatform.destroy();
endPlatform = null;
}
if (player) {
player.destroy();
player = null;
}
// Clear timer
if (gameTimer) {
LK.clearInterval(gameTimer);
gameTimer = null;
}
// Clear any remaining children
while (game.children.length > 0) {
game.children[0].destroy();
}
}
// Game over handling
function gameOver(success) {
gameState = 'gameOver';
if (gameTimer) {
LK.clearInterval(gameTimer);
gameTimer = null;
}
if (success) {
LK.getSound('success').play();
LK.setScore(LK.getScore() + timeLeft + currentLevel * 10);
if (currentLevel >= 5) {
LK.showYouWin();
} else {
// Show success message and move to next level
LK.setTimeout(function () {
startLevel(currentLevel + 1);
}, 2000);
}
} else {
LK.getSound('fall').play();
LK.showGameOver();
}
}
// Initialize game
initUI();
createLevelSelect();
// Game update loop
game.update = function () {
if (gameState === 'playing') {
// Handle stone tapping
if (targetStone && !playerMoving) {
var distance = Math.sqrt(Math.pow(targetStone.x - player.x, 2) + Math.pow(targetStone.y - player.y, 2));
if (distance < 200) {
// Within jumping range
LK.getSound('jump').play();
player.jumpTo(targetStone.x, targetStone.y, function () {
var success = targetStone.stepOn();
if (!success) {
gameOver(false);
} else {
// Check if reached end platform
var endDistance = Math.sqrt(Math.pow(endPlatform.x - player.x, 2) + Math.pow(endPlatform.y - player.y, 2));
if (endDistance < 150) {
gameOver(true);
}
}
});
}
targetStone = null;
}
// Check if player can reach end platform directly
if (!playerMoving && endPlatform) {
var endDistance = Math.sqrt(Math.pow(endPlatform.x - player.x, 2) + Math.pow(endPlatform.y - player.y, 2));
if (endDistance < 200) {
// Allow direct jump to end platform
if (LK.ticks % 10 === 0) {
instructionText.setText('Tap end platform to finish!');
}
}
}
}
};
// Handle direct clicks on end platform
game.down = function (x, y, obj) {
if (gameState === 'playing' && !playerMoving && endPlatform) {
var endDistance = Math.sqrt(Math.pow(endPlatform.x - player.x, 2) + Math.pow(endPlatform.y - player.y, 2));
if (endDistance < 200) {
// Check if click is on end platform
var localPos = endPlatform.toLocal({
x: x,
y: y
});
if (Math.abs(localPos.x) < 100 && Math.abs(localPos.y) < 50) {
LK.getSound('jump').play();
player.jumpTo(endPlatform.x, endPlatform.y - 50, function () {
gameOver(true);
});
}
}
}
};