User prompt
player speed and its jump gravity should also be affected by speed inctease
User prompt
Please fix the bug: 'TypeError: Cannot read properties of undefined (reading 'easeOutQuad')' in or related to this line: 'tween.to(comboText, {' Line Number: 117 ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Add combo pontins and also didplay it when mutiple enemies are killed during the same jump, before player touchea the gtound
User prompt
Update home screen to use super mario nes colors
User prompt
Increase speed faster
User prompt
Please fix the bug: 'TypeError: LK.getMusic is not a function' in or related to this line: 'var music = LK.getMusic('theme');' Line Number: 633
User prompt
Please fix the bug: 'TypeError: LK.getMusicSound is not a function' in or related to this line: 'var music = LK.getMusicSound('theme');' Line Number: 633
User prompt
Please fix the bug: 'TypeError: LK.getMusic is not a function' in or related to this line: 'var music = LK.getMusic('theme');' Line Number: 633
User prompt
Please fix the bug: 'TypeError: LK.setMusicPlaybackRate is not a function' in or related to this line: 'LK.setMusicPlaybackRate(musicPlaybackRate);' Line Number: 844
User prompt
Music speed should also increase like the game speed
User prompt
Paralax and enemies speed should increase in time
User prompt
Use 8bit font for the text
User prompt
I cant dash since evrey time i Tap the player jumps, how can we separate the action from jumping and dashing
User prompt
do not have player flash on double jump
User prompt
make sure dash can be identified to be different than jump
User prompt
nice it is working! now lets adda anew upgrade called, DASH. When player swipes forward, player will have a quick dash forward and be invincible for that dash ↪💡 Consider importing and using the following plugins: @upit/tween.v1, @upit/storage.v1
User prompt
Please fix the bug: 'Uncaught TypeError: doubleJumpButton.setTextOptions is not a function' in or related to this line: 'doubleJumpButton.setTextOptions({' Line Number: 463
User prompt
still ant buy double jump or click on back to menu
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot set properties of undefined (setting 'fill')' in or related to this line: 'doubleJumpButton.style.fill = storage.doubleJumpPurchased ? 0x00FF00 : 0xFFFFFF;' Line Number: 462
User prompt
Can you fix xupgraedes screen. I cant buy upgrades even if I have the coins.
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot set properties of undefined (setting 'fill')' in or related to this line: 'doubleJumpButton.style.fill = storage.doubleJumpPurchased ? 0x00FF00 : 0xFFFFFF;' Line Number: 462
User prompt
in the main menu add a new section with upgrades. Player will be able to buy upgrades with coins. Lets create a fist update called double jump that costs 5 coins. When player buys double jump player will be able to double jump in the game. ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
coins hshoudl only add one coin per pick up, seems like it is adding double now ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Separate score from coin collection. Show coint count below the score. Coins should persist between sessions. ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Add a main menu screen
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
coins: 0
});
/****
* Classes
****/
var Background = Container.expand(function () {
var self = Container.call(this);
var backgrounds = ['background1', 'background2', 'background3'];
var randomBackground = backgrounds[Math.floor(Math.random() * backgrounds.length)];
var backgroundGraphics = self.attachAsset(randomBackground, {
anchorX: 0,
anchorY: 0
});
self.speed = 3;
self.update = function () {
if (!game.playerDead) {
self.x -= self.speed;
}
if (self.x <= -2048) {
self.x = 2048;
}
};
});
var Background2 = Container.expand(function () {
var self = Container.call(this);
var backgrounds = ['background1', 'background2', 'background3'];
var randomBackground = backgrounds[Math.floor(Math.random() * backgrounds.length)];
var backgroundGraphics = self.attachAsset(randomBackground, {
anchorX: 0,
anchorY: 0
});
self.speed = 3;
self.update = function () {
if (!game.playerDead) {
self.x -= self.speed;
}
if (self.x <= -2048) {
self.x = 2048;
}
};
});
var Coin = Container.expand(function () {
var self = Container.call(this);
var coinGraphics = self.attachAsset('coin', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
self.speed = 3;
self.collected = false;
self.y = 2732 - 600; // Position coins higher than the ground
self.update = function () {
if (!game.playerDead) {
self.x -= self.speed;
}
if (self.x < -100) {
self.destroy();
}
};
});
var Enemy = Container.expand(function () {
var self = Container.call(this);
self.runFrames = ['turtle1', 'turtle2'];
self.sprites = [];
// Pre-attach all sprites
for (var i = 0; i < self.runFrames.length; i++) {
var sprite = self.attachAsset(self.runFrames[i], {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
sprite.alpha = i === 0 ? 1 : 0;
self.sprites.push(sprite);
}
self.speed = 6 + Math.random() * 2;
self.passed = false;
self.isJumping = false;
self.velocityY = 0;
self.groundY = 2732 - 400; // 400 pixels from bottom
self.y = self.groundY; // Set initial position to ground level
self.runFrameIndex = 0;
self.runFrameCounter = 0;
self.runFrameDelay = 15;
self.showFrame = function (index) {
// Hide all sprites first
for (var i = 0; i < self.sprites.length; i++) {
self.sprites[i].alpha = 0;
}
// Show the appropriate sprite
self.sprites[index].alpha = 1;
};
self.update = function () {
self.x -= self.speed + Math.floor(LK.ticks / 600) * 0.1; // Increase speed over time
if (self.isJumping) {
self.y += self.velocityY;
self.velocityY += 0.5; // Gravity effect
if (self.y > 2732) {
self.destroy();
}
} else {
self.runFrameCounter++;
if (self.runFrameCounter >= self.runFrameDelay) {
self.runFrameIndex = (self.runFrameIndex + 1) % self.runFrames.length;
self.showFrame(self.runFrameIndex);
self.runFrameCounter = 0;
}
}
if (self.x < -100) {
self.destroy();
}
};
});
var FlyKoopa = Container.expand(function () {
var self = Container.call(this);
self.runFrames = ['flykoopa1', 'flykoopa2'];
self.sprites = [];
// Pre-attach all sprites
for (var i = 0; i < self.runFrames.length; i++) {
var sprite = self.attachAsset(self.runFrames[i], {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
sprite.alpha = i === 0 ? 1 : 0;
self.sprites.push(sprite);
}
self.speed = 4 + Math.random() * 2;
self.runFrameIndex = 0;
self.runFrameCounter = 0;
self.runFrameDelay = 15;
self.isJumping = false;
self.velocityY = 0;
self.showFrame = function (index) {
// Hide all sprites first
for (var i = 0; i < self.sprites.length; i++) {
self.sprites[i].alpha = 0;
}
// Show the appropriate sprite
self.sprites[index].alpha = 1;
};
self.update = function () {
self.x -= self.speed;
if (self.isJumping) {
self.y += self.velocityY;
self.velocityY += 0.5; // Gravity effect
if (self.y > 2732) {
self.destroy();
}
} else {
self.runFrameCounter++;
if (self.runFrameCounter >= self.runFrameDelay) {
self.runFrameIndex = (self.runFrameIndex + 1) % self.runFrames.length;
self.showFrame(self.runFrameIndex);
self.runFrameCounter = 0;
}
}
if (self.x < -100) {
self.destroy();
}
};
});
var Goomba = Container.expand(function () {
var self = Container.call(this);
self.runFrames = ['goomba1', 'goomba2'];
self.sprites = [];
// Pre-attach all sprites
for (var i = 0; i < self.runFrames.length; i++) {
var sprite = self.attachAsset(self.runFrames[i], {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
sprite.alpha = i === 0 ? 1 : 0;
self.sprites.push(sprite);
}
self.speed = 4 + Math.random() * 2;
self.passed = false;
self.isJumping = false;
self.velocityY = 0;
self.groundY = 2732 - 400; // 400 pixels from bottom
self.y = self.groundY; // Set initial position to ground level
self.runFrameIndex = 0;
self.runFrameCounter = 0;
self.runFrameDelay = 15;
self.showFrame = function (index) {
// Hide all sprites first
for (var i = 0; i < self.sprites.length; i++) {
self.sprites[i].alpha = 0;
}
// Show the appropriate sprite
self.sprites[index].alpha = 1;
};
self.update = function () {
self.x -= self.speed;
if (self.isJumping) {
self.y += self.velocityY;
self.velocityY += 0.5; // Gravity effect
if (self.y > 2732) {
self.destroy();
}
} else {
self.runFrameCounter++;
if (self.runFrameCounter >= self.runFrameDelay) {
self.runFrameIndex = (self.runFrameIndex + 1) % self.runFrames.length;
self.showFrame(self.runFrameIndex);
self.runFrameCounter = 0;
}
}
if (self.x < -100) {
self.destroy();
}
};
});
var MainMenu = Container.expand(function () {
var self = Container.call(this);
// Title text
var titleText = new Text2('MARIO GAME', {
size: 150,
fill: 0xFF0000
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 2048 / 2;
titleText.y = 2732 / 3;
self.addChild(titleText);
// Subtitle text
var subtitleText = new Text2('Jump, run, and collect coins!', {
size: 80,
fill: 0xFFFFFF
});
subtitleText.anchor.set(0.5, 0.5);
subtitleText.x = 2048 / 2;
subtitleText.y = 2732 / 3 + 200;
self.addChild(subtitleText);
// Play button
var playButton = new Text2('TAP TO START', {
size: 100,
fill: 0xFFFF00
});
playButton.anchor.set(0.5, 0.5);
playButton.x = 2048 / 2;
playButton.y = 2732 / 2 + 200;
self.addChild(playButton);
// Upgrade button
var upgradeButton = new Text2('UPGRADES', {
size: 80,
fill: 0x00FFFF
});
upgradeButton.anchor.set(0.5, 0.5);
upgradeButton.x = 2048 / 2;
upgradeButton.y = 2732 / 2 + 350;
self.addChild(upgradeButton);
// Make the play button "pulse" for attention
self.animationCounter = 0;
self.update = function () {
self.animationCounter += 0.05;
playButton.scale.x = 1 + Math.sin(self.animationCounter) * 0.1;
playButton.scale.y = 1 + Math.sin(self.animationCounter) * 0.1;
};
// Handle button clicks
self.down = function (x, y, obj) {
// Check if upgrade button was clicked
if (x > upgradeButton.x - 200 && x < upgradeButton.x + 200 && y > upgradeButton.y - 50 && y < upgradeButton.y + 50) {
if (self.onUpgradeClick) {
self.onUpgradeClick();
}
return true; // Prevent propagation
}
// Default behavior - start game
if (self.onPlayClick) {
self.onPlayClick();
}
};
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
self.runAnimation = ['player_run1', 'player_run2', 'player_run3'];
self.jumpAnimation = ['player_jump'];
self.currentState = 'running';
self.sprites = [];
self.runFrame = 0;
self.jumpFrame = 0;
self.animationCounter = 0;
self.animationSpeed = 0.1;
// Pre-attach all sprites
for (var i = 0; i < self.runAnimation.length; i++) {
var sprite = self.attachAsset(self.runAnimation[i], {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
sprite.alpha = i === 0 ? 1 : 0;
self.sprites.push(sprite);
}
for (var j = 0; j < self.jumpAnimation.length; j++) {
var jumpSprite = self.attachAsset(self.jumpAnimation[j], {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
jumpSprite.alpha = 0;
self.sprites.push(jumpSprite);
}
self.speed = 5 + Math.floor(LK.ticks / 600) * 0.1; // Increase speed over time
self.jumpHeight = 25;
self.isJumping = false;
self.canDoubleJump = false; // Track if double jump is available
self.hasDoubleJumped = false; // Track if double jump was used
self.velocityY = 0;
self.groundY = 2732 - 400; // 400 pixels from bottom
self.y = self.groundY; // Set initial position to ground level
self.runFrameDelay = 10;
self.showFrame = function (frameType, index) {
// Hide all sprites first
for (var i = 0; i < self.sprites.length; i++) {
self.sprites[i].alpha = 0;
}
// Show the appropriate sprite based on state and frame index
if (frameType === 'run') {
self.sprites[index].alpha = 1;
} else if (frameType === 'jump') {
self.sprites[self.runAnimation.length + index].alpha = 1;
}
};
self.update = function () {
if (self.isJumping) {
self.y += self.velocityY;
self.velocityY += 0.3;
// Show jump sprite
self.showFrame('jump', 0);
if (self.y >= self.groundY - 30) {
if (self.y < 0) {
// Prevent jump from exceeding the top of the screen
self.y = 0;
self.velocityY = 0;
}
if (!self.isDead) {
self.y = self.groundY - 30;
self.isJumping = false;
self.hasDoubleJumped = false; // Reset double jump when landing
self.velocityY = 0;
self.currentState = 'running';
}
}
} else {
// Running animation
self.animationCounter += self.animationSpeed;
if (self.animationCounter >= 1) {
self.animationCounter = 0;
self.runFrame = (self.runFrame + 1) % self.runAnimation.length;
self.showFrame('run', self.runFrame);
}
}
};
self.jump = function () {
// Regular jump when not jumping
if (!self.isJumping) {
self.isJumping = true;
LK.getSound('jump').play();
self.velocityY = -self.jumpHeight;
self.currentState = 'jumping';
self.showFrame('jump', 0);
}
// Double jump when already jumping and upgrade purchased
else if (self.isJumping && storage.doubleJumpPurchased && !self.hasDoubleJumped) {
LK.getSound('jump').play();
self.velocityY = -self.jumpHeight * 0.8; // Slightly lower second jump
self.hasDoubleJumped = true;
// Visual effect for double jump
LK.effects.flashObject(self, 0x00FFFF, 500);
}
};
});
var UpgradeMenu = Container.expand(function () {
var self = Container.call(this);
// Background panel
var panel = self.attachAsset('gauge_background', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.1,
scaleY: 5
});
panel.alpha = 0.8;
// Title
var titleText = new Text2('UPGRADES', {
size: 100,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 0;
titleText.y = -400;
self.addChild(titleText);
// Coin display
var coinDisplay = new Text2('Coins: ' + (storage.coins || 0), {
size: 70,
fill: 0xFFD700
});
coinDisplay.anchor.set(0.5, 0.5);
coinDisplay.x = 0;
coinDisplay.y = -300;
self.addChild(coinDisplay);
// Double Jump upgrade button
var doubleJumpButton = new Text2('Double Jump: ' + (storage.doubleJumpPurchased ? 'PURCHASED' : '5 COINS'), {
size: 70,
fill: storage.doubleJumpPurchased ? 0x00FF00 : 0xFFFFFF
});
doubleJumpButton.anchor.set(0.5, 0.5);
doubleJumpButton.x = 0;
doubleJumpButton.y = -100;
self.addChild(doubleJumpButton);
// Close button
var closeButton = new Text2('BACK TO MENU', {
size: 70,
fill: 0xFF0000
});
closeButton.anchor.set(0.5, 0.5);
closeButton.x = 0;
closeButton.y = 400;
self.addChild(closeButton);
// Update coin display
self.updateCoinDisplay = function () {
coinDisplay.setText('Coins: ' + (storage.coins || 0));
doubleJumpButton.setText('Double Jump: ' + (storage.doubleJumpPurchased ? 'PURCHASED' : '5 COINS'));
doubleJumpButton.style.fill = storage.doubleJumpPurchased ? 0x00FF00 : 0xFFFFFF;
};
// Handle purchase
self.purchaseDoubleJump = function () {
if (!storage.doubleJumpPurchased && (storage.coins || 0) >= 5) {
storage.coins -= 5;
storage.doubleJumpPurchased = true;
self.updateCoinDisplay();
}
};
// Handle button presses
self.down = function (x, y, obj) {
var local = self.toLocal({
x: x,
y: y
});
// Check if double jump button was pressed
if (Math.abs(local.x - doubleJumpButton.x) < 400 && Math.abs(local.y - doubleJumpButton.y) < 50) {
self.purchaseDoubleJump();
}
// Check if close button was pressed
if (Math.abs(local.x - closeButton.x) < 300 && Math.abs(local.y - closeButton.y) < 50) {
if (self.onClose) {
self.onClose();
}
}
};
return self;
});
/****
* Initialize Game
****/
/****
*-Seperator-
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB
});
/****
* Game Code
****/
// Game state variables
var gameStarted = false;
var showingUpgradeMenu = false;
var mainMenu;
var upgradeMenu;
var background;
var background2;
var player;
var enemies = [];
var enemySpawnInterval = 80;
var enemySpawnCounter = 0;
var coinObjects = []; // Renamed from 'coins' to avoid conflict with coin counter
var coinSpawnInterval = Math.max(50, 150 - Math.floor(LK.ticks / 600)); // Decrease interval over time, minimum 50
var coinSpawnCounter = 0;
// Score system
var score = 0;
var coins = storage.coins || 0; // Get persistent coin count
var scoreText = new Text2('Score: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreText.anchor.set(1, 0);
scoreText.x = -50;
scoreText.y = 50;
LK.gui.topRight.addChild(scoreText);
// Coin count display
var coinText = new Text2('Coins: ' + coins, {
size: 50,
fill: 0xFFD700 // Gold color for coins
});
coinText.anchor.set(1, 0);
coinText.x = -50;
coinText.y = 120; // Position below score
LK.gui.topRight.addChild(coinText);
scoreText.alpha = 0; // Hide score initially
coinText.alpha = 0; // Hide coin count initially
// Initialize upgrades in storage if needed
if (storage.doubleJumpPurchased === undefined) {
storage.doubleJumpPurchased = false;
}
// Show main menu first
mainMenu = game.addChild(new MainMenu());
mainMenu.onUpgradeClick = function () {
showingUpgradeMenu = true;
mainMenu.visible = false;
// Create upgrade menu
upgradeMenu = game.addChild(new UpgradeMenu());
upgradeMenu.x = 2048 / 2;
upgradeMenu.y = 2732 / 2;
upgradeMenu.updateCoinDisplay();
upgradeMenu.onClose = function () {
showingUpgradeMenu = false;
upgradeMenu.destroy();
upgradeMenu = null;
mainMenu.visible = true;
// Update coin display on main menu
coinText.setText('Coins: ' + (storage.coins || 0));
};
};
mainMenu.onPlayClick = function () {
// Start the game
gameStarted = true;
mainMenu.destroy();
mainMenu = null;
// Initialize game elements - handled in game.down
};
game.update = function () {
// Handle menu states
if (!gameStarted) {
if (showingUpgradeMenu) {
// When in upgrade menu, no need to update main menu
return;
}
// When in menu mode, just update the menu
if (mainMenu) {
mainMenu.update();
}
return;
}
// Game hasn't been initialized yet - start it
if (!background) {
// Initialize game elements
LK.playMusic('theme');
// Create background
background = game.addChild(new Background());
background.x = 0;
background.y = 0;
background2 = game.addChild(new Background2());
background2.x = 2048;
background2.y = 0;
// Create player
player = game.addChild(new Player());
player.x = 2048 / 4;
player.y = player.groundY - 30;
// Show score and coin count
scoreText.alpha = 1;
coinText.alpha = 1;
}
// Game play update logic
background.update();
background2.update();
player.update();
enemySpawnCounter++;
coinSpawnCounter++;
if (coinSpawnCounter >= coinSpawnInterval) {
var coin = new Coin();
coin.x = 2048 + Math.random() * 200;
// Set a reasonable height range for coins (not too low, not too high)
coin.y = Math.max(300, Math.min(2732 - 600, Math.random() * (2732 - 800)));
coinObjects.push(coin);
game.addChild(coin);
coinSpawnCounter = 0;
}
if (enemySpawnCounter >= enemySpawnInterval) {
var enemyType = Math.random() < 0.33 ? 'Enemy' : Math.random() < 0.5 ? 'Goomba' : 'FlyKoopa';
var enemy;
if (enemyType === 'Enemy') {
enemy = new Enemy();
} else if (enemyType === 'Goomba') {
enemy = new Goomba();
} else {
enemy = new FlyKoopa();
// Ensure FlyKoopas spawn in the middle to upper part of the screen, not too low
enemy.y = Math.max(300, Math.min(2732 - 600, Math.random() * (2732 - 800)));
}
enemy.x = 2048 + Math.random() * 200;
if (enemyType === 'FlyKoopa') {
// Height for FlyKoopa is already set earlier, no need to set it again
} else {
enemy.y = enemy.groundY; // Use groundY for initial position
}
enemies.push(enemy);
game.addChild(enemy);
enemySpawnInterval = Math.max(20, Math.floor(Math.random() * 100) + 60 - Math.floor(LK.ticks / 600)); // Decrease interval over time, minimum 20
enemySpawnCounter = 0;
}
for (var j = enemies.length - 1; j >= 0; j--) {
enemies[j].update();
if (player.intersects(enemies[j])) {
if (!player.isDead && player.isJumping && player.velocityY > 0 && player.y < enemies[j].y) {
// Player is falling and lands on enemy
enemies[j].velocityY = -10; // Pop up effect for enemy
player.velocityY = -15; // Bounce Mario upwards
LK.getSound('stomp').play(); // Play stomp sound
// Add score for defeating an enemy
score += 50;
scoreText.setText('Score: ' + score);
LK.setScore(score);
enemies[j].isJumping = true;
enemies[j].canHarmPlayer = false; // Enemy can no longer harm player
} else if (enemies[j].canHarmPlayer !== false) {
if (!player.isDead && enemies[j].canHarmPlayer !== false) {
LK.getSound('dead').play(); // Play dead sound
player.isDead = true;
game.playerDead = true;
player.velocityY = -10; // Pop up effect similar to enemy
player.isJumping = true;
LK.setTimeout(function () {
// Save final score before game over
LK.setScore(score);
LK.showGameOver();
}, 3000); // Delay game over by 3 seconds
}
}
} else if (player.x > enemies[j].x && !enemies[j].passed) {
enemies[j].passed = true;
}
if (enemies[j].x < -100) {
enemies.splice(j, 1);
}
}
for (var k = coinObjects.length - 1; k >= 0; k--) {
coinObjects[k].update();
if (player.intersects(coinObjects[k])) {
if (!coinObjects[k].collected) {
coinObjects[k].collected = true;
LK.getSound('Coin').play(); // Play coin sound
// Increase score when collecting coins
score += 10;
// Separate coin counter
coins++;
// Update storage for persistence
storage.coins = coins;
// Update displays
scoreText.setText('Score: ' + score);
coinText.setText('Coins: ' + coins);
LK.setScore(score);
coinObjects[k].destroy();
coinObjects.splice(k, 1);
}
}
}
};
game.down = function (x, y, obj) {
if (showingUpgradeMenu) {
// Let the upgrade menu handle this event
return;
}
if (!gameStarted) {
// Let the main menu handle this event
return;
} else {
// In-game tap makes player jump
player.jump();
}
}; ===================================================================
--- original.js
+++ change.js
@@ -249,15 +249,38 @@
playButton.anchor.set(0.5, 0.5);
playButton.x = 2048 / 2;
playButton.y = 2732 / 2 + 200;
self.addChild(playButton);
+ // Upgrade button
+ var upgradeButton = new Text2('UPGRADES', {
+ size: 80,
+ fill: 0x00FFFF
+ });
+ upgradeButton.anchor.set(0.5, 0.5);
+ upgradeButton.x = 2048 / 2;
+ upgradeButton.y = 2732 / 2 + 350;
+ self.addChild(upgradeButton);
// Make the play button "pulse" for attention
self.animationCounter = 0;
self.update = function () {
self.animationCounter += 0.05;
playButton.scale.x = 1 + Math.sin(self.animationCounter) * 0.1;
playButton.scale.y = 1 + Math.sin(self.animationCounter) * 0.1;
};
+ // Handle button clicks
+ self.down = function (x, y, obj) {
+ // Check if upgrade button was clicked
+ if (x > upgradeButton.x - 200 && x < upgradeButton.x + 200 && y > upgradeButton.y - 50 && y < upgradeButton.y + 50) {
+ if (self.onUpgradeClick) {
+ self.onUpgradeClick();
+ }
+ return true; // Prevent propagation
+ }
+ // Default behavior - start game
+ if (self.onPlayClick) {
+ self.onPlayClick();
+ }
+ };
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
@@ -292,8 +315,10 @@
}
self.speed = 5 + Math.floor(LK.ticks / 600) * 0.1; // Increase speed over time
self.jumpHeight = 25;
self.isJumping = false;
+ self.canDoubleJump = false; // Track if double jump is available
+ self.hasDoubleJumped = false; // Track if double jump was used
self.velocityY = 0;
self.groundY = 2732 - 400; // 400 pixels from bottom
self.y = self.groundY; // Set initial position to ground level
self.runFrameDelay = 10;
@@ -323,8 +348,9 @@
}
if (!self.isDead) {
self.y = self.groundY - 30;
self.isJumping = false;
+ self.hasDoubleJumped = false; // Reset double jump when landing
self.velocityY = 0;
self.currentState = 'running';
}
}
@@ -338,17 +364,105 @@
}
}
};
self.jump = function () {
+ // Regular jump when not jumping
if (!self.isJumping) {
self.isJumping = true;
LK.getSound('jump').play();
self.velocityY = -self.jumpHeight;
self.currentState = 'jumping';
self.showFrame('jump', 0);
}
+ // Double jump when already jumping and upgrade purchased
+ else if (self.isJumping && storage.doubleJumpPurchased && !self.hasDoubleJumped) {
+ LK.getSound('jump').play();
+ self.velocityY = -self.jumpHeight * 0.8; // Slightly lower second jump
+ self.hasDoubleJumped = true;
+ // Visual effect for double jump
+ LK.effects.flashObject(self, 0x00FFFF, 500);
+ }
};
});
+var UpgradeMenu = Container.expand(function () {
+ var self = Container.call(this);
+ // Background panel
+ var panel = self.attachAsset('gauge_background', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ scaleX: 1.1,
+ scaleY: 5
+ });
+ panel.alpha = 0.8;
+ // Title
+ var titleText = new Text2('UPGRADES', {
+ size: 100,
+ fill: 0xFFFFFF
+ });
+ titleText.anchor.set(0.5, 0.5);
+ titleText.x = 0;
+ titleText.y = -400;
+ self.addChild(titleText);
+ // Coin display
+ var coinDisplay = new Text2('Coins: ' + (storage.coins || 0), {
+ size: 70,
+ fill: 0xFFD700
+ });
+ coinDisplay.anchor.set(0.5, 0.5);
+ coinDisplay.x = 0;
+ coinDisplay.y = -300;
+ self.addChild(coinDisplay);
+ // Double Jump upgrade button
+ var doubleJumpButton = new Text2('Double Jump: ' + (storage.doubleJumpPurchased ? 'PURCHASED' : '5 COINS'), {
+ size: 70,
+ fill: storage.doubleJumpPurchased ? 0x00FF00 : 0xFFFFFF
+ });
+ doubleJumpButton.anchor.set(0.5, 0.5);
+ doubleJumpButton.x = 0;
+ doubleJumpButton.y = -100;
+ self.addChild(doubleJumpButton);
+ // Close button
+ var closeButton = new Text2('BACK TO MENU', {
+ size: 70,
+ fill: 0xFF0000
+ });
+ closeButton.anchor.set(0.5, 0.5);
+ closeButton.x = 0;
+ closeButton.y = 400;
+ self.addChild(closeButton);
+ // Update coin display
+ self.updateCoinDisplay = function () {
+ coinDisplay.setText('Coins: ' + (storage.coins || 0));
+ doubleJumpButton.setText('Double Jump: ' + (storage.doubleJumpPurchased ? 'PURCHASED' : '5 COINS'));
+ doubleJumpButton.style.fill = storage.doubleJumpPurchased ? 0x00FF00 : 0xFFFFFF;
+ };
+ // Handle purchase
+ self.purchaseDoubleJump = function () {
+ if (!storage.doubleJumpPurchased && (storage.coins || 0) >= 5) {
+ storage.coins -= 5;
+ storage.doubleJumpPurchased = true;
+ self.updateCoinDisplay();
+ }
+ };
+ // Handle button presses
+ self.down = function (x, y, obj) {
+ var local = self.toLocal({
+ x: x,
+ y: y
+ });
+ // Check if double jump button was pressed
+ if (Math.abs(local.x - doubleJumpButton.x) < 400 && Math.abs(local.y - doubleJumpButton.y) < 50) {
+ self.purchaseDoubleJump();
+ }
+ // Check if close button was pressed
+ if (Math.abs(local.x - closeButton.x) < 300 && Math.abs(local.y - closeButton.y) < 50) {
+ if (self.onClose) {
+ self.onClose();
+ }
+ }
+ };
+ return self;
+});
/****
* Initialize Game
****/
@@ -363,9 +477,11 @@
* Game Code
****/
// Game state variables
var gameStarted = false;
+var showingUpgradeMenu = false;
var mainMenu;
+var upgradeMenu;
var background;
var background2;
var player;
var enemies = [];
@@ -395,18 +511,70 @@
coinText.y = 120; // Position below score
LK.gui.topRight.addChild(coinText);
scoreText.alpha = 0; // Hide score initially
coinText.alpha = 0; // Hide coin count initially
+// Initialize upgrades in storage if needed
+if (storage.doubleJumpPurchased === undefined) {
+ storage.doubleJumpPurchased = false;
+}
// Show main menu first
mainMenu = game.addChild(new MainMenu());
+mainMenu.onUpgradeClick = function () {
+ showingUpgradeMenu = true;
+ mainMenu.visible = false;
+ // Create upgrade menu
+ upgradeMenu = game.addChild(new UpgradeMenu());
+ upgradeMenu.x = 2048 / 2;
+ upgradeMenu.y = 2732 / 2;
+ upgradeMenu.updateCoinDisplay();
+ upgradeMenu.onClose = function () {
+ showingUpgradeMenu = false;
+ upgradeMenu.destroy();
+ upgradeMenu = null;
+ mainMenu.visible = true;
+ // Update coin display on main menu
+ coinText.setText('Coins: ' + (storage.coins || 0));
+ };
+};
+mainMenu.onPlayClick = function () {
+ // Start the game
+ gameStarted = true;
+ mainMenu.destroy();
+ mainMenu = null;
+ // Initialize game elements - handled in game.down
+};
game.update = function () {
+ // Handle menu states
if (!gameStarted) {
+ if (showingUpgradeMenu) {
+ // When in upgrade menu, no need to update main menu
+ return;
+ }
// When in menu mode, just update the menu
if (mainMenu) {
mainMenu.update();
}
return;
}
+ // Game hasn't been initialized yet - start it
+ if (!background) {
+ // Initialize game elements
+ LK.playMusic('theme');
+ // Create background
+ background = game.addChild(new Background());
+ background.x = 0;
+ background.y = 0;
+ background2 = game.addChild(new Background2());
+ background2.x = 2048;
+ background2.y = 0;
+ // Create player
+ player = game.addChild(new Player());
+ player.x = 2048 / 4;
+ player.y = player.groundY - 30;
+ // Show score and coin count
+ scoreText.alpha = 1;
+ coinText.alpha = 1;
+ }
// Game play update logic
background.update();
background2.update();
player.update();
@@ -501,32 +669,15 @@
}
}
};
game.down = function (x, y, obj) {
+ if (showingUpgradeMenu) {
+ // Let the upgrade menu handle this event
+ return;
+ }
if (!gameStarted) {
- // Start the game when player taps on menu
- gameStarted = true;
- // Remove menu
- if (mainMenu) {
- mainMenu.destroy();
- mainMenu = null;
- }
- // Initialize game elements
- LK.playMusic('theme');
- // Create background
- background = game.addChild(new Background());
- background.x = 0;
- background.y = 0;
- background2 = game.addChild(new Background2());
- background2.x = 2048;
- background2.y = 0;
- // Create player
- player = game.addChild(new Player());
- player.x = 2048 / 4;
- player.y = player.groundY - 30;
- // Show score and coin count
- scoreText.alpha = 1;
- coinText.alpha = 1;
+ // Let the main menu handle this event
+ return;
} else {
// In-game tap makes player jump
player.jump();
}