/****
* Classes
****/
// Define the SmallObstacle class
var BigObstacle = Container.expand(function () {
var self = Container.call(this);
var obstacleGraphics = self.attachAsset('bigobstacle', {
anchorX: 0.5,
anchorY: 0.5,
tint: 0xa8ed15 // Apply tint #a8ed15
});
self.speed = gameSpeed;
self.update = function () {
self.y += self.speed;
if (self.y > 2732 + self.height / 2) {
self.destroy();
}
};
});
// Define the Coin class
var Coin = Container.expand(function () {
var self = Container.call(this);
var coinGraphics = self.attachAsset('coin', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = gameSpeed;
self.update = function () {
self.y += self.speed;
if (self.y > 2732 + self.height / 2) {
self.destroy();
}
// Floating effect
self.y += Math.sin(LK.ticks / 20) * 0.5;
// Size changing effect
self.scale.x = 1 + Math.sin(LK.ticks / 20) * 0.05;
self.scale.y = 1 + Math.sin(LK.ticks / 20) * 0.05;
};
});
// Define the LaneSeparator class
var LaneSeparator = Container.expand(function () {
var self = Container.call(this);
var separatorGraphics = self.attachAsset('lineobstacle', {
anchorX: 0.5,
anchorY: 0.0,
// Adjust anchor to top
width: 15,
height: 2732 // Set the height to cover the entire screen height
});
separatorGraphics.height = 2732; // Ensure the height covers the entire screen height
self.speed = gameSpeed;
self.update = function () {
self.y += self.speed;
if (self.y > 2732 + self.height / 2) {
self.destroy();
}
};
});
// Define the LeftLaneOutline class
var LeftLaneOutline = Container.expand(function () {
var self = Container.call(this);
var outlineGraphics = self.attachAsset('lineobstacle', {
anchorX: 0.5,
anchorY: 0.0,
width: 15,
height: 2732 // Set the height to cover the entire screen height
});
outlineGraphics.height = 2732; // Ensure the height covers the entire screen height
self.speed = gameSpeed;
self.update = function () {
self.y += self.speed;
if (self.y > 2732 + self.height / 2) {
self.destroy();
}
};
});
// Define the LeftPlayer class
var LeftPlayer = Container.expand(function () {
var self = Container.call(this);
var leftPlayerGraphics = self.attachAsset('leftplayer', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 15;
self.update = function () {
// Add any specific update logic for LeftPlayer here
if (LK.ticks % 4 == 0) {
var trail = new Trail();
trail.scale.x = 0.5;
trail.scale.y = 0.5;
if (self && self.x !== undefined) {
trail.x = self.x;
} else {
trail.x = 0;
}
trail.y = self && self.y !== undefined && self.height !== undefined ? self.y + self.height / 2 : 0;
game.addChildAt(trail, game.getChildIndex(self));
}
};
});
var LineObstacle = Container.expand(function () {
var self = Container.call(this);
var obstacleGraphics = self.attachAsset('obstacleline', {
anchorX: 0.5,
anchorY: 0.5,
tint: 0xa8ed15 // Apply tint #a8ed15
});
self.speed = gameSpeed;
self.update = function () {
self.y += self.speed;
if (self.y > 2732 + self.height / 2) {
self.destroy();
}
};
});
// Define the Obstacle class
var Obstacle = Container.expand(function () {
var self = Container.call(this);
var obstacleGraphics = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 0.5,
tint: 0xa8ed15 // Apply tint #a8ed15
});
self.speed = gameSpeed;
self.update = function () {
self.y += self.speed;
if (self.y > 2732 + self.height / 2) {
self.destroy();
}
};
});
// Define the Particle class
var Particle = Container.expand(function () {
var self = Container.call(this);
var particleGraphics = self.attachAsset('particle', {
anchorX: 0.5,
anchorY: 0.5,
tint: 0xffffff // Apply tint to particle graphics
});
self.speed = Math.random() * 5 + 2; // Random speed for each particle
self.direction = Math.random() * Math.PI * 2; // Random direction for each particle
self.update = function () {
self.x += Math.cos(self.direction) * self.speed; // Move the particle in the direction
self.y += Math.sin(self.direction) * self.speed;
self.alpha -= 0.01; // Fade out the particle
if (self.alpha <= 0) {
self.destroy();
}
};
self.setTint = function (color) {
particleGraphics.tint = color;
};
});
// Define the Player class
var Player = Container.expand(function () {
var self = Container.call(this);
var playerGraphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 15;
self.shield = null;
self.transitionToLane = function (targetX) {
self.isMoving = true;
self.targetX = targetX;
if (self.x < self.targetX) {
playerGraphics.rotation = Math.PI / 4; // Rotate player 45 degrees to the direction of movement
} else {
playerGraphics.rotation = -Math.PI / 4; // Rotate player -45 degrees to the direction of movement
}
};
self.update = function () {
if (self.isInvulnerable) {
self.invulnerableTimer--;
if (!self.shield) {
self.shield = self.addChild(LK.getAsset('shield', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.5 // Set shield transparency
}));
// Play powerup sound when shield is activated
LK.getSound('powerup').play();
}
if (leftPlayer && !leftPlayer.shield) {
leftPlayer.shield = leftPlayer.addChild(LK.getAsset('shield', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.5 // Set shield transparency
}));
// Play powerup sound when left player's shield is activated
LK.getSound('powerup').play();
}
if (rightPlayer && !rightPlayer.shield) {
rightPlayer.shield = rightPlayer.addChild(LK.getAsset('shield', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.5 // Set shield transparency
}));
// Play powerup sound when right player's shield is activated
LK.getSound('powerup').play();
}
if (self.invulnerableTimer <= 0) {
self.isInvulnerable = false;
if (self.shield) {
self.shield.destroy();
self.shield = null;
}
if (leftPlayer && leftPlayer.shield) {
leftPlayer.shield.destroy();
leftPlayer.shield = null;
}
if (rightPlayer && rightPlayer.shield) {
rightPlayer.shield.destroy();
rightPlayer.shield = null;
}
} else {
// Update countdown text
if (self.shieldCountdown) {
self.shieldCountdown.setText(Math.ceil(self.invulnerableTimer / 120));
}
// Add blinking effect when shield is about to disappear
if (self.invulnerableTimer <= 120) {
// Last 2 seconds
if (LK.ticks % 30 < 15) {
// Blink every 0.5 seconds
self.shield.alpha = 0.2;
} else {
self.shield.alpha = 0.5;
// Add blinking effect when shield is about to disappear
if (self.invulnerableTimer <= 120) {
// Last 2 seconds
if (LK.ticks % 30 < 15) {
// Blink every 0.5 seconds
self.shield.alpha = 0.2;
} else {}
}
self.shield.alpha = 0.5;
// Add blinking effect when shield is about to disappear
if (self.invulnerableTimer <= 120) {
// Last 2 seconds
if (LK.ticks % 30 < 15) {
// Blink every 0.5 seconds
self.shield.alpha = 0.2;
} else {}
}
self.shield.alpha = 0.5;
}
}
}
}
if (self.isMoving) {
if (Math.abs(self.x - self.targetX) < self.speed) {
self.x = self.targetX;
self.isMoving = false;
} else {
self.x += (self.targetX - self.x) * 0.1; // Smooth movement using linear interpolation
playerGraphics.rotation = self.x < self.targetX ? Math.PI / 4 : -Math.PI / 4; // Rotate player 45 degrees to the direction of movement
}
} else {
// Smoothly transition player rotation back to its original position
if (playerGraphics.rotation > 0) {
playerGraphics.rotation -= 0.1;
} else if (playerGraphics.rotation < 0) {
playerGraphics.rotation += 0.1;
}
if (Math.abs(playerGraphics.rotation) < 0.1) {
playerGraphics.rotation = 0; // Reset rotation when player is not moving
}
}
if (!self.isJumping && self.visible) {
if (self.isMoving && LK.ticks % 1 == 0) {
var trail = new Trail();
trail.x = self.x;
trail.y = self.y + playerGraphics.height / 2;
game.addChild(trail);
} else if (LK.ticks % 4 == 0) {
var trail = new Trail();
trail.x = self.x;
trail.y = self.y + playerGraphics.height / 2;
game.addChild(trail);
}
}
if (self.isJumping) {
if (self.y > self.jumpPeakY && !self.isFalling) {
self.y -= self.jumpSpeed;
playerGraphics.scale.x += 0.01; // Increase player size when moving up
playerGraphics.scale.y += 0.01;
if (self.shield) {
self.shield.scale.x += 0.01; // Increase shield size when moving up
self.shield.scale.y += 0.01;
}
} else {
self.isFalling = true;
self.y += self.jumpSpeed;
playerGraphics.scale.x -= 0.01; // Decrease player size when falling down
playerGraphics.scale.y -= 0.01;
if (self.shield) {
self.shield.scale.x -= 0.01; // Decrease shield size when falling down
self.shield.scale.y -= 0.01;
}
if (self.y >= self.jumpStartY) {
self.y = self.jumpStartY;
self.isJumping = false;
self.isFalling = false;
playerGraphics.scale.x = 1; // Reset player size when not jumping
playerGraphics.scale.y = 1;
if (self.shield) {
self.shield.scale.x = 1; // Reset shield size when not jumping
self.shield.scale.y = 1;
}
// Destroy the player's shadow
shadow.destroy();
}
}
// Reduce jump duration by 5% every 10 seconds
if (LK.ticks % 600 == 0) {
self.jumpSpeed *= 1.05; // Increase jump speed by 5%
}
}
// Update shadow rotation to match player rotation
if (shadow) {
shadow.rotation = playerGraphics.rotation;
}
// Ensure player is always on top if it is a child of the game
if (game.children.includes(self)) {
game.setChildIndex(self, game.children.length - 1);
}
};
self.moveLeft = function () {
if (!gameStarted) {
for (var i = 0; i < starfield.length; i++) {
starfield[i].update();
}
return;
}
if (self.lane > 0 && !self.isMoving && !leftPlayer && !rightPlayer) {
self.lane--;
self.transitionToLane(lanes[self.lane]);
LK.getSound('swipe').play();
LK.getSound('swipe').play();
}
};
self.moveRight = function () {
if (!gameStarted) {
return;
} // Prevent player movement when the home screen is up
if (self.lane < 2 && !self.isMoving && !leftPlayer && !rightPlayer) {
self.lane++;
self.transitionToLane(lanes[self.lane]);
LK.getSound('swipe').play();
}
};
self.jump = function () {
if (!self.isMoving && !self.isJumping && !leftPlayer && !rightPlayer) {
self.isJumping = true;
self.jumpStartY = self.y;
self.jumpPeakY = self.y - 250; // Increase jump height
self.jumpSpeed = 4;
// Create the player's shadow
shadow = new Shadow();
shadow.x = self.x;
shadow.y = self.y;
game.addChild(shadow);
// Play jump sound when player jumps
LK.getSound('jump').play();
}
};
});
// Define the PowerUp class
var PowerUp = Container.expand(function () {
var self = Container.call(this);
var powerUpGraphics = self.attachAsset('powerup', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = gameSpeed;
self.update = function () {
self.y += self.speed;
if (self.y > 2732 + self.height / 2) {
self.destroy();
}
};
});
// Define the PowerUpCenterLane class
var PowerUpCenterLane = Container.expand(function () {
var self = Container.call(this);
var powerUpGraphics = self.attachAsset('powerup', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = gameSpeed;
self.update = function () {
self.y += self.speed;
if (self.y > 2732 + self.height / 2) {
self.destroy();
}
};
});
// Define the RightLaneOutline class
var RightLaneOutline = Container.expand(function () {
var self = Container.call(this);
var outlineGraphics = self.attachAsset('lineobstacle', {
anchorX: 0.5,
anchorY: 0.0,
width: 15,
height: 2732 // Set the height to cover the entire screen height
});
outlineGraphics.height = 2732; // Ensure the height covers the entire screen height
self.speed = gameSpeed;
self.update = function () {
self.y += self.speed;
if (self.y > 2732 + self.height / 2) {
self.destroy();
}
};
});
// Define the RightPlayer class
var RightPlayer = Container.expand(function () {
var self = Container.call(this);
var rightPlayerGraphics = self.attachAsset('rightplayer', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 15;
self.update = function () {
// Add any specific update logic for RightPlayer here
if (LK.ticks % 4 == 0) {
var trail = new Trail();
trail.scale.x = 0.5;
trail.scale.y = 0.5;
if (self && self.x !== undefined) {
trail.x = self.x;
} else {
trail.x = 0;
}
trail.y = self && self.y !== undefined && self.height !== undefined ? self.y + self.height / 2 : 0;
game.addChildAt(trail, game.getChildIndex(self));
}
};
});
//<Assets used in the game will automatically appear here>
// Define the Shadow class
var Shadow = Container.expand(function () {
var self = Container.call(this);
var shadowGraphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5,
tint: 0x000000 // Set the color to black
});
shadowGraphics.alpha = 0.5; // Dim the shadow
self.update = function () {
// The shadow's size changes based on the player's y position
var scale = 1 - (player.y - self.y) / 1000;
self.scale.x = scale;
self.scale.y = scale;
// Update the shadow's position to match the player's position
self.x = player.x;
// Rotate the shadow to match the player's rotation
if (player.playerGraphics) {
shadowGraphics.rotation = player.playerGraphics.rotation;
}
};
});
// Define the LineObstacle class
var SmallObstacle = Container.expand(function () {
var self = Container.call(this);
var obstacleGraphics = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 0.5,
tint: 0xa8ed15 // Apply tint #a8ed15
});
self.speed = gameSpeed;
self.update = function () {
self.y += self.speed;
if (self.y > 2732 + self.height / 2) {
self.destroy();
}
};
});
// Define the SmallObstacleCenterCoinSides class
var SmallObstacleCenterCoinSides = Container.expand(function () {
var self = Container.call(this);
var smallObstacle = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 0.5,
tint: 0xa8ed15 // Apply tint #a8ed15
});
self.speed = gameSpeed;
self.update = function () {
self.y += self.speed;
if (self.y > 2732 + self.height / 2) {
self.destroy();
}
};
});
var SmallObstacleMiddlePowerUpLeftCoinRight = Container.expand(function () {
var self = Container.call(this);
var smallObstacleMiddle = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 0.5,
tint: 0xa8ed15 // Apply tint #a8ed15
});
self.speed = gameSpeed;
self.update = function () {
self.y += self.speed;
if (self.y > 2732 + self.height / 2) {
self.destroy();
}
};
});
var StairedSmallObstacle = Container.expand(function (lane, yOffset) {
var self = Container.call(this);
var obstacleGraphics = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 0.5,
tint: 0xa8ed15
});
self.speed = gameSpeed;
self.x = lanes[lane];
self.y = -self.height * 2 + yOffset;
self.update = function () {
self.y += self.speed;
if (self.y > 2732 + self.height / 2) {
self.destroy();
}
};
});
var Star = Container.expand(function () {
var self = Container.call(this);
var starGraphics = self.attachAsset('star', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = Math.random() * 2 + 1; // Random speed for each star
self.scale.set(Math.random() * 1.5 + 0.5); // Random size between 0.5 and 2.0
self.update = function () {
self.y += self.speed;
if (self.y > 2732) {
self.y = -self.height;
self.x = Math.random() * 2048;
}
};
});
// Function to spawn SmallObstacle in the center and Coins on the sides
var TextObstacle = Container.expand(function (customText) {
var self = Container.call(this);
var textGraphics = new Text2(customText || 'Sample Text', {
size: 120,
fill: "#ffffff",
align: "center",
stroke: "#000000",
strokeThickness: 10,
border: true,
borderColor: "#000000",
borderWidth: 5
});
textGraphics.anchor.set(0.5, 0.5);
self.addChild(textGraphics);
self.speed = gameSpeed;
self.update = function () {
self.y += self.speed;
self.hitbox = null; // Ensure TextObstacle does not collide with player
if (self.y > 2732 + self.height / 2) {
self.destroy();
}
};
});
// Function to spawn SmallObstacle
// Define the Trail class
var Trail = Container.expand(function () {
var self = Container.call(this);
var trailGraphics = self.attachAsset('trail', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.5
});
self.speed = 5;
self.update = function () {
self.y += self.speed;
self.alpha -= 0.02; // Fade out the trail faster
self.scale.x -= 0.02; // Shrink the trail faster
self.scale.y -= 0.02; // Shrink the trail faster
if (self.y > 2732 || self.alpha <= 0 || self.scale.x <= 0 || self.scale.y <= 0) {
self.destroy();
}
};
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x101010 //Init game with even darker grey background
});
/****
* Game Code
****/
function fadeOut(target, duration, onComplete) {
var fadeStep = 1 / (duration / 16.67); // Assuming 60 FPS, 16.67ms per frame
var fadeInterval = LK.setInterval(function () {
if (target.alpha > 0) {
target.alpha -= fadeStep;
if (target.alpha < 0) {
target.alpha = 0;
}
} else {
LK.clearInterval(fadeInterval);
if (onComplete) {
onComplete();
}
}
}, 16.67);
}
function spawnStairedSmallObstacles() {
var yOffset = 0;
for (var i = 0; i < lanes.length; i++) {
var lane = i;
if (i === 1) {
// Ensure the center lane obstacle is always in the same position
yOffset = 0;
} else {
// Randomly choose positive or negative offset for left and right lanes
yOffset = (Math.random() < 0.5 ? -1 : 1) * 350;
}
var stairedObstacle = new StairedSmallObstacle(lane, yOffset);
if (!obstacles) {
obstacles = [];
}
obstacles.push(stairedObstacle);
game.addChild(stairedObstacle);
}
}
function spawnSmallObstacleMiddlePowerUpLeftCoinRight() {
var smallObstacleMiddle = new SmallObstacleMiddlePowerUpLeftCoinRight();
smallObstacleMiddle.x = lanes[1]; // Middle lane
smallObstacleMiddle.y = -smallObstacleMiddle.height * 2;
smallObstacleMiddle.speed = gameSpeed; // Ensure constant speed
if (!obstacles) {
obstacles = [];
}
obstacles.push(smallObstacleMiddle);
game.addChild(smallObstacleMiddle);
var powerUpLeft = new PowerUp();
powerUpLeft.x = lanes[0]; // Left lane
powerUpLeft.y = -powerUpLeft.height * 2;
powerUpLeft.speed = gameSpeed; // Ensure constant speed
if (!powerups) {
powerups = [];
}
powerups.push(powerUpLeft);
game.addChild(powerUpLeft);
var coinRight = new Coin();
coinRight.x = lanes[2]; // Right lane
coinRight.y = -coinRight.height * 2;
coinRight.speed = gameSpeed; // Ensure constant speed
if (!coins) {
coins = [];
}
coins.push(coinRight);
game.addChild(coinRight);
}
// New asset for obstacle line
function checkBoundingBoxCollision(obj1, obj2) {
var obj1Bounds = obj1.getBounds();
var obj2Bounds = obj2.getBounds();
var forgivenessX = obj1Bounds.width * 0.1;
var forgivenessY = obj1Bounds.height * 0.1;
return obj1Bounds.x < obj2Bounds.x + obj2Bounds.width - forgivenessX && obj1Bounds.x + obj1Bounds.width > obj2Bounds.x + forgivenessX && obj1Bounds.y < obj2Bounds.y + obj2Bounds.height - forgivenessY && obj1Bounds.y + obj1Bounds.height > obj2Bounds.y + forgivenessY;
}
// Function to spawn PowerUp in the center lane
function spawnPowerUpCenterLane() {
var powerUpCenterLane = new PowerUpCenterLane();
powerUpCenterLane.x = lanes[1]; // Center lane
powerUpCenterLane.y = -powerUpCenterLane.height * 2;
if (!powerups) {
powerups = [];
}
powerups.push(powerUpCenterLane);
game.addChild(powerUpCenterLane);
}
// Create main menu container
var mainMenu = new Container();
game.addChildAt(mainMenu, game.children.length);
// Play background music on main menu
LK.playMusic('backgroundmusic');
// Create title text with background button
var titleButton = new Container();
titleButton.update = function () {
if (LK.ticks % 120 < 60) {
titleButton.scale.x += 0.0001;
titleButton.scale.y += 0.0001;
} else {
titleButton.scale.x -= 0.0001;
titleButton.scale.y -= 0.0001;
}
};
// Removed titleBackground box
var titleImage = LK.getAsset('homeTitle', {
anchorX: 0.5,
anchorY: 0.5
});
titleButton.addChild(titleImage);
// Ensure lanes array is properly initialized before accessing its elements
if (!lanes || lanes.length < 3) {
console.error("Lanes array is not properly initialized.");
lanes = [2048 / 4, 2048 / 2, 2048 / 4 * 3]; // Reinitialize lanes array
}
titleButton.x = lanes[1]; // Center the title button over the middle lane
titleButton.y = 2732 / 4;
mainMenu.addChild(titleButton);
// Create mode 1 button with background
var mode1Button = new Container();
mode1Button.update = function () {
if (LK.ticks % 120 < 60) {
mode1Button.scale.x += 0.0001;
mode1Button.scale.y += 0.0001;
} else {
mode1Button.scale.x -= 0.0001;
mode1Button.scale.y -= 0.0001;
}
};
// Removed mode1ButtonBackground box
var mode1ButtonImage = LK.getAsset('menu1', {
anchorX: 0.5,
anchorY: 0.5
});
mode1Button.addChild(mode1ButtonImage);
mode1Button.x = lanes[1]; // Center the mode 1 button over the middle lane
mode1Button.y = 2732 / 2;
mainMenu.addChildAt(mode1Button, mainMenu.children.length);
// Create mode 2 button with background
var mode2Button = new Container();
mode2Button.update = function () {
if (LK.ticks % 120 < 60) {
mode2Button.scale.x += 0.0001;
mode2Button.scale.y += 0.0001;
} else {
mode2Button.scale.x -= 0.0001;
mode2Button.scale.y -= 0.0001;
}
};
// Removed mode2ButtonBackground box
var mode2ButtonImage = LK.getAsset('menu2', {
anchorX: 0.5,
anchorY: 0.5
});
mode2Button.addChild(mode2ButtonImage);
mode2Button.x = lanes[1]; // Center the mode 2 button over the middle lane
mode2Button.y = 2732 / 2 + 400;
mainMenu.addChildAt(mode2Button, mainMenu.children.length);
// Add event listeners for buttons
mode1Button.down = function () {
LK.getSound('select').play();
startGame('mode1');
};
mode2Button.down = function () {
LK.getSound('select').play();
startGame('mode2');
};
// Function to start the game
function startGame(mode) {
fadeOut(titleButton, 1000, function () {
mainMenu.visible = false;
});
fadeOut(mode1Button, 1000, function () {
scoreTxt.visible = true; // Show score when game starts
});
fadeOut(mode2Button, 1000, function () {
scoreBackground.visible = true; // Show score background when game starts
});
milesTxt.visible = true; // Show miles when game starts
milesBackground.visible = true; // Show miles background when game starts
// Background music is already playing from the main menu
// Hide final score text on game start
if (finalScoreTxt) {
finalScoreTxt.visible = false;
// Hide final score text on game start
if (finalScoreTxt) {
finalScoreTxt.visible = false;
}
}
if (mode === 'mode1') {
// Initialize mode 1 specific elements
obstacleSpawnOrder = [{
type: 'TextObstacle',
interval: 100,
text: 'Swipe LEFT or RIGHT!'
}, {
type: 'SmallObstacle',
interval: 100
}, {
type: 'SmallObstacleLeftMiddleCoinRight',
interval: 100
}, {
type: 'SmallObstacleRightCenterCoinLeft',
interval: 100
}, {
type: 'TextObstacle',
interval: 100,
text: 'Swipe UP to JUMP!'
}, {
type: 'LineObstacle',
interval: 100
}, {
type: 'SmallObstaclesSidesCoinMiddle',
interval: 100
}, {
type: 'TextObstacle',
interval: 100,
text: 'Swipe DOWN to SPLIT!'
}, {
type: 'BigObstacle',
interval: 150
}, {
type: 'SmallObstaclesSidesCoinMiddle',
interval: 100
}, {
type: 'TextObstacle',
interval: 100,
text: 'Collect the SHIELD!'
}, {
type: 'PowerUpCenterLane',
interval: 100
}, {
type: 'ObstacleLine',
interval: 50
}, {
type: 'ObstacleLine',
interval: 50
}, {
type: 'ObstacleLine',
interval: 50
}, {
type: 'TextObstacle',
interval: 100,
text: 'You are READY!'
}, {
type: 'TextObstacle',
interval: 100,
text: 'Get ORBS for extra score!'
}];
} else if (mode === 'mode2') {
// Initialize mode 2 specific elements
obstacleSpawnOrder = [{
type: 'SmallObstacle',
interval: 100
}, {
type: 'SmallObstacleLeftMiddleCoinRight',
interval: 100
}, {
type: 'SmallObstacleRightCenterCoinLeft',
interval: 100
}, {
type: 'LineObstacle',
interval: 100
}, {
type: 'SmallObstacleCenterCoinLeftPowerUpRight',
interval: 100
}, {
type: 'SmallObstaclesSidesCoinMiddle',
interval: 100
}, {
type: 'SmallObstacleCenterCoinSides',
interval: 100
}, {
type: 'SmallObstacleMiddlePowerUpLeftCoinRight',
interval: 100
}, {
type: 'StairedSmallObstacles',
interval: 100
}, {
type: 'BigObstacle',
interval: 150
}];
obstacleSpawnOrder = obstacleSpawnOrder.sort(function () {
return Math.random() - 0.5;
});
}
// Start the game
var timeout = LK.setTimeout(function () {
gameStarted = true;
}, 500);
}
// Function to spawn TextObstacle
function spawnTextObstacle(customText) {
var textObstacle = new TextObstacle(customText);
textObstacle.x = 2048 / 2; // Center the TextObstacle
textObstacle.y = -textObstacle.height * 2;
if (!obstacles) {
obstacles = [];
}
obstacles.push(textObstacle);
game.addChild(textObstacle);
}
// Function to spawn powerups
function spawnPowerUp(lane) {
var powerup = new PowerUp();
powerup.lane = lane;
powerup.x = lanes[powerup.lane];
powerup.y = -powerup.height * 2;
powerups.push(powerup);
game.addChild(powerup);
}
// Initialize gameStarted flag
var gameStarted = false;
// Initialize array for powerups
var powerups = [];
// Initialize shadow
var shadow;
// Initialize lanes
var lanes = [2048 / 4, 2048 / 2, 2048 / 4 * 3];
// Ensure lanes array is properly initialized before accessing its elements
if (!lanes || lanes.length < 3) {
console.error("Lanes array is not properly initialized.");
lanes = [2048 / 4, 2048 / 2, 2048 / 4 * 3]; // Reinitialize lanes array
}
// Ensure lanes array is properly initialized before accessing its elements
if (!lanes || lanes.length < 3) {
console.error("Lanes array is not properly initialized.");
lanes = [2048 / 4, 2048 / 2, 2048 / 4 * 3]; // Reinitialize lanes array
}
// Initialize starfield
// Initialize lane separators
var laneSeparators = [];
for (var i = 1; i < lanes.length; i++) {
var separator = new LaneSeparator();
separator.x = (lanes[i - 1] + lanes[i]) / 2; // Position separator between lanes
separator.y = 0;
laneSeparators.push(separator);
game.addChildAt(separator, 0); // Add lane separators at the bottom of the z axis
}
// Initialize lane outlines
var leftLaneOutline = new LeftLaneOutline();
leftLaneOutline.x = lanes[0] - (lanes[1] - lanes[0]) / 2; // Position left outline to the left of the first lane
leftLaneOutline.y = 0;
game.addChildAt(leftLaneOutline, 0); // Add left lane outline at the bottom of the z axis
var rightLaneOutline = new RightLaneOutline();
rightLaneOutline.x = lanes[2] + (lanes[2] - lanes[1]) / 2; // Position right outline to the right of the last lane
rightLaneOutline.y = 0;
game.addChildAt(rightLaneOutline, 0); // Add right lane outline at the bottom of the z axis
// Initialize player
var player = game.addChild(new Player());
player.jumpSpeed = 4; // Initialize jump speed
player.hitbox = [player];
player.lane = 1; // Start in the middle lane
player.x = lanes[player.lane];
player.y = 2732 - 200 - 350;
// Declare left and right players
var leftPlayer;
var rightPlayer;
// Initialize arrays for obstacles and coins
var obstacles = [];
var coins = [];
// Initialize split duration timer
var splitDuration = 120; // Duration in frames (2 seconds at 60 FPS)
var splitTimer = 0;
// Initialize score and final score text
var score = 0;
var finalScoreTxt = new Text2('Final Score: 0', {
size: 100,
fill: "#ffffff",
stroke: "#000000",
strokeThickness: 5,
border: true,
borderColor: "#000000",
borderWidth: 3
});
finalScoreTxt.anchor.set(0.5, 0.5);
finalScoreTxt.x = 2048 / 2;
finalScoreTxt.y = 2732 / 2;
finalScoreTxt.visible = false;
LK.gui.center.addChild(finalScoreTxt);
// Initialize game speed
var gameSpeed = 5;
// Initialize global spawn interval
var globalSpawnInterval = 120; // Default interval in frames (2 seconds at 60 FPS)
var spawnIntervalReductionTimer = 0; // Timer to track interval reduction
var intervalReductionTimer = 0; // Timer to track interval reduction for obstacle spawn order
var scoreTxt = new Text2('0', {
size: 50,
fill: "#ffffff",
stroke: "#000000",
strokeThickness: 5,
border: true,
borderColor: "#000000",
borderWidth: 3
});
var scoreBackground = LK.getAsset('scoreBackground', {
anchorX: 0.5,
anchorY: 0.5,
x: scoreTxt.x + 550,
y: scoreTxt.y + scoreTxt.height / 2 + 200
});
scoreTxt.anchor.set(0.5, 0);
scoreTxt.x += 600;
scoreTxt.y += 200;
scoreTxt.visible = false; // Hide score on main menu
scoreBackground.visible = false; // Hide score background on main menu
LK.gui.top.addChild(scoreBackground);
LK.gui.top.addChild(scoreTxt);
// Configuration for defining the order in which obstacles will spawn
var obstacleSpawnOrder = [{
type: 'TextObstacle',
// New TextObstacle type
interval: 100,
text: 'Swipe LEFT or RIGHT!' // Custom text for TextObstacle
}, {
type: 'SmallObstacle',
interval: 100
}, {
type: 'SmallObstacleLeftMiddleCoinRight',
interval: 100
}, {
type: 'SmallObstacleRightCenterCoinLeft',
interval: 100
}, {
type: 'TextObstacle',
// New TextObstacle type
interval: 100,
text: 'Swipe UP to JUMP!' // Custom text for TextObstacle
}, {
type: 'LineObstacle',
interval: 100
}, {
type: 'SmallObstacleCenterCoinLeftPowerUpRight',
interval: 100
}, {
type: 'SmallObstaclesSidesCoinMiddle',
interval: 100
}, {
type: 'TextObstacle',
// New TextObstacle type
interval: 100,
text: 'Swipe DOWN to SPLIT!' // Custom text for TextObstacle
}, {
type: 'BigObstacle',
interval: 100
}, {
type: 'SmallObstaclesSidesCoinMiddle',
interval: 100
}, {
type: 'LineObstacle',
interval: 100
}, {
type: 'SmallObstacleRightCenterCoinLeft',
interval: 100
}, {
type: 'TextObstacle',
// New TextObstacle type
interval: 100,
text: 'Avoid the Obstacles!' // Custom text for TextObstacle
}];
var currentObstacleIndex = 0;
var obstacleSpawnTimer = 0;
var obstacleSpawnOrderRandom = [{
type: 'SmallObstacle',
interval: 100
}, {
type: 'SmallObstacleLeftMiddleCoinRight',
interval: 100
}, {
type: 'SmallObstacleRightCenterCoinLeft',
interval: 100
}, {
type: 'LineObstacle',
interval: 100
}, {
type: 'SmallObstacleCenterCoinLeftPowerUpRight',
interval: 100
}, {
type: 'SmallObstaclesSidesCoinMiddle',
interval: 100
}, {
type: 'SmallObstacleCenterCoinSides',
interval: 100
}, {
type: 'StairedSmallObstacles',
interval: 100
}, {
type: 'BigObstacle',
interval: 150
}];
// Initialize queue for predicting next obstacle
var obstacleQueue = [];
// Function to spawn obstacles
function spawnObstacle(lane) {
var obstacle;
if (lane === undefined) {
obstacle = new LineObstacle();
obstacle.x = 2048 / 2; // Center the LineObstacle
} else {
obstacle = new Obstacle();
obstacle.lane = lane;
obstacle.x = lanes[obstacle.lane];
}
obstacle.y = -obstacle.height * 2;
obstacle.speed = gameSpeed; // Ensure constant speed
if (!obstacles) {
obstacles = [];
}
obstacles.push(obstacle);
game.addChild(obstacle);
}
// Function to spawn BigObstacle with specific rules
function spawnBigObstacle() {
var bigObstacle = new BigObstacle();
bigObstacle.x = 2048 / 2; // Center the BigObstacle
bigObstacle.y = -bigObstacle.height / 2;
if (!obstacles) {
obstacles = [];
}
obstacles.push(bigObstacle);
game.addChild(bigObstacle);
}
// Function to spawn coins
function spawnCoin(lane) {
var coin = new Coin();
coin.lane = lane;
coin.x = lanes[coin.lane];
coin.y = -coin.height * 2;
coins.push(coin);
game.addChild(coin);
}
// Function to spawn powerups
// Handle swipe events for player movement
var touchStartX = 0;
var touchStartY = 0;
game.down = function (x, y, obj) {
if (!gameStarted || leftPlayer || rightPlayer) {
return;
} // Prevent player movement when the home screen is up
touchStartX = x;
touchStartY = y;
};
game.up = function (x, y, obj) {
if (!gameStarted) {
return;
} // Prevent player movement when the home screen is up
if (leftPlayer || rightPlayer) {
return; // Disable touch screen while player is split
}
if (Math.abs(y - touchStartY) > Math.abs(x - touchStartX)) {
if (y < touchStartY && !leftPlayer && !rightPlayer) {
player.jump();
} else if (y > touchStartY && !leftPlayer && !rightPlayer && !player.isJumping && player.lane === 1) {
// Animate leftPlayer and rightPlayer to move to the sides
var leftTargetX = player.x - 650;
var rightTargetX = player.x + 550;
var animationDuration = 20; // Duration in frames (0.33 seconds at 60 FPS)
if (!leftPlayer) {
leftPlayer = new LeftPlayer();
leftPlayer.x = player.x;
leftPlayer.y = player.y;
game.addChild(leftPlayer);
if (!rightPlayer) {
rightPlayer = new RightPlayer();
rightPlayer.x = player.x;
rightPlayer.y = player.y;
game.addChild(rightPlayer);
// Play swipe sound when player splits
LK.getSound('swipe').play();
player.visible = false; // Hide the original player
player.hitbox = [leftPlayer, rightPlayer]; // Move player hitbox to left and right players
// Initialize update functions after adding to game
if (!leftPlayer) {
leftPlayer = new LeftPlayer();
leftPlayer.x = player.x;
leftPlayer.y = player.y;
game.addChild(leftPlayer);
leftPlayer.update = function () {
if (animationDuration > 0) {
leftPlayer.x += (leftTargetX - leftPlayer.x) / animationDuration;
animationDuration--;
}
if (LK.ticks % 4 == 0) {
var trail = new Trail();
trail.scale.x = 0.5;
trail.scale.y = 0.5;
if (leftPlayer && leftPlayer.x !== undefined) {
trail.x = leftPlayer.x;
} else {
trail.x = 0;
}
trail.y = this.y + (leftPlayer.height ? leftPlayer.height / 2 : 0);
game.addChildAt(trail, game.getChildIndex(this));
if (!rightPlayer) {
rightPlayer = new RightPlayer();
rightPlayer.x = player.x;
rightPlayer.y = player.y;
game.addChild(rightPlayer);
if (!rightPlayer) {
rightPlayer = new RightPlayer();
rightPlayer.x = player.x;
rightPlayer.y = player.y;
game.addChild(rightPlayer);
rightPlayer.update = function () {
if (animationDuration > 0) {
rightPlayer.x += (rightTargetX - rightPlayer.x) / animationDuration;
animationDuration--;
}
};
}
}
;
if (LK.ticks % 4 == 0) {
var trail = new Trail();
trail.scale.x = 0.5;
trail.scale.y = 0.5;
if (rightPlayer && rightPlayer.x !== undefined) {
trail.x = rightPlayer.x;
} else {
trail.x = 0;
}
trail.y = this.y + (rightPlayer.height ? rightPlayer.height / 2 : 0);
game.addChildAt(trail, game.getChildIndex(this));
// Initialize update functions after adding to game
leftPlayer.update = function () {
if (animationDuration > 0) {
leftPlayer.x += (leftTargetX - leftPlayer.x) * 0.1; // Smooth movement using linear interpolation
animationDuration--;
titleButton.update = function () {
if (LK.ticks % 60 < 30) {
titleButton.y += 1;
} else {}
;
titleButton.y -= 1;
};
}
};
}
;
if (LK.ticks % 4 == 0) {
var trail = new Trail();
trail.scale.x = 0.5;
trail.scale.y = 0.5;
trail.x = leftPlayer ? leftPlayer.x : 0;
trail.y = leftPlayer && leftPlayer.height ? leftPlayer.y + leftPlayer.height / 2 : 0;
game.addChildAt(trail, game.getChildIndex(leftPlayer));
}
}
;
};
rightPlayer.update = function () {
if (animationDuration > 0) {
rightPlayer.x += (rightTargetX - rightPlayer.x) * 0.1; // Smooth movement using linear interpolation
animationDuration--;
}
mode1Button.update = function () {
if (LK.ticks % 60 < 30) {
mode1Button.y += 1;
} else {
mode1Button.y -= 1;
}
};
if (LK.ticks % 4 == 0) {
var trail = new Trail();
trail.scale.x = 0.5;
trail.scale.y = 0.5;
trail.x = rightPlayer ? rightPlayer.x : 0;
trail.y = rightPlayer && rightPlayer.height ? rightPlayer.y + rightPlayer.height / 2 : 0;
game.addChildAt(trail, game.getChildIndex(rightPlayer));
}
};
}
}
;
// Initialize update functions after adding to game
leftPlayer.update = function () {
if (animationDuration > 0) {
leftPlayer.x += (leftTargetX - leftPlayer.x) / animationDuration;
animationDuration--;
}
mode2Button.update = function () {
if (LK.ticks % 60 < 30) {
mode2Button.y += 1;
} else {
mode2Button.y -= 1;
}
};
if (LK.ticks % 4 == 0) {
var trail = new Trail();
trail.scale.x = 0.5;
trail.scale.y = 0.5;
trail.x = leftPlayer.x;
trail.y = leftPlayer && leftPlayer.y !== undefined ? leftPlayer.y + (leftPlayer.height ? leftPlayer.height / 2 : 0) : 0;
game.addChildAt(trail, game.getChildIndex(leftPlayer));
}
};
}
;
rightPlayer.update = function () {
if (animationDuration > 0) {
rightPlayer.x += (rightTargetX - rightPlayer.x) / animationDuration;
animationDuration--;
}
// Add any specific update logic for RightPlayer here
if (LK.ticks % 4 == 0) {
var trail = new Trail();
trail.scale.x = 0.5;
trail.scale.y = 0.5;
trail.x = rightPlayer ? rightPlayer.x : 0;
trail.y = rightPlayer.y + rightPlayer.height / 2;
game.addChildAt(trail, game.getChildIndex(rightPlayer));
}
};
// Initialize update functions after adding to game
leftPlayer.update = function () {
if (animationDuration > 0) {
leftPlayer.x += (leftTargetX - leftPlayer.x) / animationDuration;
animationDuration--;
}
// Add any specific update logic for LeftPlayer here
if (LK.ticks % 4 == 0) {
var trail = new Trail();
trail.scale.x = 0.5;
trail.scale.y = 0.5;
trail.x = leftPlayer ? leftPlayer.x : 0;
trail.y = leftPlayer && leftPlayer.y !== undefined ? leftPlayer.y + (leftPlayer.height ? leftPlayer.height / 2 : 0) : 0;
game.addChildAt(trail, game.getChildIndex(leftPlayer));
}
};
rightPlayer.update = function () {
if (animationDuration > 0) {
rightPlayer.x += (rightTargetX - rightPlayer.x) / animationDuration;
animationDuration--;
}
// Add any specific update logic for RightPlayer here
if (LK.ticks % 4 == 0) {
var trail = new Trail();
trail.scale.x = 0.5;
trail.scale.y = 0.5;
trail.x = rightPlayer.x;
trail.y = rightPlayer.y + rightPlayer.height / 2;
game.addChildAt(trail, game.getChildIndex(rightPlayer));
}
};
}
// Start split timer
splitTimer = splitDuration;
} else {
if (x < touchStartX) {
player.moveLeft();
} else {
player.moveRight();
}
}
};
// Update game logic
game.update = function () {
// Update title button
if (titleButton.update) {
titleButton.update();
}
// Update miles traveled
milesTraveled += gameSpeed / 30; // Increase the speed at which miles are counted
milesTxt.setText(Math.floor(milesTraveled));
// Update mode1 button
mode1Button.update();
// Update mode2 button
mode2Button.update();
// Update miles traveled
milesTraveled += gameSpeed / 30; // Increase the speed at which miles are counted
milesTxt.setText(Math.floor(milesTraveled));
if (!gameStarted) {
// Update starfield
return;
}
// Update lane separators
for (var i = 0; i < laneSeparators.length; i++) {
laneSeparators[i].update();
laneSeparators[i].children[0].height = 2732; // Ensure the height covers the entire screen height
}
// Update player
player.update();
// Increase game speed and decrease global spawn interval over time
spawnIntervalReductionTimer++;
if (spawnIntervalReductionTimer >= 600) {
// Every 10 seconds
globalSpawnInterval = Math.max(30, globalSpawnInterval * 0.95); // Reduce spawn interval by 5%
spawnIntervalReductionTimer = 0; // Reset timer
}
intervalReductionTimer++;
if (intervalReductionTimer >= 600) {
for (var i = 0; i < obstacleSpawnOrder.length; i++) {
obstacleSpawnOrder[i].interval = Math.max(1, Math.floor(obstacleSpawnOrder[i].interval * 0.95));
}
intervalReductionTimer = 0;
}
if (LK.ticks % 600 == 0) {
globalSpawnInterval = Math.max(30, globalSpawnInterval * 0.95); // Reduce spawn interval by 5% every 10 seconds
// Increase speed every 10 seconds
gameSpeed *= 1.05; // Increase speed by 5%
// Decrease global spawn interval to make spawns more frequent
globalSpawnInterval = Math.max(30, globalSpawnInterval - 10); // Ensure interval doesn't go below 30 frames (0.5 seconds)
}
// Update obstacles, coins, and powerups
for (var i = powerups.length - 1; i >= 0; i--) {
powerups[i].y += gameSpeed;
powerups[i].update();
if (player && !player.isJumping && player.hitbox.some(function (hitbox) {
return hitbox.intersects(powerups[i]);
})) {
player.isInvulnerable = true;
player.invulnerableTimer = 600; // 10 seconds at 60 FPS
if (leftPlayer && leftPlayer.update) {
leftPlayer.isInvulnerable = true;
leftPlayer.invulnerableTimer = 600;
}
if (rightPlayer && rightPlayer.update) {
rightPlayer.isInvulnerable = true;
rightPlayer.invulnerableTimer = 600;
}
powerups[i].destroy();
powerups.splice(i, 1);
}
}
for (var i = obstacles.length - 1; i >= 0; i--) {
obstacles[i].y += gameSpeed;
obstacles[i].update();
if (!player.isJumping && player.hitbox && player.hitbox.some(function (hitbox) {
return checkBoundingBoxCollision(hitbox, obstacles[i]) && obstacles[i].hitbox !== null;
})) {
if (player.isInvulnerable) {
// Spawn particles
for (var j = 0; j < 50; j++) {
var particle = new Particle();
particle.x = obstacles[i].x;
particle.y = obstacles[i].y;
particle.scale.set(1); // Increase the size of the particles
particle.setTint(0xa8ed15); // Set particle color to match obstacle green tint
game.addChild(particle);
}
// Play destroy sound when an obstacle is destroyed by the player with the shield
LK.getSound('destroy').play();
obstacles[i].destroy();
obstacles.splice(i, 1);
} else {
LK.effects.flashScreen(0xffffff, 1000);
// Calculate final score
var finalScore = Math.floor(milesTraveled) + score * 100;
LK.setScore(finalScore);
// Display final score
var finalScoreTxt = new Text2('Final Score: ' + finalScore, {
size: 100,
fill: "#ffffff",
stroke: "#000000",
strokeThickness: 5,
border: true,
borderColor: "#000000",
borderWidth: 3
});
finalScoreTxt.anchor.set(0.5, 0.5);
finalScoreTxt.x = 2048 / 2;
finalScoreTxt.y = 2732 / 2;
LK.gui.center.addChild(finalScoreTxt);
// Calculate final score
var finalScore = Math.floor(milesTraveled) + score * 100;
// Display final score
if (!finalScoreTxt) {
finalScoreTxt = new Text2('Final Score: ' + finalScore, {
size: 100,
fill: "#ffffff",
stroke: "#000000",
strokeThickness: 5,
border: true,
borderColor: "#000000",
borderWidth: 3
});
finalScoreTxt.anchor.set(0.5, 0.5);
finalScoreTxt.x = 2048 / 2;
finalScoreTxt.y = 2732 / 2;
LK.gui.center.addChild(finalScoreTxt);
} else {
finalScoreTxt.setText('Final Score: ' + LK.getScore());
finalScoreTxt.visible = true;
}
// Calculate final score
var finalScore = Math.floor(milesTraveled) + score * 100;
// Display final score
if (!finalScoreTxt) {
finalScoreTxt = new Text2('Final Score: ' + finalScore, {
size: 100,
fill: "#ffffff",
stroke: "#000000",
strokeThickness: 5,
border: true,
borderColor: "#000000",
borderWidth: 3
});
finalScoreTxt.anchor.set(0.5, 0.5);
finalScoreTxt.x = 2048 / 2;
finalScoreTxt.y = 2732 / 2;
LK.gui.center.addChild(finalScoreTxt);
} else {
finalScoreTxt.setText('Final Score: ' + finalScore);
finalScoreTxt.visible = true;
}
LK.getSound('gameover').play(); // Play gameover sound
LK.stopMusic(); // Stop background music
// Create a new black asset that covers the whole screen
var gameOverCover = LK.getAsset('blackCover', {
width: 2048,
height: 2732,
color: 0x000000,
shape: 'box',
alpha: 1
});
game.addChildAt(gameOverCover, game.children.length);
player.destroy();
scoreTxt.destroy();
scoreBackground.destroy();
milesBackground.destroy();
milesTxt.destroy();
LK.setTimeout(function () {
LK.showGameOver(); // Calling this will destroy the 'Game' and reset entire game state.
}, 100); // Wait for 1 second (1000ms) before showing game over screen
}
}
}
// Handle obstacle spawning based on configuration
obstacleSpawnTimer++;
if (obstacleSpawnTimer >= obstacleSpawnOrder[currentObstacleIndex].interval) {
var obstacleType = obstacleSpawnOrder[currentObstacleIndex].type;
if (obstacleType === 'BigObstacle') {
spawnBigObstacle();
} else if (obstacleType === 'LineObstacle') {
spawnObstacle();
} else if (obstacleType === 'Obstacle') {
spawnObstacle();
} else if (obstacleType === 'SmallObstacle') {
spawnSmallObstacle();
} else if (obstacleType === 'SmallObstacleLeftMiddleCoinRight') {
spawnSmallObstacleLeftMiddleCoinRight();
} else if (obstacleType === 'SmallObstacleRightCenterCoinLeft') {
spawnSmallObstacleRightCenterCoinLeft();
} else if (obstacleType === 'SmallObstacleCenterCoinLeftPowerUpRight') {
spawnSmallObstacleCenterCoinLeftPowerUpRight();
} else if (obstacleType === 'TextObstacle') {
var customText = obstacleSpawnOrder[currentObstacleIndex].text || 'Default Text';
spawnTextObstacle(customText);
} else if (obstacleType === 'ObstacleLine') {
spawnObstacleLine();
} else if (obstacleType === 'SmallObstaclesSidesCoinMiddle') {
spawnSmallObstaclesSidesCoinMiddle();
} else if (obstacleType === 'SmallObstacleCenterCoinSides') {
spawnSmallObstacleCenterCoinSides();
} else if (obstacleType === 'SmallObstacleMiddlePowerUpLeftCoinRight') {
spawnSmallObstacleMiddlePowerUpLeftCoinRight();
} else if (obstacleType === 'PowerUpCenterLane') {
spawnPowerUpCenterLane();
} else if (obstacleType === 'StairedSmallObstacles') {
spawnStairedSmallObstacles();
}
currentObstacleIndex++;
if (currentObstacleIndex >= obstacleSpawnOrder.length) {
currentObstacleIndex = 0;
if (obstacleSpawnOrder === obstacleSpawnOrderRandom) {
obstacleSpawnOrder = obstacleSpawnOrderRandom.sort(function () {
return Math.random() - 0.5;
});
} else {
obstacleSpawnOrder = obstacleSpawnOrderRandom;
}
}
obstacleSpawnTimer = 0;
}
// Handle split duration and animate back to center
if (splitTimer > 0) {
splitTimer--;
if (LK.ticks % 600 == 0) {
splitDuration = Math.max(1, Math.floor(splitDuration * 0.95)); // Reduce split duration by 5% every 10 seconds
}
if (splitTimer === 0) {
// Animate leftPlayer and rightPlayer back to the center
var centerX = player.x;
var animationDuration = 20; // Duration in frames (0.33 seconds at 60 FPS)
// Initialize update functions after adding to game
leftPlayer.update = function () {
if (animationDuration > 0) {
leftPlayer.x += (centerX - leftPlayer.x) * 0.1; // Smooth movement using linear interpolation
animationDuration--;
} else {
leftPlayer.destroy();
leftPlayer = null;
player.visible = true;
player.hitbox = [player]; // Reset player hitbox to original player
// Play swipe sound when player merges back together
LK.getSound('swipe').play();
}
// Add any specific update logic for LeftPlayer here
if (LK.ticks % 4 == 0) {
var trail = new Trail();
trail.scale.x = 0.5;
trail.scale.y = 0.5;
trail.x = leftPlayer ? leftPlayer.x : 0;
trail.y = leftPlayer.y + leftPlayer.height / 2;
game.addChildAt(trail, game.getChildIndex(leftPlayer));
}
};
rightPlayer.update = function () {
if (animationDuration > 0) {
rightPlayer.x += (centerX - rightPlayer.x) * 0.1; // Smooth movement using linear interpolation
animationDuration--;
} else {
rightPlayer.destroy();
rightPlayer = null;
player.visible = true;
player.hitbox = [player]; // Reset player hitbox to original player
// Play swipe sound when player merges back together
LK.getSound('swipe').play();
}
// Add any specific update logic for RightPlayer here
if (LK.ticks % 4 == 0) {
var trail = new Trail();
trail.scale.x = 0.5;
trail.scale.y = 0.5;
trail.x = rightPlayer ? rightPlayer.x : 0;
trail.y = rightPlayer.y + rightPlayer.height / 2;
game.addChildAt(trail, game.getChildIndex(rightPlayer));
}
};
}
}
for (var i = coins.length - 1; i >= 0; i--) {
coins[i].y += gameSpeed;
coins[i].update();
if (player && !player.isJumping && player.hitbox.some(function (hitbox) {
return checkBoundingBoxCollision(hitbox, coins[i]);
})) {
score += 1;
scoreTxt.setText(score);
// Play bling sound
LK.getSound('bling').play();
// Spawn particles
for (var j = 0; j < 10; j++) {
var particle = new Particle();
particle.x = coins[i].x;
particle.y = coins[i].y;
particle.setTint(0xffffff); // Set particle color to white
game.addChild(particle);
}
coins[i].destroy();
coins.splice(i, 1);
}
}
for (var i = powerups.length - 1; i >= 0; i--) {
powerups[i].y += gameSpeed;
powerups[i].update();
if (player && !player.isJumping && player.hitbox.some(function (hitbox) {
return checkBoundingBoxCollision(hitbox, powerups[i]);
})) {
player.isInvulnerable = true;
player.invulnerableTimer = 600; // 10 seconds at 60 FPS
LK.getSound('powerup').play(); // Play powerup sound
LK.getSound('powerup').play(); // Play powerup sound
powerups[i].destroy();
powerups.splice(i, 1);
}
}
// Automatic spawning of obstacles, coins, and powerups has been removed
};
// Function to spawn SmallObstacle
function spawnSmallObstacle() {
var smallObstacle = new SmallObstacle();
smallObstacle.x = 2048 / 2; // Center the SmallObstacle
smallObstacle.y = -smallObstacle.height * 2;
smallObstacle.speed = gameSpeed; // Ensure constant speed
if (!obstacles) {
obstacles = [];
}
obstacles.push(smallObstacle);
game.addChild(smallObstacle);
}
// Function to spawn SmallObstacle on left and middle lanes, and Coin on right lane
function spawnSmallObstacleLeftMiddleCoinRight() {
var smallObstacleLeft = new SmallObstacle();
var smallObstacleMiddle = new SmallObstacle();
var coinRight = new Coin();
smallObstacleLeft.x = lanes[0]; // Left lane
smallObstacleMiddle.x = lanes[1]; // Middle lane
coinRight.x = lanes[2]; // Right lane
smallObstacleLeft.y = smallObstacleMiddle.y = coinRight.y = -smallObstacleLeft.height * 2;
if (!obstacles) {
obstacles = [];
}
if (!coins) {
coins = [];
}
obstacles.push(smallObstacleLeft);
obstacles.push(smallObstacleMiddle);
coins.push(coinRight);
game.addChild(smallObstacleLeft);
game.addChild(smallObstacleMiddle);
game.addChild(coinRight);
// Ensure both obstacles and coin have the same speed
var obstacleSpeed = gameSpeed;
smallObstacleLeft.speed = smallObstacleMiddle.speed = coinRight.speed = obstacleSpeed;
// Attach the obstacles together
smallObstacleLeft.update = function () {
this.y += this.speed;
smallObstacleMiddle.y = this.y; // Move middle obstacle with left obstacle
if (this.y > 2732 + this.height / 2) {
this.destroy();
smallObstacleMiddle.destroy();
}
};
smallObstacleMiddle.update = function () {
// Empty update function to prevent individual movement
};
}
// Function to spawn SmallObstacle on right and center lanes, and Coin on left lane
function spawnSmallObstacleRightCenterCoinLeft() {
var smallObstacleRight = new SmallObstacle();
var smallObstacleCenter = new SmallObstacle();
var coinLeft = new Coin();
smallObstacleRight.x = lanes[2]; // Right lane
smallObstacleCenter.x = lanes[1]; // Center lane
coinLeft.x = lanes[0]; // Left lane
smallObstacleRight.y = smallObstacleCenter.y = coinLeft.y = -smallObstacleRight.height * 2;
if (!obstacles) {
obstacles = [];
}
if (!coins) {
coins = [];
}
obstacles.push(smallObstacleRight);
obstacles.push(smallObstacleCenter);
coins.push(coinLeft);
game.addChild(smallObstacleRight);
game.addChild(smallObstacleCenter);
game.addChild(coinLeft);
// Ensure both obstacles and coin have the same speed
var obstacleSpeed = gameSpeed;
smallObstacleRight.speed = smallObstacleCenter.speed = coinLeft.speed = obstacleSpeed;
// Attach the obstacles together
smallObstacleRight.update = function () {
this.y += this.speed;
smallObstacleCenter.y = this.y; // Move center obstacle with right obstacle
if (this.y > 2732 + this.height / 2) {
this.destroy();
smallObstacleCenter.destroy();
}
};
smallObstacleCenter.update = function () {
// Empty update function to prevent individual movement
};
}
// Function to spawn a line of obstacles
function spawnObstacleLine() {
for (var i = 0; i < lanes.length; i++) {
var obstacle = new Obstacle();
obstacle.x = lanes[i];
obstacle.y = -obstacle.height * 2;
if (!obstacles) {
obstacles = [];
}
obstacles.push(obstacle);
game.addChild(obstacle);
}
}
function spawnSmallObstacleCenterCoinLeftPowerUpRight() {
var smallObstacleCenter = new SmallObstacle();
smallObstacleCenter.x = lanes[1]; // Center lane
smallObstacleCenter.y = -smallObstacleCenter.height * 2;
smallObstacleCenter.speed = gameSpeed; // Ensure constant speed
if (!obstacles) {
obstacles = [];
}
obstacles.push(smallObstacleCenter);
game.addChild(smallObstacleCenter);
var coinLeft = new Coin();
coinLeft.x = lanes[0]; // Left lane
coinLeft.y = -coinLeft.height * 2;
coinLeft.speed = gameSpeed; // Ensure constant speed
if (!coins) {
coins = [];
}
coins.push(coinLeft);
game.addChild(coinLeft);
var powerUpRight = new PowerUp();
powerUpRight.x = lanes[2]; // Right lane
powerUpRight.y = -powerUpRight.height * 2;
powerUpRight.speed = gameSpeed; // Ensure constant speed
if (!powerups) {
powerups = [];
}
powerups.push(powerUpRight);
game.addChild(powerUpRight);
}
// Function to spawn SmallObstacles on the sides and a Coin in the middle
function spawnSmallObstaclesSidesCoinMiddle() {
var smallObstacleLeft = new SmallObstacle();
smallObstacleLeft.x = lanes[0]; // Left lane
smallObstacleLeft.y = -smallObstacleLeft.height * 2;
smallObstacleLeft.speed = gameSpeed; // Ensure constant speed
if (!obstacles) {
obstacles = [];
}
obstacles.push(smallObstacleLeft);
game.addChild(smallObstacleLeft);
var smallObstacleRight = new SmallObstacle();
smallObstacleRight.x = lanes[2]; // Right lane
smallObstacleRight.y = -smallObstacleRight.height * 2;
smallObstacleRight.speed = gameSpeed; // Ensure constant speed
obstacles.push(smallObstacleRight);
game.addChild(smallObstacleRight);
var coinMiddle = new Coin();
coinMiddle.x = lanes[1]; // Middle lane
coinMiddle.y = -coinMiddle.height * 2;
coinMiddle.speed = gameSpeed; // Ensure constant speed
if (!coins) {
coins = [];
}
coins.push(coinMiddle);
game.addChild(coinMiddle);
}
// Function to spawn SmallObstacle in the center and Coins on the sides
function spawnSmallObstacleCenterCoinSides() {
var smallObstacleCenter = new SmallObstacleCenterCoinSides();
smallObstacleCenter.x = lanes[1]; // Center lane
smallObstacleCenter.y = -smallObstacleCenter.height * 2;
smallObstacleCenter.speed = gameSpeed; // Ensure constant speed
if (!obstacles) {
obstacles = [];
}
obstacles.push(smallObstacleCenter);
game.addChild(smallObstacleCenter);
var coinLeft = new Coin();
coinLeft.x = lanes[0]; // Left lane
coinLeft.y = -coinLeft.height * 2;
coinLeft.speed = gameSpeed; // Ensure constant speed
if (!coins) {
coins = [];
}
coins.push(coinLeft);
game.addChild(coinLeft);
var coinRight = new Coin();
coinRight.x = lanes[2]; // Right lane
coinRight.y = -coinRight.height * 2;
coinRight.speed = gameSpeed; // Ensure constant speed
coins.push(coinRight);
game.addChild(coinRight);
}
var starfield = [];
for (var i = 0; i < 25; i++) {
var star = new Star();
star.scale.set(Math.random() * 1.5 + 0.5); // Random size between 0.5 and 2.0
star.x = Math.random() * 2048;
star.y = Math.random() * 2732;
star.scale.set(Math.random() * 1.5 + 0.5); // Random size between 0.5 and 2.0
starfield.push(star);
game.addChildAt(star, 0); // Add stars at the bottom of the z axis
}
// Initialize miles traveled
var milesTraveled = 0;
// Create miles traveled text
var milesTxt = new Text2('Miles: 0', {
size: 100,
fill: "#ffffff",
stroke: "#000000",
strokeThickness: 5,
border: true,
borderColor: "#000000",
borderWidth: 3
});
milesTxt.anchor.set(1, 0); // Anchor to the top-right corner
milesTxt.x = 2048; // Position at the top-right corner
milesTxt.y = 0;
LK.gui.topRight.addChild(milesTxt);
// Initialize miles traveled
var milesTraveled = 0;
// Create miles traveled text
var milesTxt = new Text2('0', {
size: 50,
fill: "#ffffff",
stroke: "#000000",
strokeThickness: 5,
border: true,
borderColor: "#000000",
borderWidth: 3
});
var milesBackground = LK.getAsset('milesBackground', {
anchorX: 0.5,
anchorY: 0.5,
x: scoreTxt.x - 50,
y: scoreTxt.y - 90
});
milesTxt.anchor.set(0.5, 0);
milesTxt.x = scoreTxt.x - 10;
milesTxt.y = scoreTxt.y - 120;
milesTxt.visible = false; // Hide miles on main menu
milesBackground.visible = false; // Hide miles background on main menu
LK.gui.top.addChild(milesBackground);
LK.gui.top.addChild(milesTxt);
cartoon white circle. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
cartoon light blue circle. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
cartoon white square. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
black rectangle