/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var Bleacher = Container.expand(function () { var self = Container.call(this); var bleacherGraphics = self.attachAsset('bleacher', { anchorX: 0.5, anchorY: 0.5 }); // Keep a reference to the width and height self.width = bleacherGraphics.width; self.height = bleacherGraphics.height; self.isVIP = false; // Method to set as VIP bleacher self.setVIP = function () { self.isVIP = true; bleacherGraphics.tint = 0xFFD700; // Gold color }; return self; }); var CrowdWave = Container.expand(function () { var self = Container.call(this); var graphic = self.attachAsset('crowdWave', { anchorX: 0.5, anchorY: 0.5, alpha: 0.6 }); self.speed = 10; self.direction = 1; // 1 for right, -1 for left self.active = true; // Update method self.update = function () { if (!self.active) { return; } // Move the wave self.x += self.speed * self.direction; // If off screen, remove if (self.direction > 0 && self.x > 2048 + graphic.width / 2 || self.direction < 0 && self.x < -graphic.width / 2) { self.active = false; self.parent.removeChild(self); } }; return self; }); var Memorabilia = Container.expand(function () { var self = Container.call(this); var graphic = self.attachAsset('memorabilia', { anchorX: 0.5, anchorY: 0.5 }); self.type = 'jersey'; // Default type self.value = 10; self.velocityY = 0; self.gravity = 0.2; self.isCollected = false; // Set the type of memorabilia self.setType = function (type) { self.type = type; // Adjust appearance based on type switch (type) { case 'jersey': graphic.tint = 0x3498db; self.value = 10; break; case 'pennant': graphic.tint = 0xe74c3c; graphic.rotation = Math.PI / 4; // 45 degrees self.value = 15; break; case 'foamFinger': graphic.tint = 0xf1c40f; graphic.rotation = Math.PI / 8; self.value = 20; break; } }; // Apply floating animation self.startFloating = function () { self.floatOffset = Math.random() * Math.PI * 2; tween(self, { y: self.y - 20 }, { duration: 1000 + Math.random() * 500, easing: tween.sinceOut, onFinish: function onFinish() { tween(self, { y: self.y + 20 }, { duration: 1000 + Math.random() * 500, easing: tween.sinceIn, onFinish: function onFinish() { self.startFloating(); } }); } }); }; // Update method self.update = function () { if (self.isCollected) { // Float up when collected self.y -= 5; self.alpha -= 0.05; if (self.alpha <= 0) { self.parent.removeChild(self); } } }; // Collect this item self.collect = function () { if (!self.isCollected) { self.isCollected = true; LK.getSound('collect').play(); // Add score LK.setScore(LK.getScore() + self.value); // Show score popup var scorePopup = new Text2("+" + self.value, { size: 40, fill: 0xFFFFFF }); scorePopup.anchor.set(0.5, 0.5); scorePopup.x = self.x; scorePopup.y = self.y - 40; self.parent.addChild(scorePopup); // Animate score popup tween(scorePopup, { y: scorePopup.y - 80, alpha: 0 }, { duration: 800, easing: tween.easeOut, onFinish: function onFinish() { scorePopup.parent.removeChild(scorePopup); } }); } }; return self; }); var Obstacle = Container.expand(function () { var self = Container.call(this); var graphic = self.attachAsset('obstacle', { anchorX: 0.5, anchorY: 0.5 }); self.type = 'trash'; // Default type self.velocityX = 0; self.active = true; // Set the type of obstacle self.setType = function (type) { self.type = type; switch (type) { case 'trash': graphic.tint = 0x8e44ad; break; case 'spill': graphic.tint = 0x2980b9; graphic.scaleY = 0.5; graphic.scaleX = 1.5; break; case 'fan': graphic.tint = 0x27ae60; graphic.rotation = Math.PI / 6; self.velocityX = Math.random() > 0.5 ? 3 : -3; break; } }; // Update method self.update = function () { if (!self.active) { return; } // Moving obstacles if (self.type === 'fan') { self.x += self.velocityX; // Bounce off edges if (self.x < 100 || self.x > 2048 - 100) { self.velocityX *= -1; graphic.scaleX *= -1; } } }; return self; }); var Player = Container.expand(function () { var self = Container.call(this); // Player graphics var playerGraphics = self.attachAsset('player', { anchorX: 0.5, anchorY: 0.5 }); // Player physics properties self.velocityY = 0; self.velocityX = 0; self.jumpForce = -25; self.gravity = 1; self.isJumping = false; self.canJump = true; self.facing = 1; // 1 = right, -1 = left self.isActive = true; self.powerupActive = false; self.powerupType = null; // Jump method self.jump = function () { if (self.canJump && !self.isJumping) { self.velocityY = self.jumpForce; self.isJumping = true; self.canJump = false; LK.getSound('jump').play(); // Show jump animation tween(playerGraphics, { scaleY: 1.3, scaleX: 0.8 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { tween(playerGraphics, { scaleY: 1, scaleX: 1 }, { duration: 200, easing: tween.easeIn }); } }); } }; // Update method for physics self.update = function () { if (!self.isActive) { return; } // Apply gravity self.velocityY += self.gravity; // Apply velocity self.y += self.velocityY; self.x += self.velocityX * self.facing; // Slow down horizontal movement self.velocityX *= 0.9; // Boundary checks if (self.x < 50) { self.x = 50; self.facing = 1; } else if (self.x > 2048 - 50) { self.x = 2048 - 50; self.facing = -1; } // Update facing direction visual if (self.velocityX > 0.5) { playerGraphics.scaleX = 1; } else if (self.velocityX < -0.5) { playerGraphics.scaleX = -1; } // Flash effect for powerup if (self.powerupActive) { playerGraphics.alpha = Math.sin(LK.ticks * 0.2) * 0.3 + 0.7; } else { playerGraphics.alpha = 1; } }; // Activate powerup self.activatePowerup = function (type) { self.powerupActive = true; self.powerupType = type; // Apply powerup effect switch (type) { case 'jersey': // Jersey gives super jump self.jumpForce = -30; playerGraphics.tint = 0x3498db; break; case 'pennant': // Pennant gives speed boost self.velocityX = 15; playerGraphics.tint = 0xe74c3c; break; case 'foamFinger': // Foam finger gives invulnerability playerGraphics.tint = 0xf1c40f; break; } // Clear existing timeout if (self.powerupTimeout) { LK.clearTimeout(self.powerupTimeout); } // End powerup after 5 seconds self.powerupTimeout = LK.setTimeout(function () { self.deactivatePowerup(); }, 5000); }; // Deactivate powerup self.deactivatePowerup = function () { self.powerupActive = false; self.powerupType = null; self.jumpForce = -25; playerGraphics.tint = 0xFFFFFF; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x3498db // Sky blue background }); /**** * Game Code ****/ // Game variables var player; var bleachers = []; var memorabilia = []; var obstacles = []; var crowdWaves = []; var isGameActive = false; var gameLevel = 1; var scoreText; var levelText; var lastSpawnTime = 0; var lastWaveTime = 0; var bleacherLevelHeight = 150; // Height between bleacher rows var vipFrequency = 4; // Every X bleachers is a VIP // Initialize game elements function initGame() { // Set up score display scoreText = new Text2("SCORE: 0", { size: 60, fill: 0xFFFFFF }); scoreText.anchor.set(0.5, 0); LK.gui.top.addChild(scoreText); // Set up level display levelText = new Text2("LEVEL: 1", { size: 40, fill: 0xFFFFFF }); levelText.anchor.set(1, 0); levelText.x = 150; levelText.y = 70; LK.gui.topRight.addChild(levelText); // Reset score LK.setScore(0); updateScoreDisplay(); // Create player player = new Player(); player.x = 2048 / 2; player.y = 2732 - 300; game.addChild(player); // Generate initial bleachers generateBleachers(); // Start the game isGameActive = true; // Play background music LK.playMusic('gameMusic'); } // Generate bleachers function generateBleachers() { // Clear any existing bleachers for (var i = 0; i < bleachers.length; i++) { game.removeChild(bleachers[i]); } bleachers = []; // Create bleachers var numRows = 15 + gameLevel * 2; var startHeight = 2732 - 200; for (var row = 0; row < numRows; row++) { var rowY = startHeight - row * bleacherLevelHeight; var numBleachersInRow = 5 + Math.floor(Math.random() * 3); var rowWidth = numBleachersInRow * 250; var startX = (2048 - rowWidth) / 2 + Math.random() * 300 - 150; for (var i = 0; i < numBleachersInRow; i++) { var bleacher = new Bleacher(); bleacher.x = startX + i * 250 + Math.random() * 50; bleacher.y = rowY; // Randomly make some bleachers VIP sections if (row > 0 && row % vipFrequency === 0 && Math.random() < 0.3) { bleacher.setVIP(); } game.addChild(bleacher); bleachers.push(bleacher); // Add some obstacles and memorabilia based on level and position if (row > 1 && Math.random() < 0.2 + gameLevel * 0.05) { spawnObstacle(bleacher.x, bleacher.y - 50); } if (Math.random() < 0.15 + gameLevel * 0.02) { spawnMemorabilia(bleacher.x + (Math.random() * 100 - 50), bleacher.y - 100); } } } // Player starts on a bleacher at the bottom if (bleachers.length > 0) { player.x = bleachers[0].x; player.y = bleachers[0].y - 100; } } // Spawn a memorabilia item function spawnMemorabilia(x, y) { var item = new Memorabilia(); item.x = x; item.y = y; // Randomly select type var types = ['jersey', 'pennant', 'foamFinger']; var randomType = types[Math.floor(Math.random() * types.length)]; item.setType(randomType); // Start floating animation item.startFloating(); game.addChild(item); memorabilia.push(item); } // Spawn an obstacle function spawnObstacle(x, y) { var obstacle = new Obstacle(); obstacle.x = x; obstacle.y = y; // Randomly select type based on level var types = ['trash']; if (gameLevel >= 2) { types.push('spill'); } if (gameLevel >= 3) { types.push('fan'); } var randomType = types[Math.floor(Math.random() * types.length)]; obstacle.setType(randomType); game.addChild(obstacle); obstacles.push(obstacle); } // Spawn a crowd wave function spawnCrowdWave() { var wave = new CrowdWave(); // Start from left or right wave.direction = Math.random() > 0.5 ? 1 : -1; if (wave.direction > 0) { wave.x = -250; } else { wave.x = 2048 + 250; } // Randomize y position in middle section of screen wave.y = 800 + Math.random() * 1200; game.addChild(wave); crowdWaves.push(wave); // Play crowd cheer sound LK.getSound('crowdCheer').play(); } // Check if player is on a bleacher function checkBleacherCollisions() { var playerLanded = false; for (var i = 0; i < bleachers.length; i++) { var bleacher = bleachers[i]; // Only check if player is falling if (player.velocityY > 0) { // Check if player is above the bleacher and within horizontal bounds var playerBottom = player.y + 50; var bleacherTop = bleacher.y - bleacher.height / 2; var horizontalDistance = Math.abs(player.x - bleacher.x); if (playerBottom >= bleacherTop - 10 && playerBottom <= bleacherTop + 20 && horizontalDistance < bleacher.width / 2 - 20) { // Place player on top of bleacher player.y = bleacherTop - 50; player.velocityY = 0; player.isJumping = false; player.canJump = true; playerLanded = true; // If it's a VIP bleacher, give bonus if (bleacher.isVIP) { LK.getSound('vipCollect').play(); LK.setScore(LK.getScore() + 50); updateScoreDisplay(); // Visual feedback bleacher.setVIP = false; LK.effects.flashObject(bleacher, 0xFFD700, 500); // Show bonus text var bonusText = new Text2("VIP BONUS +50", { size: 50, fill: 0xFFD700 }); bonusText.anchor.set(0.5, 0.5); bonusText.x = bleacher.x; bonusText.y = bleacher.y - 80; game.addChild(bonusText); // Animate bonus text tween(bonusText, { y: bonusText.y - 100, alpha: 0 }, { duration: 1200, easing: tween.easeOut, onFinish: function onFinish() { game.removeChild(bonusText); } }); } break; } } } // If the player fell off the bottom of the screen if (player.y > 2732 + 100 && isGameActive) { // Instead of game over, make the player jump gradually player.velocityY = player.jumpForce / 2; // Half the jump force for a smaller jump player.isJumping = true; player.canJump = false; LK.getSound('jump').play(); } return playerLanded; } // Check collisions with memorabilia function checkMemorabilia() { for (var i = memorabilia.length - 1; i >= 0; i--) { var item = memorabilia[i]; if (!item.isCollected && player.intersects(item)) { // Collect item item.collect(); // Apply powerup effect player.activatePowerup(item.type); // Update score display updateScoreDisplay(); // Remove from array memorabilia.splice(i, 1); } else if (item.isCollected && item.alpha <= 0) { // Clean up collected items memorabilia.splice(i, 1); } else { // Update item physics item.update(); } } } // Check collisions with obstacles function checkObstacles() { for (var i = 0; i < obstacles.length; i++) { var obstacle = obstacles[i]; // Update obstacle obstacle.update(); // Check for collision only if player is not invulnerable if (player.intersects(obstacle) && player.isActive && !(player.powerupActive && player.powerupType === 'foamFinger')) { // Hit by obstacle LK.getSound('hit').play(); LK.effects.flashScreen(0xFF0000, 300); // Knock the player back player.velocityY = -15; player.velocityX = player.x > obstacle.x ? 10 : -10; player.isJumping = true; // Reduce score LK.setScore(Math.max(0, LK.getScore() - 25)); updateScoreDisplay(); // Temporarily disable player player.isActive = false; player.alpha = 0.5; LK.setTimeout(function () { player.isActive = true; player.alpha = 1; }, 1000); } } } // Check interactions with crowd waves function checkCrowdWaves() { for (var i = crowdWaves.length - 1; i >= 0; i--) { var wave = crowdWaves[i]; // Update wave wave.update(); // Check if player touches wave if (player.intersects(wave) && player.isActive) { // Boost player in wave direction player.velocityX = 15 * wave.direction; player.facing = wave.direction; // Slight upward boost if (player.velocityY > 0) { player.velocityY = -5; } // Remove the wave game.removeChild(wave); crowdWaves.splice(i, 1); } // Clean up inactive waves if (!wave.active) { crowdWaves.splice(i, 1); } } } // Check if player has reached the top function checkLevelComplete() { if (player.y < 300 && isGameActive) { // Level complete! isGameActive = false; // Play victory sound LK.getSound('crowdCheer').play(); LK.getSound('vipCollect').play(); // Show level complete text var levelCompleteText = new Text2("LEVEL " + gameLevel + " COMPLETE!", { size: 80, fill: 0xFFD700 }); levelCompleteText.anchor.set(0.5, 0.5); levelCompleteText.x = 2048 / 2; levelCompleteText.y = 2732 / 2; game.addChild(levelCompleteText); // Add level bonus var bonus = gameLevel * 100; LK.setScore(LK.getScore() + bonus); updateScoreDisplay(); // Show bonus text var bonusText = new Text2("LEVEL BONUS: +" + bonus, { size: 60, fill: 0xFFFFFF }); bonusText.anchor.set(0.5, 0.5); bonusText.x = 2048 / 2; bonusText.y = 2732 / 2 + 100; game.addChild(bonusText); // Wait and then start next level LK.setTimeout(function () { game.removeChild(levelCompleteText); game.removeChild(bonusText); // Increase level gameLevel++; levelText.setText("LEVEL: " + gameLevel); // Clean up objects for (var i = 0; i < memorabilia.length; i++) { game.removeChild(memorabilia[i]); } memorabilia = []; for (var i = 0; i < obstacles.length; i++) { game.removeChild(obstacles[i]); } obstacles = []; for (var i = 0; i < crowdWaves.length; i++) { game.removeChild(crowdWaves[i]); } crowdWaves = []; // Generate new level generateBleachers(); // Reset player position if (bleachers.length > 0) { player.x = bleachers[0].x; player.y = bleachers[0].y - 100; } // Restore game state isGameActive = true; }, 3000); } } // Game over function function gameOver() { if (!isGameActive) { return; } isGameActive = false; // Save high score var highScore = storage.highScore || 0; if (LK.getScore() > highScore) { storage.highScore = LK.getScore(); storage.highLevel = gameLevel; } // Show game over LK.showGameOver(); } // Update score display function updateScoreDisplay() { scoreText.setText("SCORE: " + LK.getScore()); } // Handle down event game.down = function (x, y, obj) { if (isGameActive && player.isActive) { player.jump(); // Add a small horizontal movement based on tap position if (x < player.x) { player.velocityX = -6; player.facing = -1; } else { player.velocityX = 6; player.facing = 1; } } }; // Game update loop game.update = function () { if (!isGameActive) { return; } // Update player player.update(); // Check collisions with bleachers checkBleacherCollisions(); // Check memorabilia collection checkMemorabilia(); // Check obstacle collisions checkObstacles(); // Check crowd wave interactions checkCrowdWaves(); // Check if level is complete checkLevelComplete(); // Periodically spawn crowd waves if (LK.ticks - lastWaveTime > 300 && Math.random() < 0.01 * gameLevel) { spawnCrowdWave(); lastWaveTime = LK.ticks; } // Camera follows player (with some limits) if (player.y < 2732 / 2) { var targetY = 2732 / 2 - player.y; game.y = Math.min(Math.max(targetY, -2000), 0); } else { game.y = 0; } }; // Initialize the game initGame();
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Bleacher = Container.expand(function () {
var self = Container.call(this);
var bleacherGraphics = self.attachAsset('bleacher', {
anchorX: 0.5,
anchorY: 0.5
});
// Keep a reference to the width and height
self.width = bleacherGraphics.width;
self.height = bleacherGraphics.height;
self.isVIP = false;
// Method to set as VIP bleacher
self.setVIP = function () {
self.isVIP = true;
bleacherGraphics.tint = 0xFFD700; // Gold color
};
return self;
});
var CrowdWave = Container.expand(function () {
var self = Container.call(this);
var graphic = self.attachAsset('crowdWave', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.6
});
self.speed = 10;
self.direction = 1; // 1 for right, -1 for left
self.active = true;
// Update method
self.update = function () {
if (!self.active) {
return;
}
// Move the wave
self.x += self.speed * self.direction;
// If off screen, remove
if (self.direction > 0 && self.x > 2048 + graphic.width / 2 || self.direction < 0 && self.x < -graphic.width / 2) {
self.active = false;
self.parent.removeChild(self);
}
};
return self;
});
var Memorabilia = Container.expand(function () {
var self = Container.call(this);
var graphic = self.attachAsset('memorabilia', {
anchorX: 0.5,
anchorY: 0.5
});
self.type = 'jersey'; // Default type
self.value = 10;
self.velocityY = 0;
self.gravity = 0.2;
self.isCollected = false;
// Set the type of memorabilia
self.setType = function (type) {
self.type = type;
// Adjust appearance based on type
switch (type) {
case 'jersey':
graphic.tint = 0x3498db;
self.value = 10;
break;
case 'pennant':
graphic.tint = 0xe74c3c;
graphic.rotation = Math.PI / 4; // 45 degrees
self.value = 15;
break;
case 'foamFinger':
graphic.tint = 0xf1c40f;
graphic.rotation = Math.PI / 8;
self.value = 20;
break;
}
};
// Apply floating animation
self.startFloating = function () {
self.floatOffset = Math.random() * Math.PI * 2;
tween(self, {
y: self.y - 20
}, {
duration: 1000 + Math.random() * 500,
easing: tween.sinceOut,
onFinish: function onFinish() {
tween(self, {
y: self.y + 20
}, {
duration: 1000 + Math.random() * 500,
easing: tween.sinceIn,
onFinish: function onFinish() {
self.startFloating();
}
});
}
});
};
// Update method
self.update = function () {
if (self.isCollected) {
// Float up when collected
self.y -= 5;
self.alpha -= 0.05;
if (self.alpha <= 0) {
self.parent.removeChild(self);
}
}
};
// Collect this item
self.collect = function () {
if (!self.isCollected) {
self.isCollected = true;
LK.getSound('collect').play();
// Add score
LK.setScore(LK.getScore() + self.value);
// Show score popup
var scorePopup = new Text2("+" + self.value, {
size: 40,
fill: 0xFFFFFF
});
scorePopup.anchor.set(0.5, 0.5);
scorePopup.x = self.x;
scorePopup.y = self.y - 40;
self.parent.addChild(scorePopup);
// Animate score popup
tween(scorePopup, {
y: scorePopup.y - 80,
alpha: 0
}, {
duration: 800,
easing: tween.easeOut,
onFinish: function onFinish() {
scorePopup.parent.removeChild(scorePopup);
}
});
}
};
return self;
});
var Obstacle = Container.expand(function () {
var self = Container.call(this);
var graphic = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 0.5
});
self.type = 'trash'; // Default type
self.velocityX = 0;
self.active = true;
// Set the type of obstacle
self.setType = function (type) {
self.type = type;
switch (type) {
case 'trash':
graphic.tint = 0x8e44ad;
break;
case 'spill':
graphic.tint = 0x2980b9;
graphic.scaleY = 0.5;
graphic.scaleX = 1.5;
break;
case 'fan':
graphic.tint = 0x27ae60;
graphic.rotation = Math.PI / 6;
self.velocityX = Math.random() > 0.5 ? 3 : -3;
break;
}
};
// Update method
self.update = function () {
if (!self.active) {
return;
}
// Moving obstacles
if (self.type === 'fan') {
self.x += self.velocityX;
// Bounce off edges
if (self.x < 100 || self.x > 2048 - 100) {
self.velocityX *= -1;
graphic.scaleX *= -1;
}
}
};
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
// Player graphics
var playerGraphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
// Player physics properties
self.velocityY = 0;
self.velocityX = 0;
self.jumpForce = -25;
self.gravity = 1;
self.isJumping = false;
self.canJump = true;
self.facing = 1; // 1 = right, -1 = left
self.isActive = true;
self.powerupActive = false;
self.powerupType = null;
// Jump method
self.jump = function () {
if (self.canJump && !self.isJumping) {
self.velocityY = self.jumpForce;
self.isJumping = true;
self.canJump = false;
LK.getSound('jump').play();
// Show jump animation
tween(playerGraphics, {
scaleY: 1.3,
scaleX: 0.8
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(playerGraphics, {
scaleY: 1,
scaleX: 1
}, {
duration: 200,
easing: tween.easeIn
});
}
});
}
};
// Update method for physics
self.update = function () {
if (!self.isActive) {
return;
}
// Apply gravity
self.velocityY += self.gravity;
// Apply velocity
self.y += self.velocityY;
self.x += self.velocityX * self.facing;
// Slow down horizontal movement
self.velocityX *= 0.9;
// Boundary checks
if (self.x < 50) {
self.x = 50;
self.facing = 1;
} else if (self.x > 2048 - 50) {
self.x = 2048 - 50;
self.facing = -1;
}
// Update facing direction visual
if (self.velocityX > 0.5) {
playerGraphics.scaleX = 1;
} else if (self.velocityX < -0.5) {
playerGraphics.scaleX = -1;
}
// Flash effect for powerup
if (self.powerupActive) {
playerGraphics.alpha = Math.sin(LK.ticks * 0.2) * 0.3 + 0.7;
} else {
playerGraphics.alpha = 1;
}
};
// Activate powerup
self.activatePowerup = function (type) {
self.powerupActive = true;
self.powerupType = type;
// Apply powerup effect
switch (type) {
case 'jersey':
// Jersey gives super jump
self.jumpForce = -30;
playerGraphics.tint = 0x3498db;
break;
case 'pennant':
// Pennant gives speed boost
self.velocityX = 15;
playerGraphics.tint = 0xe74c3c;
break;
case 'foamFinger':
// Foam finger gives invulnerability
playerGraphics.tint = 0xf1c40f;
break;
}
// Clear existing timeout
if (self.powerupTimeout) {
LK.clearTimeout(self.powerupTimeout);
}
// End powerup after 5 seconds
self.powerupTimeout = LK.setTimeout(function () {
self.deactivatePowerup();
}, 5000);
};
// Deactivate powerup
self.deactivatePowerup = function () {
self.powerupActive = false;
self.powerupType = null;
self.jumpForce = -25;
playerGraphics.tint = 0xFFFFFF;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x3498db // Sky blue background
});
/****
* Game Code
****/
// Game variables
var player;
var bleachers = [];
var memorabilia = [];
var obstacles = [];
var crowdWaves = [];
var isGameActive = false;
var gameLevel = 1;
var scoreText;
var levelText;
var lastSpawnTime = 0;
var lastWaveTime = 0;
var bleacherLevelHeight = 150; // Height between bleacher rows
var vipFrequency = 4; // Every X bleachers is a VIP
// Initialize game elements
function initGame() {
// Set up score display
scoreText = new Text2("SCORE: 0", {
size: 60,
fill: 0xFFFFFF
});
scoreText.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreText);
// Set up level display
levelText = new Text2("LEVEL: 1", {
size: 40,
fill: 0xFFFFFF
});
levelText.anchor.set(1, 0);
levelText.x = 150;
levelText.y = 70;
LK.gui.topRight.addChild(levelText);
// Reset score
LK.setScore(0);
updateScoreDisplay();
// Create player
player = new Player();
player.x = 2048 / 2;
player.y = 2732 - 300;
game.addChild(player);
// Generate initial bleachers
generateBleachers();
// Start the game
isGameActive = true;
// Play background music
LK.playMusic('gameMusic');
}
// Generate bleachers
function generateBleachers() {
// Clear any existing bleachers
for (var i = 0; i < bleachers.length; i++) {
game.removeChild(bleachers[i]);
}
bleachers = [];
// Create bleachers
var numRows = 15 + gameLevel * 2;
var startHeight = 2732 - 200;
for (var row = 0; row < numRows; row++) {
var rowY = startHeight - row * bleacherLevelHeight;
var numBleachersInRow = 5 + Math.floor(Math.random() * 3);
var rowWidth = numBleachersInRow * 250;
var startX = (2048 - rowWidth) / 2 + Math.random() * 300 - 150;
for (var i = 0; i < numBleachersInRow; i++) {
var bleacher = new Bleacher();
bleacher.x = startX + i * 250 + Math.random() * 50;
bleacher.y = rowY;
// Randomly make some bleachers VIP sections
if (row > 0 && row % vipFrequency === 0 && Math.random() < 0.3) {
bleacher.setVIP();
}
game.addChild(bleacher);
bleachers.push(bleacher);
// Add some obstacles and memorabilia based on level and position
if (row > 1 && Math.random() < 0.2 + gameLevel * 0.05) {
spawnObstacle(bleacher.x, bleacher.y - 50);
}
if (Math.random() < 0.15 + gameLevel * 0.02) {
spawnMemorabilia(bleacher.x + (Math.random() * 100 - 50), bleacher.y - 100);
}
}
}
// Player starts on a bleacher at the bottom
if (bleachers.length > 0) {
player.x = bleachers[0].x;
player.y = bleachers[0].y - 100;
}
}
// Spawn a memorabilia item
function spawnMemorabilia(x, y) {
var item = new Memorabilia();
item.x = x;
item.y = y;
// Randomly select type
var types = ['jersey', 'pennant', 'foamFinger'];
var randomType = types[Math.floor(Math.random() * types.length)];
item.setType(randomType);
// Start floating animation
item.startFloating();
game.addChild(item);
memorabilia.push(item);
}
// Spawn an obstacle
function spawnObstacle(x, y) {
var obstacle = new Obstacle();
obstacle.x = x;
obstacle.y = y;
// Randomly select type based on level
var types = ['trash'];
if (gameLevel >= 2) {
types.push('spill');
}
if (gameLevel >= 3) {
types.push('fan');
}
var randomType = types[Math.floor(Math.random() * types.length)];
obstacle.setType(randomType);
game.addChild(obstacle);
obstacles.push(obstacle);
}
// Spawn a crowd wave
function spawnCrowdWave() {
var wave = new CrowdWave();
// Start from left or right
wave.direction = Math.random() > 0.5 ? 1 : -1;
if (wave.direction > 0) {
wave.x = -250;
} else {
wave.x = 2048 + 250;
}
// Randomize y position in middle section of screen
wave.y = 800 + Math.random() * 1200;
game.addChild(wave);
crowdWaves.push(wave);
// Play crowd cheer sound
LK.getSound('crowdCheer').play();
}
// Check if player is on a bleacher
function checkBleacherCollisions() {
var playerLanded = false;
for (var i = 0; i < bleachers.length; i++) {
var bleacher = bleachers[i];
// Only check if player is falling
if (player.velocityY > 0) {
// Check if player is above the bleacher and within horizontal bounds
var playerBottom = player.y + 50;
var bleacherTop = bleacher.y - bleacher.height / 2;
var horizontalDistance = Math.abs(player.x - bleacher.x);
if (playerBottom >= bleacherTop - 10 && playerBottom <= bleacherTop + 20 && horizontalDistance < bleacher.width / 2 - 20) {
// Place player on top of bleacher
player.y = bleacherTop - 50;
player.velocityY = 0;
player.isJumping = false;
player.canJump = true;
playerLanded = true;
// If it's a VIP bleacher, give bonus
if (bleacher.isVIP) {
LK.getSound('vipCollect').play();
LK.setScore(LK.getScore() + 50);
updateScoreDisplay();
// Visual feedback
bleacher.setVIP = false;
LK.effects.flashObject(bleacher, 0xFFD700, 500);
// Show bonus text
var bonusText = new Text2("VIP BONUS +50", {
size: 50,
fill: 0xFFD700
});
bonusText.anchor.set(0.5, 0.5);
bonusText.x = bleacher.x;
bonusText.y = bleacher.y - 80;
game.addChild(bonusText);
// Animate bonus text
tween(bonusText, {
y: bonusText.y - 100,
alpha: 0
}, {
duration: 1200,
easing: tween.easeOut,
onFinish: function onFinish() {
game.removeChild(bonusText);
}
});
}
break;
}
}
}
// If the player fell off the bottom of the screen
if (player.y > 2732 + 100 && isGameActive) {
// Instead of game over, make the player jump gradually
player.velocityY = player.jumpForce / 2; // Half the jump force for a smaller jump
player.isJumping = true;
player.canJump = false;
LK.getSound('jump').play();
}
return playerLanded;
}
// Check collisions with memorabilia
function checkMemorabilia() {
for (var i = memorabilia.length - 1; i >= 0; i--) {
var item = memorabilia[i];
if (!item.isCollected && player.intersects(item)) {
// Collect item
item.collect();
// Apply powerup effect
player.activatePowerup(item.type);
// Update score display
updateScoreDisplay();
// Remove from array
memorabilia.splice(i, 1);
} else if (item.isCollected && item.alpha <= 0) {
// Clean up collected items
memorabilia.splice(i, 1);
} else {
// Update item physics
item.update();
}
}
}
// Check collisions with obstacles
function checkObstacles() {
for (var i = 0; i < obstacles.length; i++) {
var obstacle = obstacles[i];
// Update obstacle
obstacle.update();
// Check for collision only if player is not invulnerable
if (player.intersects(obstacle) && player.isActive && !(player.powerupActive && player.powerupType === 'foamFinger')) {
// Hit by obstacle
LK.getSound('hit').play();
LK.effects.flashScreen(0xFF0000, 300);
// Knock the player back
player.velocityY = -15;
player.velocityX = player.x > obstacle.x ? 10 : -10;
player.isJumping = true;
// Reduce score
LK.setScore(Math.max(0, LK.getScore() - 25));
updateScoreDisplay();
// Temporarily disable player
player.isActive = false;
player.alpha = 0.5;
LK.setTimeout(function () {
player.isActive = true;
player.alpha = 1;
}, 1000);
}
}
}
// Check interactions with crowd waves
function checkCrowdWaves() {
for (var i = crowdWaves.length - 1; i >= 0; i--) {
var wave = crowdWaves[i];
// Update wave
wave.update();
// Check if player touches wave
if (player.intersects(wave) && player.isActive) {
// Boost player in wave direction
player.velocityX = 15 * wave.direction;
player.facing = wave.direction;
// Slight upward boost
if (player.velocityY > 0) {
player.velocityY = -5;
}
// Remove the wave
game.removeChild(wave);
crowdWaves.splice(i, 1);
}
// Clean up inactive waves
if (!wave.active) {
crowdWaves.splice(i, 1);
}
}
}
// Check if player has reached the top
function checkLevelComplete() {
if (player.y < 300 && isGameActive) {
// Level complete!
isGameActive = false;
// Play victory sound
LK.getSound('crowdCheer').play();
LK.getSound('vipCollect').play();
// Show level complete text
var levelCompleteText = new Text2("LEVEL " + gameLevel + " COMPLETE!", {
size: 80,
fill: 0xFFD700
});
levelCompleteText.anchor.set(0.5, 0.5);
levelCompleteText.x = 2048 / 2;
levelCompleteText.y = 2732 / 2;
game.addChild(levelCompleteText);
// Add level bonus
var bonus = gameLevel * 100;
LK.setScore(LK.getScore() + bonus);
updateScoreDisplay();
// Show bonus text
var bonusText = new Text2("LEVEL BONUS: +" + bonus, {
size: 60,
fill: 0xFFFFFF
});
bonusText.anchor.set(0.5, 0.5);
bonusText.x = 2048 / 2;
bonusText.y = 2732 / 2 + 100;
game.addChild(bonusText);
// Wait and then start next level
LK.setTimeout(function () {
game.removeChild(levelCompleteText);
game.removeChild(bonusText);
// Increase level
gameLevel++;
levelText.setText("LEVEL: " + gameLevel);
// Clean up objects
for (var i = 0; i < memorabilia.length; i++) {
game.removeChild(memorabilia[i]);
}
memorabilia = [];
for (var i = 0; i < obstacles.length; i++) {
game.removeChild(obstacles[i]);
}
obstacles = [];
for (var i = 0; i < crowdWaves.length; i++) {
game.removeChild(crowdWaves[i]);
}
crowdWaves = [];
// Generate new level
generateBleachers();
// Reset player position
if (bleachers.length > 0) {
player.x = bleachers[0].x;
player.y = bleachers[0].y - 100;
}
// Restore game state
isGameActive = true;
}, 3000);
}
}
// Game over function
function gameOver() {
if (!isGameActive) {
return;
}
isGameActive = false;
// Save high score
var highScore = storage.highScore || 0;
if (LK.getScore() > highScore) {
storage.highScore = LK.getScore();
storage.highLevel = gameLevel;
}
// Show game over
LK.showGameOver();
}
// Update score display
function updateScoreDisplay() {
scoreText.setText("SCORE: " + LK.getScore());
}
// Handle down event
game.down = function (x, y, obj) {
if (isGameActive && player.isActive) {
player.jump();
// Add a small horizontal movement based on tap position
if (x < player.x) {
player.velocityX = -6;
player.facing = -1;
} else {
player.velocityX = 6;
player.facing = 1;
}
}
};
// Game update loop
game.update = function () {
if (!isGameActive) {
return;
}
// Update player
player.update();
// Check collisions with bleachers
checkBleacherCollisions();
// Check memorabilia collection
checkMemorabilia();
// Check obstacle collisions
checkObstacles();
// Check crowd wave interactions
checkCrowdWaves();
// Check if level is complete
checkLevelComplete();
// Periodically spawn crowd waves
if (LK.ticks - lastWaveTime > 300 && Math.random() < 0.01 * gameLevel) {
spawnCrowdWave();
lastWaveTime = LK.ticks;
}
// Camera follows player (with some limits)
if (player.y < 2732 / 2) {
var targetY = 2732 / 2 - player.y;
game.y = Math.min(Math.max(targetY, -2000), 0);
} else {
game.y = 0;
}
};
// Initialize the game
initGame();