User prompt
undo that
User prompt
get rid of the image for when you are down (tap to get up) and die when the counter reaches zero
Code edit (1 edits merged)
Please save this source code
User prompt
Stop the game when you fall over, (stop it from moving) and make the player have to tap the screen in labeled places 5 times in 15 seconds.
User prompt
Make it so when you hit an object you don’t die, you fall over, then you wait 5 seconds before getting up and continuing. The distance also resets at this ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Add the feature above
User prompt
Add a enable debugging feature in the settings, but to turn it on you have to type the developer’s name (which it will ask you to do) which is Chazlin
User prompt
Make different music depending on what game mode you are playing
User prompt
Please fix the bug: 'Script error.' in or related to this line: 'LK.showLeaderboard();' Line Number: 408
User prompt
Please fix the bug: 'Script error.' in or related to this line: 'storage.showLeaderboard();' Line Number: 408
User prompt
Please fix the bug: 'Script error.' in or related to this line: 'LK.showLeaderboard();' Line Number: 407
User prompt
Add a setting bar in the menu which has an option to turn sound off, sfx off, game test codes, leaderboard, and language settings ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Make it stop in all levels from spawning obstacles across all three lanes very closely
User prompt
Make the no don’t do it etc mode actually possible to win and add in the enemies moving 4x faster than you
User prompt
Make a “No don’t do it I’m scared help” mode where the player is half the speed, and everything else is doubled. Everything is covered by a reddish colour and all the text is in welsh until the game is reloaded ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Add a “winning zone” where you win after reaching 1000 distance on Hard, 2000 on average Joe, and 5000 on Easy
User prompt
Add a Hard Mode where there are more obstacles, and double the enemies
User prompt
Make the easy mode button green, bigger, and make the normal mode button orange, bigger, and change the normal mode to “Average Joe”
User prompt
Make the lane rider sign at the top, huge and in an appealing font, and make the other items bigger and more spaced apart ON THE START SCREEN
User prompt
Create a start menu with an easy mode button that removes the character that chases you
User prompt
When moving lanes, make the player hit the sprite it could collide with then kill the player
User prompt
Add in a sprite that swerves all over the lanes yet slowly chases you when you get close enough and add a stopwatch to see how long you survive ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Make the character move a bit quicker
Code edit (1 edits merged)
Please save this source code
User prompt
Lane Rider: Bike Rush
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var EnemyChaser = Container.expand(function () {
var self = Container.call(this);
// Enemy state
self.lane = 1; // Start in middle lane
self.speed = GAME_SPEED * 0.8; // Slightly slower than player initially
self.targetX = LANE_POSITIONS[self.lane];
self.chasingPlayer = false;
self.swerveTimer = 0;
self.swerveInterval = 120; // Time between lane changes when not chasing
self.detectionRange = 500; // Distance to start chasing player
// Create enemy graphics
var graphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5,
tint: 0xFF0000 // Red tint to distinguish from player
});
// Random swerving behavior
self.swerve = function () {
var newLane;
// Choose a random lane that's different from current
do {
newLane = Math.floor(Math.random() * 3);
} while (newLane === self.lane);
self.moveToLane(newLane);
};
// Chase player behavior
self.chase = function () {
// Move toward player's lane
if (self.lane < player.lane) {
self.moveToLane(self.lane + 1);
} else if (self.lane > player.lane) {
self.moveToLane(self.lane - 1);
}
};
// Move enemy to lane
self.moveToLane = function (laneIndex) {
if (laneIndex < 0 || laneIndex > 2) {
return;
}
self.lane = laneIndex;
self.targetX = LANE_POSITIONS[laneIndex];
tween.stop(self, {
x: true
});
tween(self, {
x: self.targetX
}, {
duration: 300,
easing: tween.easeOut
});
};
self.update = function () {
// Move forward
// In scared mode, enemies move 4x faster than player
if (scaredMode) {
self.y += self.speed * 4;
} else {
self.y += self.speed;
}
// Check if close enough to chase player
var distanceToPlayer = Math.abs(player.y - self.y);
self.chasingPlayer = distanceToPlayer < self.detectionRange;
// Update behavior based on proximity to player
if (self.chasingPlayer) {
// Chase every 60 frames when close (or faster in scared mode)
if (LK.ticks % (scaredMode ? 30 : 60) === 0) {
self.chase();
}
// Speed up when chasing
self.speed = Math.min(GAME_SPEED * 1.1, MAX_GAME_SPEED);
} else {
// Random swerving when not chasing
self.swerveTimer++;
if (self.swerveTimer >= self.swerveInterval) {
self.swerve();
self.swerveTimer = 0;
// Randomize next swerve interval
self.swerveInterval = 90 + Math.floor(Math.random() * 90);
}
// Normal speed when not chasing
self.speed = GAME_SPEED * 0.8;
}
// Reset enemy if it goes off screen
if (self.y > 2732 + graphics.height) {
self.y = -300;
self.swerveTimer = 0;
}
};
return self;
});
var Obstacle = Container.expand(function (type) {
var self = Container.call(this);
self.type = type || 'car';
self.lane = Math.floor(Math.random() * 3); // Random lane (0, 1, 2)
self.speed = GAME_SPEED;
var assetType;
switch (self.type) {
case 'car':
assetType = 'car';
break;
case 'pedestrian':
assetType = 'pedestrian';
break;
case 'pothole':
assetType = 'pothole';
break;
case 'construction':
assetType = 'construction';
break;
default:
assetType = 'car';
}
var graphics = self.attachAsset(assetType, {
anchorX: 0.5,
anchorY: 0.5
});
self.update = function () {
self.y += self.speed;
// Mark for removal if off screen
if (self.y > 2732 + graphics.height) {
self.markedForRemoval = true;
}
};
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
var playerGraphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
// Player state
self.lane = 1; // Middle lane
self.isInvincible = false;
self.invincibleTimer = null;
// Move player to lane
self.moveToLane = function (laneIndex) {
if (laneIndex < 0 || laneIndex > 2) {
return;
}
self.lane = laneIndex;
var targetX = LANE_POSITIONS[laneIndex];
tween.stop(self, {
x: true
});
tween(self, {
x: targetX
}, {
duration: self.moveSpeed || 150,
// Use moveSpeed if set (for scared mode)
easing: tween.easeOut
});
};
// Make player invincible for a duration
self.setInvincible = function (duration) {
self.isInvincible = true;
playerGraphics.tint = 0x2ECC71; // Green tint
if (self.invincibleTimer) {
LK.clearTimeout(self.invincibleTimer);
}
self.invincibleTimer = LK.setTimeout(function () {
self.isInvincible = false;
playerGraphics.tint = 0xFFFFFF; // Reset tint
}, duration);
};
return self;
});
var PowerUp = Container.expand(function () {
var self = Container.call(this);
self.lane = Math.floor(Math.random() * 3); // Random lane (0, 1, 2)
self.speed = GAME_SPEED;
var graphics = self.attachAsset('powerup', {
anchorX: 0.5,
anchorY: 0.5
});
// Add pulsing animation
function pulse() {
tween(graphics, {
scale: 1.2
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(graphics, {
scale: 1.0
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: pulse
});
}
});
}
pulse();
self.update = function () {
self.y += self.speed;
// Mark for removal if off screen
if (self.y > 2732 + graphics.height) {
self.markedForRemoval = true;
}
};
return self;
});
var SettingsMenu = Container.expand(function () {
var self = Container.call(this);
// Load settings from storage (with defaults)
var settings = {
sound: storage.sound !== undefined ? storage.sound : true,
sfx: storage.sfx !== undefined ? storage.sfx : true,
language: storage.language || 'en',
testCodes: storage.testCodes || false
};
// Create background panel
var panel = LK.getAsset('construction', {
anchorX: 0.5,
anchorY: 0.5,
width: 1200,
height: 1100,
tint: 0x333333
});
self.addChild(panel);
// Create title
var title = new Text2('SETTINGS', {
size: 100,
fill: 0xFFFFFF,
font: "'GillSans-Bold',Impact,'Arial Black',Tahoma"
});
title.anchor.set(0.5, 0.5);
title.y = -400;
self.addChild(title);
// Helper function to create toggle buttons
function createToggleButton(labelText, _isOn, y, callback) {
var container = new Container();
container.y = y;
self.addChild(container);
// Label
var label = new Text2(labelText, {
size: 70,
fill: 0xFFFFFF
});
label.anchor.set(0, 0.5);
label.x = -450;
container.addChild(label);
// Toggle button background
var toggleBg = LK.getAsset('lane', {
anchorX: 0.5,
anchorY: 0.5,
width: 200,
height: 100,
tint: 0x666666
});
toggleBg.x = 350;
container.addChild(toggleBg);
// Toggle indicator
var toggleIndicator = LK.getAsset('centerCircle', {
anchorX: 0.5,
anchorY: 0.5,
width: 80,
height: 80,
tint: _isOn ? 0x00CC00 : 0xCC0000
});
toggleIndicator.x = 350 + (_isOn ? 40 : -40);
container.addChild(toggleIndicator);
// Status text
var statusText = new Text2(_isOn ? "ON" : "OFF", {
size: 50,
fill: 0xFFFFFF
});
statusText.anchor.set(0.5, 0.5);
statusText.x = 350;
container.addChild(statusText);
// Make toggle interactive
toggleBg.interactive = true;
toggleIndicator.interactive = true;
statusText.interactive = true;
// Toggle functionality
function toggle() {
_isOn = !_isOn;
toggleIndicator.tint = _isOn ? 0x00CC00 : 0xCC0000;
toggleIndicator.x = 350 + (_isOn ? 40 : -40);
statusText.setText(_isOn ? "ON" : "OFF");
if (callback) {
callback(_isOn);
}
}
toggleBg.down = toggleIndicator.down = statusText.down = toggle;
return {
container: container,
toggle: toggle,
isOn: function isOn() {
return _isOn;
}
};
}
// Helper function to create language selector
function createLanguageSelector(y) {
var container = new Container();
container.y = y;
self.addChild(container);
// Label
var label = new Text2("Language", {
size: 70,
fill: 0xFFFFFF
});
label.anchor.set(0, 0.5);
label.x = -450;
container.addChild(label);
// Language options
var languages = ["English", "Welsh"];
var currentLang = settings.language === "cy" ? 1 : 0;
// Create language button
var langButton = LK.getAsset('lane', {
anchorX: 0.5,
anchorY: 0.5,
width: 300,
height: 100,
tint: 0x4488FF
});
langButton.x = 350;
container.addChild(langButton);
// Language text
var langText = new Text2(languages[currentLang], {
size: 50,
fill: 0xFFFFFF
});
langText.anchor.set(0.5, 0.5);
langText.x = 350;
container.addChild(langText);
// Make language button interactive
langButton.interactive = true;
langText.interactive = true;
// Toggle functionality
function toggle() {
currentLang = (currentLang + 1) % languages.length;
langText.setText(languages[currentLang]);
settings.language = currentLang === 0 ? "en" : "cy";
storage.language = settings.language;
}
langButton.down = langText.down = toggle;
return container;
}
// Create setting toggles
var soundToggle = createToggleButton("Music", settings.sound, -300, function (isOn) {
settings.sound = isOn;
storage.sound = isOn;
if (isOn) {
LK.playMusic('gameMusic');
} else {
LK.stopMusic();
}
});
var sfxToggle = createToggleButton("Sound Effects", settings.sfx, -200, function (isOn) {
settings.sfx = isOn;
storage.sfx = isOn;
});
var testCodesToggle = createToggleButton("Test Codes", settings.testCodes, -100, function (isOn) {
settings.testCodes = isOn;
storage.testCodes = isOn;
});
// Create language selector
var languageSelector = createLanguageSelector(0);
// Create leaderboard button
var leaderboardBtn = LK.getAsset('lane', {
anchorX: 0.5,
anchorY: 0.5,
width: 600,
height: 120,
tint: 0x4444FF
});
leaderboardBtn.y = 100;
self.addChild(leaderboardBtn);
var leaderboardText = new Text2("Leaderboard", {
size: 70,
fill: 0xFFFFFF
});
leaderboardText.anchor.set(0.5, 0.5);
leaderboardText.y = 100;
self.addChild(leaderboardText);
// Leaderboard button functionality
leaderboardBtn.interactive = true;
leaderboardText.interactive = true;
leaderboardBtn.down = leaderboardText.down = function () {
// Using storage plugin instead of direct LK.showLeaderboard call
storage.showLeaderboard();
};
// Create back button
var backBtn = LK.getAsset('lane', {
anchorX: 0.5,
anchorY: 0.5,
width: 300,
height: 120,
tint: 0xCC4444
});
backBtn.y = 250;
self.addChild(backBtn);
var backText = new Text2("Back", {
size: 70,
fill: 0xFFFFFF
});
backText.anchor.set(0.5, 0.5);
backText.y = 250;
self.addChild(backText);
// Back button functionality
backBtn.interactive = true;
backText.interactive = true;
backBtn.down = backText.down = function () {
self.visible = false;
startMenu.visible = true;
};
// Public method to apply settings
self.applySettings = function () {
// Apply sound settings
if (!settings.sound) {
LK.stopMusic();
}
};
// Method to check if SFX is enabled
self.isSfxEnabled = function () {
return settings.sfx;
};
return self;
});
var StartMenu = Container.expand(function () {
var self = Container.call(this);
// Create background panel
var panel = LK.getAsset('construction', {
anchorX: 0.5,
anchorY: 0.5,
width: 1200,
height: 1000,
// Increased height for settings button
tint: 0x333333
});
self.addChild(panel);
// Create title
var title = new Text2('LANE RIDER', {
size: 180,
fill: 0xFFFFFF,
font: "'GillSans-Bold',Impact,'Arial Black',Tahoma"
});
title.anchor.set(0.5, 0.5);
title.y = -250; // Adjusted position
self.addChild(title);
// Create normal mode button (now "Average Joe")
var normalBtn = LK.getAsset('lane', {
anchorX: 0.5,
anchorY: 0.5,
width: 700,
height: 180,
tint: 0xFF8C00
});
normalBtn.y = 0; // Adjusted position
self.addChild(normalBtn);
var normalText = new Text2('Average Joe', {
size: 90,
fill: 0xFFFFFF
});
normalText.anchor.set(0.5, 0.5);
normalText.y = 0; // Adjusted position
self.addChild(normalText);
// Create easy mode button
var easyBtn = LK.getAsset('lane', {
anchorX: 0.5,
anchorY: 0.5,
width: 700,
height: 180,
tint: 0x00CC00
});
easyBtn.y = 200; // Adjusted position
self.addChild(easyBtn);
var easyText = new Text2('Easy Mode', {
size: 90,
fill: 0xFFFFFF
});
easyText.anchor.set(0.5, 0.5);
easyText.y = 200; // Adjusted position
self.addChild(easyText);
// Create hard mode button
var hardBtn = LK.getAsset('lane', {
anchorX: 0.5,
anchorY: 0.5,
width: 700,
height: 180,
tint: 0xFF0000
});
hardBtn.y = 400; // Adjusted position
self.addChild(hardBtn);
var hardText = new Text2('Hard Mode', {
size: 90,
fill: 0xFFFFFF
});
hardText.anchor.set(0.5, 0.5);
hardText.y = 400; // Adjusted position
self.addChild(hardText);
// Create scared mode button
var scaredBtn = LK.getAsset('lane', {
anchorX: 0.5,
anchorY: 0.5,
width: 700,
height: 180,
tint: 0x800080 // Purple tint
});
scaredBtn.y = 600; // Adjusted position
self.addChild(scaredBtn);
var scaredText = new Text2('NO DONT DO IT IM SCARED', {
size: 50,
fill: 0xFFFFFF
});
scaredText.anchor.set(0.5, 0.5);
scaredText.y = 600; // Adjusted position
self.addChild(scaredText);
// Create settings button
var settingsBtn = LK.getAsset('lane', {
anchorX: 0.5,
anchorY: 0.5,
width: 700,
height: 180,
tint: 0x00AAAA // Teal color
});
settingsBtn.y = 800; // Position below other buttons
self.addChild(settingsBtn);
var settingsText = new Text2('Settings', {
size: 90,
fill: 0xFFFFFF
});
settingsText.anchor.set(0.5, 0.5);
settingsText.y = 800;
self.addChild(settingsText);
// Add interaction for normal mode
normalBtn.interactive = true;
normalBtn.down = normalText.down = function () {
self.visible = false;
easyMode = false;
hardMode = false;
startGame();
};
// Add interaction for easy mode
easyBtn.interactive = true;
easyBtn.down = easyText.down = function () {
self.visible = false;
easyMode = true;
hardMode = false;
startGame();
};
// Add interaction for hard mode
hardBtn.interactive = true;
hardBtn.down = hardText.down = function () {
self.visible = false;
easyMode = false;
hardMode = true;
scaredMode = false;
startGame();
};
// Add interaction for scared mode
scaredBtn.interactive = true;
scaredBtn.down = scaredText.down = function () {
self.visible = false;
easyMode = false;
hardMode = false;
scaredMode = true;
startGame();
};
// Add interaction for settings button
settingsBtn.interactive = true;
settingsText.interactive = true;
settingsBtn.down = settingsText.down = function () {
self.visible = false;
settingsMenu.visible = true;
};
return self;
});
var WinningZone = Container.expand(function () {
var self = Container.call(this);
self.width = 2048;
self.height = 300;
// Create background for winning zone
var background = LK.getAsset('lane', {
anchorX: 0.5,
anchorY: 0.5,
width: self.width,
height: self.height,
tint: 0xFFD700 // Gold color
});
self.addChild(background);
// Create winning text
var winText = new Text2(scaredMode ? welshTranslations['FINISH LINE'] : 'FINISH LINE', {
size: 100,
fill: 0x000000
});
winText.anchor.set(0.5, 0.5);
self.addChild(winText);
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x7DCEA0 // Greenish background
});
/****
* Game Code
****/
// Constants
var LANE_WIDTH = 2048 / 3;
var LANE_POSITIONS = [LANE_WIDTH / 2, LANE_WIDTH + LANE_WIDTH / 2, 2 * LANE_WIDTH + LANE_WIDTH / 2];
var MIN_OBSTACLE_INTERVAL = 60;
var MAX_OBSTACLE_INTERVAL = 120;
var GAME_SPEED = 6;
var MAX_GAME_SPEED = 15;
var SPEED_INCREASE_RATE = 0.0005;
var OBSTACLE_TYPES = ['car', 'pedestrian', 'pothole', 'construction'];
var POWERUP_CHANCE = 0.1; // 10% chance per obstacle spawn
var INVINCIBLE_DURATION = 5000; // 5 seconds (base value)
// Game variables
var player;
var enemy;
var secondEnemy; // Second enemy for hard mode
var obstacles = [];
var powerups = [];
var lanes = [];
var obstacleTimer = 0;
var nextObstacleTime = 100;
var distance = 0;
var highScore = storage.highScore || 0;
var isGameStarted = false;
var gameStartTime = 0;
var currentTime = 0;
var easyMode = false;
var hardMode = false;
var scaredMode = false; // New scared mode
var startMenu;
var settingsMenu;
var winningZone;
var winningDistance = 0; // Distance required to win based on difficulty
var redOverlay; // Reddish overlay for scared mode
// Welsh translations for scared mode
var welshTranslations = {
'Distance': 'Pellter',
'Best': 'Gorau',
'Time': 'Amser',
'Tap to start': 'Tapiwch i ddechrau',
'Swipe left/right to change lanes': 'Swipiwch chwith/dde i newid lonydd',
'FINISH LINE': 'LLINELL DERFYN',
'Easy Mode': 'Modd Hawdd',
'Average Joe': 'Joe Cyffredin',
'Hard Mode': 'Modd Caled',
'LANE RIDER': 'RIDER LÔN',
'NO DONT DO IT IM SCARED': 'PEIDIWCH Â GWNEUD OFNAIS WYFI'
};
// GUI elements
var scoreTxt;
var highScoreTxt;
var timeTxt;
var startInstructions;
// Initialize game UI
function initUI() {
// Create score display
scoreTxt = new Text2('Distance: 0', {
size: 70,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
scoreTxt.visible = false;
LK.gui.top.addChild(scoreTxt);
// Create high score display
highScoreTxt = new Text2('Best: ' + highScore, {
size: 50,
fill: 0xFFFFFF
});
highScoreTxt.anchor.set(0.5, 0);
highScoreTxt.y = 80;
highScoreTxt.visible = false;
LK.gui.top.addChild(highScoreTxt);
// Create stopwatch display
timeTxt = new Text2('Time: 0.0s', {
size: 50,
fill: 0xFFFFFF
});
timeTxt.anchor.set(0.5, 0);
timeTxt.y = 150;
timeTxt.visible = false;
LK.gui.top.addChild(timeTxt);
// Create start instructions
startInstructions = new Text2('Tap to start\nSwipe left/right to change lanes', {
size: 80,
fill: 0xFFFFFF
});
startInstructions.anchor.set(0.5, 0.5);
startInstructions.visible = false;
LK.gui.center.addChild(startInstructions);
}
// Initialize game world
function initWorld() {
// Create the three lanes
for (var i = 0; i < 3; i++) {
var lane = LK.getAsset('lane', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.3,
width: 20,
height: 2732
});
lane.x = (i + 1) * LANE_WIDTH;
game.addChild(lane);
lanes.push(lane);
}
// Create player
player = new Player();
player.x = LANE_POSITIONS[1]; // Start in middle lane
player.y = 2732 - 300; // Position near bottom of screen
game.addChild(player);
// Hide player initially
player.visible = false;
// Create enemy chaser
enemy = new EnemyChaser();
enemy.x = LANE_POSITIONS[1]; // Start in middle lane
enemy.y = -500; // Start above screen
game.addChild(enemy);
// Hide enemy initially
enemy.visible = false;
// Create second enemy chaser for hard mode
secondEnemy = new EnemyChaser();
secondEnemy.x = LANE_POSITIONS[0]; // Start in left lane
secondEnemy.y = -800; // Start above screen but offset from first enemy
game.addChild(secondEnemy);
// Hide second enemy initially
secondEnemy.visible = false;
// Create and display start menu
startMenu = new StartMenu();
startMenu.x = 2048 / 2;
startMenu.y = 2732 / 2;
game.addChild(startMenu);
// Create settings menu (hidden initially)
settingsMenu = new SettingsMenu();
settingsMenu.x = 2048 / 2;
settingsMenu.y = 2732 / 2;
settingsMenu.visible = false;
game.addChild(settingsMenu);
}
// Start the game
function startGame() {
isGameStarted = true;
player.visible = true;
// Show appropriate enemies based on game mode
enemy.visible = !easyMode && !scaredMode;
secondEnemy.visible = hardMode;
startInstructions.visible = true;
// Show UI elements
scoreTxt.visible = true;
highScoreTxt.visible = true;
timeTxt.visible = true;
// Reset game state
obstacles.forEach(function (obstacle) {
obstacle.destroy();
});
obstacles = [];
powerups.forEach(function (powerup) {
powerup.destroy();
});
powerups = [];
distance = 0;
// Handle scared mode speeds
if (scaredMode) {
GAME_SPEED = 3; // Half the normal speed
player.moveSpeed = 300; // Double the lane change time (slower movement)
// Make player start with invincibility to give them a better chance
player.setInvincible(10000); // 10 seconds of initial invincibility
// Create red overlay if it doesn't exist
if (!redOverlay) {
redOverlay = LK.getAsset('lane', {
anchorX: 0,
anchorY: 0,
width: 2048,
height: 2732,
tint: 0xFF0000
});
redOverlay.alpha = 0.3;
game.addChild(redOverlay);
} else {
redOverlay.visible = true;
}
// Translate text to Welsh for scared mode
scoreTxt.setText(welshTranslations['Distance'] + ': 0');
highScoreTxt.setText(welshTranslations['Best'] + ': ' + highScore);
timeTxt.setText(welshTranslations['Time'] + ': 0.0s');
startInstructions.setText(welshTranslations['Tap to start'] + '\n' + welshTranslations['Swipe left/right to change lanes']);
} else {
GAME_SPEED = hardMode ? 8 : 6; // Higher starting speed in hard mode
player.moveSpeed = 150; // Normal movement speed
// Hide red overlay if it exists
if (redOverlay) {
redOverlay.visible = false;
}
// Reset text to English
scoreTxt.setText('Distance: 0');
highScoreTxt.setText('Best: ' + highScore);
timeTxt.setText('Time: 0.0s');
startInstructions.setText('Tap to start\nSwipe left/right to change lanes');
}
obstacleTimer = 0;
nextObstacleTime = hardMode ? 70 : scaredMode ? 200 : 100; // Adjust obstacle intervals
// Set winning distance based on difficulty
if (hardMode) {
winningDistance = 1000;
} else if (easyMode) {
winningDistance = 5000;
} else if (scaredMode) {
winningDistance = 3000; // Scared mode winning distance
} else {
winningDistance = 2000; // Average Joe mode
}
// Reset enemy positions
enemy.y = -500;
enemy.lane = 1;
enemy.x = LANE_POSITIONS[1];
enemy.swerveTimer = 0;
// Reset second enemy
secondEnemy.y = -800;
secondEnemy.lane = 0;
secondEnemy.x = LANE_POSITIONS[0];
secondEnemy.swerveTimer = 50; // Offset timer so enemies don't swerve at the same time
// Reset stopwatch
gameStartTime = Date.now();
currentTime = 0;
// Play background music if enabled
if (storage.sound !== false) {
LK.playMusic('gameMusic');
}
// Apply settings
settingsMenu.applySettings();
}
// Spawn a new obstacle
function spawnObstacle() {
// Choose random obstacle type
var type = OBSTACLE_TYPES[Math.floor(Math.random() * OBSTACLE_TYPES.length)];
var obstacle = new Obstacle(type);
// Ensure obstacle is in a valid lane
obstacle.x = LANE_POSITIONS[obstacle.lane];
obstacle.y = -200; // Start above screen
obstacles.push(obstacle);
game.addChild(obstacle);
// In scared mode, spawn more obstacles
if (scaredMode && Math.random() < 0.8) {
// 80% chance of additional obstacle in scared mode
for (var i = 0; i < 2; i++) {
// Two more obstacles
var extraType = OBSTACLE_TYPES[Math.floor(Math.random() * OBSTACLE_TYPES.length)];
var extraObstacle = new Obstacle(extraType);
// Try to find an available lane
var freeLanes = [0, 1, 2].filter(function (lane) {
return !obstacles.some(function (obs) {
return obs.lane === lane && Math.abs(obs.y + 200) < 300;
});
});
if (freeLanes.length > 0) {
extraObstacle.lane = freeLanes[Math.floor(Math.random() * freeLanes.length)];
extraObstacle.x = LANE_POSITIONS[extraObstacle.lane];
extraObstacle.y = -200 - i * 150; // Stagger obstacles
obstacles.push(extraObstacle);
game.addChild(extraObstacle);
}
}
}
// In hard mode, possibly spawn a second obstacle in a different lane
else if (hardMode && Math.random() < 0.6) {
// 60% chance of additional obstacle
var secondType = OBSTACLE_TYPES[Math.floor(Math.random() * OBSTACLE_TYPES.length)];
var secondObstacle = new Obstacle(secondType);
// Make sure it's in a different lane
do {
secondObstacle.lane = Math.floor(Math.random() * 3);
} while (secondObstacle.lane === obstacle.lane);
secondObstacle.x = LANE_POSITIONS[secondObstacle.lane];
secondObstacle.y = -350; // Offset from first obstacle
obstacles.push(secondObstacle);
game.addChild(secondObstacle);
}
// Possibly spawn a power-up
if (Math.random() < (scaredMode ? POWERUP_CHANCE * 2 : POWERUP_CHANCE)) {
// 2x more powerups in scared mode
spawnPowerUp();
}
// Set next obstacle spawn time
nextObstacleTime = MIN_OBSTACLE_INTERVAL + Math.floor(Math.random() * (MAX_OBSTACLE_INTERVAL - MIN_OBSTACLE_INTERVAL));
// Reduce spawn interval as game progresses
nextObstacleTime = Math.max(nextObstacleTime * (1 - distance / 50000), MIN_OBSTACLE_INTERVAL);
// In scared mode, increase obstacle spawn time
if (scaredMode) {
nextObstacleTime = Math.floor(nextObstacleTime * 2); // Double the time between obstacles
}
// In hard mode, reduce obstacle spawn time further
else if (hardMode) {
nextObstacleTime = Math.floor(nextObstacleTime * 0.7);
}
}
// Spawn a power-up
function spawnPowerUp() {
var powerup = new PowerUp();
// Make sure power-up is not in same lane as last obstacle
var lastObstacle = obstacles[obstacles.length - 1];
do {
powerup.lane = Math.floor(Math.random() * 3);
} while (powerup.lane === lastObstacle.lane);
powerup.x = LANE_POSITIONS[powerup.lane];
powerup.y = -500; // Start above screen, after the obstacle
powerups.push(powerup);
game.addChild(powerup);
}
// Check collisions between player and obstacles/powerups
function checkCollisions() {
// Check obstacle collisions
for (var i = obstacles.length - 1; i >= 0; i--) {
var obstacle = obstacles[i];
if (player.lane === obstacle.lane && Math.abs(player.y - obstacle.y) < 100 && !player.isInvincible) {
// Collision detected - Move player toward obstacle first
tween.stop(player, {
x: true,
y: true
});
tween(player, {
y: obstacle.y,
x: obstacle.x
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
if (settingsMenu.isSfxEnabled()) {
LK.getSound('crash').play();
}
LK.effects.flashScreen(0xFF0000, 500);
// Update high score if needed
if (distance > highScore) {
highScore = Math.floor(distance);
storage.highScore = highScore;
highScoreTxt.setText(scaredMode ? welshTranslations['Best'] + ': ' + highScore : 'Best: ' + highScore);
}
// Game over
LK.showGameOver();
}
});
return;
}
}
// Check enemy collision (skip in easy mode)
if (!easyMode && player.lane === enemy.lane && Math.abs(player.y - enemy.y) < 100 && !player.isInvincible) {
// Collision detected - Move player toward enemy first
tween.stop(player, {
x: true,
y: true
});
tween(player, {
y: enemy.y,
x: enemy.x
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
if (settingsMenu.isSfxEnabled()) {
LK.getSound('crash').play();
}
LK.effects.flashScreen(0xFF0000, 500);
// Update high score if needed
if (distance > highScore) {
highScore = Math.floor(distance);
storage.highScore = highScore;
highScoreTxt.setText('Best: ' + highScore);
}
// Game over
LK.showGameOver();
}
});
return;
}
// Check second enemy collision (hard mode only)
if (hardMode && player.lane === secondEnemy.lane && Math.abs(player.y - secondEnemy.y) < 100 && !player.isInvincible) {
// Collision detected - Move player toward second enemy first
tween.stop(player, {
x: true,
y: true
});
tween(player, {
y: secondEnemy.y,
x: secondEnemy.x
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
if (settingsMenu.isSfxEnabled()) {
LK.getSound('crash').play();
}
LK.effects.flashScreen(0xFF0000, 500);
// Update high score if needed
if (distance > highScore) {
highScore = Math.floor(distance);
storage.highScore = highScore;
highScoreTxt.setText('Best: ' + highScore);
}
// Game over
LK.showGameOver();
}
});
return;
}
// Check power-up collisions
for (var j = powerups.length - 1; j >= 0; j--) {
var powerup = powerups[j];
if (player.lane === powerup.lane && Math.abs(player.y - powerup.y) < 100) {
// Collect power-up
if (settingsMenu.isSfxEnabled()) {
LK.getSound('powerup').play();
}
// Apply power-up effect (invincibility) - longer in scared mode
player.setInvincible(scaredMode ? INVINCIBLE_DURATION * 3 : INVINCIBLE_DURATION); // 3x longer invincibility in scared mode
// Remove power-up
powerup.destroy();
powerups.splice(j, 1);
}
}
}
// Handle touch events for swiping
var touchStartX = 0;
game.down = function (x, y) {
if (!isGameStarted) {
return;
}
touchStartX = x;
};
game.up = function (x, y) {
if (!isGameStarted) {
return;
}
var swipeDistance = x - touchStartX;
// Determine swipe direction and move player
if (Math.abs(swipeDistance) > 50) {
// Minimum swipe distance threshold
if (swipeDistance > 0) {
// Swipe right
player.moveToLane(Math.min(player.lane + 1, 2));
} else {
// Swipe left
player.moveToLane(Math.max(player.lane - 1, 0));
}
}
};
// Main game update loop
game.update = function () {
if (!isGameStarted) {
return;
}
// Update stopwatch
currentTime = (Date.now() - gameStartTime) / 1000;
if (scaredMode) {
timeTxt.setText(welshTranslations['Time'] + ': ' + currentTime.toFixed(1) + 's');
// Increment distance at half the rate in scared mode
distance += GAME_SPEED / 20;
scoreTxt.setText(welshTranslations['Distance'] + ': ' + Math.floor(distance));
} else {
timeTxt.setText('Time: ' + currentTime.toFixed(1) + 's');
// Normal distance increment
distance += GAME_SPEED / 10;
scoreTxt.setText('Distance: ' + Math.floor(distance));
}
// Check for win condition
if (distance >= winningDistance) {
// Player has reached the required distance, show win
LK.showYouWin();
// Update high score if needed
if (distance > highScore) {
highScore = Math.floor(distance);
storage.highScore = highScore;
highScoreTxt.setText('Best: ' + highScore);
}
return;
}
// Display winning zone when approaching the finish
if (distance >= (scaredMode ? winningDistance - 1000 : winningDistance - 500) && !winningZone) {
winningZone = new WinningZone();
winningZone.x = 2048 / 2;
winningZone.y = -300; // Start off-screen
game.addChild(winningZone);
}
// Move winning zone toward player as they approach finish
if (winningZone) {
winningZone.y += GAME_SPEED;
}
// Gradually increase game speed
GAME_SPEED = Math.min(GAME_SPEED + SPEED_INCREASE_RATE, MAX_GAME_SPEED);
// Spawn obstacles
obstacleTimer++;
if (obstacleTimer >= nextObstacleTime) {
spawnObstacle();
obstacleTimer = 0;
}
// Update obstacles
for (var i = obstacles.length - 1; i >= 0; i--) {
var obstacle = obstacles[i];
obstacle.speed = scaredMode ? GAME_SPEED * 2 : GAME_SPEED; // Double speed in scared mode
// Remove obstacles marked for removal
if (obstacle.markedForRemoval) {
obstacle.destroy();
obstacles.splice(i, 1);
}
}
// Update power-ups
for (var j = powerups.length - 1; j >= 0; j--) {
var powerup = powerups[j];
powerup.speed = scaredMode ? GAME_SPEED * 2 : GAME_SPEED; // Double speed in scared mode
// Remove power-ups marked for removal
if (powerup.markedForRemoval) {
powerup.destroy();
powerups.splice(j, 1);
}
}
// Update enemy chasers (based on game mode)
if (!easyMode) {
enemy.update();
// Update second enemy in hard mode
if (hardMode) {
secondEnemy.update();
}
}
// Check for collisions
checkCollisions();
};
// Initialize UI and game world
initUI();
initWorld(); ===================================================================
--- original.js
+++ change.js
@@ -388,9 +388,10 @@
// Leaderboard button functionality
leaderboardBtn.interactive = true;
leaderboardText.interactive = true;
leaderboardBtn.down = leaderboardText.down = function () {
- LK.showLeaderboard();
+ // Using storage plugin instead of direct LK.showLeaderboard call
+ storage.showLeaderboard();
};
// Create back button
var backBtn = LK.getAsset('lane', {
anchorX: 0.5,
A 2D, Pixalted Bike with one wheel in front and one at the back with a pixelated character on.. In-Game asset. 2d. High contrast. No shadows
A gem, a diamond with an emerald colour. In-Game asset. 2d. High contrast. No shadows
A pedestrian, walking down the street facing forwards. In-Game asset. 2d. High contrast. No shadows
A tarmac road, with 3 lanes, matching up with actual game lanes. In-Game asset. 2d. High contrast. No shadows
A person running backwards. In-Game asset. 2d. High contrast. No shadows
Make a pothole like hole in the road. In-Game asset. 2d. High contrast. No shadows