Code edit (1 edits merged)
Please save this source code
User prompt
Choo Choo Express Builder
Initial prompt
Toca train 🚂 (2012). Tap on the tutorial button or the build track button to get started, tap on the train 🚂 to start chugging, tap on the whistle to make it go Choo Choo, make it to the clouds in the air, the river with boats, and tunnel, make it to reach the train station
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var Boat = Container.expand(function () { var self = Container.call(this); var boatGraphics = self.attachAsset('boat', { anchorX: 0.5, anchorY: 0.5 }); self.floatSpeed = 1; self.update = function () { self.x += self.floatSpeed; if (self.x > 2048 + 40) { self.x = -40; } }; return self; }); var Cloud = Container.expand(function () { var self = Container.call(this); var cloudGraphics = self.attachAsset('cloud', { anchorX: 0.5, anchorY: 0.5 }); self.driftSpeed = 0.5; self.update = function () { self.x += self.driftSpeed; if (self.x > 2048 + 60) { self.x = -60; } }; return self; }); var TrackPiece = Container.expand(function () { var self = Container.call(this); var trackGraphics = self.attachAsset('track', { anchorX: 0.5, anchorY: 0.5 }); self.isPlaced = false; return self; }); var Train = Container.expand(function () { var self = Container.call(this); var trainGraphics = self.attachAsset('train', { anchorX: 0.5, anchorY: 0.5 }); self.isMoving = false; self.speed = 3; self.targetX = 0; self.targetY = 0; self.currentTrackIndex = 0; self.down = function (x, y, obj) { if (!self.isMoving && trackPieces.length > 0) { self.isMoving = true; self.currentTrackIndex = 0; self.moveToNextTrack(); } }; self.moveToNextTrack = function () { if (self.currentTrackIndex < trackPieces.length) { var track = trackPieces[self.currentTrackIndex]; self.targetX = track.x; self.targetY = track.y; } else { // Reached the end self.isMoving = false; if (self.targetX >= station.x - 50 && self.targetX <= station.x + 50) { // Reached station LK.effects.flashObject(station, 0x00FF00, 1000); LK.setScore(LK.getScore() + 10); scoreText.setText('Score: ' + LK.getScore()); } } }; self.update = function () { if (self.isMoving && trackPieces.length > 0) { var dx = self.targetX - self.x; var dy = self.targetY - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 5) { self.x += dx / distance * self.speed; self.y += dy / distance * self.speed; } else { self.currentTrackIndex++; self.moveToNextTrack(); } } }; return self; }); var Whistle = Container.expand(function () { var self = Container.call(this); var whistleGraphics = self.attachAsset('whistle', { anchorX: 0.5, anchorY: 0.5 }); self.down = function (x, y, obj) { LK.getSound('choo').play(); tween(self, { scaleX: 1.2, scaleY: 1.2 }, { duration: 200 }); tween(self, { scaleX: 1.0, scaleY: 1.0 }, { duration: 200 }); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x87CEEB }); /**** * Game Code ****/ var trackPieces = []; var clouds = []; var boats = []; var isBuilding = true; var tutorialStep = 0; // Create scenery var river = game.addChild(LK.getAsset('river', { anchorX: 0, anchorY: 0, x: 0, y: 1800 })); var tunnel = game.addChild(LK.getAsset('tunnel', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 1200 })); var station = game.addChild(LK.getAsset('station', { anchorX: 0.5, anchorY: 0.5, x: 1700, y: 2400 })); // Create clouds for (var i = 0; i < 5; i++) { var cloud = game.addChild(new Cloud()); cloud.x = Math.random() * 2048; cloud.y = 200 + Math.random() * 300; cloud.driftSpeed = 0.2 + Math.random() * 0.8; clouds.push(cloud); } // Create boats for (var j = 0; j < 3; j++) { var boat = game.addChild(new Boat()); boat.x = Math.random() * 2048; boat.y = 1850; boat.floatSpeed = 0.5 + Math.random() * 1; boats.push(boat); } // Create train var train = game.addChild(new Train()); train.x = 200; train.y = 2200; // Create whistle button var whistle = game.addChild(new Whistle()); whistle.x = 150; whistle.y = 150; // Create UI var scoreText = new Text2('Score: 0', { size: 60, fill: 0xFFFFFF }); scoreText.anchor.set(0.5, 0); LK.gui.top.addChild(scoreText); var instructionText = new Text2('Tap to place tracks!', { size: 50, fill: 0xFFFFFF }); instructionText.anchor.set(0.5, 0); instructionText.y = 80; LK.gui.top.addChild(instructionText); var modeText = new Text2('Building Mode', { size: 40, fill: 0xFFFF00 }); modeText.anchor.set(0.5, 1); LK.gui.bottom.addChild(modeText); // Game event handlers game.down = function (x, y, obj) { if (isBuilding) { // Place track piece var newTrack = game.addChild(new TrackPiece()); newTrack.x = x; newTrack.y = y; newTrack.isPlaced = true; trackPieces.push(newTrack); LK.getSound('place').play(); // Update instruction based on progress if (trackPieces.length === 1) { instructionText.setText('Great! Keep building your track!'); } else if (trackPieces.length === 5) { instructionText.setText('Tap the train to start its journey!'); } else if (trackPieces.length === 10) { instructionText.setText('Build toward the blue station!'); } // Check if player has built enough track if (trackPieces.length >= 3) { modeText.setText('Tap train to start journey!'); } } }; // Main game loop game.update = function () { // Update train movement if (train.isMoving) { // Check if train reached station var distanceToStation = Math.sqrt(Math.pow(train.x - station.x, 2) + Math.pow(train.y - station.y, 2)); if (distanceToStation < 100) { train.isMoving = false; LK.effects.flashScreen(0x00FF00, 500); LK.setScore(LK.getScore() + 50); scoreText.setText('Score: ' + LK.getScore()); instructionText.setText('Train reached station! Tap to build new track!'); // Reset for new round LK.setTimeout(function () { // Clear old tracks for (var i = trackPieces.length - 1; i >= 0; i--) { trackPieces[i].destroy(); } trackPieces = []; // Reset train position train.x = 200; train.y = 2200; train.isMoving = false; train.currentTrackIndex = 0; instructionText.setText('Build a new track!'); modeText.setText('Building Mode'); isBuilding = true; }, 2000); } } // Animate whistle button whistle.y = 150 + Math.sin(LK.ticks * 0.1) * 5; // Update score display if (LK.ticks % 60 === 0) { LK.setScore(LK.getScore() + 1); scoreText.setText('Score: ' + LK.getScore()); } };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Boat = Container.expand(function () {
var self = Container.call(this);
var boatGraphics = self.attachAsset('boat', {
anchorX: 0.5,
anchorY: 0.5
});
self.floatSpeed = 1;
self.update = function () {
self.x += self.floatSpeed;
if (self.x > 2048 + 40) {
self.x = -40;
}
};
return self;
});
var Cloud = Container.expand(function () {
var self = Container.call(this);
var cloudGraphics = self.attachAsset('cloud', {
anchorX: 0.5,
anchorY: 0.5
});
self.driftSpeed = 0.5;
self.update = function () {
self.x += self.driftSpeed;
if (self.x > 2048 + 60) {
self.x = -60;
}
};
return self;
});
var TrackPiece = Container.expand(function () {
var self = Container.call(this);
var trackGraphics = self.attachAsset('track', {
anchorX: 0.5,
anchorY: 0.5
});
self.isPlaced = false;
return self;
});
var Train = Container.expand(function () {
var self = Container.call(this);
var trainGraphics = self.attachAsset('train', {
anchorX: 0.5,
anchorY: 0.5
});
self.isMoving = false;
self.speed = 3;
self.targetX = 0;
self.targetY = 0;
self.currentTrackIndex = 0;
self.down = function (x, y, obj) {
if (!self.isMoving && trackPieces.length > 0) {
self.isMoving = true;
self.currentTrackIndex = 0;
self.moveToNextTrack();
}
};
self.moveToNextTrack = function () {
if (self.currentTrackIndex < trackPieces.length) {
var track = trackPieces[self.currentTrackIndex];
self.targetX = track.x;
self.targetY = track.y;
} else {
// Reached the end
self.isMoving = false;
if (self.targetX >= station.x - 50 && self.targetX <= station.x + 50) {
// Reached station
LK.effects.flashObject(station, 0x00FF00, 1000);
LK.setScore(LK.getScore() + 10);
scoreText.setText('Score: ' + LK.getScore());
}
}
};
self.update = function () {
if (self.isMoving && trackPieces.length > 0) {
var dx = self.targetX - self.x;
var dy = self.targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 5) {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
} else {
self.currentTrackIndex++;
self.moveToNextTrack();
}
}
};
return self;
});
var Whistle = Container.expand(function () {
var self = Container.call(this);
var whistleGraphics = self.attachAsset('whistle', {
anchorX: 0.5,
anchorY: 0.5
});
self.down = function (x, y, obj) {
LK.getSound('choo').play();
tween(self, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 200
});
tween(self, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 200
});
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB
});
/****
* Game Code
****/
var trackPieces = [];
var clouds = [];
var boats = [];
var isBuilding = true;
var tutorialStep = 0;
// Create scenery
var river = game.addChild(LK.getAsset('river', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 1800
}));
var tunnel = game.addChild(LK.getAsset('tunnel', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1200
}));
var station = game.addChild(LK.getAsset('station', {
anchorX: 0.5,
anchorY: 0.5,
x: 1700,
y: 2400
}));
// Create clouds
for (var i = 0; i < 5; i++) {
var cloud = game.addChild(new Cloud());
cloud.x = Math.random() * 2048;
cloud.y = 200 + Math.random() * 300;
cloud.driftSpeed = 0.2 + Math.random() * 0.8;
clouds.push(cloud);
}
// Create boats
for (var j = 0; j < 3; j++) {
var boat = game.addChild(new Boat());
boat.x = Math.random() * 2048;
boat.y = 1850;
boat.floatSpeed = 0.5 + Math.random() * 1;
boats.push(boat);
}
// Create train
var train = game.addChild(new Train());
train.x = 200;
train.y = 2200;
// Create whistle button
var whistle = game.addChild(new Whistle());
whistle.x = 150;
whistle.y = 150;
// Create UI
var scoreText = new Text2('Score: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreText.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreText);
var instructionText = new Text2('Tap to place tracks!', {
size: 50,
fill: 0xFFFFFF
});
instructionText.anchor.set(0.5, 0);
instructionText.y = 80;
LK.gui.top.addChild(instructionText);
var modeText = new Text2('Building Mode', {
size: 40,
fill: 0xFFFF00
});
modeText.anchor.set(0.5, 1);
LK.gui.bottom.addChild(modeText);
// Game event handlers
game.down = function (x, y, obj) {
if (isBuilding) {
// Place track piece
var newTrack = game.addChild(new TrackPiece());
newTrack.x = x;
newTrack.y = y;
newTrack.isPlaced = true;
trackPieces.push(newTrack);
LK.getSound('place').play();
// Update instruction based on progress
if (trackPieces.length === 1) {
instructionText.setText('Great! Keep building your track!');
} else if (trackPieces.length === 5) {
instructionText.setText('Tap the train to start its journey!');
} else if (trackPieces.length === 10) {
instructionText.setText('Build toward the blue station!');
}
// Check if player has built enough track
if (trackPieces.length >= 3) {
modeText.setText('Tap train to start journey!');
}
}
};
// Main game loop
game.update = function () {
// Update train movement
if (train.isMoving) {
// Check if train reached station
var distanceToStation = Math.sqrt(Math.pow(train.x - station.x, 2) + Math.pow(train.y - station.y, 2));
if (distanceToStation < 100) {
train.isMoving = false;
LK.effects.flashScreen(0x00FF00, 500);
LK.setScore(LK.getScore() + 50);
scoreText.setText('Score: ' + LK.getScore());
instructionText.setText('Train reached station! Tap to build new track!');
// Reset for new round
LK.setTimeout(function () {
// Clear old tracks
for (var i = trackPieces.length - 1; i >= 0; i--) {
trackPieces[i].destroy();
}
trackPieces = [];
// Reset train position
train.x = 200;
train.y = 2200;
train.isMoving = false;
train.currentTrackIndex = 0;
instructionText.setText('Build a new track!');
modeText.setText('Building Mode');
isBuilding = true;
}, 2000);
}
}
// Animate whistle button
whistle.y = 150 + Math.sin(LK.ticks * 0.1) * 5;
// Update score display
if (LK.ticks % 60 === 0) {
LK.setScore(LK.getScore() + 1);
scoreText.setText('Score: ' + LK.getScore());
}
};